All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
To: dev@dpdk.org
Cc: indranil@chelsio.com, nirranjan@chelsio.com
Subject: [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
Date: Tue,  9 Oct 2018 14:14:38 +0530	[thread overview]
Message-ID: <e43e63c404448dd66241bab98275f9c1a7c5ed08.1539073823.git.rahul.lakkireddy@chelsio.com> (raw)
In-Reply-To: <cover.1539073823.git.rahul.lakkireddy@chelsio.com>
In-Reply-To: <cover.1539073823.git.rahul.lakkireddy@chelsio.com>

Query firmware for the new filter work request to offload flows with
actions to modify IP and TCP/UDP port addresses. When available,
translate IP and TCP/UDP port address modify actions to internal
hardware specification and offload the flow to hardware.

Original work by Shagun Agrawal

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v3:
- No changes.

v2:
- No changes.

v1 changes since RFC v2:
- Re-based to tip.
- Updated all instances of fw_filter_wr to new fw_filter2_wr and removed
  fw_filter_wr.
- Ensure correct ULP type is set when offloading NAT actions.
- Returning appropriate RTE_FLOW_ERROR_TYPE_ACTION error if a corresponding
  valid flow pattern item for the header rewrite action is not found.
- Updated release notes.

 doc/guides/rel_notes/release_18_11.rst  |   4 +-
 drivers/net/cxgbe/base/common.h         |   1 +
 drivers/net/cxgbe/base/t4_msg.h         |   1 +
 drivers/net/cxgbe/base/t4fw_interface.h |  23 ++-
 drivers/net/cxgbe/cxgbe_filter.c        |  37 +++--
 drivers/net/cxgbe/cxgbe_filter.h        |  23 +++
 drivers/net/cxgbe/cxgbe_flow.c          | 178 +++++++++++++++++++++++-
 drivers/net/cxgbe/cxgbe_main.c          |  10 ++
 8 files changed, 265 insertions(+), 12 deletions(-)

diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 2b4808226..9a135c89c 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -59,7 +59,9 @@ New Features
   Flow API support has been enhanced for CXGBE Poll Mode Driver to offload:
 
   * Match items: destination MAC address.
-  * Action items: push/pop/rewrite vlan header.
+  * Action items: push/pop/rewrite vlan header, rewrite IP addresses in
+    outermost IPv4/IPv6 header, rewrite port numbers in outermost TCP/UDP
+    header.
 
 * **Added a devarg to use the latest supported vector path in i40e.**
   A new devarg ``use-latest-supported-vec`` was introduced to allow users to
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index d9f74d995..fd2006682 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -271,6 +271,7 @@ struct adapter_params {
 
 	bool ulptx_memwrite_dsgl;          /* use of T5 DSGL allowed */
 	u8 fw_caps_support;		  /* 32-bit Port Capabilities */
+	u8 filter2_wr_support;            /* FW support for FILTER2_WR */
 };
 
 /* Firmware Port Capabilities types.
diff --git a/drivers/net/cxgbe/base/t4_msg.h b/drivers/net/cxgbe/base/t4_msg.h
index 2128da64f..6494f1827 100644
--- a/drivers/net/cxgbe/base/t4_msg.h
+++ b/drivers/net/cxgbe/base/t4_msg.h
@@ -32,6 +32,7 @@ enum CPL_error {
 
 enum {
 	ULP_MODE_NONE          = 0,
+	ULP_MODE_TCPDDP        = 5,
 };
 
 enum {
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index e2d2ee897..b4c95c588 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -61,6 +61,7 @@ enum fw_wr_opcodes {
 	FW_ETH_TX_PKTS_WR	= 0x09,
 	FW_ETH_TX_PKT_VM_WR	= 0x11,
 	FW_ETH_TX_PKTS_VM_WR	= 0x12,
+	FW_FILTER2_WR		= 0x77,
 	FW_ETH_TX_PKTS2_WR      = 0x78,
 };
 
@@ -165,7 +166,7 @@ enum fw_filter_wr_cookie {
 	FW_FILTER_WR_EINVAL,
 };
 
-struct fw_filter_wr {
+struct fw_filter2_wr {
 	__be32 op_pkd;
 	__be32 len16_pkd;
 	__be64 r3;
@@ -195,6 +196,19 @@ struct fw_filter_wr {
 	__be16 fpm;
 	__be16 r7;
 	__u8   sma[6];
+	__be16 r8;
+	__u8   filter_type_swapmac;
+	__u8   natmode_to_ulp_type;
+	__be16 newlport;
+	__be16 newfport;
+	__u8   newlip[16];
+	__u8   newfip[16];
+	__be32 natseqcheck;
+	__be32 r9;
+	__be64 r10;
+	__be64 r11;
+	__be64 r12;
+	__be64 r13;
 };
 
 #define S_FW_FILTER_WR_TID	12
@@ -300,6 +314,12 @@ struct fw_filter_wr {
 #define S_FW_FILTER_WR_MATCHTYPEM	0
 #define V_FW_FILTER_WR_MATCHTYPEM(x)	((x) << S_FW_FILTER_WR_MATCHTYPEM)
 
+#define S_FW_FILTER2_WR_NATMODE		5
+#define V_FW_FILTER2_WR_NATMODE(x)	((x) << S_FW_FILTER2_WR_NATMODE)
+
+#define S_FW_FILTER2_WR_ULP_TYPE	0
+#define V_FW_FILTER2_WR_ULP_TYPE(x)	((x) << S_FW_FILTER2_WR_ULP_TYPE)
+
 /******************************************************************************
  *  C O M M A N D s
  *********************/
@@ -655,6 +675,7 @@ enum fw_params_param_dev {
 	FW_PARAMS_PARAM_DEV_FWREV	= 0x0B, /* fw version */
 	FW_PARAMS_PARAM_DEV_TPREV	= 0x0C, /* tp version */
 	FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
+	FW_PARAMS_PARAM_DEV_FILTER2_WR	= 0x1D,
 };
 
 /*
diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index dcb1dd03e..b876abf43 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -89,6 +89,9 @@ int validate_filter(struct adapter *adapter, struct ch_filter_specification *fs)
 	if (fs->val.iport >= adapter->params.nports)
 		return -ERANGE;
 
+	if (!fs->cap && fs->nat_mode && !adapter->params.filter2_wr_support)
+		return -EOPNOTSUPP;
+
 	return 0;
 }
 
@@ -627,6 +630,7 @@ void clear_filter(struct filter_entry *f)
 
 /**
  * t4_mk_filtdelwr - create a delete filter WR
+ * @adap: adapter context
  * @ftid: the filter ID
  * @wr: the filter work request to populate
  * @qid: ingress queue to receive the delete notification
@@ -634,10 +638,14 @@ void clear_filter(struct filter_entry *f)
  * Creates a filter work request to delete the supplied filter.  If @qid is
  * negative the delete notification is suppressed.
  */
-static void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid)
+static void t4_mk_filtdelwr(struct adapter *adap, unsigned int ftid,
+			    struct fw_filter2_wr *wr, int qid)
 {
 	memset(wr, 0, sizeof(*wr));
-	wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
+	if (adap->params.filter2_wr_support)
+		wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
+	else
+		wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
 	wr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*wr) / 16));
 	wr->tid_to_iq = cpu_to_be32(V_FW_FILTER_WR_TID(ftid) |
 				    V_FW_FILTER_WR_NOREPLY(qid < 0));
@@ -655,7 +663,7 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 	struct adapter *adapter = ethdev2adap(dev);
 	struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
 	struct rte_mbuf *mbuf;
-	struct fw_filter_wr *fwr;
+	struct fw_filter2_wr *fwr;
 	struct sge_ctrl_txq *ctrlq;
 	unsigned int port_id = ethdev2pinfo(dev)->port_id;
 
@@ -667,8 +675,8 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 	mbuf->data_len = sizeof(*fwr);
 	mbuf->pkt_len = mbuf->data_len;
 
-	fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter_wr *);
-	t4_mk_filtdelwr(f->tid, fwr, adapter->sge.fw_evtq.abs_id);
+	fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
+	t4_mk_filtdelwr(adapter, f->tid, fwr, adapter->sge.fw_evtq.abs_id);
 
 	/*
 	 * Mark the filter as "pending" and ship off the Filter Work Request.
@@ -684,7 +692,7 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 	struct adapter *adapter = ethdev2adap(dev);
 	struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
 	struct rte_mbuf *mbuf;
-	struct fw_filter_wr *fwr;
+	struct fw_filter2_wr *fwr;
 	struct sge_ctrl_txq *ctrlq;
 	unsigned int port_id = ethdev2pinfo(dev)->port_id;
 	int ret;
@@ -712,13 +720,16 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 	mbuf->data_len = sizeof(*fwr);
 	mbuf->pkt_len = mbuf->data_len;
 
-	fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter_wr *);
+	fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
 	memset(fwr, 0, sizeof(*fwr));
 
 	/*
 	 * Construct the work request to set the filter.
 	 */
-	fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
+	if (adapter->params.filter2_wr_support)
+		fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
+	else
+		fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
 	fwr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*fwr) / 16));
 	fwr->tid_to_iq =
 		cpu_to_be32(V_FW_FILTER_WR_TID(f->tid) |
@@ -762,6 +773,16 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
 	fwr->fp = cpu_to_be16(f->fs.val.fport);
 	fwr->fpm = cpu_to_be16(f->fs.mask.fport);
 
+	if (adapter->params.filter2_wr_support && f->fs.nat_mode) {
+		fwr->natmode_to_ulp_type =
+			V_FW_FILTER2_WR_ULP_TYPE(ULP_MODE_TCPDDP) |
+			V_FW_FILTER2_WR_NATMODE(f->fs.nat_mode);
+		memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip));
+		memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip));
+		fwr->newlport = cpu_to_be16(f->fs.nat_lport);
+		fwr->newfport = cpu_to_be16(f->fs.nat_fport);
+	}
+
 	/*
 	 * Mark the filter as "pending" and ship off the Filter Work Request.
 	 * When we get the Work Request Reply we'll clear the pending status.
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 83d647de6..950fa0bca 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -104,6 +104,18 @@ struct ch_filter_specification {
 	uint8_t dmac[ETHER_ADDR_LEN];   /* new destination MAC address */
 	uint16_t vlan;          /* VLAN Tag to insert */
 
+	/*
+	 * Switch proxy/rewrite fields.  An ingress packet which matches a
+	 * filter with "switch" set will be looped back out as an egress
+	 * packet -- potentially with some header rewriting.
+	 */
+	uint32_t nat_mode:3;	/* specify NAT operation mode */
+
+	uint8_t nat_lip[16];	/* local IP to use after NAT'ing */
+	uint8_t nat_fip[16];	/* foreign IP to use after NAT'ing */
+	uint16_t nat_lport;	/* local port number to use after NAT'ing */
+	uint16_t nat_fport;	/* foreign port number to use after NAT'ing */
+
 	/* Filter rule value/mask pairs. */
 	struct ch_filter_tuple val;
 	struct ch_filter_tuple mask;
@@ -121,6 +133,17 @@ enum {
 	VLAN_REWRITE
 };
 
+enum {
+	NAT_MODE_NONE = 0,	/* No NAT performed */
+	NAT_MODE_DIP,		/* NAT on Dst IP */
+	NAT_MODE_DIP_DP,	/* NAT on Dst IP, Dst Port */
+	NAT_MODE_DIP_DP_SIP,	/* NAT on Dst IP, Dst Port and Src IP */
+	NAT_MODE_DIP_DP_SP,	/* NAT on Dst IP, Dst Port and Src Port */
+	NAT_MODE_SIP_SP,	/* NAT on Src IP and Src Port */
+	NAT_MODE_DIP_SIP_SP,	/* NAT on Dst IP, Src IP and Src Port */
+	NAT_MODE_ALL		/* NAT on entire 4-tuple */
+};
+
 enum filter_type {
 	FILTER_TYPE_IPV4 = 0,
 	FILTER_TYPE_IPV6,
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index bee3bd640..52cb3bdf4 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -368,14 +368,77 @@ static int cxgbe_get_fidx(struct rte_flow *flow, unsigned int *fidx)
 	return 0;
 }
 
+static int
+cxgbe_get_flow_item_index(const struct rte_flow_item items[], u32 type)
+{
+	const struct rte_flow_item *i;
+	int j, index = -ENOENT;
+
+	for (i = items, j = 0; i->type != RTE_FLOW_ITEM_TYPE_END; i++, j++) {
+		if (i->type == type) {
+			index = j;
+			break;
+		}
+	}
+
+	return index;
+}
+
+static int
+ch_rte_parse_nat(uint8_t nmode, struct ch_filter_specification *fs)
+{
+	/* nmode:
+	 * BIT_0 = [src_ip],   BIT_1 = [dst_ip]
+	 * BIT_2 = [src_port], BIT_3 = [dst_port]
+	 *
+	 * Only below cases are supported as per our spec.
+	 */
+	switch (nmode) {
+	case 0:  /* 0000b */
+		fs->nat_mode = NAT_MODE_NONE;
+		break;
+	case 2:  /* 0010b */
+		fs->nat_mode = NAT_MODE_DIP;
+		break;
+	case 5:  /* 0101b */
+		fs->nat_mode = NAT_MODE_SIP_SP;
+		break;
+	case 7:  /* 0111b */
+		fs->nat_mode = NAT_MODE_DIP_SIP_SP;
+		break;
+	case 10: /* 1010b */
+		fs->nat_mode = NAT_MODE_DIP_DP;
+		break;
+	case 11: /* 1011b */
+		fs->nat_mode = NAT_MODE_DIP_DP_SIP;
+		break;
+	case 14: /* 1110b */
+		fs->nat_mode = NAT_MODE_DIP_DP_SP;
+		break;
+	case 15: /* 1111b */
+		fs->nat_mode = NAT_MODE_ALL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int
 ch_rte_parse_atype_switch(const struct rte_flow_action *a,
+			  const struct rte_flow_item items[],
+			  uint8_t *nmode,
 			  struct ch_filter_specification *fs,
 			  struct rte_flow_error *e)
 {
 	const struct rte_flow_action_of_set_vlan_vid *vlanid;
 	const struct rte_flow_action_of_push_vlan *pushvlan;
+	const struct rte_flow_action_set_ipv4 *ipv4;
+	const struct rte_flow_action_set_ipv6 *ipv6;
+	const struct rte_flow_action_set_tp *tp_port;
 	const struct rte_flow_action_phy_port *port;
+	int item_index;
 
 	switch (a->type) {
 	case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
@@ -401,6 +464,94 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
 		port = (const struct rte_flow_action_phy_port *)a->conf;
 		fs->eport = port->index;
 		break;
+	case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+		item_index = cxgbe_get_flow_item_index(items,
+						       RTE_FLOW_ITEM_TYPE_IPV4);
+		if (item_index < 0)
+			return rte_flow_error_set(e, EINVAL,
+						  RTE_FLOW_ERROR_TYPE_ACTION, a,
+						  "No RTE_FLOW_ITEM_TYPE_IPV4 "
+						  "found.");
+
+		ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf;
+		memcpy(fs->nat_fip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));
+		*nmode |= 1 << 0;
+		break;
+	case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+		item_index = cxgbe_get_flow_item_index(items,
+						       RTE_FLOW_ITEM_TYPE_IPV4);
+		if (item_index < 0)
+			return rte_flow_error_set(e, EINVAL,
+						  RTE_FLOW_ERROR_TYPE_ACTION, a,
+						  "No RTE_FLOW_ITEM_TYPE_IPV4 "
+						  "found.");
+
+		ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf;
+		memcpy(fs->nat_lip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));
+		*nmode |= 1 << 1;
+		break;
+	case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+		item_index = cxgbe_get_flow_item_index(items,
+						       RTE_FLOW_ITEM_TYPE_IPV6);
+		if (item_index < 0)
+			return rte_flow_error_set(e, EINVAL,
+						  RTE_FLOW_ERROR_TYPE_ACTION, a,
+						  "No RTE_FLOW_ITEM_TYPE_IPV6 "
+						  "found.");
+
+		ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf;
+		memcpy(fs->nat_fip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));
+		*nmode |= 1 << 0;
+		break;
+	case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+		item_index = cxgbe_get_flow_item_index(items,
+						       RTE_FLOW_ITEM_TYPE_IPV6);
+		if (item_index < 0)
+			return rte_flow_error_set(e, EINVAL,
+						  RTE_FLOW_ERROR_TYPE_ACTION, a,
+						  "No RTE_FLOW_ITEM_TYPE_IPV6 "
+						  "found.");
+
+		ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf;
+		memcpy(fs->nat_lip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));
+		*nmode |= 1 << 1;
+		break;
+	case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+		item_index = cxgbe_get_flow_item_index(items,
+						       RTE_FLOW_ITEM_TYPE_TCP);
+		if (item_index < 0) {
+			item_index =
+				cxgbe_get_flow_item_index(items,
+						RTE_FLOW_ITEM_TYPE_UDP);
+			if (item_index < 0)
+				return rte_flow_error_set(e, EINVAL,
+						RTE_FLOW_ERROR_TYPE_ACTION, a,
+						"No RTE_FLOW_ITEM_TYPE_TCP or "
+						"RTE_FLOW_ITEM_TYPE_UDP found");
+		}
+
+		tp_port = (const struct rte_flow_action_set_tp *)a->conf;
+		fs->nat_fport = be16_to_cpu(tp_port->port);
+		*nmode |= 1 << 2;
+		break;
+	case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+		item_index = cxgbe_get_flow_item_index(items,
+						       RTE_FLOW_ITEM_TYPE_TCP);
+		if (item_index < 0) {
+			item_index =
+				cxgbe_get_flow_item_index(items,
+						RTE_FLOW_ITEM_TYPE_UDP);
+			if (item_index < 0)
+				return rte_flow_error_set(e, EINVAL,
+						RTE_FLOW_ERROR_TYPE_ACTION, a,
+						"No RTE_FLOW_ITEM_TYPE_TCP or "
+						"RTE_FLOW_ITEM_TYPE_UDP found");
+		}
+
+		tp_port = (const struct rte_flow_action_set_tp *)a->conf;
+		fs->nat_lport = be16_to_cpu(tp_port->port);
+		*nmode |= 1 << 3;
+		break;
 	default:
 		/* We are not supposed to come here */
 		return rte_flow_error_set(e, EINVAL,
@@ -413,10 +564,12 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
 
 static int
 cxgbe_rtef_parse_actions(struct rte_flow *flow,
+			 const struct rte_flow_item items[],
 			 const struct rte_flow_action action[],
 			 struct rte_flow_error *e)
 {
 	struct ch_filter_specification *fs = &flow->fs;
+	uint8_t nmode = 0, nat_ipv4 = 0, nat_ipv6 = 0;
 	const struct rte_flow_action_queue *q;
 	const struct rte_flow_action *a;
 	char abit = 0;
@@ -458,6 +611,16 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
 		case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
 		case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
 		case RTE_FLOW_ACTION_TYPE_PHY_PORT:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+			nat_ipv4++;
+			goto action_switch;
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+			nat_ipv6++;
+		case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+action_switch:
 			/* We allow multiple switch actions, but switch is
 			 * not compatible with either queue or drop
 			 */
@@ -465,7 +628,14 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
 				return rte_flow_error_set(e, EINVAL,
 						RTE_FLOW_ERROR_TYPE_ACTION, a,
 						"overlapping action specified");
-			ret = ch_rte_parse_atype_switch(a, fs, e);
+			if (nat_ipv4 && nat_ipv6)
+				return rte_flow_error_set(e, EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION, a,
+					"Can't have one address ipv4 and the"
+					" other ipv6");
+
+			ret = ch_rte_parse_atype_switch(a, items, &nmode, fs,
+							e);
 			if (ret)
 				return ret;
 			fs->action = FILTER_SWITCH;
@@ -478,6 +648,10 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
 		}
 	}
 
+	if (ch_rte_parse_nat(nmode, fs))
+		return rte_flow_error_set(e, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, a,
+					  "invalid settings for swich action");
 	return 0;
 }
 
@@ -586,7 +760,7 @@ cxgbe_flow_parse(struct rte_flow *flow,
 	ret = cxgbe_rtef_parse_items(flow, item, e);
 	if (ret)
 		return ret;
-	return cxgbe_rtef_parse_actions(flow, action, e);
+	return cxgbe_rtef_parse_actions(flow, item, action, e);
 }
 
 static int __cxgbe_flow_create(struct rte_eth_dev *dev, struct rte_flow *flow)
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 9c40f51b2..a135df9c7 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -1180,6 +1180,16 @@ static int adap_init0(struct adapter *adap)
 			goto bye;
 	}
 
+	/* See if FW supports FW_FILTER2 work request */
+	if (is_t4(adap->params.chip)) {
+		adap->params.filter2_wr_support = 0;
+	} else {
+		params[0] = FW_PARAM_DEV(FILTER2_WR);
+		ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+				      1, params, val);
+		adap->params.filter2_wr_support = (ret == 0 && val[0] != 0);
+	}
+
 	/* query tid-related parameters */
 	params[0] = FW_PARAM_DEV(NTID);
 	ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
-- 
2.18.0

  parent reply	other threads:[~2018-10-09  8:45 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-24  8:28 [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
2018-09-24  8:28 ` [PATCH 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
2018-09-25  3:03   ` Xiaoyu Min
2018-09-24  8:28 ` [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
2018-09-25  3:06   ` Xiaoyu Min
2018-10-04 13:55   ` Ori Kam
2018-10-04 15:35     ` Ferruh Yigit
2018-09-24  8:28 ` [PATCH 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
2018-10-03 20:33 ` [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Thomas Monjalon
2018-10-06 15:41 ` [PATCH v2 " Rahul Lakkireddy
2018-10-06 15:41   ` [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
2018-10-08  9:22     ` Andrew Rybchenko
2018-10-06 15:41   ` [PATCH v2 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
2018-10-08  9:24     ` Andrew Rybchenko
2018-10-06 15:42   ` [PATCH v2 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
2018-10-09  8:44   ` [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
2018-10-09  8:44     ` [PATCH v3 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
2018-10-09  8:44     ` [PATCH v3 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
2018-10-09  8:44     ` Rahul Lakkireddy [this message]
2018-10-09 12:25       ` [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Ferruh Yigit
2018-10-09 12:39         ` Rahul Lakkireddy
2018-10-09 13:04     ` [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e43e63c404448dd66241bab98275f9c1a7c5ed08.1539073823.git.rahul.lakkireddy@chelsio.com \
    --to=rahul.lakkireddy@chelsio.com \
    --cc=dev@dpdk.org \
    --cc=indranil@chelsio.com \
    --cc=nirranjan@chelsio.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.