2 * BIRD Library -- Flow specification (RFC 5575) Tests
4 * (c) 2016 CZ.NIC z.s.p.o.
6 * Can be freely distributed and used under the terms of the GNU GPL.
9 #include "test/birdtest.h"
10 #include "lib/flowspec.h"
12 #define NET_ADDR_FLOW4_(what,prefix,pxlen,data_) \
15 what = alloca(sizeof(net_addr_flow4) + 128); \
16 *what = NET_ADDR_FLOW4(prefix, pxlen, sizeof(data_)); \
17 memcpy(what->data, &(data_), sizeof(data_)); \
20 #define NET_ADDR_FLOW6_(what,prefix,pxlen,data_) \
23 what = alloca(sizeof(net_addr_flow6) + 128); \
24 *what = NET_ADDR_FLOW6(prefix, pxlen, sizeof(data_)); \
25 memcpy(what->data, &(data_), sizeof(data_)); \
31 byte data
[] = { 0xcc, 0xcc, 0xcc };
33 for (uint expect
= 0; expect
< 0xf0; expect
++)
36 uint get
= flow_read_length(data
);
37 bt_assert_msg(get
== expect
, "Testing get length 0x%02x (get 0x%02x)", expect
, get
);
40 for (uint expect
= 0; expect
<= 0xfff; expect
++)
42 put_u16(data
, expect
| 0xf000);
43 uint get
= flow_read_length(data
);
44 bt_assert_msg(get
== expect
, "Testing get length 0x%03x (get 0x%03x)", expect
, get
);
53 byte data
[] = { 0xcc, 0xcc, 0xcc };
55 for (uint expect
= 0; expect
<= 0xfff; expect
++)
57 uint offset
= flow_write_length(data
, expect
);
59 uint set
= (expect
< 0xf0) ? *data
: (get_u16(data
) & 0x0fff);
60 bt_assert_msg(set
== expect
, "Testing set length 0x%03x (set 0x%03x)", expect
, set
);
61 bt_assert(offset
== (expect
< 0xf0 ? 1 : 2));
71 NET_ADDR_FLOW4_(f
, ip4_build(10,0,0,1), 24, ((byte
[]) { 0x00, 0x00, 0xab }));
73 const byte
*under240
= &f
->data
[1];
74 const byte
*above240
= &f
->data
[2];
77 bt_assert(flow4_first_part(f
) == NULL
);
81 bt_assert(flow4_first_part(f
) == under240
);
85 bt_assert(flow4_first_part(f
) == under240
);
89 bt_assert(flow4_first_part(f
) == NULL
);
93 bt_assert(flow4_first_part(f
) == above240
);
98 bt_assert(flow4_first_part(f
) == above240
);
107 NET_ADDR_FLOW4_(f
, ip4_build(5,6,7,0), 24, ((byte
[]) {
109 FLOW_TYPE_DST_PREFIX
, 24, 5, 6, 7,
110 FLOW_TYPE_SRC_PREFIX
, 32, 10, 11, 12, 13,
111 FLOW_TYPE_IP_PROTOCOL
, 0x81, 0x06,
112 FLOW_TYPE_PORT
, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
113 FLOW_TYPE_TCP_FLAGS
, 0x80, 0x55,
116 const byte
*start
= f
->data
;
117 const byte
*p1_dst_pfx
= &f
->data
[1];
118 const byte
*p2_src_pfx
= &f
->data
[6];
119 const byte
*p3_ip_proto
= &f
->data
[12];
120 const byte
*p4_port
= &f
->data
[15];
121 const byte
*p5_tcp_flags
= &f
->data
[23];
122 const byte
*end
= &f
->data
[25];
124 bt_assert(flow_read_length(f
->data
) == (end
-start
));
125 bt_assert(flow4_first_part(f
) == p1_dst_pfx
);
127 bt_assert(flow4_next_part(p1_dst_pfx
, end
) == p2_src_pfx
);
128 bt_assert(flow4_next_part(p2_src_pfx
, end
) == p3_ip_proto
);
129 bt_assert(flow4_next_part(p3_ip_proto
, end
) == p4_port
);
130 bt_assert(flow4_next_part(p4_port
, end
) == p5_tcp_flags
);
131 bt_assert(flow4_next_part(p5_tcp_flags
, end
) == NULL
);
140 NET_ADDR_FLOW6_(f
, ip6_build(0,0,0x12345678,0x9a000000), 64, ((byte
[]) {
142 FLOW_TYPE_DST_PREFIX
, 0x68, 0x40, 0x12, 0x34, 0x56, 0x78, 0x9a,
143 FLOW_TYPE_SRC_PREFIX
, 0x08, 0x0, 0xc0,
144 FLOW_TYPE_NEXT_HEADER
, 0x81, 0x06,
145 FLOW_TYPE_PORT
, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
146 FLOW_TYPE_LABEL
, 0x80, 0x55,
149 const byte
*start
= f
->data
;
150 const byte
*p1_dst_pfx
= &f
->data
[1];
151 const byte
*p2_src_pfx
= &f
->data
[9];
152 const byte
*p3_next_header
= &f
->data
[13];
153 const byte
*p4_port
= &f
->data
[16];
154 const byte
*p5_label
= &f
->data
[24];
155 const byte
*end
= &f
->data
[26];
157 bt_assert(flow_read_length(f
->data
) == (end
-start
));
158 bt_assert(flow6_first_part(f
) == p1_dst_pfx
);
160 bt_assert(flow6_next_part(p1_dst_pfx
, end
) == p2_src_pfx
);
161 bt_assert(flow6_next_part(p2_src_pfx
, end
) == p3_next_header
);
162 bt_assert(flow6_next_part(p3_next_header
, end
) == p4_port
);
163 bt_assert(flow6_next_part(p4_port
, end
) == p5_label
);
164 bt_assert(flow6_next_part(p5_label
, end
) == NULL
);
172 enum flow_validated_state res
;
175 FLOW_TYPE_DST_PREFIX
, 24, 5, 6, 7,
176 FLOW_TYPE_SRC_PREFIX
, 32, 10, 11, 12, 13,
177 FLOW_TYPE_IP_PROTOCOL
, 0x81, 0x06,
178 FLOW_TYPE_PORT
, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
179 FLOW_TYPE_TCP_FLAGS
, 0x80, 0x55,
182 /* Isn't included destination prefix */
183 res
= flow4_validate(nlri1
, 0);
184 bt_assert(res
== FLOW_ST_DEST_PREFIX_REQUIRED
);
185 res
= flow4_validate(&nlri1
[5], sizeof(nlri1
)-5);
186 bt_assert(res
== FLOW_ST_DEST_PREFIX_REQUIRED
);
188 /* Valid / Not Complete testing */
189 uint valid_sizes
[] = {5, 11, 14, 22, 25, 0};
191 for (uint size
= 1; size
<= sizeof(nlri1
); size
++)
193 res
= flow4_validate(nlri1
, size
);
194 bt_debug("size %u, result: %s\n", size
, flow_validated_state_str(res
));
195 if (size
== valid_sizes
[valid_idx
])
198 bt_assert(res
== FLOW_ST_VALID
);
202 bt_assert(res
== FLOW_ST_NOT_COMPLETE
);
209 enum flow_validated_state expect
;
215 #define TS(type, msg, data) ((struct tset) {type, msg, sizeof(data), (data)})
216 struct tset tset
[] = {
218 FLOW_ST_EXCEED_MAX_PREFIX_LENGTH
,
219 "33-length IPv4 prefix",
221 FLOW_TYPE_DST_PREFIX
, 33, 5, 6, 7, 8, 9
225 FLOW_ST_BAD_TYPE_ORDER
,
226 "Bad flowspec component type order",
228 FLOW_TYPE_SRC_PREFIX
, 32, 10, 11, 12, 13,
229 FLOW_TYPE_DST_PREFIX
, 24, 5, 6, 7,
233 FLOW_ST_BAD_TYPE_ORDER
,
234 "Doubled destination prefix component",
236 FLOW_TYPE_DST_PREFIX
, 24, 5, 6, 7,
237 FLOW_TYPE_DST_PREFIX
, 24, 5, 6, 7,
241 FLOW_ST_AND_BIT_SHOULD_BE_UNSET
,
242 "The first numeric operator has set the AND bit",
244 FLOW_TYPE_PORT
, 0x43, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
248 FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED
,
249 "Set zero bit in operand to one",
251 FLOW_TYPE_IP_PROTOCOL
, 0x89, 0x06,
255 FLOW_ST_UNKNOWN_COMPONENT
,
256 "Unknown component of type number 13",
258 FLOW_TYPE_DST_PREFIX
, 24, 5, 6, 7,
259 FLOW_TYPE_TCP_FLAGS
, 0x80, 0x55,
260 13 /*something new*/, 0x80, 0x55,
266 for (uint tcase
= 0; tcase
< ARRAY_SIZE(tset
); tcase
++)
268 res
= flow4_validate(tset
[tcase
].nlri
, tset
[tcase
].size
);
269 bt_assert_msg(res
== tset
[tcase
].expect
, "Assertion (%s == %s) %s", flow_validated_state_str(res
), flow_validated_state_str(tset
[tcase
].expect
), tset
[tcase
].description
);
278 enum flow_validated_state res
;
281 FLOW_TYPE_DST_PREFIX
, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
282 FLOW_TYPE_SRC_PREFIX
, 8, 0, 0xc0,
283 FLOW_TYPE_NEXT_HEADER
, 0x81, 0x06,
284 FLOW_TYPE_PORT
, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
285 FLOW_TYPE_LABEL
, 0x80, 0x55,
288 /* Isn't included destination prefix */
289 res
= flow6_validate(nlri1
, 0);
290 bt_assert(res
== FLOW_ST_VALID
);
292 /* Valid / Not Complete testing */
293 uint valid_sizes
[] = {0, 9, 13, 16, 24, 27, 0};
295 for (uint size
= 0; size
<= sizeof(nlri1
); size
++)
297 res
= flow6_validate(nlri1
, size
);
298 bt_debug("size %u, result: %s\n", size
, flow_validated_state_str(res
));
299 if (size
== valid_sizes
[valid_idx
])
302 bt_assert(res
== FLOW_ST_VALID
);
306 bt_assert(res
== FLOW_ST_NOT_COMPLETE
);
313 enum flow_validated_state expect
;
319 #define TS(type, msg, data) ((struct tset) {type, msg, sizeof(data), (data)})
320 struct tset tset
[] = {
322 FLOW_ST_EXCEED_MAX_PREFIX_LENGTH
,
323 "129-length IPv6 prefix",
325 FLOW_TYPE_DST_PREFIX
, 129, 64, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
329 FLOW_ST_EXCEED_MAX_PREFIX_OFFSET
,
330 "Prefix offset is higher than prefix length",
332 FLOW_TYPE_DST_PREFIX
, 48, 64, 0x40, 0x12, 0x34
336 FLOW_ST_BAD_TYPE_ORDER
,
337 "Bad flowspec component type order",
339 FLOW_TYPE_NEXT_HEADER
, 0x81, 0x06,
340 FLOW_TYPE_SRC_PREFIX
, 8, 0, 0xc0,
344 FLOW_ST_BAD_TYPE_ORDER
,
345 "Doubled destination prefix component",
347 FLOW_TYPE_DST_PREFIX
, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
348 FLOW_TYPE_DST_PREFIX
, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
352 FLOW_ST_AND_BIT_SHOULD_BE_UNSET
,
353 "The first numeric operator has set the AND bit",
355 FLOW_TYPE_PORT
, 0x43, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90
359 FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED
,
360 "Set zero bit in operand to one",
362 FLOW_TYPE_NEXT_HEADER
, 0x89, 0x06
367 "Component of type number 13 (Label) is well-known in IPv6",
369 FLOW_TYPE_LABEL
, 0x80, 0x55
373 FLOW_ST_UNKNOWN_COMPONENT
,
374 "Unknown component of type number 14",
376 FLOW_TYPE_LABEL
, 0x80, 0x55,
377 14 /*something new*/, 0x80, 0x55,
383 for (uint tcase
= 0; tcase
< ARRAY_SIZE(tset
); tcase
++)
385 res
= flow6_validate(tset
[tcase
].nlri
, tset
[tcase
].size
);
386 bt_assert_msg(res
== tset
[tcase
].expect
, "Assertion (%s == %s) %s", flow_validated_state_str(res
), flow_validated_state_str(tset
[tcase
].expect
), tset
[tcase
].description
);
403 struct flow_builder
*fb
= flow_builder_init(&root_pool
);
404 linpool
*lp
= lp_new_default(&root_pool
);
408 static byte nlri
[] = {
410 FLOW_TYPE_DST_PREFIX
, 24, 5, 6, 7,
411 FLOW_TYPE_SRC_PREFIX
, 32, 10, 11, 12, 13,
412 FLOW_TYPE_IP_PROTOCOL
, 0x80, 0x06,
413 FLOW_TYPE_PORT
, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
414 FLOW_TYPE_TCP_FLAGS
, 0x80, 0x55
417 net_addr_flow4
*expect
;
418 NET_ADDR_FLOW4_(expect
, ip4_build(5, 6, 7, 0), 24, nlri
);
423 net_fill_ip4((net_addr
*) &n1
, ip4_build(5,6,7,0), 24);
424 flow_builder_set_type(fb
, FLOW_TYPE_DST_PREFIX
);
425 flow_builder4_add_pfx(fb
, &n1
);
428 net_fill_ip4((net_addr
*) &n2
, ip4_build(10,11,12,13), 32);
429 flow_builder_set_type(fb
, FLOW_TYPE_SRC_PREFIX
);
430 flow_builder4_add_pfx(fb
, &n2
);
432 flow_builder_set_type(fb
, FLOW_TYPE_IP_PROTOCOL
);
433 flow_builder_add_op_val(fb
, 0, 0x06);
435 flow_builder_set_type(fb
, FLOW_TYPE_PORT
);
436 flow_builder_add_op_val(fb
, 0x03, 0x89);
437 flow_builder_add_op_val(fb
, 0x45, 0x8b);
438 flow_builder_add_op_val(fb
, 0x01, 0x1f90);
440 /* Try put a component twice time */
441 flow_builder_set_type(fb
, FLOW_TYPE_IP_PROTOCOL
);
442 flow_builder_add_op_val(fb
, 0, 0x06);
444 flow_builder_set_type(fb
, FLOW_TYPE_TCP_FLAGS
);
445 flow_builder_add_op_val(fb
, 0, 0x55);
447 net_addr_flow4
*res
= flow_builder4_finalize(fb
, lp
);
449 bt_assert(memcmp(res
, expect
, expect
->length
) == 0);
453 flow_builder_clear(fb
);
455 flow_builder_set_type(fb
, FLOW_TYPE_TCP_FLAGS
);
456 flow_builder_add_op_val(fb
, 0, 0x55);
458 flow_builder_set_type(fb
, FLOW_TYPE_PORT
);
459 flow_builder_add_op_val(fb
, 0x03, 0x89);
460 flow_builder_add_op_val(fb
, 0x45, 0x8b);
461 flow_builder_add_op_val(fb
, 0x01, 0x1f90);
463 flow_builder_set_type(fb
, FLOW_TYPE_IP_PROTOCOL
);
464 flow_builder_add_op_val(fb
, 0, 0x06);
466 net_fill_ip4((net_addr
*) &n2
, ip4_build(10,11,12,13), 32);
467 flow_builder_set_type(fb
, FLOW_TYPE_SRC_PREFIX
);
468 flow_builder4_add_pfx(fb
, &n2
);
470 net_fill_ip4((net_addr
*) &n1
, ip4_build(5,6,7,0), 24);
471 flow_builder_set_type(fb
, FLOW_TYPE_DST_PREFIX
);
472 flow_builder4_add_pfx(fb
, &n1
);
474 bt_assert(memcmp(res
, expect
, expect
->length
) == 0);
485 linpool
*lp
= lp_new_default(&root_pool
);
486 struct flow_builder
*fb
= flow_builder_init(&root_pool
);
493 FLOW_TYPE_DST_PREFIX
, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
494 FLOW_TYPE_SRC_PREFIX
, 8, 0, 0xc0,
495 FLOW_TYPE_NEXT_HEADER
, 0x80, 0x06,
496 FLOW_TYPE_PORT
, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
497 FLOW_TYPE_LABEL
, 0x80, 0x55,
500 net_addr_flow6
*expect
;
501 NET_ADDR_FLOW6_(expect
, ip6_build(0, 1, 0x12345678, 0x98000000), 103, nlri
);
505 net_fill_ip6((net_addr
*) &ip
, ip6_build(0, 1, 0x12345678, 0x98000000), 103);
506 flow_builder_set_type(fb
, FLOW_TYPE_DST_PREFIX
);
507 flow_builder6_add_pfx(fb
, &ip
, 61);
509 /* Try put a component twice time */
510 net_fill_ip6((net_addr
*) &ip
, ip6_build(0, 1, 0x12345678, 0x98000000), 103);
511 flow_builder_set_type(fb
, FLOW_TYPE_DST_PREFIX
);
512 bt_assert(flow_builder6_add_pfx(fb
, &ip
, 61) == 0);
514 net_fill_ip6((net_addr
*) &ip
, ip6_build(0xc0000000,0,0,0), 8);
515 flow_builder_set_type(fb
, FLOW_TYPE_SRC_PREFIX
);
516 flow_builder6_add_pfx(fb
, &ip
, 0);
518 flow_builder_set_type(fb
, FLOW_TYPE_NEXT_HEADER
);
519 flow_builder_add_op_val(fb
, 0, 0x06);
521 flow_builder_set_type(fb
, FLOW_TYPE_PORT
);
522 flow_builder_add_op_val(fb
, 0x03, 0x89);
523 flow_builder_add_op_val(fb
, 0x45, 0x8b);
524 flow_builder_add_op_val(fb
, 0x01, 0x1f90);
526 flow_builder_set_type(fb
, FLOW_TYPE_LABEL
);
527 flow_builder_add_op_val(fb
, 0, 0x55);
529 net_addr_flow6
*res
= flow_builder6_finalize(fb
, lp
);
530 bt_assert(memcmp(res
, expect
, expect
->length
) == 0);
534 flow_builder_clear(fb
);
537 flow_builder_set_type(fb
, FLOW_TYPE_LABEL
);
538 flow_builder_add_op_val(fb
, 0, 0x55);
540 flow_builder_set_type(fb
, FLOW_TYPE_PORT
);
541 flow_builder_add_op_val(fb
, 0x03, 0x89);
542 flow_builder_add_op_val(fb
, 0x45, 0x8b);
543 flow_builder_add_op_val(fb
, 0x01, 0x1f90);
545 flow_builder_set_type(fb
, FLOW_TYPE_NEXT_HEADER
);
546 flow_builder_add_op_val(fb
, 0, 0x06);
548 net_fill_ip6((net_addr
*) &ip
, ip6_build(0xc0000000,0,0,0), 8);
549 flow_builder_set_type(fb
, FLOW_TYPE_SRC_PREFIX
);
550 flow_builder6_add_pfx(fb
, &ip
, 0);
552 net_fill_ip6((net_addr
*) &ip
, ip6_build(0, 1, 0x12345678, 0x98000000), 103);
553 flow_builder_set_type(fb
, FLOW_TYPE_DST_PREFIX
);
554 flow_builder6_add_pfx(fb
, &ip
, 61);
556 res
= flow_builder6_finalize(fb
, lp
);
557 bt_assert(memcmp(res
, expect
, expect
->length
) == 0);
569 FLOW_TYPE_DST_PREFIX
, 0x08, 10,
570 FLOW_TYPE_IP_PROTOCOL
, 0x81, 23,
571 FLOW_TYPE_DST_PORT
, 0x02, 24, 0x44, 30, 0x03, 40, 0x45, 50, 0x03, 60, 0x45, 70, 0x01, 80, 0xc3, 90,
572 FLOW_TYPE_SRC_PORT
, 0x02, 24, 0x44, 0x1e, 0x01, 0x28, 0x01, 0x32, 0x03, 0x3c, 0x45, 0x46, 0x81, 0x50,
573 FLOW_TYPE_ICMP_TYPE
, 0x81, 0x50,
574 FLOW_TYPE_ICMP_CODE
, 0x81, 0x5a,
575 FLOW_TYPE_TCP_FLAGS
, 0x01, 0x03, 0xc2, 0x0c,
576 FLOW_TYPE_PACKET_LENGTH
, 0x03, 0, 0xd5, 0xff, 0xff,
577 FLOW_TYPE_DSCP
, 0x81, 63,
578 FLOW_TYPE_FRAGMENT
, 0x01, 0x01, 0x82, 0x02
580 *nlri
= (u8
) sizeof(nlri
);
582 net_addr_flow4
*input
;
583 NET_ADDR_FLOW4_(input
, ip4_build(5, 6, 7, 0), 24, nlri
);
585 const char *expect
= "flow4 { dst 10.0.0.0/8; proto 23; dport > 24 && < 30 || 40..50,60..70,80 && >= 90; sport > 24 && < 30 || 40,50,60..70,80; icmp type 80; icmp code 90; tcp flags 0x3/0x3,0x0/0xc; length 0..65535; dscp 63; fragment dont_fragment || !is_fragment; }";
587 bt_assert(flow4_net_format(b
, sizeof(b
), input
) == strlen(expect
));
588 bt_debug(" expect: '%s',\n output: '%s'\n", expect
, b
);
589 bt_assert(strcmp(b
, expect
) == 0);
601 FLOW_TYPE_DST_PREFIX
, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
602 FLOW_TYPE_SRC_PREFIX
, 8, 0, 0xc0,
603 FLOW_TYPE_NEXT_HEADER
, 0x81, 0x06,
604 FLOW_TYPE_PORT
, 0x03, 20, 0x45, 40, 0x91, 0x01, 0x11,
605 FLOW_TYPE_LABEL
, 0xa0, 0x12, 0x34, 0x56, 0x78,
607 *nlri
= (u8
) sizeof(nlri
);
609 net_addr_flow6
*input
;
610 NET_ADDR_FLOW6_(input
, ip6_build(0, 1, 0x12345678, 0x98000000), 103, nlri
);
612 const char *expect
= "flow6 { dst ::1:1234:5678:9800:0/103 offset 61; src c000::/8; next header 6; port 20..40,273; label !0x0/0x12345678; }";
614 bt_assert(flow6_net_format(b
, sizeof(b
), input
) == strlen(expect
));
615 bt_debug(" expect: '%s',\n output: '%s'\n", expect
, b
);
616 bt_assert(strcmp(b
, expect
) == 0);
622 main(int argc
, char *argv
[])
626 bt_test_suite(t_read_length
, "Testing get NLRI length");
627 bt_test_suite(t_write_length
, "Testing set NLRI length");
628 bt_test_suite(t_first_part
, "Searching first part in net_addr_flow");
629 bt_test_suite(t_iterators4
, "Testing iterators (IPv4)");
630 bt_test_suite(t_iterators6
, "Testing iterators (IPv6)");
631 bt_test_suite(t_validation4
, "Testing validation (IPv4)");
632 bt_test_suite(t_validation6
, "Testing validation (IPv6)");
633 bt_test_suite(t_builder4
, "Inserting components into existing Flow Specification (IPv4)");
634 bt_test_suite(t_builder6
, "Inserting components into existing Flow Specification (IPv6)");
635 bt_test_suite(t_formatting4
, "Formatting Flow Specification (IPv4) into text representation");
636 bt_test_suite(t_formatting6
, "Formatting Flow Specification (IPv6) into text representation");
638 return bt_exit_value();