From patchwork Mon Jun 24 13:39:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcin Smoczynski X-Patchwork-Id: 55241 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 903AA1BF14; Mon, 24 Jun 2019 15:43:05 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id 347BF1BF04 for ; Mon, 24 Jun 2019 15:43:03 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 24 Jun 2019 06:43:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,412,1557212400"; d="scan'208";a="182637020" Received: from msmoczyx-mobl.ger.corp.intel.com ([10.103.104.100]) by fmsmga001.fm.intel.com with ESMTP; 24 Jun 2019 06:43:00 -0700 From: Marcin Smoczynski To: marko.kovacevic@intel.com, orika@mellanox.com, bruce.richardson@intel.com, pablo.de.lara.guarch@intel.com, radu.nicolau@intel.com, akhil.goyal@nxp.com, tomasz.kantecki@intel.com, konstantin.ananyev@intel.com, bernard.iremonger@intel.com, olivier.matz@6wind.com Cc: dev@dpdk.org, Marcin Smoczynski Date: Mon, 24 Jun 2019 15:39:59 +0200 Message-Id: <20190624134000.2456-4-marcinx.smoczynski@intel.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20190624134000.2456-1-marcinx.smoczynski@intel.com> References: <20190508104717.13448-1-marcinx.smoczynski@intel.com> <20190624134000.2456-1-marcinx.smoczynski@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 3/4] examples/ipsec-secgw: add support for ipv6 options X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Using transport with IPv6 and header extensions requires calculating total header length including extensions up to ESP header which is achieved with iteratively parsing extensions when preparing traffic for processing. Calculated l3_len is later used to determine SPI field offset for an inbound traffic and to reconstruct L3 header by librte_ipsec. Signed-off-by: Marcin Smoczynski Acked-by: Konstantin Ananyev Tested-by: Konstantin Ananyev --- examples/ipsec-secgw/ipsec-secgw.c | 35 +++++++++++++++++++++++++----- examples/ipsec-secgw/sa.c | 5 +---- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c index 6c626fa5f..17012caf9 100644 --- a/examples/ipsec-secgw/ipsec-secgw.c +++ b/examples/ipsec-secgw/ipsec-secgw.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "ipsec.h" #include "parser.h" @@ -248,16 +249,40 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t) pkt->l2_len = 0; pkt->l3_len = sizeof(struct ip); } else if (eth->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6)) { - nlp = (uint8_t *)rte_pktmbuf_adj(pkt, RTE_ETHER_HDR_LEN); - nlp = RTE_PTR_ADD(nlp, offsetof(struct ip6_hdr, ip6_nxt)); - if (*nlp == IPPROTO_ESP) + int next_proto; + size_t l3len, ext_len; + struct rte_ipv6_hdr *v6h; + uint8_t *p; + + /* get protocol type */ + v6h = (struct rte_ipv6_hdr *)rte_pktmbuf_adj(pkt, + RTE_ETHER_HDR_LEN); + next_proto = v6h->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)) { + rte_pktmbuf_free(pkt); + return; + } + + if (next_proto == IPPROTO_ESP) t->ipsec.pkts[(t->ipsec.num)++] = pkt; else { - t->ip6.data[t->ip6.num] = nlp; + t->ip6.data[t->ip6.num] = rte_pktmbuf_mtod_offset(pkt, + uint8_t *, + offsetof(struct rte_ipv6_hdr, proto)); t->ip6.pkts[(t->ip6.num)++] = pkt; } pkt->l2_len = 0; - pkt->l3_len = sizeof(struct ip6_hdr); + pkt->l3_len = l3len; } else { /* Unknown/Unsupported type, drop the packet */ RTE_LOG(ERR, IPSEC, "Unsupported packet type 0x%x\n", diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index 8d47d1def..7262ccee8 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -1228,10 +1228,7 @@ single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt, *sa_ret = NULL; ip = rte_pktmbuf_mtod(pkt, struct ip *); - if (ip->ip_v == IPVERSION) - esp = (struct rte_esp_hdr *)(ip + 1); - else - esp = (struct rte_esp_hdr *)(((struct ip6_hdr *)ip) + 1); + esp = rte_pktmbuf_mtod_offset(pkt, struct rte_esp_hdr *, pkt->l3_len); if (esp->spi == INVALID_SPI) return;