Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2017 Intel Corporation 3 : : */ 4 : : 5 : : #include "gso_common.h" 6 : : #include "gso_tunnel_tcp4.h" 7 : : 8 : : static void 9 : 0 : update_tunnel_ipv4_tcp_headers(struct rte_mbuf *pkt, uint8_t ipid_delta, 10 : : struct rte_mbuf **segs, uint16_t nb_segs) 11 : : { 12 : : struct rte_ipv4_hdr *ipv4_hdr; 13 : : struct rte_tcp_hdr *tcp_hdr; 14 : : uint32_t sent_seq; 15 : : uint16_t outer_id, inner_id, tail_idx, i; 16 : : uint16_t outer_ipv4_offset, inner_ipv4_offset; 17 : : uint16_t udp_gre_offset, tcp_offset; 18 : : uint8_t update_udp_hdr; 19 : : 20 : 0 : outer_ipv4_offset = pkt->outer_l2_len; 21 : 0 : udp_gre_offset = outer_ipv4_offset + pkt->outer_l3_len; 22 : 0 : inner_ipv4_offset = udp_gre_offset + pkt->l2_len; 23 : 0 : tcp_offset = inner_ipv4_offset + pkt->l3_len; 24 : : 25 : : /* Outer IPv4 header. */ 26 : 0 : ipv4_hdr = (struct rte_ipv4_hdr *)(rte_pktmbuf_mtod(pkt, char *) + 27 : : outer_ipv4_offset); 28 [ # # ]: 0 : outer_id = rte_be_to_cpu_16(ipv4_hdr->packet_id); 29 : : 30 : : /* Inner IPv4 header. */ 31 : 0 : ipv4_hdr = (struct rte_ipv4_hdr *)(rte_pktmbuf_mtod(pkt, char *) + 32 : : inner_ipv4_offset); 33 [ # # ]: 0 : inner_id = rte_be_to_cpu_16(ipv4_hdr->packet_id); 34 : : 35 : 0 : tcp_hdr = (struct rte_tcp_hdr *)((char *)ipv4_hdr + pkt->l3_len); 36 [ # # ]: 0 : sent_seq = rte_be_to_cpu_32(tcp_hdr->sent_seq); 37 : 0 : tail_idx = nb_segs - 1; 38 : : 39 : : /* Only update UDP header for VxLAN packets. */ 40 : 0 : update_udp_hdr = (pkt->ol_flags & RTE_MBUF_F_TX_TUNNEL_VXLAN) ? 1 : 0; 41 : : 42 [ # # ]: 0 : for (i = 0; i < nb_segs; i++) { 43 : 0 : update_ipv4_header(segs[i], outer_ipv4_offset, outer_id); 44 [ # # ]: 0 : if (update_udp_hdr) 45 : : update_udp_header(segs[i], udp_gre_offset); 46 : 0 : update_ipv4_header(segs[i], inner_ipv4_offset, inner_id); 47 : 0 : update_tcp_header(segs[i], tcp_offset, sent_seq, i < tail_idx); 48 : 0 : outer_id++; 49 : 0 : inner_id += ipid_delta; 50 : 0 : sent_seq += (segs[i]->pkt_len - segs[i]->data_len); 51 : : } 52 : 0 : } 53 : : 54 : : int 55 : 0 : gso_tunnel_tcp4_segment(struct rte_mbuf *pkt, 56 : : uint16_t gso_size, 57 : : uint8_t ipid_delta, 58 : : struct rte_mempool *direct_pool, 59 : : struct rte_mempool *indirect_pool, 60 : : struct rte_mbuf **pkts_out, 61 : : uint16_t nb_pkts_out) 62 : : { 63 : : struct rte_ipv4_hdr *inner_ipv4_hdr; 64 : : uint16_t pyld_unit_size, hdr_offset, frag_off; 65 : : int ret; 66 : : 67 : 0 : hdr_offset = pkt->outer_l2_len + pkt->outer_l3_len + pkt->l2_len; 68 : 0 : inner_ipv4_hdr = (struct rte_ipv4_hdr *)(rte_pktmbuf_mtod(pkt, char *) + 69 : : hdr_offset); 70 : : /* 71 : : * Don't process the packet whose MF bit or offset in the inner 72 : : * IPv4 header are non-zero. 73 : : */ 74 [ # # ]: 0 : frag_off = rte_be_to_cpu_16(inner_ipv4_hdr->fragment_offset); 75 [ # # ]: 0 : if (unlikely(IS_FRAGMENTED(frag_off))) { 76 : : return 0; 77 : : } 78 : : 79 : 0 : hdr_offset += pkt->l3_len + pkt->l4_len; 80 : : /* Don't process the packet without data */ 81 [ # # ]: 0 : if (hdr_offset >= pkt->pkt_len) { 82 : : return 0; 83 : : } 84 : 0 : pyld_unit_size = gso_size - hdr_offset; 85 : : 86 : : /* Segment the payload */ 87 : 0 : ret = gso_do_segment(pkt, hdr_offset, pyld_unit_size, direct_pool, 88 : : indirect_pool, pkts_out, nb_pkts_out); 89 [ # # ]: 0 : if (ret > 1) 90 : 0 : update_tunnel_ipv4_tcp_headers(pkt, ipid_delta, pkts_out, ret); 91 : : 92 : : return ret; 93 : : }