X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_ip_frag%2Fip_frag_internal.c;h=09b755c92db69dcb54344b56a8e2367b0b9a84a2;hb=31850d26850e59cb20cdb84a8048d9f501f3cb22;hp=2f5a4b8a1494e6d0be0d7a170d14e167c54ed603;hpb=416707812c03e799719b46993af4a6ddfe14ef6c;p=dpdk.git diff --git a/lib/librte_ip_frag/ip_frag_internal.c b/lib/librte_ip_frag/ip_frag_internal.c index 2f5a4b8a14..09b755c92d 100644 --- a/lib/librte_ip_frag/ip_frag_internal.c +++ b/lib/librte_ip_frag/ip_frag_internal.c @@ -32,15 +32,10 @@ */ #include -#include -#include #include -#ifdef RTE_MACHINE_CPUFLAG_SSE4_2 #include -#endif /* RTE_MACHINE_CPUFLAG_SSE4_2 */ -#include "rte_ip_frag.h" #include "ip_frag_common.h" #define PRIME_VALUE 0xeaad8405 @@ -57,7 +52,7 @@ /* local frag table helper functions */ static inline void ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr, - struct rte_ip_frag_pkt *fp) + struct ip_frag_pkt *fp) { ip_frag_free(fp, dr); ip_frag_key_invalidate(&fp->key); @@ -67,7 +62,7 @@ ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr, } static inline void -ip_frag_tbl_add(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_pkt *fp, +ip_frag_tbl_add(struct rte_ip_frag_tbl *tbl, struct ip_frag_pkt *fp, const struct ip_frag_key *key, uint64_t tms) { fp->key = key[0]; @@ -79,7 +74,7 @@ ip_frag_tbl_add(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_pkt *fp, static inline void ip_frag_tbl_reuse(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr, - struct rte_ip_frag_pkt *fp, uint64_t tms) + struct ip_frag_pkt *fp, uint64_t tms) { ip_frag_free(fp, dr); ip_frag_reset(fp, tms); @@ -97,21 +92,50 @@ ipv4_frag_hash(const struct ip_frag_key *key, uint32_t *v1, uint32_t *v2) p = (const uint32_t *)&key->src_dst; -#ifdef RTE_MACHINE_CPUFLAG_SSE4_2 +#ifdef RTE_ARCH_X86 v = rte_hash_crc_4byte(p[0], PRIME_VALUE); v = rte_hash_crc_4byte(p[1], v); v = rte_hash_crc_4byte(key->id, v); #else v = rte_jhash_3words(p[0], p[1], key->id, PRIME_VALUE); -#endif /* RTE_MACHINE_CPUFLAG_SSE4_2 */ +#endif /* RTE_ARCH_X86 */ + + *v1 = v; + *v2 = (v << 7) + (v >> 14); +} + +static inline void +ipv6_frag_hash(const struct ip_frag_key *key, uint32_t *v1, uint32_t *v2) +{ + uint32_t v; + const uint32_t *p; + + p = (const uint32_t *) &key->src_dst; + +#ifdef RTE_ARCH_X86 + v = rte_hash_crc_4byte(p[0], PRIME_VALUE); + v = rte_hash_crc_4byte(p[1], v); + v = rte_hash_crc_4byte(p[2], v); + v = rte_hash_crc_4byte(p[3], v); + v = rte_hash_crc_4byte(p[4], v); + v = rte_hash_crc_4byte(p[5], v); + v = rte_hash_crc_4byte(p[6], v); + v = rte_hash_crc_4byte(p[7], v); + v = rte_hash_crc_4byte(key->id, v); +#else + + v = rte_jhash_3words(p[0], p[1], p[2], PRIME_VALUE); + v = rte_jhash_3words(p[3], p[4], p[5], v); + v = rte_jhash_3words(p[6], p[7], key->id, v); +#endif /* RTE_ARCH_X86 */ *v1 = v; *v2 = (v << 7) + (v >> 14); } struct rte_mbuf * -ip_frag_process(struct rte_ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr, +ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb, uint16_t ofs, uint16_t len, uint16_t more_frags) { uint32_t idx; @@ -142,25 +166,39 @@ ip_frag_process(struct rte_ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr, if (idx >= sizeof (fp->frags) / sizeof (fp->frags[0])) { /* report an error. */ - IP_FRAG_LOG(DEBUG, "%s:%d invalid fragmented packet:\n" - "ipv4_frag_pkt: %p, key: <%" PRIx64 ", %#x>, " - "total_size: %u, frag_size: %u, last_idx: %u\n" - "first fragment: ofs: %u, len: %u\n" - "last fragment: ofs: %u, len: %u\n\n", - __func__, __LINE__, - fp, fp->key.src_dst[0], fp->key.id, - fp->total_size, fp->frag_size, fp->last_idx, - fp->frags[IP_FIRST_FRAG_IDX].ofs, - fp->frags[IP_FIRST_FRAG_IDX].len, - fp->frags[IP_LAST_FRAG_IDX].ofs, - fp->frags[IP_LAST_FRAG_IDX].len); + if (fp->key.key_len == IPV4_KEYLEN) + IP_FRAG_LOG(DEBUG, "%s:%d invalid fragmented packet:\n" + "ipv4_frag_pkt: %p, key: <%" PRIx64 ", %#x>, " + "total_size: %u, frag_size: %u, last_idx: %u\n" + "first fragment: ofs: %u, len: %u\n" + "last fragment: ofs: %u, len: %u\n\n", + __func__, __LINE__, + fp, fp->key.src_dst[0], fp->key.id, + fp->total_size, fp->frag_size, fp->last_idx, + fp->frags[IP_FIRST_FRAG_IDX].ofs, + fp->frags[IP_FIRST_FRAG_IDX].len, + fp->frags[IP_LAST_FRAG_IDX].ofs, + fp->frags[IP_LAST_FRAG_IDX].len); + else + IP_FRAG_LOG(DEBUG, "%s:%d invalid fragmented packet:\n" + "ipv4_frag_pkt: %p, key: <" IPv6_KEY_BYTES_FMT ", %#x>, " + "total_size: %u, frag_size: %u, last_idx: %u\n" + "first fragment: ofs: %u, len: %u\n" + "last fragment: ofs: %u, len: %u\n\n", + __func__, __LINE__, + fp, IPv6_KEY_BYTES(fp->key.src_dst), fp->key.id, + fp->total_size, fp->frag_size, fp->last_idx, + fp->frags[IP_FIRST_FRAG_IDX].ofs, + fp->frags[IP_FIRST_FRAG_IDX].len, + fp->frags[IP_LAST_FRAG_IDX].ofs, + fp->frags[IP_LAST_FRAG_IDX].len); /* free all fragments, invalidate the entry. */ ip_frag_free(fp, dr); ip_frag_key_invalidate(&fp->key); IP_FRAG_MBUF2DR(dr, mb); - return (NULL); + return NULL; } fp->frags[idx].ofs = ofs; @@ -171,29 +209,47 @@ ip_frag_process(struct rte_ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr, /* not all fragments are collected yet. */ if (likely (fp->frag_size < fp->total_size)) { - return (mb); + return mb; /* if we collected all fragments, then try to reassemble. */ } else if (fp->frag_size == fp->total_size && - fp->frags[IP_FIRST_FRAG_IDX].mb != NULL) - mb = ipv4_frag_reassemble(fp); + fp->frags[IP_FIRST_FRAG_IDX].mb != NULL) { + if (fp->key.key_len == IPV4_KEYLEN) + mb = ipv4_frag_reassemble(fp); + else + mb = ipv6_frag_reassemble(fp); + } /* errorenous set of fragments. */ if (mb == NULL) { /* report an error. */ - IP_FRAG_LOG(DEBUG, "%s:%d invalid fragmented packet:\n" - "ipv4_frag_pkt: %p, key: <%" PRIx64 ", %#x>, " - "total_size: %u, frag_size: %u, last_idx: %u\n" - "first fragment: ofs: %u, len: %u\n" - "last fragment: ofs: %u, len: %u\n\n", - __func__, __LINE__, - fp, fp->key.src_dst[0], fp->key.id, - fp->total_size, fp->frag_size, fp->last_idx, - fp->frags[IP_FIRST_FRAG_IDX].ofs, - fp->frags[IP_FIRST_FRAG_IDX].len, - fp->frags[IP_LAST_FRAG_IDX].ofs, - fp->frags[IP_LAST_FRAG_IDX].len); + if (fp->key.key_len == IPV4_KEYLEN) + IP_FRAG_LOG(DEBUG, "%s:%d invalid fragmented packet:\n" + "ipv4_frag_pkt: %p, key: <%" PRIx64 ", %#x>, " + "total_size: %u, frag_size: %u, last_idx: %u\n" + "first fragment: ofs: %u, len: %u\n" + "last fragment: ofs: %u, len: %u\n\n", + __func__, __LINE__, + fp, fp->key.src_dst[0], fp->key.id, + fp->total_size, fp->frag_size, fp->last_idx, + fp->frags[IP_FIRST_FRAG_IDX].ofs, + fp->frags[IP_FIRST_FRAG_IDX].len, + fp->frags[IP_LAST_FRAG_IDX].ofs, + fp->frags[IP_LAST_FRAG_IDX].len); + else + IP_FRAG_LOG(DEBUG, "%s:%d invalid fragmented packet:\n" + "ipv4_frag_pkt: %p, key: <" IPv6_KEY_BYTES_FMT ", %#x>, " + "total_size: %u, frag_size: %u, last_idx: %u\n" + "first fragment: ofs: %u, len: %u\n" + "last fragment: ofs: %u, len: %u\n\n", + __func__, __LINE__, + fp, IPv6_KEY_BYTES(fp->key.src_dst), fp->key.id, + fp->total_size, fp->frag_size, fp->last_idx, + fp->frags[IP_FIRST_FRAG_IDX].ofs, + fp->frags[IP_FIRST_FRAG_IDX].len, + fp->frags[IP_LAST_FRAG_IDX].ofs, + fp->frags[IP_LAST_FRAG_IDX].len); /* free associated resources. */ ip_frag_free(fp, dr); @@ -201,7 +257,7 @@ ip_frag_process(struct rte_ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr, /* we are done with that entry, invalidate it. */ ip_frag_key_invalidate(&fp->key); - return (mb); + return mb; } @@ -210,11 +266,11 @@ ip_frag_process(struct rte_ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr, * If such entry is not present, then allocate a new one. * If the entry is stale, then free and reuse it. */ -struct rte_ip_frag_pkt * +struct ip_frag_pkt * ip_frag_find(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr, const struct ip_frag_key *key, uint64_t tms) { - struct rte_ip_frag_pkt *pkt, *free, *stale, *lru; + struct ip_frag_pkt *pkt, *free, *stale, *lru; uint64_t max_cycles; /* @@ -269,16 +325,16 @@ ip_frag_find(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr, IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, fail_total, (pkt == NULL)); tbl->last = pkt; - return (pkt); + return pkt; } -struct rte_ip_frag_pkt * +struct ip_frag_pkt * ip_frag_lookup(struct rte_ip_frag_tbl *tbl, const struct ip_frag_key *key, uint64_t tms, - struct rte_ip_frag_pkt **free, struct rte_ip_frag_pkt **stale) + struct ip_frag_pkt **free, struct ip_frag_pkt **stale) { - struct rte_ip_frag_pkt *p1, *p2; - struct rte_ip_frag_pkt *empty, *old; + struct ip_frag_pkt *p1, *p2; + struct ip_frag_pkt *empty, *old; uint64_t max_cycles; uint32_t i, assoc, sig1, sig2; @@ -288,43 +344,66 @@ ip_frag_lookup(struct rte_ip_frag_tbl *tbl, max_cycles = tbl->max_cycles; assoc = tbl->bucket_entries; - if (tbl->last != NULL && ip_frag_key_cmp(&tbl->last->key, key) == 0) - return (tbl->last); + if (tbl->last != NULL && ip_frag_key_cmp(key, &tbl->last->key) == 0) + return tbl->last; - ipv4_frag_hash(key, &sig1, &sig2); + /* different hashing methods for IPv4 and IPv6 */ + if (key->key_len == IPV4_KEYLEN) + ipv4_frag_hash(key, &sig1, &sig2); + else + ipv6_frag_hash(key, &sig1, &sig2); p1 = IP_FRAG_TBL_POS(tbl, sig1); p2 = IP_FRAG_TBL_POS(tbl, sig2); for (i = 0; i != assoc; i++) { - - IP_FRAG_LOG(DEBUG, "%s:%d:\n" - "tbl: %p, max_entries: %u, use_entries: %u\n" - "ipv6_frag_pkt line0: %p, index: %u from %u\n" - "key: <%" PRIx64 ", %#x>, start: %" PRIu64 "\n", - __func__, __LINE__, - tbl, tbl->max_entries, tbl->use_entries, - p1, i, assoc, - p1[i].key.src_dst[0], p1[i].key.id, p1[i].start); - - if (ip_frag_key_cmp(&p1[i].key, key) == 0) - return (p1 + i); + if (p1->key.key_len == IPV4_KEYLEN) + IP_FRAG_LOG(DEBUG, "%s:%d:\n" + "tbl: %p, max_entries: %u, use_entries: %u\n" + "ipv6_frag_pkt line0: %p, index: %u from %u\n" + "key: <%" PRIx64 ", %#x>, start: %" PRIu64 "\n", + __func__, __LINE__, + tbl, tbl->max_entries, tbl->use_entries, + p1, i, assoc, + p1[i].key.src_dst[0], p1[i].key.id, p1[i].start); + else + IP_FRAG_LOG(DEBUG, "%s:%d:\n" + "tbl: %p, max_entries: %u, use_entries: %u\n" + "ipv6_frag_pkt line0: %p, index: %u from %u\n" + "key: <" IPv6_KEY_BYTES_FMT ", %#x>, start: %" PRIu64 "\n", + __func__, __LINE__, + tbl, tbl->max_entries, tbl->use_entries, + p1, i, assoc, + IPv6_KEY_BYTES(p1[i].key.src_dst), p1[i].key.id, p1[i].start); + + if (ip_frag_key_cmp(key, &p1[i].key) == 0) + return p1 + i; else if (ip_frag_key_is_empty(&p1[i].key)) empty = (empty == NULL) ? (p1 + i) : empty; else if (max_cycles + p1[i].start < tms) old = (old == NULL) ? (p1 + i) : old; - IP_FRAG_LOG(DEBUG, "%s:%d:\n" - "tbl: %p, max_entries: %u, use_entries: %u\n" - "ipv6_frag_pkt line1: %p, index: %u from %u\n" - "key: <%" PRIx64 ", %#x>, start: %" PRIu64 "\n", - __func__, __LINE__, - tbl, tbl->max_entries, tbl->use_entries, - p2, i, assoc, - p2[i].key.src_dst[0], p2[i].key.id, p2[i].start); - - if (ip_frag_key_cmp(&p2[i].key, key) == 0) - return (p2 + i); + if (p2->key.key_len == IPV4_KEYLEN) + IP_FRAG_LOG(DEBUG, "%s:%d:\n" + "tbl: %p, max_entries: %u, use_entries: %u\n" + "ipv6_frag_pkt line1: %p, index: %u from %u\n" + "key: <%" PRIx64 ", %#x>, start: %" PRIu64 "\n", + __func__, __LINE__, + tbl, tbl->max_entries, tbl->use_entries, + p2, i, assoc, + p2[i].key.src_dst[0], p2[i].key.id, p2[i].start); + else + IP_FRAG_LOG(DEBUG, "%s:%d:\n" + "tbl: %p, max_entries: %u, use_entries: %u\n" + "ipv6_frag_pkt line1: %p, index: %u from %u\n" + "key: <" IPv6_KEY_BYTES_FMT ", %#x>, start: %" PRIu64 "\n", + __func__, __LINE__, + tbl, tbl->max_entries, tbl->use_entries, + p2, i, assoc, + IPv6_KEY_BYTES(p2[i].key.src_dst), p2[i].key.id, p2[i].start); + + if (ip_frag_key_cmp(key, &p2[i].key) == 0) + return p2 + i; else if (ip_frag_key_is_empty(&p2[i].key)) empty = (empty == NULL) ?( p2 + i) : empty; else if (max_cycles + p2[i].start < tms) @@ -333,5 +412,5 @@ ip_frag_lookup(struct rte_ip_frag_tbl *tbl, *free = empty; *stale = old; - return (NULL); + return NULL; }