15c55e819SKumara Parameshwaran
25c55e819SKumara Parameshwaran /* SPDX-License-Identifier: BSD-3-Clause
35c55e819SKumara Parameshwaran * Copyright(c) 2023 Intel Corporation
45c55e819SKumara Parameshwaran */
55c55e819SKumara Parameshwaran
65c55e819SKumara Parameshwaran #ifndef _GRO_TCP_INTERNAL_H_
75c55e819SKumara Parameshwaran #define _GRO_TCP_INTERNAL_H_
85c55e819SKumara Parameshwaran
95c55e819SKumara Parameshwaran static inline uint32_t
find_an_empty_item(struct gro_tcp_item * items,uint32_t max_item_num)105c55e819SKumara Parameshwaran find_an_empty_item(struct gro_tcp_item *items,
115c55e819SKumara Parameshwaran uint32_t max_item_num)
125c55e819SKumara Parameshwaran {
135c55e819SKumara Parameshwaran uint32_t i;
145c55e819SKumara Parameshwaran
155c55e819SKumara Parameshwaran for (i = 0; i < max_item_num; i++)
165c55e819SKumara Parameshwaran if (items[i].firstseg == NULL)
175c55e819SKumara Parameshwaran return i;
185c55e819SKumara Parameshwaran return INVALID_ARRAY_INDEX;
195c55e819SKumara Parameshwaran }
205c55e819SKumara Parameshwaran
215c55e819SKumara Parameshwaran static inline uint32_t
insert_new_tcp_item(struct rte_mbuf * pkt,struct gro_tcp_item * items,uint32_t * item_num,uint32_t max_item_num,uint64_t start_time,uint32_t prev_idx,uint32_t sent_seq,uint16_t ip_id,uint8_t is_atomic)225c55e819SKumara Parameshwaran insert_new_tcp_item(struct rte_mbuf *pkt,
235c55e819SKumara Parameshwaran struct gro_tcp_item *items,
245c55e819SKumara Parameshwaran uint32_t *item_num,
255c55e819SKumara Parameshwaran uint32_t max_item_num,
265c55e819SKumara Parameshwaran uint64_t start_time,
275c55e819SKumara Parameshwaran uint32_t prev_idx,
285c55e819SKumara Parameshwaran uint32_t sent_seq,
295c55e819SKumara Parameshwaran uint16_t ip_id,
305c55e819SKumara Parameshwaran uint8_t is_atomic)
315c55e819SKumara Parameshwaran {
325c55e819SKumara Parameshwaran uint32_t item_idx;
335c55e819SKumara Parameshwaran
345c55e819SKumara Parameshwaran item_idx = find_an_empty_item(items, max_item_num);
355c55e819SKumara Parameshwaran if (item_idx == INVALID_ARRAY_INDEX)
365c55e819SKumara Parameshwaran return INVALID_ARRAY_INDEX;
375c55e819SKumara Parameshwaran
385c55e819SKumara Parameshwaran items[item_idx].firstseg = pkt;
395c55e819SKumara Parameshwaran items[item_idx].lastseg = rte_pktmbuf_lastseg(pkt);
405c55e819SKumara Parameshwaran items[item_idx].start_time = start_time;
415c55e819SKumara Parameshwaran items[item_idx].next_pkt_idx = INVALID_ARRAY_INDEX;
425c55e819SKumara Parameshwaran items[item_idx].sent_seq = sent_seq;
435c55e819SKumara Parameshwaran items[item_idx].l3.ip_id = ip_id;
445c55e819SKumara Parameshwaran items[item_idx].nb_merged = 1;
455c55e819SKumara Parameshwaran items[item_idx].is_atomic = is_atomic;
465c55e819SKumara Parameshwaran (*item_num) += 1;
475c55e819SKumara Parameshwaran
485c55e819SKumara Parameshwaran /* if the previous packet exists, chain them together. */
495c55e819SKumara Parameshwaran if (prev_idx != INVALID_ARRAY_INDEX) {
505c55e819SKumara Parameshwaran items[item_idx].next_pkt_idx =
515c55e819SKumara Parameshwaran items[prev_idx].next_pkt_idx;
525c55e819SKumara Parameshwaran items[prev_idx].next_pkt_idx = item_idx;
535c55e819SKumara Parameshwaran }
545c55e819SKumara Parameshwaran
555c55e819SKumara Parameshwaran return item_idx;
565c55e819SKumara Parameshwaran }
575c55e819SKumara Parameshwaran
585c55e819SKumara Parameshwaran static inline uint32_t
delete_tcp_item(struct gro_tcp_item * items,uint32_t item_idx,uint32_t * item_num,uint32_t prev_item_idx)595c55e819SKumara Parameshwaran delete_tcp_item(struct gro_tcp_item *items, uint32_t item_idx,
605c55e819SKumara Parameshwaran uint32_t *item_num,
615c55e819SKumara Parameshwaran uint32_t prev_item_idx)
625c55e819SKumara Parameshwaran {
635c55e819SKumara Parameshwaran uint32_t next_idx = items[item_idx].next_pkt_idx;
645c55e819SKumara Parameshwaran
655c55e819SKumara Parameshwaran /* NULL indicates an empty item */
665c55e819SKumara Parameshwaran items[item_idx].firstseg = NULL;
675c55e819SKumara Parameshwaran (*item_num) -= 1;
685c55e819SKumara Parameshwaran if (prev_item_idx != INVALID_ARRAY_INDEX)
695c55e819SKumara Parameshwaran items[prev_item_idx].next_pkt_idx = next_idx;
705c55e819SKumara Parameshwaran
715c55e819SKumara Parameshwaran return next_idx;
725c55e819SKumara Parameshwaran }
735c55e819SKumara Parameshwaran
745c55e819SKumara Parameshwaran static inline int32_t
process_tcp_item(struct rte_mbuf * pkt,struct rte_tcp_hdr * tcp_hdr,int32_t tcp_dl,struct gro_tcp_item * items,uint32_t item_idx,uint32_t * item_num,uint32_t max_item_num,uint16_t ip_id,uint8_t is_atomic,uint64_t start_time)755c55e819SKumara Parameshwaran process_tcp_item(struct rte_mbuf *pkt,
765c55e819SKumara Parameshwaran struct rte_tcp_hdr *tcp_hdr,
775c55e819SKumara Parameshwaran int32_t tcp_dl,
785c55e819SKumara Parameshwaran struct gro_tcp_item *items,
795c55e819SKumara Parameshwaran uint32_t item_idx,
805c55e819SKumara Parameshwaran uint32_t *item_num,
815c55e819SKumara Parameshwaran uint32_t max_item_num,
825c55e819SKumara Parameshwaran uint16_t ip_id,
835c55e819SKumara Parameshwaran uint8_t is_atomic,
845c55e819SKumara Parameshwaran uint64_t start_time)
855c55e819SKumara Parameshwaran {
865c55e819SKumara Parameshwaran uint32_t cur_idx;
875c55e819SKumara Parameshwaran uint32_t prev_idx;
885c55e819SKumara Parameshwaran int cmp;
895c55e819SKumara Parameshwaran uint32_t sent_seq;
905c55e819SKumara Parameshwaran
915c55e819SKumara Parameshwaran sent_seq = rte_be_to_cpu_32(tcp_hdr->sent_seq);
925c55e819SKumara Parameshwaran /*
935c55e819SKumara Parameshwaran * Check all packets in the flow and try to find a neighbor for
945c55e819SKumara Parameshwaran * the input packet.
955c55e819SKumara Parameshwaran */
965c55e819SKumara Parameshwaran cur_idx = item_idx;
975c55e819SKumara Parameshwaran prev_idx = cur_idx;
985c55e819SKumara Parameshwaran do {
995c55e819SKumara Parameshwaran cmp = check_seq_option(&items[cur_idx], tcp_hdr,
1005c55e819SKumara Parameshwaran sent_seq, ip_id, pkt->l4_len, tcp_dl, 0,
1015c55e819SKumara Parameshwaran is_atomic);
1025c55e819SKumara Parameshwaran if (cmp) {
1035c55e819SKumara Parameshwaran if (merge_two_tcp_packets(&items[cur_idx],
104*547f2943SKumara Parameshwaran pkt, cmp, sent_seq, tcp_hdr->tcp_flags, ip_id, 0))
1055c55e819SKumara Parameshwaran return 1;
1065c55e819SKumara Parameshwaran /*
1075c55e819SKumara Parameshwaran * Fail to merge the two packets, as the packet
1085c55e819SKumara Parameshwaran * length is greater than the max value. Store
1095c55e819SKumara Parameshwaran * the packet into the flow.
1105c55e819SKumara Parameshwaran */
1115c55e819SKumara Parameshwaran if (insert_new_tcp_item(pkt, items, item_num, max_item_num,
1125c55e819SKumara Parameshwaran start_time, cur_idx, sent_seq, ip_id, is_atomic) ==
1135c55e819SKumara Parameshwaran INVALID_ARRAY_INDEX)
1145c55e819SKumara Parameshwaran return -1;
1155c55e819SKumara Parameshwaran return 0;
1165c55e819SKumara Parameshwaran }
1175c55e819SKumara Parameshwaran prev_idx = cur_idx;
1185c55e819SKumara Parameshwaran cur_idx = items[cur_idx].next_pkt_idx;
1195c55e819SKumara Parameshwaran } while (cur_idx != INVALID_ARRAY_INDEX);
1205c55e819SKumara Parameshwaran
1215c55e819SKumara Parameshwaran /* Fail to find a neighbor, so store the packet into the flow. */
1225c55e819SKumara Parameshwaran if (insert_new_tcp_item(pkt, items, item_num, max_item_num, start_time, prev_idx, sent_seq,
1235c55e819SKumara Parameshwaran ip_id, is_atomic) == INVALID_ARRAY_INDEX)
1245c55e819SKumara Parameshwaran return -1;
1255c55e819SKumara Parameshwaran
1265c55e819SKumara Parameshwaran return 0;
1275c55e819SKumara Parameshwaran }
1285c55e819SKumara Parameshwaran #endif
129