From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3CD2941CE4; Sun, 19 Feb 2023 23:44:10 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2A3B742D63; Sun, 19 Feb 2023 23:44:10 +0100 (CET) Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) by mails.dpdk.org (Postfix) with ESMTP id A7F0942D5E for ; Sun, 19 Feb 2023 23:44:08 +0100 (CET) Received: by mail-wm1-f50.google.com with SMTP id j41-20020a05600c1c2900b003e1e754657aso1059583wms.2 for ; Sun, 19 Feb 2023 14:44:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=sKARLyYu/EcSUBDs6/07LTaPyD9CNUdgAcD52YvJq+4=; b=Z5cMPmySA2Yy5bs4XLp6OguABWExT3d4v1HJPJCg9rTx9jE2tqIRFX76SzTzC/AeM5 HcJnFsUAmMjWXaWM3Rf6m5YK/Wlk6sBFvgdAh5Za+FAG+z7V27qTuZtTgdV9aXl/7gAY u5fIL8RCwRbk/5TS5g2j1Ogtjhs/hOp5yS5W7B6VOs+FEoK/O2ulUC7WddsPNzDUlqsK iu/Cph0ih1T+vMGSqqkbGNsQOI4LMW/hvVyBtfgif5FU8mZjO6n0Mr4iY+4Yzsl6hLjX ZS1yBZANcPe3WUGKP9LhfqpZBZpzdoNtKDrpC2WGdAIEMmPWLkGQLRmd+2pyfoKnY7FO IFqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=sKARLyYu/EcSUBDs6/07LTaPyD9CNUdgAcD52YvJq+4=; b=opsv669icLM+pr2/RzzZrV2d6yfPJuK1bF+QX/UGslFwFmE7LLFFvy2sVhsB+VccfQ j+lJYrcXEizkhx1x0dxyD9olS3P2Nz/bPXP44UOht38AisbqTrbREXdPixnYTkR7LbGT bU05I3u3c5dnozCmupenoV8+8oOQ9hO7kNuD0KOItDyDcuMspZp02tPO/BNNI/0xtzGI NCXfqvsb5kVMyvvvsKwHMo1YkY3kZKzhwF9zhq2iIrg7i4IzADih25nGVzjqcDmbszsy bR4dy1YRRP6MfIyuknX27uN1j/AU2ipToW6Ypv7fFPI203brXVhufO0buKHSIM+v1gsP yNBg== X-Gm-Message-State: AO0yUKVYQKMR+eG5Hy3n5bs6DhJJy2oDiPhJh0Yt6j9AqHYJogZCrBwF 7+s2peOyszvaUvutffK8ucQ= X-Google-Smtp-Source: AK7set8hdy8NdMEduYRpdtXjDh9vZZIvtNq9bj58HQCs0qLhPZHbNkX+8gzB0EunYZA4m+nmhB6V3g== X-Received: by 2002:a05:600c:30ca:b0:3dc:5009:bc74 with SMTP id h10-20020a05600c30ca00b003dc5009bc74mr5819046wmn.7.1676846648146; Sun, 19 Feb 2023 14:44:08 -0800 (PST) Received: from DESKTOP-KPIMD3E.localdomain ([2407:d000:f:3985:100a:5b84:56fb:c266]) by smtp.gmail.com with ESMTPSA id o8-20020a05600c510800b003e220998b6bsm9900485wms.17.2023.02.19.14.44.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Feb 2023 14:44:07 -0800 (PST) From: Tanzeel-inline To: olivier.matz@6wind.com, thomas@monjalon.net Cc: dev@dpdk.org, Tanzeel Ahmed Subject: [PATCH v2] lib/net: add MPLS insert and strip functionality Date: Mon, 20 Feb 2023 03:43:34 +0500 Message-Id: <20230219224334.309-1-tanxeel1.ahmed@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Tanzeel Ahmed This patch is new version of [PATCH] lib/net: added push MPLS header API. I have also added the MPLS strip functionality in the same patch to address the question asked in last patch. > You should explain why you add this function. None of the foundational NICs currently supports MPLS insertion and stripping, this functionality can help users who rely on MPLS in their network application. > I'm not sure it should be inline I did for perfomance in high-traffic application. Signed-off-by: Tanzeel Ahmed --- v2: * marked experimental * coding style fixed * changed rte_memcpy to memcpy * mpls header marked as const in parameter * added MPLS stripping functionality --- .mailmap | 1 + lib/net/rte_mpls.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/.mailmap b/.mailmap index a9f4f28..2af4e0d 100644 --- a/.mailmap +++ b/.mailmap @@ -1312,6 +1312,7 @@ Takeshi Yoshimura Takuya Asada Tal Avraham Tal Shnaiderman +Tanzeel Ahmed Tao Y Yang Tao Zhu Taripin Samuel diff --git a/lib/net/rte_mpls.h b/lib/net/rte_mpls.h index 51523e7..b51520f 100644 --- a/lib/net/rte_mpls.h +++ b/lib/net/rte_mpls.h @@ -13,6 +13,8 @@ #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -36,6 +38,101 @@ struct rte_mpls_hdr { uint8_t ttl; /**< Time to live. */ } __rte_packed; +#define RTE_MPLS_HLEN 4 /**< Length of MPLS header. */ + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Insert MPLS header into the packet. + * If it's first MPLS header to be inserted in the packet, + * - Updates the ether type. + * - Sets the MPLS bottom-of-stack bit to 1. + * + * @param m + * The pointer to the mbuf. + * @param mp + * The pointer to the MPLS header. + * @return + * 0 on success, -1 on error + */ +__rte_experimental +static int +rte_mpls_push_over_l2(struct rte_mbuf **m, const struct rte_mpls_hdr *mp) +{ + struct rte_ether_hdr *oh, *nh; + struct rte_mpls_hdr *mph; + + /* Can't insert header if mbuf is shared */ + if (!RTE_MBUF_DIRECT(*m) || rte_mbuf_refcnt_read(*m) > 1) + return -EINVAL; + + /* Can't insert header if ethernet frame doesn't exist */ + if (rte_pktmbuf_data_len(*m) < RTE_ETHER_HDR_LEN) + return -EINVAL; + + oh = rte_pktmbuf_mtod(*m, struct rte_ether_hdr *); + nh = (struct rte_ether_hdr *)(void *) + rte_pktmbuf_prepend(*m, sizeof(struct rte_mpls_hdr)); + if (nh == NULL) + return -ENOSPC; + + memmove(nh, oh, RTE_ETHER_HDR_LEN); + + /* Copy the MPLS header after ethernet frame */ + mph = rte_pktmbuf_mtod_offset(*m, struct rte_mpls_hdr*, + sizeof(struct rte_ether_hdr)); + memcpy(mph, mp, RTE_MPLS_HLEN); + + mph->tag_msb = rte_cpu_to_be_16(mp->tag_msb); + + /* If first MPLS header, update ether type and bottom-of-stack bit */ + if (nh->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS)) { + nh->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS); + mph->bs = 1; + } else { + mph->bs = 0; + } + + return 0; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Strips MPLS from the packet. Doesn't update the ether type + * + * @param m + * The pointer to the mbuf. + * @return + * 0 on success, -1 on error + */ +__rte_experimental +static inline int +rte_mpls_strip_over_l2(struct rte_mbuf *m) +{ + struct rte_ether_hdr *eh = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); + struct rte_mpls_hdr *mph; + bool mpls_exist = true; + + if (eh->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS)) + return -1; + + /* Stripping all MPLS header */ + while (mpls_exist) { + mph = rte_pktmbuf_mtod_offset(m, struct rte_mpls_hdr*, + sizeof(struct rte_ether_hdr)); + if (mph->bs & 1) + mpls_exist = false; + memmove(rte_pktmbuf_adj(m, sizeof(struct rte_mpls_hdr)), + eh, sizeof(struct rte_ether_hdr)); + eh = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); + } + + return 0; +} + #ifdef __cplusplus } #endif -- 1.8.3.1