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