From: Nithin Dabilpuram <ndabilpuram@marvell.com>
To: <jerinj@marvell.com>, Radu Nicolau <radu.nicolau@intel.com>,
Akhil Goyal <gakhil@marvell.com>
Cc: <dev@dpdk.org>, <anoobj@marvell.com>,
Nithin Dabilpuram <ndabilpuram@marvell.com>
Subject: [PATCH 2/7] examples/ipsec-secgw: use HW parsed packet type in poll mode
Date: Tue, 22 Mar 2022 23:28:40 +0530 [thread overview]
Message-ID: <20220322175902.363520-2-ndabilpuram@marvell.com> (raw)
In-Reply-To: <20220322175902.363520-1-ndabilpuram@marvell.com>
Use HW parsed packet type when ethdev supports necessary protocols.
If packet type is not supported, then register ethdev callbacks
for parse packet in SW. This is better for performance as it
effects fast path.
Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
---
examples/ipsec-secgw/ipsec-secgw.c | 259 +++++++++++++++++++++++++++----------
1 file changed, 194 insertions(+), 65 deletions(-)
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 76919e5..e8f9e90 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -374,53 +374,30 @@ print_stats_cb(__rte_unused void *param)
static inline void
prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t)
{
+ uint32_t ptype = pkt->packet_type;
const struct rte_ether_hdr *eth;
const struct rte_ipv4_hdr *iph4;
const struct rte_ipv6_hdr *iph6;
- const struct rte_udp_hdr *udp;
- uint16_t ip4_hdr_len;
- uint16_t nat_port;
+ uint32_t tun_type, l3_type;
+
+ tun_type = ptype & RTE_PTYPE_TUNNEL_MASK;
+ l3_type = ptype & RTE_PTYPE_L3_MASK;
eth = rte_pktmbuf_mtod(pkt, const struct rte_ether_hdr *);
- if (eth->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
-
+ if (l3_type == RTE_PTYPE_L3_IPV4) {
iph4 = (const struct rte_ipv4_hdr *)rte_pktmbuf_adj(pkt,
RTE_ETHER_HDR_LEN);
adjust_ipv4_pktlen(pkt, iph4, 0);
- switch (iph4->next_proto_id) {
- case IPPROTO_ESP:
+ if (tun_type == RTE_PTYPE_TUNNEL_ESP) {
t->ipsec.pkts[(t->ipsec.num)++] = pkt;
- break;
- case IPPROTO_UDP:
- if (app_sa_prm.udp_encap == 1) {
- ip4_hdr_len = ((iph4->version_ihl &
- RTE_IPV4_HDR_IHL_MASK) *
- RTE_IPV4_IHL_MULTIPLIER);
- udp = rte_pktmbuf_mtod_offset(pkt,
- struct rte_udp_hdr *, ip4_hdr_len);
- nat_port = rte_cpu_to_be_16(IPSEC_NAT_T_PORT);
- if (udp->src_port == nat_port ||
- udp->dst_port == nat_port){
- t->ipsec.pkts[(t->ipsec.num)++] = pkt;
- pkt->packet_type |=
- MBUF_PTYPE_TUNNEL_ESP_IN_UDP;
- break;
- }
- }
- /* Fall through */
- default:
+ } else {
t->ip4.data[t->ip4.num] = &iph4->next_proto_id;
t->ip4.pkts[(t->ip4.num)++] = pkt;
}
pkt->l2_len = 0;
pkt->l3_len = sizeof(*iph4);
- pkt->packet_type |= RTE_PTYPE_L3_IPV4;
- if (pkt->packet_type & RTE_PTYPE_L4_TCP)
- pkt->l4_len = sizeof(struct rte_tcp_hdr);
- else if (pkt->packet_type & RTE_PTYPE_L4_UDP)
- pkt->l4_len = sizeof(struct rte_udp_hdr);
- } else if (eth->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6)) {
+ } else if (l3_type & RTE_PTYPE_L3_IPV6) {
int next_proto;
size_t l3len, ext_len;
uint8_t *p;
@@ -430,47 +407,37 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t)
RTE_ETHER_HDR_LEN);
adjust_ipv6_pktlen(pkt, iph6, 0);
- next_proto = iph6->proto;
-
- /* determine l3 header size up to ESP extension */
l3len = sizeof(struct ip6_hdr);
- p = rte_pktmbuf_mtod(pkt, uint8_t *);
- while (next_proto != IPPROTO_ESP && l3len < pkt->data_len &&
- (next_proto = rte_ipv6_get_next_ext(p + l3len,
- next_proto, &ext_len)) >= 0)
- l3len += ext_len;
- /* drop packet when IPv6 header exceeds first segment length */
- if (unlikely(l3len > pkt->data_len)) {
- free_pkts(&pkt, 1);
- return;
- }
-
- switch (next_proto) {
- case IPPROTO_ESP:
+ if (tun_type == RTE_PTYPE_TUNNEL_ESP) {
t->ipsec.pkts[(t->ipsec.num)++] = pkt;
- break;
- case IPPROTO_UDP:
- if (app_sa_prm.udp_encap == 1) {
- udp = rte_pktmbuf_mtod_offset(pkt,
- struct rte_udp_hdr *, l3len);
- nat_port = rte_cpu_to_be_16(IPSEC_NAT_T_PORT);
- if (udp->src_port == nat_port ||
- udp->dst_port == nat_port){
- t->ipsec.pkts[(t->ipsec.num)++] = pkt;
- pkt->packet_type |=
- MBUF_PTYPE_TUNNEL_ESP_IN_UDP;
- break;
- }
- }
- /* Fall through */
- default:
+ } else {
t->ip6.data[t->ip6.num] = &iph6->proto;
t->ip6.pkts[(t->ip6.num)++] = pkt;
}
+
+ /* Determine l3 header size up to ESP extension by walking
+ * through extension headers.
+ */
+ if (l3_type == RTE_PTYPE_L3_IPV6_EXT ||
+ l3_type == RTE_PTYPE_L3_IPV6_EXT_UNKNOWN) {
+ p = rte_pktmbuf_mtod(pkt, uint8_t *);
+ next_proto = iph6->proto;
+ while (next_proto != IPPROTO_ESP &&
+ l3len < pkt->data_len &&
+ (next_proto = rte_ipv6_get_next_ext(p + l3len,
+ next_proto, &ext_len)) >= 0)
+ l3len += ext_len;
+
+ /* Drop pkt when IPv6 header exceeds first seg size */
+ if (unlikely(l3len > pkt->data_len)) {
+ free_pkts(&pkt, 1);
+ return;
+ }
+ }
+
pkt->l2_len = 0;
pkt->l3_len = l3len;
- pkt->packet_type |= RTE_PTYPE_L3_IPV6;
} else {
/* Unknown/Unsupported type, drop the packet */
RTE_LOG(ERR, IPSEC, "Unsupported packet type 0x%x\n",
@@ -479,6 +446,11 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t)
return;
}
+ if (ptype & RTE_PTYPE_L4_TCP)
+ pkt->l4_len = sizeof(struct rte_tcp_hdr);
+ else if (ptype & RTE_PTYPE_L4_UDP)
+ pkt->l4_len = sizeof(struct rte_udp_hdr);
+
/* Check if the packet has been processed inline. For inline protocol
* processed packets, the metadata in the mbuf can be used to identify
* the security processing done on the packet. The metadata will be
@@ -2249,6 +2221,147 @@ cryptodevs_init(uint16_t req_queue_num)
return total_nb_qps;
}
+static int
+check_ptype(int portid)
+{
+ int l3_ipv4 = 0, l3_ipv6 = 0, l4_udp = 0, tunnel_esp = 0;
+ int i, nb_ptypes;
+ uint32_t mask;
+
+ mask = (RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK |
+ RTE_PTYPE_TUNNEL_MASK);
+
+ nb_ptypes = rte_eth_dev_get_supported_ptypes(portid, mask, NULL, 0);
+ if (nb_ptypes <= 0)
+ return 0;
+
+ uint32_t ptypes[nb_ptypes];
+
+ nb_ptypes = rte_eth_dev_get_supported_ptypes(portid, mask, ptypes, nb_ptypes);
+ for (i = 0; i < nb_ptypes; ++i) {
+ if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+ l3_ipv4 = 1;
+ if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+ l3_ipv6 = 1;
+ if (ptypes[i] & RTE_PTYPE_TUNNEL_ESP)
+ tunnel_esp = 1;
+ if (ptypes[i] & RTE_PTYPE_L4_UDP)
+ l4_udp = 1;
+ }
+
+ if (l3_ipv4 == 0)
+ printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+ if (l3_ipv6 == 0)
+ printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+
+ if (l4_udp == 0)
+ printf("port %d cannot parse RTE_PTYPE_L4_UDP\n", portid);
+
+ if (tunnel_esp == 0)
+ printf("port %d cannot parse RTE_PTYPE_TUNNEL_ESP\n", portid);
+
+ if (l3_ipv4 && l3_ipv6 && l4_udp && tunnel_esp)
+ return 1;
+
+ return 0;
+
+}
+
+static inline void
+parse_ptype(struct rte_mbuf *m)
+{
+ uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+ const struct rte_ipv4_hdr *iph4;
+ const struct rte_ipv6_hdr *iph6;
+ const struct rte_ether_hdr *eth;
+ const struct rte_udp_hdr *udp;
+ uint16_t nat_port, ether_type;
+ int next_proto = 0;
+ size_t ext_len = 0;
+ const uint8_t *p;
+ uint32_t l3len;
+
+ eth = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
+ ether_type = eth->ether_type;
+
+ if (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
+ iph4 = (const struct rte_ipv4_hdr *)(eth + 1);
+ l3len = ((iph4->version_ihl & RTE_IPV4_HDR_IHL_MASK) *
+ RTE_IPV4_IHL_MULTIPLIER);
+
+ if (l3len == sizeof(struct rte_ipv4_hdr))
+ packet_type |= RTE_PTYPE_L3_IPV4;
+ else
+ packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+
+ next_proto = iph4->next_proto_id;
+ p = (const uint8_t *)iph4;
+ } else if (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6)) {
+ iph6 = (const struct rte_ipv6_hdr *)(eth + 1);
+ l3len = sizeof(struct ip6_hdr);
+
+ /* determine l3 header size up to ESP extension */
+ next_proto = iph6->proto;
+ p = (const uint8_t *)iph6;
+ while (next_proto != IPPROTO_ESP && l3len < m->data_len &&
+ (next_proto = rte_ipv6_get_next_ext(p + l3len,
+ next_proto, &ext_len)) >= 0)
+ l3len += ext_len;
+
+ /* Skip IPv6 header exceeds first segment length */
+ if (unlikely(l3len + RTE_ETHER_HDR_LEN > m->data_len))
+ goto exit;
+
+ if (l3len == sizeof(struct ip6_hdr))
+ packet_type |= RTE_PTYPE_L3_IPV6;
+ else
+ packet_type |= RTE_PTYPE_L3_IPV6_EXT;
+ }
+
+ switch (next_proto) {
+ case IPPROTO_ESP:
+ packet_type |= RTE_PTYPE_TUNNEL_ESP;
+ break;
+ case IPPROTO_UDP:
+ if (app_sa_prm.udp_encap == 1) {
+ udp = (const struct rte_udp_hdr *)(p + l3len);
+ nat_port = rte_cpu_to_be_16(IPSEC_NAT_T_PORT);
+ if (udp->src_port == nat_port ||
+ udp->dst_port == nat_port)
+ packet_type |=
+ MBUF_PTYPE_TUNNEL_ESP_IN_UDP;
+ }
+ break;
+ default:
+ break;
+ }
+exit:
+ m->packet_type = packet_type;
+}
+
+static uint16_t
+parse_ptype_cb(uint16_t port __rte_unused, uint16_t queue __rte_unused,
+ struct rte_mbuf *pkts[], uint16_t nb_pkts,
+ uint16_t max_pkts __rte_unused,
+ void *user_param __rte_unused)
+{
+ uint32_t i;
+
+ if (unlikely(nb_pkts == 0))
+ return nb_pkts;
+
+ rte_prefetch0(rte_pktmbuf_mtod(pkts[0], struct ether_hdr *));
+ for (i = 0; i < (unsigned int) (nb_pkts - 1); ++i) {
+ rte_prefetch0(rte_pktmbuf_mtod(pkts[i+1],
+ struct ether_hdr *));
+ parse_ptype(pkts[i]);
+ }
+ parse_ptype(pkts[i]);
+
+ return nb_pkts;
+}
+
static void
port_init(uint16_t portid, uint64_t req_rx_offloads, uint64_t req_tx_offloads)
{
@@ -2260,6 +2373,7 @@ port_init(uint16_t portid, uint64_t req_rx_offloads, uint64_t req_tx_offloads)
struct lcore_conf *qconf;
struct rte_ether_addr ethaddr;
struct rte_eth_conf local_port_conf = port_conf;
+ int ptype_supported;
ret = rte_eth_dev_info_get(portid, &dev_info);
if (ret != 0)
@@ -2357,6 +2471,11 @@ port_init(uint16_t portid, uint64_t req_rx_offloads, uint64_t req_tx_offloads)
rte_exit(EXIT_FAILURE, "Cannot adjust number of descriptors: "
"err=%d, port=%d\n", ret, portid);
+ /* Check if required ptypes are supported */
+ ptype_supported = check_ptype(portid);
+ if (!ptype_supported)
+ printf("Port %d: softly parse packet type info\n", portid);
+
/* init one TX queue per lcore */
tx_queueid = 0;
for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
@@ -2418,6 +2537,16 @@ port_init(uint16_t portid, uint64_t req_rx_offloads, uint64_t req_tx_offloads)
rte_exit(EXIT_FAILURE,
"rte_eth_rx_queue_setup: err=%d, "
"port=%d\n", ret, portid);
+
+ /* Register Rx callback if ptypes are not supported */
+ if (!ptype_supported &&
+ !rte_eth_add_rx_callback(portid, queue,
+ parse_ptype_cb, NULL)) {
+ printf("Failed to add rx callback: port=%d, "
+ "queue=%d\n", portid, queue);
+ }
+
+
}
}
printf("\n");
--
2.8.4
next prev parent reply other threads:[~2022-03-22 17:59 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-22 17:58 [PATCH 1/7] examples/ipsec-secgw: disable Tx chksum offload for inline Nithin Dabilpuram
2022-03-22 17:58 ` Nithin Dabilpuram [this message]
2022-04-14 15:43 ` [PATCH 2/7] examples/ipsec-secgw: use HW parsed packet type in poll mode Ananyev, Konstantin
2022-03-22 17:58 ` [PATCH 3/7] examples/ipsec-secgw: allow larger burst size for vectors Nithin Dabilpuram
2022-03-22 17:58 ` [PATCH 4/7] examples/ipsec-secgw: move fast path helper functions Nithin Dabilpuram
2022-03-22 17:58 ` [PATCH 5/7] examples/ipsec-secgw: get security context from lcore conf Nithin Dabilpuram
2022-03-22 17:58 ` [PATCH 6/7] examples/ipsec-secgw: update eth header during route lookup Nithin Dabilpuram
2022-03-22 17:58 ` [PATCH 7/7] examples/ipsec-secgw: add poll mode worker for inline proto Nithin Dabilpuram
2022-04-13 6:13 ` [PATCH 1/7] examples/ipsec-secgw: disable Tx chksum offload for inline Nithin Kumar Dabilpuram
2022-04-14 14:07 ` Ananyev, Konstantin
2022-04-19 13:56 ` Nithin Kumar Dabilpuram
2022-04-20 10:42 ` Ananyev, Konstantin
2022-04-21 13:31 ` [PATCH v2 1/7] examples/ipsec-secgw: move fast path helper functions Nithin Dabilpuram
2022-04-21 13:31 ` [PATCH v2 2/7] examples/ipsec-secgw: disable Tx chksum offload for inline Nithin Dabilpuram
2022-04-21 13:31 ` [PATCH v2 3/7] examples/ipsec-secgw: use HW parsed packet type in poll mode Nithin Dabilpuram
2022-04-21 13:31 ` [PATCH v2 4/7] examples/ipsec-secgw: allow larger burst size for vectors Nithin Dabilpuram
2022-04-21 13:31 ` [PATCH v2 5/7] examples/ipsec-secgw: get security context from lcore conf Nithin Dabilpuram
2022-04-21 13:31 ` [PATCH v2 6/7] examples/ipsec-secgw: update eth header during route lookup Nithin Dabilpuram
2022-04-21 13:31 ` [PATCH v2 7/7] examples/ipsec-secgw: add poll mode worker for inline proto Nithin Dabilpuram
2022-04-28 15:04 ` [PATCH v3 1/7] examples/ipsec-secgw: move fast path helper functions Nithin Dabilpuram
2022-04-28 15:04 ` [PATCH v3 2/7] examples/ipsec-secgw: disable Tx chksum offload for inline Nithin Dabilpuram
2022-04-28 15:04 ` [PATCH v3 3/7] examples/ipsec-secgw: use HW parsed packet type in poll mode Nithin Dabilpuram
2022-04-28 15:04 ` [PATCH v3 4/7] examples/ipsec-secgw: allow larger burst size for vectors Nithin Dabilpuram
2022-04-28 15:04 ` [PATCH v3 5/7] examples/ipsec-secgw: get security context from lcore conf Nithin Dabilpuram
2022-04-28 15:04 ` [PATCH v3 6/7] examples/ipsec-secgw: update eth header during route lookup Nithin Dabilpuram
2022-04-28 15:04 ` [PATCH v3 7/7] examples/ipsec-secgw: add poll mode worker for inline proto Nithin Dabilpuram
2022-04-29 10:23 ` [PATCH v3 1/7] examples/ipsec-secgw: move fast path helper functions Nithin Kumar Dabilpuram
2022-04-29 10:29 ` Akhil Goyal
2022-04-29 20:44 ` [PATCH v4 " Nithin Dabilpuram
2022-04-29 20:44 ` [PATCH v4 2/7] examples/ipsec-secgw: disable Tx chksum offload for inline Nithin Dabilpuram
2022-05-01 17:10 ` Konstantin Ananyev
2022-04-29 20:44 ` [PATCH v4 3/7] examples/ipsec-secgw: use HW parsed packet type in poll mode Nithin Dabilpuram
2022-04-29 20:44 ` [PATCH v4 4/7] examples/ipsec-secgw: allow larger burst size for vectors Nithin Dabilpuram
2022-04-29 20:44 ` [PATCH v4 5/7] examples/ipsec-secgw: get security context from lcore conf Nithin Dabilpuram
2022-04-29 20:44 ` [PATCH v4 6/7] examples/ipsec-secgw: update eth header during route lookup Nithin Dabilpuram
2022-04-29 20:44 ` [PATCH v4 7/7] examples/ipsec-secgw: add poll mode worker for inline proto Nithin Dabilpuram
2022-05-11 19:34 ` [PATCH v4 1/7] examples/ipsec-secgw: move fast path helper functions Akhil Goyal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220322175902.363520-2-ndabilpuram@marvell.com \
--to=ndabilpuram@marvell.com \
--cc=anoobj@marvell.com \
--cc=dev@dpdk.org \
--cc=gakhil@marvell.com \
--cc=jerinj@marvell.com \
--cc=radu.nicolau@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).