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