summaryrefslogtreecommitdiffstats
path: root/vpp-api-test/vat/api_format.c
diff options
context:
space:
mode:
authorJuraj Sloboda <jsloboda@cisco.com>2016-08-07 23:46:45 -0700
committerDamjan Marion <dmarion.lists@gmail.com>2016-10-10 20:51:28 +0000
commit51ffa817d910ba058cd76f2b7dd9a4142944f2ee (patch)
tree826ab211ee1e1f330694bb1ce430d11044228e5b /vpp-api-test/vat/api_format.c
parent506b24564d32c7aca58055a710eba64ed942c1c4 (diff)
ipfix: add l4 unformat support for mask and match (VPP-204)
Change-Id: Iff32c488af9b71acbc4e572c6741afae0a67333c Signed-off-by: Juraj Sloboda <jsloboda@cisco.com>
Diffstat (limited to 'vpp-api-test/vat/api_format.c')
-rw-r--r--vpp-api-test/vat/api_format.c208
1 files changed, 201 insertions, 7 deletions
diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c
index 78e01c6fcaf..fec31588128 100644
--- a/vpp-api-test/vat/api_format.c
+++ b/vpp-api-test/vat/api_format.c
@@ -7836,17 +7836,148 @@ api_sr_multicast_map_add_del (vat_main_t * vam)
}
+#define foreach_tcp_proto_field \
+_(src_port) \
+_(dst_port)
+
+#define foreach_udp_proto_field \
+_(src_port) \
+_(dst_port)
+
#define foreach_ip4_proto_field \
_(src_address) \
_(dst_address) \
_(tos) \
-_(length) \
+_(length) \
_(fragment_id) \
_(ttl) \
_(protocol) \
_(checksum)
uword
+unformat_tcp_mask (unformat_input_t * input, va_list * args)
+{
+ u8 **maskp = va_arg (*args, u8 **);
+ u8 *mask = 0;
+ u8 found_something = 0;
+ tcp_header_t *tcp;
+
+#define _(a) u8 a=0;
+ foreach_tcp_proto_field;
+#undef _
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (0);
+#define _(a) else if (unformat (input, #a)) a=1;
+ foreach_tcp_proto_field
+#undef _
+ else
+ break;
+ }
+
+#define _(a) found_something += a;
+ foreach_tcp_proto_field;
+#undef _
+
+ if (found_something == 0)
+ return 0;
+
+ vec_validate (mask, sizeof (*tcp) - 1);
+
+ tcp = (tcp_header_t *) mask;
+
+#define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
+ foreach_tcp_proto_field;
+#undef _
+
+ *maskp = mask;
+ return 1;
+}
+
+uword
+unformat_udp_mask (unformat_input_t * input, va_list * args)
+{
+ u8 **maskp = va_arg (*args, u8 **);
+ u8 *mask = 0;
+ u8 found_something = 0;
+ udp_header_t *udp;
+
+#define _(a) u8 a=0;
+ foreach_udp_proto_field;
+#undef _
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (0);
+#define _(a) else if (unformat (input, #a)) a=1;
+ foreach_udp_proto_field
+#undef _
+ else
+ break;
+ }
+
+#define _(a) found_something += a;
+ foreach_udp_proto_field;
+#undef _
+
+ if (found_something == 0)
+ return 0;
+
+ vec_validate (mask, sizeof (*udp) - 1);
+
+ udp = (udp_header_t *) mask;
+
+#define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
+ foreach_udp_proto_field;
+#undef _
+
+ *maskp = mask;
+ return 1;
+}
+
+typedef struct
+{
+ u16 src_port, dst_port;
+} tcpudp_header_t;
+
+uword
+unformat_l4_mask (unformat_input_t * input, va_list * args)
+{
+ u8 **maskp = va_arg (*args, u8 **);
+ u16 src_port = 0, dst_port = 0;
+ tcpudp_header_t *tcpudp;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
+ return 1;
+ else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
+ return 1;
+ else if (unformat (input, "src_port"))
+ src_port = 0xFFFF;
+ else if (unformat (input, "dst_port"))
+ dst_port = 0xFFFF;
+ else
+ return 0;
+ }
+
+ if (!src_port && !dst_port)
+ return 0;
+
+ u8 *mask = 0;
+ vec_validate (mask, sizeof (tcpudp_header_t) - 1);
+
+ tcpudp = (tcpudp_header_t *) mask;
+ tcpudp->src_port = src_port;
+ tcpudp->dst_port = dst_port;
+
+ *maskp = mask;
+
+ return 1;
+}
+
+uword
unformat_ip4_mask (unformat_input_t * input, va_list * args)
{
u8 **maskp = va_arg (*args, u8 **);
@@ -8123,6 +8254,7 @@ unformat_classify_mask (unformat_input_t * input, va_list * args)
u8 *mask = 0;
u8 *l2 = 0;
u8 *l3 = 0;
+ u8 *l4 = 0;
int i;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -8133,13 +8265,23 @@ unformat_classify_mask (unformat_input_t * input, va_list * args)
;
else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
;
+ else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
+ ;
else
break;
}
- if (mask || l2 || l3)
+ if (l4 && !l3)
{
- if (l2 || l3)
+ vec_free (mask);
+ vec_free (l2);
+ vec_free (l4);
+ return 0;
+ }
+
+ if (mask || l2 || l3 || l4)
+ {
+ if (l2 || l3 || l4)
{
/* "With a free Ethernet header in every package" */
if (l2 == 0)
@@ -8150,6 +8292,11 @@ unformat_classify_mask (unformat_input_t * input, va_list * args)
vec_append (mask, l3);
vec_free (l3);
}
+ if (vec_len (l4))
+ {
+ vec_append (mask, l4);
+ vec_free (l4);
+ }
}
/* Scan forward looking for the first significant mask octet */
@@ -8390,6 +8537,37 @@ api_classify_add_del_table (vat_main_t * vam)
}
uword
+unformat_l4_match (unformat_input_t * input, va_list * args)
+{
+ u8 **matchp = va_arg (*args, u8 **);
+
+ u8 *proto_header = 0;
+ int src_port = 0;
+ int dst_port = 0;
+
+ tcpudp_header_t h;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "src_port %d", &src_port))
+ ;
+ else if (unformat (input, "dst_port %d", &dst_port))
+ ;
+ else
+ return 0;
+ }
+
+ h.src_port = clib_host_to_net_u16 (src_port);
+ h.dst_port = clib_host_to_net_u16 (dst_port);
+ vec_validate (proto_header, sizeof (h) - 1);
+ memcpy (proto_header, &h, sizeof (h));
+
+ *matchp = proto_header;
+
+ return 1;
+}
+
+uword
unformat_ip4_match (unformat_input_t * input, va_list * args)
{
u8 **matchp = va_arg (*args, u8 **);
@@ -8473,13 +8651,13 @@ unformat_ip4_match (unformat_input_t * input, va_list * args)
ip->tos = tos_val;
if (length)
- ip->length = length_val;
+ ip->length = clib_host_to_net_u16 (length_val);
if (ttl)
ip->ttl = ttl_val;
if (checksum)
- ip->checksum = checksum_val;
+ ip->checksum = clib_host_to_net_u16 (checksum_val);
*matchp = match;
return 1;
@@ -8734,6 +8912,7 @@ unformat_classify_match (unformat_input_t * input, va_list * args)
u8 *match = 0;
u8 *l2 = 0;
u8 *l3 = 0;
+ u8 *l4 = 0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
@@ -8743,13 +8922,23 @@ unformat_classify_match (unformat_input_t * input, va_list * args)
;
else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
;
+ else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
+ ;
else
break;
}
- if (match || l2 || l3)
+ if (l4 && !l3)
{
- if (l2 || l3)
+ vec_free (match);
+ vec_free (l2);
+ vec_free (l4);
+ return 0;
+ }
+
+ if (match || l2 || l3 || l4)
+ {
+ if (l2 || l3 || l4)
{
/* "Win a free Ethernet header in every packet" */
if (l2 == 0)
@@ -8760,6 +8949,11 @@ unformat_classify_match (unformat_input_t * input, va_list * args)
vec_append_aligned (match, l3, sizeof (u32x4));
vec_free (l3);
}
+ if (vec_len (l4))
+ {
+ vec_append_aligned (match, l4, sizeof (u32x4));
+ vec_free (l4);
+ }
}
/* Make sure the vector is big enough even if key is all 0's */