]> git.ipfire.org Git - thirdparty/bird.git/blob - lib/flowspec_test.c
OSPF: Support for graceful restart
[thirdparty/bird.git] / lib / flowspec_test.c
1 /*
2 * BIRD Library -- Flow specification (RFC 5575) Tests
3 *
4 * (c) 2016 CZ.NIC z.s.p.o.
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9 #include "test/birdtest.h"
10 #include "lib/flowspec.h"
11
12 #define NET_ADDR_FLOW4_(what,prefix,pxlen,data_) \
13 do \
14 { \
15 what = alloca(sizeof(net_addr_flow4) + 128); \
16 *what = NET_ADDR_FLOW4(prefix, pxlen, sizeof(data_)); \
17 memcpy(what->data, &(data_), sizeof(data_)); \
18 } while(0)
19
20 #define NET_ADDR_FLOW6_(what,prefix,pxlen,data_) \
21 do \
22 { \
23 what = alloca(sizeof(net_addr_flow6) + 128); \
24 *what = NET_ADDR_FLOW6(prefix, pxlen, sizeof(data_)); \
25 memcpy(what->data, &(data_), sizeof(data_)); \
26 } while(0)
27
28 static int
29 t_read_length(void)
30 {
31 byte data[] = { 0xcc, 0xcc, 0xcc };
32
33 for (uint expect = 0; expect < 0xf0; expect++)
34 {
35 *data = expect;
36 uint get = flow_read_length(data);
37 bt_assert_msg(get == expect, "Testing get length 0x%02x (get 0x%02x)", expect, get);
38 }
39
40 for (uint expect = 0; expect <= 0xfff; expect++)
41 {
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);
45 }
46
47 return 1;
48 }
49
50 static int
51 t_write_length(void)
52 {
53 byte data[] = { 0xcc, 0xcc, 0xcc };
54
55 for (uint expect = 0; expect <= 0xfff; expect++)
56 {
57 uint offset = flow_write_length(data, expect);
58
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));
62 }
63
64 return 1;
65 }
66
67 static int
68 t_first_part(void)
69 {
70 net_addr_flow4 *f;
71 NET_ADDR_FLOW4_(f, ip4_build(10,0,0,1), 24, ((byte[]) { 0x00, 0x00, 0xab }));
72
73 const byte *under240 = &f->data[1];
74 const byte *above240 = &f->data[2];
75
76 /* Case 0x00 0x00 */
77 bt_assert(flow4_first_part(f) == NULL);
78
79 /* Case 0x01 0x00 */
80 f->data[0] = 0x01;
81 bt_assert(flow4_first_part(f) == under240);
82
83 /* Case 0xef 0x00 */
84 f->data[0] = 0xef;
85 bt_assert(flow4_first_part(f) == under240);
86
87 /* Case 0xf0 0x00 */
88 f->data[0] = 0xf0;
89 bt_assert(flow4_first_part(f) == NULL);
90
91 /* Case 0xf0 0x01 */
92 f->data[1] = 0x01;
93 bt_assert(flow4_first_part(f) == above240);
94
95 /* Case 0xff 0xff */
96 f->data[0] = 0xff;
97 f->data[1] = 0xff;
98 bt_assert(flow4_first_part(f) == above240);
99
100 return 1;
101 }
102
103 static int
104 t_iterators4(void)
105 {
106 net_addr_flow4 *f;
107 NET_ADDR_FLOW4_(f, ip4_build(5,6,7,0), 24, ((byte[]) {
108 25, /* Length */
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,
114 }));
115
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];
123
124 bt_assert(flow_read_length(f->data) == (end-start));
125 bt_assert(flow4_first_part(f) == p1_dst_pfx);
126
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);
132
133 return 1;
134 }
135
136 static int
137 t_iterators6(void)
138 {
139 net_addr_flow6 *f;
140 NET_ADDR_FLOW6_(f, ip6_build(0,0,0x12345678,0x9a000000), 64, ((byte[]) {
141 26, /* Length */
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,
147 }));
148
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];
156
157 bt_assert(flow_read_length(f->data) == (end-start));
158 bt_assert(flow6_first_part(f) == p1_dst_pfx);
159
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);
165
166 return 1;
167 }
168
169 static int
170 t_validation4(void)
171 {
172 enum flow_validated_state res;
173
174 byte nlri1[] = {
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,
180 };
181
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);
187
188 /* Valid / Not Complete testing */
189 uint valid_sizes[] = {5, 11, 14, 22, 25, 0};
190 uint valid_idx = 0;
191 for (uint size = 1; size <= sizeof(nlri1); size++)
192 {
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])
196 {
197 valid_idx++;
198 bt_assert(res == FLOW_ST_VALID);
199 }
200 else
201 {
202 bt_assert(res == FLOW_ST_NOT_COMPLETE);
203 }
204 }
205
206 /* Misc err tests */
207
208 struct tset {
209 enum flow_validated_state expect;
210 char *description;
211 u16 size;
212 byte *nlri;
213 };
214
215 #define TS(type, msg, data) ((struct tset) {type, msg, sizeof(data), (data)})
216 struct tset tset[] = {
217 TS(
218 FLOW_ST_EXCEED_MAX_PREFIX_LENGTH,
219 "33-length IPv4 prefix",
220 ((byte []) {
221 FLOW_TYPE_DST_PREFIX, 33, 5, 6, 7, 8, 9
222 })
223 ),
224 TS(
225 FLOW_ST_BAD_TYPE_ORDER,
226 "Bad flowspec component type order",
227 ((byte []) {
228 FLOW_TYPE_SRC_PREFIX, 32, 10, 11, 12, 13,
229 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
230 })
231 ),
232 TS(
233 FLOW_ST_BAD_TYPE_ORDER,
234 "Doubled destination prefix component",
235 ((byte []) {
236 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
237 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
238 })
239 ),
240 TS(
241 FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
242 "The first numeric operator has set the AND bit",
243 ((byte []) {
244 FLOW_TYPE_PORT, 0x43, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
245 })
246 ),
247 TS(
248 FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
249 "Set zero bit in operand to one",
250 ((byte []) {
251 FLOW_TYPE_IP_PROTOCOL, 0x89, 0x06,
252 })
253 ),
254 TS(
255 FLOW_ST_UNKNOWN_COMPONENT,
256 "Unknown component of type number 13",
257 ((byte []) {
258 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
259 FLOW_TYPE_TCP_FLAGS, 0x80, 0x55,
260 13 /*something new*/, 0x80, 0x55,
261 })
262 ),
263 };
264 #undef TS
265
266 for (uint tcase = 0; tcase < ARRAY_SIZE(tset); tcase++)
267 {
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);
270 }
271
272 return 1;
273 }
274
275 static int
276 t_validation6(void)
277 {
278 enum flow_validated_state res;
279
280 byte nlri1[] = {
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,
286 };
287
288 /* Isn't included destination prefix */
289 res = flow6_validate(nlri1, 0);
290 bt_assert(res == FLOW_ST_VALID);
291
292 /* Valid / Not Complete testing */
293 uint valid_sizes[] = {0, 9, 13, 16, 24, 27, 0};
294 uint valid_idx = 0;
295 for (uint size = 0; size <= sizeof(nlri1); size++)
296 {
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])
300 {
301 valid_idx++;
302 bt_assert(res == FLOW_ST_VALID);
303 }
304 else
305 {
306 bt_assert(res == FLOW_ST_NOT_COMPLETE);
307 }
308 }
309
310 /* Misc err tests */
311
312 struct tset {
313 enum flow_validated_state expect;
314 char *description;
315 u16 size;
316 byte *nlri;
317 };
318
319 #define TS(type, msg, data) ((struct tset) {type, msg, sizeof(data), (data)})
320 struct tset tset[] = {
321 TS(
322 FLOW_ST_EXCEED_MAX_PREFIX_LENGTH,
323 "129-length IPv6 prefix",
324 ((byte []) {
325 FLOW_TYPE_DST_PREFIX, 129, 64, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
326 })
327 ),
328 TS(
329 FLOW_ST_EXCEED_MAX_PREFIX_OFFSET,
330 "Prefix offset is higher than prefix length",
331 ((byte []) {
332 FLOW_TYPE_DST_PREFIX, 48, 64, 0x40, 0x12, 0x34
333 })
334 ),
335 TS(
336 FLOW_ST_BAD_TYPE_ORDER,
337 "Bad flowspec component type order",
338 ((byte []) {
339 FLOW_TYPE_NEXT_HEADER, 0x81, 0x06,
340 FLOW_TYPE_SRC_PREFIX, 8, 0, 0xc0,
341 })
342 ),
343 TS(
344 FLOW_ST_BAD_TYPE_ORDER,
345 "Doubled destination prefix component",
346 ((byte []) {
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,
349 })
350 ),
351 TS(
352 FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
353 "The first numeric operator has set the AND bit",
354 ((byte []) {
355 FLOW_TYPE_PORT, 0x43, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90
356 })
357 ),
358 TS(
359 FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
360 "Set zero bit in operand to one",
361 ((byte []) {
362 FLOW_TYPE_NEXT_HEADER, 0x89, 0x06
363 })
364 ),
365 TS(
366 FLOW_ST_VALID,
367 "Component of type number 13 (Label) is well-known in IPv6",
368 ((byte []) {
369 FLOW_TYPE_LABEL, 0x80, 0x55
370 })
371 ),
372 TS(
373 FLOW_ST_UNKNOWN_COMPONENT,
374 "Unknown component of type number 14",
375 ((byte []) {
376 FLOW_TYPE_LABEL, 0x80, 0x55,
377 14 /*something new*/, 0x80, 0x55,
378 })
379 )
380 };
381 #undef TS
382
383 for (uint tcase = 0; tcase < ARRAY_SIZE(tset); tcase++)
384 {
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);
387 }
388
389 return 1;
390 }
391
392
393
394 /*
395 * Builder tests
396 */
397
398 static int
399 t_builder4(void)
400 {
401 resource_init();
402
403 struct flow_builder *fb = flow_builder_init(&root_pool);
404 linpool *lp = lp_new_default(&root_pool);
405
406 /* Expectation */
407
408 static byte nlri[] = {
409 25,
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
415 };
416
417 net_addr_flow4 *expect;
418 NET_ADDR_FLOW4_(expect, ip4_build(5, 6, 7, 0), 24, nlri);
419
420 /* Normal order */
421
422 net_addr_ip4 n1;
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);
426
427 net_addr_ip4 n2;
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);
431
432 flow_builder_set_type(fb, FLOW_TYPE_IP_PROTOCOL);
433 flow_builder_add_op_val(fb, 0, 0x06);
434
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);
439
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);
443
444 flow_builder_set_type(fb, FLOW_TYPE_TCP_FLAGS);
445 flow_builder_add_op_val(fb, 0, 0x55);
446
447 net_addr_flow4 *res = flow_builder4_finalize(fb, lp);
448
449 bt_assert(memcmp(res, expect, expect->length) == 0);
450
451 /* Reverse order */
452
453 flow_builder_clear(fb);
454
455 flow_builder_set_type(fb, FLOW_TYPE_TCP_FLAGS);
456 flow_builder_add_op_val(fb, 0, 0x55);
457
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);
462
463 flow_builder_set_type(fb, FLOW_TYPE_IP_PROTOCOL);
464 flow_builder_add_op_val(fb, 0, 0x06);
465
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);
469
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);
473
474 bt_assert(memcmp(res, expect, expect->length) == 0);
475
476 return 1;
477 }
478
479 static int
480 t_builder6(void)
481 {
482 net_addr_ip6 ip;
483
484 resource_init();
485 linpool *lp = lp_new_default(&root_pool);
486 struct flow_builder *fb = flow_builder_init(&root_pool);
487 fb->ipv6 = 1;
488
489 /* Expectation */
490
491 byte nlri[] = {
492 27,
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,
498 };
499
500 net_addr_flow6 *expect;
501 NET_ADDR_FLOW6_(expect, ip6_build(0, 1, 0x12345678, 0x98000000), 103, nlri);
502
503 /* Normal order */
504
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);
508
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);
513
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);
517
518 flow_builder_set_type(fb, FLOW_TYPE_NEXT_HEADER);
519 flow_builder_add_op_val(fb, 0, 0x06);
520
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);
525
526 flow_builder_set_type(fb, FLOW_TYPE_LABEL);
527 flow_builder_add_op_val(fb, 0, 0x55);
528
529 net_addr_flow6 *res = flow_builder6_finalize(fb, lp);
530 bt_assert(memcmp(res, expect, expect->length) == 0);
531
532 /* Reverse order */
533
534 flow_builder_clear(fb);
535 fb->ipv6 = 1;
536
537 flow_builder_set_type(fb, FLOW_TYPE_LABEL);
538 flow_builder_add_op_val(fb, 0, 0x55);
539
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);
544
545 flow_builder_set_type(fb, FLOW_TYPE_NEXT_HEADER);
546 flow_builder_add_op_val(fb, 0, 0x06);
547
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);
551
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);
555
556 res = flow_builder6_finalize(fb, lp);
557 bt_assert(memcmp(res, expect, expect->length) == 0);
558
559 return 1;
560 }
561
562 static int
563 t_formatting4(void)
564 {
565 char b[1024];
566
567 byte nlri[] = {
568 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
579 };
580 *nlri = (u8) sizeof(nlri);
581
582 net_addr_flow4 *input;
583 NET_ADDR_FLOW4_(input, ip4_build(5, 6, 7, 0), 24, nlri);
584
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; }";
586
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);
590
591 return 1;
592 }
593
594 static int
595 t_formatting6(void)
596 {
597 char b[1024];
598
599 byte nlri[] = {
600 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,
606 };
607 *nlri = (u8) sizeof(nlri);
608
609 net_addr_flow6 *input;
610 NET_ADDR_FLOW6_(input, ip6_build(0, 1, 0x12345678, 0x98000000), 103, nlri);
611
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; }";
613
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);
617
618 return 1;
619 }
620
621 int
622 main(int argc, char *argv[])
623 {
624 bt_init(argc, argv);
625
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");
637
638 return bt_exit_value();
639 }