1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2014-2020 Mellanox Technologies, Ltd
3 */
4
5 #ifndef _5TSWAP_H_
6 #define _5TSWAP_H_
7
8 #include "macswap_common.h"
9
10 static inline void
swap_mac(struct rte_ether_hdr * eth_hdr)11 swap_mac(struct rte_ether_hdr *eth_hdr)
12 {
13 struct rte_ether_addr addr;
14
15 /* Swap dest and src mac addresses. */
16 rte_ether_addr_copy(ð_hdr->dst_addr, &addr);
17 rte_ether_addr_copy(ð_hdr->src_addr, ð_hdr->dst_addr);
18 rte_ether_addr_copy(&addr, ð_hdr->src_addr);
19 }
20
21 static inline void
swap_ipv4(struct rte_ipv4_hdr * ipv4_hdr)22 swap_ipv4(struct rte_ipv4_hdr *ipv4_hdr)
23 {
24 rte_be32_t addr;
25
26 /* Swap dest and src ipv4 addresses. */
27 addr = ipv4_hdr->src_addr;
28 ipv4_hdr->src_addr = ipv4_hdr->dst_addr;
29 ipv4_hdr->dst_addr = addr;
30 }
31
32 static inline void
swap_ipv6(struct rte_ipv6_hdr * ipv6_hdr)33 swap_ipv6(struct rte_ipv6_hdr *ipv6_hdr)
34 {
35 uint8_t addr[16];
36
37 /* Swap dest and src ipv6 addresses. */
38 memcpy(&addr, &ipv6_hdr->src_addr, 16);
39 memcpy(&ipv6_hdr->src_addr, &ipv6_hdr->dst_addr, 16);
40 memcpy(&ipv6_hdr->dst_addr, &addr, 16);
41 }
42
43 static inline void
swap_tcp(struct rte_tcp_hdr * tcp_hdr)44 swap_tcp(struct rte_tcp_hdr *tcp_hdr)
45 {
46 rte_be16_t port;
47
48 /* Swap dest and src tcp port. */
49 port = tcp_hdr->src_port;
50 tcp_hdr->src_port = tcp_hdr->dst_port;
51 tcp_hdr->dst_port = port;
52 }
53
54 static inline void
swap_udp(struct rte_udp_hdr * udp_hdr)55 swap_udp(struct rte_udp_hdr *udp_hdr)
56 {
57 rte_be16_t port;
58
59 /* Swap dest and src udp port */
60 port = udp_hdr->src_port;
61 udp_hdr->src_port = udp_hdr->dst_port;
62 udp_hdr->dst_port = port;
63 }
64
65 static inline void
do_5tswap(struct rte_mbuf * pkts_burst[],uint16_t nb_rx,struct fwd_stream * fs)66 do_5tswap(struct rte_mbuf *pkts_burst[], uint16_t nb_rx,
67 struct fwd_stream *fs)
68 {
69 struct rte_port *txp;
70 struct rte_mbuf *mb;
71 uint16_t next_proto;
72 uint64_t ol_flags;
73 uint16_t proto;
74 int i;
75 union {
76 struct rte_ether_hdr *eth;
77 struct rte_vlan_hdr *vlan;
78 struct rte_ipv4_hdr *ipv4;
79 struct rte_ipv6_hdr *ipv6;
80 struct rte_tcp_hdr *tcp;
81 struct rte_udp_hdr *udp;
82 uint8_t *byte;
83 } h;
84
85 txp = &ports[fs->tx_port];
86 ol_flags = ol_flags_init(txp->dev_conf.txmode.offloads);
87 vlan_qinq_set(pkts_burst, nb_rx, ol_flags,
88 txp->tx_vlan_id, txp->tx_vlan_id_outer);
89 for (i = 0; i < nb_rx; i++) {
90 if (likely(i < nb_rx - 1))
91 rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i+1],
92 void *));
93 mb = pkts_burst[i];
94 h.eth = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);
95 proto = h.eth->ether_type;
96 swap_mac(h.eth);
97 mb->l2_len = sizeof(struct rte_ether_hdr);
98 h.eth++;
99 while (proto == RTE_BE16(RTE_ETHER_TYPE_VLAN) ||
100 proto == RTE_BE16(RTE_ETHER_TYPE_QINQ)) {
101 proto = h.vlan->eth_proto;
102 h.vlan++;
103 mb->l2_len += sizeof(struct rte_vlan_hdr);
104 }
105 if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV4)) {
106 swap_ipv4(h.ipv4);
107 next_proto = h.ipv4->next_proto_id;
108 mb->l3_len = rte_ipv4_hdr_len(h.ipv4);
109 h.byte += mb->l3_len;
110 } else if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV6)) {
111 swap_ipv6(h.ipv6);
112 next_proto = h.ipv6->proto;
113 h.ipv6++;
114 mb->l3_len = sizeof(struct rte_ipv6_hdr);
115 } else {
116 mbuf_field_set(mb, ol_flags);
117 continue;
118 }
119 if (next_proto == IPPROTO_UDP) {
120 swap_udp(h.udp);
121 mb->l4_len = sizeof(struct rte_udp_hdr);
122 } else if (next_proto == IPPROTO_TCP) {
123 swap_tcp(h.tcp);
124 mb->l4_len = (h.tcp->data_off & 0xf0) >> 2;
125 }
126 mbuf_field_set(mb, ol_flags);
127 }
128 }
129
130 #endif /* _5TSWAP_H_ */
131