xref: /dpdk/app/test-pmd/5tswap.h (revision 1d343c19330a11f05e3ea369ae5780d38772358e)
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(&eth_hdr->dst_addr, &addr);
17 	rte_ether_addr_copy(&eth_hdr->src_addr, &eth_hdr->dst_addr);
18 	rte_ether_addr_copy(&addr, &eth_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