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