33 struct rte_mbuf **rx_packets;
34 struct rte_mbuf **tx_packets;
35 uint32_t num_tx_packets = 0;
44 DOCA_LOG_ERR(
"%s: 'tcp_queues argument cannot be NULL", __func__);
49 DOCA_LOG_ERR(
"%s: 'tcp_queues->port argument cannot be NULL", __func__);
54 DOCA_LOG_ERR(
"%s: 'tcp_queues->rxq_pipe_gpu argument cannot be NULL", __func__);
62 if (rx_packets ==
NULL) {
63 DOCA_LOG_ERR(
"No memory available to allocate DPDK rx packets");
68 if (tx_packets ==
NULL) {
70 DOCA_LOG_ERR(
"No memory available to allocate DPDK tx packets");
77 while (DOCA_GPUNETIO_VOLATILE(
force_quit) ==
false) {
80 for (
int i = 0; i < num_rx_packets; i++) {
81 const struct rte_mbuf *pkt = rx_packets[i];
90 DOCA_LOG_WARN(
"Unexpected TCP packet flags: 0x%x, expected SYN/RST/FIN",
108 DOCA_LOG_WARN(
"Unexpected TCP packet flags: 0x%x, expected SYN/RST/FIN",
115 tx_packets[num_tx_packets++] = ack;
118 while (num_tx_packets > 0) {
119 num_sent = rte_eth_tx_burst(port_id,
queue_id, tx_packets, num_tx_packets);
120 DOCA_LOG_DBG(
"DPDK tx_burst sent %d packets", num_sent);
121 num_tx_packets -= num_sent;
124 for (
int i = 0; i < num_rx_packets; i++)
125 rte_pktmbuf_free(rx_packets[i]);
142 const struct rte_ether_hdr *eth_hdr = rte_pktmbuf_mtod(packet,
struct rte_ether_hdr *);
144 if (((uint16_t)htons(eth_hdr->ether_type)) != RTE_ETHER_TYPE_IPV4) {
147 ((uint16_t)htons(eth_hdr->ether_type)));
151 const struct rte_ipv4_hdr *
ipv4_hdr = (
struct rte_ipv4_hdr *)ð_hdr[1];
158 const struct rte_tcp_hdr *
tcp_hdr = (
struct rte_tcp_hdr *)&
ipv4_hdr[1];
164 const struct rte_mbuf *pkt,
165 struct doca_flow_port *port,
166 struct doca_flow_pipe *gpu_rss_pipe)
172 if (!session_entry) {
181 DOCA_LOG_ERR(
"Couldn't add new has key data err %d", ret);
193 if (rte_hash_lookup_data(
tcp_session_table, &
key, (
void **)&session_entry) < 0 || !session_entry)
199 rte_free(session_entry);
204 const struct rte_ether_hdr *eth_hdr = rte_pktmbuf_mtod(packet,
struct rte_ether_hdr *);
205 const struct rte_ipv4_hdr *
ipv4_hdr = (
struct rte_ipv4_hdr *)ð_hdr[1];
206 const struct rte_tcp_hdr *
tcp_hdr = (
struct rte_tcp_hdr *)&
ipv4_hdr[1];
220 struct rte_mbuf *
create_ack_packet(
const struct rte_mbuf *src_packet,
struct rte_mempool *tcp_ack_pkt_pool)
222 uint32_t RTE_TCP_OPT_NOP_bytes = 1;
223 uint32_t RTE_TCP_OPT_MSS_nbytes = 4;
224 uint32_t RTE_TCP_OPT_WND_SCALE_nbytes = 3;
225 uint32_t RTE_TCP_OPT_SACK_PERMITTED_nbytes = 2;
226 uint32_t RTE_TCP_OPT_TIMESTAMP_nbytes = 10;
228 size_t tcp_option_array_len = RTE_TCP_OPT_MSS_nbytes + RTE_TCP_OPT_SACK_PERMITTED_nbytes +
229 RTE_TCP_OPT_TIMESTAMP_nbytes + RTE_TCP_OPT_NOP_bytes +
230 RTE_TCP_OPT_WND_SCALE_nbytes;
232 struct rte_ether_hdr *dst_eth_hdr;
233 struct rte_ipv4_hdr *dst_ipv4_hdr;
234 struct rte_tcp_hdr *dst_tcp_hdr;
235 uint8_t *dst_tcp_opts;
236 struct rte_mbuf *dst_packet;
237 const struct rte_ether_hdr *src_eth_hdr = rte_pktmbuf_mtod(src_packet,
struct rte_ether_hdr *);
238 const struct rte_ipv4_hdr *src_ipv4_hdr = (
struct rte_ipv4_hdr *)&src_eth_hdr[1];
239 const struct rte_tcp_hdr *src_tcp_hdr = (
struct rte_tcp_hdr *)&src_ipv4_hdr[1];
241 if (!src_tcp_hdr->syn) {
243 tcp_option_array_len = 0;
246 dst_packet = rte_pktmbuf_alloc(tcp_ack_pkt_pool);
253 (
struct rte_ether_hdr *)rte_pktmbuf_append(dst_packet,
254 sizeof(
struct rte_ether_hdr) +
sizeof(
struct rte_ipv4_hdr) +
255 sizeof(struct rte_tcp_hdr) + tcp_option_array_len);
256 if (dst_eth_hdr ==
NULL)
259 dst_ipv4_hdr = (
struct rte_ipv4_hdr *)&dst_eth_hdr[1];
260 dst_tcp_hdr = (
struct rte_tcp_hdr *)&dst_ipv4_hdr[1];
261 dst_tcp_opts = (uint8_t *)&dst_tcp_hdr[1];
263 dst_eth_hdr->src_addr = src_eth_hdr->dst_addr;
264 dst_eth_hdr->dst_addr = src_eth_hdr->src_addr;
265 dst_eth_hdr->ether_type = src_eth_hdr->ether_type;
268 dst_ipv4_hdr->version = 4;
269 dst_ipv4_hdr->ihl = 5;
270 dst_ipv4_hdr->src_addr = src_ipv4_hdr->dst_addr;
271 dst_ipv4_hdr->dst_addr = src_ipv4_hdr->src_addr;
272 dst_ipv4_hdr->total_length =
273 RTE_BE16(
sizeof(
struct rte_ipv4_hdr) +
sizeof(
struct rte_tcp_hdr) + tcp_option_array_len);
274 dst_ipv4_hdr->fragment_offset = htons(RTE_IPV4_HDR_DF_FLAG);
275 dst_ipv4_hdr->time_to_live = 64;
276 dst_ipv4_hdr->next_proto_id = IPPROTO_TCP;
278 dst_tcp_hdr->src_port = src_tcp_hdr->dst_port;
279 dst_tcp_hdr->dst_port = src_tcp_hdr->src_port;
280 dst_tcp_hdr->recv_ack = RTE_BE32(RTE_BE32(src_tcp_hdr->sent_seq) + 1);
281 dst_tcp_hdr->sent_seq = src_tcp_hdr->syn ? RTE_BE32(1000) : src_tcp_hdr->recv_ack;
282 dst_tcp_hdr->rx_win = RTE_BE16(60000);
283 dst_tcp_hdr->dt_off = 5 + tcp_option_array_len / 4;
285 if (!src_tcp_hdr->ack) {
286 dst_tcp_hdr->syn = src_tcp_hdr->syn;
287 dst_tcp_hdr->fin = src_tcp_hdr->fin;
289 dst_tcp_hdr->ack = 1;
291 if (tcp_option_array_len) {
292 uint8_t *mss_opt = dst_tcp_opts;
293 uint8_t *sack_ok_opt = dst_tcp_opts + RTE_TCP_OPT_MSS_nbytes;
294 uint8_t *ts_opt = sack_ok_opt + RTE_TCP_OPT_SACK_PERMITTED_nbytes;
295 uint8_t *nop_opt = ts_opt + RTE_TCP_OPT_TIMESTAMP_nbytes;
296 uint8_t *ws_opt = nop_opt + 1;
297 time_t seconds = htonl(time(
NULL));
299 mss_opt[0] = RTE_TCP_OPT_MSS;
300 mss_opt[1] = RTE_TCP_OPT_MSS_nbytes;
301 mss_opt[2] = (uint8_t)(mss >> 8);
302 mss_opt[3] = (uint8_t)mss;
304 sack_ok_opt[0] = RTE_TCP_OPT_SACK_PERMITTED;
305 sack_ok_opt[1] = RTE_TCP_OPT_SACK_PERMITTED_nbytes;
307 ts_opt[0] = RTE_TCP_OPT_TIMESTAMP;
308 ts_opt[1] = RTE_TCP_OPT_TIMESTAMP_nbytes;
309 memcpy(ts_opt + 2, &seconds, 4);
312 nop_opt[0] = RTE_TCP_OPT_NOP;
314 ws_opt[0] = RTE_TCP_OPT_WND_SCALE;
315 ws_opt[1] = RTE_TCP_OPT_WND_SCALE_nbytes;
318 const uint8_t *src_tcp_option = (uint8_t *)&src_tcp_hdr[1];
319 const uint8_t *src_tcp_options_end = src_tcp_option + 4 * src_tcp_hdr->data_off;
320 uint32_t opt_len = 0;
322 while (src_tcp_option < src_tcp_options_end) {
323 DOCA_LOG_DBG(
"Processing TCP Option 0x%x", *src_tcp_option);
324 switch (*src_tcp_option) {
325 case RTE_TCP_OPT_END:
326 src_tcp_option = src_tcp_options_end;
328 case RTE_TCP_OPT_NOP:
331 case RTE_TCP_OPT_MSS:
332 opt_len = *src_tcp_option;
335 case RTE_TCP_OPT_WND_SCALE:
338 case RTE_TCP_OPT_SACK_PERMITTED:
341 case RTE_TCP_OPT_SACK:
342 opt_len = *src_tcp_option;
343 src_tcp_option += opt_len;
345 case RTE_TCP_OPT_TIMESTAMP: {
346 const uint8_t *src_tsval = src_tcp_option + 2;
347 uint8_t *dst_tsecr = ts_opt + 6;
349 memcpy(dst_tsecr, src_tsval, 4);
350 src_tcp_option += 10;
358 dst_packet->ol_flags |= RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_TCP_CKSUM;
363 rte_pktmbuf_free(dst_packet);
369 const struct rte_ether_hdr *eth_hdr = rte_pktmbuf_mtod(packet,
struct rte_ether_hdr *);
370 const struct rte_ipv4_hdr *
ipv4_hdr = (
struct rte_ipv4_hdr *)ð_hdr[1];
371 const struct rte_tcp_hdr *
tcp_hdr = (
struct rte_tcp_hdr *)&
ipv4_hdr[1];
doca_error_t enable_tcp_gpu_offload(struct doca_flow_port *port, uint16_t queue_id, struct doca_flow_pipe *gpu_rss_pipe, struct tcp_session_entry *session_entry)
doca_error_t disable_tcp_gpu_offload(struct doca_flow_port *port, uint16_t queue_id, struct tcp_session_entry *session_entry)
#define DPDK_DEFAULT_PORT
static volatile bool force_quit
static struct rxq_tcp_queues tcp_queues
enum doca_error doca_error_t
DOCA API return codes.
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
#define DOCA_LOG_WARN(format,...)
Generates a WARNING application log message.
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
#define DOCA_LOG_DBG(format,...)
Generates a DEBUG application log message.
struct doca_flow_pipe * rxq_pipe_gpu
struct rte_mempool * tcp_ack_pkt_pool
struct doca_flow_port * port
struct tcp_session_key key
struct rte_hash * tcp_session_table