diff options
author | Xinyao Cai <xinyao.cai@intel.com> | 2023-02-28 14:44:58 +0800 |
---|---|---|
committer | Damjan Marion <dmarion@0xa5.net> | 2023-03-06 16:46:17 +0000 |
commit | 99d3a405431dadca2cb5138183603946b6d64408 (patch) | |
tree | e1894cae223d9f5c63953cf1a54d2293da04e9b6 /src/vnet/flow | |
parent | a20afdc845f4e901f7d3e6974e59a0dc2e8bf427 (diff) |
flow dpdk: introduce IP in IP support for flow
This patch introduces IP in IP packet support for flow cli and dpdk plugin.
Specifically, the following IP in IP packet types are supported:
MAC-IPv4-IPv4-TCP/UDP/None,
MAC-IPv4-IPv6-TCP/UDP/None,
MAC-IPv6-IPv4-TCP/UDP/None,
MAC-IPv6-IPv6-TCP/UDP/None,
IP in IP flow rules can be created by using the following new keywords in vppctl:
in-src-ip, in-dst-ip : to provide information for inner IPv4 header
in-ip6-src-ip, in-ip6-dst-ip: to provide information for inner IPv6 header
in-proto : to specify inner transport layer protocol type (TCP or UDP)
in-src-port, in-dst-port : to provide information for inner TCP/UDP header
An example to create flow rule for MAC-IPv6-IPv6-TCP:
test flow add index 0 ip6-src-ip any ip6-dst-ip any in-ip6-src-ip any in-ip6-dst-ip any in-proto tcp in-src-port 1234 in-dst-port any rss function default
Another example to create flow rule for MAC-IPv6-IPv6:
test flow add index 0 ip6-src-ip any in-ip6-src-ip any rss function default
Type: feature
Signed-off-by: Xinyao Cai <xinyao.cai@intel.com>
Change-Id: I6a1ca36d47eb65b9cb5a4b8d874b2a7f017c35cd
Diffstat (limited to 'src/vnet/flow')
-rw-r--r-- | src/vnet/flow/flow.h | 47 | ||||
-rw-r--r-- | src/vnet/flow/flow_cli.c | 118 |
2 files changed, 156 insertions, 9 deletions
diff --git a/src/vnet/flow/flow.h b/src/vnet/flow/flow.h index 194579b88d8..9069bd1cea5 100644 --- a/src/vnet/flow/flow.h +++ b/src/vnet/flow/flow.h @@ -45,7 +45,16 @@ _ (IP4_GTPC, ip4_gtpc, "ipv4-gtpc") \ _ (IP4_GTPU, ip4_gtpu, "ipv4-gtpu") \ /* generic flow */ \ - _ (GENERIC, generic, "generic") + _ (GENERIC, generic, "generic") \ + /* IP in IP */ \ + _ (IP6_IP6, ip6_ip6, "ipv6-ipv6") \ + _ (IP6_IP4, ip6_ip4, "ipv6-ipv4") \ + _ (IP4_IP6, ip4_ip6, "ipv4-ipv6") \ + _ (IP4_IP4, ip4_ip4, "ipv4-ipv4") \ + _ (IP6_IP6_N_TUPLE, ip6_ip6_n_tuple, "ipv6-ipv6-n-tuple") \ + _ (IP6_IP4_N_TUPLE, ip6_ip4_n_tuple, "ipv6-ipv4-n-tuple") \ + _ (IP4_IP6_N_TUPLE, ip4_ip6_n_tuple, "ipv4-ipv6-n-tuple") \ + _ (IP4_IP4_N_TUPLE, ip4_ip4_n_tuple, "ipv4-ipv4-n-tuple") #define foreach_flow_entry_ethernet \ _fe(ethernet_header_t, eth_hdr) @@ -106,6 +115,42 @@ foreach_flow_entry_ip4_n_tuple \ _fe(u32, teid) +#define foreach_flow_entry_ip6_ip6 \ + foreach_flow_entry_ip6 _fe (ip6_address_and_mask_t, in_src_addr) \ + _fe (ip6_address_and_mask_t, in_dst_addr) \ + _fe (ip_prot_and_mask_t, in_protocol) + +#define foreach_flow_entry_ip6_ip6_n_tuple \ + foreach_flow_entry_ip6_ip6 _fe (ip_port_and_mask_t, in_src_port) \ + _fe (ip_port_and_mask_t, in_dst_port) + +#define foreach_flow_entry_ip6_ip4 \ + foreach_flow_entry_ip6 _fe (ip4_address_and_mask_t, in_src_addr) \ + _fe (ip4_address_and_mask_t, in_dst_addr) \ + _fe (ip_prot_and_mask_t, in_protocol) + +#define foreach_flow_entry_ip6_ip4_n_tuple \ + foreach_flow_entry_ip6_ip4 _fe (ip_port_and_mask_t, in_src_port) \ + _fe (ip_port_and_mask_t, in_dst_port) + +#define foreach_flow_entry_ip4_ip6 \ + foreach_flow_entry_ip4 _fe (ip6_address_and_mask_t, in_src_addr) \ + _fe (ip6_address_and_mask_t, in_dst_addr) \ + _fe (ip_prot_and_mask_t, in_protocol) + +#define foreach_flow_entry_ip4_ip6_n_tuple \ + foreach_flow_entry_ip4_ip6 _fe (ip_port_and_mask_t, in_src_port) \ + _fe (ip_port_and_mask_t, in_dst_port) + +#define foreach_flow_entry_ip4_ip4 \ + foreach_flow_entry_ip4 _fe (ip4_address_and_mask_t, in_src_addr) \ + _fe (ip4_address_and_mask_t, in_dst_addr) \ + _fe (ip_prot_and_mask_t, in_protocol) + +#define foreach_flow_entry_ip4_ip4_n_tuple \ + foreach_flow_entry_ip4_ip4 _fe (ip_port_and_mask_t, in_src_port) \ + _fe (ip_port_and_mask_t, in_dst_port) + #define foreach_flow_entry_generic _fe (generic_pattern_t, pattern) #define foreach_flow_action \ diff --git a/src/vnet/flow/flow_cli.c b/src/vnet/flow/flow_cli.c index 5f44a099f57..bf343b0d550 100644 --- a/src/vnet/flow/flow_cli.c +++ b/src/vnet/flow/flow_cli.c @@ -366,15 +366,16 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, u32 vni = 0; u32 queue_start = 0, queue_end = 0; vnet_flow_type_t type = VNET_FLOW_TYPE_UNKNOWN; - ip4_address_and_mask_t ip4s = { }; - ip4_address_and_mask_t ip4d = { }; - ip6_address_and_mask_t ip6s = { }; - ip6_address_and_mask_t ip6d = { }; - ip_port_and_mask_t sport = { }; - ip_port_and_mask_t dport = { }; - ip_prot_and_mask_t protocol = { }; + ip4_address_and_mask_t ip4s = {}, in_ip4s = {}; + ip4_address_and_mask_t ip4d = {}, in_ip4d = {}; + ip6_address_and_mask_t ip6s = {}, in_ip6s = {}; + ip6_address_and_mask_t ip6d = {}, in_ip6d = {}; + ip_port_and_mask_t sport = {}, in_sport = {}; + ip_port_and_mask_t dport = {}, in_dport = {}; + ip_prot_and_mask_t protocol = {}, in_proto = {}; u16 eth_type; - bool tcp_udp_port_set = false; + bool inner_ip4_set = false, inner_ip6_set = false; + bool tcp_udp_port_set = false, inner_port_set = false; bool gtpc_set = false; bool gtpu_set = false; bool vni_set = false; @@ -415,12 +416,24 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, else if (unformat (line_input, "dst-ip %U", unformat_ip4_address_and_mask, &ip4d)) flow_class = FLOW_IPV4_CLASS; + else if (unformat (line_input, "in-src-ip %U", + unformat_ip4_address_and_mask, &in_ip4s)) + inner_ip4_set = true; + else if (unformat (line_input, "in-dst-ip %U", + unformat_ip4_address_and_mask, &in_ip4d)) + inner_ip4_set = true; else if (unformat (line_input, "ip6-src-ip %U", unformat_ip6_address_and_mask, &ip6s)) flow_class = FLOW_IPV6_CLASS; else if (unformat (line_input, "ip6-dst-ip %U", unformat_ip6_address_and_mask, &ip6d)) flow_class = FLOW_IPV6_CLASS; + else if (unformat (line_input, "in-ip6-src-ip %U", + unformat_ip6_address_and_mask, &in_ip6s)) + inner_ip6_set = true; + else if (unformat (line_input, "in-ip6-dst-ip %U", + unformat_ip6_address_and_mask, &in_ip6d)) + inner_ip6_set = true; else if (unformat (line_input, "src-port %U", unformat_ip_port_and_mask, &sport)) tcp_udp_port_set = true; @@ -432,6 +445,15 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, (line_input, "proto %U", unformat_ip_protocol_and_mask, &protocol)) ; + else if (unformat (line_input, "in-src-port %U", + unformat_ip_port_and_mask, &in_sport)) + inner_port_set = true; + else if (unformat (line_input, "in-dst-port %U", + unformat_ip_port_and_mask, &in_dport)) + inner_port_set = true; + else if (unformat (line_input, "in-proto %U", + unformat_ip_protocol_and_mask, &in_proto)) + ; else if (unformat (line_input, "gtpc teid %u", &teid)) gtpc_set = true; else if (unformat (line_input, "gtpu teid %u", &teid)) @@ -592,6 +614,22 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, type = VNET_FLOW_TYPE_IP4_IPSEC_AH; else if (tcp_udp_port_set) type = VNET_FLOW_TYPE_IP4_N_TUPLE; + else if (inner_ip4_set) + { + if (inner_port_set) + type = VNET_FLOW_TYPE_IP4_IP4_N_TUPLE; + else + type = VNET_FLOW_TYPE_IP4_IP4; + protocol.prot = IP_PROTOCOL_IP_IN_IP; + } + else if (inner_ip6_set) + { + if (inner_port_set) + type = VNET_FLOW_TYPE_IP4_IP6_N_TUPLE; + else + type = VNET_FLOW_TYPE_IP4_IP6; + protocol.prot = IP_PROTOCOL_IPV6; + } else type = VNET_FLOW_TYPE_IP4; break; @@ -600,6 +638,22 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, type = VNET_FLOW_TYPE_IP6_N_TUPLE; else if (vni_set) type = VNET_FLOW_TYPE_IP6_VXLAN; + else if (inner_ip4_set) + { + if (inner_port_set) + type = VNET_FLOW_TYPE_IP6_IP4_N_TUPLE; + else + type = VNET_FLOW_TYPE_IP6_IP4; + protocol.prot = IP_PROTOCOL_IP_IN_IP; + } + else if (inner_ip6_set) + { + if (inner_port_set) + type = VNET_FLOW_TYPE_IP6_IP6_N_TUPLE; + else + type = VNET_FLOW_TYPE_IP6_IP6; + protocol.prot = IP_PROTOCOL_IPV6; + } else type = VNET_FLOW_TYPE_IP6; break; @@ -660,6 +714,30 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, case IP_PROTOCOL_IPSEC_AH: flow.ip4_ipsec_esp.spi = spi; break; + case IP_PROTOCOL_IP_IN_IP: + clib_memcpy (&flow.ip4_ip4.in_src_addr, &in_ip4s, + sizeof (ip4_address_and_mask_t)); + clib_memcpy (&flow.ip4_ip4.in_dst_addr, &in_ip4d, + sizeof (ip4_address_and_mask_t)); + if (type == VNET_FLOW_TYPE_IP4_IP4_N_TUPLE) + { + flow.ip4_ip4.in_protocol.prot = in_proto.prot; + flow.ip4_ip4_n_tuple.in_src_port = in_sport; + flow.ip4_ip4_n_tuple.in_dst_port = in_dport; + } + break; + case IP_PROTOCOL_IPV6: + clib_memcpy (&flow.ip4_ip6.in_src_addr, &in_ip6s, + sizeof (ip6_address_and_mask_t)); + clib_memcpy (&flow.ip4_ip6.in_dst_addr, &in_ip6d, + sizeof (ip6_address_and_mask_t)); + if (type == VNET_FLOW_TYPE_IP4_IP6_N_TUPLE) + { + flow.ip4_ip6.in_protocol.prot = in_proto.prot; + flow.ip4_ip6_n_tuple.in_src_port = in_sport; + flow.ip4_ip6_n_tuple.in_dst_port = in_dport; + } + break; default: break; } @@ -693,6 +771,30 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, if (type == VNET_FLOW_TYPE_IP6_VXLAN) flow.ip6_vxlan.vni = vni; break; + case IP_PROTOCOL_IP_IN_IP: + clib_memcpy (&flow.ip6_ip4.in_src_addr, &in_ip4s, + sizeof (ip4_address_and_mask_t)); + clib_memcpy (&flow.ip6_ip4.in_dst_addr, &in_ip4d, + sizeof (ip4_address_and_mask_t)); + if (type == VNET_FLOW_TYPE_IP6_IP4_N_TUPLE) + { + flow.ip6_ip4.in_protocol.prot = in_proto.prot; + flow.ip6_ip4_n_tuple.in_src_port = in_sport; + flow.ip6_ip4_n_tuple.in_dst_port = in_dport; + } + break; + case IP_PROTOCOL_IPV6: + clib_memcpy (&flow.ip6_ip6.in_src_addr, &in_ip6s, + sizeof (ip6_address_and_mask_t)); + clib_memcpy (&flow.ip6_ip6.in_dst_addr, &in_ip6d, + sizeof (ip6_address_and_mask_t)); + if (type == VNET_FLOW_TYPE_IP6_IP6_N_TUPLE) + { + flow.ip6_ip6.in_protocol.prot = in_proto.prot; + flow.ip6_ip6_n_tuple.in_src_port = in_sport; + flow.ip6_ip6_n_tuple.in_dst_port = in_dport; + } + break; default: break; } |