]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/examples/l3fwd/l3fwd_lpm_altivec.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2016 Intel Corporation.
3 * Copyright(c) 2017 IBM Corporation.
7 #ifndef __L3FWD_LPM_ALTIVEC_H__
8 #define __L3FWD_LPM_ALTIVEC_H__
10 #include "l3fwd_altivec.h"
13 * Read packet_type and destination IPV4 addresses from 4 mbufs.
16 processx4_step1(struct rte_mbuf
*pkt
[FWDSTEP
],
17 vector
unsigned int *dip
,
20 struct rte_ipv4_hdr
*ipv4_hdr
;
21 struct rte_ether_hdr
*eth_hdr
;
22 uint32_t x0
, x1
, x2
, x3
;
24 eth_hdr
= rte_pktmbuf_mtod(pkt
[0], struct rte_ether_hdr
*);
25 ipv4_hdr
= (struct rte_ipv4_hdr
*)(eth_hdr
+ 1);
26 x0
= ipv4_hdr
->dst_addr
;
27 ipv4_flag
[0] = pkt
[0]->packet_type
& RTE_PTYPE_L3_IPV4
;
29 rte_compiler_barrier();
30 eth_hdr
= rte_pktmbuf_mtod(pkt
[1], struct rte_ether_hdr
*);
31 ipv4_hdr
= (struct rte_ipv4_hdr
*)(eth_hdr
+ 1);
32 x1
= ipv4_hdr
->dst_addr
;
33 ipv4_flag
[0] &= pkt
[1]->packet_type
;
35 rte_compiler_barrier();
36 eth_hdr
= rte_pktmbuf_mtod(pkt
[2], struct rte_ether_hdr
*);
37 ipv4_hdr
= (struct rte_ipv4_hdr
*)(eth_hdr
+ 1);
38 x2
= ipv4_hdr
->dst_addr
;
39 ipv4_flag
[0] &= pkt
[2]->packet_type
;
41 rte_compiler_barrier();
42 eth_hdr
= rte_pktmbuf_mtod(pkt
[3], struct rte_ether_hdr
*);
43 ipv4_hdr
= (struct rte_ipv4_hdr
*)(eth_hdr
+ 1);
44 x3
= ipv4_hdr
->dst_addr
;
45 ipv4_flag
[0] &= pkt
[3]->packet_type
;
47 rte_compiler_barrier();
48 dip
[0] = (vector
unsigned int){x0
, x1
, x2
, x3
};
52 * Lookup into LPM for destination port.
53 * If lookup fails, use incoming port (portid) as destination port.
56 processx4_step2(const struct lcore_conf
*qconf
,
57 vector
unsigned int dip
,
60 struct rte_mbuf
*pkt
[FWDSTEP
],
61 uint16_t dprt
[FWDSTEP
])
64 const vector
unsigned char bswap_mask
= (vector
unsigned char){
70 /* Byte swap 4 IPV4 addresses. */
71 dip
= (vector
unsigned int)vec_perm(*(vector
unsigned char *)&dip
,
72 (vector
unsigned char){}, bswap_mask
);
74 /* if all 4 packets are IPV4. */
75 if (likely(ipv4_flag
)) {
76 rte_lpm_lookupx4(qconf
->ipv4_lookup_struct
, (xmm_t
)dip
,
77 (uint32_t *)&dst
, portid
);
78 /* get rid of unused upper 16 bit for each dport. */
79 dst
.x
= (xmm_t
)vec_packs(dst
.x
, dst
.x
);
80 *(uint64_t *)dprt
= dst
.u64
[0];
83 dprt
[0] = lpm_get_dst_port_with_ipv4(qconf
, pkt
[0],
85 dprt
[1] = lpm_get_dst_port_with_ipv4(qconf
, pkt
[1],
87 dprt
[2] = lpm_get_dst_port_with_ipv4(qconf
, pkt
[2],
89 dprt
[3] = lpm_get_dst_port_with_ipv4(qconf
, pkt
[3],
95 * Buffer optimized handling of packets, invoked
99 l3fwd_lpm_send_packets(int nb_rx
, struct rte_mbuf
**pkts_burst
,
100 uint8_t portid
, struct lcore_conf
*qconf
)
103 uint16_t dst_port
[MAX_PKT_BURST
];
104 vector
unsigned int dip
[MAX_PKT_BURST
/ FWDSTEP
];
105 uint32_t ipv4_flag
[MAX_PKT_BURST
/ FWDSTEP
];
106 const int32_t k
= RTE_ALIGN_FLOOR(nb_rx
, FWDSTEP
);
108 for (j
= 0; j
!= k
; j
+= FWDSTEP
)
109 processx4_step1(&pkts_burst
[j
], &dip
[j
/ FWDSTEP
],
110 &ipv4_flag
[j
/ FWDSTEP
]);
112 for (j
= 0; j
!= k
; j
+= FWDSTEP
)
113 processx4_step2(qconf
, dip
[j
/ FWDSTEP
],
114 ipv4_flag
[j
/ FWDSTEP
],
115 portid
, &pkts_burst
[j
], &dst_port
[j
]);
117 /* Classify last up to 3 packets one by one */
118 switch (nb_rx
% FWDSTEP
) {
120 dst_port
[j
] = lpm_get_dst_port(qconf
, pkts_burst
[j
], portid
);
124 dst_port
[j
] = lpm_get_dst_port(qconf
, pkts_burst
[j
], portid
);
128 dst_port
[j
] = lpm_get_dst_port(qconf
, pkts_burst
[j
], portid
);
133 send_packets_multi(qconf
, pkts_burst
, dst_port
, nb_rx
);
136 #endif /* __L3FWD_LPM_ALTIVEC_H__ */