]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/lib/librte_gso/gso_tunnel_tcp4.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Intel Corporation
5 #include "gso_common.h"
6 #include "gso_tunnel_tcp4.h"
9 update_tunnel_ipv4_tcp_headers(struct rte_mbuf
*pkt
, uint8_t ipid_delta
,
10 struct rte_mbuf
**segs
, uint16_t nb_segs
)
12 struct ipv4_hdr
*ipv4_hdr
;
13 struct tcp_hdr
*tcp_hdr
;
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
;
20 outer_ipv4_offset
= pkt
->outer_l2_len
;
21 udp_gre_offset
= outer_ipv4_offset
+ pkt
->outer_l3_len
;
22 inner_ipv4_offset
= udp_gre_offset
+ pkt
->l2_len
;
23 tcp_offset
= inner_ipv4_offset
+ pkt
->l3_len
;
25 /* Outer IPv4 header. */
26 ipv4_hdr
= (struct ipv4_hdr
*)(rte_pktmbuf_mtod(pkt
, char *) +
28 outer_id
= rte_be_to_cpu_16(ipv4_hdr
->packet_id
);
30 /* Inner IPv4 header. */
31 ipv4_hdr
= (struct ipv4_hdr
*)(rte_pktmbuf_mtod(pkt
, char *) +
33 inner_id
= rte_be_to_cpu_16(ipv4_hdr
->packet_id
);
35 tcp_hdr
= (struct tcp_hdr
*)((char *)ipv4_hdr
+ pkt
->l3_len
);
36 sent_seq
= rte_be_to_cpu_32(tcp_hdr
->sent_seq
);
37 tail_idx
= nb_segs
- 1;
39 /* Only update UDP header for VxLAN packets. */
40 update_udp_hdr
= (pkt
->ol_flags
& PKT_TX_TUNNEL_VXLAN
) ? 1 : 0;
42 for (i
= 0; i
< nb_segs
; i
++) {
43 update_ipv4_header(segs
[i
], outer_ipv4_offset
, outer_id
);
45 update_udp_header(segs
[i
], udp_gre_offset
);
46 update_ipv4_header(segs
[i
], inner_ipv4_offset
, inner_id
);
47 update_tcp_header(segs
[i
], tcp_offset
, sent_seq
, i
< tail_idx
);
49 inner_id
+= ipid_delta
;
50 sent_seq
+= (segs
[i
]->pkt_len
- segs
[i
]->data_len
);
55 gso_tunnel_tcp4_segment(struct rte_mbuf
*pkt
,
58 struct rte_mempool
*direct_pool
,
59 struct rte_mempool
*indirect_pool
,
60 struct rte_mbuf
**pkts_out
,
63 struct ipv4_hdr
*inner_ipv4_hdr
;
64 uint16_t pyld_unit_size
, hdr_offset
, frag_off
;
67 hdr_offset
= pkt
->outer_l2_len
+ pkt
->outer_l3_len
+ pkt
->l2_len
;
68 inner_ipv4_hdr
= (struct ipv4_hdr
*)(rte_pktmbuf_mtod(pkt
, char *) +
71 * Don't process the packet whose MF bit or offset in the inner
72 * IPv4 header are non-zero.
74 frag_off
= rte_be_to_cpu_16(inner_ipv4_hdr
->fragment_offset
);
75 if (unlikely(IS_FRAGMENTED(frag_off
))) {
80 hdr_offset
+= pkt
->l3_len
+ pkt
->l4_len
;
81 /* Don't process the packet without data */
82 if (hdr_offset
>= pkt
->pkt_len
) {
86 pyld_unit_size
= gso_size
- hdr_offset
;
88 /* Segment the payload */
89 ret
= gso_do_segment(pkt
, hdr_offset
, pyld_unit_size
, direct_pool
,
90 indirect_pool
, pkts_out
, nb_pkts_out
);
94 update_tunnel_ipv4_tcp_headers(pkt
, ipid_delta
, pkts_out
, ret
);