diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/dpdk/device/flow.c | 16 | ||||
-rw-r--r-- | src/vnet/flow/flow.h | 50 | ||||
-rw-r--r-- | src/vnet/flow/flow_cli.c | 53 |
3 files changed, 87 insertions, 32 deletions
diff --git a/src/plugins/dpdk/device/flow.c b/src/plugins/dpdk/device/flow.c index 19d504e5514..91541f40163 100644 --- a/src/plugins/dpdk/device/flow.c +++ b/src/plugins/dpdk/device/flow.c @@ -142,6 +142,7 @@ dpdk_flow_add (dpdk_device_t * xd, vnet_flow_t * f, dpdk_flow_entry_t * fe) struct rte_flow_item_l2tpv3oip l2tp[2] = { }; struct rte_flow_item_esp esp[2] = { }; struct rte_flow_item_ah ah[2] = { }; + struct rte_flow_item_raw generic[2] = {}; struct rte_flow_action_mark mark = { 0 }; struct rte_flow_action_queue queue = { 0 }; struct rte_flow_action_rss rss = { 0 }; @@ -165,6 +166,20 @@ dpdk_flow_add (dpdk_device_t * xd, vnet_flow_t * f, dpdk_flow_entry_t * fe) u8 protocol = IP_PROTOCOL_RESERVED; int rv = 0; + /* Handle generic flow first */ + if (f->type == VNET_FLOW_TYPE_GENERIC) + { + generic[0].pattern = f->generic.pattern.spec; + generic[1].pattern = f->generic.pattern.mask; + + vec_add2 (items, item, 1); + item->type = RTE_FLOW_ITEM_TYPE_RAW; + item->spec = generic; + item->mask = generic + 1; + + goto pattern_end; + } + enum { FLOW_UNKNOWN_CLASS, @@ -653,6 +668,7 @@ dpdk_flow_ops_fn (vnet_main_t * vnm, vnet_flow_dev_op_t op, u32 dev_instance, case VNET_FLOW_TYPE_IP4_L2TPV3OIP: case VNET_FLOW_TYPE_IP4_IPSEC_ESP: case VNET_FLOW_TYPE_IP4_IPSEC_AH: + case VNET_FLOW_TYPE_GENERIC: if ((rv = dpdk_flow_add (xd, flow, fe))) goto done; break; diff --git a/src/vnet/flow/flow.h b/src/vnet/flow/flow.h index 4945f4367c7..313e85c45f9 100644 --- a/src/vnet/flow/flow.h +++ b/src/vnet/flow/flow.h @@ -24,26 +24,28 @@ #include <vnet/ip/ip6_packet.h> #include <vnet/ethernet/packet.h> -#define foreach_flow_type \ - /* l2 flow*/ \ - _(ETHERNET, ethernet, "ethernet") \ - /* l3 IP flow */ \ - _(IP4, ip4, "ipv4") \ - _(IP6, ip6, "ipv6") \ - /* IP tunnel flow */ \ - _(IP4_L2TPV3OIP, ip4_l2tpv3oip, "ipv4-l2tpv3oip") \ - _(IP4_IPSEC_ESP, ip4_ipsec_esp, "ipv4-ipsec-esp") \ - _(IP4_IPSEC_AH, ip4_ipsec_ah, "ipv4-ipsec-ah") \ - /* l4 flow*/ \ - _(IP4_N_TUPLE, ip4_n_tuple, "ipv4-n-tuple") \ - _(IP6_N_TUPLE, ip6_n_tuple, "ipv6-n-tuple") \ - _(IP4_N_TUPLE_TAGGED, ip4_n_tuple_tagged, "ipv4-n-tuple-tagged") \ - _(IP6_N_TUPLE_TAGGED, ip6_n_tuple_tagged, "ipv6-n-tuple-tagged") \ - /* L4 tunnel flow*/ \ - _(IP4_VXLAN, ip4_vxlan, "ipv4-vxlan") \ - _(IP6_VXLAN, ip6_vxlan, "ipv6-vxlan") \ - _(IP4_GTPC, ip4_gtpc, "ipv4-gtpc") \ - _(IP4_GTPU, ip4_gtpu, "ipv4-gtpu") +#define foreach_flow_type \ + /* l2 flow*/ \ + _ (ETHERNET, ethernet, "ethernet") \ + /* l3 IP flow */ \ + _ (IP4, ip4, "ipv4") \ + _ (IP6, ip6, "ipv6") \ + /* IP tunnel flow */ \ + _ (IP4_L2TPV3OIP, ip4_l2tpv3oip, "ipv4-l2tpv3oip") \ + _ (IP4_IPSEC_ESP, ip4_ipsec_esp, "ipv4-ipsec-esp") \ + _ (IP4_IPSEC_AH, ip4_ipsec_ah, "ipv4-ipsec-ah") \ + /* l4 flow*/ \ + _ (IP4_N_TUPLE, ip4_n_tuple, "ipv4-n-tuple") \ + _ (IP6_N_TUPLE, ip6_n_tuple, "ipv6-n-tuple") \ + _ (IP4_N_TUPLE_TAGGED, ip4_n_tuple_tagged, "ipv4-n-tuple-tagged") \ + _ (IP6_N_TUPLE_TAGGED, ip6_n_tuple_tagged, "ipv6-n-tuple-tagged") \ + /* L4 tunnel flow*/ \ + _ (IP4_VXLAN, ip4_vxlan, "ipv4-vxlan") \ + _ (IP6_VXLAN, ip6_vxlan, "ipv6-vxlan") \ + _ (IP4_GTPC, ip4_gtpc, "ipv4-gtpc") \ + _ (IP4_GTPU, ip4_gtpu, "ipv4-gtpu") \ + /* generic flow */ \ + _ (GENERIC, generic, "generic") #define foreach_flow_entry_ethernet \ _fe(ethernet_header_t, eth_hdr) @@ -104,6 +106,8 @@ foreach_flow_entry_ip4_n_tuple \ _fe(u32, teid) +#define foreach_flow_entry_generic _fe (generic_pattern_t, pattern) + #define foreach_flow_action \ _(0, COUNT, "count") \ _(1, MARK, "mark") \ @@ -190,6 +194,12 @@ typedef struct u8 mask; } ip_prot_and_mask_t; +typedef struct +{ + u8 spec[1024]; + u8 mask[1024]; +} generic_pattern_t; + typedef enum { VNET_FLOW_TYPE_UNKNOWN, diff --git a/src/vnet/flow/flow_cli.c b/src/vnet/flow/flow_cli.c index e2a3141c551..f3e6c3912bd 100644 --- a/src/vnet/flow/flow_cli.c +++ b/src/vnet/flow/flow_cli.c @@ -223,6 +223,11 @@ show_flow_entry (vlib_main_t * vm, unformat_input_t * input, vlib_cli_output (vm, "%-10s: %u", "index", f->index); vlib_cli_output (vm, "%-10s: %s", "type", flow_type_strings[f->type]); vlib_cli_output (vm, "%-10s: %U", "match", format_flow, f); + if (f->type == VNET_FLOW_TYPE_GENERIC) + { + vlib_cli_output (vm, "%s: %s", "spec", f->generic.pattern.spec); + vlib_cli_output (vm, "%s: %s", "mask", f->generic.pattern.mask); + } /* *INDENT-OFF* */ hash_foreach (hw_if_index, private_data, f->private_data, ({ @@ -243,6 +248,11 @@ no_args: pool_foreach (f, fm->global_flow_pool) { vlib_cli_output (vm, "%U\n", format_flow, f); + if (f->type == VNET_FLOW_TYPE_GENERIC) + { + vlib_cli_output (vm, "%s: %s", "spec", f->generic.pattern.spec); + vlib_cli_output (vm, "%s: %s", "mask", f->generic.pattern.mask); + } } /* *INDENT-ON* */ @@ -371,6 +381,8 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, bool ipsec_esp_set = false, ipsec_ah_set = false; u8 *rss_type[3] = { }; u8 *type_str = NULL; + u8 *spec = NULL; + u8 *mask = NULL; clib_memset (&flow, 0, sizeof (vnet_flow_t)); flow.index = ~0; @@ -389,6 +401,10 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, action = FLOW_ENABLE; else if (unformat (line_input, "disable")) action = FLOW_DISABLE; + else if (unformat (line_input, "spec %s", &spec)) + ; + else if (unformat (line_input, "mask %s", &mask)) + ; else if (unformat (line_input, "eth-type %U", unformat_ethernet_type_host_byte_order, ð_type)) flow_class = FLOW_ETHERNET_CLASS; @@ -573,6 +589,11 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, break; default: + if (spec && mask) + { + type = VNET_FLOW_TYPE_GENERIC; + break; + } return clib_error_return (0, "Please specify a supported flow type"); } @@ -660,6 +681,13 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, break; } } + if (type == VNET_FLOW_TYPE_GENERIC) + { + clib_memcpy (flow.generic.pattern.spec, spec, + sizeof (flow.generic.pattern.spec)); + clib_memcpy (flow.generic.pattern.mask, mask, + sizeof (flow.generic.pattern.mask)); + } flow.type = type; rv = vnet_flow_add (vnm, &flow, &flow_index); @@ -689,18 +717,19 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (test_flow_command, static) = { - .path = "test flow", - .short_help = "test flow [add|del|enable|disable] [index <id>] " - "[src-ip <ip-addr/mask>] [dst-ip <ip-addr/mask>] " - "[ip6-src-ip <ip-addr/mask>] [ip6-dst-ip <ip-addr/mask>] " - "[src-port <port/mask>] [dst-port <port/mask>] " - "[proto <ip-proto>] " - "[gtpc teid <teid>] [gtpu teid <teid>] [vxlan <vni>] " - "[session id <session>] [spi <spi>]" - "[next-node <node>] [mark <id>] [buffer-advance <len>] " - "[redirect-to-queue <queue>] [drop] " - "[rss function <name>] [rss types <flow type>]", - .function = test_flow, + .path = "test flow", + .short_help = "test flow [add|del|enable|disable] [index <id>] " + "[src-ip <ip-addr/mask>] [dst-ip <ip-addr/mask>] " + "[ip6-src-ip <ip-addr/mask>] [ip6-dst-ip <ip-addr/mask>] " + "[src-port <port/mask>] [dst-port <port/mask>] " + "[proto <ip-proto>] " + "[gtpc teid <teid>] [gtpu teid <teid>] [vxlan <vni>] " + "[session id <session>] [spi <spi>]" + "[spec <spec string>] [mask <mask string>]" + "[next-node <node>] [mark <id>] [buffer-advance <len>] " + "[redirect-to-queue <queue>] [drop] " + "[rss function <name>] [rss types <flow type>]", + .function = test_flow, }; /* *INDENT-ON* */ |