summaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/flow/flow.h122
-rw-r--r--src/vnet/flow/flow_api.c26
-rw-r--r--src/vnet/flow/flow_cli.c506
-rw-r--r--src/vnet/flow/flow_types.api80
-rw-r--r--src/vnet/vxlan/vxlan.c10
5 files changed, 389 insertions, 355 deletions
diff --git a/src/vnet/flow/flow.h b/src/vnet/flow/flow.h
index b5ec7ccd142..04305edf92a 100644
--- a/src/vnet/flow/flow.h
+++ b/src/vnet/flow/flow.h
@@ -26,86 +26,75 @@
#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") \
- /* 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 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") \
- _(IP4_GTPU_IP4, ip4_gtpu_ip4, "ipv4-gtpu-ipv4") \
- _(IP4_GTPU_IP6, ip4_gtpu_ip6, "ipv4-gtpu-ipv6") \
- _(IP6_GTPC, ip6_gtpc, "ipv6-gtpc") \
- _(IP6_GTPU, ip6_gtpu, "ipv6-gtpu") \
- _(IP6_GTPU_IP4, ip6_gtpu_ip4, "ipv6-gtpu-ipv4") \
- _(IP6_GTPU_IP6, ip6_gtpu_ip6, "ipv6-gtpu-ipv6")
+ _(IP4_GTPU, ip4_gtpu, "ipv4-gtpu")
#define foreach_flow_entry_ethernet \
_fe(ethernet_header_t, eth_hdr)
-#define foreach_flow_entry_ip4_n_tuple \
- _fe(ip4_address_and_mask_t, src_addr) \
- _fe(ip4_address_and_mask_t, dst_addr) \
- _fe(ip_port_and_mask_t, src_port) \
- _fe(ip_port_and_mask_t, dst_port) \
- _fe(ip_protocol_t, protocol)
-
-#define foreach_flow_entry_ip6_n_tuple \
- _fe(ip6_address_and_mask_t, src_addr) \
- _fe(ip6_address_and_mask_t, dst_addr) \
- _fe(ip_port_and_mask_t, src_port) \
- _fe(ip_port_and_mask_t, dst_port) \
- _fe(ip_protocol_t, protocol)
-
-#define foreach_flow_entry_ip4_n_tuple_tagged \
+#define foreach_flow_entry_ip4 \
_fe(ip4_address_and_mask_t, src_addr) \
_fe(ip4_address_and_mask_t, dst_addr) \
- _fe(ip_port_and_mask_t, src_port) \
- _fe(ip_port_and_mask_t, dst_port) \
- _fe(ip_protocol_t, protocol)
+ _fe(ip_prot_and_mask_t, protocol)
-#define foreach_flow_entry_ip6_n_tuple_tagged \
+#define foreach_flow_entry_ip6 \
_fe(ip6_address_and_mask_t, src_addr) \
_fe(ip6_address_and_mask_t, dst_addr) \
- _fe(ip_port_and_mask_t, src_port) \
- _fe(ip_port_and_mask_t, dst_port) \
- _fe(ip_protocol_t, protocol)
+ _fe(ip_prot_and_mask_t, protocol)
#define foreach_flow_entry_ip4_l2tpv3oip \
- _fe(ip4_address_and_mask_t, src_addr) \
- _fe(ip4_address_and_mask_t, dst_addr) \
- _fe(ip_protocol_t, protocol) \
+ foreach_flow_entry_ip4 \
_fe(u32, session_id)
#define foreach_flow_entry_ip4_ipsec_esp \
- _fe(ip4_address_and_mask_t, src_addr) \
- _fe(ip4_address_and_mask_t, dst_addr) \
- _fe(ip_protocol_t, protocol) \
+ foreach_flow_entry_ip4 \
_fe(u32, spi)
#define foreach_flow_entry_ip4_ipsec_ah \
- _fe(ip4_address_and_mask_t, src_addr) \
- _fe(ip4_address_and_mask_t, dst_addr) \
- _fe(ip_protocol_t, protocol) \
+ foreach_flow_entry_ip4 \
_fe(u32, spi)
+#define foreach_flow_entry_ip4_n_tuple \
+ foreach_flow_entry_ip4 \
+ _fe(ip_port_and_mask_t, src_port) \
+ _fe(ip_port_and_mask_t, dst_port)
+
+#define foreach_flow_entry_ip6_n_tuple \
+ foreach_flow_entry_ip6 \
+ _fe(ip_port_and_mask_t, src_port) \
+ _fe(ip_port_and_mask_t, dst_port)
+
+#define foreach_flow_entry_ip4_n_tuple_tagged \
+ foreach_flow_entry_ip4 \
+ _fe(ip_port_and_mask_t, src_port) \
+ _fe(ip_port_and_mask_t, dst_port)
+
+#define foreach_flow_entry_ip6_n_tuple_tagged \
+ foreach_flow_entry_ip6 \
+ _fe(ip_port_and_mask_t, src_port) \
+ _fe(ip_port_and_mask_t, dst_port)
+
#define foreach_flow_entry_ip4_vxlan \
- _fe(ip4_address_t, src_addr) \
- _fe(ip4_address_t, dst_addr) \
- _fe(u16, dst_port) \
+ foreach_flow_entry_ip4_n_tuple \
_fe(u16, vni)
#define foreach_flow_entry_ip6_vxlan \
- _fe(ip6_address_t, src_addr) \
- _fe(ip6_address_t, dst_addr) \
- _fe(u16, dst_port) \
+ foreach_flow_entry_ip6_n_tuple \
_fe(u16, vni)
#define foreach_flow_entry_ip4_gtpc \
@@ -116,34 +105,6 @@
foreach_flow_entry_ip4_n_tuple \
_fe(u32, teid)
-#define foreach_flow_entry_ip4_gtpu_ip4 \
- foreach_flow_entry_ip4_gtpu \
- _fe(ip4_address_and_mask_t, inner_src_addr) \
- _fe(ip4_address_and_mask_t, inner_dst_addr)
-
-#define foreach_flow_entry_ip4_gtpu_ip6 \
- foreach_flow_entry_ip4_gtpu \
- _fe(ip6_address_and_mask_t, inner_src_addr) \
- _fe(ip6_address_and_mask_t, inner_dst_addr)
-
-#define foreach_flow_entry_ip6_gtpc \
- foreach_flow_entry_ip6_n_tuple \
- _fe(u32, teid)
-
-#define foreach_flow_entry_ip6_gtpu \
- foreach_flow_entry_ip6_n_tuple \
- _fe(u32, teid)
-
-#define foreach_flow_entry_ip6_gtpu_ip4 \
- foreach_flow_entry_ip6_gtpu \
- _fe(ip4_address_and_mask_t, inner_src_addr) \
- _fe(ip4_address_and_mask_t, inner_dst_addr)
-
-#define foreach_flow_entry_ip6_gtpu_ip6 \
- foreach_flow_entry_ip6_gtpu \
- _fe(ip6_address_and_mask_t, inner_src_addr) \
- _fe(ip6_address_and_mask_t, inner_dst_addr)
-
#define foreach_flow_action \
_(0, COUNT, "count") \
_(1, MARK, "mark") \
@@ -160,7 +121,6 @@ typedef enum
#undef _
} vnet_flow_action_t;
-
#define foreach_flow_error \
_( -1, NOT_SUPPORTED, "not supported") \
_( -2, ALREADY_DONE, "already done") \
@@ -215,6 +175,14 @@ typedef struct
u16 port, mask;
} ip_port_and_mask_t;
+typedef struct
+{
+ ip_protocol_t prot;
+ /* ip protocol mask should be either 0 or 0xFF */
+ /* other values are meanless */
+ u8 mask;
+} ip_prot_and_mask_t;
+
typedef enum
{
VNET_FLOW_TYPE_UNKNOWN,
diff --git a/src/vnet/flow/flow_api.c b/src/vnet/flow/flow_api.c
index bd077d79df8..9ae3802b6fe 100644
--- a/src/vnet/flow/flow_api.c
+++ b/src/vnet/flow/flow_api.c
@@ -66,6 +66,14 @@ ipv6_addr_and_mask_convert (vl_api_ip6_address_and_mask_t * vl_api_addr,
}
static inline void
+protocol_and_mask_convert (vl_api_ip_prot_and_mask_t * vl_api_protocol,
+ ip_prot_and_mask_t * vnet_protocol)
+{
+ vnet_protocol->prot = (ip_protocol_t) vl_api_protocol->prot;
+ vnet_protocol->mask = vl_api_protocol->mask;
+}
+
+static inline void
port_and_mask_convert (vl_api_ip_port_and_mask_t * vl_api_port,
ip_port_and_mask_t * vnet_port)
{
@@ -79,11 +87,10 @@ ipv4_n_tuple_flow_convert (vl_api_flow_ip4_n_tuple_t * vl_api_flow,
{
ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
+ protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
-
- f->protocol = (ip_protocol_t) vl_api_flow->protocol;
}
static void
@@ -92,11 +99,10 @@ ipv6_n_tuple_flow_convert (vl_api_flow_ip6_n_tuple_t * vl_api_flow,
{
ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
+ protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
-
- f->protocol = (ip_protocol_t) vl_api_flow->protocol;
}
static inline void
@@ -124,7 +130,7 @@ ipv4_l2tpv3oip_flow_convert (vl_api_flow_ip4_l2tpv3oip_t * vl_api_flow,
ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
- f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+ protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
f->session_id = ntohl (vl_api_flow->session_id);
}
@@ -135,7 +141,7 @@ ipv4_ipsec_esp_flow_convert (vl_api_flow_ip4_ipsec_esp_t * vl_api_flow,
ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
- f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+ protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
f->spi = ntohl (vl_api_flow->spi);
}
@@ -146,7 +152,7 @@ ipv4_ipsec_ah_flow_convert (vl_api_flow_ip4_ipsec_ah_t * vl_api_flow,
ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
- f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+ protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
f->spi = ntohl (vl_api_flow->spi);
}
@@ -160,7 +166,7 @@ ipv4_gtpu_flow_convert (vl_api_flow_ip4_gtpu_t * vl_api_flow,
port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
- f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+ protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
f->teid = ntohl (vl_api_flow->teid);
}
@@ -174,7 +180,7 @@ ipv4_gtpc_flow_convert (vl_api_flow_ip4_gtpc_t * vl_api_flow,
port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
- f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+ protocol_and_mask_convert (&vl_api_flow->protocol, &f->protocol);
f->teid = ntohl (vl_api_flow->teid);
}
@@ -235,12 +241,10 @@ vl_api_flow_add_t_handler (vl_api_flow_add_t * mp)
rv = VNET_FLOW_ERROR_NOT_SUPPORTED;
goto out;
break;
-
}
rv = vnet_flow_add (vnm, &flow, &flow_index);
- goto out;
out:
/* *INDENT-OFF* */
REPLY_MACRO2(VL_API_FLOW_ADD_REPLY,
diff --git a/src/vnet/flow/flow_cli.c b/src/vnet/flow/flow_cli.c
index 98007a7723e..7dd68677c3b 100644
--- a/src/vnet/flow/flow_cli.c
+++ b/src/vnet/flow/flow_cli.c
@@ -12,11 +12,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <stddef.h>
#include <vnet/vnet.h>
#include <vnet/devices/devices.h>
#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>
+#include <vnet/ethernet/packet.h>
#include <vnet/flow/flow.h>
static format_function_t format_flow;
@@ -60,6 +62,40 @@ format_ip_port_and_mask (u8 * s, va_list * args)
return format (s, "%u/0x%x", pm->port, pm->mask);
}
+uword
+unformat_ip_protocol_and_mask (unformat_input_t * input, va_list * args)
+{
+ ip_prot_and_mask_t *pm = va_arg (*args, ip_prot_and_mask_t *);
+ u32 prot = 0, mask = 0;
+
+ if (unformat (input, "any"))
+ ;
+ else if (unformat (input, "%U", unformat_ip_protocol, &prot))
+ mask = 0xFF;
+ else if (unformat (input, "%u", &prot))
+ mask = 0xFF;
+ else
+ return 0;
+
+ if (prot > 0XFF || mask > 0xFF)
+ return 0;
+
+ pm->prot = prot;
+ pm->mask = mask;
+ return 1;
+}
+
+u8 *
+format_ip_protocol_and_mask (u8 * s, va_list * args)
+{
+ ip_prot_and_mask_t *pm = va_arg (*args, ip_prot_and_mask_t *);
+
+ if (pm->prot == 0 && pm->mask == 0)
+ return format (s, "any");
+
+ return format (s, "%U", format_ip_protocol, pm->prot);
+}
+
u8 *
format_flow_error (u8 * s, va_list * args)
{
@@ -114,6 +150,38 @@ format_flow_enabled_hw (u8 * s, va_list * args)
return s;
}
+u8 *
+format_rss_function (u8 * s, va_list * args)
+{
+ vnet_rss_function_t func = va_arg (*args, vnet_rss_function_t);
+
+ if (0)
+ ;
+#undef _
+#define _(f, n) \
+ else if (func == VNET_RSS_FUNC_##f) \
+ return format (s, n);
+
+ foreach_rss_function
+#undef _
+ return format (s, "unknown");
+}
+
+u8 *
+format_rss_types (u8 * s, va_list * args)
+{
+ u64 type = va_arg (*args, u64);
+
+#undef _
+#define _(a,b,c) \
+ if (type & (1UL<<a)) \
+ s = format (s, "%s ", c);
+
+ foreach_flow_rss_types
+#undef _
+ return s;
+}
+
static const char *flow_type_strings[] = { 0,
#define _(a,b,c) c,
foreach_flow_type
@@ -274,37 +342,40 @@ test_flow (vlib_main_t * vm, unformat_input_t * input,
FLOW_ENABLE,
FLOW_DISABLE
} action = FLOW_UNKNOWN_ACTION;
+ enum
+ {
+ FLOW_UNKNOWN_CLASS,
+ FLOW_ETHERNET_CLASS,
+ FLOW_IPV4_CLASS,
+ FLOW_IPV6_CLASS,
+ } flow_class = FLOW_UNKNOWN_CLASS;
+
u32 hw_if_index = ~0, flow_index = ~0;
int rv;
- u32 prot = 0, teid = 0, session_id = 0, spi = 0;
- vnet_flow_type_t type = VNET_FLOW_TYPE_IP4_N_TUPLE;
- bool is_gtpc_set = false;
- bool is_gtpu_set = false;
- bool is_l2tpv3oip_set = false;
- bool is_ipsec_esp_set = false, is_ipsec_ah_set = false;
- vnet_flow_type_t outer_type = VNET_FLOW_TYPE_UNKNOWN;
- vnet_flow_type_t inner_type = VNET_FLOW_TYPE_UNKNOWN;
- bool outer_ip4_set = false, inner_ip4_set = false;
- bool outer_ip6_set = false, inner_ip6_set = false;
+ u32 teid = 0, session_id = 0, spi = 0;
+ u16 vni = 0;
+ vnet_flow_type_t type = VNET_FLOW_TYPE_UNKNOWN;
ip4_address_and_mask_t ip4s = { };
ip4_address_and_mask_t ip4d = { };
- ip4_address_and_mask_t inner_ip4s = { };
- ip4_address_and_mask_t inner_ip4d = { };
ip6_address_and_mask_t ip6s = { };
ip6_address_and_mask_t ip6d = { };
- ip6_address_and_mask_t inner_ip6s = { };
- ip6_address_and_mask_t inner_ip6d = { };
ip_port_and_mask_t sport = { };
ip_port_and_mask_t dport = { };
+ ip_prot_and_mask_t protocol = { };
u16 eth_type;
- bool ethernet_set = false;
+ bool tcp_udp_port_set = false;
+ bool gtpc_set = false;
+ bool gtpu_set = false;
+ bool vni_set = false;
+ bool l2tpv3oip_set = false;
+ bool ipsec_esp_set = false, ipsec_ah_set = false;
u8 *rss_type[3] = { };
u8 *type_str = NULL;
clib_memset (&flow, 0, sizeof (vnet_flow_t));
flow.index = ~0;
flow.actions = 0;
- flow.ip4_n_tuple.protocol = ~0;
+
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
@@ -320,56 +391,47 @@ test_flow (vlib_main_t * vm, unformat_input_t * input,
action = FLOW_DISABLE;
else if (unformat (line_input, "eth-type %U",
unformat_ethernet_type_host_byte_order, &eth_type))
- ethernet_set = true;
+ flow_class = FLOW_ETHERNET_CLASS;
else if (unformat (line_input, "src-ip %U",
unformat_ip4_address_and_mask, &ip4s))
- outer_ip4_set = true;
+ flow_class = FLOW_IPV4_CLASS;
else if (unformat (line_input, "dst-ip %U",
unformat_ip4_address_and_mask, &ip4d))
- outer_ip4_set = true;
+ flow_class = FLOW_IPV4_CLASS;
else if (unformat (line_input, "ip6-src-ip %U",
unformat_ip6_address_and_mask, &ip6s))
- outer_ip6_set = true;
+ flow_class = FLOW_IPV6_CLASS;
else if (unformat (line_input, "ip6-dst-ip %U",
unformat_ip6_address_and_mask, &ip6d))
- outer_ip6_set = true;
- else if (unformat (line_input, "inner-src-ip %U",
- unformat_ip4_address_and_mask, &inner_ip4s))
- inner_ip4_set = true;
- else if (unformat (line_input, "inner-dst-ip %U",
- unformat_ip4_address_and_mask, &inner_ip4d))
- inner_ip4_set = true;
- else if (unformat (line_input, "inner-ip6-src-ip %U",
- unformat_ip6_address_and_mask, &inner_ip6s))
- inner_ip6_set = true;
- else if (unformat (line_input, "inner-ip6-dst-ip %U",
- unformat_ip6_address_and_mask, &inner_ip6d))
- inner_ip6_set = true;
+ flow_class = FLOW_IPV6_CLASS;
else if (unformat (line_input, "src-port %U", unformat_ip_port_and_mask,
&sport))
- ;
+ tcp_udp_port_set = true;
else if (unformat (line_input, "dst-port %U", unformat_ip_port_and_mask,
&dport))
- ;
- else if (unformat (line_input, "proto %U", unformat_ip_protocol, &prot))
- ;
- else if (unformat (line_input, "proto %u", &prot))
+ tcp_udp_port_set = true;
+ else
+ if (unformat
+ (line_input, "proto %U", unformat_ip_protocol_and_mask,
+ &protocol))
;
else if (unformat (line_input, "gtpc teid %u", &teid))
- is_gtpc_set = true;
+ gtpc_set = true;
else if (unformat (line_input, "gtpu teid %u", &teid))
- is_gtpu_set = true;
+ gtpu_set = true;
+ else if (unformat (line_input, "vxlan vni %u", &vni))
+ vni_set = true;
else if (unformat (line_input, "session id %u", &session_id))
{
- if (prot == IP_PROTOCOL_L2TP)
- is_l2tpv3oip_set = true;
+ if (protocol.prot == IP_PROTOCOL_L2TP)
+ l2tpv3oip_set = true;
}
else if (unformat (line_input, "spi %u", &spi))
{
- if (prot == IP_PROTOCOL_IPSEC_ESP)
- is_ipsec_esp_set = true;
- else if (prot == IP_PROTOCOL_IPSEC_AH)
- is_ipsec_ah_set = true;
+ if (protocol.prot == IP_PROTOCOL_IPSEC_ESP)
+ ipsec_esp_set = true;
+ else if (protocol.prot == IP_PROTOCOL_IPSEC_AH)
+ ipsec_ah_set = true;
}
else if (unformat (line_input, "index %u", &flow_index))
;
@@ -391,9 +453,9 @@ test_flow (vlib_main_t * vm, unformat_input_t * input,
if (0)
;
#undef _
-#define _(f, s) \
- else if (unformat (line_input, s)) \
- flow.rss_fun = VNET_RSS_FUNC_##f;
+#define _(f, s) \
+ else if (unformat (line_input, s)) \
+ flow.rss_fun = VNET_RSS_FUNC_##f;
foreach_rss_function
#undef _
@@ -415,30 +477,29 @@ test_flow (vlib_main_t * vm, unformat_input_t * input,
if (unformat (line_input, "%s use %s and %s",
&rss_type[0], &rss_type[1], &rss_type[2]))
;
- else
- if (unformat
- (line_input, "%s use %s", &rss_type[0], &rss_type[1]))
+ else if (unformat
+ (line_input, "%s use %s", &rss_type[0], &rss_type[1]))
;
else if (unformat (line_input, "%s", &rss_type[0]))
;
#undef _
#define _(a,b,c) \
- else if (!clib_strcmp(c, (const char *)type_str)) \
- flow.rss_types |= (1ULL<<a);
+ else if (!clib_strcmp(c, (const char *)type_str)) \
+ flow.rss_types |= (1ULL<<a);
#define check_rss_types(_str) \
- if (_str != NULL) {\
- type_str = _str;\
- if (0) \
- ; \
- foreach_flow_rss_types \
- else \
- { \
- return clib_error_return (0, "parse error: '%U'", \
- format_unformat_error, line_input); \
- } \
- }
+ if (_str != NULL) {\
+ type_str = _str;\
+ if (0) \
+ ; \
+ foreach_flow_rss_types \
+ else \
+ { \
+ return clib_error_return (0, "parse error: '%U'", \
+ format_unformat_error, line_input); \
+ } \
+ }
check_rss_types (rss_type[0])
check_rss_types (rss_type[1]) check_rss_types (rss_type[2])
@@ -469,200 +530,141 @@ test_flow (vlib_main_t * vm, unformat_input_t * input,
return clib_error_return (0, "Please specify at least one action");
/* Adjust the flow type */
- if (ethernet_set == true)
- outer_type = VNET_FLOW_TYPE_ETHERNET;
- if (outer_ip4_set == true)
- outer_type = VNET_FLOW_TYPE_IP4_N_TUPLE;
- else if (outer_ip6_set == true)
- outer_type = VNET_FLOW_TYPE_IP6_N_TUPLE;
- if (inner_ip4_set == true)
- inner_type = VNET_FLOW_TYPE_IP4_N_TUPLE;
- else if (inner_ip6_set == true)
- inner_type = VNET_FLOW_TYPE_IP6_N_TUPLE;
-
- if (outer_type == VNET_FLOW_TYPE_UNKNOWN)
- return clib_error_return (0, "Please specify a supported flow type");
-
- if (outer_type == VNET_FLOW_TYPE_ETHERNET)
- type = VNET_FLOW_TYPE_ETHERNET;
- else if (outer_type == VNET_FLOW_TYPE_IP4_N_TUPLE)
+ switch (flow_class)
{
- type = VNET_FLOW_TYPE_IP4_N_TUPLE;
+ case FLOW_ETHERNET_CLASS:
+ type = VNET_FLOW_TYPE_ETHERNET;
+ break;
- if (inner_type == VNET_FLOW_TYPE_UNKNOWN)
+ case FLOW_IPV4_CLASS:
+ if (gtpc_set)
{
- if (is_gtpc_set)
- type = VNET_FLOW_TYPE_IP4_GTPC;
- else if (is_gtpu_set)
- type = VNET_FLOW_TYPE_IP4_GTPU;
- else if (is_l2tpv3oip_set)
- type = VNET_FLOW_TYPE_IP4_L2TPV3OIP;
- else if (is_ipsec_esp_set)
- type = VNET_FLOW_TYPE_IP4_IPSEC_ESP;
- else if (is_ipsec_ah_set)
- type = VNET_FLOW_TYPE_IP4_IPSEC_AH;
+ type = VNET_FLOW_TYPE_IP4_GTPC;
+ protocol.prot = IP_PROTOCOL_UDP;
}
- else if (inner_type == VNET_FLOW_TYPE_IP4_N_TUPLE)
+ else if (gtpu_set)
{
- if (is_gtpu_set)
- type = VNET_FLOW_TYPE_IP4_GTPU_IP4;
+ type = VNET_FLOW_TYPE_IP4_GTPU;
+ protocol.prot = IP_PROTOCOL_UDP;
}
- else if (inner_type == VNET_FLOW_TYPE_IP6_N_TUPLE)
+ else if (vni_set)
{
- if (is_gtpu_set)
- type = VNET_FLOW_TYPE_IP4_GTPU_IP6;
+ type = VNET_FLOW_TYPE_IP4_VXLAN;
+ protocol.prot = IP_PROTOCOL_UDP;
}
- }
- else if (outer_type == VNET_FLOW_TYPE_IP6_N_TUPLE)
- {
- type = VNET_FLOW_TYPE_IP6_N_TUPLE;
+ else if (l2tpv3oip_set)
+ type = VNET_FLOW_TYPE_IP4_L2TPV3OIP;
+ else if (ipsec_esp_set)
+ type = VNET_FLOW_TYPE_IP4_IPSEC_ESP;
+ else if (ipsec_ah_set)
+ type = VNET_FLOW_TYPE_IP4_IPSEC_AH;
+ else if (tcp_udp_port_set)
+ type = VNET_FLOW_TYPE_IP4_N_TUPLE;
+ else
+ type = VNET_FLOW_TYPE_IP4;
+ break;
+ case FLOW_IPV6_CLASS:
+ if (tcp_udp_port_set)
+ type = VNET_FLOW_TYPE_IP6_N_TUPLE;
+ else if (vni_set)
+ type = VNET_FLOW_TYPE_IP6_VXLAN;
+ else
+ type = VNET_FLOW_TYPE_IP6;
+ break;
- if (inner_type == VNET_FLOW_TYPE_UNKNOWN)
- {
- if (is_gtpc_set)
- type = VNET_FLOW_TYPE_IP6_GTPC;
- else if (is_gtpu_set)
- type = VNET_FLOW_TYPE_IP6_GTPU;
- }
- else if (inner_type == VNET_FLOW_TYPE_IP4_N_TUPLE)
- {
- if (is_gtpu_set)
- type = VNET_FLOW_TYPE_IP6_GTPU_IP4;
- }
- else if (inner_type == VNET_FLOW_TYPE_IP6_N_TUPLE)
- {
- if (is_gtpu_set)
- type = VNET_FLOW_TYPE_IP6_GTPU_IP6;
- }
+ default:
+ return clib_error_return (0,
+ "Please specify a supported flow type");
}
- //assign specific field values per flow type
- switch (type)
+ /* Assign specific field values per flow type */
+ if (flow_class == FLOW_ETHERNET_CLASS)
{
- case VNET_FLOW_TYPE_ETHERNET:
- memset (&flow.ethernet, 0, sizeof (flow.ethernet));
flow.ethernet.eth_hdr.type = eth_type;
- break;
- case VNET_FLOW_TYPE_IP4_L2TPV3OIP:
- clib_memcpy (&flow.ip4_l2tpv3oip.src_addr, &ip4s,
- sizeof (ip4_address_and_mask_t));
- clib_memcpy (&flow.ip4_l2tpv3oip.dst_addr, &ip4d,
- sizeof (ip4_address_and_mask_t));
- flow.ip4_l2tpv3oip.protocol = prot;
- flow.ip4_l2tpv3oip.session_id = session_id;
- break;
- case VNET_FLOW_TYPE_IP4_IPSEC_ESP:
- clib_memcpy (&flow.ip4_ipsec_esp.src_addr, &ip4s,
- sizeof (ip4_address_and_mask_t));
- clib_memcpy (&flow.ip4_ipsec_esp.dst_addr, &ip4d,
- sizeof (ip4_address_and_mask_t));
- flow.ip4_ipsec_esp.protocol = prot;
- flow.ip4_ipsec_esp.spi = spi;
- break;
- case VNET_FLOW_TYPE_IP4_IPSEC_AH:
- clib_memcpy (&flow.ip4_ipsec_ah.src_addr, &ip4s,
- sizeof (ip4_address_and_mask_t));
- clib_memcpy (&flow.ip4_ipsec_ah.dst_addr, &ip4d,
- sizeof (ip4_address_and_mask_t));
- flow.ip4_ipsec_ah.protocol = prot;
- flow.ip4_ipsec_ah.spi = spi;
- break;
- case VNET_FLOW_TYPE_IP4_N_TUPLE:
- case VNET_FLOW_TYPE_IP4_GTPC:
- case VNET_FLOW_TYPE_IP4_GTPU:
- case VNET_FLOW_TYPE_IP4_GTPU_IP4:
- case VNET_FLOW_TYPE_IP4_GTPU_IP6:
- clib_memcpy (&flow.ip4_n_tuple.src_addr, &ip4s,
+ }
+ else if (flow_class == FLOW_IPV4_CLASS)
+ {
+ vnet_flow_ip4_t *ip4_ptr = &flow.ip4;
+
+ clib_memcpy (&ip4_ptr->src_addr, &ip4s,
sizeof (ip4_address_and_mask_t));
- clib_memcpy (&flow.ip4_n_tuple.dst_addr, &ip4d,
+ clib_memcpy (&ip4_ptr->dst_addr, &ip4d,
sizeof (ip4_address_and_mask_t));
- clib_memcpy (&flow.ip4_n_tuple.src_port, &sport,
- sizeof (ip_port_and_mask_t));
- clib_memcpy (&flow.ip4_n_tuple.dst_port, &dport,
- sizeof (ip_port_and_mask_t));
- flow.ip4_n_tuple.protocol = prot;
-
- if (type == VNET_FLOW_TYPE_IP4_GTPC)
- flow.ip4_gtpc.teid = teid;
- else if (type == VNET_FLOW_TYPE_IP4_GTPU)
- flow.ip4_gtpu.teid = teid;
- else if (type == VNET_FLOW_TYPE_IP4_GTPU_IP4)
- {
- flow.ip4_gtpu_ip4.teid = teid;
- clib_memcpy (&flow.ip4_gtpu_ip4.inner_src_addr, &inner_ip4s,
- sizeof (ip4_address_and_mask_t));
- clib_memcpy (&flow.ip4_gtpu_ip4.inner_dst_addr, &inner_ip4d,
- sizeof (ip4_address_and_mask_t));
- }
- else if (type == VNET_FLOW_TYPE_IP4_GTPU_IP6)
+ ip4_ptr->protocol.prot = protocol.prot;
+
+ /* In this cli, we use the protocol.mask only when the flow type is
+ * VNET_FLOW_TYPE_IP4/IP6. For other cases, the IP protocol is just
+ * used to identify the next layer type: e.g. UDP/TCP or IPSEC_ESP
+ */
+ if (type == VNET_FLOW_TYPE_IP4)
+ ip4_ptr->protocol.mask = protocol.mask;
+
+ switch (protocol.prot)
{
- flow.ip4_gtpu_ip6.teid = teid;
- clib_memcpy (&flow.ip4_gtpu_ip6.inner_src_addr, &inner_ip6s,
- sizeof (ip6_address_and_mask_t));
- clib_memcpy (&flow.ip4_gtpu_ip6.inner_dst_addr, &inner_ip6d,
- sizeof (ip6_address_and_mask_t));
+ /* ip4-n-tuple */
+ case IP_PROTOCOL_TCP:
+ case IP_PROTOCOL_UDP:
+ flow.ip4_n_tuple.src_port = sport;
+ flow.ip4_n_tuple.dst_port = dport;
+
+ if (type == VNET_FLOW_TYPE_IP4_GTPC)
+ flow.ip4_gtpc.teid = teid;
+ else if (type == VNET_FLOW_TYPE_IP4_GTPU)
+ flow.ip4_gtpu.teid = teid;
+ else if (type == VNET_FLOW_TYPE_IP4_VXLAN)
+ flow.ip4_vxlan.vni = vni;
+ break;
+ case IP_PROTOCOL_L2TP:
+ flow.ip4_l2tpv3oip.session_id = session_id;
+ break;
+ case IP_PROTOCOL_IPSEC_ESP:
+ flow.ip4_ipsec_esp.spi = spi;
+ break;
+ case IP_PROTOCOL_IPSEC_AH:
+ flow.ip4_ipsec_esp.spi = spi;
+ break;
+ default:
+ break;
}
+ }
+ else if (flow_class == FLOW_IPV6_CLASS)
+ {
+ vnet_flow_ip6_t *ip6_ptr = &flow.ip6;
- if (flow.ip4_n_tuple.protocol == (ip_protocol_t) ~ 0)
- return clib_error_return (0, "Please specify ip protocol");
- if ((type != VNET_FLOW_TYPE_IP4_N_TUPLE) &&
- (flow.ip4_n_tuple.protocol != IP_PROTOCOL_UDP))
- return clib_error_return (0,
- "For GTP related flow, ip protocol must be UDP");
- break;
-
- case VNET_FLOW_TYPE_IP6_N_TUPLE:
- case VNET_FLOW_TYPE_IP6_GTPC:
- case VNET_FLOW_TYPE_IP6_GTPU:
- case VNET_FLOW_TYPE_IP6_GTPU_IP4:
- case VNET_FLOW_TYPE_IP6_GTPU_IP6:
clib_memcpy (&flow.ip6_n_tuple.src_addr, &ip6s,
sizeof (ip6_address_and_mask_t));
clib_memcpy (&flow.ip6_n_tuple.dst_addr, &ip6d,
sizeof (ip6_address_and_mask_t));
- clib_memcpy (&flow.ip6_n_tuple.src_port, &sport,
- sizeof (ip_port_and_mask_t));
- clib_memcpy (&flow.ip6_n_tuple.dst_port, &dport,
- sizeof (ip_port_and_mask_t));
- flow.ip6_n_tuple.protocol = prot;
-
- if (type == VNET_FLOW_TYPE_IP6_GTPC)
- flow.ip6_gtpc.teid = teid;
- else if (type == VNET_FLOW_TYPE_IP6_GTPU)
- flow.ip6_gtpu.teid = teid;
- else if (type == VNET_FLOW_TYPE_IP6_GTPU_IP4)
- {
- flow.ip6_gtpu_ip4.teid = teid;
- clib_memcpy (&flow.ip6_gtpu_ip4.inner_src_addr, &inner_ip4s,
- sizeof (ip4_address_and_mask_t));
- clib_memcpy (&flow.ip6_gtpu_ip4.inner_dst_addr, &inner_ip4d,
- sizeof (ip4_address_and_mask_t));
- }
- else if (type == VNET_FLOW_TYPE_IP6_GTPU_IP6)
- {
- flow.ip6_gtpu_ip6.teid = teid;
- clib_memcpy (&flow.ip6_gtpu_ip6.inner_src_addr, &inner_ip6s,
- sizeof (ip6_address_and_mask_t));
- clib_memcpy (&flow.ip6_gtpu_ip6.inner_dst_addr, &inner_ip6d,
- sizeof (ip6_address_and_mask_t));
- }
- if (flow.ip6_n_tuple.protocol == (ip_protocol_t) ~ 0)
- return clib_error_return (0, "Please specify ip protocol");
- if ((type != VNET_FLOW_TYPE_IP6_N_TUPLE) &&
- (flow.ip6_n_tuple.protocol != IP_PROTOCOL_UDP))
- return clib_error_return (0,
- "For GTP related flow, ip protocol must be UDP");
- break;
+ ip6_ptr->protocol.prot = protocol.prot;
- default:
- break;
+ /* In this cli, we use the protocol.mask only when the flow type is
+ * VNET_FLOW_TYPE_IP4/IP6. For other cases, the IP protocol is just
+ * used to identify the next layer type: e.g. UDP/TCP or IPSEC_ESP
+ */
+ if (type == VNET_FLOW_TYPE_IP6)
+ ip6_ptr->protocol.mask = protocol.mask;
+
+ switch (protocol.prot)
+ {
+ /* ip6-n-tuple */
+ case IP_PROTOCOL_TCP:
+ case IP_PROTOCOL_UDP:
+ flow.ip6_n_tuple.src_port = sport;
+ flow.ip6_n_tuple.dst_port = dport;
+
+ if (type == VNET_FLOW_TYPE_IP6_VXLAN)
+ flow.ip6_vxlan.vni = vni;
+ break;
+ default:
+ break;
+ }
}
flow.type = type;
rv = vnet_flow_add (vnm, &flow, &flow_index);
if (!rv)
- printf ("flow %u added\n", flow_index);
+ vlib_cli_output (vm, "flow %u added", flow_index);
break;
case FLOW_DEL:
@@ -681,20 +683,27 @@ test_flow (vlib_main_t * vm, unformat_input_t * input,
if (rv < 0)
return clib_error_return (0, "flow error: %U", format_flow_error, rv);
+
return 0;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (test_flow_command, static) = {
.path = "test flow",
- .short_help = "test flow add [src-ip <ip-addr/mask>] [dst-ip "
- "<ip-addr/mask>] [src-port <port/mask>] [dst-port <port/mask>] "
- "[proto <ip-proto>",
+ .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,
};
/* *INDENT-ON* */
-
static u8 *
format_flow_match_element (u8 * s, va_list * args)
{
@@ -710,6 +719,16 @@ format_flow_match_element (u8 * s, va_list * args)
if (strncmp (type, "u32", 3) == 0)
return format (s, "%d", *(u32 *) ptr);
+ if (strncmp (type, "ethernet_header_t", 13) == 0)
+ {
+ ethernet_max_header_t m;
+ memset (&m, 0, sizeof (m));
+ m.ethernet = *(ethernet_header_t *) ptr;
+ /* convert the ethernet type to net order */
+ m.ethernet.type = clib_host_to_net_u16 (m.ethernet.type);
+ return format (s, "%U", format_ethernet_header, &m);
+ }
+
if (strncmp (type, "ip4_address_t", 13) == 0)
return format (s, "%U", format_ip4_address, ptr);
@@ -722,8 +741,8 @@ format_flow_match_element (u8 * s, va_list * args)
if (strncmp (type, "ip6_address_and_mask_t", 13) == 0)
return format (s, "%U", format_ip6_address_and_mask, ptr);
- if (strncmp (type, "ip_protocol_t", 13) == 0)
- return format (s, "%U", format_ip_protocol, *(ip_protocol_t *) ptr);
+ if (strncmp (type, "ip_prot_and_mask_t", 13) == 0)
+ return format (s, "%U", format_ip_protocol_and_mask, ptr);
if (strncmp (type, "ip_port_and_mask_t", 18) == 0)
return format (s, "%U", format_ip_port_and_mask, ptr);
@@ -777,9 +796,16 @@ format_flow (u8 * s, va_list * args)
s = format (s, "\n%Uaction: %U", format_white_space, indent + 2,
format_flow_actions, f->actions);
+ if (f->actions & VNET_FLOW_ACTION_DROP)
+ t = format (t, "%sdrop", t ? ", " : "");
+
if (f->actions & VNET_FLOW_ACTION_MARK)
t = format (t, "%smark %u", t ? ", " : "", f->mark_flow_id);
+ if (f->actions & VNET_FLOW_ACTION_REDIRECT_TO_QUEUE)
+ t =
+ format (t, "%sredirect-to-queue %u", t ? ", " : "", f->redirect_queue);
+
if (f->actions & VNET_FLOW_ACTION_REDIRECT_TO_NODE)
t = format (t, "%snext-node %U", t ? ", " : "",
format_vlib_node_name, vm, f->redirect_node_index);
@@ -787,6 +813,14 @@ format_flow (u8 * s, va_list * args)
if (f->actions & VNET_FLOW_ACTION_BUFFER_ADVANCE)
t = format (t, "%sbuffer-advance %d", t ? ", " : "", f->buffer_advance);
+ if (f->actions & VNET_FLOW_ACTION_RSS)
+ {
+ t = format (t, "%srss function %U", t ? ", " : "",
+ format_rss_function, f->rss_fun);
+ t = format (t, "%srss types %U", t ? ", " : "",
+ format_rss_types, f->rss_types);
+ }
+
if (t)
{
s = format (s, "\n%U%v", format_white_space, indent + 4, t);
diff --git a/src/vnet/flow/flow_types.api b/src/vnet/flow/flow_types.api
index d872d6eb264..7df46d2131d 100644
--- a/src/vnet/flow/flow_types.api
+++ b/src/vnet/flow/flow_types.api
@@ -14,20 +14,22 @@
* limitations under the License.
*/
-option version = "0.0.1";
+option version = "0.0.2";
import "vnet/ethernet/ethernet_types.api";
import "vnet/ip/ip_types.api";
enum flow_type
{
FLOW_TYPE_ETHERNET = 1,
+ FLOW_TYPE_IP4,
+ FLOW_TYPE_IP6,
+ FLOW_TYPE_IP4_L2TPV3OIP,
+ FLOW_TYPE_IP4_IPSEC_ESP,
+ FLOW_TYPE_IP4_IPSEC_AH,
FLOW_TYPE_IP4_N_TUPLE,
FLOW_TYPE_IP6_N_TUPLE,
FLOW_TYPE_IP4_N_TUPLE_TAGGED,
FLOW_TYPE_IP6_N_TUPLE_TAGGED,
- FLOW_TYPE_IP4_L2TPV3OIP,
- FLOW_TYPE_IP4_IPSEC_ESP,
- FLOW_TYPE_IP4_IPSEC_AH,
FLOW_TYPE_IP4_VXLAN,
FLOW_TYPE_IP6_VXLAN,
FLOW_TYPE_IP4_GTPC,
@@ -50,6 +52,12 @@ typedef ip_port_and_mask
u16 mask;
};
+typedef ip_prot_and_mask
+{
+ vl_api_ip_proto_t prot;
+ u8 mask;
+};
+
typedef flow_ethernet
{
i32 foo;
@@ -58,14 +66,30 @@ typedef flow_ethernet
u16 type;
};
+typedef flow_ip4
+{
+ i32 foo;
+ vl_api_ip4_address_and_mask_t src_addr;
+ vl_api_ip4_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
+};
+
+typedef flow_ip6
+{
+ i32 foo;
+ vl_api_ip6_address_and_mask_t src_addr;
+ vl_api_ip6_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
+};
+
typedef flow_ip4_n_tuple
{
i32 foo;
vl_api_ip4_address_and_mask_t src_addr;
vl_api_ip4_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
vl_api_ip_port_and_mask_t src_port;
vl_api_ip_port_and_mask_t dst_port;
- vl_api_ip_proto_t protocol;
};
typedef flow_ip6_n_tuple
@@ -73,9 +97,9 @@ typedef flow_ip6_n_tuple
i32 foo;
vl_api_ip6_address_and_mask_t src_addr;
vl_api_ip6_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
vl_api_ip_port_and_mask_t src_port;
vl_api_ip_port_and_mask_t dst_port;
- vl_api_ip_proto_t protocol;
};
typedef flow_ip4_n_tuple_tagged
@@ -83,9 +107,9 @@ typedef flow_ip4_n_tuple_tagged
i32 foo;
vl_api_ip4_address_and_mask_t src_addr;
vl_api_ip4_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
vl_api_ip_port_and_mask_t src_port;
vl_api_ip_port_and_mask_t dst_port;
- vl_api_ip_proto_t protocol;
};
typedef flow_ip6_n_tuple_tagged
@@ -93,9 +117,9 @@ typedef flow_ip6_n_tuple_tagged
i32 foo;
vl_api_ip6_address_and_mask_t src_addr;
vl_api_ip6_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
vl_api_ip_port_and_mask_t src_port;
vl_api_ip_port_and_mask_t dst_port;
- vl_api_ip_proto_t protocol;
};
typedef flow_ip4_l2tpv3oip
@@ -103,9 +127,7 @@ typedef flow_ip4_l2tpv3oip
i32 foo;
vl_api_ip4_address_and_mask_t src_addr;
vl_api_ip4_address_and_mask_t dst_addr;
- vl_api_ip_port_and_mask_t src_port;
- vl_api_ip_port_and_mask_t dst_port;
- vl_api_ip_proto_t protocol;
+ vl_api_ip_prot_and_mask_t protocol;
u32 session_id;
};
@@ -114,9 +136,7 @@ typedef flow_ip4_ipsec_esp
i32 foo;
vl_api_ip4_address_and_mask_t src_addr;
vl_api_ip4_address_and_mask_t dst_addr;
- vl_api_ip_port_and_mask_t src_port;
- vl_api_ip_port_and_mask_t dst_port;
- vl_api_ip_proto_t protocol;
+ vl_api_ip_prot_and_mask_t protocol;
u32 spi;
};
@@ -125,27 +145,29 @@ typedef flow_ip4_ipsec_ah
i32 foo;
vl_api_ip4_address_and_mask_t src_addr;
vl_api_ip4_address_and_mask_t dst_addr;
- vl_api_ip_port_and_mask_t src_port;
- vl_api_ip_port_and_mask_t dst_port;
- vl_api_ip_proto_t protocol;
+ vl_api_ip_prot_and_mask_t protocol;
u32 spi;
};
typedef flow_ip4_vxlan
{
i32 foo;
- vl_api_ip4_address_t src_addr;
- vl_api_ip4_address_t dst_addr;
- u16 dst_port;
+ vl_api_ip4_address_and_mask_t src_addr;
+ vl_api_ip4_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
+ vl_api_ip_port_and_mask_t src_port;
+ vl_api_ip_port_and_mask_t dst_port;
u16 vni;
};
typedef flow_ip6_vxlan
{
i32 foo;
- vl_api_ip6_address_t src_addr;
- vl_api_ip6_address_t dst_addr;
- u16 dst_port;
+ vl_api_ip6_address_and_mask_t src_addr;
+ vl_api_ip6_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
+ vl_api_ip_port_and_mask_t src_port;
+ vl_api_ip_port_and_mask_t dst_port;
u16 vni;
};
@@ -154,9 +176,9 @@ typedef flow_ip4_gtpc
i32 foo;
vl_api_ip4_address_and_mask_t src_addr;
vl_api_ip4_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
vl_api_ip_port_and_mask_t src_port;
vl_api_ip_port_and_mask_t dst_port;
- vl_api_ip_proto_t protocol;
u32 teid;
};
@@ -165,22 +187,24 @@ typedef flow_ip4_gtpu
i32 foo;
vl_api_ip4_address_and_mask_t src_addr;
vl_api_ip4_address_and_mask_t dst_addr;
+ vl_api_ip_prot_and_mask_t protocol;
vl_api_ip_port_and_mask_t src_port;
vl_api_ip_port_and_mask_t dst_port;
- vl_api_ip_proto_t protocol;
u32 teid;
};
union flow
{
vl_api_flow_ethernet_t ethernet;
+ vl_api_flow_ip4_t ip4;
+ vl_api_flow_ip6_t ip6;
+ vl_api_flow_ip4_l2tpv3oip_t ip4_l2tpv3oip;
+ vl_api_flow_ip4_ipsec_esp_t ip4_ipsec_esp;
+ vl_api_flow_ip4_ipsec_ah_t ip4_ipsec_ah;
vl_api_flow_ip4_n_tuple_t ip4_n_tuple;
vl_api_flow_ip6_n_tuple_t ip6_n_tuple;
vl_api_flow_ip4_n_tuple_tagged_t ip4_n_tuple_tagged;
vl_api_flow_ip6_n_tuple_tagged_t ip6_n_tuple_tagged;
- vl_api_flow_ip4_l2tpv3oip_t ip4_l2tpv3oip;
- vl_api_flow_ip4_ipsec_esp_t ip4_ipsec_esp;
- vl_api_flow_ip4_ipsec_ah_t ip4_ipsec_ah;
vl_api_flow_ip4_vxlan_t ip4_vxlan;
vl_api_flow_ip6_vxlan_t ip6_vxlan;
vl_api_flow_ip4_gtpc_t ip4_gtpc;
diff --git a/src/vnet/vxlan/vxlan.c b/src/vnet/vxlan/vxlan.c
index ea1748ce4a8..b1e4aaf291f 100644
--- a/src/vnet/vxlan/vxlan.c
+++ b/src/vnet/vxlan/vxlan.c
@@ -1114,9 +1114,13 @@ vnet_vxlan_add_del_rx_flow (u32 hw_if_index, u32 t_index, int is_add)
.buffer_advance = sizeof (ethernet_header_t),
.type = VNET_FLOW_TYPE_IP4_VXLAN,
.ip4_vxlan = {
- .src_addr = t->dst.ip4,
- .dst_addr = t->src.ip4,
- .dst_port = UDP_DST_PORT_vxlan,
+ .protocol.prot = IP_PROTOCOL_UDP,
+ .src_addr.addr = t->dst.ip4,
+ .dst_addr.addr = t->src.ip4,
+ .src_addr.mask.as_u32 = ~0,
+ .dst_addr.mask.as_u32 = ~0,
+ .dst_port.port = UDP_DST_PORT_vxlan,
+ .dst_port.mask = 0xFF,
.vni = t->vni,
}
,