From patchwork Sat Dec 29 18:51:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Ovsiienko X-Patchwork-Id: 49356 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 514F35B2A; Sat, 29 Dec 2018 19:51:53 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 55DD35592 for ; Sat, 29 Dec 2018 19:51:48 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from viacheslavo@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Dec 2018 20:51:47 +0200 Received: from pegasus12.mtr.labs.mlnx. (pegasus12.mtr.labs.mlnx [10.210.17.40]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id wBTIplpd012118; Sat, 29 Dec 2018 20:51:47 +0200 From: Viacheslav Ovsiienko To: shahafs@mellanox.com Cc: dev@dpdk.org Date: Sat, 29 Dec 2018 18:51:38 +0000 Message-Id: <1546109501-24865-2-git-send-email-viacheslavo@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1546109501-24865-1-git-send-email-viacheslavo@mellanox.com> References: <1546109501-24865-1-git-send-email-viacheslavo@mellanox.com> Subject: [dpdk-dev] [PATCH 1/4] net/mlx5: add tos and ttl flower match and tunnel keys 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" This patch is a preparation for adding the type-of-service and time-to-live IP header fields support on E-Switch. There are two types of keys added - one for match pattern, other for tunnel encapsulation header. This issue is critical for some Open VSwitch configuration on overlayed (tunneled) networks, where the tos field can be inherited from outer header to inner header. Signed-off-by: Viacheslav Ovsiienko --- drivers/net/mlx5/Makefile | 50 ++++++++++++++++++++++++++++++++++++++++ drivers/net/mlx5/meson.build | 20 ++++++++++++++++ drivers/net/mlx5/mlx5_flow_tcf.c | 35 ++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index 895cdfe..6246f49 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -373,6 +373,26 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh enum TCA_FLOWER_KEY_TCP_FLAGS_MASK \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_TCA_FLOWER_KEY_IP_TOS \ + linux/pkt_cls.h \ + enum TCA_FLOWER_KEY_IP_TOS \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_TCA_FLOWER_KEY_IP_TOS_MASK \ + linux/pkt_cls.h \ + enum TCA_FLOWER_KEY_IP_TOS_MASK \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_TCA_FLOWER_KEY_IP_TTL \ + linux/pkt_cls.h \ + enum TCA_FLOWER_KEY_IP_TTL \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_TCA_FLOWER_KEY_IP_TTL_MASK \ + linux/pkt_cls.h \ + enum TCA_FLOWER_KEY_IP_TTL_MASK \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_TC_ACT_GOTO_CHAIN \ linux/pkt_cls.h \ define TC_ACT_GOTO_CHAIN \ @@ -448,6 +468,26 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh enum TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_TCA_FLOWER_KEY_ENC_IP_TOS \ + linux/pkt_cls.h \ + enum TCA_FLOWER_KEY_ENC_IP_TOS \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_TCA_FLOWER_KEY_ENC_IP_TOS_MASK \ + linux/pkt_cls.h \ + enum TCA_FLOWER_KEY_ENC_IP_TOS_MASK \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_TCA_FLOWER_KEY_ENC_IP_TTL \ + linux/pkt_cls.h \ + enum TCA_FLOWER_KEY_ENC_IP_TTL \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_TCA_FLOWER_KEY_ENC_IP_TTL_MASK \ + linux/pkt_cls.h \ + enum TCA_FLOWER_KEY_ENC_IP_TTL_MASK \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_TC_ACT_TUNNEL_KEY \ linux/tc_act/tc_tunnel_key.h \ define TCA_ACT_TUNNEL_KEY \ @@ -458,6 +498,16 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh enum TCA_TUNNEL_KEY_ENC_DST_PORT \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_TCA_TUNNEL_KEY_ENC_TOS \ + linux/tc_act/tc_tunnel_key.h \ + enum TCA_TUNNEL_KEY_ENC_TOS \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_TCA_TUNNEL_KEY_ENC_TTL \ + linux/tc_act/tc_tunnel_key.h \ + enum TCA_TUNNEL_KEY_ENC_TTL \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_TCA_TUNNEL_KEY_NO_CSUM \ linux/tc_act/tc_tunnel_key.h \ enum TCA_TUNNEL_KEY_NO_CSUM \ diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build index 28938db..d64ae1b 100644 --- a/drivers/net/mlx5/meson.build +++ b/drivers/net/mlx5/meson.build @@ -192,6 +192,14 @@ if build 'TCA_FLOWER_KEY_TCP_FLAGS' ], [ 'HAVE_TCA_FLOWER_KEY_TCP_FLAGS_MASK', 'linux/pkt_cls.h', 'TCA_FLOWER_KEY_TCP_FLAGS_MASK' ], + [ 'HAVE_TCA_FLOWER_KEY_IP_TOS', 'linux/pkt_cls.h', + 'TCA_FLOWER_KEY_IP_TOS' ], + [ 'HAVE_TCA_FLOWER_KEY_IP_TOS_MASK', 'linux/pkt_cls.h', + 'TCA_FLOWER_KEY_IP_TOS_MASK' ], + [ 'HAVE_TCA_FLOWER_KEY_IP_TTL', 'linux/pkt_cls.h', + 'TCA_FLOWER_KEY_IP_TTL' ], + [ 'HAVE_TCA_FLOWER_KEY_IP_TTL_MASK', 'linux/pkt_cls.h', + 'TCA_FLOWER_KEY_IP_TTL_MASK' ], [ 'HAVE_TC_ACT_GOTO_CHAIN', 'linux/pkt_cls.h', 'TC_ACT_GOTO_CHAIN' ], [ 'HAVE_TC_ACT_VLAN', 'linux/tc_act/tc_vlan.h', @@ -222,10 +230,22 @@ if build 'TCA_FLOWER_KEY_ENC_UDP_DST_PORT' ], [ 'HAVE_TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK', 'linux/pkt_cls.h', 'TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK' ], + [ 'HAVE_TCA_FLOWER_KEY_ENC_IP_TOS', 'linux/pkt_cls.h', + 'TCA_FLOWER_KEY_ENC_IP_TOS' ], + [ 'HAVE_TCA_FLOWER_KEY_ENC_IP_TOS_MASK', 'linux/pkt_cls.h', + 'TCA_FLOWER_KEY_ENC_IP_TOS_MASK' ], + [ 'HAVE_TCA_FLOWER_KEY_ENC_IP_TTL', 'linux/pkt_cls.h', + 'TCA_FLOWER_KEY_ENC_IP_TTL' ], + [ 'HAVE_TCA_FLOWER_KEY_ENC_IP_TTL_MASK', 'linux/pkt_cls.h', + 'TCA_FLOWER_KEY_ENC_IP_TTL_MASK' ], [ 'HAVE_TC_ACT_TUNNEL_KEY', 'linux/tc_act/tc_tunnel_key.h', 'TCA_ACT_TUNNEL_KEY' ], [ 'HAVE_TCA_TUNNEL_KEY_ENC_DST_PORT', 'linux/tc_act/tc_tunnel_key.h', 'TCA_TUNNEL_KEY_ENC_DST_PORT' ], + [ 'HAVE_TCA_TUNNEL_KEY_ENC_TOS', 'linux/tc_act/tc_tunnel_key.h', + 'TCA_TUNNEL_KEY_ENC_TOS' ], + [ 'HAVE_TCA_TUNNEL_KEY_ENC_TTL', 'linux/tc_act/tc_tunnel_key.h', + 'TCA_TUNNEL_KEY_ENC_TTL' ], [ 'HAVE_TCA_TUNNEL_KEY_NO_CSUM', 'linux/tc_act/tc_tunnel_key.h', 'TCA_TUNNEL_KEY_NO_CSUM' ], [ 'HAVE_TC_ACT_PEDIT', 'linux/tc_act/tc_pedit.h', diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c index 9e5d947..87585ed 100644 --- a/drivers/net/mlx5/mlx5_flow_tcf.c +++ b/drivers/net/mlx5/mlx5_flow_tcf.c @@ -125,6 +125,14 @@ struct tc_pedit_sel { #define TCA_TUNNEL_KEY_NO_CSUM 10 #endif +#ifndef HAVE_TCA_TUNNEL_KEY_ENC_TOS +#define TCA_TUNNEL_KEY_ENC_TOS 12 +#endif + +#ifndef HAVE_TCA_TUNNEL_KEY_ENC_TTL +#define TCA_TUNNEL_KEY_ENC_TTL 13 +#endif + #else /* HAVE_TC_ACT_TUNNEL_KEY */ #define TCA_ACT_TUNNEL_KEY 17 @@ -138,6 +146,8 @@ struct tc_pedit_sel { #define TCA_TUNNEL_KEY_ENC_KEY_ID 7 #define TCA_TUNNEL_KEY_ENC_DST_PORT 9 #define TCA_TUNNEL_KEY_NO_CSUM 10 +#define TCA_TUNNEL_KEY_ENC_TOS 12 +#define TCA_TUNNEL_KEY_ENC_TTL 13 struct tc_tunnel_key { tc_gen; @@ -292,6 +302,31 @@ struct tc_tunnel_key { #ifndef HAVE_TCA_FLOWER_KEY_TCP_FLAGS_MASK #define TCA_FLOWER_KEY_TCP_FLAGS_MASK 72 #endif +#ifndef HAVE_TCA_FLOWER_KEY_IP_TOS +#define TCA_FLOWER_KEY_IP_TOS 73 +#endif +#ifndef HAVE_TCA_FLOWER_KEY_IP_TOS_MASK +#define TCA_FLOWER_KEY_IP_TOS_MASK 74 +#endif +#ifndef HAVE_TCA_FLOWER_KEY_IP_TTL +#define TCA_FLOWER_KEY_IP_TTL 75 +#endif +#ifndef HAVE_TCA_FLOWER_KEY_IP_TTL_MASK +#define TCA_FLOWER_KEY_IP_TTL_MASK 76 +#endif +#ifndef HAVE_TCA_FLOWER_KEY_ENC_IP_TOS +#define TCA_FLOWER_KEY_ENC_IP_TOS 80 +#endif +#ifndef HAVE_TCA_FLOWER_KEY_ENC_IP_TOS_MASK +#define TCA_FLOWER_KEY_ENC_IP_TOS_MASK 81 +#endif +#ifndef HAVE_TCA_FLOWER_KEY_ENC_IP_TTL +#define TCA_FLOWER_KEY_ENC_IP_TTL 82 +#endif +#ifndef HAVE_TCA_FLOWER_KEY_ENC_IP_TTL_MASK +#define TCA_FLOWER_KEY_ENC_IP_TTL_MASK 83 +#endif + #ifndef HAVE_TC_ACT_GOTO_CHAIN #define TC_ACT_GOTO_CHAIN 0x20000000 #endif From patchwork Sat Dec 29 18:51:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Ovsiienko X-Patchwork-Id: 49355 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 7AC5C58CB; Sat, 29 Dec 2018 19:51:51 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 4EBE74D3A for ; Sat, 29 Dec 2018 19:51:48 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from viacheslavo@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Dec 2018 20:51:47 +0200 Received: from pegasus12.mtr.labs.mlnx. (pegasus12.mtr.labs.mlnx [10.210.17.40]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id wBTIplpe012118; Sat, 29 Dec 2018 20:51:47 +0200 From: Viacheslav Ovsiienko To: shahafs@mellanox.com Cc: dev@dpdk.org Date: Sat, 29 Dec 2018 18:51:39 +0000 Message-Id: <1546109501-24865-3-git-send-email-viacheslavo@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1546109501-24865-1-git-send-email-viacheslavo@mellanox.com> References: <1546109501-24865-1-git-send-email-viacheslavo@mellanox.com> Subject: [dpdk-dev] [PATCH 2/4] net/mlx5: add tos and ttl fields support on E-Switch 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" This patch adds the type-of-service and time-to-live IP header fields support on E-Switch. There match pattern for both fields with masking is added. Also these fields can be set for VXLAN tunnel encapsulation header. This issue is critical for some Open VSwitch configuration on overlayed (tunneled) networks, where the tos field can be inherited from outer header to inner header. Signed-off-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5_flow_tcf.c | 166 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 160 insertions(+), 6 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c index 87585ed..ca8ea0b 100644 --- a/drivers/net/mlx5/mlx5_flow_tcf.c +++ b/drivers/net/mlx5/mlx5_flow_tcf.c @@ -372,6 +372,8 @@ enum flow_tcf_tunact_type { #define FLOW_TCF_ENCAP_UDP_SRC (1u << 6) #define FLOW_TCF_ENCAP_UDP_DST (1u << 7) #define FLOW_TCF_ENCAP_VXLAN_VNI (1u << 8) +#define FLOW_TCF_ENCAP_IP_TTL (1u << 9) +#define FLOW_TCF_ENCAP_IP_TOS (1u << 10) /** * Structure for holding netlink context. @@ -457,6 +459,8 @@ struct flow_tcf_vxlan_decap { struct flow_tcf_vxlan_encap { struct flow_tcf_tunnel_hdr hdr; uint32_t mask; + uint8_t ip_tos; + uint8_t ip_ttl_hop; struct { struct ether_addr dst; struct ether_addr src; @@ -1303,6 +1307,20 @@ struct pedit_parser { " must be specified for" " vxlan encapsulation"); } + if (mask->hdr.type_of_service && + mask->hdr.type_of_service != 0xff) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask, + "no support for partial mask on" + " \"ipv4.hdr.type_of_service\" field" + " for vxlan encapsulation"); + if (mask->hdr.time_to_live && + mask->hdr.time_to_live != 0xff) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask, + "no support for partial mask on" + " \"ipv4.hdr.time_to_live\" field" + " for vxlan encapsulation"); return 0; } @@ -1324,6 +1342,7 @@ struct pedit_parser { { const struct rte_flow_item_ipv6 *spec = item->spec; const struct rte_flow_item_ipv6 *mask = item->mask; + uint8_t msk6; if (!spec) { /* @@ -1389,6 +1408,20 @@ struct pedit_parser { " must be specified for" " vxlan encapsulation"); } + msk6 = (rte_be_to_cpu_32(mask->hdr.vtc_flow) >> + IPV6_HDR_TC_SHIFT) & 0xff; + if (msk6 && msk6 != 0xff) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask, + "no support for partial mask on" + " \"ipv6.hdr.vtc_flow.tos\" field" + " for vxlan encapsulation"); + if (mask->hdr.hop_limits && mask->hdr.hop_limits != 0xff) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask, + "no support for partial mask on" + " \"ipv6.hdr.hop_limits\" field" + " for vxlan encapsulation"); return 0; } @@ -2476,16 +2509,31 @@ struct pedit_parser { SZ_NLATTR_TYPE_OF(uint8_t) + /* VLAN prio. */ SZ_NLATTR_TYPE_OF(uint16_t); /* VLAN ID. */ break; - case RTE_FLOW_ITEM_TYPE_IPV4: + case RTE_FLOW_ITEM_TYPE_IPV4: { + const struct rte_flow_item_ipv4 *ipv4 = items->mask; + size += SZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */ SZ_NLATTR_TYPE_OF(uint32_t) * 4; /* dst/src IP addr and mask. */ + if (ipv4 && ipv4->hdr.time_to_live) + size += SZ_NLATTR_TYPE_OF(uint8_t) * 2; + if (ipv4 && ipv4->hdr.type_of_service) + size += SZ_NLATTR_TYPE_OF(uint8_t) * 2; break; - case RTE_FLOW_ITEM_TYPE_IPV6: + } + case RTE_FLOW_ITEM_TYPE_IPV6: { + const struct rte_flow_item_ipv6 *ipv6 = items->mask; + size += SZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */ SZ_NLATTR_DATA_OF(IPV6_ADDR_LEN) * 4; /* dst/src IP addr and mask. */ + if (ipv6 && ipv6->hdr.hop_limits) + size += SZ_NLATTR_TYPE_OF(uint8_t) * 2; + if (ipv6 && (rte_be_to_cpu_32(ipv6->hdr.vtc_flow) & + (0xfful << IPV6_HDR_TC_SHIFT))) + size += SZ_NLATTR_TYPE_OF(uint8_t) * 2; break; + } case RTE_FLOW_ITEM_TYPE_UDP: size += SZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */ SZ_NLATTR_TYPE_OF(uint16_t) * 4; @@ -2553,12 +2601,27 @@ struct pedit_parser { case RTE_FLOW_ITEM_TYPE_ETH: /* This item does not require message buffer. */ break; - case RTE_FLOW_ITEM_TYPE_IPV4: + case RTE_FLOW_ITEM_TYPE_IPV4: { + const struct rte_flow_item_ipv4 *ipv4 = items->mask; + size += SZ_NLATTR_DATA_OF(IPV4_ADDR_LEN) * 2; + if (ipv4 && ipv4->hdr.time_to_live) + size += SZ_NLATTR_TYPE_OF(uint8_t) * 2; + if (ipv4 && ipv4->hdr.type_of_service) + size += SZ_NLATTR_TYPE_OF(uint8_t) * 2; break; - case RTE_FLOW_ITEM_TYPE_IPV6: + } + case RTE_FLOW_ITEM_TYPE_IPV6: { + const struct rte_flow_item_ipv6 *ipv6 = items->mask; + size += SZ_NLATTR_DATA_OF(IPV6_ADDR_LEN) * 2; + if (ipv6 && ipv6->hdr.hop_limits) + size += SZ_NLATTR_TYPE_OF(uint8_t) * 2; + if (ipv6 && (rte_be_to_cpu_32(ipv6->hdr.vtc_flow) & + (0xfful << IPV6_HDR_TC_SHIFT))) + size += SZ_NLATTR_TYPE_OF(uint8_t) * 2; break; + } case RTE_FLOW_ITEM_TYPE_UDP: { const struct rte_flow_item_udp *udp = items->mask; @@ -2936,11 +2999,14 @@ struct pedit_parser { * * @param[in] spec * RTE_FLOW_ITEM_TYPE_IPV4 entry specification. + * @param[in] mask + * RTE_FLOW_ITEM_TYPE_IPV4 entry mask. * @param[out] encap * Structure to fill the gathered IPV4 address data. */ static void flow_tcf_parse_vxlan_encap_ipv4(const struct rte_flow_item_ipv4 *spec, + const struct rte_flow_item_ipv4 *mask, struct flow_tcf_vxlan_encap *encap) { /* Item must be validated before. No redundant checks. */ @@ -2949,6 +3015,14 @@ struct pedit_parser { encap->ipv4.src = spec->hdr.src_addr; encap->mask |= FLOW_TCF_ENCAP_IPV4_SRC | FLOW_TCF_ENCAP_IPV4_DST; + if (mask && mask->hdr.type_of_service) { + encap->mask |= FLOW_TCF_ENCAP_IP_TOS; + encap->ip_tos = spec->hdr.type_of_service; + } + if (mask && mask->hdr.time_to_live) { + encap->mask |= FLOW_TCF_ENCAP_IP_TTL; + encap->ip_ttl_hop = spec->hdr.time_to_live; + } } /** @@ -2959,11 +3033,14 @@ struct pedit_parser { * * @param[in] spec * RTE_FLOW_ITEM_TYPE_IPV6 entry specification. + * @param[in] mask + * RTE_FLOW_ITEM_TYPE_IPV6 entry mask. * @param[out] encap * Structure to fill the gathered IPV6 address data. */ static void flow_tcf_parse_vxlan_encap_ipv6(const struct rte_flow_item_ipv6 *spec, + const struct rte_flow_item_ipv6 *mask, struct flow_tcf_vxlan_encap *encap) { /* Item must be validated before. No redundant checks. */ @@ -2972,6 +3049,19 @@ struct pedit_parser { memcpy(encap->ipv6.src, spec->hdr.src_addr, IPV6_ADDR_LEN); encap->mask |= FLOW_TCF_ENCAP_IPV6_SRC | FLOW_TCF_ENCAP_IPV6_DST; + if (mask) { + if ((rte_be_to_cpu_32(mask->hdr.vtc_flow) >> + IPV6_HDR_TC_SHIFT) & 0xff) { + encap->mask |= FLOW_TCF_ENCAP_IP_TOS; + encap->ip_tos = (rte_be_to_cpu_32 + (spec->hdr.vtc_flow) >> + IPV6_HDR_TC_SHIFT) & 0xff; + } + if (mask->hdr.hop_limits) { + encap->mask |= FLOW_TCF_ENCAP_IP_TTL; + encap->ip_ttl_hop = spec->hdr.hop_limits; + } + } } /** @@ -3066,11 +3156,15 @@ struct pedit_parser { break; case RTE_FLOW_ITEM_TYPE_IPV4: spec.ipv4 = items->spec; - flow_tcf_parse_vxlan_encap_ipv4(spec.ipv4, encap); + mask.ipv4 = items->mask; + flow_tcf_parse_vxlan_encap_ipv4(spec.ipv4, mask.ipv4, + encap); break; case RTE_FLOW_ITEM_TYPE_IPV6: spec.ipv6 = items->spec; - flow_tcf_parse_vxlan_encap_ipv6(spec.ipv6, encap); + mask.ipv6 = items->mask; + flow_tcf_parse_vxlan_encap_ipv6(spec.ipv6, mask.ipv6, + encap); break; case RTE_FLOW_ITEM_TYPE_UDP: mask.udp = items->mask; @@ -3383,10 +3477,35 @@ struct pedit_parser { TCA_FLOWER_KEY_IPV4_DST_MASK, mask.ipv4->hdr.dst_addr); } + if (mask.ipv4->hdr.time_to_live) { + mnl_attr_put_u8 + (nlh, tunnel_outer ? + TCA_FLOWER_KEY_ENC_IP_TTL : + TCA_FLOWER_KEY_IP_TTL, + spec.ipv4->hdr.time_to_live); + mnl_attr_put_u8 + (nlh, tunnel_outer ? + TCA_FLOWER_KEY_ENC_IP_TTL_MASK : + TCA_FLOWER_KEY_IP_TTL_MASK, + mask.ipv4->hdr.time_to_live); + } + if (mask.ipv4->hdr.type_of_service) { + mnl_attr_put_u8 + (nlh, tunnel_outer ? + TCA_FLOWER_KEY_ENC_IP_TOS : + TCA_FLOWER_KEY_IP_TOS, + spec.ipv4->hdr.type_of_service); + mnl_attr_put_u8 + (nlh, tunnel_outer ? + TCA_FLOWER_KEY_ENC_IP_TOS_MASK : + TCA_FLOWER_KEY_IP_TOS_MASK, + mask.ipv4->hdr.type_of_service); + } assert(dev_flow->tcf.nlsize >= nlh->nlmsg_len); break; case RTE_FLOW_ITEM_TYPE_IPV6: { bool ipv6_src, ipv6_dst; + uint8_t msk6, tos6; item_flags |= (item_flags & MLX5_FLOW_LAYER_TUNNEL) ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : @@ -3472,6 +3591,33 @@ struct pedit_parser { IPV6_ADDR_LEN, mask.ipv6->hdr.dst_addr); } + if (mask.ipv6->hdr.hop_limits) { + mnl_attr_put_u8 + (nlh, tunnel_outer ? + TCA_FLOWER_KEY_ENC_IP_TTL : + TCA_FLOWER_KEY_IP_TTL, + spec.ipv6->hdr.hop_limits); + mnl_attr_put_u8 + (nlh, tunnel_outer ? + TCA_FLOWER_KEY_ENC_IP_TTL_MASK : + TCA_FLOWER_KEY_IP_TTL_MASK, + mask.ipv6->hdr.hop_limits); + } + msk6 = (rte_be_to_cpu_32(mask.ipv6->hdr.vtc_flow) >> + IPV6_HDR_TC_SHIFT) & 0xff; + if (msk6) { + tos6 = (rte_be_to_cpu_32 + (spec.ipv6->hdr.vtc_flow) >> + IPV6_HDR_TC_SHIFT) & 0xff; + mnl_attr_put_u8 + (nlh, tunnel_outer ? + TCA_FLOWER_KEY_ENC_IP_TOS : + TCA_FLOWER_KEY_IP_TOS, tos6); + mnl_attr_put_u8 + (nlh, tunnel_outer ? + TCA_FLOWER_KEY_ENC_IP_TOS_MASK : + TCA_FLOWER_KEY_IP_TOS_MASK, msk6); + } assert(dev_flow->tcf.nlsize >= nlh->nlmsg_len); break; } @@ -3824,6 +3970,14 @@ struct pedit_parser { TCA_TUNNEL_KEY_ENC_IPV6_DST, sizeof(encap.vxlan->ipv6.dst), &encap.vxlan->ipv6.dst); + if (encap.vxlan->mask & FLOW_TCF_ENCAP_IP_TTL) + mnl_attr_put_u8(nlh, + TCA_TUNNEL_KEY_ENC_TTL, + encap.vxlan->ip_ttl_hop); + if (encap.vxlan->mask & FLOW_TCF_ENCAP_IP_TOS) + mnl_attr_put_u8(nlh, + TCA_TUNNEL_KEY_ENC_TOS, + encap.vxlan->ip_tos); if (encap.vxlan->mask & FLOW_TCF_ENCAP_VXLAN_VNI) mnl_attr_put_u32(nlh, TCA_TUNNEL_KEY_ENC_KEY_ID, From patchwork Sat Dec 29 18:51:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Ovsiienko X-Patchwork-Id: 49358 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 896425F16; Sat, 29 Dec 2018 19:51:56 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 47EF74CA0 for ; Sat, 29 Dec 2018 19:51:48 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from viacheslavo@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Dec 2018 20:51:47 +0200 Received: from pegasus12.mtr.labs.mlnx. (pegasus12.mtr.labs.mlnx [10.210.17.40]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id wBTIplpf012118; Sat, 29 Dec 2018 20:51:47 +0200 From: Viacheslav Ovsiienko To: shahafs@mellanox.com Cc: dev@dpdk.org Date: Sat, 29 Dec 2018 18:51:40 +0000 Message-Id: <1546109501-24865-4-git-send-email-viacheslavo@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1546109501-24865-1-git-send-email-viacheslavo@mellanox.com> References: <1546109501-24865-1-git-send-email-viacheslavo@mellanox.com> Subject: [dpdk-dev] [PATCH 3/4] net/mlx5: add tos and ttl validation on E-Switch 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" This patch adds the type-of-service and time-to-live IP header fields validation on E-Switch, both for match pattern and VXLAN encapsulation action IP header itesm. The E-Switch flows will use the common mlx5_flow_validate_item_ipv4/6 routines with added extra parameter, specifying the supported fields mask. Signed-off-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5_flow.c | 14 ++++++++++++-- drivers/net/mlx5/mlx5_flow.h | 2 ++ drivers/net/mlx5/mlx5_flow_dv.c | 4 ++-- drivers/net/mlx5/mlx5_flow_tcf.c | 24 ++++++++++++++++-------- drivers/net/mlx5/mlx5_flow_verbs.c | 4 ++-- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index ee129b9..0fd6ed5 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -1141,6 +1141,9 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, * Item specification. * @param[in] item_flags * Bit-fields that holds the items detected until now. + * @param[in] acc_mask + * Acceptable mask, if NULL default internal default mask + * will be used to check whether item fields are supported. * @param[out] error * Pointer to error structure. * @@ -1150,6 +1153,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, int mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item, uint64_t item_flags, + const struct rte_flow_item_ipv4 *acc_mask, struct rte_flow_error *error) { const struct rte_flow_item_ipv4 *mask = item->mask; @@ -1185,7 +1189,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, "partial mask is not supported" " for protocol"); ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, - (const uint8_t *)&nic_mask, + acc_mask ? (const uint8_t *)acc_mask + : (const uint8_t *)&nic_mask, sizeof(struct rte_flow_item_ipv4), error); if (ret < 0) @@ -1200,6 +1205,9 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, * Item specification. * @param[in] item_flags * Bit-fields that holds the items detected until now. + * @param[in] acc_mask + * Acceptable mask, if NULL default internal default mask + * will be used to check whether item fields are supported. * @param[out] error * Pointer to error structure. * @@ -1209,6 +1217,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, int mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item, uint64_t item_flags, + const struct rte_flow_item_ipv6 *acc_mask, struct rte_flow_error *error) { const struct rte_flow_item_ipv6 *mask = item->mask; @@ -1243,7 +1252,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, if (!mask) mask = &rte_flow_item_ipv6_mask; ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, - (const uint8_t *)&nic_mask, + acc_mask ? (const uint8_t *)acc_mask + : (const uint8_t *)&nic_mask, sizeof(struct rte_flow_item_ipv6), error); if (ret < 0) diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 4a7c052..8e4eacb 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -381,9 +381,11 @@ int mlx5_flow_validate_item_gre(const struct rte_flow_item *item, struct rte_flow_error *error); int mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item, uint64_t item_flags, + const struct rte_flow_item_ipv4 *acc_mask, struct rte_flow_error *error); int mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item, uint64_t item_flags, + const struct rte_flow_item_ipv6 *acc_mask, struct rte_flow_error *error); int mlx5_flow_validate_item_mpls(struct rte_eth_dev *dev, const struct rte_flow_item *item, diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 1f31874..ab87165 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -808,7 +808,7 @@ break; case RTE_FLOW_ITEM_TYPE_IPV4: ret = mlx5_flow_validate_item_ipv4(items, item_flags, - error); + NULL, error); if (ret < 0) return ret; last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 : @@ -829,7 +829,7 @@ break; case RTE_FLOW_ITEM_TYPE_IPV6: ret = mlx5_flow_validate_item_ipv6(items, item_flags, - error); + NULL, error); if (ret < 0) return ret; last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c index ca8ea0b..16fc936 100644 --- a/drivers/net/mlx5/mlx5_flow_tcf.c +++ b/drivers/net/mlx5/mlx5_flow_tcf.c @@ -532,11 +532,15 @@ struct flow_tcf_stats_basic { }, .ipv4.hdr = { .next_proto_id = 0xff, + .time_to_live = 0xff, + .type_of_service = 0xff, .src_addr = RTE_BE32(0xffffffff), .dst_addr = RTE_BE32(0xffffffff), }, .ipv6.hdr = { .proto = 0xff, + .vtc_flow = RTE_BE32(0xfful << IPV6_HDR_FL_SHIFT), + .hop_limits = 0xff, .src_addr = "\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff", @@ -1589,8 +1593,9 @@ struct pedit_parser { break; break; case RTE_FLOW_ITEM_TYPE_IPV4: - ret = mlx5_flow_validate_item_ipv4(items, item_flags, - error); + ret = mlx5_flow_validate_item_ipv4 + (items, item_flags, + &flow_tcf_mask_supported.ipv4, error); if (ret < 0) return ret; ret = flow_tcf_validate_vxlan_encap_ipv4(items, error); @@ -1599,8 +1604,9 @@ struct pedit_parser { item_flags |= MLX5_FLOW_LAYER_OUTER_L3_IPV4; break; case RTE_FLOW_ITEM_TYPE_IPV6: - ret = mlx5_flow_validate_item_ipv6(items, item_flags, - error); + ret = mlx5_flow_validate_item_ipv6 + (items, item_flags, + &flow_tcf_mask_supported.ipv6, error); if (ret < 0) return ret; ret = flow_tcf_validate_vxlan_encap_ipv6(items, error); @@ -2119,8 +2125,9 @@ struct pedit_parser { vlan_etype = spec.vlan->inner_type; break; case RTE_FLOW_ITEM_TYPE_IPV4: - ret = mlx5_flow_validate_item_ipv4(items, item_flags, - error); + ret = mlx5_flow_validate_item_ipv4 + (items, item_flags, + &flow_tcf_mask_supported.ipv4, error); if (ret < 0) return ret; item_flags |= (item_flags & MLX5_FLOW_LAYER_TUNNEL) ? @@ -2179,8 +2186,9 @@ struct pedit_parser { } break; case RTE_FLOW_ITEM_TYPE_IPV6: - ret = mlx5_flow_validate_item_ipv6(items, item_flags, - error); + ret = mlx5_flow_validate_item_ipv6 + (items, item_flags, + &flow_tcf_mask_supported.ipv6, error); if (ret < 0) return ret; item_flags |= (item_flags & MLX5_FLOW_LAYER_TUNNEL) ? diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c index 81ec59d..130cf68 100644 --- a/drivers/net/mlx5/mlx5_flow_verbs.c +++ b/drivers/net/mlx5/mlx5_flow_verbs.c @@ -1053,7 +1053,7 @@ break; case RTE_FLOW_ITEM_TYPE_IPV4: ret = mlx5_flow_validate_item_ipv4(items, item_flags, - error); + NULL, error); if (ret < 0) return ret; last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 : @@ -1074,7 +1074,7 @@ break; case RTE_FLOW_ITEM_TYPE_IPV6: ret = mlx5_flow_validate_item_ipv6(items, item_flags, - error); + NULL, error); if (ret < 0) return ret; last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : From patchwork Sat Dec 29 18:51:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Ovsiienko X-Patchwork-Id: 49354 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 358044CAB; Sat, 29 Dec 2018 19:51:50 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 523004F9C for ; Sat, 29 Dec 2018 19:51:48 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from viacheslavo@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Dec 2018 20:51:47 +0200 Received: from pegasus12.mtr.labs.mlnx. (pegasus12.mtr.labs.mlnx [10.210.17.40]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id wBTIplpg012118; Sat, 29 Dec 2018 20:51:47 +0200 From: Viacheslav Ovsiienko To: shahafs@mellanox.com Cc: dev@dpdk.org Date: Sat, 29 Dec 2018 18:51:41 +0000 Message-Id: <1546109501-24865-5-git-send-email-viacheslavo@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1546109501-24865-1-git-send-email-viacheslavo@mellanox.com> References: <1546109501-24865-1-git-send-email-viacheslavo@mellanox.com> Subject: [dpdk-dev] [PATCH 4/4] app/testpmd: add tos and ttl field to vxlan encapsulation 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" The new testpmd set vxlan-tos-ttl command is added. It allows to specify tos and tll fields for encapsulation IP header. IPv4 VXLAN outer header: testpmd> set vxlan-tos-ttl ip-version ipv4 vni 4 udp-src 4 udp-dst 4 ip-tos 0 ip-ttl 255 ip-src 127.0.0.1 ip-dst 128.0.0.1 eth-src 11:11:11:11:11:11 eth-dst 22:22:22:22:22:22 IPv6 VXLAN outer header: testpmd> set vxlan-tos-ttl ip-version ipv6 vni 4 udp-src 4 udp-dst 4 ip-tos 0 ip-ttl 255 ::1 ip-dst ::2222 eth-src 11:11:11:11:11:11 eth-dst 22:22:22:22:22:22 Note: ip-ttl parameter corresponds the nop_limits field for IPv6. Signed-off-by: Viacheslav Ovsiienko --- app/test-pmd/cmdline.c | 63 +++++++++++++++++++++++++++++ app/test-pmd/cmdline_flow.c | 32 +++++++++++++++ app/test-pmd/testpmd.c | 3 ++ app/test-pmd/testpmd.h | 3 ++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 16 ++++++++ 5 files changed, 117 insertions(+) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 3ddc3e0..9e9e898 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -794,6 +794,12 @@ static void cmd_help_long_parsed(void *parsed_result, " eth-dst (eth-dst)\n" " Configure the VXLAN encapsulation for flows.\n\n" + "vxlan-tos-ttl ip-version (ipv4|ipv6) vni (vni) udp-src" + " (udp-src) udp-dst (udp-dst) ip-tos (ip-tos) ip-ttl (ip-ttl)" + " ip-src (ip-src) ip-dst (ip-dst) eth-src (eth-src)" + " eth-dst (eth-dst)\n" + " Configure the VXLAN encapsulation for flows.\n\n" + "nvgre ip-version (ipv4|ipv6) tni (tni) ip-src" " (ip-src) ip-dst (ip-dst) eth-src (eth-src) eth-dst" " (eth-dst)\n" @@ -15034,6 +15040,8 @@ struct cmd_set_vxlan_result { cmdline_ipaddr_t ip_src; cmdline_ipaddr_t ip_dst; uint16_t tci; + uint8_t tos; + uint8_t ttl; struct ether_addr eth_src; struct ether_addr eth_dst; }; @@ -15042,6 +15050,9 @@ struct cmd_set_vxlan_result { TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, set, "set"); cmdline_parse_token_string_t cmd_set_vxlan_vxlan = TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, vxlan, "vxlan"); +cmdline_parse_token_string_t cmd_set_vxlan_vxlan_tos_ttl = + TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, vxlan, + "vxlan-tos-ttl"); cmdline_parse_token_string_t cmd_set_vxlan_vxlan_with_vlan = TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, vxlan, "vxlan-with-vlan"); @@ -15066,6 +15077,16 @@ struct cmd_set_vxlan_result { "udp-dst"); cmdline_parse_token_num_t cmd_set_vxlan_udp_dst_value = TOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, udp_dst, UINT16); +cmdline_parse_token_string_t cmd_set_vxlan_ip_tos = + TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token, + "ip-tos"); +cmdline_parse_token_num_t cmd_set_vxlan_ip_tos_value = + TOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, tos, UINT8); +cmdline_parse_token_string_t cmd_set_vxlan_ip_ttl = + TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token, + "ip-ttl"); +cmdline_parse_token_num_t cmd_set_vxlan_ip_ttl_value = + TOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, ttl, UINT8); cmdline_parse_token_string_t cmd_set_vxlan_ip_src = TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token, "ip-src"); @@ -15104,10 +15125,15 @@ static void cmd_set_vxlan_parsed(void *parsed_result, .vxlan_id = rte_cpu_to_be_32(res->vni) & RTE_BE32(0x00ffffff), }; + vxlan_encap_conf.select_tos = 0; if (strcmp(res->vxlan, "vxlan") == 0) vxlan_encap_conf.select_vlan = 0; else if (strcmp(res->vxlan, "vxlan-with-vlan") == 0) vxlan_encap_conf.select_vlan = 1; + else if (strcmp(res->vxlan, "vxlan-tos-ttl") == 0) { + vxlan_encap_conf.select_vlan = 0; + vxlan_encap_conf.select_tos = 1; + } if (strcmp(res->ip_version, "ipv4") == 0) vxlan_encap_conf.select_ipv4 = 1; else if (strcmp(res->ip_version, "ipv6") == 0) @@ -15117,6 +15143,8 @@ static void cmd_set_vxlan_parsed(void *parsed_result, rte_memcpy(vxlan_encap_conf.vni, &id.vni[1], 3); vxlan_encap_conf.udp_src = rte_cpu_to_be_16(res->udp_src); vxlan_encap_conf.udp_dst = rte_cpu_to_be_16(res->udp_dst); + vxlan_encap_conf.ip_tos = res->tos; + vxlan_encap_conf.ip_ttl = res->ttl; if (vxlan_encap_conf.select_ipv4) { IPV4_ADDR_TO_UINT(res->ip_src, vxlan_encap_conf.ipv4_src); IPV4_ADDR_TO_UINT(res->ip_dst, vxlan_encap_conf.ipv4_dst); @@ -15161,6 +15189,40 @@ static void cmd_set_vxlan_parsed(void *parsed_result, }, }; +cmdline_parse_inst_t cmd_set_vxlan_tos_ttl = { + .f = cmd_set_vxlan_parsed, + .data = NULL, + .help_str = "set vxlan-tos-ttl ip-version ipv4|ipv6 vni udp-src" + " udp-dst ip-tos ip-ttl " + " ip-src ip-dst eth-src " + " eth-dst ", + .tokens = { + (void *)&cmd_set_vxlan_set, + (void *)&cmd_set_vxlan_vxlan_tos_ttl, + (void *)&cmd_set_vxlan_ip_version, + (void *)&cmd_set_vxlan_ip_version_value, + (void *)&cmd_set_vxlan_vni, + (void *)&cmd_set_vxlan_vni_value, + (void *)&cmd_set_vxlan_udp_src, + (void *)&cmd_set_vxlan_udp_src_value, + (void *)&cmd_set_vxlan_udp_dst, + (void *)&cmd_set_vxlan_udp_dst_value, + (void *)&cmd_set_vxlan_ip_tos, + (void *)&cmd_set_vxlan_ip_tos_value, + (void *)&cmd_set_vxlan_ip_ttl, + (void *)&cmd_set_vxlan_ip_ttl_value, + (void *)&cmd_set_vxlan_ip_src, + (void *)&cmd_set_vxlan_ip_src_value, + (void *)&cmd_set_vxlan_ip_dst, + (void *)&cmd_set_vxlan_ip_dst_value, + (void *)&cmd_set_vxlan_eth_src, + (void *)&cmd_set_vxlan_eth_src_value, + (void *)&cmd_set_vxlan_eth_dst, + (void *)&cmd_set_vxlan_eth_dst_value, + NULL, + }, +}; + cmdline_parse_inst_t cmd_set_vxlan_with_vlan = { .f = cmd_set_vxlan_parsed, .data = NULL, @@ -18696,6 +18758,7 @@ struct cmd_show_tx_metadata_result { (cmdline_parse_inst_t *)&cmd_set_port_tm_hierarchy_default, #endif (cmdline_parse_inst_t *)&cmd_set_vxlan, + (cmdline_parse_inst_t *)&cmd_set_vxlan_tos_ttl, (cmdline_parse_inst_t *)&cmd_set_vxlan_with_vlan, (cmdline_parse_inst_t *)&cmd_set_nvgre, (cmdline_parse_inst_t *)&cmd_set_nvgre_with_vlan, diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 5c0108f..a883c72 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -3501,6 +3501,38 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *, if (!vxlan_encap_conf.select_vlan) action_vxlan_encap_data->items[1].type = RTE_FLOW_ITEM_TYPE_VOID; + if (vxlan_encap_conf.select_tos) { + if (vxlan_encap_conf.select_ipv4) { + static struct rte_flow_item_ipv4 ipv4_mask_tos; + + memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, + sizeof(ipv4_mask_tos)); + ipv4_mask_tos.hdr.type_of_service = 0xff; + ipv4_mask_tos.hdr.time_to_live = 0xff; + action_vxlan_encap_data->item_ipv4.hdr.type_of_service = + vxlan_encap_conf.ip_tos; + action_vxlan_encap_data->item_ipv4.hdr.time_to_live = + vxlan_encap_conf.ip_ttl; + action_vxlan_encap_data->items[2].mask = + &ipv4_mask_tos; + } else { + static struct rte_flow_item_ipv6 ipv6_mask_tos; + + memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, + sizeof(ipv6_mask_tos)); + ipv6_mask_tos.hdr.vtc_flow |= + RTE_BE32(0xfful << IPV6_HDR_TC_SHIFT); + ipv6_mask_tos.hdr.hop_limits = 0xff; + action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= + rte_cpu_to_be_32 + ((uint32_t)vxlan_encap_conf.ip_tos << + IPV6_HDR_TC_SHIFT); + action_vxlan_encap_data->item_ipv6.hdr.hop_limits = + vxlan_encap_conf.ip_ttl; + action_vxlan_encap_data->items[2].mask = + &ipv6_mask_tos; + } + } memcpy(action_vxlan_encap_data->item_vxlan.vni, vxlan_encap_conf.vni, RTE_DIM(vxlan_encap_conf.vni)); action->conf = &action_vxlan_encap_data->conf; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 4c75587..99c8505 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -469,6 +469,7 @@ struct rte_fdir_conf fdir_conf = { struct vxlan_encap_conf vxlan_encap_conf = { .select_ipv4 = 1, .select_vlan = 0, + .select_tos = 0, .vni = "\x00\x00\x00", .udp_src = 0, .udp_dst = RTE_BE16(4789), @@ -479,6 +480,8 @@ struct vxlan_encap_conf vxlan_encap_conf = { .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x11\x11", .vlan_tci = 0, + .ip_tos = 0, + .ip_ttl = 255, .eth_src = "\x00\x00\x00\x00\x00\x00", .eth_dst = "\xff\xff\xff\xff\xff\xff", }; diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 3ff11e6..559f2aa 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -488,6 +488,7 @@ struct gso_status { struct vxlan_encap_conf { uint32_t select_ipv4:1; uint32_t select_vlan:1; + uint32_t select_tos:1; uint8_t vni[3]; rte_be16_t udp_src; rte_be16_t udp_dst; @@ -496,6 +497,8 @@ struct vxlan_encap_conf { uint8_t ipv6_src[16]; uint8_t ipv6_dst[16]; rte_be16_t vlan_tci; + uint8_t ip_tos; + uint8_t ip_ttl; uint8_t eth_src[ETHER_ADDR_LEN]; uint8_t eth_dst[ETHER_ADDR_LEN]; }; diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index cbf23e9..635dbf5 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -1583,6 +1583,10 @@ Configure the outer layer to encapsulate a packet inside a VXLAN tunnel:: udp-dst (udp-dst) ip-src (ip-src) ip-dst (ip-dst) vlan-tci (vlan-tci) \ eth-src (eth-src) eth-dst (eth-dst) + set vxlan-tos-ttl ip-version (ipv4|ipv6) vni (vni) udp-src (udp-src) \ + udp-dst (udp-dst) ip-tos (ip-tos) ip-ttl (ip-ttl) ip-src (ip-src) \ + ip-dst (ip-dst) eth-src (eth-src) eth-dst (eth-dst) + Those command will set an internal configuration inside testpmd, any following flow rule using the action vxlan_encap will use the last configuration set. To have a different encapsulation header, one of those commands must be called @@ -4241,6 +4245,12 @@ IPv4 VXLAN outer header:: testpmd> flow create 0 ingress pattern end actions vxlan_encap / queue index 0 / end + testpmd> set vxlan-tos-ttl ip-version ipv4 vni 4 udp-src 4 udp-dst 4 ip-tos 0 + ip-ttl 255 ip-src 127.0.0.1 ip-dst 128.0.0.1 eth-src 11:11:11:11:11:11 + eth-dst 22:22:22:22:22:22 + testpmd> flow create 0 ingress pattern end actions vxlan_encap / + queue index 0 / end + IPv6 VXLAN outer header:: testpmd> set vxlan ip-version ipv6 vni 4 udp-src 4 udp-dst 4 ip-src ::1 @@ -4254,6 +4264,12 @@ IPv6 VXLAN outer header:: testpmd> flow create 0 ingress pattern end actions vxlan_encap / queue index 0 / end + testpmd> set vxlan-tos-ttl ip-version ipv6 vni 4 udp-src 4 udp-dst 4 + ip-tos 0 ip-ttl 255 ::1 ip-dst ::2222 eth-src 11:11:11:11:11:11 + eth-dst 22:22:22:22:22:22 + testpmd> flow create 0 ingress pattern end actions vxlan_encap / + queue index 0 / end + Sample NVGRE encapsulation rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~