]> git.ipfire.org Git - thirdparty/bird.git/blob - lib/flowspec_test.c
Filter: Fix function comparison
[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), 0x68, ((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_accessors4(void)
171 {
172 net_addr_flow4 *f;
173 NET_ADDR_FLOW4_(f, ip4_build(5,6,7,0), 24, ((byte[]) {
174 25, /* Length */
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 const byte *p1_dst_px = &f->data[1];
183 const ip4_addr p1_dst_addr = ip4_build(5,6,7,0);
184
185 const byte *p2_src_px = &f->data[6];
186 const ip4_addr p2_src_addr = ip4_build(10,11,12,13);
187
188 bt_assert(ip4_equal(flow_read_ip4_part(p1_dst_px), p1_dst_addr));
189 bt_assert(ip4_equal(flow_read_ip4_part(p2_src_px), p2_src_addr));
190
191 return 1;
192 }
193
194 static int
195 t_accessors6(void)
196 {
197 net_addr_flow6 *f;
198 NET_ADDR_FLOW6_(f, ip6_build(0,0,0x12345678,0x9a000000), 0x68, ((byte[]) {
199 26, /* Length */
200 FLOW_TYPE_DST_PREFIX, 0x68, 0x40, 0x12, 0x34, 0x56, 0x78, 0x9a,
201 FLOW_TYPE_SRC_PREFIX, 0x08, 0x0, 0xc0,
202 FLOW_TYPE_NEXT_HEADER, 0x81, 0x06,
203 FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
204 FLOW_TYPE_LABEL, 0x80, 0x55,
205 }));
206
207 const byte *p1_dst_px = &f->data[1];
208 const ip6_addr p1_dst_addr = ip6_build(0,0,0x12345678,0x9a000000);
209
210 const byte *p2_src_px = &f->data[9];
211 const ip6_addr p2_src_addr = ip6_build(0xc0000000, 0, 0, 0);
212
213 bt_assert(ip6_equal(flow_read_ip6_part(p1_dst_px), p1_dst_addr));
214 bt_assert(ip6_equal(flow_read_ip6_part(p2_src_px), p2_src_addr));
215
216 return 1;
217 }
218
219 static int
220 t_validation4(void)
221 {
222 enum flow_validated_state res;
223
224 byte nlri1[] = {
225 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
226 FLOW_TYPE_SRC_PREFIX, 32, 10, 11, 12, 13,
227 FLOW_TYPE_IP_PROTOCOL, 0x81, 0x06,
228 FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
229 FLOW_TYPE_TCP_FLAGS, 0x80, 0x55,
230 };
231
232 /* Isn't included destination prefix */
233 res = flow4_validate(nlri1, 0);
234 bt_assert(res == FLOW_ST_DEST_PREFIX_REQUIRED);
235 res = flow4_validate(&nlri1[5], sizeof(nlri1)-5);
236 bt_assert(res == FLOW_ST_DEST_PREFIX_REQUIRED);
237
238 /* Valid / Not Complete testing */
239 uint valid_sizes[] = {5, 11, 14, 22, 25, 0};
240 uint valid_idx = 0;
241 for (uint size = 1; size <= sizeof(nlri1); size++)
242 {
243 res = flow4_validate(nlri1, size);
244 bt_debug("size %u, result: %s\n", size, flow_validated_state_str(res));
245 if (size == valid_sizes[valid_idx])
246 {
247 valid_idx++;
248 bt_assert(res == FLOW_ST_VALID);
249 }
250 else
251 {
252 bt_assert(res == FLOW_ST_NOT_COMPLETE);
253 }
254 }
255
256 /* Misc err tests */
257
258 struct tset {
259 enum flow_validated_state expect;
260 char *description;
261 u16 size;
262 byte *nlri;
263 };
264
265 #define TS(type, msg, data) ((struct tset) {type, msg, sizeof(data), (data)})
266 struct tset tset[] = {
267 TS(
268 FLOW_ST_EXCEED_MAX_PREFIX_LENGTH,
269 "33-length IPv4 prefix",
270 ((byte []) {
271 FLOW_TYPE_DST_PREFIX, 33, 5, 6, 7, 8, 9
272 })
273 ),
274 TS(
275 FLOW_ST_BAD_TYPE_ORDER,
276 "Bad flowspec component type order",
277 ((byte []) {
278 FLOW_TYPE_SRC_PREFIX, 32, 10, 11, 12, 13,
279 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
280 })
281 ),
282 TS(
283 FLOW_ST_BAD_TYPE_ORDER,
284 "Doubled destination prefix component",
285 ((byte []) {
286 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
287 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
288 })
289 ),
290 TS(
291 FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
292 "The first numeric operator has set the AND bit",
293 ((byte []) {
294 FLOW_TYPE_PORT, 0x43, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
295 })
296 ),
297 TS(
298 FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
299 "Set zero bit in operand to one",
300 ((byte []) {
301 FLOW_TYPE_IP_PROTOCOL, 0x89, 0x06,
302 })
303 ),
304 TS(
305 FLOW_ST_UNKNOWN_COMPONENT,
306 "Unknown component of type number 13",
307 ((byte []) {
308 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
309 FLOW_TYPE_TCP_FLAGS, 0x80, 0x55,
310 13 /*something new*/, 0x80, 0x55,
311 })
312 ),
313 };
314 #undef TS
315
316 for (uint tcase = 0; tcase < ARRAY_SIZE(tset); tcase++)
317 {
318 res = flow4_validate(tset[tcase].nlri, tset[tcase].size);
319 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);
320 }
321
322 return 1;
323 }
324
325 static int
326 t_validation6(void)
327 {
328 enum flow_validated_state res;
329
330 byte nlri1[] = {
331 FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
332 FLOW_TYPE_SRC_PREFIX, 8, 0, 0xc0,
333 FLOW_TYPE_NEXT_HEADER, 0x81, 0x06,
334 FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
335 FLOW_TYPE_LABEL, 0x80, 0x55,
336 };
337
338 /* Isn't included destination prefix */
339 res = flow6_validate(nlri1, 0);
340 bt_assert(res == FLOW_ST_VALID);
341
342 /* Valid / Not Complete testing */
343 uint valid_sizes[] = {0, 9, 13, 16, 24, 27, 0};
344 uint valid_idx = 0;
345 for (uint size = 0; size <= sizeof(nlri1); size++)
346 {
347 res = flow6_validate(nlri1, size);
348 bt_debug("size %u, result: %s\n", size, flow_validated_state_str(res));
349 if (size == valid_sizes[valid_idx])
350 {
351 valid_idx++;
352 bt_assert(res == FLOW_ST_VALID);
353 }
354 else
355 {
356 bt_assert(res == FLOW_ST_NOT_COMPLETE);
357 }
358 }
359
360 /* Misc err tests */
361
362 struct tset {
363 enum flow_validated_state expect;
364 char *description;
365 u16 size;
366 byte *nlri;
367 };
368
369 #define TS(type, msg, data) ((struct tset) {type, msg, sizeof(data), (data)})
370 struct tset tset[] = {
371 TS(
372 FLOW_ST_EXCEED_MAX_PREFIX_LENGTH,
373 "129-length IPv6 prefix",
374 ((byte []) {
375 FLOW_TYPE_DST_PREFIX, 129, 64, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
376 })
377 ),
378 TS(
379 FLOW_ST_EXCEED_MAX_PREFIX_OFFSET,
380 "Prefix offset is higher than prefix length",
381 ((byte []) {
382 FLOW_TYPE_DST_PREFIX, 48, 64, 0x40, 0x12, 0x34
383 })
384 ),
385 TS(
386 FLOW_ST_BAD_TYPE_ORDER,
387 "Bad flowspec component type order",
388 ((byte []) {
389 FLOW_TYPE_NEXT_HEADER, 0x81, 0x06,
390 FLOW_TYPE_SRC_PREFIX, 8, 0, 0xc0,
391 })
392 ),
393 TS(
394 FLOW_ST_BAD_TYPE_ORDER,
395 "Doubled destination prefix component",
396 ((byte []) {
397 FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
398 FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
399 })
400 ),
401 TS(
402 FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
403 "The first numeric operator has set the AND bit",
404 ((byte []) {
405 FLOW_TYPE_PORT, 0x43, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90
406 })
407 ),
408 TS(
409 FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
410 "Set zero bit in operand to one",
411 ((byte []) {
412 FLOW_TYPE_NEXT_HEADER, 0x89, 0x06
413 })
414 ),
415 TS(
416 FLOW_ST_VALID,
417 "Component of type number 13 (Label) is well-known in IPv6",
418 ((byte []) {
419 FLOW_TYPE_LABEL, 0x80, 0x55
420 })
421 ),
422 TS(
423 FLOW_ST_UNKNOWN_COMPONENT,
424 "Unknown component of type number 14",
425 ((byte []) {
426 FLOW_TYPE_LABEL, 0x80, 0x55,
427 14 /*something new*/, 0x80, 0x55,
428 })
429 )
430 };
431 #undef TS
432
433 for (uint tcase = 0; tcase < ARRAY_SIZE(tset); tcase++)
434 {
435 res = flow6_validate(tset[tcase].nlri, tset[tcase].size);
436 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);
437 }
438
439 return 1;
440 }
441
442
443
444 /*
445 * Builder tests
446 */
447
448 static int
449 t_builder4(void)
450 {
451 resource_init();
452
453 struct flow_builder *fb = flow_builder_init(&root_pool);
454 linpool *lp = lp_new_default(&root_pool);
455
456 /* Expectation */
457
458 static byte nlri[] = {
459 25,
460 FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
461 FLOW_TYPE_SRC_PREFIX, 32, 10, 11, 12, 13,
462 FLOW_TYPE_IP_PROTOCOL, 0x80, 0x06,
463 FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
464 FLOW_TYPE_TCP_FLAGS, 0x80, 0x55
465 };
466
467 net_addr_flow4 *expect;
468 NET_ADDR_FLOW4_(expect, ip4_build(5, 6, 7, 0), 24, nlri);
469
470 /* Normal order */
471
472 net_addr_ip4 n1;
473 net_fill_ip4((net_addr *) &n1, ip4_build(5,6,7,0), 24);
474 flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
475 flow_builder4_add_pfx(fb, &n1);
476
477 net_addr_ip4 n2;
478 net_fill_ip4((net_addr *) &n2, ip4_build(10,11,12,13), 32);
479 flow_builder_set_type(fb, FLOW_TYPE_SRC_PREFIX);
480 flow_builder4_add_pfx(fb, &n2);
481
482 flow_builder_set_type(fb, FLOW_TYPE_IP_PROTOCOL);
483 flow_builder_add_op_val(fb, 0, 0x06);
484
485 flow_builder_set_type(fb, FLOW_TYPE_PORT);
486 flow_builder_add_op_val(fb, 0x03, 0x89);
487 flow_builder_add_op_val(fb, 0x45, 0x8b);
488 flow_builder_add_op_val(fb, 0x01, 0x1f90);
489
490 /* Try put a component twice time */
491 flow_builder_set_type(fb, FLOW_TYPE_IP_PROTOCOL);
492 flow_builder_add_op_val(fb, 0, 0x06);
493
494 flow_builder_set_type(fb, FLOW_TYPE_TCP_FLAGS);
495 flow_builder_add_op_val(fb, 0, 0x55);
496
497 net_addr_flow4 *res = flow_builder4_finalize(fb, lp);
498
499 bt_assert(memcmp(res, expect, expect->length) == 0);
500
501 /* Reverse order */
502
503 flow_builder_clear(fb);
504
505 flow_builder_set_type(fb, FLOW_TYPE_TCP_FLAGS);
506 flow_builder_add_op_val(fb, 0, 0x55);
507
508 flow_builder_set_type(fb, FLOW_TYPE_PORT);
509 flow_builder_add_op_val(fb, 0x03, 0x89);
510 flow_builder_add_op_val(fb, 0x45, 0x8b);
511 flow_builder_add_op_val(fb, 0x01, 0x1f90);
512
513 flow_builder_set_type(fb, FLOW_TYPE_IP_PROTOCOL);
514 flow_builder_add_op_val(fb, 0, 0x06);
515
516 net_fill_ip4((net_addr *) &n2, ip4_build(10,11,12,13), 32);
517 flow_builder_set_type(fb, FLOW_TYPE_SRC_PREFIX);
518 flow_builder4_add_pfx(fb, &n2);
519
520 net_fill_ip4((net_addr *) &n1, ip4_build(5,6,7,0), 24);
521 flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
522 flow_builder4_add_pfx(fb, &n1);
523
524 bt_assert(memcmp(res, expect, expect->length) == 0);
525
526 return 1;
527 }
528
529 static int
530 t_builder6(void)
531 {
532 net_addr_ip6 ip;
533
534 resource_init();
535 linpool *lp = lp_new_default(&root_pool);
536 struct flow_builder *fb = flow_builder_init(&root_pool);
537 fb->ipv6 = 1;
538
539 /* Expectation */
540
541 byte nlri[] = {
542 27,
543 FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
544 FLOW_TYPE_SRC_PREFIX, 8, 0, 0xc0,
545 FLOW_TYPE_NEXT_HEADER, 0x80, 0x06,
546 FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
547 FLOW_TYPE_LABEL, 0x80, 0x55,
548 };
549
550 net_addr_flow6 *expect;
551 NET_ADDR_FLOW6_(expect, ip6_build(0, 1, 0x12345678, 0x98000000), 103, nlri);
552
553 /* Normal order */
554
555 net_fill_ip6((net_addr *) &ip, ip6_build(0, 1, 0x12345678, 0x98000000), 103);
556 flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
557 flow_builder6_add_pfx(fb, &ip, 61);
558
559 /* Try put a component twice time */
560 net_fill_ip6((net_addr *) &ip, ip6_build(0, 1, 0x12345678, 0x98000000), 103);
561 flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
562 bt_assert(flow_builder6_add_pfx(fb, &ip, 61) == 0);
563
564 net_fill_ip6((net_addr *) &ip, ip6_build(0xc0000000,0,0,0), 8);
565 flow_builder_set_type(fb, FLOW_TYPE_SRC_PREFIX);
566 flow_builder6_add_pfx(fb, &ip, 0);
567
568 flow_builder_set_type(fb, FLOW_TYPE_NEXT_HEADER);
569 flow_builder_add_op_val(fb, 0, 0x06);
570
571 flow_builder_set_type(fb, FLOW_TYPE_PORT);
572 flow_builder_add_op_val(fb, 0x03, 0x89);
573 flow_builder_add_op_val(fb, 0x45, 0x8b);
574 flow_builder_add_op_val(fb, 0x01, 0x1f90);
575
576 flow_builder_set_type(fb, FLOW_TYPE_LABEL);
577 flow_builder_add_op_val(fb, 0, 0x55);
578
579 net_addr_flow6 *res = flow_builder6_finalize(fb, lp);
580 bt_assert(memcmp(res, expect, expect->length) == 0);
581
582 /* Reverse order */
583
584 flow_builder_clear(fb);
585 fb->ipv6 = 1;
586
587 flow_builder_set_type(fb, FLOW_TYPE_LABEL);
588 flow_builder_add_op_val(fb, 0, 0x55);
589
590 flow_builder_set_type(fb, FLOW_TYPE_PORT);
591 flow_builder_add_op_val(fb, 0x03, 0x89);
592 flow_builder_add_op_val(fb, 0x45, 0x8b);
593 flow_builder_add_op_val(fb, 0x01, 0x1f90);
594
595 flow_builder_set_type(fb, FLOW_TYPE_NEXT_HEADER);
596 flow_builder_add_op_val(fb, 0, 0x06);
597
598 net_fill_ip6((net_addr *) &ip, ip6_build(0xc0000000,0,0,0), 8);
599 flow_builder_set_type(fb, FLOW_TYPE_SRC_PREFIX);
600 flow_builder6_add_pfx(fb, &ip, 0);
601
602 net_fill_ip6((net_addr *) &ip, ip6_build(0, 1, 0x12345678, 0x98000000), 103);
603 flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
604 flow_builder6_add_pfx(fb, &ip, 61);
605
606 res = flow_builder6_finalize(fb, lp);
607 bt_assert(memcmp(res, expect, expect->length) == 0);
608
609 return 1;
610 }
611
612 static int
613 t_formatting4(void)
614 {
615 char b[1024];
616
617 byte nlri[] = {
618 0,
619 FLOW_TYPE_DST_PREFIX, 0x08, 10,
620 FLOW_TYPE_IP_PROTOCOL, 0x81, 23,
621 FLOW_TYPE_DST_PORT, 0x02, 24, 0x44, 30, 0x03, 40, 0x45, 50, 0x03, 60, 0x45, 70, 0x01, 80, 0xc3, 90,
622 FLOW_TYPE_SRC_PORT, 0x02, 24, 0x44, 0x1e, 0x01, 0x28, 0x01, 0x32, 0x03, 0x3c, 0x45, 0x46, 0x81, 0x50,
623 FLOW_TYPE_ICMP_TYPE, 0x81, 0x50,
624 FLOW_TYPE_ICMP_CODE, 0x81, 0x5a,
625 FLOW_TYPE_TCP_FLAGS, 0x01, 0x03, 0xc2, 0x0c,
626 FLOW_TYPE_PACKET_LENGTH, 0x03, 0, 0xd5, 0xff, 0xff,
627 FLOW_TYPE_DSCP, 0x81, 63,
628 FLOW_TYPE_FRAGMENT, 0x01, 0x01, 0x82, 0x02
629 };
630 *nlri = (u8) sizeof(nlri);
631
632 net_addr_flow4 *input;
633 NET_ADDR_FLOW4_(input, ip4_build(5, 6, 7, 0), 24, nlri);
634
635 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; }";
636
637 bt_assert(flow4_net_format(b, sizeof(b), input) == strlen(expect));
638 bt_debug(" expect: '%s',\n output: '%s'\n", expect, b);
639 bt_assert(strcmp(b, expect) == 0);
640
641 return 1;
642 }
643
644 static int
645 t_formatting6(void)
646 {
647 char b[1024];
648
649 byte nlri[] = {
650 0,
651 FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
652 FLOW_TYPE_SRC_PREFIX, 8, 0, 0xc0,
653 FLOW_TYPE_NEXT_HEADER, 0x81, 0x06,
654 FLOW_TYPE_PORT, 0x03, 20, 0x45, 40, 0x91, 0x01, 0x11,
655 FLOW_TYPE_LABEL, 0xa0, 0x12, 0x34, 0x56, 0x78,
656 };
657 *nlri = (u8) sizeof(nlri);
658
659 net_addr_flow6 *input;
660 NET_ADDR_FLOW6_(input, ip6_build(0, 1, 0x12345678, 0x98000000), 103, nlri);
661
662 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; }";
663
664 bt_assert(flow6_net_format(b, sizeof(b), input) == strlen(expect));
665 bt_debug(" expect: '%s',\n output: '%s'\n", expect, b);
666 bt_assert(strcmp(b, expect) == 0);
667
668 return 1;
669 }
670
671 int
672 main(int argc, char *argv[])
673 {
674 bt_init(argc, argv);
675
676 bt_test_suite(t_read_length, "Testing get NLRI length");
677 bt_test_suite(t_write_length, "Testing set NLRI length");
678 bt_test_suite(t_first_part, "Searching first part in net_addr_flow");
679 bt_test_suite(t_iterators4, "Testing iterators (IPv4)");
680 bt_test_suite(t_iterators6, "Testing iterators (IPv6)");
681 bt_test_suite(t_accessors4, "Testing accessors (IPv4)");
682 bt_test_suite(t_accessors6, "Testing accessors (IPv6)");
683 bt_test_suite(t_validation4, "Testing validation (IPv4)");
684 bt_test_suite(t_validation6, "Testing validation (IPv6)");
685 bt_test_suite(t_builder4, "Inserting components into existing Flow Specification (IPv4)");
686 bt_test_suite(t_builder6, "Inserting components into existing Flow Specification (IPv6)");
687 bt_test_suite(t_formatting4, "Formatting Flow Specification (IPv4) into text representation");
688 bt_test_suite(t_formatting6, "Formatting Flow Specification (IPv6) into text representation");
689
690 return bt_exit_value();
691 }