]> git.proxmox.com Git - mirror_frr.git/blob - tests/bgpd/test_aspath.c
3cc9a630727ca2d7305ca815b46a01ee89089a9d
[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 = {};
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 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",
275
276 "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",
277 250, 0, NOT_ALL_PRIVATE, 4096, 4, 8466},
278 },
279 {
280 /* 15 */
281 "seq1extra",
282 "seq(8466,3,52737,4096,3456)",
283 {0x2, 0x5, 0x21, 0x12, 0x00, 0x03, 0xce, 0x01, 0x10, 0x00, 0x0d,
284 0x80},
285 12,
286 {"8466 3 52737 4096 3456", "8466 3 52737 4096 3456", 5, 0,
287 NOT_ALL_PRIVATE, 4096, 4, 8466},
288 },
289 {
290 /* 16 */
291 "empty",
292 "<empty>",
293 {},
294 0,
295 {"", "", 0, 0, 0, 0, 0, 0},
296 },
297 {
298 /* 17 */
299 "redundantset",
300 "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153)",
301 {0x2, 0x5, 0x21, 0x12, 0x00, 0x03, 0xce, 0x01,
302 0x10, 0x00, 0x0d, 0x80, 0x1, 0x4, 0x1b, 0xbb,
303 0x1f, 0xd9, 0x1f, 0xd9, 0x1f, 0xd9},
304 22,
305 {/* We shouldn't ever /generate/ such paths. However, we should
306 * cope with them fine.
307 */
308 "8466 3 52737 4096 3456 {7099,8153}",
309 "8466 3 52737 4096 3456 {7099,8153}", 6, 0, NOT_ALL_PRIVATE,
310 4096, 4, 8466},
311 },
312 {
313 /* 18 */
314 "reconcile_lead_asp",
315 "seq(6435,59408,21665) set(23456,23456,23456), seq(23456,23456,23456)",
316 {0x2, 0x3, 0x19, 0x23, 0xe8, 0x10, 0x54, 0xa1,
317 0x1, 0x3, 0x5b, 0xa0, 0x5b, 0xa0, 0x5b, 0xa0,
318 0x2, 0x3, 0x5b, 0xa0, 0x5b, 0xa0, 0x5b, 0xa0},
319 24,
320 {"6435 59408 21665 {23456} 23456 23456 23456",
321 "6435 59408 21665 {23456} 23456 23456 23456", 7, 0,
322 NOT_ALL_PRIVATE, 23456, 1, 6435},
323 },
324 {
325 /* 19 */
326 "reconcile_new_asp",
327 "set(2457,61697,4369), seq(1842,41591,51793)",
328 {0x1, 0x3, 0x09, 0x99, 0xf1, 0x01, 0x11, 0x11, 0x2, 0x3, 0x07,
329 0x32, 0xa2, 0x77, 0xca, 0x51},
330 16,
331 {"{2457,4369,61697} 1842 41591 51793",
332 "{2457,4369,61697} 1842 41591 51793", 4, 0, NOT_ALL_PRIVATE,
333 51793, 1, 2457},
334 },
335 {
336 /* 20 */
337 "reconcile_confed",
338 "confseq(123,456,789) confset(456,124,788) seq(6435,59408,21665) set(23456,23456,23456), seq(23456,23456,23456)",
339 {0x3, 0x3, 0x00, 0x7b, 0x01, 0xc8, 0x03, 0x15, 0x4, 0x3,
340 0x01, 0xc8, 0x00, 0x7c, 0x03, 0x14, 0x2, 0x3, 0x19, 0x23,
341 0xe8, 0x10, 0x54, 0xa1, 0x1, 0x3, 0x5b, 0xa0, 0x5b, 0xa0,
342 0x5b, 0xa0, 0x2, 0x3, 0x5b, 0xa0, 0x5b, 0xa0, 0x5b, 0xa0},
343 40,
344 {"(123 456 789) [124,456,788] 6435 59408 21665 {23456} 23456 23456 23456",
345 "6435 59408 21665 {23456} 23456 23456 23456", 7, 4,
346 NOT_ALL_PRIVATE, 23456, 1, 6435},
347 },
348 {
349 /* 21 */
350 "reconcile_start_trans",
351 "seq(23456,23456,23456) seq(6435,59408,21665)",
352 {
353 0x2, 0x3, 0x5b, 0xa0, 0x5b, 0xa0, 0x5b, 0xa0, 0x2, 0x3,
354 0x19, 0x23, 0xe8, 0x10, 0x54, 0xa1,
355 },
356 16,
357 {"23456 23456 23456 6435 59408 21665",
358 "23456 23456 23456 6435 59408 21665", 6, 0, NOT_ALL_PRIVATE,
359 21665, 1, 23456},
360 },
361 {
362 /* 22 */
363 "reconcile_start_trans4",
364 "seq(1842,41591,51793) seq(6435,59408,21665)",
365 {
366 0x2, 0x3, 0x07, 0x32, 0xa2, 0x77, 0xca, 0x51, 0x2, 0x3,
367 0x19, 0x23, 0xe8, 0x10, 0x54, 0xa1,
368 },
369 16,
370 {"1842 41591 51793 6435 59408 21665",
371 "1842 41591 51793 6435 59408 21665", 6, 0, NOT_ALL_PRIVATE,
372 41591, 1, 1842},
373 },
374 {
375 /* 23 */
376 "reconcile_start_trans_error",
377 "seq(23456,23456,23456) seq(6435,59408)",
378 {
379 0x2, 0x3, 0x5b, 0xa0, 0x5b, 0xa0, 0x5b, 0xa0, 0x2, 0x2,
380 0x19, 0x23, 0xe8, 0x10,
381 },
382 14,
383 {"23456 23456 23456 6435 59408", "23456 23456 23456 6435 59408",
384 5, 0, NOT_ALL_PRIVATE, 59408, 1, 23456},
385 },
386 {
387 /* 24 */
388 "redundantset2",
389 "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153,7099)",
390 {
391 0x2, 0x5, 0x21, 0x12, 0x00, 0x03, 0xce, 0x01,
392 0x10, 0x00, 0x0d, 0x80, 0x1, 0x5, 0x1b, 0xbb,
393 0x1f, 0xd9, 0x1f, 0xd9, 0x1f, 0xd9, 0x1b, 0xbb,
394 },
395 24,
396 {/* We should weed out duplicate set members. */
397 "8466 3 52737 4096 3456 {7099,8153}",
398 "8466 3 52737 4096 3456 {7099,8153}", 6, 0, NOT_ALL_PRIVATE,
399 4096, 4, 8466},
400 },
401 {
402 /* 25 */
403 "zero-size overflow",
404 "#ASNs = 0, data = seq(8466 3 52737 4096 3456)",
405 {0x2, 0x0, 0x21, 0x12, 0x00, 0x03, 0xce, 0x01, 0x10, 0x00, 0x0d,
406 0x80},
407 12,
408 {NULL, NULL, 0, 0, 0, 0, 0, 0},
409 },
410 {
411 /* 26 */
412 "zero-size overflow + valid segment",
413 "seq(#AS=0:8466 3 52737),seq(4096 3456)",
414 {0x2, 0x0, 0x21, 0x12, 0x00, 0x03, 0xce, 0x01, 0x2, 0x2, 0x10,
415 0x00, 0x0d, 0x80},
416 14,
417 {NULL, NULL, 0, 0, 0, 0, 0, 0},
418 },
419 {
420 /* 27 */
421 "invalid segment type",
422 "type=8(4096 3456)",
423 {0x8, 0x2, 0x10, 0x00, 0x0d, 0x80},
424 14,
425 {NULL, NULL, 0, 0, 0, 0, 0, 0},
426 },
427 {
428 /* 28 */
429 "BGP_AS_ZERO",
430 "seq(8466,3,52737,0,4096)",
431 {0x2, 0x5,
432 0x21, 0x12,
433 0x00, 0x03,
434 0xce, 0x01,
435 0x00, 0x00,
436 0x10, 0x00},
437 12,
438 {"8466 3 52737 0 4096", "8466 3 52737 0 4096", 5, 0,
439 NOT_ALL_PRIVATE, 4096, 4, 8466},
440 },
441 {NULL, NULL, {0}, 0, {NULL, 0, 0}}};
442
443 #define COMMON_ATTRS \
444 BGP_ATTR_FLAG_TRANS, BGP_ATTR_ORIGIN, 1, BGP_ORIGIN_EGP, \
445 BGP_ATTR_FLAG_TRANS, BGP_ATTR_NEXT_HOP, 4, 192, 0, 2, 0
446 #define COMMON_ATTR_SIZE 11
447
448 /* */
449 static struct aspath_tests {
450 const char *desc;
451 const struct test_segment *segment;
452 const char *shouldbe; /* String it should evaluate to */
453 const enum as4 {
454 AS4_DATA,
455 AS2_DATA
456 } as4; /* whether data should be as4 or not (ie as2) */
457 const int result; /* expected result for bgp_attr_parse */
458 const int cap; /* capabilities to set for peer */
459 const char attrheader[1024];
460 size_t len;
461 const struct test_segment *old_segment;
462 } aspath_tests[] = {
463 /* 0 */
464 {
465 "basic test",
466 &test_segments[0],
467 "8466 3 52737 4096",
468 AS2_DATA,
469 0,
470 0,
471 {
472 COMMON_ATTRS,
473 BGP_ATTR_FLAG_TRANS,
474 BGP_ATTR_AS_PATH,
475 10,
476 },
477 COMMON_ATTR_SIZE + 3,
478 },
479 /* 1 */
480 {
481 "length too short",
482 &test_segments[0],
483 "8466 3 52737 4096",
484 AS2_DATA,
485 -1,
486 0,
487 {
488 COMMON_ATTRS,
489 BGP_ATTR_FLAG_TRANS,
490 BGP_ATTR_AS_PATH,
491 8,
492 },
493 COMMON_ATTR_SIZE + 3,
494 },
495 /* 2 */
496 {
497 "length too long",
498 &test_segments[0],
499 "8466 3 52737 4096",
500 AS2_DATA,
501 -1,
502 0,
503 {
504 COMMON_ATTRS,
505 BGP_ATTR_FLAG_TRANS,
506 BGP_ATTR_AS_PATH,
507 12,
508 },
509 COMMON_ATTR_SIZE + 3,
510 },
511 /* 3 */
512 {
513 "incorrect flag",
514 &test_segments[0],
515 "8466 3 52737 4096",
516 AS2_DATA,
517 -1,
518 0,
519 {
520 COMMON_ATTRS,
521 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
522 BGP_ATTR_AS_PATH,
523 10,
524 },
525 COMMON_ATTR_SIZE + 3,
526 },
527 /* 4 */
528 {
529 "as4_path, with as2 format data",
530 &test_segments[0],
531 "8466 3 52737 4096",
532 AS2_DATA,
533 -1,
534 0,
535 {
536 COMMON_ATTRS,
537 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
538 BGP_ATTR_AS4_PATH,
539 10,
540 },
541 COMMON_ATTR_SIZE + 3,
542 },
543 /* 5 */
544 {
545 "as4, with incorrect attr length",
546 &test_segments[0],
547 "8466 3 52737 4096",
548 AS4_DATA,
549 -1,
550 PEER_CAP_AS4_RCV,
551 {
552 COMMON_ATTRS,
553 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
554 BGP_ATTR_AS4_PATH,
555 10,
556 },
557 COMMON_ATTR_SIZE + 3,
558 },
559 /* 6 */
560 {
561 "basic 4-byte as-path",
562 &test_segments[0],
563 "8466 3 52737 4096",
564 AS4_DATA,
565 0,
566 PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
567 {
568 COMMON_ATTRS,
569 BGP_ATTR_FLAG_TRANS,
570 BGP_ATTR_AS_PATH,
571 18,
572 },
573 COMMON_ATTR_SIZE + 3,
574 },
575 /* 7 */
576 {
577 "4b AS_PATH: too short",
578 &test_segments[0],
579 "8466 3 52737 4096",
580 AS4_DATA,
581 -1,
582 PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
583 {
584 COMMON_ATTRS,
585 BGP_ATTR_FLAG_TRANS,
586 BGP_ATTR_AS_PATH,
587 16,
588 },
589 COMMON_ATTR_SIZE + 3,
590 },
591 /* 8 */
592 {
593 "4b AS_PATH: too long",
594 &test_segments[0],
595 "8466 3 52737 4096",
596 AS4_DATA,
597 -1,
598 PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
599 {
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,
613 -1,
614 PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
615 {
616 COMMON_ATTRS,
617 BGP_ATTR_FLAG_TRANS,
618 BGP_ATTR_AS_PATH,
619 22,
620 },
621 COMMON_ATTR_SIZE + 3,
622 },
623 /* 10 */
624 {
625 "4b AS_PATH: bad flags",
626 &test_segments[0],
627 "8466 3 52737 4096",
628 AS4_DATA,
629 -1,
630 PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
631 {
632 COMMON_ATTRS,
633 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
634 BGP_ATTR_AS_PATH,
635 18,
636 },
637 COMMON_ATTR_SIZE + 3,
638 },
639 /* 11 */
640 {
641 "4b AS4_PATH w/o AS_PATH",
642 &test_segments[6],
643 NULL,
644 AS4_DATA,
645 -2,
646 PEER_CAP_AS4_ADV,
647 {
648 COMMON_ATTRS,
649 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
650 BGP_ATTR_AS4_PATH,
651 14,
652 },
653 COMMON_ATTR_SIZE + 3,
654 },
655 /* 12 */
656 {
657 "4b AS4_PATH: confed",
658 &test_segments[6],
659 "8466 3 52737 4096 (123 456 789)",
660 AS4_DATA,
661 0,
662 PEER_CAP_AS4_ADV,
663 {
664 COMMON_ATTRS,
665 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
666 BGP_ATTR_AS4_PATH,
667 14,
668 },
669 COMMON_ATTR_SIZE + 3,
670 &test_segments[0],
671 },
672 /* 13 */
673 {
674 "4b AS4_PATH: BGP_AS_ZERO",
675 &test_segments[28],
676 "8466 3 52737 0 4096",
677 AS4_DATA,
678 -2,
679 PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
680 {
681 COMMON_ATTRS,
682 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
683 BGP_ATTR_AS4_PATH,
684 22,
685 },
686 COMMON_ATTR_SIZE + 3,
687 },
688 {NULL, NULL, NULL, 0, 0, 0, {0}, 0},
689 };
690
691 /* prepending tests */
692 static struct tests {
693 const struct test_segment *test1;
694 const struct test_segment *test2;
695 struct test_spec sp;
696 } prepend_tests[] = {
697 /* 0 */
698 {
699 &test_segments[0],
700 &test_segments[1],
701 {"8466 3 52737 4096 8722 4", "8466 3 52737 4096 8722 4", 6, 0,
702 NOT_ALL_PRIVATE, 4096, 1, 8466},
703 },
704 /* 1 */
705 {&test_segments[1],
706 &test_segments[3],
707 {"8722 4 8482 51457 {5204}", "8722 4 8482 51457 {5204}", 5, 0,
708 NOT_ALL_PRIVATE, 5204, 1, 8722}},
709 /* 2 */
710 {
711 &test_segments[3],
712 &test_segments[4],
713 {"8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
714 "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}", 7,
715 0, NOT_ALL_PRIVATE, 5204, 1, 8482},
716 },
717 /* 3 */
718 {&test_segments[4],
719 &test_segments[5],
720 {"8467 59649 {4196,48658} {17322,30745} 6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
721 "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
722 11, 0, NOT_ALL_PRIVATE, 61697, 1, 8467}},
723 /* 4 */
724 {
725 &test_segments[5],
726 &test_segments[6],
727 {"6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
728 "6435 59408 21665 {2457,4369,61697} 1842 41590 51793", 7, 0,
729 NOT_ALL_PRIVATE, 1842, 1, 6435},
730 },
731 /* 5 */
732 {&test_segments[6],
733 &test_segments[7],
734 {"(123 456 789) (123 456 789) (111 222)", "", 0, 8, NOT_ALL_PRIVATE,
735 111, 1, 0}},
736 {&test_segments[7],
737 &test_segments[8],
738 {"(123 456 789) (111 222) [123,456,789]", "", 0, 6, NOT_ALL_PRIVATE,
739 111, 1, 0}},
740 {
741 &test_segments[8],
742 &test_segments[9],
743 {"[123,456,789] (123 456 789) [111,222] 8722 {4196,48658}",
744 "8722 {4196,48658}", 2, 5, NOT_ALL_PRIVATE, 456, 1, NULL_ASN},
745 },
746 {
747 &test_segments[9],
748 &test_segments[8],
749 {"(123 456 789) [111,222] 8722 {4196,48658} [123,456,789]",
750 "8722 {4196,48658}", 2, 5, NOT_ALL_PRIVATE, 48658, 1,
751 NULL_ASN},
752 },
753 {
754 &test_segments[14],
755 &test_segments[11],
756 {"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",
757
758 "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",
759 257, 0, NOT_ALL_PRIVATE, 4096, 1000, 8466},
760 },
761 {NULL,
762 NULL,
763 {
764 NULL, 0, 0, 0, 0, 0, 0,
765 }},
766 };
767
768 struct tests reconcile_tests[] = {
769 {
770 &test_segments[18],
771 &test_segments[19],
772 {"6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
773 "6435 59408 21665 {2457,4369,61697} 1842 41591 51793", 7, 0,
774 NOT_ALL_PRIVATE, 51793, 1, 6435},
775 },
776 {
777 &test_segments[19],
778 &test_segments[18],
779 /* AS_PATH (19) has more hops than NEW_AS_PATH,
780 * so just AS_PATH should be used (though, this practice
781 * is bad imho).
782 */
783 {"{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456",
784 "{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456",
785 11, 0, NOT_ALL_PRIVATE, 51793, 1, 6435},
786 },
787 {
788 &test_segments[20],
789 &test_segments[19],
790 {"(123 456 789) [124,456,788] 6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
791 "6435 59408 21665 {2457,4369,61697} 1842 41591 51793", 7, 4,
792 NOT_ALL_PRIVATE, 51793, 1, 6435},
793 },
794 {
795 &test_segments[21],
796 &test_segments[22],
797 {"1842 41591 51793 6435 59408 21665",
798 "1842 41591 51793 6435 59408 21665", 6, 0, NOT_ALL_PRIVATE,
799 51793, 1, 1842},
800 },
801 {
802 &test_segments[23],
803 &test_segments[22],
804 {"23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665",
805 "23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665",
806 11, 0, NOT_ALL_PRIVATE, 51793, 1, 1842},
807 },
808 {NULL,
809 NULL,
810 {
811 NULL, 0, 0, 0, 0, 0, 0,
812 }},
813 };
814
815 struct tests aggregate_tests[] = {
816 {
817 &test_segments[0],
818 &test_segments[2],
819 {"8466 3 52737 4096 {4,8722}", "8466 3 52737 4096 {4,8722}", 5,
820 0, NOT_ALL_PRIVATE, 4, 1, 8466},
821 },
822 {
823 &test_segments[2],
824 &test_segments[0],
825 {"8466 3 52737 4096 {4,8722}", "8466 3 52737 4096 {4,8722}", 5,
826 0, NOT_ALL_PRIVATE, 8722, 1, 8466},
827 },
828 {
829 &test_segments[2],
830 &test_segments[10],
831 {"8466 {2,3,4,4096,8722,52737}", "8466 {2,3,4,4096,8722,52737}",
832 2, 0, NOT_ALL_PRIVATE, 8722, 5, 8466},
833 },
834 {
835 &test_segments[10],
836 &test_segments[2],
837 {"8466 {2,3,4,4096,8722,52737}", "8466 {2,3,4,4096,8722,52737}",
838 2, 0, NOT_ALL_PRIVATE, 2, 20000, 8466},
839 },
840
841 {
842 &test_segments[5],
843 &test_segments[18],
844 {"6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}",
845 "6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}", 4,
846 0, NOT_ALL_PRIVATE, 41590, 1, 6435},
847 },
848
849 {NULL, NULL, {NULL, 0, 0}},
850 };
851
852 struct compare_tests {
853 int test_index1;
854 int test_index2;
855 #define CMP_RES_YES 1
856 #define CMP_RES_NO 0
857 char shouldbe_cmp;
858 char shouldbe_confed;
859 } left_compare[] = {
860 {0, 1, CMP_RES_NO, CMP_RES_NO}, {0, 2, CMP_RES_YES, CMP_RES_NO},
861 {0, 11, CMP_RES_YES, CMP_RES_NO}, {0, 15, CMP_RES_YES, CMP_RES_NO},
862 {0, 16, CMP_RES_NO, CMP_RES_NO}, {1, 11, CMP_RES_NO, CMP_RES_NO},
863 {6, 7, CMP_RES_NO, CMP_RES_YES}, {6, 8, CMP_RES_NO, CMP_RES_NO},
864 {7, 8, CMP_RES_NO, CMP_RES_NO}, {1, 9, CMP_RES_YES, CMP_RES_NO},
865 {0, 9, CMP_RES_NO, CMP_RES_NO}, {3, 9, CMP_RES_NO, CMP_RES_NO},
866 {0, 6, CMP_RES_NO, CMP_RES_NO}, {1, 6, CMP_RES_NO, CMP_RES_NO},
867 {0, 8, CMP_RES_NO, CMP_RES_NO}, {1, 8, CMP_RES_NO, CMP_RES_NO},
868 {11, 6, CMP_RES_NO, CMP_RES_NO}, {11, 7, CMP_RES_NO, CMP_RES_NO},
869 {11, 8, CMP_RES_NO, CMP_RES_NO}, {9, 6, CMP_RES_NO, CMP_RES_YES},
870 {9, 7, CMP_RES_NO, CMP_RES_YES}, {9, 8, CMP_RES_NO, CMP_RES_NO},
871 };
872
873 /* make an aspath from a data stream */
874 static struct aspath *make_aspath(const uint8_t *data, size_t len, int use32bit)
875 {
876 struct stream *s = NULL;
877 struct aspath *as;
878
879 if (len) {
880 s = stream_new(len);
881 stream_put(s, data, len);
882 }
883 as = aspath_parse(s, len, use32bit);
884
885 if (s)
886 stream_free(s);
887
888 return as;
889 }
890
891 static void printbytes(const uint8_t *bytes, int len)
892 {
893 int i = 0;
894 while (i < len) {
895 if (i % 2)
896 printf("%02hhx%s", bytes[i], " ");
897 else
898 printf("0x%02hhx", bytes[i]);
899 i++;
900 }
901 printf("\n");
902 }
903
904 /* validate the given aspath */
905 static int validate(struct aspath *as, const struct test_spec *sp)
906 {
907 size_t bytes, bytes4;
908 int fails = 0;
909 const uint8_t *out;
910 static struct stream *s;
911 struct aspath *asinout, *asconfeddel, *asstr, *as4;
912
913 if (as == NULL && sp->shouldbe == NULL) {
914 printf("Correctly failed to parse\n");
915 return fails;
916 }
917
918 out = aspath_snmp_pathseg(as, &bytes);
919 asinout = make_aspath(out, bytes, 0);
920
921 /* Excercise AS4 parsing a bit, with a dogfood test */
922 if (!s)
923 s = stream_new(BGP_MAX_PACKET_SIZE);
924 bytes4 = aspath_put(s, as, 1);
925 as4 = make_aspath(STREAM_DATA(s), bytes4, 1);
926
927 asstr = aspath_str2aspath(sp->shouldbe);
928
929 asconfeddel = aspath_delete_confed_seq(aspath_dup(asinout));
930
931 printf("got: %s\n", aspath_print(as));
932
933 /* the parsed path should match the specified 'shouldbe' string.
934 * We should pass the "eat our own dog food" test, be able to output
935 * this path and then input it again. Ie the path resulting from:
936 *
937 * aspath_parse(aspath_put(as))
938 *
939 * should:
940 *
941 * - also match the specified 'shouldbe' value
942 * - hash to same value as original path
943 * - have same hops and confed counts as original, and as the
944 * the specified counts
945 *
946 * aspath_str2aspath() and shouldbe should match
947 *
948 * We do the same for:
949 *
950 * aspath_parse(aspath_put(as,USE32BIT))
951 *
952 * Confederation related tests:
953 * - aspath_delete_confed_seq(aspath) should match shouldbe_confed
954 * - aspath_delete_confed_seq should be idempotent.
955 */
956 if (strcmp(aspath_print(as), sp->shouldbe)
957 /* hash validation */
958 || (aspath_key_make(as) != aspath_key_make(asinout))
959 /* by string */
960 || strcmp(aspath_print(asinout), sp->shouldbe)
961 /* By 4-byte parsing */
962 || strcmp(aspath_print(as4), sp->shouldbe)
963 /* by various path counts */
964 || (aspath_count_hops(as) != sp->hops)
965 || (aspath_count_confeds(as) != sp->confeds)
966 || (aspath_count_hops(asinout) != sp->hops)
967 || (aspath_count_confeds(asinout) != sp->confeds)) {
968 failed++;
969 fails++;
970 printf("shouldbe:\n%s\n", sp->shouldbe);
971 printf("as4:\n%s\n", aspath_print(as4));
972 printf("hash keys: in: %d out->in: %d\n", aspath_key_make(as),
973 aspath_key_make(asinout));
974 printf("hops: %d, counted %d %d\n", sp->hops,
975 aspath_count_hops(as), aspath_count_hops(asinout));
976 printf("confeds: %d, counted %d %d\n", sp->confeds,
977 aspath_count_confeds(as), aspath_count_confeds(asinout));
978 printf("out->in:\n%s\nbytes: ", aspath_print(asinout));
979 printbytes(out, bytes);
980 }
981 /* basic confed related tests */
982 if ((aspath_print(asconfeddel) == NULL
983 && sp->shouldbe_delete_confed != NULL)
984 || (aspath_print(asconfeddel) != NULL
985 && sp->shouldbe_delete_confed == NULL)
986 || strcmp(aspath_print(asconfeddel), sp->shouldbe_delete_confed)
987 /* delete_confed_seq should be idempotent */
988 || (aspath_key_make(asconfeddel)
989 != aspath_key_make(aspath_delete_confed_seq(asconfeddel)))) {
990 failed++;
991 fails++;
992 printf("as-path minus confeds is: %s\n",
993 aspath_print(asconfeddel));
994 printf("as-path minus confeds should be: %s\n",
995 sp->shouldbe_delete_confed);
996 }
997 /* aspath_str2aspath test */
998 if ((aspath_print(asstr) == NULL && sp->shouldbe != NULL)
999 || (aspath_print(asstr) != NULL && sp->shouldbe == NULL)
1000 || strcmp(aspath_print(asstr), sp->shouldbe)) {
1001 failed++;
1002 fails++;
1003 printf("asstr: %s\n", aspath_print(asstr));
1004 }
1005
1006 /* loop, private and first as checks */
1007 if ((sp->does_loop && aspath_loop_check(as, sp->does_loop) == 0)
1008 || (sp->doesnt_loop && aspath_loop_check(as, sp->doesnt_loop) != 0)
1009 || (aspath_private_as_check(as) != sp->private_as)
1010 || (aspath_firstas_check(as, sp->first) && sp->first == 0)) {
1011 failed++;
1012 fails++;
1013 printf("firstas: %d, got %d\n", sp->first,
1014 aspath_firstas_check(as, sp->first));
1015 printf("loop does: %d %d, doesnt: %d %d\n", sp->does_loop,
1016 aspath_loop_check(as, sp->does_loop), sp->doesnt_loop,
1017 aspath_loop_check(as, sp->doesnt_loop));
1018 printf("private check: %d %d\n", sp->private_as,
1019 aspath_private_as_check(as));
1020 }
1021 aspath_unintern(&asinout);
1022 aspath_unintern(&as4);
1023
1024 aspath_free(asconfeddel);
1025 aspath_free(asstr);
1026 stream_reset(s);
1027
1028 return fails;
1029 }
1030
1031 static void empty_get_test(void)
1032 {
1033 struct aspath *as = aspath_empty_get();
1034 struct test_spec sp = {"", "", 0, 0, 0, 0, 0, 0};
1035
1036 printf("empty_get_test, as: %s\n", aspath_print(as));
1037 if (!validate(as, &sp))
1038 printf("%s\n", OK);
1039 else
1040 printf("%s!\n", FAILED);
1041
1042 printf("\n");
1043
1044 aspath_free(as);
1045 }
1046
1047 /* basic parsing test */
1048 static void parse_test(struct test_segment *t)
1049 {
1050 struct aspath *asp;
1051
1052 printf("%s: %s\n", t->name, t->desc);
1053
1054 asp = make_aspath(t->asdata, t->len, 0);
1055
1056 printf("aspath: %s\nvalidating...:\n", aspath_print(asp));
1057
1058 if (!validate(asp, &t->sp))
1059 printf(OK "\n");
1060 else
1061 printf(FAILED "\n");
1062
1063 printf("\n");
1064
1065 aspath_unintern(&asp);
1066 }
1067
1068 /* prepend testing */
1069 static void prepend_test(struct tests *t)
1070 {
1071 struct aspath *asp1, *asp2, *ascratch;
1072
1073 printf("prepend %s: %s\n", t->test1->name, t->test1->desc);
1074 printf("to %s: %s\n", t->test2->name, t->test2->desc);
1075
1076 asp1 = make_aspath(t->test1->asdata, t->test1->len, 0);
1077 asp2 = make_aspath(t->test2->asdata, t->test2->len, 0);
1078
1079 ascratch = aspath_dup(asp2);
1080 aspath_unintern(&asp2);
1081
1082 asp2 = aspath_prepend(asp1, ascratch);
1083
1084 printf("aspath: %s\n", aspath_print(asp2));
1085
1086 if (!validate(asp2, &t->sp))
1087 printf("%s\n", OK);
1088 else
1089 printf("%s!\n", FAILED);
1090
1091 printf("\n");
1092 aspath_unintern(&asp1);
1093 aspath_free(asp2);
1094 }
1095
1096 /* empty-prepend testing */
1097 static void empty_prepend_test(struct test_segment *t)
1098 {
1099 struct aspath *asp1, *asp2, *ascratch;
1100
1101 printf("empty prepend %s: %s\n", t->name, t->desc);
1102
1103 asp1 = make_aspath(t->asdata, t->len, 0);
1104 asp2 = aspath_empty();
1105
1106 ascratch = aspath_dup(asp2);
1107 aspath_unintern(&asp2);
1108
1109 asp2 = aspath_prepend(asp1, ascratch);
1110
1111 printf("aspath: %s\n", aspath_print(asp2));
1112
1113 if (!validate(asp2, &t->sp))
1114 printf(OK "\n");
1115 else
1116 printf(FAILED "!\n");
1117
1118 printf("\n");
1119 aspath_unintern(&asp1);
1120 aspath_free(asp2);
1121 }
1122
1123 /* as2+as4 reconciliation testing */
1124 static void as4_reconcile_test(struct tests *t)
1125 {
1126 struct aspath *asp1, *asp2, *ascratch;
1127
1128 printf("reconciling %s:\n %s\n", t->test1->name, t->test1->desc);
1129 printf("with %s:\n %s\n", t->test2->name, t->test2->desc);
1130
1131 asp1 = make_aspath(t->test1->asdata, t->test1->len, 0);
1132 asp2 = make_aspath(t->test2->asdata, t->test2->len, 0);
1133
1134 ascratch = aspath_reconcile_as4(asp1, asp2);
1135
1136 if (!validate(ascratch, &t->sp))
1137 printf(OK "\n");
1138 else
1139 printf(FAILED "!\n");
1140
1141 printf("\n");
1142 aspath_unintern(&asp1);
1143 aspath_unintern(&asp2);
1144 aspath_free(ascratch);
1145 }
1146
1147
1148 /* aggregation testing */
1149 static void aggregate_test(struct tests *t)
1150 {
1151 struct aspath *asp1, *asp2, *ascratch;
1152
1153 printf("aggregate %s: %s\n", t->test1->name, t->test1->desc);
1154 printf("with %s: %s\n", t->test2->name, t->test2->desc);
1155
1156 asp1 = make_aspath(t->test1->asdata, t->test1->len, 0);
1157 asp2 = make_aspath(t->test2->asdata, t->test2->len, 0);
1158
1159 ascratch = aspath_aggregate(asp1, asp2);
1160
1161 if (!validate(ascratch, &t->sp))
1162 printf(OK "\n");
1163 else
1164 printf(FAILED "!\n");
1165
1166 printf("\n");
1167 aspath_unintern(&asp1);
1168 aspath_unintern(&asp2);
1169 aspath_free(ascratch);
1170 /* aspath_unintern (ascratch);*/
1171 }
1172
1173 /* cmp_left tests */
1174 static void cmp_test(void)
1175 {
1176 unsigned int i;
1177 #define CMP_TESTS_MAX (sizeof(left_compare) / sizeof(struct compare_tests))
1178
1179 for (i = 0; i < CMP_TESTS_MAX; i++) {
1180 struct test_segment *t1 =
1181 &test_segments[left_compare[i].test_index1];
1182 struct test_segment *t2 =
1183 &test_segments[left_compare[i].test_index2];
1184 struct aspath *asp1, *asp2;
1185
1186 printf("left cmp %s: %s\n", t1->name, t1->desc);
1187 printf("and %s: %s\n", t2->name, t2->desc);
1188
1189 asp1 = make_aspath(t1->asdata, t1->len, 0);
1190 asp2 = make_aspath(t2->asdata, t2->len, 0);
1191
1192 if (aspath_cmp_left(asp1, asp2) != left_compare[i].shouldbe_cmp
1193 || aspath_cmp_left(asp2, asp1)
1194 != left_compare[i].shouldbe_cmp
1195 || aspath_cmp_left_confed(asp1, asp2)
1196 != left_compare[i].shouldbe_confed
1197 || aspath_cmp_left_confed(asp2, asp1)
1198 != left_compare[i].shouldbe_confed) {
1199 failed++;
1200 printf(FAILED "\n");
1201 printf("result should be: cmp: %d, confed: %d\n",
1202 left_compare[i].shouldbe_cmp,
1203 left_compare[i].shouldbe_confed);
1204 printf("got: cmp %d, cmp_confed: %d\n",
1205 aspath_cmp_left(asp1, asp2),
1206 aspath_cmp_left_confed(asp1, asp2));
1207 printf("path1: %s\npath2: %s\n", aspath_print(asp1),
1208 aspath_print(asp2));
1209 } else
1210 printf(OK "\n");
1211
1212 printf("\n");
1213 aspath_unintern(&asp1);
1214 aspath_unintern(&asp2);
1215 }
1216 }
1217
1218 static int handle_attr_test(struct aspath_tests *t)
1219 {
1220 struct bgp bgp = {0};
1221 struct peer peer = {0};
1222 struct attr attr = {0};
1223 int ret;
1224 int initfail = failed;
1225 struct aspath *asp;
1226 size_t datalen;
1227
1228 asp = make_aspath(t->segment->asdata, t->segment->len, 0);
1229
1230 peer.curr = stream_new(BGP_MAX_PACKET_SIZE);
1231 peer.obuf = stream_fifo_new();
1232 peer.bgp = &bgp;
1233 peer.host = (char *)"none";
1234 peer.fd = -1;
1235 peer.cap = t->cap;
1236 peer.max_packet_size = BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
1237
1238 stream_write(peer.curr, t->attrheader, t->len);
1239 datalen = aspath_put(peer.curr, asp, t->as4 == AS4_DATA);
1240 if (t->old_segment) {
1241 char dummyaspath[] = {BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH,
1242 t->old_segment->len};
1243 stream_write(peer.curr, dummyaspath, sizeof(dummyaspath));
1244 stream_write(peer.curr, t->old_segment->asdata,
1245 t->old_segment->len);
1246 datalen += sizeof(dummyaspath) + t->old_segment->len;
1247 }
1248
1249 ret = bgp_attr_parse(&peer, &attr, t->len + datalen, NULL, NULL);
1250
1251 if (ret != t->result) {
1252 printf("bgp_attr_parse returned %d, expected %d\n", ret,
1253 t->result);
1254 printf("datalen %zd\n", datalen);
1255 failed++;
1256 }
1257 if (ret != 0)
1258 goto out;
1259
1260 if (t->shouldbe && attr.aspath == NULL) {
1261 printf("aspath is NULL, but should be: %s\n", t->shouldbe);
1262 failed++;
1263 }
1264 if (t->shouldbe && attr.aspath
1265 && strcmp(attr.aspath->str, t->shouldbe)) {
1266 printf("attr str and 'shouldbe' mismatched!\n"
1267 "attr str: %s\n"
1268 "shouldbe: %s\n",
1269 attr.aspath->str, t->shouldbe);
1270 failed++;
1271 }
1272 if (!t->shouldbe && attr.aspath) {
1273 printf("aspath should be NULL, but is: %s\n", attr.aspath->str);
1274 failed++;
1275 }
1276
1277 out:
1278 aspath_unintern(&attr.aspath);
1279 aspath_unintern(&asp);
1280 return failed - initfail;
1281 }
1282
1283 static void attr_test(struct aspath_tests *t)
1284 {
1285 printf("%s\n", t->desc);
1286 printf("%s\n\n", handle_attr_test(t) ? FAILED : OK);
1287 }
1288
1289 int main(void)
1290 {
1291 int i = 0;
1292 qobj_init();
1293 bgp_master_init(thread_master_create(NULL), BGP_SOCKET_SNDBUF_SIZE,
1294 list_new());
1295 master = bm->master;
1296 bgp_option_set(BGP_OPT_NO_LISTEN);
1297 bgp_attr_init();
1298
1299 while (test_segments[i].name) {
1300 printf("test %u\n", i);
1301 parse_test(&test_segments[i]);
1302 empty_prepend_test(&test_segments[i++]);
1303 }
1304
1305 i = 0;
1306 while (prepend_tests[i].test1) {
1307 printf("prepend test %u\n", i);
1308 prepend_test(&prepend_tests[i++]);
1309 }
1310
1311 i = 0;
1312 while (aggregate_tests[i].test1) {
1313 printf("aggregate test %u\n", i);
1314 aggregate_test(&aggregate_tests[i++]);
1315 }
1316
1317 i = 0;
1318
1319 while (reconcile_tests[i].test1) {
1320 printf("reconcile test %u\n", i);
1321 as4_reconcile_test(&reconcile_tests[i++]);
1322 }
1323
1324 i = 0;
1325
1326 cmp_test();
1327
1328 i = 0;
1329
1330 empty_get_test();
1331
1332 i = 0;
1333
1334 frr_pthread_init();
1335 bgp_pthreads_init();
1336 bgp_pth_ka->running = true;
1337
1338 while (aspath_tests[i].desc) {
1339 printf("aspath_attr test %d\n", i);
1340 attr_test(&aspath_tests[i++]);
1341 }
1342
1343 printf("failures: %d\n", failed);
1344 printf("aspath count: %ld\n", aspath_count());
1345
1346 return (failed + aspath_count());
1347 }