]> git.droids-corp.org - dpdk.git/commitdiff
net/iavf: support L2TPv2 for flow director
authorJie Wang <jie1x.wang@intel.com>
Tue, 15 Feb 2022 08:25:37 +0000 (16:25 +0800)
committerQi Zhang <qi.z.zhang@intel.com>
Tue, 15 Feb 2022 16:32:33 +0000 (17:32 +0100)
Add support for L2TPv2(include PPP over L2TPv2) protocols FDIR
based on outer MAC src/dst address and L2TPv2 session ID.

Add support for PPPoL2TPv2oUDP protocols FDIR based on inner IP
src/dst address and UDP/TCP src/dst port.

Patterns are listed below:
eth/ipv4(6)/udp/l2tpv2
eth/ipv4(6)/udp/l2tpv2/ppp

eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp

Signed-off-by: Jie Wang <jie1x.wang@intel.com>
Acked-by: Beilei Xing <beilei.xing@intel.com>
doc/guides/rel_notes/release_22_03.rst
drivers/net/iavf/iavf_fdir.c
drivers/net/iavf/iavf_generic_flow.h

index 3ec9e79e56c0d616477c16f34570a1b70e5b2f4d..814f3a82acd2418419fca565f3f1b264776d74e8 100644 (file)
@@ -113,6 +113,10 @@ New Features
 
   * Added L2TPv2 (include PPP over L2TPv2) RSS support based on outer
     MAC src/dst address and L2TPv2 session ID.
+  * Added L2TPv2 (include PPP over L2TPv2) FDIR support based on outer
+    MAC src/dst address and L2TPv2 session ID.
+  * Added PPPoL2TPv2oUDP FDIR distribute packets based on inner IP
+    src/dst address and UDP/TCP src/dst port.
 
 * **Updated Wangxun ngbe driver.**
 
index b63aaca91df89a1e541d7c573fb95cf054ba1aa4..e9a3566c0d983313d6a46e90c7e36377faa725d4 100644 (file)
        IAVF_FDIR_INSET_GRE_IPV6 | IAVF_INSET_TUN_UDP_SRC_PORT | \
        IAVF_INSET_TUN_UDP_DST_PORT)
 
+#define IAVF_FDIR_INSET_L2TPV2 (\
+       IAVF_INSET_SMAC | IAVF_INSET_DMAC | IAVF_INSET_L2TPV2)
+
+#define IAVF_FDIR_INSET_L2TPV2_PPP_IPV4 (\
+       IAVF_INSET_TUN_IPV4_SRC | IAVF_INSET_TUN_IPV4_DST)
+
+#define IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_UDP (\
+       IAVF_FDIR_INSET_L2TPV2_PPP_IPV4 | IAVF_INSET_TUN_UDP_SRC_PORT | \
+       IAVF_INSET_TUN_UDP_DST_PORT)
+
+#define IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_TCP (\
+       IAVF_FDIR_INSET_L2TPV2_PPP_IPV4 | IAVF_INSET_TUN_TCP_SRC_PORT | \
+       IAVF_INSET_TUN_TCP_DST_PORT)
+
+#define IAVF_FDIR_INSET_L2TPV2_PPP_IPV6 (\
+       IAVF_INSET_TUN_IPV6_SRC | IAVF_INSET_TUN_IPV6_DST)
+
+#define IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_UDP (\
+       IAVF_FDIR_INSET_L2TPV2_PPP_IPV6 | IAVF_INSET_TUN_UDP_SRC_PORT | \
+       IAVF_INSET_TUN_UDP_DST_PORT)
+
+#define IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_TCP (\
+       IAVF_FDIR_INSET_L2TPV2_PPP_IPV6 | IAVF_INSET_TUN_TCP_SRC_PORT | \
+       IAVF_INSET_TUN_TCP_DST_PORT)
+
 static struct iavf_pattern_match_item iavf_fdir_pattern[] = {
        {iavf_pattern_ethertype,                 IAVF_FDIR_INSET_ETH,           IAVF_INSET_NONE},
        {iavf_pattern_eth_ipv4,                  IAVF_FDIR_INSET_ETH_IPV4,      IAVF_INSET_NONE},
@@ -275,6 +300,23 @@ static struct iavf_pattern_match_item iavf_fdir_pattern[] = {
        {iavf_pattern_eth_ipv6_gre_ipv6,        IAVF_FDIR_INSET_GRE_IPV6,       IAVF_INSET_NONE},
        {iavf_pattern_eth_ipv6_gre_ipv6_tcp,    IAVF_FDIR_INSET_GRE_IPV6_TCP,   IAVF_INSET_NONE},
        {iavf_pattern_eth_ipv6_gre_ipv6_udp,    IAVF_FDIR_INSET_GRE_IPV6_UDP,   IAVF_INSET_NONE},
+
+       {iavf_pattern_eth_ipv4_udp_l2tpv2,              IAVF_FDIR_INSET_L2TPV2,                 IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp,          IAVF_FDIR_INSET_L2TPV2,                 IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv6_udp_l2tpv2,              IAVF_FDIR_INSET_L2TPV2,                 IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp,          IAVF_FDIR_INSET_L2TPV2,                 IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,     IAVF_FDIR_INSET_L2TPV2_PPP_IPV4,        IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_UDP,    IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_TCP,    IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,     IAVF_FDIR_INSET_L2TPV2_PPP_IPV4,        IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_UDP,    IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_TCP,    IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,     IAVF_FDIR_INSET_L2TPV2_PPP_IPV6,        IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_UDP,    IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_TCP,    IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,     IAVF_FDIR_INSET_L2TPV2_PPP_IPV6,        IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_UDP,    IAVF_INSET_NONE},
+       {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_TCP,    IAVF_INSET_NONE},
 };
 
 static struct iavf_flow_parser iavf_fdir_parser;
@@ -694,6 +736,8 @@ iavf_fdir_parse_pattern(__rte_unused struct iavf_adapter *ad,
        const struct rte_flow_item_pfcp *pfcp_spec, *pfcp_mask;
        const struct rte_flow_item_ecpri *ecpri_spec, *ecpri_mask;
        const struct rte_flow_item_gre *gre_spec, *gre_mask;
+       const struct rte_flow_item_l2tpv2 *l2tpv2_spec, *l2tpv2_mask;
+       const struct rte_flow_item_ppp *ppp_spec, *ppp_mask;
        const struct rte_flow_item *item = pattern;
        struct virtchnl_proto_hdr *hdr, *hdr1 = NULL;
        struct rte_ecpri_common_hdr ecpri_common;
@@ -701,7 +745,7 @@ iavf_fdir_parse_pattern(__rte_unused struct iavf_adapter *ad,
        enum rte_flow_item_type item_type;
        enum rte_flow_item_type next_type;
        uint8_t tun_inner = 0;
-       uint16_t ether_type;
+       uint16_t ether_type, flags_version;
        int layer = 0;
 
        uint8_t  ipv6_addr_mask[16] = {
@@ -739,37 +783,41 @@ iavf_fdir_parse_pattern(__rte_unused struct iavf_adapter *ad,
                        }
 
                        if (eth_spec && eth_mask) {
-                               if (!rte_is_zero_ether_addr(&eth_mask->src) ||
-                                   !rte_is_zero_ether_addr(&eth_mask->dst)) {
-                                       rte_flow_error_set(error, EINVAL,
-                                               RTE_FLOW_ERROR_TYPE_ITEM, item,
-                                               "Invalid MAC_addr mask.");
-                                       return -rte_errno;
+                               if (!rte_is_zero_ether_addr(&eth_mask->dst)) {
+                                       input_set |= IAVF_INSET_DMAC;
+                                       VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1,
+                                                                       ETH,
+                                                                       DST);
+                               } else if (!rte_is_zero_ether_addr(&eth_mask->src)) {
+                                       input_set |= IAVF_INSET_SMAC;
+                                       VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1,
+                                                                       ETH,
+                                                                       SRC);
                                }
-                       }
 
-                       if (eth_spec && eth_mask && eth_mask->type) {
-                               if (eth_mask->type != RTE_BE16(0xffff)) {
-                                       rte_flow_error_set(error, EINVAL,
-                                               RTE_FLOW_ERROR_TYPE_ITEM,
-                                               item, "Invalid type mask.");
-                                       return -rte_errno;
+                               if (eth_mask->type) {
+                                       if (eth_mask->type != RTE_BE16(0xffff)) {
+                                               rte_flow_error_set(error, EINVAL,
+                                                       RTE_FLOW_ERROR_TYPE_ITEM,
+                                                       item, "Invalid type mask.");
+                                               return -rte_errno;
+                                       }
+
+                                       ether_type = rte_be_to_cpu_16(eth_spec->type);
+                                       if (ether_type == RTE_ETHER_TYPE_IPV4 ||
+                                               ether_type == RTE_ETHER_TYPE_IPV6) {
+                                               rte_flow_error_set(error, EINVAL,
+                                                       RTE_FLOW_ERROR_TYPE_ITEM,
+                                                       item,
+                                                       "Unsupported ether_type.");
+                                               return -rte_errno;
+                                       }
+
+                                       input_set |= IAVF_INSET_ETHERTYPE;
+                                       VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1, ETH,
+                                                                       ETHERTYPE);
                                }
 
-                               ether_type = rte_be_to_cpu_16(eth_spec->type);
-                               if (ether_type == RTE_ETHER_TYPE_IPV4 ||
-                                       ether_type == RTE_ETHER_TYPE_IPV6) {
-                                       rte_flow_error_set(error, EINVAL,
-                                               RTE_FLOW_ERROR_TYPE_ITEM,
-                                               item,
-                                               "Unsupported ether_type.");
-                                       return -rte_errno;
-                               }
-
-                               input_set |= IAVF_INSET_ETHERTYPE;
-                               VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1, ETH,
-                                                                ETHERTYPE);
-
                                rte_memcpy(hdr1->buffer, eth_spec,
                                           sizeof(struct rte_ether_hdr));
                        }
@@ -1319,6 +1367,71 @@ iavf_fdir_parse_pattern(__rte_unused struct iavf_adapter *ad,
                        hdrs->count = ++layer;
                        break;
 
+               case RTE_FLOW_ITEM_TYPE_L2TPV2:
+                       l2tpv2_spec = item->spec;
+                       l2tpv2_mask = item->mask;
+
+                       hdr = &hdrs->proto_hdr[layer];
+
+                       VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, L2TPV2);
+
+                       if (l2tpv2_spec && l2tpv2_mask) {
+                               flags_version =
+                                       rte_be_to_cpu_16(l2tpv2_spec->hdr.common.flags_version);
+                               if ((flags_version == RTE_L2TPV2_MSG_TYPE_CONTROL &&
+                                    l2tpv2_mask->hdr.type3.session_id == UINT16_MAX) ||
+                                   (flags_version == RTE_L2TPV2_MSG_TYPE_DATA &&
+                                    l2tpv2_mask->hdr.type7.session_id == UINT16_MAX) ||
+                                   (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L &&
+                                    l2tpv2_mask->hdr.type6.session_id == UINT16_MAX) ||
+                                   (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_S &&
+                                    l2tpv2_mask->hdr.type5.session_id == UINT16_MAX) ||
+                                   (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_O &&
+                                    l2tpv2_mask->hdr.type4.session_id == UINT16_MAX) ||
+                                   (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_S &&
+                                    l2tpv2_mask->hdr.type3.session_id == UINT16_MAX) ||
+                                   (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_O &&
+                                    l2tpv2_mask->hdr.type2.session_id == UINT16_MAX) ||
+                                   (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_S_O &&
+                                    l2tpv2_mask->hdr.type1.session_id == UINT16_MAX) ||
+                                   (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_S_O &&
+                                    l2tpv2_mask->hdr.type0.session_id == UINT16_MAX)) {
+                                       input_set |= IAVF_L2TPV2_SESSION_ID;
+                                       if (flags_version & IAVF_L2TPV2_FLAGS_LEN)
+                                               VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr,
+                                                               L2TPV2,
+                                                               LEN_SESS_ID);
+                                       else
+                                               VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr,
+                                                               L2TPV2,
+                                                               SESS_ID);
+                               }
+
+                               rte_memcpy(hdr->buffer, l2tpv2_spec,
+                                          sizeof(*l2tpv2_spec));
+                       }
+
+                       tun_inner = 1;
+
+                       hdrs->count = ++layer;
+                       break;
+
+               case RTE_FLOW_ITEM_TYPE_PPP:
+                       ppp_spec = item->spec;
+                       ppp_mask = item->mask;
+
+                       hdr = &hdrs->proto_hdr[layer];
+
+                       VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, PPP);
+
+                       if (ppp_spec && ppp_mask) {
+                               rte_memcpy(hdr->buffer, ppp_spec,
+                                          sizeof(*ppp_spec));
+                       }
+
+                       hdrs->count = ++layer;
+                       break;
+
                case RTE_FLOW_ITEM_TYPE_VOID:
                        break;
 
index 107bbc1a234f717f0b138e51e90174eda502c099..f6af176073f0094d0844cc698d83470ad8850735 100644 (file)
@@ -35,6 +35,7 @@
 #define IAVF_PROT_L2TPV3OIP        (1ULL << 24)
 #define IAVF_PROT_PFCP             (1ULL << 25)
 #define IAVF_PROT_ECPRI                    (1ULL << 26)
+#define IAVF_PROT_L2TPV2           (1ULL << 27)
 
 
 /* field */
@@ -62,6 +63,7 @@
 #define IAVF_PFCP_SEID             (1ULL << 43)
 #define IAVF_ECPRI_PC_RTC_ID       (1ULL << 42)
 #define IAVF_IP_PKID               (1ULL << 41)
+#define IAVF_L2TPV2_SESSION_ID     (1ULL << 40)
 
 /* input set */
 
        (IAVF_PROT_PFCP | IAVF_PFCP_S_FIELD | IAVF_PFCP_SEID)
 #define IAVF_INSET_ECPRI \
        (IAVF_PROT_ECPRI | IAVF_ECPRI_PC_RTC_ID)
+#define IAVF_INSET_L2TPV2 \
+       (IAVF_PROT_L2TPV2 | IAVF_L2TPV2_SESSION_ID)
 
 /* empty pattern */
 extern enum rte_flow_item_type iavf_pattern_empty[];