From patchwork Tue Apr 24 15:58:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 38828 X-Patchwork-Delegate: ferruh.yigit@amd.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 5F04058C3; Tue, 24 Apr 2018 17:59:15 +0200 (CEST) Received: from mail-wm0-f65.google.com (mail-wm0-f65.google.com [74.125.82.65]) by dpdk.org (Postfix) with ESMTP id D4E45559A for ; Tue, 24 Apr 2018 17:59:13 +0200 (CEST) Received: by mail-wm0-f65.google.com with SMTP id a8so2036815wmg.5 for ; Tue, 24 Apr 2018 08:59:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=wlShLzYsMngtXj9u1Hf4oq3ima6214MKT9sM3871n2Y=; b=JejZ8KnxmHnGvsdCDMaV/Wj+IR/CPjcWCRdZ1tCPhBwSpF9Ert5qHM48qKop56ybl/ s2uNmW1+zbha33qZR6Uq8OrkM6KY4IBvkuL6afwlBWsYlZYDRXvpngQYIEKIJsmNHiLg TKIIgkvO1iP2e3esxEHYNQnyx7NEivAEIWsVVtT8qRW5D54qR1wlad6BJ8uSHZArP37r HgN58vOmHaSlsHJXm6JQIJzP90kImI0k4zqRl2Zq4A+IgeN5e3YpK7EKhn+mUoDnXwCy N37CsiGvb19h8bdXn+rJPaKf8uxYPGPeI7EjXPXa4v7WwxdFqSCjqQ022a+7zMHd2I4J VCgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=wlShLzYsMngtXj9u1Hf4oq3ima6214MKT9sM3871n2Y=; b=fTjcdeMvzA60uDrP5BXXStxZTIZkuk38IPHq99NX8TbzqJ4uIpff8geruR4VsCn0pJ RHeJ45A5ZEFp3gRg82vBN8kTZEzrFBs4m16ZqUVGfSp3BZ2Ew2bzKuj/qOoOn+SOjgqY CZWZrIOcr/hPqHHpcsEYoX2f7lXD5CpQMvZrtvl1Ux8iWcDpw9yix2+V2pP5swHl7G54 l+gJxRBmQm5xy22pTkymt3lsChefRuH7eyqGMzVQlLANKThx+EZS+Zh3D39BaNuuJBLb sKfBvvB0Y2Lz9S9rWEGinFjnFW9xBQG9mfulnq0IZ1SjvJDfu5gFeAq859hpZAYWRtaB 7bgw== X-Gm-Message-State: ALQs6tC7Bai44BuUG+LjPv0RL4hhBMIn2s6Owy0UMdO5r3EK/qDmwc0l rPu9OJbWLeY5nzLuucYXQJbm0A== X-Google-Smtp-Source: AIpwx4/YSKr+6YcO6elPco4ytjPFxFObu+RtH+jiUlNxqGXoE8jaxbdMo7hqIdLAQ9Yh/2bDFv48gw== X-Received: by 10.28.46.14 with SMTP id u14mr12793655wmu.98.1524585552813; Tue, 24 Apr 2018 08:59:12 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id g75sm14154866wmc.47.2018.04.24.08.59.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Apr 2018 08:59:12 -0700 (PDT) Date: Tue, 24 Apr 2018 17:58:58 +0200 From: Adrien Mazarguil To: Ferruh Yigit , Qi Zhang Cc: dev@dpdk.org, declan.doherty@intel.com, sugesh.chandran@intel.com, michael.j.glynn@intel.com, yu.y.liu@intel.com, konstantin.ananyev@intel.com, bruce.richardson@intel.com Message-ID: <20180424154822.19666-2-adrien.mazarguil@6wind.com> References: <20180423063610.246387-1-qi.z.zhang@intel.com> <20180424154822.19666-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180424154822.19666-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v5 1/3] ethdev: add neighbor discovery support to flow API 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" From: Qi Zhang - RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4: matches an ARP header for Ethernet/IPv4. - RTE_FLOW_ITEM_TYPE_IPV6_EXT: matches the presence of any IPv6 extension header. - RTE_FLOW_ITEM_TYPE_ICMP6: matches any ICMPv6 header. - RTE_FLOW_ITEM_TYPE_ICMP6_ND_NS: matches an ICMPv6 neighbor discovery solicitation. - RTE_FLOW_ITEM_TYPE_ICMP6_ND_NA: matches an ICMPv6 neighbor discovery advertisement. - RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT: matches the presence of any ICMPv6 neighbor discovery option. - RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_ETH_SLA: matches an ICMPv6 neighbor discovery source Ethernet link-layer address option. - RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_ETH_TLA: matches an ICMPv6 neighbor discovery target Ethernet link-layer address option. Signed-off-by: Qi Zhang Signed-off-by: Adrien Mazarguil --- v5 changes: - Clarified ITEM_ARP_IPV4 as ITEM_ARP_ETH_IPV4. - Expanded abbreviated macros (e.g. ITEM_ICMP6_ND_NS_TGT_ADDR => ITEM_ICMP6_ND_NS_TARGET_ADDR) to match the name of the underlying structure field. - Fixed testpmd flow command issues (lack of ITEM_NEXT, use of UNSIGNED instead of IPV4_ADDR/IPV6_ADDR/MAC_ADDR). - Clarified/fixed flow command help strings and matching documentation. - Added ITEM_ICMP6_ND_OPT for generic ND options. - Modified ITEM_ICMP6_ND_OPT_SLA_ETH and ITEM_ICMP6_ND_OPT_TLA_ETH to not include an ICMPv6 header but instead work like ITEM_ICMP6_ND_OPT as separate items to stack on top of ICMPv6 ND on a needed basis. - Updated documentation accordingly. - Added these new pattern items to rte_flow_copy(). - Updated commit log to reflect patch contents. --- app/test-pmd/cmdline_flow.c | 241 +++++++++++++++++++++ app/test-pmd/config.c | 10 + doc/guides/prog_guide/rte_flow.rst | 114 +++++++++- doc/guides/testpmd_app_ug/testpmd_funcs.rst | 38 ++++ lib/librte_ether/rte_flow.c | 10 + lib/librte_ether/rte_flow.h | 254 ++++++++++++++++++++++- 6 files changed, 665 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 32fe6645a..2bb2be101 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -154,6 +154,26 @@ enum index { ITEM_GENEVE, ITEM_GENEVE_VNI, ITEM_GENEVE_PROTO, + ITEM_ARP_ETH_IPV4, + ITEM_ARP_ETH_IPV4_SHA, + ITEM_ARP_ETH_IPV4_SPA, + ITEM_ARP_ETH_IPV4_THA, + ITEM_ARP_ETH_IPV4_TPA, + ITEM_IPV6_EXT, + ITEM_IPV6_EXT_NEXT_HDR, + ITEM_ICMP6, + ITEM_ICMP6_TYPE, + ITEM_ICMP6_CODE, + ITEM_ICMP6_ND_NS, + ITEM_ICMP6_ND_NS_TARGET_ADDR, + ITEM_ICMP6_ND_NA, + ITEM_ICMP6_ND_NA_TARGET_ADDR, + ITEM_ICMP6_ND_OPT, + ITEM_ICMP6_ND_OPT_TYPE, + ITEM_ICMP6_ND_OPT_SLA_ETH, + ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, + ITEM_ICMP6_ND_OPT_TLA_ETH, + ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, /* Validate/create actions. */ ACTIONS, @@ -470,6 +490,14 @@ static const enum index next_item[] = { ITEM_GTPC, ITEM_GTPU, ITEM_GENEVE, + ITEM_ARP_ETH_IPV4, + ITEM_IPV6_EXT, + ITEM_ICMP6, + ITEM_ICMP6_ND_NS, + ITEM_ICMP6_ND_NA, + ITEM_ICMP6_ND_OPT, + ITEM_ICMP6_ND_OPT_SLA_ETH, + ITEM_ICMP6_ND_OPT_TLA_ETH, ZERO, }; @@ -626,6 +654,58 @@ static const enum index item_geneve[] = { ZERO, }; +static const enum index item_arp_eth_ipv4[] = { + ITEM_ARP_ETH_IPV4_SHA, + ITEM_ARP_ETH_IPV4_SPA, + ITEM_ARP_ETH_IPV4_THA, + ITEM_ARP_ETH_IPV4_TPA, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_ipv6_ext[] = { + ITEM_IPV6_EXT_NEXT_HDR, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_icmp6[] = { + ITEM_ICMP6_TYPE, + ITEM_ICMP6_CODE, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_icmp6_nd_ns[] = { + ITEM_ICMP6_ND_NS_TARGET_ADDR, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_icmp6_nd_na[] = { + ITEM_ICMP6_ND_NA_TARGET_ADDR, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_icmp6_nd_opt[] = { + ITEM_ICMP6_ND_OPT_TYPE, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_icmp6_nd_opt_sla_eth[] = { + ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_icmp6_nd_opt_tla_eth[] = { + ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, + ITEM_NEXT, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -1560,6 +1640,167 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, protocol)), }, + [ITEM_ARP_ETH_IPV4] = { + .name = "arp_eth_ipv4", + .help = "match ARP header for Ethernet/IPv4", + .priv = PRIV_ITEM(ARP_ETH_IPV4, + sizeof(struct rte_flow_item_arp_eth_ipv4)), + .next = NEXT(item_arp_eth_ipv4), + .call = parse_vc, + }, + [ITEM_ARP_ETH_IPV4_SHA] = { + .name = "sha", + .help = "sender hardware address", + .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(MAC_ADDR), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, + sha)), + }, + [ITEM_ARP_ETH_IPV4_SPA] = { + .name = "spa", + .help = "sender IPv4 address", + .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(IPV4_ADDR), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, + spa)), + }, + [ITEM_ARP_ETH_IPV4_THA] = { + .name = "tha", + .help = "target hardware address", + .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(MAC_ADDR), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, + tha)), + }, + [ITEM_ARP_ETH_IPV4_TPA] = { + .name = "tpa", + .help = "target IPv4 address", + .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(IPV4_ADDR), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, + tpa)), + }, + [ITEM_IPV6_EXT] = { + .name = "ipv6_ext", + .help = "match presence of any IPv6 extension header", + .priv = PRIV_ITEM(IPV6_EXT, + sizeof(struct rte_flow_item_ipv6_ext)), + .next = NEXT(item_ipv6_ext), + .call = parse_vc, + }, + [ITEM_IPV6_EXT_NEXT_HDR] = { + .name = "next_hdr", + .help = "next header", + .next = NEXT(item_ipv6_ext, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, + next_hdr)), + }, + [ITEM_ICMP6] = { + .name = "icmp6", + .help = "match any ICMPv6 header", + .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), + .next = NEXT(item_icmp6), + .call = parse_vc, + }, + [ITEM_ICMP6_TYPE] = { + .name = "type", + .help = "ICMPv6 type", + .next = NEXT(item_icmp6, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, + type)), + }, + [ITEM_ICMP6_CODE] = { + .name = "code", + .help = "ICMPv6 code", + .next = NEXT(item_icmp6, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, + code)), + }, + [ITEM_ICMP6_ND_NS] = { + .name = "icmp6_nd_ns", + .help = "match ICMPv6 neighbor discovery solicitation", + .priv = PRIV_ITEM(ICMP6_ND_NS, + sizeof(struct rte_flow_item_icmp6_nd_ns)), + .next = NEXT(item_icmp6_nd_ns), + .call = parse_vc, + }, + [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { + .name = "target_addr", + .help = "target address", + .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(IPV6_ADDR), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, + target_addr)), + }, + [ITEM_ICMP6_ND_NA] = { + .name = "icmp6_nd_na", + .help = "match ICMPv6 neighbor discovery advertisement", + .priv = PRIV_ITEM(ICMP6_ND_NA, + sizeof(struct rte_flow_item_icmp6_nd_na)), + .next = NEXT(item_icmp6_nd_na), + .call = parse_vc, + }, + [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { + .name = "target_addr", + .help = "target address", + .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(IPV6_ADDR), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, + target_addr)), + }, + [ITEM_ICMP6_ND_OPT] = { + .name = "icmp6_nd_opt", + .help = "match presence of any ICMPv6 neighbor discovery" + " option", + .priv = PRIV_ITEM(ICMP6_ND_OPT, + sizeof(struct rte_flow_item_icmp6_nd_opt)), + .next = NEXT(item_icmp6_nd_opt), + .call = parse_vc, + }, + [ITEM_ICMP6_ND_OPT_TYPE] = { + .name = "type", + .help = "ND option type", + .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, + type)), + }, + [ITEM_ICMP6_ND_OPT_SLA_ETH] = { + .name = "icmp6_nd_opt_sla_eth", + .help = "match ICMPv6 neighbor discovery source Ethernet" + " link-layer address option", + .priv = PRIV_ITEM + (ICMP6_ND_OPT_SLA_ETH, + sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), + .next = NEXT(item_icmp6_nd_opt_sla_eth), + .call = parse_vc, + }, + [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { + .name = "sla", + .help = "source Ethernet LLA", + .next = NEXT(item_icmp6_nd_opt_sla_eth, NEXT_ENTRY(MAC_ADDR), + item_param), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), + }, + [ITEM_ICMP6_ND_OPT_TLA_ETH] = { + .name = "icmp6_nd_opt_tla_eth", + .help = "match ICMPv6 neighbor discovery target Ethernet" + " link-layer address option", + .priv = PRIV_ITEM + (ICMP6_ND_OPT_TLA_ETH, + sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), + .next = NEXT(item_icmp6_nd_opt_tla_eth), + .call = parse_vc, + }, + [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { + .name = "tla", + .help = "target Ethernet LLA", + .next = NEXT(item_icmp6_nd_opt_tla_eth, NEXT_ENTRY(MAC_ADDR), + item_param), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), + }, /* Validate/create actions. */ [ACTIONS] = { diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 104e85ba2..c06b76c31 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1014,6 +1014,16 @@ static const struct { MK_FLOW_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), MK_FLOW_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), + MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)), + MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)), + MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), + MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct rte_flow_item_icmp6_nd_ns)), + MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct rte_flow_item_icmp6_nd_na)), + MK_FLOW_ITEM(ICMP6_ND_OPT, sizeof(struct rte_flow_item_icmp6_nd_opt)), + MK_FLOW_ITEM(ICMP6_ND_OPT_SLA_ETH, + sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), + MK_FLOW_ITEM(ICMP6_ND_OPT_TLA_ETH, + sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), }; /** Pattern item specification types. */ diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 2fb8e9c3f..644076cb9 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -874,7 +874,8 @@ Item: ``IPV6`` Matches an IPv6 header. -Note: IPv6 options are handled by dedicated pattern items. +Note: IPv6 options are handled by dedicated pattern items, see `Item: +IPV6_EXT`_. - ``hdr``: IPv6 header definition (``rte_ip.h``). - Default ``mask`` matches source and destination addresses only. @@ -1054,6 +1055,117 @@ Matches a GENEVE header. - ``rsvd1``: reserved, normally 0x00. - Default ``mask`` matches VNI only. +Item: ``ARP_ETH_IPV4`` +^^^^^^^^^^^^^^^^^^^^^^ + +Matches an ARP header for Ethernet/IPv4. + +- ``hdr``: hardware type, normally 1. +- ``pro``: protocol type, normally 0x0800. +- ``hln``: hardware address length, normally 6. +- ``pln``: protocol address length, normally 4. +- ``op``: opcode (1 for request, 2 for reply). +- ``sha``: sender hardware address. +- ``spa``: sender IPv4 address. +- ``tha``: target hardware address. +- ``tpa``: target IPv4 address. +- Default ``mask`` matches SHA, SPA, THA and TPA. + +Item: ``IPV6_EXT`` +^^^^^^^^^^^^^^^^^^ + +Matches the presence of any IPv6 extension header. + +- ``next_hdr``: next header. +- Default ``mask`` matches ``next_hdr``. + +Normally preceded by any of: + +- `Item: IPV6`_ +- `Item: IPV6_EXT`_ + +Item: ``ICMP6`` +^^^^^^^^^^^^^^^ + +Matches any ICMPv6 header. + +- ``type``: ICMPv6 type. +- ``code``: ICMPv6 code. +- ``checksum``: ICMPv6 checksum. +- Default ``mask`` matches ``type`` and ``code``. + +Item: ``ICMP6_ND_NS`` +^^^^^^^^^^^^^^^^^^^^^ + +Matches an ICMPv6 neighbor discovery solicitation. + +- ``type``: ICMPv6 type, normally 135. +- ``code``: ICMPv6 code, normally 0. +- ``checksum``: ICMPv6 checksum. +- ``reserved``: reserved, normally 0. +- ``target_addr``: target address. +- Default ``mask`` matches target address only. + +Item: ``ICMP6_ND_NA`` +^^^^^^^^^^^^^^^^^^^^^ + +Matches an ICMPv6 neighbor discovery advertisement. + +- ``type``: ICMPv6 type, normally 136. +- ``code``: ICMPv6 code, normally 0. +- ``checksum``: ICMPv6 checksum. +- ``rso_reserved``: route flag (1b), solicited flag (1b), override flag + (1b), reserved (29b). +- ``target_addr``: target address. +- Default ``mask`` matches target address only. + +Item: ``ICMP6_ND_OPT`` +^^^^^^^^^^^^^^^^^^^^^^ + +Matches the presence of any ICMPv6 neighbor discovery option. + +- ``type``: ND option type. +- ``length``: ND option length. +- Default ``mask`` matches type only. + +Normally preceded by any of: + +- `Item: ICMP6_ND_NA`_ +- `Item: ICMP6_ND_NS`_ +- `Item: ICMP6_ND_OPT`_ + +Item: ``ICMP6_ND_OPT_SLA_ETH`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Matches an ICMPv6 neighbor discovery source Ethernet link-layer address +option. + +- ``type``: ND option type, normally 1. +- ``length``: ND option length, normally 1. +- ``sla``: source Ethernet LLA. +- Default ``mask`` matches source link-layer address only. + +Normally preceded by any of: + +- `Item: ICMP6_ND_NA`_ +- `Item: ICMP6_ND_OPT`_ + +Item: ``ICMP6_ND_OPT_TLA_ETH`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Matches an ICMPv6 neighbor discovery target Ethernet link-layer address +option. + +- ``type``: ND option type, normally 2. +- ``length``: ND option length, normally 1. +- ``tla``: target Ethernet LLA. +- Default ``mask`` matches target link-layer address only. + +Normally preceded by any of: + +- `Item: ICMP6_ND_NS`_ +- `Item: ICMP6_ND_OPT`_ + Actions ~~~~~~~ diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 829e38428..8e7cae00b 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3312,6 +3312,44 @@ This section lists supported pattern items and their attributes, if any. - ``vni {unsigned}``: virtual network identifier. - ``protocol {unsigned}``: protocol type. +- ``arp_eth_ipv4``: match ARP header for Ethernet/IPv4. + + - ``sha {MAC-48}``: sender hardware address. + - ``spa {ipv4 address}``: sender IPv4 address. + - ``tha {MAC-48}``: target hardware address. + - ``tpa {ipv4 address}``: target IPv4 address. + +- ``ipv6_ext``: match presence of any IPv6 extension header. + + - ``next_hdr {unsigned}``: next header. + +- ``icmp6``: match any ICMPv6 header. + + - ``type {unsigned}``: ICMPv6 type. + - ``code {unsigned}``: ICMPv6 code. + +- ``icmp6_nd_ns``: match ICMPv6 neighbor discovery solicitation. + + - ``target_addr {ipv6 address}``: target address. + +- ``icmp6_nd_na``: match ICMPv6 neighbor discovery advertisement. + + - ``target_addr {ipv6 address}``: target address. + +- ``icmp6_nd_opt``: match presence of any ICMPv6 neighbor discovery option. + + - ``type {unsigned}``: ND option type. + +- ``icmp6_nd_opt_sla_eth``: match ICMPv6 neighbor discovery source Ethernet + link-layer address option. + + - ``sla {MAC-48}``: source Ethernet LLA. + +- ``icmp6_nd_opt_sla_eth``: match ICMPv6 neighbor discovery target Ethernet + link-layer address option. + + - ``tla {MAC-48}``: target Ethernet LLA. + Actions list ^^^^^^^^^^^^ diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c index cecab59f6..39fa93baa 100644 --- a/lib/librte_ether/rte_flow.c +++ b/lib/librte_ether/rte_flow.c @@ -55,6 +55,16 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), + MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)), + MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)), + MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), + MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct rte_flow_item_icmp6_nd_ns)), + MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct rte_flow_item_icmp6_nd_na)), + MK_FLOW_ITEM(ICMP6_ND_OPT, sizeof(struct rte_flow_item_icmp6_nd_opt)), + MK_FLOW_ITEM(ICMP6_ND_OPT_SLA_ETH, + sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), + MK_FLOW_ITEM(ICMP6_ND_OPT_TLA_ETH, + sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), }; /** Generate flow_action[] entry. */ diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h index 09a21e531..e9b361dda 100644 --- a/lib/librte_ether/rte_flow.h +++ b/lib/librte_ether/rte_flow.h @@ -339,6 +339,64 @@ enum rte_flow_item_type { * See struct rte_flow_item_geneve. */ RTE_FLOW_ITEM_TYPE_GENEVE, + + /** + * Matches an ARP header for Ethernet/IPv4. + * + * See struct rte_flow_item_arp_eth_ipv4. + */ + RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4, + + /** + * Matches the presence of any IPv6 extension header. + * + * See struct rte_flow_item_ipv6_ext. + */ + RTE_FLOW_ITEM_TYPE_IPV6_EXT, + + /** + * Matches any ICMPv6 header. + * + * See struct rte_flow_item_icmp6. + */ + RTE_FLOW_ITEM_TYPE_ICMP6, + + /** + * Matches an ICMPv6 neighbor discovery solicitation. + * + * See struct rte_flow_item_icmp6_nd_ns. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_NS, + + /** + * Matches an ICMPv6 neighbor discovery advertisement. + * + * See struct rte_flow_item_icmp6_nd_na. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_NA, + + /** + * Matches the presence of any ICMPv6 neighbor discovery option. + * + * See struct rte_flow_item_icmp6_nd_opt. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT, + + /** + * Matches an ICMPv6 neighbor discovery source Ethernet link-layer + * address option. + * + * See struct rte_flow_item_icmp6_nd_opt_sla_eth. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_SLA_ETH, + + /** + * Matches an ICMPv6 neighbor discovery target Ethernet link-layer + * address option. + * + * See struct rte_flow_item_icmp6_nd_opt_tla_eth. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_TLA_ETH, }; /** @@ -564,7 +622,8 @@ static const struct rte_flow_item_ipv4 rte_flow_item_ipv4_mask = { * * Matches an IPv6 header. * - * Note: IPv6 options are handled by dedicated pattern items. + * Note: IPv6 options are handled by dedicated pattern items, see + * RTE_FLOW_ITEM_TYPE_IPV6_EXT. */ struct rte_flow_item_ipv6 { struct ipv6_hdr hdr; /**< IPv6 header definition. */ @@ -868,6 +927,199 @@ static const struct rte_flow_item_geneve rte_flow_item_geneve_mask = { #endif /** + * RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4 + * + * Matches an ARP header for Ethernet/IPv4. + */ +struct rte_flow_item_arp_eth_ipv4 { + rte_be16_t hrd; /**< Hardware type, normally 1. */ + rte_be16_t pro; /**< Protocol type, normally 0x0800. */ + uint8_t hln; /**< Hardware address length, normally 6. */ + uint8_t pln; /**< Protocol address length, normally 4. */ + rte_be16_t op; /**< Opcode (1 for request, 2 for reply). */ + struct ether_addr sha; /**< Sender hardware address. */ + rte_be32_t spa; /**< Sender IPv4 address. */ + struct ether_addr tha; /**< Target hardware address. */ + rte_be32_t tpa; /**< Target IPv4 address. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4. */ +#ifndef __cplusplus +static const struct rte_flow_item_arp_eth_ipv4 +rte_flow_item_arp_eth_ipv4_mask = { + .sha.addr_bytes = "\xff\xff\xff\xff\xff\xff", + .spa = RTE_BE32(0xffffffff), + .tha.addr_bytes = "\xff\xff\xff\xff\xff\xff", + .tpa = RTE_BE32(0xffffffff), +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_IPV6_EXT + * + * Matches the presence of any IPv6 extension header. + * + * Normally preceded by any of: + * + * - RTE_FLOW_ITEM_TYPE_IPV6 + * - RTE_FLOW_ITEM_TYPE_IPV6_EXT + */ +struct rte_flow_item_ipv6_ext { + uint8_t next_hdr; /**< Next header. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_IPV6_EXT. */ +#ifndef __cplusplus +static const +struct rte_flow_item_ipv6_ext rte_flow_item_ipv6_ext_mask = { + .next_hdr = 0xff, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_ICMP6 + * + * Matches any ICMPv6 header. + */ +struct rte_flow_item_icmp6 { + uint8_t type; /**< ICMPv6 type. */ + uint8_t code; /**< ICMPv6 code. */ + uint16_t checksum; /**< ICMPv6 checksum. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP6. */ +#ifndef __cplusplus +static const struct rte_flow_item_icmp6 rte_flow_item_icmp6_mask = { + .type = 0xff, + .code = 0xff, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_ICMP6_ND_NS + * + * Matches an ICMPv6 neighbor discovery solicitation. + */ +struct rte_flow_item_icmp6_nd_ns { + uint8_t type; /**< ICMPv6 type, normally 135. */ + uint8_t code; /**< ICMPv6 code, normally 0. */ + rte_be16_t checksum; /**< ICMPv6 checksum. */ + rte_be32_t reserved; /**< Reserved, normally 0. */ + uint8_t target_addr[16]; /**< Target address. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP6_ND_NS. */ +#ifndef __cplusplus +static const +struct rte_flow_item_icmp6_nd_ns rte_flow_item_icmp6_nd_ns_mask = { + .target_addr = + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff", +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_ICMP6_ND_NA + * + * Matches an ICMPv6 neighbor discovery advertisement. + */ +struct rte_flow_item_icmp6_nd_na { + uint8_t type; /**< ICMPv6 type, normally 136. */ + uint8_t code; /**< ICMPv6 code, normally 0. */ + rte_be16_t checksum; /**< ICMPv6 checksum. */ + /** + * Route flag (1b), solicited flag (1b), override flag (1b), + * reserved (29b). + */ + rte_be32_t rso_reserved; + uint8_t target_addr[16]; /**< Target address. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP6_ND_NA. */ +#ifndef __cplusplus +static const +struct rte_flow_item_icmp6_nd_na rte_flow_item_icmp6_nd_na_mask = { + .target_addr = + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff", +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT + * + * Matches the presence of any ICMPv6 neighbor discovery option. + * + * Normally preceded by any of: + * + * - RTE_FLOW_ITEM_TYPE_ICMP6_ND_NA + * - RTE_FLOW_ITEM_TYPE_ICMP6_ND_NS + * - RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT + */ +struct rte_flow_item_icmp6_nd_opt { + uint8_t type; /**< ND option type. */ + uint8_t length; /**< ND option length. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT. */ +#ifndef __cplusplus +static const struct rte_flow_item_icmp6_nd_opt +rte_flow_item_icmp6_nd_opt_mask = { + .type = 0xff, +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_SLA_ETH + * + * Matches an ICMPv6 neighbor discovery source Ethernet link-layer address + * option. + * + * Normally preceded by any of: + * + * - RTE_FLOW_ITEM_TYPE_ICMP6_ND_NA + * - RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT + */ +struct rte_flow_item_icmp6_nd_opt_sla_eth { + uint8_t type; /**< ND option type, normally 1. */ + uint8_t length; /**< ND option length, normally 1. */ + struct ether_addr sla; /**< Source Ethernet LLA. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_SLA_ETH. */ +#ifndef __cplusplus +static const struct rte_flow_item_icmp6_nd_opt_sla_eth +rte_flow_item_icmp6_nd_opt_sla_eth_mask = { + .sla.addr_bytes = "\xff\xff\xff\xff\xff\xff", +}; +#endif + +/** + * RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_TLA_ETH + * + * Matches an ICMPv6 neighbor discovery target Ethernet link-layer address + * option. + * + * Normally preceded by any of: + * + * - RTE_FLOW_ITEM_TYPE_ICMP6_ND_NS + * - RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT + */ +struct rte_flow_item_icmp6_nd_opt_tla_eth { + uint8_t type; /**< ND option type, normally 2. */ + uint8_t length; /**< ND option length, normally 1. */ + struct ether_addr tla; /**< Target Ethernet LLA. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_TLA_ETH. */ +#ifndef __cplusplus +static const struct rte_flow_item_icmp6_nd_opt_tla_eth +rte_flow_item_icmp6_nd_opt_tla_eth_mask = { + .tla.addr_bytes = "\xff\xff\xff\xff\xff\xff", +}; +#endif + +/** * Matching pattern item definition. * * A pattern is formed by stacking items starting from the lowest protocol