Show a patch.

GET /api/patches/41387/
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 41387,
    "url": "http://patches.dpdk.org/api/patches/41387/",
    "web_url": "http://patches.dpdk.org/patch/41387/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk"
    },
    "msgid": "<22b7a1f11b2076719c3fee60306eec860ea3eed1.1529650435.git.rahul.lakkireddy@chelsio.com>",
    "date": "2018-06-22T09:56:05",
    "name": "[RFC,3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "d9035f42dcb42f782ac80fb522dfd41807b0dac4",
    "submitter": {
        "id": 241,
        "url": "http://patches.dpdk.org/api/people/241/",
        "name": "Rahul Lakkireddy",
        "email": "rahul.lakkireddy@chelsio.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@intel.com"
    },
    "mbox": "http://patches.dpdk.org/patch/41387/mbox/",
    "series": [
        {
            "id": 204,
            "url": "http://patches.dpdk.org/api/series/204/",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=204",
            "date": "2018-06-22T09:56:02",
            "name": "ethdev: add IP address and TCP/UDP port rewrite actions to flow API",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/204/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/41387/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/41387/checks/",
    "tags": {},
    "headers": {
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "X-Original-To": "patchwork@dpdk.org",
        "List-Post": "<mailto:dev@dpdk.org>",
        "References": [
            "<cover.1529650435.git.rahul.lakkireddy@chelsio.com>",
            "<cover.1529650435.git.rahul.lakkireddy@chelsio.com>"
        ],
        "X-BeenThere": "dev@dpdk.org",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "Subject": "[dpdk-dev] [RFC 3/3] net/cxgbe: add flow actions to modify IP and\n\tTCP/UDP port address",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "From": "Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id A26611BB71;\n\tFri, 22 Jun 2018 11:57:21 +0200 (CEST)",
            "from stargate.chelsio.com (stargate.chelsio.com [12.32.117.8])\n\tby dpdk.org (Postfix) with ESMTP id 832641BB3D\n\tfor <dev@dpdk.org>; Fri, 22 Jun 2018 11:57:19 +0200 (CEST)",
            "from localhost (scalar.blr.asicdesigners.com [10.193.185.94])\n\tby stargate.chelsio.com (8.13.8/8.13.8) with ESMTP id w5M9vF7G000812; \n\tFri, 22 Jun 2018 02:57:15 -0700"
        ],
        "To": "dev@dpdk.org",
        "X-Mailer": "git-send-email 2.5.3",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "Date": "Fri, 22 Jun 2018 15:26:05 +0530",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "Delivered-To": "patchwork@dpdk.org",
        "In-Reply-To": [
            "<cover.1529650435.git.rahul.lakkireddy@chelsio.com>",
            "<cover.1529650435.git.rahul.lakkireddy@chelsio.com>"
        ],
        "Cc": "shaguna@chelsio.com, indranil@chelsio.com, nirranjan@chelsio.com",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Message-Id": "<22b7a1f11b2076719c3fee60306eec860ea3eed1.1529650435.git.rahul.lakkireddy@chelsio.com>",
        "Return-Path": "<dev-bounces@dpdk.org>"
    },
    "content": "From: Shagun Agrawal <shaguna@chelsio.com>\n\nQuery firmware for the new filter work request to offload flows with\nactions to modify IP and TCP/UDP port addresses. When available,\ntranslate IP and TCP/UDP port address modify actions to internal\nhardware specification and offload the flow to hardware.\n\nSigned-off-by: Shagun Agrawal <shaguna@chelsio.com>\nSigned-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>\n---\n drivers/net/cxgbe/base/common.h         |   1 +\n drivers/net/cxgbe/base/t4fw_interface.h |  50 +++++++++++++\n drivers/net/cxgbe/cxgbe_filter.c        |  23 +++++-\n drivers/net/cxgbe/cxgbe_filter.h        |  26 ++++++-\n drivers/net/cxgbe/cxgbe_flow.c          | 127 ++++++++++++++++++++++++++++++++\n drivers/net/cxgbe/cxgbe_main.c          |  10 +++\n 6 files changed, 233 insertions(+), 4 deletions(-)",
    "diff": "diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h\nindex e524f7931..f4b2e14cd 100644\n--- a/drivers/net/cxgbe/base/common.h\n+++ b/drivers/net/cxgbe/base/common.h\n@@ -256,6 +256,7 @@ struct adapter_params {\n \n \tbool ulptx_memwrite_dsgl;          /* use of T5 DSGL allowed */\n \tu8 fw_caps_support;\t\t  /* 32-bit Port Capabilities */\n+\tbool filter2_wr_support;\t/* FW support for FILTER2_WR */\n };\n \n /* Firmware Port Capabilities types.\ndiff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h\nindex 842aa1263..d20d73590 100644\n--- a/drivers/net/cxgbe/base/t4fw_interface.h\n+++ b/drivers/net/cxgbe/base/t4fw_interface.h\n@@ -59,6 +59,7 @@ enum fw_wr_opcodes {\n \tFW_ETH_TX_PKTS_WR\t= 0x09,\n \tFW_ETH_TX_PKT_VM_WR\t= 0x11,\n \tFW_ETH_TX_PKTS_VM_WR\t= 0x12,\n+\tFW_FILTER2_WR\t\t= 0x77,\n \tFW_ETH_TX_PKTS2_WR      = 0x78,\n };\n \n@@ -185,6 +186,51 @@ struct fw_filter_wr {\n \t__u8   sma[6];\n };\n \n+struct fw_filter2_wr {\n+\t__be32 op_pkd;\n+\t__be32 len16_pkd;\n+\t__be64 r3;\n+\t__be32 tid_to_iq;\n+\t__be32 del_filter_to_l2tix;\n+\t__be16 ethtype;\n+\t__be16 ethtypem;\n+\t__u8   frag_to_ovlan_vldm;\n+\t__u8   smac_sel;\n+\t__be16 rx_chan_rx_rpl_iq;\n+\t__be32 maci_to_matchtypem;\n+\t__u8   ptcl;\n+\t__u8   ptclm;\n+\t__u8   ttyp;\n+\t__u8   ttypm;\n+\t__be16 ivlan;\n+\t__be16 ivlanm;\n+\t__be16 ovlan;\n+\t__be16 ovlanm;\n+\t__u8   lip[16];\n+\t__u8   lipm[16];\n+\t__u8   fip[16];\n+\t__u8   fipm[16];\n+\t__be16 lp;\n+\t__be16 lpm;\n+\t__be16 fp;\n+\t__be16 fpm;\n+\t__be16 r7;\n+\t__u8   sma[6];\n+\t__be16 r8;\n+\t__u8   filter_type_swapmac;\n+\t__u8   natmode_to_ulp_type;\n+\t__be16 newlport;\n+\t__be16 newfport;\n+\t__u8   newlip[16];\n+\t__u8   newfip[16];\n+\t__be32 natseqcheck;\n+\t__be32 r9;\n+\t__be64 r10;\n+\t__be64 r11;\n+\t__be64 r12;\n+\t__be64 r13;\n+};\n+\n #define S_FW_FILTER_WR_TID\t12\n #define V_FW_FILTER_WR_TID(x)\t((x) << S_FW_FILTER_WR_TID)\n \n@@ -288,6 +334,9 @@ struct fw_filter_wr {\n #define S_FW_FILTER_WR_MATCHTYPEM\t0\n #define V_FW_FILTER_WR_MATCHTYPEM(x)\t((x) << S_FW_FILTER_WR_MATCHTYPEM)\n \n+#define S_FW_FILTER2_WR_NATMODE\t\t5\n+#define V_FW_FILTER2_WR_NATMODE(x)\t((x) << S_FW_FILTER2_WR_NATMODE)\n+\n /******************************************************************************\n  *  C O M M A N D s\n  *********************/\n@@ -642,6 +691,7 @@ enum fw_params_param_dev {\n \tFW_PARAMS_PARAM_DEV_FWREV\t= 0x0B, /* fw version */\n \tFW_PARAMS_PARAM_DEV_TPREV\t= 0x0C, /* tp version */\n \tFW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,\n+\tFW_PARAMS_PARAM_DEV_FILTER2_WR\t= 0x1D,\n };\n \n /*\ndiff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c\nindex d098b9308..6744b6a60 100644\n--- a/drivers/net/cxgbe/cxgbe_filter.c\n+++ b/drivers/net/cxgbe/cxgbe_filter.c\n@@ -30,6 +30,10 @@ int validate_filter(struct adapter *adapter, struct ch_filter_specification *fs)\n \n #undef S\n #undef U\n+\n+\tif (fs->nat_mode && !adapter->params.filter2_wr_support)\n+\t\treturn -EOPNOTSUPP;\n+\n \treturn 0;\n }\n \n@@ -193,7 +197,7 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)\n \tstruct adapter *adapter = ethdev2adap(dev);\n \tstruct filter_entry *f = &adapter->tids.ftid_tab[fidx];\n \tstruct rte_mbuf *mbuf;\n-\tstruct fw_filter_wr *fwr;\n+\tstruct fw_filter2_wr *fwr;\n \tstruct sge_ctrl_txq *ctrlq;\n \tunsigned int port_id = ethdev2pinfo(dev)->port_id;\n \tint ret;\n@@ -208,13 +212,16 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)\n \tmbuf->data_len = sizeof(*fwr);\n \tmbuf->pkt_len = mbuf->data_len;\n \n-\tfwr = rte_pktmbuf_mtod(mbuf, struct fw_filter_wr *);\n+\tfwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);\n \tmemset(fwr, 0, sizeof(*fwr));\n \n \t/*\n \t * Construct the work request to set the filter.\n \t */\n-\tfwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));\n+\tif (adapter->params.filter2_wr_support)\n+\t\tfwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));\n+\telse\n+\t\tfwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));\n \tfwr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*fwr) / 16));\n \tfwr->tid_to_iq =\n \t\tcpu_to_be32(V_FW_FILTER_WR_TID(f->tid) |\n@@ -224,6 +231,7 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)\n \tfwr->del_filter_to_l2tix =\n \t\tcpu_to_be32(V_FW_FILTER_WR_DROP(f->fs.action == FILTER_DROP) |\n \t\t\t    V_FW_FILTER_WR_DIRSTEER(f->fs.dirsteer) |\n+\t\t\t    V_FW_FILTER_WR_LPBK(f->fs.action == FILTER_SWITCH) |\n \t\t\t    V_FW_FILTER_WR_HITCNTS(f->fs.hitcnts) |\n \t\t\t    V_FW_FILTER_WR_PRIO(f->fs.prio));\n \tfwr->ethtype = cpu_to_be16(f->fs.val.ethtype);\n@@ -244,6 +252,15 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)\n \tfwr->fp = cpu_to_be16(f->fs.val.fport);\n \tfwr->fpm = cpu_to_be16(f->fs.mask.fport);\n \n+\tif (adapter->params.filter2_wr_support && f->fs.nat_mode) {\n+\t\tfwr->natmode_to_ulp_type =\n+\t\t\tV_FW_FILTER2_WR_NATMODE(f->fs.nat_mode);\n+\t\tmemcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip));\n+\t\tmemcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip));\n+\t\tfwr->newlport = cpu_to_be16(f->fs.nat_lport);\n+\t\tfwr->newfport = cpu_to_be16(f->fs.nat_fport);\n+\t}\n+\n \t/*\n \t * Mark the filter as \"pending\" and ship off the Filter Work Request.\n \t * When we get the Work Request Reply we'll clear the pending status.\ndiff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h\nindex 4df37b9cd..609751474 100644\n--- a/drivers/net/cxgbe/cxgbe_filter.h\n+++ b/drivers/net/cxgbe/cxgbe_filter.h\n@@ -97,6 +97,18 @@ struct ch_filter_specification {\n \tuint32_t dirsteer:1;\t/* 0 => RSS, 1 => steer to iq */\n \tuint32_t iq:10;\t\t/* ingress queue */\n \n+\t/*\n+\t * Switch proxy/rewrite fields.  An ingress packet which matches a\n+\t * filter with \"switch\" set will be looped back out as an egress\n+\t * packet -- potentially with some Ethernet header rewriting.\n+\t */\n+\tuint32_t nat_mode:3;\t/* specify NAT operation mode */\n+\n+\tuint8_t nat_lip[16];\t/* local IP to use after NAT'ing */\n+\tuint8_t nat_fip[16];\t/* foreign IP to use after NAT'ing */\n+\tuint16_t nat_lport;\t/* local port to use after NAT'ing */\n+\tuint16_t nat_fport;\t/* foreign port to use after NAT'ing */\n+\n \t/* Filter rule value/mask pairs. */\n \tstruct ch_filter_tuple val;\n \tstruct ch_filter_tuple mask;\n@@ -104,7 +116,19 @@ struct ch_filter_specification {\n \n enum {\n \tFILTER_PASS = 0,\t/* default */\n-\tFILTER_DROP\n+\tFILTER_DROP,\n+\tFILTER_SWITCH,\n+};\n+\n+enum {\n+\tNAT_MODE_NONE = 0,\t/* No NAT performed */\n+\tNAT_MODE_DIP,\t\t/* NAT on Dst IP */\n+\tNAT_MODE_DIP_DP,\t/* NAT on Dst IP, Dst Port */\n+\tNAT_MODE_DIP_DP_SIP,\t/* NAT on Dst IP, Dst Port and Src IP */\n+\tNAT_MODE_DIP_DP_SP,\t/* NAT on Dst IP, Dst Port and Src Port */\n+\tNAT_MODE_SIP_SP,\t/* NAT on Src IP and Src Port */\n+\tNAT_MODE_DIP_SIP_SP,\t/* NAT on Dst IP, Src IP and Src Port */\n+\tNAT_MODE_ALL\t\t/* NAT on entire 4-tuple */\n };\n \n enum filter_type {\ndiff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c\nindex 23b7d00b3..1ef330a0f 100644\n--- a/drivers/net/cxgbe/cxgbe_flow.c\n+++ b/drivers/net/cxgbe/cxgbe_flow.c\n@@ -249,6 +249,97 @@ static int cxgbe_get_fidx(struct rte_flow *flow, unsigned int *fidx)\n \treturn 0;\n }\n \n+static int\n+ch_rte_parse_nat(uint8_t nmode, struct ch_filter_specification *fs)\n+{\n+\t/* nmode:\n+\t * BIT_0 = [src_ip],   BIT_1 = [dst_ip]\n+\t * BIT_2 = [src_port], BIT_3 = [dst_port]\n+\t *\n+\t * Only below cases are supported as per our spec.\n+\t */\n+\tswitch (nmode) {\n+\tcase 0:  /* 0000b */\n+\t\tfs->nat_mode = NAT_MODE_NONE;\n+\t\tbreak;\n+\tcase 2:  /* 0010b */\n+\t\tfs->nat_mode = NAT_MODE_DIP;\n+\t\tbreak;\n+\tcase 5:  /* 0101b */\n+\t\tfs->nat_mode = NAT_MODE_SIP_SP;\n+\t\tbreak;\n+\tcase 7:  /* 0111b */\n+\t\tfs->nat_mode = NAT_MODE_DIP_SIP_SP;\n+\t\tbreak;\n+\tcase 10: /* 1010b */\n+\t\tfs->nat_mode = NAT_MODE_DIP_DP;\n+\t\tbreak;\n+\tcase 11: /* 1011b */\n+\t\tfs->nat_mode = NAT_MODE_DIP_DP_SIP;\n+\t\tbreak;\n+\tcase 14: /* 1110 */\n+\t\tfs->nat_mode = NAT_MODE_DIP_DP_SP;\n+\t\tbreak;\n+\tcase 15: /* 1111b */\n+\t\tfs->nat_mode = NAT_MODE_ALL;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+ch_rte_parse_atype_switch(const struct rte_flow_action *a, uint8_t *nmode,\n+\t\t\t  struct ch_filter_specification *fs,\n+\t\t\t  struct rte_flow_error *e)\n+{\n+\tconst struct rte_flow_action_of_set_nw_ipv4 *ipv4;\n+\tconst struct rte_flow_action_of_set_nw_ipv6 *ipv6;\n+\tconst struct rte_flow_action_of_set_tp *port;\n+\n+\tswitch (a->type) {\n+\tcase RTE_FLOW_ACTION_TYPE_OF_SET_NW_IPV4_SRC:\n+\t\tipv4 = (const struct rte_flow_action_of_set_nw_ipv4 *)a->conf;\n+\t\tmemcpy(fs->nat_fip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));\n+\t\t*nmode |= 1 << 0;\n+\t\tbreak;\n+\tcase RTE_FLOW_ACTION_TYPE_OF_SET_NW_IPV4_DST:\n+\t\tipv4 = (const struct rte_flow_action_of_set_nw_ipv4 *)a->conf;\n+\t\tmemcpy(fs->nat_lip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));\n+\t\t*nmode |= 1 << 1;\n+\t\tbreak;\n+\tcase RTE_FLOW_ACTION_TYPE_OF_SET_NW_IPV6_SRC:\n+\t\tipv6 = (const struct rte_flow_action_of_set_nw_ipv6 *)a->conf;\n+\t\tmemcpy(fs->nat_fip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));\n+\t\t*nmode |= 1 << 0;\n+\t\tbreak;\n+\tcase RTE_FLOW_ACTION_TYPE_OF_SET_NW_IPV6_DST:\n+\t\tipv6 = (const struct rte_flow_action_of_set_nw_ipv6 *)a->conf;\n+\t\tmemcpy(fs->nat_lip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));\n+\t\t*nmode |= 1 << 1;\n+\t\tbreak;\n+\tcase RTE_FLOW_ACTION_TYPE_OF_SET_TP_SRC:\n+\t\tport = (const struct rte_flow_action_of_set_tp *)a->conf;\n+\t\tfs->nat_fport = be16_to_cpu(port->port);\n+\t\t*nmode |= 1 << 2;\n+\t\tbreak;\n+\tcase RTE_FLOW_ACTION_TYPE_OF_SET_TP_DST:\n+\t\tport = (const struct rte_flow_action_of_set_tp *)a->conf;\n+\t\tfs->nat_lport = be16_to_cpu(port->port);\n+\t\t*nmode |= 1 << 3;\n+\t\tbreak;\n+\tdefault:\n+\t\t/* We are not supposed to come here */\n+\t\treturn rte_flow_error_set(e, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, a,\n+\t\t\t\t\t  \"Action not supported\");\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n cxgbe_rtef_parse_actions(struct rte_flow *flow,\n \t\t\t const struct rte_flow_action action[],\n@@ -257,6 +348,8 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,\n \tstruct ch_filter_specification *fs = &flow->fs;\n \tconst struct rte_flow_action_queue *q;\n \tconst struct rte_flow_action *a;\n+\tint ret;\n+\tuint8_t nmode = 0, nat_ipv4 = 0, nat_ipv6 = 0;\n \tchar abit = 0;\n \n \tfor (a = action; a->type != RTE_FLOW_ACTION_TYPE_END; a++) {\n@@ -291,6 +384,36 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,\n \t\tcase RTE_FLOW_ACTION_TYPE_COUNT:\n \t\t\tfs->hitcnts = 1;\n \t\t\tbreak;\n+\n+\t\t/* switch actions */\n+\t\tcase RTE_FLOW_ACTION_TYPE_OF_SET_NW_IPV4_SRC:\n+\t\tcase RTE_FLOW_ACTION_TYPE_OF_SET_NW_IPV4_DST:\n+\t\t\tnat_ipv4++;\n+\t\t\tgoto action_switch;\n+\t\tcase RTE_FLOW_ACTION_TYPE_OF_SET_NW_IPV6_SRC:\n+\t\tcase RTE_FLOW_ACTION_TYPE_OF_SET_NW_IPV6_DST:\n+\t\t\tnat_ipv6++;\n+\t\tcase RTE_FLOW_ACTION_TYPE_OF_SET_TP_SRC:\n+\t\tcase RTE_FLOW_ACTION_TYPE_OF_SET_TP_DST:\n+action_switch:\n+\t\t\t/* We allow multiple switch actions, but switch is\n+\t\t\t * not compatible with either queue or drop\n+\t\t\t */\n+\t\t\tif (abit++ && fs->action != FILTER_SWITCH)\n+\t\t\t\treturn rte_flow_error_set(e, EINVAL,\n+\t\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ACTION, a,\n+\t\t\t\t\t\t\"overlapping action specified\");\n+\t\t\tif (nat_ipv4 && nat_ipv6)\n+\t\t\t\treturn rte_flow_error_set(e, EINVAL,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ACTION, a,\n+\t\t\t\t\t\"Can't have one address ipv4 and the\"\n+\t\t\t\t\t\" other ipv6\");\n+\n+\t\t\tret = ch_rte_parse_atype_switch(a, &nmode, fs, e);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\t\t\tfs->action = FILTER_SWITCH;\n+\t\t\tbreak;\n \t\tdefault:\n \t\t\t/* Not supported action : return error */\n \t\t\treturn rte_flow_error_set(e, ENOTSUP,\n@@ -299,6 +422,10 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,\n \t\t}\n \t}\n \n+\tif (ch_rte_parse_nat(nmode, fs))\n+\t\treturn rte_flow_error_set(e, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, a,\n+\t\t\t\t\t  \"invalid settings for swich action\");\n \treturn 0;\n }\n \ndiff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c\nindex 21ad380ae..50d93e7da 100644\n--- a/drivers/net/cxgbe/cxgbe_main.c\n+++ b/drivers/net/cxgbe/cxgbe_main.c\n@@ -990,6 +990,16 @@ static int adap_init0(struct adapter *adap)\n \tif (ret < 0)\n \t\tgoto bye;\n \n+\t/* See if FW supports FW_FILTER2 work request */\n+\tif (is_t4(adap->params.chip)) {\n+\t\tadap->params.filter2_wr_support = 0;\n+\t} else {\n+\t\tparams[0] = FW_PARAM_DEV(FILTER2_WR);\n+\t\tret = t4_query_params(adap, adap->mbox, adap->pf, 0,\n+\t\t\t\t      1, params, val);\n+\t\tadap->params.filter2_wr_support = (ret == 0 && val[0] != 0);\n+\t}\n+\n \t/* query tid-related parameters */\n \tparams[0] = FW_PARAM_DEV(NTID);\n \tret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,\n",
    "prefixes": [
        "RFC",
        "3/3"
    ]
}