Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2023 Intel Corporation
3 : : */
4 : :
5 : : #ifndef _GRO_TCP_INTERNAL_H_
6 : : #define _GRO_TCP_INTERNAL_H_
7 : :
8 : : static inline uint32_t
9 : : find_an_empty_item(struct gro_tcp_item *items,
10 : : uint32_t max_item_num)
11 : : {
12 : : uint32_t i;
13 : :
14 [ # # # # ]: 0 : for (i = 0; i < max_item_num; i++)
15 [ # # # # ]: 0 : if (items[i].firstseg == NULL)
16 : : return i;
17 : : return INVALID_ARRAY_INDEX;
18 : : }
19 : :
20 : : static inline uint32_t
21 : 0 : insert_new_tcp_item(struct rte_mbuf *pkt,
22 : : struct gro_tcp_item *items,
23 : : uint32_t *item_num,
24 : : uint32_t max_item_num,
25 : : uint64_t start_time,
26 : : uint32_t prev_idx,
27 : : uint32_t sent_seq,
28 : : uint16_t ip_id,
29 : : uint8_t is_atomic)
30 : : {
31 : : uint32_t item_idx;
32 : :
33 : : item_idx = find_an_empty_item(items, max_item_num);
34 [ # # # # ]: 0 : if (item_idx == INVALID_ARRAY_INDEX)
35 : : return INVALID_ARRAY_INDEX;
36 : :
37 : 0 : items[item_idx].firstseg = pkt;
38 : 0 : items[item_idx].lastseg = rte_pktmbuf_lastseg(pkt);
39 : 0 : items[item_idx].start_time = start_time;
40 : 0 : items[item_idx].next_pkt_idx = INVALID_ARRAY_INDEX;
41 : 0 : items[item_idx].sent_seq = sent_seq;
42 : 0 : items[item_idx].l3.ip_id = ip_id;
43 : 0 : items[item_idx].nb_merged = 1;
44 : 0 : items[item_idx].is_atomic = is_atomic;
45 : 0 : (*item_num) += 1;
46 : :
47 : : /* if the previous packet exists, chain them together. */
48 [ # # ]: 0 : if (prev_idx != INVALID_ARRAY_INDEX) {
49 : 0 : items[item_idx].next_pkt_idx =
50 : 0 : items[prev_idx].next_pkt_idx;
51 : 0 : items[prev_idx].next_pkt_idx = item_idx;
52 : : }
53 : :
54 : : return item_idx;
55 : : }
56 : :
57 : : static inline uint32_t
58 : : delete_tcp_item(struct gro_tcp_item *items, uint32_t item_idx,
59 : : uint32_t *item_num,
60 : : uint32_t prev_item_idx)
61 : : {
62 : 0 : uint32_t next_idx = items[item_idx].next_pkt_idx;
63 : :
64 : : /* NULL indicates an empty item */
65 : 0 : items[item_idx].firstseg = NULL;
66 [ # # ]: 0 : (*item_num) -= 1;
67 : : if (prev_item_idx != INVALID_ARRAY_INDEX)
68 : : items[prev_item_idx].next_pkt_idx = next_idx;
69 : :
70 : : return next_idx;
71 : : }
72 : :
73 : : static inline int32_t
74 : 0 : process_tcp_item(struct rte_mbuf *pkt,
75 : : struct rte_tcp_hdr *tcp_hdr,
76 : : int32_t tcp_dl,
77 : : struct gro_tcp_item *items,
78 : : uint32_t item_idx,
79 : : uint32_t *item_num,
80 : : uint32_t max_item_num,
81 : : uint16_t ip_id,
82 : : uint8_t is_atomic,
83 : : uint64_t start_time)
84 : : {
85 : : uint32_t cur_idx;
86 : : uint32_t prev_idx;
87 : : int cmp;
88 : : uint32_t sent_seq;
89 : :
90 [ # # ]: 0 : sent_seq = rte_be_to_cpu_32(tcp_hdr->sent_seq);
91 : : /*
92 : : * Check all packets in the flow and try to find a neighbor for
93 : : * the input packet.
94 : : */
95 : : cur_idx = item_idx;
96 : : prev_idx = cur_idx;
97 : : do {
98 : 0 : cmp = check_seq_option(&items[cur_idx], tcp_hdr,
99 : 0 : sent_seq, ip_id, pkt->l4_len, tcp_dl, 0,
100 : : is_atomic);
101 [ # # ]: 0 : if (cmp) {
102 [ # # ]: 0 : if (merge_two_tcp_packets(&items[cur_idx],
103 : 0 : pkt, cmp, sent_seq, tcp_hdr->tcp_flags, ip_id, 0))
104 : : return 1;
105 : : /*
106 : : * Fail to merge the two packets, as the packet
107 : : * length is greater than the max value. Store
108 : : * the packet into the flow.
109 : : */
110 [ # # ]: 0 : if (insert_new_tcp_item(pkt, items, item_num, max_item_num,
111 : : start_time, cur_idx, sent_seq, ip_id, is_atomic) ==
112 : : INVALID_ARRAY_INDEX)
113 : : return -1;
114 : 0 : return 0;
115 : : }
116 : : prev_idx = cur_idx;
117 : 0 : cur_idx = items[cur_idx].next_pkt_idx;
118 [ # # ]: 0 : } while (cur_idx != INVALID_ARRAY_INDEX);
119 : :
120 : : /* Fail to find a neighbor, so store the packet into the flow. */
121 [ # # ]: 0 : if (insert_new_tcp_item(pkt, items, item_num, max_item_num, start_time, prev_idx, sent_seq,
122 : : ip_id, is_atomic) == INVALID_ARRAY_INDEX)
123 : 0 : return -1;
124 : :
125 : : return 0;
126 : : }
127 : : #endif
|