* [dpdk-dev] [PATCH] net/enic: support GTP header flow matching
@ 2021-10-26 1:16 John Daley
2021-10-28 6:36 ` [dpdk-dev] [PATCH v2] " John Daley
0 siblings, 1 reply; 4+ messages in thread
From: John Daley @ 2021-10-26 1:16 UTC (permalink / raw)
To: ferruh.yigit, arybchenko; +Cc: dev, John Daley, Hyong Youb Kim
The GTP, GTP-U, GTP-C header fields can be matched, however NIC does not
support GTP tunneling so no items after the GTP header can be specified.
If a GTP-U or GTP-C item is specified without a preceding UDP item, the
UDP destination port is implicitly matched. For GTP, the destination UDP
port must be specified but its value is not enforced.
Signed-off-by: John Daley <johndale@cisco.com>
Reviewed-by: Hyong Youb Kim <hyonkim@cisco.com>
---
doc/guides/nics/enic.rst | 2 +
doc/guides/nics/features/enic.ini | 3 +
doc/guides/rel_notes/release_21_11.rst | 4 +
drivers/net/enic/enic_fm_flow.c | 119 +++++++++++++++++++++++++
4 files changed, 128 insertions(+)
diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index f2ee49fe82..5e2054fc8a 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -473,6 +473,8 @@ RTE_MBUF_F_RX_VLAN_STRIPPED mbuf flags would not be set. This mode is enabled wi
packets and then receive them normally. These require 1400 series VIC adapters
and latest firmware.
- RAW items are limited to matching UDP tunnel headers like VXLAN.
+ - GTP, GTP-C and GTP-U header matching is enabled, however matching items within
+ the tunnel is not supported.
- For 1400 VICs, all flows using the RSS action on a port use same hash
configuration. The RETA is ignored. The queues used in the RSS group must be
sequential. There is a performance hit if the number of queues is not a power of 2.
diff --git a/doc/guides/nics/features/enic.ini b/doc/guides/nics/features/enic.ini
index 3064336162..1177752c15 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -40,6 +40,9 @@ Usage doc = Y
[rte_flow items]
eth = Y
+gtp = Y
+gtpc = Y
+gtpu = Y
ipv4 = Y
ipv6 = Y
raw = Y
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 1ccac87b73..2cee5347f3 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -154,6 +154,10 @@ New Features
* Implement support for tunnel offload.
* Updated HWRM API to version 1.10.2.44
+* **Updated Cisco enic driver.**
+
+ * Added rte_flow support for matching GTP, GTP-C and GTP-U headers.
+
* **Updated Intel e1000 emulated driver.**
* Added Intel e1000 support on Windows.
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 2c60bb864e..e318a5f828 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -235,6 +235,7 @@ static enic_copy_item_fn enic_fm_copy_item_tcp;
static enic_copy_item_fn enic_fm_copy_item_udp;
static enic_copy_item_fn enic_fm_copy_item_vlan;
static enic_copy_item_fn enic_fm_copy_item_vxlan;
+static enic_copy_item_fn enic_fm_copy_item_gtp;
/* Ingress actions */
static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -346,6 +347,30 @@ static const struct enic_fm_items enic_fm_items[] = {
RTE_FLOW_ITEM_TYPE_END,
},
},
+ [RTE_FLOW_ITEM_TYPE_GTP] = {
+ .copy_item = enic_fm_copy_item_gtp,
+ .valid_start_item = 0,
+ .prev_items = (const enum rte_flow_item_type[]) {
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_END,
+ },
+ },
+ [RTE_FLOW_ITEM_TYPE_GTPC] = {
+ .copy_item = enic_fm_copy_item_gtp,
+ .valid_start_item = 1,
+ .prev_items = (const enum rte_flow_item_type[]) {
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_END,
+ },
+ },
+ [RTE_FLOW_ITEM_TYPE_GTPU] = {
+ .copy_item = enic_fm_copy_item_gtp,
+ .valid_start_item = 1,
+ .prev_items = (const enum rte_flow_item_type[]) {
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_END,
+ },
+ },
};
static int
@@ -629,6 +654,100 @@ enic_fm_copy_item_vxlan(struct copy_item_args *arg)
return 0;
}
+static int
+enic_fm_copy_item_gtp(struct copy_item_args *arg)
+{
+ const struct rte_flow_item *item = arg->item;
+ const struct rte_flow_item_gtp *spec = item->spec;
+ const struct rte_flow_item_gtp *mask = item->mask;
+ struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+ struct fm_header_set *fm_data, *fm_mask;
+ int off;
+ uint16_t udp_gtp_uc_port = 0;
+
+ ENICPMD_FUNC_TRACE();
+ /* Only 2 header levels (outer and inner) allowed */
+ if (arg->header_level > 0)
+ return -EINVAL;
+
+ fm_data = &entry->ftm_data.fk_hdrset[0];
+ fm_mask = &entry->ftm_mask.fk_hdrset[0];
+
+ switch (item->type) {
+ case RTE_FLOW_ITEM_TYPE_GTP:
+ {
+ /* For vanilla GTP, the UDP destination port must be specified
+ * but value of the port is not enforced here.
+ */
+ if (!(fm_data->fk_metadata & FKM_UDP) ||
+ !(fm_data->fk_header_select & FKH_UDP) ||
+ fm_data->l4.udp.fk_dest == 0)
+ return -EINVAL;
+ if (!(fm_mask->fk_metadata & FKM_UDP) ||
+ !(fm_mask->fk_header_select & FKH_UDP) ||
+ fm_mask->l4.udp.fk_dest != 0xFFFF)
+ return -EINVAL;
+ break;
+ }
+ case RTE_FLOW_ITEM_TYPE_GTPC:
+ {
+ udp_gtp_uc_port = RTE_GTPC_UDP_PORT;
+ break;
+ }
+ case RTE_FLOW_ITEM_TYPE_GTPU:
+ {
+ udp_gtp_uc_port = RTE_GTPU_UDP_PORT;
+ break;
+ }
+ default:
+ RTE_ASSERT(0);
+ }
+
+ /* The GTP-C or GTP-U UDP destination port must be matched. */
+ if (udp_gtp_uc_port) {
+ if (fm_data->fk_metadata & FKM_UDP &&
+ fm_data->fk_header_select & FKH_UDP &&
+ rte_be_to_cpu_16(fm_data->l4.udp.fk_dest) !=
+ udp_gtp_uc_port)
+ return -EINVAL;
+ if (fm_mask->fk_metadata & FKM_UDP &&
+ fm_mask->fk_header_select & FKH_UDP &&
+ fm_mask->l4.udp.fk_dest != 0xFFFF)
+ return -EINVAL;
+
+ /* In any case, add match for GTP-C GTP-U UDP dst port */
+ fm_data->fk_metadata |= FKM_UDP;
+ fm_data->fk_header_select |= FKH_UDP;
+ fm_data->l4.udp.fk_dest = udp_gtp_uc_port;
+ fm_mask->fk_metadata |= FKM_UDP;
+ fm_mask->fk_header_select |= FKH_UDP;
+ fm_mask->l4.udp.fk_dest = 0xFFFF;
+ }
+
+ /* NIC does not support GTP tunnels. No Items are allowed after this.
+ * This prevents the specificaiton of further items.
+ */
+ arg->header_level = 0;
+
+ /* Match all if no spec */
+ if (!spec)
+ return 0;
+ if (!mask)
+ mask = &rte_flow_item_gtp_mask;
+
+ /*
+ * Use the raw L4 buffer to match GTP as fm_header_set does not have
+ * GTP header. UDP dst port must be specifiec. Using the raw buffer
+ * does not affect such UDP item, since we skip UDP in the raw buffer.
+ */
+ fm_data->fk_header_select |= FKH_L4RAW;
+ fm_mask->fk_header_select |= FKH_L4RAW;
+ off = sizeof(fm_data->l4.udp);
+ memcpy(&fm_data->l4.rawdata[off], spec, sizeof(*spec));
+ memcpy(&fm_mask->l4.rawdata[off], mask, sizeof(*mask));
+ return 0;
+}
+
/*
* Currently, raw pattern match is very limited. It is intended for matching
* UDP tunnel header (e.g. vxlan or geneve).
--
2.26.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [dpdk-dev] [PATCH v2] net/enic: support GTP header flow matching
2021-10-26 1:16 [dpdk-dev] [PATCH] net/enic: support GTP header flow matching John Daley
@ 2021-10-28 6:36 ` John Daley
2021-10-28 20:04 ` [dpdk-dev] [PATCH v3] " John Daley
0 siblings, 1 reply; 4+ messages in thread
From: John Daley @ 2021-10-28 6:36 UTC (permalink / raw)
To: ferruh.yigit, arybchenko; +Cc: dev, John Daley, Hyong Youb Kim
The GTP, GTP-U, GTP-C header fields can be matched, however NIC does not
support GTP tunneling so no items after the GTP header can be specified.
If a GTP-U or GTP-C item is specified without a preceding UDP item, the
UDP destination port is implicitly matched. For GTP, the destination UDP
port must be specified but its value is not enforced.
Signed-off-by: John Daley <johndale@cisco.com>
Reviewed-by: Hyong Youb Kim <hyonkim@cisco.com>
---
v2: Fixed specification of the max enic flowman item
doc/guides/nics/enic.rst | 2 +
doc/guides/nics/features/enic.ini | 3 +
doc/guides/rel_notes/release_21_11.rst | 4 +
drivers/net/enic/enic_fm_flow.c | 124 ++++++++++++++++++++++++-
4 files changed, 129 insertions(+), 4 deletions(-)
diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index f2ee49fe82..5e2054fc8a 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -473,6 +473,8 @@ RTE_MBUF_F_RX_VLAN_STRIPPED mbuf flags would not be set. This mode is enabled wi
packets and then receive them normally. These require 1400 series VIC adapters
and latest firmware.
- RAW items are limited to matching UDP tunnel headers like VXLAN.
+ - GTP, GTP-C and GTP-U header matching is enabled, however matching items within
+ the tunnel is not supported.
- For 1400 VICs, all flows using the RSS action on a port use same hash
configuration. The RETA is ignored. The queues used in the RSS group must be
sequential. There is a performance hit if the number of queues is not a power of 2.
diff --git a/doc/guides/nics/features/enic.ini b/doc/guides/nics/features/enic.ini
index 3064336162..1177752c15 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -40,6 +40,9 @@ Usage doc = Y
[rte_flow items]
eth = Y
+gtp = Y
+gtpc = Y
+gtpu = Y
ipv4 = Y
ipv6 = Y
raw = Y
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 1ccac87b73..2cee5347f3 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -154,6 +154,10 @@ New Features
* Implement support for tunnel offload.
* Updated HWRM API to version 1.10.2.44
+* **Updated Cisco enic driver.**
+
+ * Added rte_flow support for matching GTP, GTP-C and GTP-U headers.
+
* **Updated Intel e1000 emulated driver.**
* Added Intel e1000 support on Windows.
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 2c60bb864e..48ea1d0ff9 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -22,9 +22,6 @@
#define IP_DEFTTL 64 /* from RFC 1340. */
#define IP6_VTC_FLOW 0x60000000
-/* Highest Item type supported by Flowman */
-#define FM_MAX_ITEM_TYPE RTE_FLOW_ITEM_TYPE_VXLAN
-
/* Up to 1024 TCAM entries */
#define FM_MAX_TCAM_TABLE_SIZE 1024
@@ -235,6 +232,7 @@ static enic_copy_item_fn enic_fm_copy_item_tcp;
static enic_copy_item_fn enic_fm_copy_item_udp;
static enic_copy_item_fn enic_fm_copy_item_vlan;
static enic_copy_item_fn enic_fm_copy_item_vxlan;
+static enic_copy_item_fn enic_fm_copy_item_gtp;
/* Ingress actions */
static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -346,6 +344,30 @@ static const struct enic_fm_items enic_fm_items[] = {
RTE_FLOW_ITEM_TYPE_END,
},
},
+ [RTE_FLOW_ITEM_TYPE_GTP] = {
+ .copy_item = enic_fm_copy_item_gtp,
+ .valid_start_item = 0,
+ .prev_items = (const enum rte_flow_item_type[]) {
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_END,
+ },
+ },
+ [RTE_FLOW_ITEM_TYPE_GTPC] = {
+ .copy_item = enic_fm_copy_item_gtp,
+ .valid_start_item = 1,
+ .prev_items = (const enum rte_flow_item_type[]) {
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_END,
+ },
+ },
+ [RTE_FLOW_ITEM_TYPE_GTPU] = {
+ .copy_item = enic_fm_copy_item_gtp,
+ .valid_start_item = 1,
+ .prev_items = (const enum rte_flow_item_type[]) {
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_END,
+ },
+ },
};
static int
@@ -629,6 +651,100 @@ enic_fm_copy_item_vxlan(struct copy_item_args *arg)
return 0;
}
+static int
+enic_fm_copy_item_gtp(struct copy_item_args *arg)
+{
+ const struct rte_flow_item *item = arg->item;
+ const struct rte_flow_item_gtp *spec = item->spec;
+ const struct rte_flow_item_gtp *mask = item->mask;
+ struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+ struct fm_header_set *fm_data, *fm_mask;
+ int off;
+ uint16_t udp_gtp_uc_port = 0;
+
+ ENICPMD_FUNC_TRACE();
+ /* Only 2 header levels (outer and inner) allowed */
+ if (arg->header_level > 0)
+ return -EINVAL;
+
+ fm_data = &entry->ftm_data.fk_hdrset[0];
+ fm_mask = &entry->ftm_mask.fk_hdrset[0];
+
+ switch (item->type) {
+ case RTE_FLOW_ITEM_TYPE_GTP:
+ {
+ /* For vanilla GTP, the UDP destination port must be specified
+ * but value of the port is not enforced here.
+ */
+ if (!(fm_data->fk_metadata & FKM_UDP) ||
+ !(fm_data->fk_header_select & FKH_UDP) ||
+ fm_data->l4.udp.fk_dest == 0)
+ return -EINVAL;
+ if (!(fm_mask->fk_metadata & FKM_UDP) ||
+ !(fm_mask->fk_header_select & FKH_UDP) ||
+ fm_mask->l4.udp.fk_dest != 0xFFFF)
+ return -EINVAL;
+ break;
+ }
+ case RTE_FLOW_ITEM_TYPE_GTPC:
+ {
+ udp_gtp_uc_port = RTE_GTPC_UDP_PORT;
+ break;
+ }
+ case RTE_FLOW_ITEM_TYPE_GTPU:
+ {
+ udp_gtp_uc_port = RTE_GTPU_UDP_PORT;
+ break;
+ }
+ default:
+ RTE_ASSERT(0);
+ }
+
+ /* The GTP-C or GTP-U UDP destination port must be matched. */
+ if (udp_gtp_uc_port) {
+ if (fm_data->fk_metadata & FKM_UDP &&
+ fm_data->fk_header_select & FKH_UDP &&
+ rte_be_to_cpu_16(fm_data->l4.udp.fk_dest) !=
+ udp_gtp_uc_port)
+ return -EINVAL;
+ if (fm_mask->fk_metadata & FKM_UDP &&
+ fm_mask->fk_header_select & FKH_UDP &&
+ fm_mask->l4.udp.fk_dest != 0xFFFF)
+ return -EINVAL;
+
+ /* In any case, add match for GTP-C GTP-U UDP dst port */
+ fm_data->fk_metadata |= FKM_UDP;
+ fm_data->fk_header_select |= FKH_UDP;
+ fm_data->l4.udp.fk_dest = udp_gtp_uc_port;
+ fm_mask->fk_metadata |= FKM_UDP;
+ fm_mask->fk_header_select |= FKH_UDP;
+ fm_mask->l4.udp.fk_dest = 0xFFFF;
+ }
+
+ /* NIC does not support GTP tunnels. No Items are allowed after this.
+ * This prevents the specificaiton of further items.
+ */
+ arg->header_level = 0;
+
+ /* Match all if no spec */
+ if (!spec)
+ return 0;
+ if (!mask)
+ mask = &rte_flow_item_gtp_mask;
+
+ /*
+ * Use the raw L4 buffer to match GTP as fm_header_set does not have
+ * GTP header. UDP dst port must be specifiec. Using the raw buffer
+ * does not affect such UDP item, since we skip UDP in the raw buffer.
+ */
+ fm_data->fk_header_select |= FKH_L4RAW;
+ fm_mask->fk_header_select |= FKH_L4RAW;
+ off = sizeof(fm_data->l4.udp);
+ memcpy(&fm_data->l4.rawdata[off], spec, sizeof(*spec));
+ memcpy(&fm_mask->l4.rawdata[off], mask, sizeof(*mask));
+ return 0;
+}
+
/*
* Currently, raw pattern match is very limited. It is intended for matching
* UDP tunnel header (e.g. vxlan or geneve).
@@ -863,7 +979,7 @@ enic_fm_copy_entry(struct enic_flowman *fm,
item_info = &enic_fm_items[item->type];
- if (item->type > FM_MAX_ITEM_TYPE ||
+ if (item->type >= RTE_DIM(enic_fm_items) ||
item_info->copy_item == NULL) {
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ITEM,
--
2.26.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [dpdk-dev] [PATCH v3] net/enic: support GTP header flow matching
2021-10-28 6:36 ` [dpdk-dev] [PATCH v2] " John Daley
@ 2021-10-28 20:04 ` John Daley
2021-11-04 11:36 ` Ferruh Yigit
0 siblings, 1 reply; 4+ messages in thread
From: John Daley @ 2021-10-28 20:04 UTC (permalink / raw)
To: ferruh.yigit, arybchenko; +Cc: dev, John Daley, Hyong Youb Kim
The GTP, GTP-U, GTP-C header fields can be matched, however NIC does not
support GTP tunneling so no items after the GTP header can be specified.
If a GTP-U or GTP-C item is specified without a preceding UDP item, the
UDP destination port is implicitly matched. For GTP, the destination UDP
port must be specified but its value is not enforced.
Signed-off-by: John Daley <johndale@cisco.com>
Reviewed-by: Hyong Youb Kim <hyonkim@cisco.com>
---
v2: Fixed specification of the max enic flowman item
v3: Fixed endianness of UDP dst port
doc/guides/nics/enic.rst | 2 +
doc/guides/nics/features/enic.ini | 3 +
doc/guides/rel_notes/release_21_11.rst | 4 +
drivers/net/enic/enic_fm_flow.c | 123 ++++++++++++++++++++++++-
4 files changed, 128 insertions(+), 4 deletions(-)
diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index f2ee49fe82..5e2054fc8a 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -473,6 +473,8 @@ RTE_MBUF_F_RX_VLAN_STRIPPED mbuf flags would not be set. This mode is enabled wi
packets and then receive them normally. These require 1400 series VIC adapters
and latest firmware.
- RAW items are limited to matching UDP tunnel headers like VXLAN.
+ - GTP, GTP-C and GTP-U header matching is enabled, however matching items within
+ the tunnel is not supported.
- For 1400 VICs, all flows using the RSS action on a port use same hash
configuration. The RETA is ignored. The queues used in the RSS group must be
sequential. There is a performance hit if the number of queues is not a power of 2.
diff --git a/doc/guides/nics/features/enic.ini b/doc/guides/nics/features/enic.ini
index 3064336162..1177752c15 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -40,6 +40,9 @@ Usage doc = Y
[rte_flow items]
eth = Y
+gtp = Y
+gtpc = Y
+gtpu = Y
ipv4 = Y
ipv6 = Y
raw = Y
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 1ccac87b73..2cee5347f3 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -154,6 +154,10 @@ New Features
* Implement support for tunnel offload.
* Updated HWRM API to version 1.10.2.44
+* **Updated Cisco enic driver.**
+
+ * Added rte_flow support for matching GTP, GTP-C and GTP-U headers.
+
* **Updated Intel e1000 emulated driver.**
* Added Intel e1000 support on Windows.
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 2c60bb864e..ae43f36bc0 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -22,9 +22,6 @@
#define IP_DEFTTL 64 /* from RFC 1340. */
#define IP6_VTC_FLOW 0x60000000
-/* Highest Item type supported by Flowman */
-#define FM_MAX_ITEM_TYPE RTE_FLOW_ITEM_TYPE_VXLAN
-
/* Up to 1024 TCAM entries */
#define FM_MAX_TCAM_TABLE_SIZE 1024
@@ -235,6 +232,7 @@ static enic_copy_item_fn enic_fm_copy_item_tcp;
static enic_copy_item_fn enic_fm_copy_item_udp;
static enic_copy_item_fn enic_fm_copy_item_vlan;
static enic_copy_item_fn enic_fm_copy_item_vxlan;
+static enic_copy_item_fn enic_fm_copy_item_gtp;
/* Ingress actions */
static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -346,6 +344,30 @@ static const struct enic_fm_items enic_fm_items[] = {
RTE_FLOW_ITEM_TYPE_END,
},
},
+ [RTE_FLOW_ITEM_TYPE_GTP] = {
+ .copy_item = enic_fm_copy_item_gtp,
+ .valid_start_item = 0,
+ .prev_items = (const enum rte_flow_item_type[]) {
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_END,
+ },
+ },
+ [RTE_FLOW_ITEM_TYPE_GTPC] = {
+ .copy_item = enic_fm_copy_item_gtp,
+ .valid_start_item = 1,
+ .prev_items = (const enum rte_flow_item_type[]) {
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_END,
+ },
+ },
+ [RTE_FLOW_ITEM_TYPE_GTPU] = {
+ .copy_item = enic_fm_copy_item_gtp,
+ .valid_start_item = 1,
+ .prev_items = (const enum rte_flow_item_type[]) {
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_END,
+ },
+ },
};
static int
@@ -629,6 +651,99 @@ enic_fm_copy_item_vxlan(struct copy_item_args *arg)
return 0;
}
+static int
+enic_fm_copy_item_gtp(struct copy_item_args *arg)
+{
+ const struct rte_flow_item *item = arg->item;
+ const struct rte_flow_item_gtp *spec = item->spec;
+ const struct rte_flow_item_gtp *mask = item->mask;
+ struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+ struct fm_header_set *fm_data, *fm_mask;
+ int off;
+ uint16_t udp_gtp_uc_port_be = 0;
+
+ ENICPMD_FUNC_TRACE();
+ /* Only 2 header levels (outer and inner) allowed */
+ if (arg->header_level > 0)
+ return -EINVAL;
+
+ fm_data = &entry->ftm_data.fk_hdrset[0];
+ fm_mask = &entry->ftm_mask.fk_hdrset[0];
+
+ switch (item->type) {
+ case RTE_FLOW_ITEM_TYPE_GTP:
+ {
+ /* For vanilla GTP, the UDP destination port must be specified
+ * but value of the port is not enforced here.
+ */
+ if (!(fm_data->fk_metadata & FKM_UDP) ||
+ !(fm_data->fk_header_select & FKH_UDP) ||
+ fm_data->l4.udp.fk_dest == 0)
+ return -EINVAL;
+ if (!(fm_mask->fk_metadata & FKM_UDP) ||
+ !(fm_mask->fk_header_select & FKH_UDP) ||
+ fm_mask->l4.udp.fk_dest != 0xFFFF)
+ return -EINVAL;
+ break;
+ }
+ case RTE_FLOW_ITEM_TYPE_GTPC:
+ {
+ udp_gtp_uc_port_be = rte_cpu_to_be_16(RTE_GTPC_UDP_PORT);
+ break;
+ }
+ case RTE_FLOW_ITEM_TYPE_GTPU:
+ {
+ udp_gtp_uc_port_be = rte_cpu_to_be_16(RTE_GTPU_UDP_PORT);
+ break;
+ }
+ default:
+ RTE_ASSERT(0);
+ }
+
+ /* The GTP-C or GTP-U UDP destination port must be matched. */
+ if (udp_gtp_uc_port_be) {
+ if (fm_data->fk_metadata & FKM_UDP &&
+ fm_data->fk_header_select & FKH_UDP &&
+ fm_data->l4.udp.fk_dest != udp_gtp_uc_port_be)
+ return -EINVAL;
+ if (fm_mask->fk_metadata & FKM_UDP &&
+ fm_mask->fk_header_select & FKH_UDP &&
+ fm_mask->l4.udp.fk_dest != 0xFFFF)
+ return -EINVAL;
+
+ /* In any case, add match for GTP-C GTP-U UDP dst port */
+ fm_data->fk_metadata |= FKM_UDP;
+ fm_data->fk_header_select |= FKH_UDP;
+ fm_data->l4.udp.fk_dest = udp_gtp_uc_port_be;
+ fm_mask->fk_metadata |= FKM_UDP;
+ fm_mask->fk_header_select |= FKH_UDP;
+ fm_mask->l4.udp.fk_dest = 0xFFFF;
+ }
+
+ /* NIC does not support GTP tunnels. No Items are allowed after this.
+ * This prevents the specificaiton of further items.
+ */
+ arg->header_level = 0;
+
+ /* Match all if no spec */
+ if (!spec)
+ return 0;
+ if (!mask)
+ mask = &rte_flow_item_gtp_mask;
+
+ /*
+ * Use the raw L4 buffer to match GTP as fm_header_set does not have
+ * GTP header. UDP dst port must be specifiec. Using the raw buffer
+ * does not affect such UDP item, since we skip UDP in the raw buffer.
+ */
+ fm_data->fk_header_select |= FKH_L4RAW;
+ fm_mask->fk_header_select |= FKH_L4RAW;
+ off = sizeof(fm_data->l4.udp);
+ memcpy(&fm_data->l4.rawdata[off], spec, sizeof(*spec));
+ memcpy(&fm_mask->l4.rawdata[off], mask, sizeof(*mask));
+ return 0;
+}
+
/*
* Currently, raw pattern match is very limited. It is intended for matching
* UDP tunnel header (e.g. vxlan or geneve).
@@ -863,7 +978,7 @@ enic_fm_copy_entry(struct enic_flowman *fm,
item_info = &enic_fm_items[item->type];
- if (item->type > FM_MAX_ITEM_TYPE ||
+ if (item->type >= RTE_DIM(enic_fm_items) ||
item_info->copy_item == NULL) {
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ITEM,
--
2.26.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [dpdk-dev] [PATCH v3] net/enic: support GTP header flow matching
2021-10-28 20:04 ` [dpdk-dev] [PATCH v3] " John Daley
@ 2021-11-04 11:36 ` Ferruh Yigit
0 siblings, 0 replies; 4+ messages in thread
From: Ferruh Yigit @ 2021-11-04 11:36 UTC (permalink / raw)
To: John Daley, arybchenko; +Cc: dev, Hyong Youb Kim
On 10/28/2021 9:04 PM, John Daley wrote:
> The GTP, GTP-U, GTP-C header fields can be matched, however NIC does not
> support GTP tunneling so no items after the GTP header can be specified.
> If a GTP-U or GTP-C item is specified without a preceding UDP item, the
> UDP destination port is implicitly matched. For GTP, the destination UDP
> port must be specified but its value is not enforced.
>
> Signed-off-by: John Daley <johndale@cisco.com>
> Reviewed-by: Hyong Youb Kim <hyonkim@cisco.com>
Applied to dpdk-next-net/main, thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-11-04 11:36 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-26 1:16 [dpdk-dev] [PATCH] net/enic: support GTP header flow matching John Daley
2021-10-28 6:36 ` [dpdk-dev] [PATCH v2] " John Daley
2021-10-28 20:04 ` [dpdk-dev] [PATCH v3] " John Daley
2021-11-04 11:36 ` Ferruh Yigit
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).