GTP-C & GTP-U are not supported by cloud filter due
to limited resource of HW, this patch enables GTP-C
and GTP-U cloud filter by replacing inner_mac and
TUNNEL_KEY.
This configuration will be set when adding GTP-C or
GTP-U filter rules, and it will be invalid only by
NIC core reset.

Signed-off-by: Beilei Xing <beilei.x...@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 187 +++++++++++++++++++++++++++++++++++++----
 drivers/net/i40e/i40e_ethdev.h |  11 ++-
 drivers/net/i40e/i40e_flow.c   |  26 ++++--
 3 files changed, 196 insertions(+), 28 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 18b3d8c..06e6ee0 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -7132,7 +7132,7 @@ i40e_status_code i40e_replace_mpls_l1_filter(struct 
i40e_pf *pf)
        /* create L1 filter */
        filter_replace.old_filter_type =
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC;
-       filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_TEID_MPLS;
+       filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X11;
        filter_replace.tr_bit = 0;
 
        /* Prepare the buffer, 3 entries */
@@ -7180,12 +7180,12 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct 
i40e_pf *pf)
                I40E_AQC_MIRROR_CLOUD_FILTER;
        filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IIP;
        filter_replace.new_filter_type =
-               I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP;
+               I40E_AQC_ADD_CLOUD_FILTER_0X11;
        /* Prepare the buffer, 2 entries */
        filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
        filter_replace_buf.data[0] |=
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
-       filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_TEID_MPLS;
+       filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_0X11;
        filter_replace_buf.data[4] |=
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
        status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
@@ -7203,12 +7203,129 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct 
i40e_pf *pf)
                I40E_AQC_MIRROR_CLOUD_FILTER;
        filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IMAC;
        filter_replace.new_filter_type =
-               I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE;
+               I40E_AQC_ADD_CLOUD_FILTER_0X12;
        /* Prepare the buffer, 2 entries */
        filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
        filter_replace_buf.data[0] |=
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
-       filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_TEID_MPLS;
+       filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_0X11;
+       filter_replace_buf.data[4] |=
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+
+       status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
+                                              &filter_replace_buf);
+       return status;
+}
+
+static enum i40e_status_code
+i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
+{
+       struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
+       struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
+       struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       enum i40e_status_code status = I40E_SUCCESS;
+
+       /* For GTP-C */
+       memset(&filter_replace, 0,
+              sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
+       memset(&filter_replace_buf, 0,
+              sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
+       /* create L1 filter */
+       filter_replace.old_filter_type =
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC;
+       filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X12;
+       filter_replace.tr_bit = 22 | 0x80;
+       /* Prepare the buffer, 2 entries */
+       filter_replace_buf.data[0] =
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0;
+       filter_replace_buf.data[0] |=
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+       filter_replace_buf.data[2] = 0xFF;
+       filter_replace_buf.data[3] = 0xFF;
+       filter_replace_buf.data[4] =
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1;
+       filter_replace_buf.data[4] |=
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+       filter_replace_buf.data[6] = 0xFF;
+       filter_replace_buf.data[7] = 0xFF;
+       status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
+                                              &filter_replace_buf);
+       if (status < 0)
+               return status;
+
+       /* for GTP-U */
+       memset(&filter_replace, 0,
+              sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
+       memset(&filter_replace_buf, 0,
+              sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
+       /* create L1 filter */
+       filter_replace.old_filter_type =
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TUNNLE_KEY;
+       filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X13;
+       filter_replace.tr_bit = 21 | 0x80;
+       /* Prepare the buffer, 2 entries */
+       filter_replace_buf.data[0] =
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0;
+       filter_replace_buf.data[0] |=
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+       filter_replace_buf.data[2] = 0xFF;
+       filter_replace_buf.data[3] = 0xFF;
+       filter_replace_buf.data[4] =
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1;
+       filter_replace_buf.data[4] |=
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+       filter_replace_buf.data[6] = 0xFF;
+       filter_replace_buf.data[7] = 0xFF;
+
+       status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
+                                              &filter_replace_buf);
+       return status;
+}
+
+static enum
+i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
+{
+       struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
+       struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
+       struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       enum i40e_status_code status = I40E_SUCCESS;
+
+       /* for GTP-C */
+       memset(&filter_replace, 0,
+              sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
+       memset(&filter_replace_buf, 0,
+              sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
+       filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER;
+       filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN;
+       filter_replace.new_filter_type =
+               I40E_AQC_ADD_CLOUD_FILTER_0X11;
+       /* Prepare the buffer, 2 entries */
+       filter_replace_buf.data[0] = I40E_AQC_ADD_L1_FILTER_0X12;
+       filter_replace_buf.data[0] |=
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+       filter_replace_buf.data[4] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
+       filter_replace_buf.data[4] |=
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+       status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
+                                              &filter_replace_buf);
+       if (status < 0)
+               return status;
+
+       /* for GTP-U */
+       memset(&filter_replace, 0,
+              sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
+       memset(&filter_replace_buf, 0,
+              sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
+       filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER;
+       filter_replace.old_filter_type =
+               I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID;
+       filter_replace.new_filter_type =
+               I40E_AQC_ADD_CLOUD_FILTER_0X12;
+       /* Prepare the buffer, 2 entries */
+       filter_replace_buf.data[0] = I40E_AQC_ADD_L1_FILTER_0X13;
+       filter_replace_buf.data[0] |=
+               I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+       filter_replace_buf.data[4] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
        filter_replace_buf.data[4] |=
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
 
@@ -7317,6 +7434,36 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
                big_buffer = 1;
                tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSoGRE;
                break;
+       case I40E_TUNNEL_TYPE_GTPC:
+               if (!pf->gtp_replace_flag) {
+                       i40e_replace_gtp_l1_filter(pf);
+                       i40e_replace_gtp_cloud_filter(pf);
+                       pf->gtp_replace_flag = 1;
+               }
+               teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
+               pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD0] =
+                       (teid_le >> 16) & 0xFFFF;
+               pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD1] =
+                       teid_le & 0xFFFF;
+               pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD2] =
+                       0x0;
+               big_buffer = 1;
+               break;
+       case I40E_TUNNEL_TYPE_GTPU:
+               if (!pf->gtp_replace_flag) {
+                       i40e_replace_gtp_l1_filter(pf);
+                       i40e_replace_gtp_cloud_filter(pf);
+                       pf->gtp_replace_flag = 1;
+               }
+               teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
+               pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD0] =
+                       (teid_le >> 16) & 0xFFFF;
+               pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD1] =
+                       teid_le & 0xFFFF;
+               pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD2] =
+                       0x0;
+               big_buffer = 1;
+               break;
        case I40E_TUNNEL_TYPE_QINQ:
                if (!pf->qinq_replace_flag) {
                        ret = i40e_cloud_filter_qinq_create(pf);
@@ -7343,13 +7490,19 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf 
*pf,
 
        if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoUDP)
                pfilter->element.flags =
-                       I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP;
+                       I40E_AQC_ADD_CLOUD_FILTER_0X11;
        else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoGRE)
                pfilter->element.flags =
-                       I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE;
+                       I40E_AQC_ADD_CLOUD_FILTER_0X12;
+       else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_GTPC)
+               pfilter->element.flags =
+                       I40E_AQC_ADD_CLOUD_FILTER_0X11;
+       else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_GTPU)
+               pfilter->element.flags =
+                       I40E_AQC_ADD_CLOUD_FILTER_0X12;
        else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_QINQ)
                pfilter->element.flags |=
-                       I40E_AQC_ADD_CLOUD_FILTER_CUSTOM_QINQ;
+                       I40E_AQC_ADD_CLOUD_FILTER_0X10;
        else {
                val = i40e_dev_get_filter_type(tunnel_filter->filter_type,
                                                &pfilter->element.flags);
@@ -10870,14 +11023,14 @@ i40e_tunnel_filter_restore(struct i40e_pf *pf)
                           sizeof(f->input.general_fields));
 
                if (((f->input.flags &
-                    I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP) ==
-                    I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP) ||
+                    I40E_AQC_ADD_CLOUD_FILTER_0X11) ==
+                    I40E_AQC_ADD_CLOUD_FILTER_0X11) ||
                    ((f->input.flags &
-                    I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE) ==
-                    I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE) ||
+                    I40E_AQC_ADD_CLOUD_FILTER_0X12) ==
+                    I40E_AQC_ADD_CLOUD_FILTER_0X12) ||
                    ((f->input.flags &
-                    I40E_AQC_ADD_CLOUD_FILTER_CUSTOM_QINQ) ==
-                    I40E_AQC_ADD_CLOUD_FILTER_CUSTOM_QINQ))
+                    I40E_AQC_ADD_CLOUD_FILTER_0X10) ==
+                    I40E_AQC_ADD_CLOUD_FILTER_0X10))
                        big_buffer = 1;
 
                if (big_buffer)
@@ -11087,7 +11240,7 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
        /* create L1 filter */
        filter_replace.old_filter_type =
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_IVLAN;
-       filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_CUSTOM_QINQ;
+       filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_0X10;
        filter_replace.tr_bit = 0;
 
        /* Prepare the buffer, 2 entries */
@@ -11118,13 +11271,13 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
        /* create L2 filter, input for L2 filter will be L1 filter  */
        filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER;
        filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_OIP;
-       filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_CUSTOM_QINQ;
+       filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_0X10;
 
        /* Prepare the buffer, 2 entries */
        filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
        filter_replace_buf.data[0] |=
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
-       filter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_CUSTOM_QINQ;
+       filter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X10;
        filter_replace_buf.data[4] |=
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
        ret = i40e_aq_replace_cloud_filters(hw, &filter_replace,
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index f252ff3..087ff4d 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -643,10 +643,12 @@ struct i40e_ethertype_rule {
 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1 45
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSoUDP 8
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSoGRE 9
-#define I40E_AQC_ADD_CLOUD_FILTER_CUSTOM_QINQ 0x10
-#define I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP 0x11
-#define I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE 0x12
-#define I40E_AQC_ADD_L1_FILTER_TEID_MPLS 0x11
+#define I40E_AQC_ADD_CLOUD_FILTER_0X10 0x10
+#define I40E_AQC_ADD_CLOUD_FILTER_0X11 0x11
+#define I40E_AQC_ADD_CLOUD_FILTER_0X12 0x12
+#define I40E_AQC_ADD_L1_FILTER_0X11 0x11
+#define I40E_AQC_ADD_L1_FILTER_0X12 0x12
+#define I40E_AQC_ADD_L1_FILTER_0X13 0x13
 
 enum i40e_tunnel_iptype {
        I40E_TUNNEL_IPTYPE_IPV4,
@@ -896,6 +898,7 @@ struct i40e_pf {
        bool floating_veb_list[I40E_MAX_VF];
        struct i40e_flow_list flow_list;
        bool mpls_replace_flag;  /* 1 - MPLS filter replace is done */
+       bool gtp_replace_flag; /* 1 - GTP-C/U filter replace is done */
        bool qinq_replace_flag;  /* QINQ filter replace is done */
        struct i40e_tm_conf tm_conf;
        /* customer personalized pctype */
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index be44abb..7eb02fd 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -3751,15 +3751,17 @@ i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
  *    filled with 0.
  */
 static int
-i40e_flow_parse_gtp_pattern(__rte_unused struct rte_eth_dev *dev,
+i40e_flow_parse_gtp_pattern(struct rte_eth_dev *dev,
                            const struct rte_flow_item *pattern,
                            struct rte_flow_error *error,
                            struct i40e_tunnel_filter_conf *filter)
 {
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        const struct rte_flow_item *item = pattern;
        const struct rte_flow_item_gtp *gtp_spec;
        const struct rte_flow_item_gtp *gtp_mask;
        enum rte_flow_item_type item_type;
+       int pctype = 0;
 
        for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
                if (item->last) {
@@ -3809,6 +3811,16 @@ i40e_flow_parse_gtp_pattern(__rte_unused struct 
rte_eth_dev *dev,
                        gtp_mask =
                                (const struct rte_flow_item_gtp *)item->mask;
 
+                       pctype = i40e_flow_find_new_pctype(pf,
+                                                          item_type);
+                       if (pctype == I40E_INVALID_PCTYPE) {
+                               rte_flow_error_set(error, EINVAL,
+                                                  RTE_FLOW_ERROR_TYPE_ITEM,
+                                                  item,
+                                                  "Unsupported protocol");
+                               return -rte_errno;
+                       }
+
                        if (!gtp_spec || !gtp_mask) {
                                rte_flow_error_set(error, EINVAL,
                                                   RTE_FLOW_ERROR_TYPE_ITEM,
@@ -4245,12 +4257,12 @@ i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
                vsi = vf->vsi;
        }
 
-       if (((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP) ==
-           I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP) ||
-           ((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE) ==
-           I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE) ||
-           ((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_CUSTOM_QINQ) ==
-           I40E_AQC_ADD_CLOUD_FILTER_CUSTOM_QINQ))
+       if (((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_0X11) ==
+           I40E_AQC_ADD_CLOUD_FILTER_0X11) ||
+           ((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_0X12) ==
+           I40E_AQC_ADD_CLOUD_FILTER_0X12) ||
+           ((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_0X10) ==
+           I40E_AQC_ADD_CLOUD_FILTER_0X10))
                big_buffer = 1;
 
        if (big_buffer)
-- 
2.5.5

Reply via email to