refactor: IP reassembly and rename stat name

This commit is contained in:
luwenpeng
2024-08-19 16:15:08 +08:00
parent bf2de263cf
commit 28f50b922b
6 changed files with 572 additions and 524 deletions

View File

@@ -48,28 +48,34 @@ enum METRIC_TYPE
METRIC_TYPE_CTRL_BYTES_TX, METRIC_TYPE_CTRL_BYTES_TX,
// ipv4 reassembly // ipv4 reassembly
METRIC_TYPE_IP4_FLOW_FIND, METRIC_TYPE_IP4_DEFRAGS_EXPECTED,
METRIC_TYPE_IP4_FLOW_ADD, METRIC_TYPE_IP4_DEFRAGS_SUCCEED,
METRIC_TYPE_IP4_FLOW_DEL, METRIC_TYPE_IP4_DEFRAGS_FAILED_TIMEOUT,
METRIC_TYPE_IP4_FLOW_TIMEOUT, METRIC_TYPE_IP4_DEFRAGS_FAILED_INVALID_LENGTH,
METRIC_TYPE_IP4_FLOW_FAIL_NO_SPACE, METRIC_TYPE_IP4_DEFRAGS_FAILED_OVERLAP,
METRIC_TYPE_IP4_FLOW_FAIL_OVERLAP, METRIC_TYPE_IP4_DEFRAGS_FAILED_TOO_MANY_FRAG,
METRIC_TYPE_IP4_FLOW_FAIL_MANY_FRAG,
METRIC_TYPE_IP4_FLOW_FAIL_INVALID_LENGTH, METRIC_TYPE_IP4_FRAGS,
METRIC_TYPE_IP4_FLOW_BYPASS_DUP_FIST_FRAG, METRIC_TYPE_IP4_FRAGS_FREED,
METRIC_TYPE_IP4_FLOW_BYPASS_DUP_LAST_FRAG, METRIC_TYPE_IP4_FRAGS_BUFFERED,
METRIC_TYPE_IP4_FRAGS_BYPASS_NO_BUFFER,
METRIC_TYPE_IP4_FRAGS_BYPASS_DUP_FIST_FRAG,
METRIC_TYPE_IP4_FRAGS_BYPASS_DUP_LAST_FRAG,
// ipv6 reassembly // ipv6 reassembly
METRIC_TYPE_IP6_FLOW_FIND, METRIC_TYPE_IP6_DEFRAGS_EXPECTED,
METRIC_TYPE_IP6_FLOW_ADD, METRIC_TYPE_IP6_DEFRAGS_SUCCEED,
METRIC_TYPE_IP6_FLOW_DEL, METRIC_TYPE_IP6_DEFRAGS_FAILED_TIMEOUT,
METRIC_TYPE_IP6_FLOW_TIMEOUT, METRIC_TYPE_IP6_DEFRAGS_FAILED_INVALID_LENGTH,
METRIC_TYPE_IP6_FLOW_FAIL_NO_SPACE, METRIC_TYPE_IP6_DEFRAGS_FAILED_OVERLAP,
METRIC_TYPE_IP6_FLOW_FAIL_OVERLAP, METRIC_TYPE_IP6_DEFRAGS_FAILED_TOO_MANY_FRAG,
METRIC_TYPE_IP6_FLOW_FAIL_MANY_FRAG,
METRIC_TYPE_IP6_FLOW_FAIL_INVALID_LENGTH, METRIC_TYPE_IP6_FRAGS,
METRIC_TYPE_IP6_FLOW_BYPASS_DUP_FIST_FRAG, METRIC_TYPE_IP6_FRAGS_FREED,
METRIC_TYPE_IP6_FLOW_BYPASS_DUP_LAST_FRAG, METRIC_TYPE_IP6_FRAGS_BUFFERED,
METRIC_TYPE_IP6_FRAGS_BYPASS_NO_BUFFER,
METRIC_TYPE_IP6_FRAGS_BYPASS_DUP_FIST_FRAG,
METRIC_TYPE_IP6_FRAGS_BYPASS_DUP_LAST_FRAG,
// TCP session // TCP session
METRIC_TYPE_HISTORY_TCP_SESSIONS, METRIC_TYPE_HISTORY_TCP_SESSIONS,
@@ -148,30 +154,34 @@ const char *name[] = {
"ctrl_bytes_tx", "ctrl_bytes_tx",
// ipv4 reassembly // ipv4 reassembly
// TODO rename "ip4_defrags_expected",
"ip4_flow_find", "ip4_defrags_succeed",
"ip4_flow_add", "ip4_defrags_failed_timeout",
"ip4_flow_del", "ip4_defrags_failed_invalid_length",
"ip4_flow_timeout", "ip4_defrags_failed_overlap",
"ip4_flow_fail_no_space", "ip4_defrags_failed_too_many_frag",
"ip4_flow_fail_overlap",
"ip4_flow_fail_many_frag", "ip4_frags",
"ip4_flow_fail_invalid_length", "ip4_frags_freed",
"ip4_flow_bypass_dup_fist_frag", "ip4_frags_buffered",
"ip4_flow_bypass_dup_last_frag", "ip4_frags_bypass_no_buffer",
"ip4_frags_bypass_dup_fist_frag",
"ip4_frags_bypass_dup_last_frag",
// ipv6 reassembly // ipv6 reassembly
// TODO rename "ip6_defrags_expected",
"ip6_flow_find", "ip6_defrags_succeed",
"ip6_flow_add", "ip6_defrags_failed_timeout",
"ip6_flow_del", "ip6_defrags_failed_invalid_length",
"ip6_flow_timeout", "ip6_defrags_failed_overlap",
"ip6_flow_fail_no_space", "ip6_defrags_failed_too_many_frag",
"ip6_flow_fail_overlap",
"ip6_flow_fail_many_frag", "ip6_frags",
"ip6_flow_fail_invalid_length", "ip6_frags_freed",
"ip6_flow_bypass_dup_fist_frag", "ip6_frags_buffered",
"ip6_flow_bypass_dup_last_frag", "ip6_frags_bypass_no_buffer",
"ip6_frags_bypass_dup_fist_frag",
"ip6_frags_bypass_dup_last_frag",
// TCP session // TCP session
"history_tcp_sessions", "history_tcp_sessions",
@@ -365,66 +375,78 @@ void stellar_stat_output(struct stellar_stat *stat)
stat->metric_val[j] += thr_stat->packet_io->ctrl_bytes_tx; stat->metric_val[j] += thr_stat->packet_io->ctrl_bytes_tx;
break; break;
// ipv4 reassembly // ipv4 reassembly
case METRIC_TYPE_IP4_FLOW_FIND: case METRIC_TYPE_IP4_DEFRAGS_EXPECTED:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_find; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_expected;
break; break;
case METRIC_TYPE_IP4_FLOW_ADD: case METRIC_TYPE_IP4_DEFRAGS_SUCCEED:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_add; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_succeed;
break; break;
case METRIC_TYPE_IP4_FLOW_DEL: case METRIC_TYPE_IP4_DEFRAGS_FAILED_TIMEOUT:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_del; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_failed_timeout;
break; break;
case METRIC_TYPE_IP4_FLOW_TIMEOUT: case METRIC_TYPE_IP4_DEFRAGS_FAILED_INVALID_LENGTH:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_timeout; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_failed_invalid_length;
break; break;
case METRIC_TYPE_IP4_FLOW_FAIL_NO_SPACE: case METRIC_TYPE_IP4_DEFRAGS_FAILED_OVERLAP:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_fail_no_space; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_failed_overlap;
break; break;
case METRIC_TYPE_IP4_FLOW_FAIL_OVERLAP: case METRIC_TYPE_IP4_DEFRAGS_FAILED_TOO_MANY_FRAG:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_fail_overlap; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_failed_too_many_frag;
break; break;
case METRIC_TYPE_IP4_FLOW_FAIL_MANY_FRAG: case METRIC_TYPE_IP4_FRAGS:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_fail_many_frag; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags;
break; break;
case METRIC_TYPE_IP4_FLOW_FAIL_INVALID_LENGTH: case METRIC_TYPE_IP4_FRAGS_FREED:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_fail_invalid_length; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_freed;
break; break;
case METRIC_TYPE_IP4_FLOW_BYPASS_DUP_FIST_FRAG: case METRIC_TYPE_IP4_FRAGS_BUFFERED:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_bypass_dup_fist_frag; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_buffered;
break; break;
case METRIC_TYPE_IP4_FLOW_BYPASS_DUP_LAST_FRAG: case METRIC_TYPE_IP4_FRAGS_BYPASS_NO_BUFFER:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_flow_bypass_dup_last_frag; stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_bypass_no_buffer;
break;
case METRIC_TYPE_IP4_FRAGS_BYPASS_DUP_FIST_FRAG:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_bypass_dup_fist_frag;
break;
case METRIC_TYPE_IP4_FRAGS_BYPASS_DUP_LAST_FRAG:
stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_bypass_dup_last_frag;
break; break;
// ipv6 reassembly // ipv6 reassembly
case METRIC_TYPE_IP6_FLOW_FIND: case METRIC_TYPE_IP6_DEFRAGS_EXPECTED:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_find; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_expected;
break; break;
case METRIC_TYPE_IP6_FLOW_ADD: case METRIC_TYPE_IP6_DEFRAGS_SUCCEED:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_add; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_succeed;
break; break;
case METRIC_TYPE_IP6_FLOW_DEL: case METRIC_TYPE_IP6_DEFRAGS_FAILED_TIMEOUT:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_del; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_failed_timeout;
break; break;
case METRIC_TYPE_IP6_FLOW_TIMEOUT: case METRIC_TYPE_IP6_DEFRAGS_FAILED_INVALID_LENGTH:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_timeout; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_failed_invalid_length;
break; break;
case METRIC_TYPE_IP6_FLOW_FAIL_NO_SPACE: case METRIC_TYPE_IP6_DEFRAGS_FAILED_OVERLAP:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_fail_no_space; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_failed_overlap;
break; break;
case METRIC_TYPE_IP6_FLOW_FAIL_OVERLAP: case METRIC_TYPE_IP6_DEFRAGS_FAILED_TOO_MANY_FRAG:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_fail_overlap; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_failed_too_many_frag;
break; break;
case METRIC_TYPE_IP6_FLOW_FAIL_MANY_FRAG: case METRIC_TYPE_IP6_FRAGS:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_fail_many_frag; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags;
break; break;
case METRIC_TYPE_IP6_FLOW_FAIL_INVALID_LENGTH: case METRIC_TYPE_IP6_FRAGS_FREED:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_fail_invalid_length; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_freed;
break; break;
case METRIC_TYPE_IP6_FLOW_BYPASS_DUP_FIST_FRAG: case METRIC_TYPE_IP6_FRAGS_BUFFERED:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_bypass_dup_fist_frag; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_buffered;
break; break;
case METRIC_TYPE_IP6_FLOW_BYPASS_DUP_LAST_FRAG: case METRIC_TYPE_IP6_FRAGS_BYPASS_NO_BUFFER:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_flow_bypass_dup_last_frag; stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_bypass_no_buffer;
break;
case METRIC_TYPE_IP6_FRAGS_BYPASS_DUP_FIST_FRAG:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_bypass_dup_fist_frag;
break;
case METRIC_TYPE_IP6_FRAGS_BYPASS_DUP_LAST_FRAG:
stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_bypass_dup_last_frag;
break; break;
// TCP session // TCP session
case METRIC_TYPE_HISTORY_TCP_SESSIONS: case METRIC_TYPE_HISTORY_TCP_SESSIONS:

View File

@@ -78,7 +78,7 @@ struct ip_frag_hdr
uint8_t next_proto; uint8_t next_proto;
}; };
struct ip_frag_pkt struct ip_frag
{ {
void *data; // need be freed void *data; // need be freed
uint16_t len; uint16_t len;
@@ -86,7 +86,7 @@ struct ip_frag_pkt
uint16_t offset; uint16_t offset;
}; };
struct ip_flow_key struct ip_frag_key
{ {
uint64_t src_dst_addr[4]; // src and dst address (only first 8 bytes used for IPv4) uint64_t src_dst_addr[4]; // src and dst address (only first 8 bytes used for IPv4)
uint32_t src_dst_len; uint32_t src_dst_len;
@@ -94,20 +94,20 @@ struct ip_flow_key
uint8_t proto; uint8_t proto;
}; };
struct ip_flow struct ip_frag_pkt
{ {
struct struct
{ {
struct ip_flow *tqe_next; struct ip_frag_pkt *tqe_next;
struct ip_flow **tqe_prev; struct ip_frag_pkt **tqe_prev;
} lru; } lru;
struct ip_flow_key key; struct ip_frag_key key;
struct ip_frag_hdr hdr; struct ip_frag_hdr hdr;
uint64_t create_time; uint64_t create_time;
uint32_t expected_total_size; uint32_t expected_total_size;
uint32_t received_frag_size; uint32_t received_frag_size;
uint32_t next_fill_idx; uint32_t next_fill_idx;
struct ip_frag_pkt frags[IP_MAX_FRAG_NUM]; // first two entries in the frags[] array are for the last and first fragments. struct ip_frag frags[IP_MAX_FRAG_NUM]; // first two entries in the frags[] array are for the last and first fragments.
}; };
struct ip_reassembly struct ip_reassembly
@@ -128,26 +128,26 @@ struct ip_reassembly
// hash table // hash table
struct struct
{ {
struct ip_flow *tqh_first; struct ip_frag_pkt *tqh_first;
struct ip_flow **tqh_last; struct ip_frag_pkt **tqh_last;
} lru; } lru;
struct ip_flow *last; struct ip_frag_pkt *last;
struct ip_flow *table; // array of ip_flow struct ip_frag_pkt *table; // array of ip_frag_pkt
}; };
/****************************************************************************** /******************************************************************************
* utils * utils
******************************************************************************/ ******************************************************************************/
#define ip_reassembly_stat_inc(assy, filed, key) \ #define IP_REASSEMBLY_STAT_INC(stat, filed, key) \
{ \ { \
if ((key)->src_dst_len == IPV4_KEYLEN) \ if ((key)->src_dst_len == IPV4_KEYLEN) \
{ \ { \
(assy)->stat.ip4_flow_##filed++; \ (stat)->ip4_##filed++; \
} \ } \
else \ else \
{ \ { \
(assy)->stat.ip6_flow_##filed++; \ (stat)->ip6_##filed++; \
} \ } \
} }
@@ -223,10 +223,10 @@ static int check_options(const struct ip_reassembly_options *opts)
} }
/****************************************************************************** /******************************************************************************
* ip flow key * ip frag key
******************************************************************************/ ******************************************************************************/
static inline void ipv4_flow_key_hash(const struct ip_flow_key *key, uint32_t *value1, uint32_t *value2) static inline void ipv4_frag_key_hash(const struct ip_frag_key *key, uint32_t *value1, uint32_t *value2)
{ {
uint32_t v = 0; uint32_t v = 0;
const uint32_t *p = (const uint32_t *)&key->src_dst_addr; const uint32_t *p = (const uint32_t *)&key->src_dst_addr;
@@ -239,7 +239,7 @@ static inline void ipv4_flow_key_hash(const struct ip_flow_key *key, uint32_t *v
*value2 = (v << 7) + (v >> 14); *value2 = (v << 7) + (v >> 14);
} }
static inline void ipv6_flow_key_hash(const struct ip_flow_key *key, uint32_t *value1, uint32_t *value2) static inline void ipv6_frag_key_hash(const struct ip_frag_key *key, uint32_t *value1, uint32_t *value2)
{ {
uint32_t v = 0; uint32_t v = 0;
const uint32_t *p = (const uint32_t *)&key->src_dst_addr; const uint32_t *p = (const uint32_t *)&key->src_dst_addr;
@@ -258,7 +258,7 @@ static inline void ipv6_flow_key_hash(const struct ip_flow_key *key, uint32_t *v
*value2 = (v << 7) + (v >> 14); *value2 = (v << 7) + (v >> 14);
} }
static inline uint64_t ip_flow_key_cmp(const struct ip_flow_key *key1, const struct ip_flow_key *key2) static inline uint64_t ip_frag_key_cmp(const struct ip_frag_key *key1, const struct ip_frag_key *key2)
{ {
if (key1->ip_id != key2->ip_id) if (key1->ip_id != key2->ip_id)
{ {
@@ -281,12 +281,12 @@ static inline uint64_t ip_flow_key_cmp(const struct ip_flow_key *key1, const str
return 0; return 0;
} }
static inline int ip_flow_key_is_empty(const struct ip_flow_key *key) static inline int ip_frag_key_is_empty(const struct ip_frag_key *key)
{ {
return (key->src_dst_len == 0); return (key->src_dst_len == 0);
} }
static inline void ip_flow_key_zero(struct ip_flow_key *key) static inline void ip_frag_key_zero(struct ip_frag_key *key)
{ {
key->src_dst_addr[0] = 0; key->src_dst_addr[0] = 0;
key->src_dst_addr[1] = 0; key->src_dst_addr[1] = 0;
@@ -339,78 +339,100 @@ static inline void ip_frag_hdr_free(struct ip_frag_hdr *hdr)
} }
/****************************************************************************** /******************************************************************************
* ip frag pkt * ip frag
******************************************************************************/ ******************************************************************************/
static inline void ip_frag_pkt_init(struct ip_frag_pkt *frag, void *data, uint16_t len, uint16_t offset) static inline void ip_frag_init(struct ip_frag *frag, void *data, uint16_t len, uint16_t offset)
{ {
frag->data = memdup(data, len); frag->data = memdup(data, len);
frag->len = len; frag->len = len;
frag->offset = offset; frag->offset = offset;
} }
static inline void ip_frag_pkt_free(struct ip_frag_pkt *frag) static inline int ip_frag_free(struct ip_frag *frag)
{ {
int ret = -1;
if (frag) if (frag)
{ {
if (frag->data) if (frag->data)
{ {
free(frag->data); free(frag->data);
frag->data = NULL; frag->data = NULL;
ret = 0;
} }
frag->len = 0; frag->len = 0;
frag->offset = 0; frag->offset = 0;
} }
return ret;
} }
/****************************************************************************** /******************************************************************************
* ip flow * ip frag pkt
******************************************************************************/ ******************************************************************************/
static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *key, uint64_t now) static inline void ip_frag_pkt_init(struct ip_frag_pkt *frag_pkt, const struct ip_frag_key *key, uint64_t now)
{ {
static const struct ip_frag_pkt zero_frag = { static const struct ip_frag zero_frag = {
.data = NULL, .data = NULL,
.len = 0, .len = 0,
.offset = 0, .offset = 0,
}; };
flow->lru.tqe_next = NULL; frag_pkt->lru.tqe_next = NULL;
flow->lru.tqe_prev = NULL; frag_pkt->lru.tqe_prev = NULL;
flow->key = *key; frag_pkt->key = *key;
flow->create_time = now; frag_pkt->create_time = now;
flow->expected_total_size = UINT32_MAX; frag_pkt->expected_total_size = UINT32_MAX;
flow->received_frag_size = 0; frag_pkt->received_frag_size = 0;
flow->next_fill_idx = IP_MIN_FRAG_NUM;
flow->frags[IP_LAST_FRAG_IDX] = zero_frag; frag_pkt->next_fill_idx = IP_MIN_FRAG_NUM;
flow->frags[IP_FIRST_FRAG_IDX] = zero_frag; frag_pkt->frags[IP_LAST_FRAG_IDX] = zero_frag;
frag_pkt->frags[IP_FIRST_FRAG_IDX] = zero_frag;
} }
static inline void ip_flow_free(struct ip_flow *flow) static inline void ip_frag_pkt_clean(struct ip_reassembly_stat *stat, struct ip_frag_pkt *frag_pkt)
{ {
for (uint32_t i = 0; i < IP_MAX_FRAG_NUM; i++) for (uint32_t i = 0; i < IP_MAX_FRAG_NUM; i++)
{ {
struct ip_frag_pkt *frag = &flow->frags[i]; struct ip_frag *frag = &frag_pkt->frags[i];
ip_frag_pkt_free(frag); if (ip_frag_free(frag) == 0)
{
IP_REASSEMBLY_STAT_INC(stat, frags_freed, &frag_pkt->key);
}
} }
ip_flow_key_zero(&flow->key); ip_frag_key_zero(&frag_pkt->key);
ip_frag_hdr_free(&flow->hdr); ip_frag_hdr_free(&frag_pkt->hdr);
} }
static inline int ip_flow_is_ready(struct ip_flow *flow) static inline int ip_frag_pkt_is_ready(struct ip_frag_pkt *frag_pkt)
{ {
return (flow->received_frag_size == flow->expected_total_size && flow->frags[IP_FIRST_FRAG_IDX].data != NULL); return (frag_pkt->received_frag_size == frag_pkt->expected_total_size && frag_pkt->frags[IP_FIRST_FRAG_IDX].data != NULL);
}
static inline void ip_reassembly_add_frag_pkt(struct ip_reassembly *assy, struct ip_frag_pkt *frag_pkt, const struct ip_frag_key *key, uint64_t now)
{
ip_frag_pkt_init(frag_pkt, key, now);
IP_REASSEMBLY_STAT_INC(&assy->stat, defrags_expected, &frag_pkt->key);
TAILQ_INSERT_TAIL(&assy->lru, frag_pkt, lru);
assy->entry_used++;
}
static inline void ip_reassembly_del_frag_pkt(struct ip_reassembly *assy, struct ip_frag_pkt *frag_pkt)
{
TAILQ_REMOVE(&assy->lru, frag_pkt, lru);
assy->entry_used--;
ip_frag_pkt_clean(&assy->stat, frag_pkt);
} }
// return 0 : success // return 0 : success
// return -1 : failed // return -1 : failed
static inline int ip_flow_update(struct ip_reassembly *assy, static inline int ip_frag_pkt_update(struct ip_reassembly *assy,
struct ip_flow *flow, const struct packet *pkt, struct ip_frag_pkt *frag_pkt, const struct packet *pkt,
char *frag_data, uint16_t frag_len, uint16_t frag_offset, bool more_frags) char *frag_data, uint16_t frag_len, uint16_t frag_offset, bool more_frags)
{ {
uint32_t idx; uint32_t idx;
struct ip_frag_pkt *frag_pkt;
/* /*
* Internet Protocol, Version 6 (IPv6) Specification * Internet Protocol, Version 6 (IPv6) Specification
* *
@@ -424,81 +446,55 @@ static inline int ip_flow_update(struct ip_reassembly *assy,
*/ */
if (frag_offset == 0) if (frag_offset == 0)
{ {
if (flow->frags[IP_FIRST_FRAG_IDX].data != NULL) if (frag_pkt->frags[IP_FIRST_FRAG_IDX].data != NULL)
{ {
IP_REASSEMBLE_DEBUG1("duplicate first fragment bypass", &flow->key); IP_REASSEMBLE_DEBUG1("duplicate first fragment bypass", &frag_pkt->key);
ip_reassembly_stat_inc(assy, bypass_dup_fist_frag, &flow->key); IP_REASSEMBLY_STAT_INC(&assy->stat, frags_bypass_dup_fist_frag, &frag_pkt->key);
return 0; return 0;
} }
idx = IP_FIRST_FRAG_IDX; idx = IP_FIRST_FRAG_IDX;
ip_frag_hdr_init(&flow->hdr, pkt); ip_frag_hdr_init(&frag_pkt->hdr, pkt);
} }
else if (more_frags == 0) else if (more_frags == 0)
{ {
if (flow->frags[IP_LAST_FRAG_IDX].data != NULL) if (frag_pkt->frags[IP_LAST_FRAG_IDX].data != NULL)
{ {
IP_REASSEMBLE_DEBUG1("duplicate last fragment bypass", &flow->key); IP_REASSEMBLE_DEBUG1("duplicate last fragment bypass", &frag_pkt->key);
ip_reassembly_stat_inc(assy, bypass_dup_last_frag, &flow->key); IP_REASSEMBLY_STAT_INC(&assy->stat, frags_bypass_dup_last_frag, &frag_pkt->key);
return 0; return 0;
} }
idx = IP_LAST_FRAG_IDX; idx = IP_LAST_FRAG_IDX;
flow->expected_total_size = frag_offset + frag_len; frag_pkt->expected_total_size = frag_offset + frag_len;
} }
else else
{ {
if (flow->next_fill_idx >= IP_MAX_FRAG_NUM) if (frag_pkt->next_fill_idx >= IP_MAX_FRAG_NUM)
{ {
IP_REASSEMBLE_ERROR1("max number of fragment exceeded", &flow->key); IP_REASSEMBLE_ERROR1("max number of fragment exceeded", &frag_pkt->key);
ip_reassembly_stat_inc(assy, fail_many_frag, &flow->key); IP_REASSEMBLY_STAT_INC(&assy->stat, defrags_failed_too_many_frag, &frag_pkt->key);
ip_reassembly_del_frag_pkt(assy, frag_pkt);
return -1; return -1;
} }
idx = flow->next_fill_idx; idx = frag_pkt->next_fill_idx;
flow->next_fill_idx++; frag_pkt->next_fill_idx++;
} }
flow->received_frag_size += frag_len; frag_pkt->received_frag_size += frag_len;
frag_pkt = &flow->frags[idx]; struct ip_frag *frag = &frag_pkt->frags[idx];
ip_frag_pkt_init(frag_pkt, frag_data, frag_len, frag_offset); ip_frag_init(frag, frag_data, frag_len, frag_offset);
IP_REASSEMBLY_STAT_INC(&assy->stat, frags_buffered, &frag_pkt->key);
return 0; return 0;
} }
/******************************************************************************
* ip reassemble manager add/del/reuse/find/update flow
******************************************************************************/
static inline void ip_reassembly_add_flow(struct ip_reassembly *assy, struct ip_flow *flow)
{
ip_reassembly_stat_inc(assy, add, &flow->key);
TAILQ_INSERT_TAIL(&assy->lru, flow, lru);
assy->entry_used++;
}
static inline void ip_reassembly_del_flow(struct ip_reassembly *assy, struct ip_flow *flow)
{
ip_reassembly_stat_inc(assy, del, &flow->key);
TAILQ_REMOVE(&assy->lru, flow, lru);
assy->entry_used--;
}
static inline void ip_reassembly_reuse_flow(struct ip_reassembly *assy, struct ip_flow *flow, const struct ip_flow_key *key, uint64_t now)
{
ip_reassembly_del_flow(assy, flow);
ip_flow_free(flow);
ip_flow_init(flow, key, now);
ip_reassembly_add_flow(assy, flow);
}
/* /*
* if return NULL, then *free and *expired are valid * if return NULL, then *free and *expired are valid
* free : the first empty entry in the bucket * free : the first empty entry in the bucket
* expired: the first timed-out entry in the bucket * expired: the first timed-out entry in the bucket
*/ */
static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *assy, const struct ip_flow_key *key, struct ip_flow **free, struct ip_flow **expired, uint64_t now) static struct ip_frag_pkt *ip_reassembly_find_frag_pkt(struct ip_reassembly *assy, const struct ip_frag_key *key, struct ip_frag_pkt **free, struct ip_frag_pkt **expired, uint64_t now)
{ {
ip_reassembly_stat_inc(assy, find, key); if (assy->last != NULL && ip_frag_key_cmp(key, &assy->last->key) == 0)
if (assy->last != NULL && ip_flow_key_cmp(key, &assy->last->key) == 0)
{ {
return assy->last; return assy->last;
} }
@@ -507,31 +503,31 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *assy, const
uint32_t sig2 = 0; uint32_t sig2 = 0;
if (key->src_dst_len == IPV4_KEYLEN) if (key->src_dst_len == IPV4_KEYLEN)
{ {
ipv4_flow_key_hash(key, &sig1, &sig2); ipv4_frag_key_hash(key, &sig1, &sig2);
} }
else else
{ {
ipv6_flow_key_hash(key, &sig1, &sig2); ipv6_frag_key_hash(key, &sig1, &sig2);
} }
// get the bucket by hash // get the bucket by hash
struct ip_flow *p1 = IP_FRAG_TBL_POS(assy, sig1); struct ip_frag_pkt *p1 = IP_FRAG_TBL_POS(assy, sig1);
struct ip_flow *p2 = IP_FRAG_TBL_POS(assy, sig2); struct ip_frag_pkt *p2 = IP_FRAG_TBL_POS(assy, sig2);
// search in the bucket // search in the bucket
struct ip_flow *old = NULL; struct ip_frag_pkt *old = NULL;
struct ip_flow *empty = NULL; struct ip_frag_pkt *empty = NULL;
uint64_t timeout = assy->timeout; uint64_t timeout = assy->timeout;
uint32_t assoc = assy->bucket_entries; uint32_t assoc = assy->bucket_entries;
for (uint32_t i = 0; i != assoc; i++) for (uint32_t i = 0; i != assoc; i++)
{ {
if (ip_flow_key_cmp(key, &p1[i].key) == 0) if (ip_frag_key_cmp(key, &p1[i].key) == 0)
{ {
*free = NULL; *free = NULL;
*expired = NULL; *expired = NULL;
return p1 + i; return p1 + i;
} }
else if (ip_flow_key_is_empty(&p1[i].key)) else if (ip_frag_key_is_empty(&p1[i].key))
{ {
empty = (empty == NULL) ? (p1 + i) : empty; empty = (empty == NULL) ? (p1 + i) : empty;
} }
@@ -540,13 +536,13 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *assy, const
old = (old == NULL) ? (p1 + i) : old; old = (old == NULL) ? (p1 + i) : old;
} }
if (ip_flow_key_cmp(key, &p2[i].key) == 0) if (ip_frag_key_cmp(key, &p2[i].key) == 0)
{ {
*free = NULL; *free = NULL;
*expired = NULL; *expired = NULL;
return p2 + i; return p2 + i;
} }
else if (ip_flow_key_is_empty(&p2[i].key)) else if (ip_frag_key_is_empty(&p2[i].key))
{ {
empty = (empty == NULL) ? (p2 + i) : empty; empty = (empty == NULL) ? (p2 + i) : empty;
} }
@@ -561,20 +557,21 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *assy, const
return NULL; return NULL;
} }
static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *assy, const struct ip_flow_key *key, uint64_t now) static struct ip_frag_pkt *ip_reassembly_update_frag_pkt(struct ip_reassembly *assy, const struct ip_frag_key *key, uint64_t now)
{ {
struct ip_flow *flow = NULL; struct ip_frag_pkt *frag_pkt = NULL;
struct ip_flow *free = NULL; struct ip_frag_pkt *free = NULL;
struct ip_flow *expired = NULL; struct ip_frag_pkt *expired = NULL;
flow = ip_reassembly_find_flow(assy, key, &free, &expired, now); frag_pkt = ip_reassembly_find_frag_pkt(assy, key, &free, &expired, now);
if (flow == NULL) if (frag_pkt == NULL)
{ {
if (expired) if (expired)
{ {
IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key); IP_REASSEMBLE_DEBUG1("add ip frag pkt success: reuse expired entry", key);
ip_reassembly_reuse_flow(assy, expired, key, now); IP_REASSEMBLY_STAT_INC(&assy->stat, defrags_failed_timeout, key);
ip_reassembly_stat_inc(assy, timeout, key); ip_reassembly_del_frag_pkt(assy, expired);
ip_reassembly_add_frag_pkt(assy, expired, key, now);
assy->last = expired; assy->last = expired;
return expired; return expired;
@@ -582,38 +579,38 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *assy, con
if (free) if (free)
{ {
IP_REASSEMBLE_DEBUG1("add ip flow success: use free entry", key); IP_REASSEMBLE_DEBUG1("add ip frag pkt success: use free entry", key);
ip_flow_init(free, key, now); ip_reassembly_add_frag_pkt(assy, free, key, now);
ip_reassembly_add_flow(assy, free);
assy->last = free; assy->last = free;
return free; return free;
} }
// no space // no space
IP_REASSEMBLE_ERROR1("add ip flow failed: bucket full", key); IP_REASSEMBLE_ERROR1("add ip frag pkt failed: bucket full", key);
ip_reassembly_stat_inc(assy, fail_no_space, key); IP_REASSEMBLY_STAT_INC(&assy->stat, frags_bypass_no_buffer, key);
return NULL; return NULL;
} }
else else
{ {
// expired // expired
if (assy->timeout + flow->create_time <= now) if (assy->timeout + frag_pkt->create_time <= now)
{ {
IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key); IP_REASSEMBLE_DEBUG1("add ip frag pkt success: reuse expired entry", key);
ip_reassembly_reuse_flow(assy, flow, key, now); IP_REASSEMBLY_STAT_INC(&assy->stat, defrags_failed_timeout, key);
ip_reassembly_stat_inc(assy, timeout, key); ip_reassembly_del_frag_pkt(assy, frag_pkt);
ip_reassembly_add_frag_pkt(assy, frag_pkt, key, now);
assy->last = flow; assy->last = frag_pkt;
return flow; return frag_pkt;
} }
// not expired // not expired
else else
{ {
IP_REASSEMBLE_DEBUG1("find ip flow success: not expire", key); IP_REASSEMBLE_DEBUG1("find ip frag pkt success: not expire", key);
assy->last = flow; assy->last = frag_pkt;
return flow; return frag_pkt;
} }
} }
} }
@@ -622,11 +619,11 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *assy, con
* frag reassemble * frag reassemble
******************************************************************************/ ******************************************************************************/
static struct packet *ip_frag_reassemble(struct ip_reassembly *assy, struct ip_flow *flow) static struct packet *ip_frag_reassemble(struct ip_reassembly *assy, struct ip_frag_pkt *frag_pkt)
{ {
struct ip_frag_pkt *first = &flow->frags[IP_FIRST_FRAG_IDX]; struct ip_frag *first = &frag_pkt->frags[IP_FIRST_FRAG_IDX];
struct ip_frag_pkt *last = &flow->frags[IP_LAST_FRAG_IDX]; struct ip_frag *last = &frag_pkt->frags[IP_LAST_FRAG_IDX];
struct ip_frag_pkt *temp = NULL; struct ip_frag *temp = NULL;
uint32_t loop = 0; uint32_t loop = 0;
uint16_t last_offset = last->offset; uint16_t last_offset = last->offset;
@@ -635,7 +632,7 @@ static struct packet *ip_frag_reassemble(struct ip_reassembly *assy, struct ip_f
struct ip6_hdr *ip6_hdr = NULL; struct ip6_hdr *ip6_hdr = NULL;
// calculate the length of the reassembled packet // calculate the length of the reassembled packet
uint32_t packet_len = flow->expected_total_size + flow->hdr.hdr_len; uint32_t packet_len = frag_pkt->expected_total_size + frag_pkt->hdr.hdr_len;
struct packet *pkt = packet_new(packet_len); struct packet *pkt = packet_new(packet_len);
if (pkt == NULL) if (pkt == NULL)
{ {
@@ -649,7 +646,7 @@ static struct packet *ip_frag_reassemble(struct ip_reassembly *assy, struct ip_f
// copy last frag // copy last frag
if (last->len > end - ptr) if (last->len > end - ptr)
{ {
IP_REASSEMBLE_ERROR1("last frag length not match expected reassembled length", &flow->key); IP_REASSEMBLE_ERROR1("last frag length not match expected reassembled length", &frag_pkt->key);
goto error_out_invalid_length; goto error_out_invalid_length;
} }
end -= last->len; end -= last->len;
@@ -665,14 +662,14 @@ static struct packet *ip_frag_reassemble(struct ip_reassembly *assy, struct ip_f
* will use the more recently arrived copy in the data buffer and * will use the more recently arrived copy in the data buffer and
* datagram delivered. * datagram delivered.
*/ */
for (uint32_t i = flow->next_fill_idx - 1; i >= IP_MIN_FRAG_NUM; i--) for (uint32_t i = frag_pkt->next_fill_idx - 1; i >= IP_MIN_FRAG_NUM; i--)
{ {
temp = &flow->frags[i]; temp = &frag_pkt->frags[i];
if (temp->offset + temp->len == last_offset) if (temp->offset + temp->len == last_offset)
{ {
if (temp->len > end - ptr) if (temp->len > end - ptr)
{ {
IP_REASSEMBLE_ERROR1("middle frag length not match expected reassembled length", &flow->key); IP_REASSEMBLE_ERROR1("middle frag length not match expected reassembled length", &frag_pkt->key);
goto error_out_invalid_length; goto error_out_invalid_length;
} }
@@ -683,9 +680,9 @@ static struct packet *ip_frag_reassemble(struct ip_reassembly *assy, struct ip_f
} }
} }
if (loop > flow->next_fill_idx - IP_MIN_FRAG_NUM) if (loop > frag_pkt->next_fill_idx - IP_MIN_FRAG_NUM)
{ {
IP_REASSEMBLE_ERROR1("overlap appear during frag reassemble", &flow->key); IP_REASSEMBLE_ERROR1("overlap appear during frag reassemble", &frag_pkt->key);
goto error_out_overlap; goto error_out_overlap;
} }
@@ -695,55 +692,64 @@ static struct packet *ip_frag_reassemble(struct ip_reassembly *assy, struct ip_f
// copy fist fragment data // copy fist fragment data
if (first->len > end - ptr) if (first->len > end - ptr)
{ {
IP_REASSEMBLE_ERROR1("first frag length not match expected reassembled length", &flow->key); IP_REASSEMBLE_ERROR1("first frag length not match expected reassembled length", &frag_pkt->key);
goto error_out_invalid_length; goto error_out_invalid_length;
} }
end -= first->len; end -= first->len;
memcpy(end, first->data, first->len); memcpy(end, first->data, first->len);
// copy frag hdr // copy frag hdr
if (flow->hdr.hdr_len > end - ptr) if (frag_pkt->hdr.hdr_len > end - ptr)
{ {
IP_REASSEMBLE_ERROR1("packet header length not match expected reassembled length", &flow->key); IP_REASSEMBLE_ERROR1("packet header length not match expected reassembled length", &frag_pkt->key);
goto error_out_invalid_length; goto error_out_invalid_length;
} }
end -= flow->hdr.hdr_len; end -= frag_pkt->hdr.hdr_len;
memcpy(end, flow->hdr.hdr_data, flow->hdr.hdr_len); memcpy(end, frag_pkt->hdr.hdr_data, frag_pkt->hdr.hdr_len);
// assert // assert
assert(ptr == end); assert(ptr == end);
if (flow->key.src_dst_len == IPV4_KEYLEN) if (frag_pkt->key.src_dst_len == IPV4_KEYLEN)
{ {
// update ip total length & ip checksum // update ip total length & ip checksum
ip4_hdr = (struct ip *)(ptr + flow->hdr.l3_offset); ip4_hdr = (struct ip *)(ptr + frag_pkt->hdr.l3_offset);
ip4_hdr_set_total_len(ip4_hdr, packet_len - flow->hdr.l3_offset); // update total length ip4_hdr_set_total_len(ip4_hdr, packet_len - frag_pkt->hdr.l3_offset); // update total length
ip4_hdr_set_mf_flag(ip4_hdr, false); // update more fragment flag ip4_hdr_set_mf_flag(ip4_hdr, false); // update more fragment flag
ip4_hdr_set_frag_offset(ip4_hdr, 0); // update fragment offset ip4_hdr_set_frag_offset(ip4_hdr, 0); // update fragment offset
ip4_hdr->ip_sum = 0; // update checksum ip4_hdr->ip_sum = 0; // update checksum
ip4_hdr->ip_sum = checksum((const void *)ip4_hdr, flow->hdr.l3_len); ip4_hdr->ip_sum = checksum((const void *)ip4_hdr, frag_pkt->hdr.l3_len);
} }
else else
{ {
// update ipv6 payload length & next header // update ipv6 payload length & next header
ip6_hdr = (struct ip6_hdr *)(ptr + flow->hdr.l3_offset); ip6_hdr = (struct ip6_hdr *)(ptr + frag_pkt->hdr.l3_offset);
ip6_hdr_set_payload_len(ip6_hdr, flow->expected_total_size); // update payload length ip6_hdr_set_payload_len(ip6_hdr, frag_pkt->expected_total_size); // update payload length
ip6_hdr_set_next_header(ip6_hdr, flow->hdr.next_proto); // update next header ip6_hdr_set_next_header(ip6_hdr, frag_pkt->hdr.next_proto); // update next header
} }
// create a new packet // create a new packet
packet_parse(pkt, ptr, packet_len); packet_parse(pkt, ptr, packet_len);
IP_REASSEMBLY_STAT_INC(&assy->stat, defrags_succeed, &frag_pkt->key);
ip_reassembly_del_frag_pkt(assy, frag_pkt);
return pkt; return pkt;
error_out_invalid_length: error_out_invalid_length:
ip_reassembly_stat_inc(assy, fail_invalid_length, &flow->key);
packet_free(pkt); packet_free(pkt);
IP_REASSEMBLY_STAT_INC(&assy->stat, defrags_failed_invalid_length, &frag_pkt->key);
ip_reassembly_del_frag_pkt(assy, frag_pkt);
return NULL; return NULL;
error_out_overlap: error_out_overlap:
ip_reassembly_stat_inc(assy, fail_overlap, &flow->key);
packet_free(pkt); packet_free(pkt);
IP_REASSEMBLY_STAT_INC(&assy->stat, defrags_failed_overlap, &frag_pkt->key);
ip_reassembly_del_frag_pkt(assy, frag_pkt);
return NULL; return NULL;
} }
@@ -783,7 +789,7 @@ struct ip_reassembly *ip_reassembly_new(const struct ip_reassembly_options *opts
assy->entry_total = (uint32_t)entry_total; assy->entry_total = (uint32_t)entry_total;
assy->entry_mask = (assy->entry_total - 1) & ~(assy->bucket_entries - 1); assy->entry_mask = (assy->entry_total - 1) & ~(assy->bucket_entries - 1);
assy->table = (struct ip_flow *)calloc(assy->entry_total, sizeof(struct ip_flow)); assy->table = (struct ip_frag_pkt *)calloc(assy->entry_total, sizeof(struct ip_frag_pkt));
if (assy->table == NULL) if (assy->table == NULL)
{ {
IP_REASSEMBLE_ERROR("unable to allocate memory"); IP_REASSEMBLE_ERROR("unable to allocate memory");
@@ -804,7 +810,7 @@ void ip_reassembly_free(struct ip_reassembly *assy)
{ {
for (uint32_t i = 0; i < assy->entry_total; i++) for (uint32_t i = 0; i < assy->entry_total; i++)
{ {
ip_flow_free(assy->table + i); ip_frag_pkt_clean(&assy->stat, assy->table + i);
} }
free(assy->table); free(assy->table);
@@ -818,16 +824,15 @@ void ip_reassembly_free(struct ip_reassembly *assy)
void ip_reassembly_expire(struct ip_reassembly *assy, uint64_t max_free, uint64_t now) void ip_reassembly_expire(struct ip_reassembly *assy, uint64_t max_free, uint64_t now)
{ {
uint64_t count = 0; uint64_t count = 0;
struct ip_flow *flow = NULL; struct ip_frag_pkt *frag_pkt = NULL;
uint64_t timeout = assy->timeout; uint64_t timeout = assy->timeout;
TAILQ_FOREACH(flow, &assy->lru, lru) TAILQ_FOREACH(frag_pkt, &assy->lru, lru)
{ {
if (timeout + flow->create_time <= now) if (timeout + frag_pkt->create_time <= now)
{ {
IP_REASSEMBLE_DEBUG1("expire ip flow: discarding old fragmented packets", &flow->key); IP_REASSEMBLE_DEBUG1("expire ip frag pkt: discarding old fragmented packets", &frag_pkt->key);
ip_reassembly_del_flow(assy, flow); IP_REASSEMBLY_STAT_INC(&assy->stat, defrags_failed_timeout, &frag_pkt->key);
ip_reassembly_stat_inc(assy, timeout, &flow->key); ip_reassembly_del_frag_pkt(assy, frag_pkt);
ip_flow_free(flow);
count++; count++;
if (count >= max_free) if (count >= max_free)
@@ -916,7 +921,7 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *assy, const struct p
return NULL; return NULL;
} }
struct ip_flow_key key = {}; struct ip_frag_key key = {};
uint64_t src_addr = hdr->ip_src.s_addr; uint64_t src_addr = hdr->ip_src.s_addr;
uint64_t dst_addr = hdr->ip_dst.s_addr; uint64_t dst_addr = hdr->ip_dst.s_addr;
key.src_dst_addr[0] = src_addr << 32 | dst_addr; key.src_dst_addr[0] = src_addr << 32 | dst_addr;
@@ -924,8 +929,10 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *assy, const struct p
key.ip_id = ip4_hdr_get_ipid(hdr); key.ip_id = ip4_hdr_get_ipid(hdr);
key.proto = ip4_hdr_get_proto(hdr); key.proto = ip4_hdr_get_proto(hdr);
struct ip_flow *flow = ip_reassembly_update_flow(assy, &key, now); IP_REASSEMBLY_STAT_INC(&assy->stat, frags, &key);
if (flow == NULL)
struct ip_frag_pkt *frag_pkt = ip_reassembly_update_frag_pkt(assy, &key, now);
if (frag_pkt == NULL)
{ {
return NULL; return NULL;
} }
@@ -933,23 +940,17 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *assy, const struct p
char *frag_data = (char *)layer->pld_ptr; char *frag_data = (char *)layer->pld_ptr;
bool more_frags = ip4_hdr_get_mf_flag(hdr); bool more_frags = ip4_hdr_get_mf_flag(hdr);
uint16_t frag_offset = ip4_hdr_get_frag_offset(hdr); uint16_t frag_offset = ip4_hdr_get_frag_offset(hdr);
if (ip_flow_update(assy, flow, pkt, frag_data, frag_len, frag_offset, more_frags) != 0) if (ip_frag_pkt_update(assy, frag_pkt, pkt, frag_data, frag_len, frag_offset, more_frags) != 0)
{
ip_reassembly_del_flow(assy, flow);
ip_flow_free(flow);
return NULL;
}
if (!ip_flow_is_ready(flow))
{ {
return NULL; return NULL;
} }
struct packet *new_pkt = ip_frag_reassemble(assy, flow); if (!ip_frag_pkt_is_ready(frag_pkt))
ip_reassembly_del_flow(assy, flow); {
ip_flow_free(flow); return NULL;
}
return new_pkt; return ip_frag_reassemble(assy, frag_pkt);
} }
/* /*
@@ -1009,36 +1010,32 @@ struct packet *ipv6_reassembly_packet(struct ip_reassembly *assy, const struct p
return NULL; return NULL;
} }
struct ip_flow_key key = {}; struct ip_frag_key key = {};
memcpy(&key.src_dst_addr[0], hdr->ip6_src.s6_addr, 16); memcpy(&key.src_dst_addr[0], hdr->ip6_src.s6_addr, 16);
memcpy(&key.src_dst_addr[2], hdr->ip6_dst.s6_addr, 16); memcpy(&key.src_dst_addr[2], hdr->ip6_dst.s6_addr, 16);
key.src_dst_len = IPV6_KEYLEN; key.src_dst_len = IPV6_KEYLEN;
key.ip_id = ipv6_frag_get_ident(frag_hdr); key.ip_id = ipv6_frag_get_ident(frag_hdr);
key.proto = 0; // only first fragment has the upper layer protocol key.proto = 0; // only first fragment has the upper layer protocol
struct ip_flow *flow = ip_reassembly_update_flow(assy, &key, now); IP_REASSEMBLY_STAT_INC(&assy->stat, frags, &key);
if (flow == NULL)
struct ip_frag_pkt *frag_pkt = ip_reassembly_update_frag_pkt(assy, &key, now);
if (frag_pkt == NULL)
{ {
return NULL; return NULL;
} }
bool more_frags = ipv6_frag_get_more(frag_hdr); bool more_frags = ipv6_frag_get_more(frag_hdr);
uint16_t frag_offset = ipv6_frag_get_offset(frag_hdr); uint16_t frag_offset = ipv6_frag_get_offset(frag_hdr);
if (ip_flow_update(assy, flow, pkt, frag_data, frag_len, frag_offset, more_frags) != 0) if (ip_frag_pkt_update(assy, frag_pkt, pkt, frag_data, frag_len, frag_offset, more_frags) != 0)
{
ip_reassembly_del_flow(assy, flow);
ip_flow_free(flow);
return NULL;
}
if (!ip_flow_is_ready(flow))
{ {
return NULL; return NULL;
} }
struct packet *new_pkt = ip_frag_reassemble(assy, flow); if (!ip_frag_pkt_is_ready(frag_pkt))
ip_reassembly_del_flow(assy, flow); {
ip_flow_free(flow); return NULL;
}
return new_pkt; return ip_frag_reassemble(assy, frag_pkt);
} }

View File

@@ -15,31 +15,35 @@ struct ip_reassembly_options
struct ip_reassembly_stat struct ip_reassembly_stat
{ {
// IPv4 flow stat // IPv4 frag stat
uint64_t ip4_flow_find; uint64_t ip4_defrags_expected;
uint64_t ip4_flow_add; uint64_t ip4_defrags_succeed;
uint64_t ip4_flow_del; uint64_t ip4_defrags_failed_timeout;
uint64_t ip4_flow_timeout; uint64_t ip4_defrags_failed_invalid_length;
uint64_t ip4_defrags_failed_overlap;
uint64_t ip4_defrags_failed_too_many_frag;
uint64_t ip4_flow_fail_no_space; uint64_t ip4_frags;
uint64_t ip4_flow_fail_overlap; uint64_t ip4_frags_freed;
uint64_t ip4_flow_fail_many_frag; uint64_t ip4_frags_buffered;
uint64_t ip4_flow_fail_invalid_length; uint64_t ip4_frags_bypass_no_buffer;
uint64_t ip4_flow_bypass_dup_fist_frag; uint64_t ip4_frags_bypass_dup_fist_frag;
uint64_t ip4_flow_bypass_dup_last_frag; uint64_t ip4_frags_bypass_dup_last_frag;
// IPv6 flow stat // IPv6 frag stat
uint64_t ip6_flow_find; uint64_t ip6_defrags_expected;
uint64_t ip6_flow_add; uint64_t ip6_defrags_succeed;
uint64_t ip6_flow_del; uint64_t ip6_defrags_failed_timeout;
uint64_t ip6_flow_timeout; uint64_t ip6_defrags_failed_invalid_length;
uint64_t ip6_defrags_failed_overlap;
uint64_t ip6_defrags_failed_too_many_frag;
uint64_t ip6_flow_fail_no_space; uint64_t ip6_frags;
uint64_t ip6_flow_fail_overlap; uint64_t ip6_frags_freed;
uint64_t ip6_flow_fail_many_frag; uint64_t ip6_frags_buffered;
uint64_t ip6_flow_fail_invalid_length; uint64_t ip6_frags_bypass_no_buffer;
uint64_t ip6_flow_bypass_dup_fist_frag; uint64_t ip6_frags_bypass_dup_fist_frag;
uint64_t ip6_flow_bypass_dup_last_frag; uint64_t ip6_frags_bypass_dup_last_frag;
}; };
struct ip_reassembly *ip_reassembly_new(const struct ip_reassembly_options *opts); struct ip_reassembly *ip_reassembly_new(const struct ip_reassembly_options *opts);

View File

@@ -209,10 +209,10 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -221,10 +221,10 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -233,10 +233,10 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
2, 1, 1, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 2, 2, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// check packet // check packet
packet_dump_stdio(new_pkt); packet_dump_stdio(new_pkt);
@@ -304,10 +304,10 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -316,10 +316,10 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -328,10 +328,10 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
2, 1, 1, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 2, 2, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// check packet // check packet
packet_dump_stdio(new_pkt); packet_dump_stdio(new_pkt);
@@ -398,10 +398,10 @@ TEST(IPV4_REASSEMBLE, EXPIRE)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -410,10 +410,10 @@ TEST(IPV4_REASSEMBLE, EXPIRE)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -422,10 +422,10 @@ TEST(IPV4_REASSEMBLE, EXPIRE)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
2, 2, 1, 1, // ip4: find, add, del, timeout 2, 0, 1, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 1, 2, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// free packet // free packet
packet_free(new_pkt); packet_free(new_pkt);
@@ -452,10 +452,10 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -464,10 +464,10 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -476,10 +476,10 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
2, 1, 0, 0, // ip4: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 1, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 0, 1, 0, 1, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -488,10 +488,10 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
3, 1, 1, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 1, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 3, 2, 2, 0, 1, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// check packet // check packet
packet_dump_stdio(new_pkt); packet_dump_stdio(new_pkt);
@@ -559,10 +559,10 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -571,10 +571,10 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -583,10 +583,10 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
2, 1, 0, 0, // ip4: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 1, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 0, 1, 0, 0, 1, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -595,10 +595,10 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
3, 1, 1, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 1, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 3, 2, 2, 0, 0, 1, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// check packet // check packet
packet_dump_stdio(new_pkt); packet_dump_stdio(new_pkt);
@@ -665,10 +665,10 @@ TEST(IPV4_REASSEMBLE, FULL)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
char dup_frag[sizeof(frag1)] = {0}; char dup_frag[sizeof(frag1)] = {0};
memcpy(dup_frag, frag1, sizeof(frag1)); memcpy(dup_frag, frag1, sizeof(frag1));
@@ -681,10 +681,10 @@ TEST(IPV4_REASSEMBLE, FULL)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// flow2 // flow2
packet_set_ipv4_src_addr(&pkt, 2); packet_set_ipv4_src_addr(&pkt, 2);
@@ -692,10 +692,10 @@ TEST(IPV4_REASSEMBLE, FULL)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
2, 2, 0, 0, // ip4: find, add, del, timeout 2, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 0, 2, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// flow3 // flow3
packet_set_ipv4_src_addr(&pkt, 3); packet_set_ipv4_src_addr(&pkt, 3);
@@ -703,10 +703,10 @@ TEST(IPV4_REASSEMBLE, FULL)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
3, 2, 0, 0, // ip4: find, add, del, timeout 2, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
1, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 3, 0, 2, 1, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// free packet // free packet
packet_free(new_pkt); packet_free(new_pkt);

View File

@@ -620,10 +620,10 @@ TEST(IPV6_REASSEMBLE, NORMAL)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -632,10 +632,10 @@ TEST(IPV6_REASSEMBLE, NORMAL)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
1, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -644,10 +644,10 @@ TEST(IPV6_REASSEMBLE, NORMAL)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
2, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 0, 2, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag3 // frag3
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -656,10 +656,10 @@ TEST(IPV6_REASSEMBLE, NORMAL)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
3, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 3, 0, 3, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag4 // frag4
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -668,10 +668,10 @@ TEST(IPV6_REASSEMBLE, NORMAL)
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
4, 1, 1, 0, // ip6: find, add, del, timeout 1, 1, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 4, 4, 4, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// check packet // check packet
packet_dump_stdio(new_pkt); packet_dump_stdio(new_pkt);
@@ -732,10 +732,10 @@ TEST(IPV6_REASSEMBLE, EXPIRE)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -744,10 +744,10 @@ TEST(IPV6_REASSEMBLE, EXPIRE)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
1, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -756,10 +756,10 @@ TEST(IPV6_REASSEMBLE, EXPIRE)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
2, 2, 1, 1, // ip6: find, add, del, timeout 2, 0, 1, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 1, 2, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// free packet // free packet
packet_free(new_pkt); packet_free(new_pkt);
@@ -786,10 +786,10 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -798,10 +798,10 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
1, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -810,10 +810,10 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
2, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 1, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 0, 1, 0, 1, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -822,10 +822,10 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
3, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 1, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 3, 0, 2, 0, 1, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag3 // frag3
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -834,10 +834,10 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
4, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 1, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 4, 0, 3, 0, 1, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag4 // frag4
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -846,10 +846,10 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
5, 1, 1, 0, // ip6: find, add, del, timeout 1, 1, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 1, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 5, 4, 4, 0, 1, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// check packet // check packet
packet_dump_stdio(new_pkt); packet_dump_stdio(new_pkt);
@@ -911,10 +911,10 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag4 // frag4
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -923,10 +923,10 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
1, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag4 // frag4
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -935,10 +935,10 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
2, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 1); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 0, 1, 0, 0, 1); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag3 // frag3
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -947,10 +947,10 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
3, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 1); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 3, 0, 2, 0, 0, 1); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -959,10 +959,10 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
4, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 1); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 4, 0, 3, 0, 0, 1); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -971,10 +971,10 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
5, 1, 1, 0, // ip6: find, add, del, timeout 1, 1, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 1); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 5, 4, 4, 0, 0, 1); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// check packet // check packet
packet_dump_stdio(new_pkt); packet_dump_stdio(new_pkt);
@@ -1036,10 +1036,10 @@ TEST(IPV6_REASSEMBLE, FULL)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
char dup_frag[sizeof(frag1)] = {0}; char dup_frag[sizeof(frag1)] = {0};
memcpy(dup_frag, frag1, sizeof(frag1)); memcpy(dup_frag, frag1, sizeof(frag1));
@@ -1053,10 +1053,10 @@ TEST(IPV6_REASSEMBLE, FULL)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
1, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// flow2 // flow2
memset(&src_addr, 2, sizeof(src_addr)); memset(&src_addr, 2, sizeof(src_addr));
@@ -1065,10 +1065,10 @@ TEST(IPV6_REASSEMBLE, FULL)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
2, 2, 0, 0, // ip6: find, add, del, timeout 2, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 0, 2, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// flow3 // flow3
memset(&src_addr, 3, sizeof(src_addr)); memset(&src_addr, 3, sizeof(src_addr));
@@ -1077,10 +1077,10 @@ TEST(IPV6_REASSEMBLE, FULL)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
3, 2, 0, 0, // ip6: find, add, del, timeout 2, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
1, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 3, 0, 2, 1, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// free packet // free packet
packet_free(new_pkt); packet_free(new_pkt);
@@ -1106,10 +1106,10 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
EXPECT_TRUE(assy != NULL); EXPECT_TRUE(assy != NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag1 // frag1
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -1118,10 +1118,10 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
1, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 1, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag2 // frag2
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -1130,10 +1130,10 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
2, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 2, 0, 2, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag3 -- overwrite frag offset // frag3 -- overwrite frag offset
char dup_frag[sizeof(frag3)] = {0}; char dup_frag[sizeof(frag3)] = {0};
@@ -1145,10 +1145,10 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
3, 1, 0, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 3, 0, 3, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// frag4 // frag4
memset(&pkt, 0, sizeof(pkt)); memset(&pkt, 0, sizeof(pkt));
@@ -1157,10 +1157,10 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
check_stat(ip_reassembly_stat(assy), check_stat(ip_reassembly_stat(assy),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
4, 1, 1, 0, // ip6: find, add, del, timeout 1, 0, 0, 0, 1, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
0, 1, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 4, 4, 4, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
// free packet // free packet
packet_free(new_pkt); packet_free(new_pkt);

View File

@@ -40,40 +40,65 @@ static inline void packet_set_ipv6_frag_offset(struct packet *pkt, uint16_t offs
} }
static inline void check_stat(struct ip_reassembly_stat *stat, static inline void check_stat(struct ip_reassembly_stat *stat,
uint64_t ip4_flow_find, uint64_t ip4_flow_add, uint64_t ip4_flow_del, uint64_t ip4_flow_timeout, // IPv4 frag stat
uint64_t ip4_flow_fail_no_space, uint64_t ip4_flow_fail_overlap, uint64_t ip4_flow_fail_many_frag, uint64_t ip4_defrags_expected,
uint64_t ip4_flow_fail_invalid_length, uint64_t ip4_flow_bypass_dup_fist_frag, uint64_t ip4_flow_bypass_dup_last_frag, uint64_t ip4_defrags_succeed,
uint64_t ip6_flow_find, uint64_t ip6_flow_add, uint64_t ip6_flow_del, uint64_t ip6_flow_timeout, uint64_t ip4_defrags_failed_timeout,
uint64_t ip6_flow_fail_no_space, uint64_t ip6_flow_fail_overlap, uint64_t ip6_flow_fail_many_frag, uint64_t ip4_defrags_failed_invalid_length,
uint64_t ip6_flow_fail_invalid_length, uint64_t ip6_flow_bypass_dup_fist_frag, uint64_t ip6_flow_bypass_dup_last_frag) uint64_t ip4_defrags_failed_overlap,
uint64_t ip4_defrags_failed_too_many_frag,
uint64_t ip4_frags,
uint64_t ip4_frags_freed,
uint64_t ip4_frags_buffered,
uint64_t ip4_frags_bypass_no_buffer,
uint64_t ip4_frags_bypass_dup_fist_frag,
uint64_t ip4_frags_bypass_dup_last_frag,
// IPv6 frag stat
uint64_t ip6_defrags_expected,
uint64_t ip6_defrags_succeed,
uint64_t ip6_defrags_failed_timeout,
uint64_t ip6_defrags_failed_invalid_length,
uint64_t ip6_defrags_failed_overlap,
uint64_t ip6_defrags_failed_too_many_frag,
uint64_t ip6_frags,
uint64_t ip6_frags_freed,
uint64_t ip6_frags_buffered,
uint64_t ip6_frags_bypass_no_buffer,
uint64_t ip6_frags_bypass_dup_fist_frag,
uint64_t ip6_frags_bypass_dup_last_frag)
{ {
EXPECT_TRUE(stat != NULL); EXPECT_TRUE(stat != NULL);
EXPECT_TRUE(stat->ip4_flow_find == ip4_flow_find); EXPECT_TRUE(stat->ip4_defrags_expected == ip4_defrags_expected);
EXPECT_TRUE(stat->ip4_flow_add == ip4_flow_add); EXPECT_TRUE(stat->ip4_defrags_succeed == ip4_defrags_succeed);
EXPECT_TRUE(stat->ip4_flow_del == ip4_flow_del); EXPECT_TRUE(stat->ip4_defrags_failed_timeout == ip4_defrags_failed_timeout);
EXPECT_TRUE(stat->ip4_flow_timeout == ip4_flow_timeout); EXPECT_TRUE(stat->ip4_defrags_failed_invalid_length == ip4_defrags_failed_invalid_length);
EXPECT_TRUE(stat->ip4_defrags_failed_overlap == ip4_defrags_failed_overlap);
EXPECT_TRUE(stat->ip4_defrags_failed_too_many_frag == ip4_defrags_failed_too_many_frag);
EXPECT_TRUE(stat->ip4_flow_fail_no_space == ip4_flow_fail_no_space); EXPECT_TRUE(stat->ip4_frags == ip4_frags);
EXPECT_TRUE(stat->ip4_flow_fail_overlap == ip4_flow_fail_overlap); EXPECT_TRUE(stat->ip4_frags_freed == ip4_frags_freed);
EXPECT_TRUE(stat->ip4_flow_fail_many_frag == ip4_flow_fail_many_frag); EXPECT_TRUE(stat->ip4_frags_buffered == ip4_frags_buffered);
EXPECT_TRUE(stat->ip4_frags_bypass_no_buffer == ip4_frags_bypass_no_buffer);
EXPECT_TRUE(stat->ip4_frags_bypass_dup_fist_frag == ip4_frags_bypass_dup_fist_frag);
EXPECT_TRUE(stat->ip4_frags_bypass_dup_last_frag == ip4_frags_bypass_dup_last_frag);
EXPECT_TRUE(stat->ip4_flow_fail_invalid_length == ip4_flow_fail_invalid_length); EXPECT_TRUE(stat->ip6_defrags_expected == ip6_defrags_expected);
EXPECT_TRUE(stat->ip4_flow_bypass_dup_fist_frag == ip4_flow_bypass_dup_fist_frag); EXPECT_TRUE(stat->ip6_defrags_succeed == ip6_defrags_succeed);
EXPECT_TRUE(stat->ip4_flow_bypass_dup_last_frag == ip4_flow_bypass_dup_last_frag); EXPECT_TRUE(stat->ip6_defrags_failed_timeout == ip6_defrags_failed_timeout);
EXPECT_TRUE(stat->ip6_defrags_failed_invalid_length == ip6_defrags_failed_invalid_length);
EXPECT_TRUE(stat->ip6_defrags_failed_overlap == ip6_defrags_failed_overlap);
EXPECT_TRUE(stat->ip6_defrags_failed_too_many_frag == ip6_defrags_failed_too_many_frag);
EXPECT_TRUE(stat->ip6_flow_find == ip6_flow_find); EXPECT_TRUE(stat->ip6_frags == ip6_frags);
EXPECT_TRUE(stat->ip6_flow_add == ip6_flow_add); EXPECT_TRUE(stat->ip6_frags_freed == ip6_frags_freed);
EXPECT_TRUE(stat->ip6_flow_del == ip6_flow_del); EXPECT_TRUE(stat->ip6_frags_buffered == ip6_frags_buffered);
EXPECT_TRUE(stat->ip6_flow_timeout == ip6_flow_timeout); EXPECT_TRUE(stat->ip6_frags_bypass_no_buffer == ip6_frags_bypass_no_buffer);
EXPECT_TRUE(stat->ip6_frags_bypass_dup_fist_frag == ip6_frags_bypass_dup_fist_frag);
EXPECT_TRUE(stat->ip6_flow_fail_no_space == ip6_flow_fail_no_space); EXPECT_TRUE(stat->ip6_frags_bypass_dup_last_frag == ip6_frags_bypass_dup_last_frag);
EXPECT_TRUE(stat->ip6_flow_fail_overlap == ip6_flow_fail_overlap);
EXPECT_TRUE(stat->ip6_flow_fail_many_frag == ip6_flow_fail_many_frag);
EXPECT_TRUE(stat->ip6_flow_fail_invalid_length == ip6_flow_fail_invalid_length);
EXPECT_TRUE(stat->ip6_flow_bypass_dup_fist_frag == ip6_flow_bypass_dup_fist_frag);
EXPECT_TRUE(stat->ip6_flow_bypass_dup_last_frag == ip6_flow_bypass_dup_last_frag);
} }
#ifdef __cplusplus #ifdef __cplusplus