xref: /dpdk/lib/ip_frag/ip_reassembly.h (revision 3401a4afbb54a1b897551847a3e16c36afdf707a)
1060ef29dSKonstantin Ananyev /* SPDX-License-Identifier: BSD-3-Clause
2060ef29dSKonstantin Ananyev  * Copyright(c) 2010-2021 Intel Corporation
3060ef29dSKonstantin Ananyev  */
4060ef29dSKonstantin Ananyev 
5060ef29dSKonstantin Ananyev #ifndef _IP_REASSEMBLY_H_
6060ef29dSKonstantin Ananyev #define _IP_REASSEMBLY_H_
7060ef29dSKonstantin Ananyev 
8060ef29dSKonstantin Ananyev /*
9060ef29dSKonstantin Ananyev  * IP Fragmentation and Reassembly
10060ef29dSKonstantin Ananyev  * Implementation of IP packet fragmentation and reassembly.
11060ef29dSKonstantin Ananyev  */
12060ef29dSKonstantin Ananyev 
13060ef29dSKonstantin Ananyev #include <rte_ip_frag.h>
14060ef29dSKonstantin Ananyev 
15060ef29dSKonstantin Ananyev enum {
16060ef29dSKonstantin Ananyev 	IP_LAST_FRAG_IDX,    /* index of last fragment */
17060ef29dSKonstantin Ananyev 	IP_FIRST_FRAG_IDX,   /* index of first fragment */
18060ef29dSKonstantin Ananyev 	IP_MIN_FRAG_NUM,     /* minimum number of fragments */
19060ef29dSKonstantin Ananyev 	IP_MAX_FRAG_NUM = RTE_LIBRTE_IP_FRAG_MAX_FRAG,
20060ef29dSKonstantin Ananyev 	/* maximum number of fragments per packet */
21060ef29dSKonstantin Ananyev };
22060ef29dSKonstantin Ananyev 
23060ef29dSKonstantin Ananyev /* fragmented mbuf */
24060ef29dSKonstantin Ananyev struct ip_frag {
25060ef29dSKonstantin Ananyev 	uint16_t ofs;        /* offset into the packet */
26060ef29dSKonstantin Ananyev 	uint16_t len;        /* length of fragment */
27060ef29dSKonstantin Ananyev 	struct rte_mbuf *mb; /* fragment mbuf */
28060ef29dSKonstantin Ananyev };
29060ef29dSKonstantin Ananyev 
30060ef29dSKonstantin Ananyev /*
31060ef29dSKonstantin Ananyev  * key: <src addr, dst_addr, id> to uniquely identify fragmented datagram.
32060ef29dSKonstantin Ananyev  */
33060ef29dSKonstantin Ananyev struct ip_frag_key {
34060ef29dSKonstantin Ananyev 	uint64_t src_dst[4];
35060ef29dSKonstantin Ananyev 	/* src and dst address, only first 8 bytes used for IPv4 */
36060ef29dSKonstantin Ananyev 	union {
37060ef29dSKonstantin Ananyev 		uint64_t id_key_len; /* combined for easy fetch */
38060ef29dSKonstantin Ananyev 		__extension__
39060ef29dSKonstantin Ananyev 		struct {
40060ef29dSKonstantin Ananyev 			uint32_t id;      /* packet id */
41060ef29dSKonstantin Ananyev 			uint32_t key_len; /* src/dst key length */
42060ef29dSKonstantin Ananyev 		};
43060ef29dSKonstantin Ananyev 	};
44060ef29dSKonstantin Ananyev };
45060ef29dSKonstantin Ananyev 
46060ef29dSKonstantin Ananyev /*
47060ef29dSKonstantin Ananyev  * Fragmented packet to reassemble.
48060ef29dSKonstantin Ananyev  * First two entries in the frags[] array are for the last and first fragments.
49060ef29dSKonstantin Ananyev  */
50c6552d9aSTyler Retzlaff struct __rte_cache_aligned ip_frag_pkt {
51060ef29dSKonstantin Ananyev 	RTE_TAILQ_ENTRY(ip_frag_pkt) lru;      /* LRU list */
52060ef29dSKonstantin Ananyev 	struct ip_frag_key key;                /* fragmentation key */
53060ef29dSKonstantin Ananyev 	uint64_t start;                        /* creation timestamp */
54060ef29dSKonstantin Ananyev 	uint32_t total_size;                   /* expected reassembled size */
55060ef29dSKonstantin Ananyev 	uint32_t frag_size;                    /* size of fragments received */
56060ef29dSKonstantin Ananyev 	uint32_t last_idx;                     /* index of next entry to fill */
57060ef29dSKonstantin Ananyev 	struct ip_frag frags[IP_MAX_FRAG_NUM]; /* fragments */
58c6552d9aSTyler Retzlaff };
59060ef29dSKonstantin Ananyev 
60060ef29dSKonstantin Ananyev  /* fragments tailq */
61060ef29dSKonstantin Ananyev RTE_TAILQ_HEAD(ip_pkt_list, ip_frag_pkt);
62060ef29dSKonstantin Ananyev 
63060ef29dSKonstantin Ananyev /* fragmentation table statistics */
64c6552d9aSTyler Retzlaff struct __rte_cache_aligned ip_frag_tbl_stat {
65060ef29dSKonstantin Ananyev 	uint64_t find_num;     /* total # of find/insert attempts. */
66060ef29dSKonstantin Ananyev 	uint64_t add_num;      /* # of add ops. */
67060ef29dSKonstantin Ananyev 	uint64_t del_num;      /* # of del ops. */
68060ef29dSKonstantin Ananyev 	uint64_t reuse_num;    /* # of reuse (del/add) ops. */
69060ef29dSKonstantin Ananyev 	uint64_t fail_total;   /* total # of add failures. */
70060ef29dSKonstantin Ananyev 	uint64_t fail_nospace; /* # of 'no space' add failures. */
71c6552d9aSTyler Retzlaff };
72060ef29dSKonstantin Ananyev 
73060ef29dSKonstantin Ananyev /* fragmentation table */
74060ef29dSKonstantin Ananyev struct rte_ip_frag_tbl {
75060ef29dSKonstantin Ananyev 	uint64_t max_cycles;     /* ttl for table entries. */
76060ef29dSKonstantin Ananyev 	uint32_t entry_mask;     /* hash value mask. */
77060ef29dSKonstantin Ananyev 	uint32_t max_entries;    /* max entries allowed. */
78060ef29dSKonstantin Ananyev 	uint32_t use_entries;    /* entries in use. */
79060ef29dSKonstantin Ananyev 	uint32_t bucket_entries; /* hash associativity. */
80060ef29dSKonstantin Ananyev 	uint32_t nb_entries;     /* total size of the table. */
81060ef29dSKonstantin Ananyev 	uint32_t nb_buckets;     /* num of associativity lines. */
82060ef29dSKonstantin Ananyev 	struct ip_frag_pkt *last;     /* last used entry. */
83060ef29dSKonstantin Ananyev 	struct ip_pkt_list lru;       /* LRU list for table entries. */
84060ef29dSKonstantin Ananyev 	struct ip_frag_tbl_stat stat; /* statistics counters. */
85*3401a4afSDavid Marchand 	struct ip_frag_pkt pkt[]; /* hash table. */
86060ef29dSKonstantin Ananyev };
87060ef29dSKonstantin Ananyev 
88060ef29dSKonstantin Ananyev #endif /* _IP_REASSEMBLY_H_ */
89