dt->id = (int32_t)IPV6_EXTHDR_GET_FH_ID(p);
dt->af = AF_INET6;
}
+ dt->vlan_id[0] = p->vlan_id[0];
+ dt->vlan_id[1] = p->vlan_id[1];
dt->policy = DefragGetOsPolicy(p);
TAILQ_INIT(&dt->frags);
(void) DefragTrackerIncrUsecnt(dt);
struct {
uint32_t src, dst;
uint32_t id;
+ uint16_t vlan_id[2];
};
- uint32_t u32[3];
+ uint32_t u32[4];
};
} DefragHashKey4;
struct {
uint32_t src[4], dst[4];
uint32_t id;
+ uint16_t vlan_id[2];
};
- uint32_t u32[9];
+ uint32_t u32[10];
};
} DefragHashKey6;
* source address
* destination address
* id
+ * vlan_id
*/
static inline uint32_t DefragHashGetKey(Packet *p) {
uint32_t key;
dhk.dst = p->src.addr_data32[0];
}
dhk.id = (uint32_t)IPV4_GET_IPID(p);
+ dhk.vlan_id[0] = p->vlan_id[0];
+ dhk.vlan_id[1] = p->vlan_id[1];
- uint32_t hash = hashword(dhk.u32, 3, defrag_config.hash_rand);
+ uint32_t hash = hashword(dhk.u32, 4, defrag_config.hash_rand);
key = hash % defrag_config.hash_size;
} else if (p->ip6h != NULL) {
DefragHashKey6 dhk;
dhk.dst[3] = p->src.addr_data32[3];
}
dhk.id = IPV6_EXTHDR_GET_FH_ID(p);
+ dhk.vlan_id[0] = p->vlan_id[0];
+ dhk.vlan_id[1] = p->vlan_id[1];
- uint32_t hash = hashword(dhk.u32, 9, defrag_config.hash_rand);
+ uint32_t hash = hashword(dhk.u32, 10, defrag_config.hash_rand);
key = hash % defrag_config.hash_size;
} else
key = 0;
CMP_ADDR(&(d1)->dst_addr, &(d2)->dst)) || \
(CMP_ADDR(&(d1)->src_addr, &(d2)->dst) && \
CMP_ADDR(&(d1)->dst_addr, &(d2)->src))) && \
- (d1)->id == (id))
+ (d1)->id == (id) && \
+ (d1)->vlan_id[0] == (d2)->vlan_id[0] && \
+ (d1)->vlan_id[1] == (d2)->vlan_id[1])
static inline int DefragTrackerCompare(DefragTracker *t, Packet *p) {
uint32_t id;
return ret;
}
+/**
+ * Test that fragments in different VLANs that would otherwise be
+ * re-assembled, are not re-assembled. Just use simple in-order
+ * fragments.
+ */
+static int
+DefragVlanTest(void) {
+ Packet *p1 = NULL, *p2 = NULL, *r = NULL;
+ int ret = 0;
+
+ DefragInit();
+
+ p1 = BuildTestPacket(1, 0, 1, 'A', 8);
+ if (p1 == NULL)
+ goto end;
+ p2 = BuildTestPacket(1, 1, 0, 'B', 8);
+ if (p2 == NULL)
+ goto end;
+
+ /* With no VLAN IDs set, packets should re-assemble. */
+ if ((r = Defrag(NULL, NULL, p1)) != NULL)
+ goto end;
+ if ((r = Defrag(NULL, NULL, p2)) == NULL)
+ goto end;
+ SCFree(r);
+
+ /* With mismatched VLANs, packets should not re-assemble. */
+ p1->vlan_id[0] = 1;
+ p2->vlan_id[0] = 2;
+ if ((r = Defrag(NULL, NULL, p1)) != NULL)
+ goto end;
+ if ((r = Defrag(NULL, NULL, p2)) != NULL)
+ goto end;
+
+ /* Pass. */
+ ret = 1;
+
+end:
+ if (p1 != NULL)
+ SCFree(p1);
+ if (p2 != NULL)
+ SCFree(p2);
+ DefragDestroy();
+
+ return ret;
+}
+
+/**
+ * Like DefragVlanTest, but for QinQ, testing the second level VLAN ID.
+ */
+static int
+DefragVlanQinQTest(void) {
+ Packet *p1 = NULL, *p2 = NULL, *r = NULL;
+ int ret = 0;
+
+ DefragInit();
+
+ p1 = BuildTestPacket(1, 0, 1, 'A', 8);
+ if (p1 == NULL)
+ goto end;
+ p2 = BuildTestPacket(1, 1, 0, 'B', 8);
+ if (p2 == NULL)
+ goto end;
+
+ /* With no VLAN IDs set, packets should re-assemble. */
+ if ((r = Defrag(NULL, NULL, p1)) != NULL)
+ goto end;
+ if ((r = Defrag(NULL, NULL, p2)) == NULL)
+ goto end;
+ SCFree(r);
+
+ /* With mismatched VLANs, packets should not re-assemble. */
+ p1->vlan_id[0] = 1;
+ p2->vlan_id[0] = 1;
+ p1->vlan_id[1] = 1;
+ p2->vlan_id[1] = 2;
+ if ((r = Defrag(NULL, NULL, p1)) != NULL)
+ goto end;
+ if ((r = Defrag(NULL, NULL, p2)) != NULL)
+ goto end;
+
+ /* Pass. */
+ ret = 1;
+
+end:
+ if (p1 != NULL)
+ SCFree(p1);
+ if (p2 != NULL)
+ SCFree(p2);
+ DefragDestroy();
+
+ return ret;
+}
+
#endif /* UNITTESTS */
void
UtRegisterTest("IPV6DefragSturgesNovakLastTest",
IPV6DefragSturgesNovakLastTest, 1);
+ UtRegisterTest("DefragVlanTest", DefragVlanTest, 1);
+ UtRegisterTest("DefragVlanQinQTest", DefragVlanQinQTest, 1);
+
UtRegisterTest("DefragTimeoutTest",
DefragTimeoutTest, 1);
#endif /* UNITTESTS */
prealloc: 10000
emergency-recovery: 30
-# This option controls the use of vlan ids in the flow hashing. Normally this
-# should be enabled, but in some (broken) setups where both sides of a flow are
-# not tagged with the same vlan tag, we can ignore the vlan id's in the flow
-# hashing.
+# This option controls the use of vlan ids in the flow (and defrag)
+# hashing. Normally this should be enabled, but in some (broken)
+# setups where both sides of a flow are not tagged with the same vlan
+# tag, we can ignore the vlan id's in the flow hashing.
vlan:
use-for-tracking: true