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