xref: /dpdk/lib/gro/gro_tcp6.h (revision 7917b0d38e92e8b9ec5a870415b791420e10f11a)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2023 Intel Corporation
3  */
4 
5 #ifndef _GRO_TCP6_H_
6 #define _GRO_TCP6_H_
7 
8 #include "gro_tcp.h"
9 
10 #define GRO_TCP6_TBL_MAX_ITEM_NUM (1024UL * 1024UL)
11 
12 /* Header fields representing a TCP/IPv6 flow */
13 struct tcp6_flow_key {
14 	struct cmn_tcp_key cmn_key;
15 	uint8_t  src_addr[16];
16 	uint8_t  dst_addr[16];
17 	rte_be32_t vtc_flow;
18 };
19 
20 struct gro_tcp6_flow {
21 	struct tcp6_flow_key key;
22 	/*
23 	 * The index of the first packet in the flow.
24 	 * INVALID_ARRAY_INDEX indicates an empty flow.
25 	 */
26 	uint32_t start_index;
27 };
28 
29 /*
30  * TCP/IPv6 reassembly table structure.
31  */
32 struct gro_tcp6_tbl {
33 	/* item array */
34 	struct gro_tcp_item *items;
35 	/* flow array */
36 	struct gro_tcp6_flow *flows;
37 	/* current item number */
38 	uint32_t item_num;
39 	/* current flow num */
40 	uint32_t flow_num;
41 	/* item array size */
42 	uint32_t max_item_num;
43 	/* flow array size */
44 	uint32_t max_flow_num;
45 };
46 
47 /**
48  * This function creates a TCP/IPv6 reassembly table.
49  *
50  * @param socket_id
51  *  Socket index for allocating the TCP/IPv6 reassemble table
52  * @param max_flow_num
53  *  The maximum number of flows in the TCP/IPv6 GRO table
54  * @param max_item_per_flow
55  *  The maximum number of packets per flow
56  *
57  * @return
58  *  - Return the table pointer on success.
59  *  - Return NULL on failure.
60  */
61 void *gro_tcp6_tbl_create(uint16_t socket_id,
62 		uint16_t max_flow_num,
63 		uint16_t max_item_per_flow);
64 
65 /**
66  * This function destroys a TCP/IPv6 reassembly table.
67  *
68  * @param tbl
69  *  Pointer pointing to the TCP/IPv6 reassembly table.
70  */
71 void gro_tcp6_tbl_destroy(void *tbl);
72 
73 /**
74  * This function merges a TCP/IPv6 packet. It doesn't process the packet,
75  * which has SYN, FIN, RST, PSH, CWR, ECE or URG set, or doesn't have
76  * payload.
77  *
78  * This function doesn't check if the packet has correct checksums and
79  * doesn't re-calculate checksums for the merged packet. Additionally,
80  * it assumes the packets are complete (i.e., MF==0 && frag_off==0),
81  * when IP fragmentation is possible (i.e., DF==0). It returns the
82  * packet, if the packet has invalid parameters (e.g. SYN bit is set)
83  * or there is no available space in the table.
84  *
85  * @param pkt
86  *  Packet to reassemble
87  * @param tbl
88  *  Pointer pointing to the TCP/IPv6 reassembly table
89  * @start_time
90  *  The time when the packet is inserted into the table
91  *
92  * @return
93  *  - Return a positive value if the packet is merged.
94  *  - Return zero if the packet isn't merged but stored in the table.
95  *  - Return a negative value for invalid parameters or no available
96  *    space in the table.
97  */
98 int32_t gro_tcp6_reassemble(struct rte_mbuf *pkt,
99 		struct gro_tcp6_tbl *tbl,
100 		uint64_t start_time);
101 
102 /**
103  * This function flushes timeout packets in a TCP/IPv6 reassembly table,
104  * and without updating checksums.
105  *
106  * @param tbl
107  *  TCP/IPv6 reassembly table pointer
108  * @param flush_timestamp
109  *  Flush packets which are inserted into the table before or at the
110  *  flush_timestamp.
111  * @param out
112  *  Pointer array used to keep flushed packets
113  * @param nb_out
114  *  The element number in 'out'. It also determines the maximum number of
115  *  packets that can be flushed finally.
116  *
117  * @return
118  *  The number of flushed packets
119  */
120 uint16_t gro_tcp6_tbl_timeout_flush(struct gro_tcp6_tbl *tbl,
121 		uint64_t flush_timestamp,
122 		struct rte_mbuf **out,
123 		uint16_t nb_out);
124 
125 /**
126  * This function returns the number of the packets in a TCP/IPv6
127  * reassembly table.
128  *
129  * @param tbl
130  *  TCP/IPv6 reassembly table pointer
131  *
132  * @return
133  *  The number of packets in the table
134  */
135 uint32_t gro_tcp6_tbl_pkt_count(void *tbl);
136 
137 /*
138  * Check if two TCP/IPv6 packets belong to the same flow.
139  */
140 static inline int
141 is_same_tcp6_flow(struct tcp6_flow_key *k1, struct tcp6_flow_key *k2)
142 {
143 	rte_be32_t vtc_flow_diff;
144 
145 	if (memcmp(&k1->src_addr, &k2->src_addr, 16))
146 		return 0;
147 	if (memcmp(&k1->dst_addr, &k2->dst_addr, 16))
148 		return 0;
149 	/*
150 	 * IP version (4) Traffic Class (8) Flow Label (20)
151 	 * All fields except Traffic class should be same
152 	 */
153 	vtc_flow_diff = (k1->vtc_flow ^ k2->vtc_flow);
154 	if (vtc_flow_diff & htonl(0xF00FFFFF))
155 		return 0;
156 
157 	return is_same_common_tcp_key(&k1->cmn_key, &k2->cmn_key);
158 }
159 
160 #endif
161