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