1: /*
2: * Copyright (C) 2005 Sun Microsystems, Inc.
3: *
4: * This file is part of Quagga.
5: *
6: * Quagga is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2, or (at your option) any
9: * later version.
10: *
11: * Quagga is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with Quagga; see the file COPYING. If not, write to the Free
18: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19: * 02111-1307, USA.
20: */
21:
22: #include <zebra.h>
23:
24: #include "vty.h"
25: #include "stream.h"
26: #include "privs.h"
27: #include "filter.h"
28:
29: #include "bgpd/bgpd.h"
30: #include "bgpd/bgp_aspath.h"
31: #include "bgpd/bgp_attr.h"
32:
33: #define VT100_RESET "\x1b[0m"
34: #define VT100_RED "\x1b[31m"
35: #define VT100_GREEN "\x1b[32m"
36: #define VT100_YELLOW "\x1b[33m"
37: #define OK VT100_GREEN "OK" VT100_RESET
38: #define FAILED VT100_RED "failed" VT100_RESET
39:
40: /* need these to link in libbgp */
41: struct zebra_privs_t *bgpd_privs = NULL;
42: struct thread_master *master = NULL;
43:
44: static int failed = 0;
45:
46: /* specification for a test - what the results should be */
47: struct test_spec
48: {
49: const char *shouldbe; /* the string the path should parse to */
50: const char *shouldbe_delete_confed; /* ditto, but once confeds are deleted */
51: const unsigned int hops; /* aspath_count_hops result */
52: const unsigned int confeds; /* aspath_count_confeds */
53: const int private_as; /* whether the private_as check should pass or fail */
54: #define NOT_ALL_PRIVATE 0
55: #define ALL_PRIVATE 1
56: const as_t does_loop; /* an ASN which should trigger loop-check */
57: const as_t doesnt_loop; /* one which should not */
58: const as_t first; /* the first ASN, if there is one */
59: #define NULL_ASN 0
60: };
61:
62:
63: /* test segments to parse and validate, and use for other tests */
64: static struct test_segment {
65: const char *name;
66: const char *desc;
67: const u_char asdata[1024];
68: int len;
69: struct test_spec sp;
70: } test_segments [] =
71: {
72: { /* 0 */
73: "seq1",
74: "seq(8466,3,52737,4096)",
75: { 0x2,0x4, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00 },
76: 10,
77: { "8466 3 52737 4096",
78: "8466 3 52737 4096",
79: 4, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
80: },
81: { /* 1 */
82: "seq2",
83: "seq(8722) seq(4)",
84: { 0x2,0x1, 0x22,0x12,
85: 0x2,0x1, 0x00,0x04 },
86: 8,
87: { "8722 4",
88: "8722 4",
89: 2, 0, NOT_ALL_PRIVATE, 4, 5, 8722, },
90: },
91: { /* 2 */
92: "seq3",
93: "seq(8466,3,52737,4096,8722,4)",
94: { 0x2,0x6, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00,
95: 0x22,0x12, 0x00,0x04},
96: 14,
97: { "8466 3 52737 4096 8722 4",
98: "8466 3 52737 4096 8722 4",
99: 6, 0, NOT_ALL_PRIVATE, 3, 5, 8466 },
100: },
101: { /* 3 */
102: "seqset",
103: "seq(8482,51457) set(5204)",
104: { 0x2,0x2, 0x21,0x22, 0xc9,0x01,
105: 0x1,0x1, 0x14,0x54 },
106: 10,
107: { "8482 51457 {5204}",
108: "8482 51457 {5204}",
109: 3, 0, NOT_ALL_PRIVATE, 5204, 51456, 8482},
110: },
111: { /* 4 */
112: "seqset2",
113: "seq(8467, 59649) set(4196,48658) set(17322,30745)",
114: { 0x2,0x2, 0x21,0x13, 0xe9,0x01,
115: 0x1,0x2, 0x10,0x64, 0xbe,0x12,
116: 0x1,0x2, 0x43,0xaa, 0x78,0x19 },
117: 18,
118: { "8467 59649 {4196,48658} {17322,30745}",
119: "8467 59649 {4196,48658} {17322,30745}",
120: 4, 0, NOT_ALL_PRIVATE, 48658, 1, 8467},
121: },
122: { /* 5 */
123: "multi",
124: "seq(6435,59408,21665) set(2457,61697,4369), seq(1842,41590,51793)",
125: { 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
126: 0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
127: 0x2,0x3, 0x07,0x32, 0xa2,0x76, 0xca,0x51 },
128: 24,
129: { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
130: "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
131: 7, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
132: },
133: { /* 6 */
134: "confed",
135: "confseq(123,456,789)",
136: { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15 },
137: 8,
138: { "(123 456 789)",
139: "",
140: 0, 3, NOT_ALL_PRIVATE, 789, 1, NULL_ASN },
141: },
142: { /* 7 */
143: "confed2",
144: "confseq(123,456,789) confseq(111,222)",
145: { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
146: 0x3,0x2, 0x00,0x6f, 0x00,0xde },
147: 14,
148: { "(123 456 789) (111 222)",
149: "",
150: 0, 5, NOT_ALL_PRIVATE, 111, 1, NULL_ASN },
151: },
152: { /* 8 */
153: "confset",
154: "confset(456,123,789)",
155: { 0x4,0x3, 0x01,0xc8, 0x00,0x7b, 0x03,0x15 },
156: 8,
157: { "[123,456,789]",
158: "[123,456,789]",
159: 0, 1, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
160: },
161: { /* 9 */
162: "confmulti",
163: "confseq(123,456,789) confset(222,111) seq(8722) set(4196,48658)",
164: { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
165: 0x4,0x2, 0x00,0xde, 0x00,0x6f,
166: 0x2,0x1, 0x22,0x12,
167: 0x1,0x2, 0x10,0x64, 0xbe,0x12 },
168: 24,
169: { "(123 456 789) [111,222] 8722 {4196,48658}",
170: "8722 {4196,48658}",
171: 2, 4, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
172: },
173: { /* 10 */
174: "seq4",
175: "seq(8466,2,52737,4096,8722,4)",
176: { 0x2,0x6, 0x21,0x12, 0x00,0x02, 0xce,0x01, 0x10,0x00,
177: 0x22,0x12, 0x00,0x04},
178: 14,
179: { "8466 2 52737 4096 8722 4",
180: "8466 2 52737 4096 8722 4",
181: 6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
182: },
183: { /* 11 */
184: "tripleseq1",
185: "seq(8466,2,52737) seq(4096,8722,4) seq(8722)",
186: { 0x2,0x3, 0x21,0x12, 0x00,0x02, 0xce,0x01,
187: 0x2,0x3, 0x10,0x00, 0x22,0x12, 0x00,0x04,
188: 0x2,0x1, 0x22,0x12},
189: 20,
190: { "8466 2 52737 4096 8722 4 8722",
191: "8466 2 52737 4096 8722 4 8722",
192: 7, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
193: },
194: { /* 12 */
195: "someprivate",
196: "seq(8466,64512,52737,65535)",
197: { 0x2,0x4, 0x21,0x12, 0xfc,0x00, 0xce,0x01, 0xff,0xff },
198: 10,
199: { "8466 64512 52737 65535",
200: "8466 64512 52737 65535",
201: 4, 0, NOT_ALL_PRIVATE, 65535, 4, 8466 },
202: },
203: { /* 13 */
204: "allprivate",
205: "seq(65534,64512,64513,65535)",
206: { 0x2,0x4, 0xff,0xfe, 0xfc,0x00, 0xfc,0x01, 0xff,0xff },
207: 10,
208: { "65534 64512 64513 65535",
209: "65534 64512 64513 65535",
210: 4, 0, ALL_PRIVATE, 65534, 4, 65534 },
211: },
212: { /* 14 */
213: "long",
214: "seq(8466,3,52737,4096,34285,<repeated 49 more times>)",
215: { 0x2,0xfa, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
216: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
217: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
218: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
219: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
220: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
221: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
222: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
223: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
224: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
225: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
226: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
227: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
228: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
229: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
230: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
231: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
232: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
233: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
234: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
235: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
236: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
237: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
238: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
239: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
240: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
241: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
242: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
243: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
244: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
245: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
246: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
247: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
248: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
249: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
250: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
251: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
252: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
253: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
254: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
255: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
256: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
257: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
258: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
259: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
260: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
261: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
262: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
263: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
264: 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed, },
265: 502,
266: { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
267: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
268: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
269: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
270: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
271: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
272: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
273: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
274: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
275: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
276: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
277: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
278: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
279: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
280: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
281: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
282: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
283: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
284: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
285: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
286: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
287: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
288: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
289: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
290: "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
291:
292: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
293: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
294: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
295: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
296: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
297: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
298: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
299: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
300: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
301: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
302: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
303: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
304: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
305: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
306: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
307: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
308: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
309: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
310: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
311: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
312: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
313: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
314: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
315: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
316: "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
317: 250, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
318: },
319: { /* 15 */
320: "seq1extra",
321: "seq(8466,3,52737,4096,3456)",
322: { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
323: 12,
324: { "8466 3 52737 4096 3456",
325: "8466 3 52737 4096 3456",
326: 5, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
327: },
328: { /* 16 */
329: "empty",
330: "<empty>",
331: {},
332: 0,
333: { "", "", 0, 0, 0, 0, 0, 0 },
334: },
335: { /* 17 */
336: "redundantset",
337: "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153)",
338: { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
339: 0x1,0x4, 0x1b,0xbb, 0x1f,0xd9, 0x1f,0xd9, 0x1f,0xd9 },
340: 22,
341: {
342: /* We shouldn't ever /generate/ such paths. However, we should
343: * cope with them fine.
344: */
345: "8466 3 52737 4096 3456 {7099,8153}",
346: "8466 3 52737 4096 3456 {7099,8153}",
347: 6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
348: },
349: { /* 18 */
350: "reconcile_lead_asp",
351: "seq(6435,59408,21665) set(23456,23456,23456), seq(23456,23456,23456)",
352: { 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
353: 0x1,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
354: 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0 },
355: 24,
356: { "6435 59408 21665 {23456} 23456 23456 23456",
357: "6435 59408 21665 {23456} 23456 23456 23456",
358: 7, 0, NOT_ALL_PRIVATE, 23456, 1, 6435 },
359: },
360: { /* 19 */
361: "reconcile_new_asp",
362: "set(2457,61697,4369), seq(1842,41591,51793)",
363: {
364: 0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
365: 0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51 },
366: 16,
367: { "{2457,4369,61697} 1842 41591 51793",
368: "{2457,4369,61697} 1842 41591 51793",
369: 4, 0, NOT_ALL_PRIVATE, 51793, 1, 2457 },
370: },
371: { /* 20 */
372: "reconcile_confed",
373: "confseq(123,456,789) confset(456,124,788) seq(6435,59408,21665)"
374: " set(23456,23456,23456), seq(23456,23456,23456)",
375: { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
376: 0x4,0x3, 0x01,0xc8, 0x00,0x7c, 0x03,0x14,
377: 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
378: 0x1,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
379: 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0 },
380: 40,
381: { "(123 456 789) [124,456,788] 6435 59408 21665"
382: " {23456} 23456 23456 23456",
383: "6435 59408 21665 {23456} 23456 23456 23456",
384: 7, 4, NOT_ALL_PRIVATE, 23456, 1, 6435 },
385: },
386: { /* 21 */
387: "reconcile_start_trans",
388: "seq(23456,23456,23456) seq(6435,59408,21665)",
389: { 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
390: 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, },
391: 16,
392: { "23456 23456 23456 6435 59408 21665",
393: "23456 23456 23456 6435 59408 21665",
394: 6, 0, NOT_ALL_PRIVATE, 21665, 1, 23456 },
395: },
396: { /* 22 */
397: "reconcile_start_trans4",
398: "seq(1842,41591,51793) seq(6435,59408,21665)",
399: { 0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51,
400: 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, },
401: 16,
402: { "1842 41591 51793 6435 59408 21665",
403: "1842 41591 51793 6435 59408 21665",
404: 6, 0, NOT_ALL_PRIVATE, 41591, 1, 1842 },
405: },
406: { /* 23 */
407: "reconcile_start_trans_error",
408: "seq(23456,23456,23456) seq(6435,59408)",
409: { 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
410: 0x2,0x2, 0x19,0x23, 0xe8,0x10, },
411: 14,
412: { "23456 23456 23456 6435 59408",
413: "23456 23456 23456 6435 59408",
414: 5, 0, NOT_ALL_PRIVATE, 59408, 1, 23456 },
415: },
416: { /* 24 */
417: "redundantset2",
418: "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153,7099)",
419: { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
420: 0x1,0x5, 0x1b,0xbb, 0x1f,0xd9, 0x1f,0xd9, 0x1f,0xd9, 0x1b,0xbb,},
421: 24,
422: {
423: /* We should weed out duplicate set members. */
424: "8466 3 52737 4096 3456 {7099,8153}",
425: "8466 3 52737 4096 3456 {7099,8153}",
426: 6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
427: },
428: { /* 25 */
429: "zero-size overflow",
430: "#ASNs = 0, data = seq(8466 3 52737 4096 3456)",
431: { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
432: 12,
433: { NULL, NULL,
434: 0, 0, 0, 0, 0, 0 },
435: },
436: { /* 26 */
437: "zero-size overflow + valid segment",
438: "seq(#AS=0:8466 3 52737),seq(4096 3456)",
439: { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01,
440: 0x2,0x2, 0x10,0x00, 0x0d,0x80 },
441: 14
442: ,
443: { NULL, NULL,
444: 0, 0, 0, 0, 0, 0 },
445: },
446: { /* 27 */
447: "invalid segment type",
448: "type=8(4096 3456)",
449: { 0x8,0x2, 0x10,0x00, 0x0d,0x80 },
450: 14
451: ,
452: { NULL, NULL,
453: 0, 0, 0, 0, 0, 0 },
454: }, { NULL, NULL, {0}, 0, { NULL, 0, 0 } }
455: };
456:
457: #define COMMON_ATTRS \
458: BGP_ATTR_FLAG_TRANS, \
459: BGP_ATTR_ORIGIN, \
460: 1, \
461: BGP_ORIGIN_EGP, \
462: BGP_ATTR_FLAG_TRANS, \
463: BGP_ATTR_NEXT_HOP, \
464: 4, 192, 0, 2, 0
465: #define COMMON_ATTR_SIZE 11
466:
467: /* */
468: static struct aspath_tests {
469: const char *desc;
470: const struct test_segment *segment;
471: const char *shouldbe; /* String it should evaluate to */
472: const enum as4 { AS4_DATA, AS2_DATA }
473: as4; /* whether data should be as4 or not (ie as2) */
474: const int result; /* expected result for bgp_attr_parse */
475: const int cap; /* capabilities to set for peer */
476: const char attrheader [1024];
477: size_t len;
478: const struct test_segment *old_segment;
479: } aspath_tests [] =
480: {
481: /* 0 */
482: {
483: "basic test",
484: &test_segments[0],
485: "8466 3 52737 4096",
486: AS2_DATA, 0,
487: 0,
488: { COMMON_ATTRS,
489: BGP_ATTR_FLAG_TRANS,
490: BGP_ATTR_AS_PATH,
491: 10,
492: },
493: COMMON_ATTR_SIZE + 3,
494: },
495: /* 1 */
496: {
497: "length too short",
498: &test_segments[0],
499: "8466 3 52737 4096",
500: AS2_DATA, -1,
501: 0,
502: { COMMON_ATTRS,
503: BGP_ATTR_FLAG_TRANS,
504: BGP_ATTR_AS_PATH,
505: 8,
506: },
507: COMMON_ATTR_SIZE + 3,
508: },
509: /* 2 */
510: {
511: "length too long",
512: &test_segments[0],
513: "8466 3 52737 4096",
514: AS2_DATA, -1,
515: 0,
516: { COMMON_ATTRS,
517: BGP_ATTR_FLAG_TRANS,
518: BGP_ATTR_AS_PATH,
519: 12,
520: },
521: COMMON_ATTR_SIZE + 3,
522: },
523: /* 3 */
524: {
525: "incorrect flag",
526: &test_segments[0],
527: "8466 3 52737 4096",
528: AS2_DATA, -1,
529: 0,
530: { COMMON_ATTRS,
531: BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
532: BGP_ATTR_AS_PATH,
533: 10,
534: },
535: COMMON_ATTR_SIZE + 3,
536: },
537: /* 4 */
538: {
539: "as4_path, with as2 format data",
540: &test_segments[0],
541: "8466 3 52737 4096",
542: AS2_DATA, -1,
543: 0,
544: { COMMON_ATTRS,
545: BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
546: BGP_ATTR_AS4_PATH,
547: 10,
548: },
549: COMMON_ATTR_SIZE + 3,
550: },
551: /* 5 */
552: {
553: "as4, with incorrect attr length",
554: &test_segments[0],
555: "8466 3 52737 4096",
556: AS4_DATA, -1,
557: PEER_CAP_AS4_RCV,
558: { COMMON_ATTRS,
559: BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
560: BGP_ATTR_AS4_PATH,
561: 10,
562: },
563: COMMON_ATTR_SIZE + 3,
564: },
565: /* 6 */
566: {
567: "basic 4-byte as-path",
568: &test_segments[0],
569: "8466 3 52737 4096",
570: AS4_DATA, 0,
571: PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
572: { COMMON_ATTRS,
573: BGP_ATTR_FLAG_TRANS,
574: BGP_ATTR_AS_PATH,
575: 18,
576: },
577: COMMON_ATTR_SIZE + 3,
578: },
579: /* 7 */
580: {
581: "4b AS_PATH: too short",
582: &test_segments[0],
583: "8466 3 52737 4096",
584: AS4_DATA, -1,
585: PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
586: { COMMON_ATTRS,
587: BGP_ATTR_FLAG_TRANS,
588: BGP_ATTR_AS_PATH,
589: 16,
590: },
591: COMMON_ATTR_SIZE + 3,
592: },
593: /* 8 */
594: {
595: "4b AS_PATH: too long",
596: &test_segments[0],
597: "8466 3 52737 4096",
598: AS4_DATA, -1,
599: PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
600: { COMMON_ATTRS,
601: BGP_ATTR_FLAG_TRANS,
602: BGP_ATTR_AS_PATH,
603: 20,
604: },
605: COMMON_ATTR_SIZE + 3,
606: },
607: /* 9 */
608: {
609: "4b AS_PATH: too long2",
610: &test_segments[0],
611: "8466 3 52737 4096",
612: AS4_DATA, -1,
613: PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
614: { COMMON_ATTRS,
615: BGP_ATTR_FLAG_TRANS,
616: BGP_ATTR_AS_PATH,
617: 22,
618: },
619: COMMON_ATTR_SIZE + 3,
620: },
621: /* 10 */
622: {
623: "4b AS_PATH: bad flags",
624: &test_segments[0],
625: "8466 3 52737 4096",
626: AS4_DATA, -1,
627: PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
628: { COMMON_ATTRS,
629: BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
630: BGP_ATTR_AS_PATH,
631: 18,
632: },
633: COMMON_ATTR_SIZE + 3,
634: },
635: /* 11 */
636: {
637: "4b AS4_PATH w/o AS_PATH",
638: &test_segments[6],
639: NULL,
640: AS4_DATA, -1,
641: PEER_CAP_AS4_ADV,
642: { COMMON_ATTRS,
643: BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
644: BGP_ATTR_AS4_PATH,
645: 14,
646: },
647: COMMON_ATTR_SIZE + 3,
648: },
649: /* 12 */
650: {
651: "4b AS4_PATH: confed",
652: &test_segments[6],
653: "8466 3 52737 4096 (123 456 789)",
654: AS4_DATA, 0,
655: PEER_CAP_AS4_ADV,
656: { COMMON_ATTRS,
657: BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
658: BGP_ATTR_AS4_PATH,
659: 14,
660: },
661: COMMON_ATTR_SIZE + 3,
662: &test_segments[0],
663: },
664: { NULL, NULL, NULL, 0, 0, 0, { 0 }, 0 },
665: };
666:
667: /* prepending tests */
668: static struct tests {
669: const struct test_segment *test1;
670: const struct test_segment *test2;
671: struct test_spec sp;
672: } prepend_tests[] =
673: {
674: /* 0 */
675: { &test_segments[0], &test_segments[1],
676: { "8466 3 52737 4096 8722 4",
677: "8466 3 52737 4096 8722 4",
678: 6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
679: },
680: /* 1 */
681: { &test_segments[1], &test_segments[3],
682: { "8722 4 8482 51457 {5204}",
683: "8722 4 8482 51457 {5204}",
684: 5, 0, NOT_ALL_PRIVATE, 5204, 1, 8722 }
685: },
686: /* 2 */
687: { &test_segments[3], &test_segments[4],
688: { "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
689: "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
690: 7, 0, NOT_ALL_PRIVATE, 5204, 1, 8482 },
691: },
692: /* 3 */
693: { &test_segments[4], &test_segments[5],
694: { "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
695: " {2457,4369,61697} 1842 41590 51793",
696: "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
697: " {2457,4369,61697} 1842 41590 51793",
698: 11, 0, NOT_ALL_PRIVATE, 61697, 1, 8467 }
699: },
700: /* 4 */
701: { &test_segments[5], &test_segments[6],
702: { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
703: "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
704: 7, 0, NOT_ALL_PRIVATE, 1842, 1, 6435 },
705: },
706: /* 5 */
707: { &test_segments[6], &test_segments[7],
708: { "(123 456 789) (123 456 789) (111 222)",
709: "",
710: 0, 8, NOT_ALL_PRIVATE, 111, 1, 0 }
711: },
712: { &test_segments[7], &test_segments[8],
713: { "(123 456 789) (111 222) [123,456,789]",
714: "",
715: 0, 6, NOT_ALL_PRIVATE, 111, 1, 0 }
716: },
717: { &test_segments[8], &test_segments[9],
718: { "[123,456,789] (123 456 789) [111,222] 8722 {4196,48658}",
719: "[123,456,789] (123 456 789) [111,222] 8722 {4196,48658}",
720: 2, 5, NOT_ALL_PRIVATE, 456, 1, NULL_ASN },
721: },
722: { &test_segments[9], &test_segments[8],
723: { "(123 456 789) [111,222] 8722 {4196,48658} [123,456,789]",
724: "8722 {4196,48658} [123,456,789]",
725: 2, 5, NOT_ALL_PRIVATE, 48658, 1, NULL_ASN },
726: },
727: { &test_segments[14], &test_segments[11],
728: { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
729: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
730: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
731: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
732: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
733: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
734: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
735: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
736: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
737: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
738: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
739: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
740: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
741: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
742: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
743: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
744: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
745: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
746: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
747: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
748: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
749: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
750: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
751: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
752: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
753: "8466 2 52737 4096 8722 4 8722",
754:
755: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
756: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
757: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
758: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
759: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
760: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
761: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
762: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
763: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
764: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
765: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
766: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
767: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
768: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
769: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
770: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
771: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
772: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
773: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
774: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
775: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
776: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
777: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
778: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
779: "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
780: "8466 2 52737 4096 8722 4 8722",
781: 257, 0, NOT_ALL_PRIVATE, 4096, 1000, 8466 },
782: },
783: { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
784: };
785:
786: struct tests reconcile_tests[] =
787: {
788: { &test_segments[18], &test_segments[19],
789: { "6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
790: "6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
791: 7, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
792: },
793: { &test_segments[19], &test_segments[18],
794: /* AS_PATH (19) has more hops than NEW_AS_PATH,
795: * so just AS_PATH should be used (though, this practice
796: * is bad imho).
797: */
798: { "{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456",
799: "{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456",
800: 11, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
801: },
802: { &test_segments[20], &test_segments[19],
803: { "(123 456 789) [124,456,788] 6435 59408 21665"
804: " {2457,4369,61697} 1842 41591 51793",
805: "6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
806: 7, 4, NOT_ALL_PRIVATE, 51793, 1, 6435 },
807: },
808: { &test_segments[21], &test_segments[22],
809: { "1842 41591 51793 6435 59408 21665",
810: "1842 41591 51793 6435 59408 21665",
811: 6, 0, NOT_ALL_PRIVATE, 51793, 1, 1842 },
812: },
813: { &test_segments[23], &test_segments[22],
814: { "23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665",
815: "23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665",
816: 11, 0, NOT_ALL_PRIVATE, 51793, 1, 1842 },
817: },
818: { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
819: };
820:
821: struct tests aggregate_tests[] =
822: {
823: { &test_segments[0], &test_segments[2],
824: { "8466 3 52737 4096 {4,8722}",
825: "8466 3 52737 4096 {4,8722}",
826: 5, 0, NOT_ALL_PRIVATE, 4, 1, 8466 },
827: },
828: { &test_segments[2], &test_segments[0],
829: { "8466 3 52737 4096 {4,8722}",
830: "8466 3 52737 4096 {4,8722}",
831: 5, 0, NOT_ALL_PRIVATE, 8722, 1, 8466 },
832: },
833: { &test_segments[2], &test_segments[10],
834: { "8466 {2,3,4,4096,8722,52737}",
835: "8466 {2,3,4,4096,8722,52737}",
836: 2, 0, NOT_ALL_PRIVATE, 8722, 5, 8466 },
837: },
838: { &test_segments[10], &test_segments[2],
839: { "8466 {2,3,4,4096,8722,52737}",
840: "8466 {2,3,4,4096,8722,52737}",
841: 2, 0, NOT_ALL_PRIVATE, 2, 20000, 8466 },
842: },
843:
844: { &test_segments[5], &test_segments[18],
845: { "6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}",
846: "6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}",
847: 4, 0, NOT_ALL_PRIVATE, 41590, 1, 6435 },
848: },
849:
850: { NULL, NULL, { NULL, 0, 0} },
851: };
852:
853: struct compare_tests
854: {
855: int test_index1;
856: int test_index2;
857: #define CMP_RES_YES 1
858: #define CMP_RES_NO 0
859: char shouldbe_cmp;
860: char shouldbe_confed;
861: } left_compare [] =
862: {
863: { 0, 1, CMP_RES_NO, CMP_RES_NO },
864: { 0, 2, CMP_RES_YES, CMP_RES_NO },
865: { 0, 11, CMP_RES_YES, CMP_RES_NO },
866: { 0, 15, CMP_RES_YES, CMP_RES_NO },
867: { 0, 16, CMP_RES_NO, CMP_RES_NO },
868: { 1, 11, CMP_RES_NO, CMP_RES_NO },
869: { 6, 7, CMP_RES_NO, CMP_RES_YES },
870: { 6, 8, CMP_RES_NO, CMP_RES_NO },
871: { 7, 8, CMP_RES_NO, CMP_RES_NO },
872: { 1, 9, CMP_RES_YES, CMP_RES_NO },
873: { 0, 9, CMP_RES_NO, CMP_RES_NO },
874: { 3, 9, CMP_RES_NO, CMP_RES_NO },
875: { 0, 6, CMP_RES_NO, CMP_RES_NO },
876: { 1, 6, CMP_RES_NO, CMP_RES_NO },
877: { 0, 8, CMP_RES_NO, CMP_RES_NO },
878: { 1, 8, CMP_RES_NO, CMP_RES_NO },
879: { 11, 6, CMP_RES_NO, CMP_RES_NO },
880: { 11, 7, CMP_RES_NO, CMP_RES_NO },
881: { 11, 8, CMP_RES_NO, CMP_RES_NO },
882: { 9, 6, CMP_RES_NO, CMP_RES_YES },
883: { 9, 7, CMP_RES_NO, CMP_RES_YES },
884: { 9, 8, CMP_RES_NO, CMP_RES_NO },
885: };
886:
887: /* make an aspath from a data stream */
888: static struct aspath *
889: make_aspath (const u_char *data, size_t len, int use32bit)
890: {
891: struct stream *s = NULL;
892: struct aspath *as;
893:
894: if (len)
895: {
896: s = stream_new (len);
897: stream_put (s, data, len);
898: }
899: as = aspath_parse (s, len, use32bit);
900:
901: if (s)
902: stream_free (s);
903:
904: return as;
905: }
906:
907: static void
908: printbytes (const u_char *bytes, int len)
909: {
910: int i = 0;
911: while (i < len)
912: {
913: if (i % 2)
914: printf ("%02hhx%s", bytes[i], " ");
915: else
916: printf ("0x%02hhx", bytes[i]);
917: i++;
918: }
919: printf ("\n");
920: }
921:
922: /* validate the given aspath */
923: static int
924: validate (struct aspath *as, const struct test_spec *sp)
925: {
926: size_t bytes, bytes4;
927: int fails = 0;
928: const u_char *out;
929: static struct stream *s;
930: struct aspath *asinout, *asconfeddel, *asstr, *as4;
931:
932: if (as == NULL && sp->shouldbe == NULL)
933: {
934: printf ("Correctly failed to parse\n");
935: return fails;
936: }
937:
938: out = aspath_snmp_pathseg (as, &bytes);
939: asinout = make_aspath (out, bytes, 0);
940:
941: /* Excercise AS4 parsing a bit, with a dogfood test */
942: if (!s)
943: s = stream_new (4096);
944: bytes4 = aspath_put (s, as, 1);
945: as4 = make_aspath (STREAM_DATA(s), bytes4, 1);
946:
947: asstr = aspath_str2aspath (sp->shouldbe);
948:
949: asconfeddel = aspath_delete_confed_seq (aspath_dup (asinout));
950:
951: printf ("got: %s\n", aspath_print(as));
952:
953: /* the parsed path should match the specified 'shouldbe' string.
954: * We should pass the "eat our own dog food" test, be able to output
955: * this path and then input it again. Ie the path resulting from:
956: *
957: * aspath_parse(aspath_put(as))
958: *
959: * should:
960: *
961: * - also match the specified 'shouldbe' value
962: * - hash to same value as original path
963: * - have same hops and confed counts as original, and as the
964: * the specified counts
965: *
966: * aspath_str2aspath() and shouldbe should match
967: *
968: * We do the same for:
969: *
970: * aspath_parse(aspath_put(as,USE32BIT))
971: *
972: * Confederation related tests:
973: * - aspath_delete_confed_seq(aspath) should match shouldbe_confed
974: * - aspath_delete_confed_seq should be idempotent.
975: */
976: if (strcmp(aspath_print (as), sp->shouldbe)
977: /* hash validation */
978: || (aspath_key_make (as) != aspath_key_make (asinout))
979: /* by string */
980: || strcmp(aspath_print (asinout), sp->shouldbe)
981: /* By 4-byte parsing */
982: || strcmp(aspath_print (as4), sp->shouldbe)
983: /* by various path counts */
984: || (aspath_count_hops (as) != sp->hops)
985: || (aspath_count_confeds (as) != sp->confeds)
986: || (aspath_count_hops (asinout) != sp->hops)
987: || (aspath_count_confeds (asinout) != sp->confeds))
988: {
989: failed++;
990: fails++;
991: printf ("shouldbe:\n%s\n", sp->shouldbe);
992: printf ("as4:\n%s\n", aspath_print (as4));
993: printf ("hash keys: in: %d out->in: %d\n",
994: aspath_key_make (as), aspath_key_make (asinout));
995: printf ("hops: %d, counted %d %d\n", sp->hops,
996: aspath_count_hops (as),
997: aspath_count_hops (asinout) );
998: printf ("confeds: %d, counted %d %d\n", sp->confeds,
999: aspath_count_confeds (as),
1000: aspath_count_confeds (asinout));
1001: printf ("out->in:\n%s\nbytes: ", aspath_print(asinout));
1002: printbytes (out, bytes);
1003: }
1004: /* basic confed related tests */
1005: if ((aspath_print (asconfeddel) == NULL
1006: && sp->shouldbe_delete_confed != NULL)
1007: || (aspath_print (asconfeddel) != NULL
1008: && sp->shouldbe_delete_confed == NULL)
1009: || strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed)
1010: /* delete_confed_seq should be idempotent */
1011: || (aspath_key_make (asconfeddel)
1012: != aspath_key_make (aspath_delete_confed_seq (asconfeddel))))
1013: {
1014: failed++;
1015: fails++;
1016: printf ("confed_del: %s\n", aspath_print (asconfeddel));
1017: printf ("should be: %s\n", sp->shouldbe_delete_confed);
1018: }
1019: /* aspath_str2aspath test */
1020: if ((aspath_print (asstr) == NULL && sp->shouldbe != NULL)
1021: || (aspath_print (asstr) != NULL && sp->shouldbe == NULL)
1022: || strcmp(aspath_print (asstr), sp->shouldbe))
1023: {
1024: failed++;
1025: fails++;
1026: printf ("asstr: %s\n", aspath_print (asstr));
1027: }
1028:
1029: /* loop, private and first as checks */
1030: if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0)
1031: || (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0)
1032: || (aspath_private_as_check (as) != sp->private_as)
1033: || (aspath_firstas_check (as,sp->first)
1034: && sp->first == 0))
1035: {
1036: failed++;
1037: fails++;
1038: printf ("firstas: %d, got %d\n", sp->first,
1039: aspath_firstas_check (as,sp->first));
1040: printf ("loop does: %d %d, doesnt: %d %d\n",
1041: sp->does_loop, aspath_loop_check (as, sp->does_loop),
1042: sp->doesnt_loop, aspath_loop_check (as, sp->doesnt_loop));
1043: printf ("private check: %d %d\n", sp->private_as,
1044: aspath_private_as_check (as));
1045: }
1046: aspath_unintern (&asinout);
1047: aspath_unintern (&as4);
1048:
1049: aspath_free (asconfeddel);
1050: aspath_free (asstr);
1051: stream_reset (s);
1052:
1053: return fails;
1054: }
1055:
1056: static void
1057: empty_get_test ()
1058: {
1059: struct aspath *as = aspath_empty_get ();
1060: struct test_spec sp = { "", "", 0, 0, 0, 0, 0, 0 };
1061:
1062: printf ("empty_get_test, as: %s\n",aspath_print (as));
1063: if (!validate (as, &sp))
1064: printf ("%s\n", OK);
1065: else
1066: printf ("%s!\n", FAILED);
1067:
1068: printf ("\n");
1069:
1070: aspath_free (as);
1071: }
1072:
1073: /* basic parsing test */
1074: static void
1075: parse_test (struct test_segment *t)
1076: {
1077: struct aspath *asp;
1078:
1079: printf ("%s: %s\n", t->name, t->desc);
1080:
1081: asp = make_aspath (t->asdata, t->len, 0);
1082:
1083: printf ("aspath: %s\nvalidating...:\n", aspath_print (asp));
1084:
1085: if (!validate (asp, &t->sp))
1086: printf (OK "\n");
1087: else
1088: printf (FAILED "\n");
1089:
1090: printf ("\n");
1091:
1092: if (asp)
1093: aspath_unintern (&asp);
1094: }
1095:
1096: /* prepend testing */
1097: static void
1098: prepend_test (struct tests *t)
1099: {
1100: struct aspath *asp1, *asp2, *ascratch;
1101:
1102: printf ("prepend %s: %s\n", t->test1->name, t->test1->desc);
1103: printf ("to %s: %s\n", t->test2->name, t->test2->desc);
1104:
1105: asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
1106: asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
1107:
1108: ascratch = aspath_dup (asp2);
1109: aspath_unintern (&asp2);
1110:
1111: asp2 = aspath_prepend (asp1, ascratch);
1112:
1113: printf ("aspath: %s\n", aspath_print (asp2));
1114:
1115: if (!validate (asp2, &t->sp))
1116: printf ("%s\n", OK);
1117: else
1118: printf ("%s!\n", FAILED);
1119:
1120: printf ("\n");
1121: aspath_unintern (&asp1);
1122: aspath_free (asp2);
1123: }
1124:
1125: /* empty-prepend testing */
1126: static void
1127: empty_prepend_test (struct test_segment *t)
1128: {
1129: struct aspath *asp1, *asp2, *ascratch;
1130:
1131: printf ("empty prepend %s: %s\n", t->name, t->desc);
1132:
1133: asp1 = make_aspath (t->asdata, t->len, 0);
1134: asp2 = aspath_empty ();
1135:
1136: ascratch = aspath_dup (asp2);
1137: aspath_unintern (&asp2);
1138:
1139: asp2 = aspath_prepend (asp1, ascratch);
1140:
1141: printf ("aspath: %s\n", aspath_print (asp2));
1142:
1143: if (!validate (asp2, &t->sp))
1144: printf (OK "\n");
1145: else
1146: printf (FAILED "!\n");
1147:
1148: printf ("\n");
1149: if (asp1)
1150: aspath_unintern (&asp1);
1151: aspath_free (asp2);
1152: }
1153:
1154: /* as2+as4 reconciliation testing */
1155: static void
1156: as4_reconcile_test (struct tests *t)
1157: {
1158: struct aspath *asp1, *asp2, *ascratch;
1159:
1160: printf ("reconciling %s:\n %s\n", t->test1->name, t->test1->desc);
1161: printf ("with %s:\n %s\n", t->test2->name, t->test2->desc);
1162:
1163: asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
1164: asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
1165:
1166: ascratch = aspath_reconcile_as4 (asp1, asp2);
1167:
1168: if (!validate (ascratch, &t->sp))
1169: printf (OK "\n");
1170: else
1171: printf (FAILED "!\n");
1172:
1173: printf ("\n");
1174: aspath_unintern (&asp1);
1175: aspath_unintern (&asp2);
1176: aspath_free (ascratch);
1177: }
1178:
1179:
1180: /* aggregation testing */
1181: static void
1182: aggregate_test (struct tests *t)
1183: {
1184: struct aspath *asp1, *asp2, *ascratch;
1185:
1186: printf ("aggregate %s: %s\n", t->test1->name, t->test1->desc);
1187: printf ("with %s: %s\n", t->test2->name, t->test2->desc);
1188:
1189: asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
1190: asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
1191:
1192: ascratch = aspath_aggregate (asp1, asp2);
1193:
1194: if (!validate (ascratch, &t->sp))
1195: printf (OK "\n");
1196: else
1197: printf (FAILED "!\n");
1198:
1199: printf ("\n");
1200: aspath_unintern (&asp1);
1201: aspath_unintern (&asp2);
1202: aspath_free (ascratch);
1203: /* aspath_unintern (ascratch);*/
1204: }
1205:
1206: /* cmp_left tests */
1207: static void
1208: cmp_test ()
1209: {
1210: unsigned int i;
1211: #define CMP_TESTS_MAX \
1212: (sizeof(left_compare) / sizeof (struct compare_tests))
1213:
1214: for (i = 0; i < CMP_TESTS_MAX; i++)
1215: {
1216: struct test_segment *t1 = &test_segments[left_compare[i].test_index1];
1217: struct test_segment *t2 = &test_segments[left_compare[i].test_index2];
1218: struct aspath *asp1, *asp2;
1219:
1220: printf ("left cmp %s: %s\n", t1->name, t1->desc);
1221: printf ("and %s: %s\n", t2->name, t2->desc);
1222:
1223: asp1 = make_aspath (t1->asdata, t1->len, 0);
1224: asp2 = make_aspath (t2->asdata, t2->len, 0);
1225:
1226: if (aspath_cmp_left (asp1, asp2) != left_compare[i].shouldbe_cmp
1227: || aspath_cmp_left (asp2, asp1) != left_compare[i].shouldbe_cmp
1228: || aspath_cmp_left_confed (asp1, asp2)
1229: != left_compare[i].shouldbe_confed
1230: || aspath_cmp_left_confed (asp2, asp1)
1231: != left_compare[i].shouldbe_confed)
1232: {
1233: failed++;
1234: printf (FAILED "\n");
1235: printf ("result should be: cmp: %d, confed: %d\n",
1236: left_compare[i].shouldbe_cmp,
1237: left_compare[i].shouldbe_confed);
1238: printf ("got: cmp %d, cmp_confed: %d\n",
1239: aspath_cmp_left (asp1, asp2),
1240: aspath_cmp_left_confed (asp1, asp2));
1241: printf("path1: %s\npath2: %s\n", aspath_print (asp1),
1242: aspath_print (asp2));
1243: }
1244: else
1245: printf (OK "\n");
1246:
1247: printf ("\n");
1248: aspath_unintern (&asp1);
1249: aspath_unintern (&asp2);
1250: }
1251: }
1252:
1253: static int
1254: handle_attr_test (struct aspath_tests *t)
1255: {
1256: struct bgp bgp = { 0 };
1257: struct peer peer = { 0 };
1258: struct attr attr = { 0 };
1259: int ret;
1260: int initfail = failed;
1261: struct aspath *asp;
1262: size_t datalen;
1263:
1264: asp = make_aspath (t->segment->asdata, t->segment->len, 0);
1265:
1266: peer.ibuf = stream_new (BGP_MAX_PACKET_SIZE);
1267: peer.obuf = stream_fifo_new ();
1268: peer.bgp = &bgp;
1269: peer.host = (char *)"none";
1270: peer.fd = -1;
1271: peer.cap = t->cap;
1272:
1273: stream_write (peer.ibuf, t->attrheader, t->len);
1274: datalen = aspath_put (peer.ibuf, asp, t->as4 == AS4_DATA);
1275: if (t->old_segment)
1276: {
1277: char dummyaspath[] = { BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH,
1278: t->old_segment->len };
1279: stream_write (peer.ibuf, dummyaspath, sizeof (dummyaspath));
1280: stream_write (peer.ibuf, t->old_segment->asdata, t->old_segment->len);
1281: datalen += sizeof (dummyaspath) + t->old_segment->len;
1282: }
1283:
1284: ret = bgp_attr_parse (&peer, &attr, t->len + datalen, NULL, NULL);
1285:
1286: if (ret != t->result)
1287: {
1288: printf ("bgp_attr_parse returned %d, expected %d\n", ret, t->result);
1289: printf ("datalen %zd\n", datalen);
1290: failed++;
1291: }
1292: if (ret != 0)
1293: goto out;
1294:
1295: if (t->shouldbe && attr.aspath == NULL)
1296: {
1297: printf ("aspath is NULL, but should be: %s\n", t->shouldbe);
1298: failed++;
1299: }
1300: if (t->shouldbe && attr.aspath && strcmp (attr.aspath->str, t->shouldbe))
1301: {
1302: printf ("attr str and 'shouldbe' mismatched!\n"
1303: "attr str: %s\n"
1304: "shouldbe: %s\n",
1305: attr.aspath->str, t->shouldbe);
1306: failed++;
1307: }
1308: if (!t->shouldbe && attr.aspath)
1309: {
1310: printf ("aspath should be NULL, but is: %s\n", attr.aspath->str);
1311: failed++;
1312: }
1313:
1314: out:
1315: if (attr.aspath)
1316: aspath_unintern (&attr.aspath);
1317: if (asp)
1318: aspath_unintern (&asp);
1319: return failed - initfail;
1320: }
1321:
1322: static void
1323: attr_test (struct aspath_tests *t)
1324: {
1325: printf ("%s\n", t->desc);
1326: printf ("%s\n\n", handle_attr_test (t) ? FAILED : OK);
1327: }
1328:
1329: int
1330: main (void)
1331: {
1332: int i = 0;
1333: bgp_master_init ();
1334: master = bm->master;
1335: bgp_option_set (BGP_OPT_NO_LISTEN);
1336: bgp_attr_init ();
1337:
1338: while (test_segments[i].name)
1339: {
1340: printf ("test %u\n", i);
1341: parse_test (&test_segments[i]);
1342: empty_prepend_test (&test_segments[i++]);
1343: }
1344:
1345: i = 0;
1346: while (prepend_tests[i].test1)
1347: {
1348: printf ("prepend test %u\n", i);
1349: prepend_test (&prepend_tests[i++]);
1350: }
1351:
1352: i = 0;
1353: while (aggregate_tests[i].test1)
1354: {
1355: printf ("aggregate test %u\n", i);
1356: aggregate_test (&aggregate_tests[i++]);
1357: }
1358:
1359: i = 0;
1360:
1361: while (reconcile_tests[i].test1)
1362: {
1363: printf ("reconcile test %u\n", i);
1364: as4_reconcile_test (&reconcile_tests[i++]);
1365: }
1366:
1367: i = 0;
1368:
1369: cmp_test();
1370:
1371: i = 0;
1372:
1373: empty_get_test();
1374:
1375: i = 0;
1376:
1377: while (aspath_tests[i].desc)
1378: {
1379: printf ("aspath_attr test %d\n", i);
1380: attr_test (&aspath_tests[i++]);
1381: }
1382:
1383: printf ("failures: %d\n", failed);
1384: printf ("aspath count: %ld\n", aspath_count());
1385:
1386: return (failed + aspath_count());
1387: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>