ipfix: add l4 unformat support for mask and match (VPP-204)
Change-Id: Iff32c488af9b71acbc4e572c6741afae0a67333c Signed-off-by: Juraj Sloboda <jsloboda@cisco.com>
This commit is contained in:

committed by
Damjan Marion

parent
506b24564d
commit
51ffa817d9
@ -7836,16 +7836,147 @@ 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)
|
||||
{
|
||||
@ -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 */
|
||||
@ -8389,6 +8536,37 @@ api_classify_add_del_table (vat_main_t * vam)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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 */
|
||||
|
Reference in New Issue
Block a user