xref: /dpdk/lib/gro/gro_tcp6.h (revision 41d71aeb56694f06d60f0de20e5ac2d718ea5328)
174080d7dSKumara Parameshwaran /* SPDX-License-Identifier: BSD-3-Clause
274080d7dSKumara Parameshwaran  * Copyright(c) 2023 Intel Corporation
374080d7dSKumara Parameshwaran  */
474080d7dSKumara Parameshwaran 
574080d7dSKumara Parameshwaran #ifndef _GRO_TCP6_H_
674080d7dSKumara Parameshwaran #define _GRO_TCP6_H_
774080d7dSKumara Parameshwaran 
8*41d71aebSRobin Jarry #include <rte_ip6.h>
9*41d71aebSRobin Jarry 
1074080d7dSKumara Parameshwaran #include "gro_tcp.h"
1174080d7dSKumara Parameshwaran 
1274080d7dSKumara Parameshwaran #define GRO_TCP6_TBL_MAX_ITEM_NUM (1024UL * 1024UL)
1374080d7dSKumara Parameshwaran 
1474080d7dSKumara Parameshwaran /* Header fields representing a TCP/IPv6 flow */
1574080d7dSKumara Parameshwaran struct tcp6_flow_key {
1674080d7dSKumara Parameshwaran 	struct cmn_tcp_key cmn_key;
17*41d71aebSRobin Jarry 	struct rte_ipv6_addr src_addr;
18*41d71aebSRobin Jarry 	struct rte_ipv6_addr dst_addr;
1974080d7dSKumara Parameshwaran 	rte_be32_t vtc_flow;
2074080d7dSKumara Parameshwaran };
2174080d7dSKumara Parameshwaran 
2274080d7dSKumara Parameshwaran struct gro_tcp6_flow {
2374080d7dSKumara Parameshwaran 	struct tcp6_flow_key key;
2474080d7dSKumara Parameshwaran 	/*
2574080d7dSKumara Parameshwaran 	 * The index of the first packet in the flow.
2674080d7dSKumara Parameshwaran 	 * INVALID_ARRAY_INDEX indicates an empty flow.
2774080d7dSKumara Parameshwaran 	 */
2874080d7dSKumara Parameshwaran 	uint32_t start_index;
2974080d7dSKumara Parameshwaran };
3074080d7dSKumara Parameshwaran 
3174080d7dSKumara Parameshwaran /*
3274080d7dSKumara Parameshwaran  * TCP/IPv6 reassembly table structure.
3374080d7dSKumara Parameshwaran  */
3474080d7dSKumara Parameshwaran struct gro_tcp6_tbl {
3574080d7dSKumara Parameshwaran 	/* item array */
3674080d7dSKumara Parameshwaran 	struct gro_tcp_item *items;
3774080d7dSKumara Parameshwaran 	/* flow array */
3874080d7dSKumara Parameshwaran 	struct gro_tcp6_flow *flows;
3974080d7dSKumara Parameshwaran 	/* current item number */
4074080d7dSKumara Parameshwaran 	uint32_t item_num;
4174080d7dSKumara Parameshwaran 	/* current flow num */
4274080d7dSKumara Parameshwaran 	uint32_t flow_num;
4374080d7dSKumara Parameshwaran 	/* item array size */
4474080d7dSKumara Parameshwaran 	uint32_t max_item_num;
4574080d7dSKumara Parameshwaran 	/* flow array size */
4674080d7dSKumara Parameshwaran 	uint32_t max_flow_num;
4774080d7dSKumara Parameshwaran };
4874080d7dSKumara Parameshwaran 
4974080d7dSKumara Parameshwaran /**
5074080d7dSKumara Parameshwaran  * This function creates a TCP/IPv6 reassembly table.
5174080d7dSKumara Parameshwaran  *
5274080d7dSKumara Parameshwaran  * @param socket_id
5374080d7dSKumara Parameshwaran  *  Socket index for allocating the TCP/IPv6 reassemble table
5474080d7dSKumara Parameshwaran  * @param max_flow_num
5574080d7dSKumara Parameshwaran  *  The maximum number of flows in the TCP/IPv6 GRO table
5674080d7dSKumara Parameshwaran  * @param max_item_per_flow
5774080d7dSKumara Parameshwaran  *  The maximum number of packets per flow
5874080d7dSKumara Parameshwaran  *
5974080d7dSKumara Parameshwaran  * @return
6074080d7dSKumara Parameshwaran  *  - Return the table pointer on success.
6174080d7dSKumara Parameshwaran  *  - Return NULL on failure.
6274080d7dSKumara Parameshwaran  */
6374080d7dSKumara Parameshwaran void *gro_tcp6_tbl_create(uint16_t socket_id,
6474080d7dSKumara Parameshwaran 		uint16_t max_flow_num,
6574080d7dSKumara Parameshwaran 		uint16_t max_item_per_flow);
6674080d7dSKumara Parameshwaran 
6774080d7dSKumara Parameshwaran /**
6874080d7dSKumara Parameshwaran  * This function destroys a TCP/IPv6 reassembly table.
6974080d7dSKumara Parameshwaran  *
7074080d7dSKumara Parameshwaran  * @param tbl
7174080d7dSKumara Parameshwaran  *  Pointer pointing to the TCP/IPv6 reassembly table.
7274080d7dSKumara Parameshwaran  */
7374080d7dSKumara Parameshwaran void gro_tcp6_tbl_destroy(void *tbl);
7474080d7dSKumara Parameshwaran 
7574080d7dSKumara Parameshwaran /**
7674080d7dSKumara Parameshwaran  * This function merges a TCP/IPv6 packet. It doesn't process the packet,
7774080d7dSKumara Parameshwaran  * which has SYN, FIN, RST, PSH, CWR, ECE or URG set, or doesn't have
7874080d7dSKumara Parameshwaran  * payload.
7974080d7dSKumara Parameshwaran  *
8074080d7dSKumara Parameshwaran  * This function doesn't check if the packet has correct checksums and
8174080d7dSKumara Parameshwaran  * doesn't re-calculate checksums for the merged packet. Additionally,
8274080d7dSKumara Parameshwaran  * it assumes the packets are complete (i.e., MF==0 && frag_off==0),
8374080d7dSKumara Parameshwaran  * when IP fragmentation is possible (i.e., DF==0). It returns the
8474080d7dSKumara Parameshwaran  * packet, if the packet has invalid parameters (e.g. SYN bit is set)
8574080d7dSKumara Parameshwaran  * or there is no available space in the table.
8674080d7dSKumara Parameshwaran  *
8774080d7dSKumara Parameshwaran  * @param pkt
8874080d7dSKumara Parameshwaran  *  Packet to reassemble
8974080d7dSKumara Parameshwaran  * @param tbl
9074080d7dSKumara Parameshwaran  *  Pointer pointing to the TCP/IPv6 reassembly table
9174080d7dSKumara Parameshwaran  * @start_time
9274080d7dSKumara Parameshwaran  *  The time when the packet is inserted into the table
9374080d7dSKumara Parameshwaran  *
9474080d7dSKumara Parameshwaran  * @return
9574080d7dSKumara Parameshwaran  *  - Return a positive value if the packet is merged.
9674080d7dSKumara Parameshwaran  *  - Return zero if the packet isn't merged but stored in the table.
9774080d7dSKumara Parameshwaran  *  - Return a negative value for invalid parameters or no available
9874080d7dSKumara Parameshwaran  *    space in the table.
9974080d7dSKumara Parameshwaran  */
10074080d7dSKumara Parameshwaran int32_t gro_tcp6_reassemble(struct rte_mbuf *pkt,
10174080d7dSKumara Parameshwaran 		struct gro_tcp6_tbl *tbl,
10274080d7dSKumara Parameshwaran 		uint64_t start_time);
10374080d7dSKumara Parameshwaran 
10474080d7dSKumara Parameshwaran /**
10574080d7dSKumara Parameshwaran  * This function flushes timeout packets in a TCP/IPv6 reassembly table,
10674080d7dSKumara Parameshwaran  * and without updating checksums.
10774080d7dSKumara Parameshwaran  *
10874080d7dSKumara Parameshwaran  * @param tbl
10974080d7dSKumara Parameshwaran  *  TCP/IPv6 reassembly table pointer
11074080d7dSKumara Parameshwaran  * @param flush_timestamp
11174080d7dSKumara Parameshwaran  *  Flush packets which are inserted into the table before or at the
11274080d7dSKumara Parameshwaran  *  flush_timestamp.
11374080d7dSKumara Parameshwaran  * @param out
11474080d7dSKumara Parameshwaran  *  Pointer array used to keep flushed packets
11574080d7dSKumara Parameshwaran  * @param nb_out
11674080d7dSKumara Parameshwaran  *  The element number in 'out'. It also determines the maximum number of
11774080d7dSKumara Parameshwaran  *  packets that can be flushed finally.
11874080d7dSKumara Parameshwaran  *
11974080d7dSKumara Parameshwaran  * @return
12074080d7dSKumara Parameshwaran  *  The number of flushed packets
12174080d7dSKumara Parameshwaran  */
12274080d7dSKumara Parameshwaran uint16_t gro_tcp6_tbl_timeout_flush(struct gro_tcp6_tbl *tbl,
12374080d7dSKumara Parameshwaran 		uint64_t flush_timestamp,
12474080d7dSKumara Parameshwaran 		struct rte_mbuf **out,
12574080d7dSKumara Parameshwaran 		uint16_t nb_out);
12674080d7dSKumara Parameshwaran 
12774080d7dSKumara Parameshwaran /**
12874080d7dSKumara Parameshwaran  * This function returns the number of the packets in a TCP/IPv6
12974080d7dSKumara Parameshwaran  * reassembly table.
13074080d7dSKumara Parameshwaran  *
13174080d7dSKumara Parameshwaran  * @param tbl
13274080d7dSKumara Parameshwaran  *  TCP/IPv6 reassembly table pointer
13374080d7dSKumara Parameshwaran  *
13474080d7dSKumara Parameshwaran  * @return
13574080d7dSKumara Parameshwaran  *  The number of packets in the table
13674080d7dSKumara Parameshwaran  */
13774080d7dSKumara Parameshwaran uint32_t gro_tcp6_tbl_pkt_count(void *tbl);
13874080d7dSKumara Parameshwaran 
13974080d7dSKumara Parameshwaran /*
14074080d7dSKumara Parameshwaran  * Check if two TCP/IPv6 packets belong to the same flow.
14174080d7dSKumara Parameshwaran  */
14274080d7dSKumara Parameshwaran static inline int
14374080d7dSKumara Parameshwaran is_same_tcp6_flow(struct tcp6_flow_key *k1, struct tcp6_flow_key *k2)
14474080d7dSKumara Parameshwaran {
14574080d7dSKumara Parameshwaran 	rte_be32_t vtc_flow_diff;
14674080d7dSKumara Parameshwaran 
14774080d7dSKumara Parameshwaran 	if (memcmp(&k1->src_addr, &k2->src_addr, 16))
14874080d7dSKumara Parameshwaran 		return 0;
14974080d7dSKumara Parameshwaran 	if (memcmp(&k1->dst_addr, &k2->dst_addr, 16))
15074080d7dSKumara Parameshwaran 		return 0;
15174080d7dSKumara Parameshwaran 	/*
15274080d7dSKumara Parameshwaran 	 * IP version (4) Traffic Class (8) Flow Label (20)
15374080d7dSKumara Parameshwaran 	 * All fields except Traffic class should be same
15474080d7dSKumara Parameshwaran 	 */
15574080d7dSKumara Parameshwaran 	vtc_flow_diff = (k1->vtc_flow ^ k2->vtc_flow);
15674080d7dSKumara Parameshwaran 	if (vtc_flow_diff & htonl(0xF00FFFFF))
15774080d7dSKumara Parameshwaran 		return 0;
15874080d7dSKumara Parameshwaran 
15974080d7dSKumara Parameshwaran 	return is_same_common_tcp_key(&k1->cmn_key, &k2->cmn_key);
16074080d7dSKumara Parameshwaran }
16174080d7dSKumara Parameshwaran 
16274080d7dSKumara Parameshwaran #endif
163