1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #ifndef _IP_FRAG_COMMON_H_ 6 #define _IP_FRAG_COMMON_H_ 7 8 #include "rte_ip_frag.h" 9 #include "ip_reassembly.h" 10 11 /* logging macros. */ 12 #ifdef RTE_LIBRTE_IP_FRAG_DEBUG 13 #define IP_FRAG_LOG(lvl, fmt, args...) RTE_LOG(lvl, USER1, fmt, ##args) 14 #else 15 #define IP_FRAG_LOG(lvl, fmt, args...) do {} while(0) 16 #endif /* IP_FRAG_DEBUG */ 17 18 #define IPV4_KEYLEN 1 19 #define IPV6_KEYLEN 4 20 21 /* helper macros */ 22 #define IP_FRAG_MBUF2DR(dr, mb) ((dr)->row[(dr)->cnt++] = (mb)) 23 24 #define IPv6_KEY_BYTES(key) \ 25 (key)[0], (key)[1], (key)[2], (key)[3] 26 #define IPv6_KEY_BYTES_FMT \ 27 "%08" PRIx64 "%08" PRIx64 "%08" PRIx64 "%08" PRIx64 28 29 #ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT 30 #define IP_FRAG_TBL_STAT_UPDATE(s, f, v) ((s)->f += (v)) 31 #else 32 #define IP_FRAG_TBL_STAT_UPDATE(s, f, v) do {} while (0) 33 #endif /* IP_FRAG_TBL_STAT */ 34 35 /* internal functions declarations */ 36 struct rte_mbuf * ip_frag_process(struct ip_frag_pkt *fp, 37 struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb, 38 uint16_t ofs, uint16_t len, uint16_t more_frags); 39 40 struct ip_frag_pkt * ip_frag_find(struct rte_ip_frag_tbl *tbl, 41 struct rte_ip_frag_death_row *dr, 42 const struct ip_frag_key *key, uint64_t tms); 43 44 struct ip_frag_pkt * ip_frag_lookup(struct rte_ip_frag_tbl *tbl, 45 const struct ip_frag_key *key, uint64_t tms, 46 struct ip_frag_pkt **free, struct ip_frag_pkt **stale); 47 48 /* these functions need to be declared here as ip_frag_process relies on them */ 49 struct rte_mbuf *ipv4_frag_reassemble(struct ip_frag_pkt *fp); 50 struct rte_mbuf *ipv6_frag_reassemble(struct ip_frag_pkt *fp); 51 52 53 54 /* 55 * misc frag key functions 56 */ 57 58 /* check if key is empty */ 59 static inline int 60 ip_frag_key_is_empty(const struct ip_frag_key * key) 61 { 62 return (key->key_len == 0); 63 } 64 65 /* invalidate the key */ 66 static inline void 67 ip_frag_key_invalidate(struct ip_frag_key * key) 68 { 69 key->key_len = 0; 70 } 71 72 /* compare two keys */ 73 static inline uint64_t 74 ip_frag_key_cmp(const struct ip_frag_key * k1, const struct ip_frag_key * k2) 75 { 76 uint32_t i; 77 uint64_t val; 78 val = k1->id_key_len ^ k2->id_key_len; 79 for (i = 0; i < k1->key_len; i++) 80 val |= k1->src_dst[i] ^ k2->src_dst[i]; 81 return val; 82 } 83 84 /* 85 * misc fragment functions 86 */ 87 88 /* put fragment on death row */ 89 static inline void 90 ip_frag_free(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr) 91 { 92 uint32_t i, k; 93 94 k = dr->cnt; 95 for (i = 0; i != fp->last_idx; i++) { 96 if (fp->frags[i].mb != NULL) { 97 dr->row[k++] = fp->frags[i].mb; 98 fp->frags[i].mb = NULL; 99 } 100 } 101 102 fp->last_idx = 0; 103 dr->cnt = k; 104 } 105 106 /* delete fragment's mbufs immediately instead of using death row */ 107 static inline void 108 ip_frag_free_immediate(struct ip_frag_pkt *fp) 109 { 110 uint32_t i; 111 112 for (i = 0; i < fp->last_idx; i++) { 113 if (fp->frags[i].mb != NULL) { 114 IP_FRAG_LOG(DEBUG, "%s:%d\n" 115 "mbuf: %p, tms: %" PRIu64", key: <%" PRIx64 ", %#x>\n", 116 __func__, __LINE__, fp->frags[i].mb, fp->start, 117 fp->key.src_dst[0], fp->key.id); 118 rte_pktmbuf_free(fp->frags[i].mb); 119 fp->frags[i].mb = NULL; 120 } 121 } 122 123 fp->last_idx = 0; 124 } 125 126 /* if key is empty, mark key as in use */ 127 static inline void 128 ip_frag_inuse(struct rte_ip_frag_tbl *tbl, const struct ip_frag_pkt *fp) 129 { 130 if (ip_frag_key_is_empty(&fp->key)) { 131 TAILQ_REMOVE(&tbl->lru, fp, lru); 132 tbl->use_entries--; 133 } 134 } 135 136 /* reset the fragment */ 137 static inline void 138 ip_frag_reset(struct ip_frag_pkt *fp, uint64_t tms) 139 { 140 static const struct ip_frag zero_frag = { 141 .ofs = 0, 142 .len = 0, 143 .mb = NULL, 144 }; 145 146 fp->start = tms; 147 fp->total_size = UINT32_MAX; 148 fp->frag_size = 0; 149 fp->last_idx = IP_MIN_FRAG_NUM; 150 fp->frags[IP_LAST_FRAG_IDX] = zero_frag; 151 fp->frags[IP_FIRST_FRAG_IDX] = zero_frag; 152 } 153 154 /* local frag table helper functions */ 155 static inline void 156 ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr, 157 struct ip_frag_pkt *fp) 158 { 159 ip_frag_free(fp, dr); 160 ip_frag_key_invalidate(&fp->key); 161 TAILQ_REMOVE(&tbl->lru, fp, lru); 162 tbl->use_entries--; 163 IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, del_num, 1); 164 } 165 166 #endif /* _IP_FRAG_COMMON_H_ */ 167