GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: printconf.c,v 1.106 2017/08/12 16:47:50 phessler Exp $ */ |
||
2 |
|||
3 |
/* |
||
4 |
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> |
||
5 |
* Copyright (c) 2016 Job Snijders <job@instituut.net> |
||
6 |
* Copyright (c) 2016 Peter Hessler <phessler@openbsd.org> |
||
7 |
* |
||
8 |
* Permission to use, copy, modify, and distribute this software for any |
||
9 |
* purpose with or without fee is hereby granted, provided that the above |
||
10 |
* copyright notice and this permission notice appear in all copies. |
||
11 |
* |
||
12 |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||
13 |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||
14 |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||
15 |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||
16 |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA, PROFITS OR MIND, WHETHER IN |
||
17 |
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT |
||
18 |
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||
19 |
*/ |
||
20 |
|||
21 |
#include <limits.h> |
||
22 |
#include <stdio.h> |
||
23 |
#include <stdlib.h> |
||
24 |
#include <string.h> |
||
25 |
|||
26 |
#include "bgpd.h" |
||
27 |
#include "mrt.h" |
||
28 |
#include "session.h" |
||
29 |
#include "rde.h" |
||
30 |
#include "log.h" |
||
31 |
|||
32 |
void print_op(enum comp_ops); |
||
33 |
void print_community(int, int); |
||
34 |
void print_largecommunity(int64_t, int64_t, int64_t); |
||
35 |
void print_extcommunity(struct filter_extcommunity *); |
||
36 |
void print_origin(u_int8_t); |
||
37 |
void print_set(struct filter_set_head *); |
||
38 |
void print_mainconf(struct bgpd_config *); |
||
39 |
void print_rdomain_targets(struct filter_set_head *, const char *); |
||
40 |
void print_rdomain(struct rdomain *); |
||
41 |
const char *print_af(u_int8_t); |
||
42 |
void print_network(struct network_config *, const char *); |
||
43 |
void print_peer(struct peer_config *, struct bgpd_config *, |
||
44 |
const char *); |
||
45 |
const char *print_auth_alg(u_int8_t); |
||
46 |
const char *print_enc_alg(u_int8_t); |
||
47 |
void print_announce(struct peer_config *, const char *); |
||
48 |
void print_as(struct filter_rule *); |
||
49 |
void print_rule(struct peer *, struct filter_rule *); |
||
50 |
const char *mrt_type(enum mrt_type); |
||
51 |
void print_mrt(struct bgpd_config *, u_int32_t, u_int32_t, |
||
52 |
const char *, const char *); |
||
53 |
void print_groups(struct bgpd_config *, struct peer *); |
||
54 |
int peer_compare(const void *, const void *); |
||
55 |
|||
56 |
void |
||
57 |
print_op(enum comp_ops op) |
||
58 |
{ |
||
59 |
✓✗✗✗ ✗✗✓✗ ✗ |
208 |
switch (op) { |
60 |
case OP_RANGE: |
||
61 |
12 |
printf("-"); |
|
62 |
12 |
break; |
|
63 |
case OP_XRANGE: |
||
64 |
printf("><"); |
||
65 |
break; |
||
66 |
case OP_EQ: |
||
67 |
printf("="); |
||
68 |
break; |
||
69 |
case OP_NE: |
||
70 |
printf("!="); |
||
71 |
break; |
||
72 |
case OP_LE: |
||
73 |
printf("<="); |
||
74 |
break; |
||
75 |
case OP_LT: |
||
76 |
printf("<"); |
||
77 |
break; |
||
78 |
case OP_GE: |
||
79 |
92 |
printf(">="); |
|
80 |
92 |
break; |
|
81 |
case OP_GT: |
||
82 |
printf(">"); |
||
83 |
break; |
||
84 |
default: |
||
85 |
printf("?"); |
||
86 |
break; |
||
87 |
} |
||
88 |
104 |
} |
|
89 |
|||
90 |
void |
||
91 |
print_community(int as, int type) |
||
92 |
{ |
||
93 |
✗✓ | 16 |
if (as == COMMUNITY_ANY) |
94 |
printf("*:"); |
||
95 |
✗✓ | 8 |
else if (as == COMMUNITY_NEIGHBOR_AS) |
96 |
printf("neighbor-as:"); |
||
97 |
✓✓ | 8 |
else if (as == COMMUNITY_LOCAL_AS) |
98 |
4 |
printf("local-as:"); |
|
99 |
else |
||
100 |
4 |
printf("%u:", (unsigned int)as); |
|
101 |
|||
102 |
✗✓ | 8 |
if (type == COMMUNITY_ANY) |
103 |
printf("* "); |
||
104 |
✓✓ | 8 |
else if (type == COMMUNITY_NEIGHBOR_AS) |
105 |
4 |
printf("neighbor-as "); |
|
106 |
✗✓ | 4 |
else if (type == COMMUNITY_LOCAL_AS) |
107 |
printf("local-as"); |
||
108 |
else |
||
109 |
4 |
printf("%d ", type); |
|
110 |
8 |
} |
|
111 |
|||
112 |
void |
||
113 |
print_largecommunity(int64_t as, int64_t ld1, int64_t ld2) |
||
114 |
{ |
||
115 |
✗✓ | 8 |
if (as == COMMUNITY_ANY) |
116 |
printf("*:"); |
||
117 |
✗✓ | 4 |
else if (as == COMMUNITY_NEIGHBOR_AS) |
118 |
printf("neighbor-as:"); |
||
119 |
✓✗ | 4 |
else if (as == COMMUNITY_LOCAL_AS) |
120 |
4 |
printf("local-as:"); |
|
121 |
else |
||
122 |
printf("%lld:", as); |
||
123 |
|||
124 |
✗✓ | 4 |
if (ld1 == COMMUNITY_ANY) |
125 |
printf("*:"); |
||
126 |
✓✗ | 4 |
else if (ld1 == COMMUNITY_NEIGHBOR_AS) |
127 |
4 |
printf("neighbor-as:"); |
|
128 |
else if (ld1 == COMMUNITY_LOCAL_AS) |
||
129 |
printf("local-as:"); |
||
130 |
else |
||
131 |
printf("%lld:", ld1); |
||
132 |
|||
133 |
✓✗ | 4 |
if (ld2 == COMMUNITY_ANY) |
134 |
4 |
printf("* "); |
|
135 |
else if (ld2 == COMMUNITY_NEIGHBOR_AS) |
||
136 |
printf("neighbor-as "); |
||
137 |
else if (ld2 == COMMUNITY_LOCAL_AS) |
||
138 |
printf("local-as "); |
||
139 |
else |
||
140 |
printf("%lld ", ld2); |
||
141 |
|||
142 |
4 |
} |
|
143 |
|||
144 |
|||
145 |
void |
||
146 |
print_extcommunity(struct filter_extcommunity *c) |
||
147 |
{ |
||
148 |
40 |
printf("%s ", log_ext_subtype(c->type, c->subtype)); |
|
149 |
|||
150 |
✓✓✗✗ ✗✓✗ |
20 |
switch (c->type) { |
151 |
case EXT_COMMUNITY_TRANS_TWO_AS: |
||
152 |
4 |
printf("%hu:%u ", c->data.ext_as.as, c->data.ext_as.val); |
|
153 |
4 |
break; |
|
154 |
case EXT_COMMUNITY_TRANS_IPV4: |
||
155 |
8 |
printf("%s:%u ", inet_ntoa(c->data.ext_ip.addr), |
|
156 |
4 |
c->data.ext_ip.val); |
|
157 |
4 |
break; |
|
158 |
case EXT_COMMUNITY_TRANS_FOUR_AS: |
||
159 |
printf("%s:%u ", log_as(c->data.ext_as4.as4), |
||
160 |
c->data.ext_as.val); |
||
161 |
break; |
||
162 |
case EXT_COMMUNITY_TRANS_OPAQUE: |
||
163 |
case EXT_COMMUNITY_TRANS_EVPN: |
||
164 |
printf("0x%llx ", c->data.ext_opaq); |
||
165 |
break; |
||
166 |
case EXT_COMMUNITY_NON_TRANS_OPAQUE: |
||
167 |
✓✓✓✓ |
24 |
switch (c->data.ext_opaq) { |
168 |
case EXT_COMMUNITY_OVS_VALID: |
||
169 |
4 |
printf("valid "); |
|
170 |
4 |
break; |
|
171 |
case EXT_COMMUNITY_OVS_NOTFOUND: |
||
172 |
4 |
printf("not-found "); |
|
173 |
4 |
break; |
|
174 |
case EXT_COMMUNITY_OVS_INVALID: |
||
175 |
4 |
printf("invalid "); |
|
176 |
4 |
break; |
|
177 |
} |
||
178 |
break; |
||
179 |
default: |
||
180 |
printf("0x%llx ", c->data.ext_opaq); |
||
181 |
break; |
||
182 |
} |
||
183 |
20 |
} |
|
184 |
|||
185 |
void |
||
186 |
print_origin(u_int8_t o) |
||
187 |
{ |
||
188 |
if (o == ORIGIN_IGP) |
||
189 |
printf("igp "); |
||
190 |
else if (o == ORIGIN_EGP) |
||
191 |
printf("egp "); |
||
192 |
else if (o == ORIGIN_INCOMPLETE) |
||
193 |
printf("incomplete "); |
||
194 |
else |
||
195 |
printf("%u ", o); |
||
196 |
} |
||
197 |
|||
198 |
void |
||
199 |
print_set(struct filter_set_head *set) |
||
200 |
{ |
||
201 |
struct filter_set *s; |
||
202 |
|||
203 |
✓✓ | 368 |
if (TAILQ_EMPTY(set)) |
204 |
180 |
return; |
|
205 |
|||
206 |
4 |
printf("set { "); |
|
207 |
✓✓ | 16 |
TAILQ_FOREACH(s, set, entry) { |
208 |
✓✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✓ |
8 |
switch (s->type) { |
209 |
case ACTION_SET_LOCALPREF: |
||
210 |
4 |
printf("localpref %u ", s->action.metric); |
|
211 |
4 |
break; |
|
212 |
case ACTION_SET_RELATIVE_LOCALPREF: |
||
213 |
printf("localpref %+d ", s->action.relative); |
||
214 |
break; |
||
215 |
case ACTION_SET_MED: |
||
216 |
printf("metric %u ", s->action.metric); |
||
217 |
break; |
||
218 |
case ACTION_SET_RELATIVE_MED: |
||
219 |
printf("metric %+d ", s->action.relative); |
||
220 |
break; |
||
221 |
case ACTION_SET_WEIGHT: |
||
222 |
printf("weight %u ", s->action.metric); |
||
223 |
break; |
||
224 |
case ACTION_SET_RELATIVE_WEIGHT: |
||
225 |
printf("weight %+d ", s->action.relative); |
||
226 |
break; |
||
227 |
case ACTION_SET_NEXTHOP: |
||
228 |
printf("nexthop %s ", log_addr(&s->action.nexthop)); |
||
229 |
break; |
||
230 |
case ACTION_SET_NEXTHOP_REJECT: |
||
231 |
printf("nexthop reject "); |
||
232 |
break; |
||
233 |
case ACTION_SET_NEXTHOP_BLACKHOLE: |
||
234 |
printf("nexthop blackhole "); |
||
235 |
break; |
||
236 |
case ACTION_SET_NEXTHOP_NOMODIFY: |
||
237 |
printf("nexthop no-modify "); |
||
238 |
break; |
||
239 |
case ACTION_SET_NEXTHOP_SELF: |
||
240 |
printf("nexthop self "); |
||
241 |
break; |
||
242 |
case ACTION_SET_PREPEND_SELF: |
||
243 |
printf("prepend-self %u ", s->action.prepend); |
||
244 |
break; |
||
245 |
case ACTION_SET_PREPEND_PEER: |
||
246 |
printf("prepend-neighbor %u ", s->action.prepend); |
||
247 |
break; |
||
248 |
case ACTION_DEL_COMMUNITY: |
||
249 |
printf("community delete "); |
||
250 |
print_community(s->action.community.as, |
||
251 |
s->action.community.type); |
||
252 |
printf(" "); |
||
253 |
break; |
||
254 |
case ACTION_SET_COMMUNITY: |
||
255 |
printf("community "); |
||
256 |
print_community(s->action.community.as, |
||
257 |
s->action.community.type); |
||
258 |
printf(" "); |
||
259 |
break; |
||
260 |
case ACTION_DEL_LARGE_COMMUNITY: |
||
261 |
printf("large-community delete "); |
||
262 |
print_largecommunity(s->action.large_community.as, |
||
263 |
s->action.large_community.ld1, |
||
264 |
s->action.large_community.ld2); |
||
265 |
printf(" "); |
||
266 |
break; |
||
267 |
case ACTION_SET_LARGE_COMMUNITY: |
||
268 |
printf("large-community "); |
||
269 |
print_largecommunity(s->action.large_community.as, |
||
270 |
s->action.large_community.ld1, |
||
271 |
s->action.large_community.ld2); |
||
272 |
printf(" "); |
||
273 |
break; |
||
274 |
case ACTION_PFTABLE: |
||
275 |
printf("pftable %s ", s->action.pftable); |
||
276 |
break; |
||
277 |
case ACTION_RTLABEL: |
||
278 |
printf("rtlabel %s ", s->action.rtlabel); |
||
279 |
break; |
||
280 |
case ACTION_SET_ORIGIN: |
||
281 |
printf("origin "); |
||
282 |
print_origin(s->action.origin); |
||
283 |
break; |
||
284 |
case ACTION_RTLABEL_ID: |
||
285 |
case ACTION_PFTABLE_ID: |
||
286 |
/* not possible */ |
||
287 |
printf("king bula saiz: config broken"); |
||
288 |
break; |
||
289 |
case ACTION_SET_EXT_COMMUNITY: |
||
290 |
printf("ext-community "); |
||
291 |
print_extcommunity(&s->action.ext_community); |
||
292 |
break; |
||
293 |
case ACTION_DEL_EXT_COMMUNITY: |
||
294 |
printf("ext-community delete "); |
||
295 |
print_extcommunity(&s->action.ext_community); |
||
296 |
break; |
||
297 |
} |
||
298 |
} |
||
299 |
4 |
printf("}"); |
|
300 |
188 |
} |
|
301 |
|||
302 |
void |
||
303 |
print_mainconf(struct bgpd_config *conf) |
||
304 |
{ |
||
305 |
struct in_addr ina; |
||
306 |
struct listen_addr *la; |
||
307 |
|||
308 |
24 |
printf("AS %s", log_as(conf->as)); |
|
309 |
✗✓✗✗ |
12 |
if (conf->as > USHRT_MAX && conf->short_as != AS_TRANS) |
310 |
printf(" %u", conf->short_as); |
||
311 |
12 |
ina.s_addr = conf->bgpid; |
|
312 |
12 |
printf("\nrouter-id %s\n", inet_ntoa(ina)); |
|
313 |
|||
314 |
12 |
printf("socket \"%s\"\n", conf->csock); |
|
315 |
✗✓ | 12 |
if (conf->rcsock) |
316 |
printf("socket \"%s\" restricted\n", conf->rcsock); |
||
317 |
✗✓ | 12 |
if (conf->holdtime) |
318 |
printf("holdtime %u\n", conf->holdtime); |
||
319 |
✓✗ | 12 |
if (conf->min_holdtime) |
320 |
12 |
printf("holdtime min %u\n", conf->min_holdtime); |
|
321 |
✗✓ | 12 |
if (conf->connectretry) |
322 |
printf("connect-retry %u\n", conf->connectretry); |
||
323 |
|||
324 |
✗✓ | 12 |
if (conf->flags & BGPD_FLAG_NO_EVALUATE) |
325 |
printf("route-collector yes\n"); |
||
326 |
|||
327 |
✗✓ | 12 |
if (conf->flags & BGPD_FLAG_DECISION_ROUTEAGE) |
328 |
printf("rde route-age evaluate\n"); |
||
329 |
|||
330 |
✗✓ | 12 |
if (conf->flags & BGPD_FLAG_DECISION_MED_ALWAYS) |
331 |
printf("rde med compare always\n"); |
||
332 |
|||
333 |
✗✓ | 12 |
if (conf->log & BGPD_LOG_UPDATES) |
334 |
printf("log updates\n"); |
||
335 |
|||
336 |
✗✓ | 24 |
TAILQ_FOREACH(la, conf->listen_addrs, entry) |
337 |
printf("listen on %s\n", |
||
338 |
log_sockaddr((struct sockaddr *)&la->sa)); |
||
339 |
|||
340 |
✗✓ | 12 |
if (conf->flags & BGPD_FLAG_NEXTHOP_BGP) |
341 |
printf("nexthop qualify via bgp\n"); |
||
342 |
✗✓ | 12 |
if (conf->flags & BGPD_FLAG_NEXTHOP_DEFAULT) |
343 |
printf("nexthop qualify via default\n"); |
||
344 |
12 |
printf("fib-priority %hhu", conf->fib_priority); |
|
345 |
12 |
} |
|
346 |
|||
347 |
void |
||
348 |
print_rdomain_targets(struct filter_set_head *set, const char *tgt) |
||
349 |
{ |
||
350 |
struct filter_set *s; |
||
351 |
TAILQ_FOREACH(s, set, entry) { |
||
352 |
printf("\t%s ", tgt); |
||
353 |
print_extcommunity(&s->action.ext_community); |
||
354 |
printf("\n"); |
||
355 |
} |
||
356 |
} |
||
357 |
|||
358 |
void |
||
359 |
print_rdomain(struct rdomain *r) |
||
360 |
{ |
||
361 |
struct network *n; |
||
362 |
|||
363 |
printf("rdomain %u {\n", r->rtableid); |
||
364 |
if (*r->descr) |
||
365 |
printf("\tdescr \"%s\"\n", r->descr); |
||
366 |
if (r->flags & F_RIB_NOFIBSYNC) |
||
367 |
printf("\tfib-update no\n"); |
||
368 |
else |
||
369 |
printf("\tfib-update yes\n"); |
||
370 |
printf("\tdepend on %s\n", r->ifmpe); |
||
371 |
|||
372 |
TAILQ_FOREACH(n, &r->net_l, entry) |
||
373 |
print_network(&n->net, "\t"); |
||
374 |
|||
375 |
printf("\n\t%s\n", log_rd(r->rd)); |
||
376 |
|||
377 |
print_rdomain_targets(&r->export, "export-target"); |
||
378 |
print_rdomain_targets(&r->import, "import-target"); |
||
379 |
|||
380 |
printf("}\n"); |
||
381 |
} |
||
382 |
|||
383 |
const char * |
||
384 |
print_af(u_int8_t aid) |
||
385 |
{ |
||
386 |
/* |
||
387 |
* Hack around the fact that aid2str() will return "IPv4 unicast" |
||
388 |
* for AID_INET. AID_INET and AID_INET6 need special handling and |
||
389 |
* the other AID should never end up here (at least for now). |
||
390 |
*/ |
||
391 |
if (aid == AID_INET) |
||
392 |
return ("inet"); |
||
393 |
if (aid == AID_INET6) |
||
394 |
return ("inet6"); |
||
395 |
return (aid2str(aid)); |
||
396 |
} |
||
397 |
|||
398 |
void |
||
399 |
print_network(struct network_config *n, const char *c) |
||
400 |
{ |
||
401 |
switch (n->type) { |
||
402 |
case NETWORK_STATIC: |
||
403 |
printf("%snetwork %s static", c, print_af(n->prefix.aid)); |
||
404 |
break; |
||
405 |
case NETWORK_CONNECTED: |
||
406 |
printf("%snetwork %s connected", c, print_af(n->prefix.aid)); |
||
407 |
break; |
||
408 |
case NETWORK_RTLABEL: |
||
409 |
printf("%snetwork %s rtlabel \"%s\"", c, |
||
410 |
print_af(n->prefix.aid), rtlabel_id2name(n->rtlabel)); |
||
411 |
break; |
||
412 |
default: |
||
413 |
printf("%snetwork %s/%u", c, log_addr(&n->prefix), |
||
414 |
n->prefixlen); |
||
415 |
break; |
||
416 |
} |
||
417 |
if (!TAILQ_EMPTY(&n->attrset)) |
||
418 |
printf(" "); |
||
419 |
print_set(&n->attrset); |
||
420 |
printf("\n"); |
||
421 |
} |
||
422 |
|||
423 |
void |
||
424 |
print_peer(struct peer_config *p, struct bgpd_config *conf, const char *c) |
||
425 |
{ |
||
426 |
char *method; |
||
427 |
struct in_addr ina; |
||
428 |
|||
429 |
✓✗✓✓ ✗✗ |
96 |
if ((p->remote_addr.aid == AID_INET && p->remote_masklen != 32) || |
430 |
✗✓ | 28 |
(p->remote_addr.aid == AID_INET6 && p->remote_masklen != 128)) |
431 |
8 |
printf("%sneighbor %s/%u {\n", c, log_addr(&p->remote_addr), |
|
432 |
4 |
p->remote_masklen); |
|
433 |
else |
||
434 |
28 |
printf("%sneighbor %s {\n", c, log_addr(&p->remote_addr)); |
|
435 |
✓✓ | 32 |
if (p->descr[0]) |
436 |
28 |
printf("%s\tdescr \"%s\"\n", c, p->descr); |
|
437 |
✗✓ | 32 |
if (p->rib[0]) |
438 |
printf("%s\trib \"%s\"\n", c, p->rib); |
||
439 |
✓✓ | 32 |
if (p->remote_as) |
440 |
28 |
printf("%s\tremote-as %s\n", c, log_as(p->remote_as)); |
|
441 |
✗✓ | 32 |
if (p->local_as != conf->as) { |
442 |
printf("%s\tlocal-as %s", c, log_as(p->local_as)); |
||
443 |
if (p->local_as > USHRT_MAX && p->local_short_as != AS_TRANS) |
||
444 |
printf(" %u", p->local_short_as); |
||
445 |
printf("\n"); |
||
446 |
} |
||
447 |
✗✓ | 32 |
if (p->down) |
448 |
printf("%s\tdown\n", c); |
||
449 |
✓✓ | 32 |
if (p->distance > 1) |
450 |
4 |
printf("%s\tmultihop %u\n", c, p->distance); |
|
451 |
✓✓ | 32 |
if (p->passive) |
452 |
4 |
printf("%s\tpassive\n", c); |
|
453 |
✓✓ | 32 |
if (p->local_addr.aid) |
454 |
24 |
printf("%s\tlocal-address %s\n", c, log_addr(&p->local_addr)); |
|
455 |
✗✓ | 32 |
if (p->max_prefix) { |
456 |
printf("%s\tmax-prefix %u", c, p->max_prefix); |
||
457 |
if (p->max_prefix_restart) |
||
458 |
printf(" restart %u", p->max_prefix_restart); |
||
459 |
printf("\n"); |
||
460 |
} |
||
461 |
✓✓ | 32 |
if (p->holdtime) |
462 |
4 |
printf("%s\tholdtime %u\n", c, p->holdtime); |
|
463 |
✓✓ | 32 |
if (p->min_holdtime) |
464 |
4 |
printf("%s\tholdtime min %u\n", c, p->min_holdtime); |
|
465 |
✗✓ | 32 |
if (p->announce_capa == 0) |
466 |
printf("%s\tannounce capabilities no\n", c); |
||
467 |
✗✓ | 32 |
if (p->capabilities.refresh == 0) |
468 |
printf("%s\tannounce refresh no\n", c); |
||
469 |
✗✓ | 32 |
if (p->capabilities.grestart.restart == 0) |
470 |
printf("%s\tannounce restart no\n", c); |
||
471 |
✗✓ | 32 |
if (p->capabilities.as4byte == 0) |
472 |
printf("%s\tannounce as4byte no\n", c); |
||
473 |
✓✓ | 32 |
if (p->announce_type == ANNOUNCE_SELF) |
474 |
24 |
printf("%s\tannounce self\n", c); |
|
475 |
✓✓ | 8 |
else if (p->announce_type == ANNOUNCE_NONE) |
476 |
4 |
printf("%s\tannounce none\n", c); |
|
477 |
✓✗ | 4 |
else if (p->announce_type == ANNOUNCE_ALL) |
478 |
4 |
printf("%s\tannounce all\n", c); |
|
479 |
else if (p->announce_type == ANNOUNCE_DEFAULT_ROUTE) |
||
480 |
printf("%s\tannounce default-route\n", c); |
||
481 |
else |
||
482 |
printf("%s\tannounce ???\n", c); |
||
483 |
✓✓ | 32 |
if (p->enforce_as == ENFORCE_AS_ON) |
484 |
28 |
printf("%s\tenforce neighbor-as yes\n", c); |
|
485 |
else |
||
486 |
4 |
printf("%s\tenforce neighbor-as no\n", c); |
|
487 |
✓✗ | 32 |
if (p->enforce_local_as == ENFORCE_AS_ON) |
488 |
32 |
printf("%s\tenforce local-as yes\n", c); |
|
489 |
else |
||
490 |
printf("%s\tenforce local-as no\n", c); |
||
491 |
✗✓ | 32 |
if (p->reflector_client) { |
492 |
if (conf->clusterid == 0) |
||
493 |
printf("%s\troute-reflector\n", c); |
||
494 |
else { |
||
495 |
ina.s_addr = conf->clusterid; |
||
496 |
printf("%s\troute-reflector %s\n", c, |
||
497 |
inet_ntoa(ina)); |
||
498 |
} |
||
499 |
} |
||
500 |
✗✓ | 32 |
if (p->demote_group[0]) |
501 |
printf("%s\tdemote %s\n", c, p->demote_group); |
||
502 |
✗✓ | 32 |
if (p->if_depend[0]) |
503 |
printf("%s\tdepend on \"%s\"\n", c, p->if_depend); |
||
504 |
✗✓ | 32 |
if (p->flags & PEERFLAG_TRANS_AS) |
505 |
printf("%s\ttransparent-as yes\n", c); |
||
506 |
|||
507 |
✗✓ | 32 |
if (p->flags & PEERFLAG_LOG_UPDATES) |
508 |
printf("%s\tlog updates\n", c); |
||
509 |
|||
510 |
✓✓ | 32 |
if (p->auth.method == AUTH_MD5SIG) |
511 |
8 |
printf("%s\ttcp md5sig\n", c); |
|
512 |
✓✓✗✓ |
44 |
else if (p->auth.method == AUTH_IPSEC_MANUAL_ESP || |
513 |
20 |
p->auth.method == AUTH_IPSEC_MANUAL_AH) { |
|
514 |
✓✗ | 4 |
if (p->auth.method == AUTH_IPSEC_MANUAL_ESP) |
515 |
4 |
method = "esp"; |
|
516 |
else |
||
517 |
method = "ah"; |
||
518 |
|||
519 |
4 |
printf("%s\tipsec %s in spi %u %s XXXXXX", c, method, |
|
520 |
4 |
p->auth.spi_in, print_auth_alg(p->auth.auth_alg_in)); |
|
521 |
✓✗ | 4 |
if (p->auth.enc_alg_in) |
522 |
4 |
printf(" %s XXXXXX", print_enc_alg(p->auth.enc_alg_in)); |
|
523 |
4 |
printf("\n"); |
|
524 |
|||
525 |
4 |
printf("%s\tipsec %s out spi %u %s XXXXXX", c, method, |
|
526 |
4 |
p->auth.spi_out, print_auth_alg(p->auth.auth_alg_out)); |
|
527 |
✓✗ | 4 |
if (p->auth.enc_alg_out) |
528 |
4 |
printf(" %s XXXXXX", |
|
529 |
4 |
print_enc_alg(p->auth.enc_alg_out)); |
|
530 |
4 |
printf("\n"); |
|
531 |
✓✓ | 24 |
} else if (p->auth.method == AUTH_IPSEC_IKE_AH) |
532 |
12 |
printf("%s\tipsec ah ike\n", c); |
|
533 |
✓✓ | 8 |
else if (p->auth.method == AUTH_IPSEC_IKE_ESP) |
534 |
4 |
printf("%s\tipsec esp ike\n", c); |
|
535 |
|||
536 |
✗✓ | 32 |
if (p->ttlsec) |
537 |
printf("%s\tttl-security yes\n", c); |
||
538 |
|||
539 |
32 |
print_announce(p, c); |
|
540 |
|||
541 |
32 |
print_mrt(conf, p->id, p->groupid, c, "\t"); |
|
542 |
|||
543 |
32 |
printf("%s}\n", c); |
|
544 |
32 |
} |
|
545 |
|||
546 |
const char * |
||
547 |
print_auth_alg(u_int8_t alg) |
||
548 |
{ |
||
549 |
✓✗✗ | 16 |
switch (alg) { |
550 |
case SADB_AALG_SHA1HMAC: |
||
551 |
8 |
return ("sha1"); |
|
552 |
case SADB_AALG_MD5HMAC: |
||
553 |
return ("md5"); |
||
554 |
default: |
||
555 |
return ("???"); |
||
556 |
} |
||
557 |
8 |
} |
|
558 |
|||
559 |
const char * |
||
560 |
print_enc_alg(u_int8_t alg) |
||
561 |
{ |
||
562 |
✗✓✗ | 16 |
switch (alg) { |
563 |
case SADB_EALG_3DESCBC: |
||
564 |
return ("3des"); |
||
565 |
case SADB_X_EALG_AES: |
||
566 |
8 |
return ("aes"); |
|
567 |
default: |
||
568 |
return ("???"); |
||
569 |
} |
||
570 |
8 |
} |
|
571 |
|||
572 |
void |
||
573 |
print_announce(struct peer_config *p, const char *c) |
||
574 |
{ |
||
575 |
u_int8_t aid; |
||
576 |
|||
577 |
✓✓ | 352 |
for (aid = 0; aid < AID_MAX; aid++) |
578 |
✓✓ | 128 |
if (p->capabilities.mp[aid]) |
579 |
32 |
printf("%s\tannounce %s\n", c, aid2str(aid)); |
|
580 |
32 |
} |
|
581 |
|||
582 |
void print_as(struct filter_rule *r) |
||
583 |
{ |
||
584 |
✓✗✗✓ |
64 |
switch(r->match.as.op) { |
585 |
case OP_RANGE: |
||
586 |
20 |
printf("%s - ", log_as(r->match.as.as_min)); |
|
587 |
20 |
printf("%s ", log_as(r->match.as.as_max)); |
|
588 |
20 |
break; |
|
589 |
case OP_XRANGE: |
||
590 |
printf("%s >< ", log_as(r->match.as.as_min)); |
||
591 |
printf("%s ", log_as(r->match.as.as_max)); |
||
592 |
break; |
||
593 |
case OP_NE: |
||
594 |
printf("!= %s ", log_as(r->match.as.as)); |
||
595 |
break; |
||
596 |
default: |
||
597 |
12 |
printf("%s ", log_as(r->match.as.as)); |
|
598 |
12 |
break; |
|
599 |
} |
||
600 |
32 |
} |
|
601 |
|||
602 |
void |
||
603 |
print_rule(struct peer *peer_l, struct filter_rule *r) |
||
604 |
{ |
||
605 |
struct peer *p; |
||
606 |
|||
607 |
✓✓ | 368 |
if (r->action == ACTION_ALLOW) |
608 |
48 |
printf("allow "); |
|
609 |
✓✓ | 136 |
else if (r->action == ACTION_DENY) |
610 |
132 |
printf("deny "); |
|
611 |
else |
||
612 |
4 |
printf("match "); |
|
613 |
✗✓ | 184 |
if (r->quick) |
614 |
printf("quick "); |
||
615 |
|||
616 |
✗✓ | 184 |
if (r->rib[0]) |
617 |
printf("rib %s ", r->rib); |
||
618 |
|||
619 |
✓✓ | 184 |
if (r->dir == DIR_IN) |
620 |
176 |
printf("from "); |
|
621 |
✓✗ | 8 |
else if (r->dir == DIR_OUT) |
622 |
8 |
printf("to "); |
|
623 |
else |
||
624 |
printf("eeeeeeeps. "); |
||
625 |
|||
626 |
✗✓ | 184 |
if (r->peer.peerid) { |
627 |
for (p = peer_l; p != NULL && p->conf.id != r->peer.peerid; |
||
628 |
p = p->next) |
||
629 |
; /* nothing */ |
||
630 |
if (p == NULL) |
||
631 |
printf("? "); |
||
632 |
else |
||
633 |
printf("%s ", log_addr(&p->conf.remote_addr)); |
||
634 |
✗✓ | 184 |
} else if (r->peer.groupid) { |
635 |
for (p = peer_l; p != NULL && |
||
636 |
p->conf.groupid != r->peer.groupid; p = p->next) |
||
637 |
; /* nothing */ |
||
638 |
if (p == NULL) |
||
639 |
printf("group ? "); |
||
640 |
else |
||
641 |
printf("group \"%s\" ", p->conf.group); |
||
642 |
✗✓ | 184 |
} else if (r->peer.remote_as) { |
643 |
printf("AS %s ", log_as(r->peer.remote_as)); |
||
644 |
✓✓ | 184 |
} else if (r->peer.ebgp) { |
645 |
8 |
printf("ebgp "); |
|
646 |
✓✓ | 184 |
} else if (r->peer.ibgp) { |
647 |
8 |
printf("ibgp "); |
|
648 |
8 |
} else |
|
649 |
168 |
printf("any "); |
|
650 |
|||
651 |
✓✓ | 184 |
if (r->match.prefix.addr.aid) |
652 |
208 |
printf("prefix %s/%u ", log_addr(&r->match.prefix.addr), |
|
653 |
104 |
r->match.prefix.len); |
|
654 |
|||
655 |
✓✓ | 184 |
if (r->match.prefix.op) { |
656 |
✓✓✗✓ |
196 |
if (r->match.prefix.op == OP_RANGE || |
657 |
92 |
r->match.prefix.op == OP_XRANGE) { |
|
658 |
12 |
printf("prefixlen %u ", r->match.prefix.len_min); |
|
659 |
12 |
print_op(r->match.prefix.op); |
|
660 |
12 |
printf(" %u ", r->match.prefix.len_max); |
|
661 |
12 |
} else { |
|
662 |
92 |
printf("prefixlen "); |
|
663 |
92 |
print_op(r->match.prefix.op); |
|
664 |
92 |
printf(" %u ", r->match.prefix.len_min); |
|
665 |
} |
||
666 |
} |
||
667 |
|||
668 |
✗✓ | 184 |
if (r->match.nexthop.flags) { |
669 |
if (r->match.nexthop.flags == FILTER_NEXTHOP_NEIGHBOR) |
||
670 |
printf("nexthop neighbor "); |
||
671 |
else |
||
672 |
printf("nexthop %s ", log_addr(&r->match.nexthop.addr)); |
||
673 |
} |
||
674 |
|||
675 |
✓✓ | 184 |
if (r->match.as.type) { |
676 |
✓✗ | 32 |
if (r->match.as.type == AS_ALL) |
677 |
32 |
printf("AS "); |
|
678 |
else if (r->match.as.type == AS_SOURCE) |
||
679 |
printf("source-as "); |
||
680 |
else if (r->match.as.type == AS_TRANSIT) |
||
681 |
printf("transit-as "); |
||
682 |
else if (r->match.as.type == AS_PEER) |
||
683 |
printf("peer-as "); |
||
684 |
else |
||
685 |
printf("unfluffy-as "); |
||
686 |
32 |
print_as(r); |
|
687 |
32 |
} |
|
688 |
|||
689 |
✗✓ | 184 |
if (r->match.aslen.type) { |
690 |
printf("%s %u ", r->match.aslen.type == ASLEN_MAX ? |
||
691 |
"max-as-len" : "max-as-seq", r->match.aslen.aslen); |
||
692 |
} |
||
693 |
|||
694 |
✓✓ | 184 |
if (r->match.community.as != COMMUNITY_UNSET) { |
695 |
8 |
printf("community "); |
|
696 |
16 |
print_community(r->match.community.as, |
|
697 |
8 |
r->match.community.type); |
|
698 |
8 |
} |
|
699 |
✓✓ | 184 |
if (r->match.ext_community.flags & EXT_COMMUNITY_FLAG_VALID) { |
700 |
20 |
printf("ext-community "); |
|
701 |
20 |
print_extcommunity(&r->match.ext_community); |
|
702 |
20 |
} |
|
703 |
✓✓ | 184 |
if (r->match.large_community.as != COMMUNITY_UNSET) { |
704 |
4 |
printf("large-community "); |
|
705 |
8 |
print_largecommunity(r->match.large_community.as, |
|
706 |
4 |
r->match.large_community.ld1, |
|
707 |
4 |
r->match.large_community.ld2); |
|
708 |
4 |
} |
|
709 |
|||
710 |
184 |
print_set(&r->set); |
|
711 |
|||
712 |
184 |
printf("\n"); |
|
713 |
184 |
} |
|
714 |
|||
715 |
const char * |
||
716 |
mrt_type(enum mrt_type t) |
||
717 |
{ |
||
718 |
switch (t) { |
||
719 |
case MRT_NONE: |
||
720 |
break; |
||
721 |
case MRT_TABLE_DUMP: |
||
722 |
return "table"; |
||
723 |
case MRT_TABLE_DUMP_MP: |
||
724 |
return "table-mp"; |
||
725 |
case MRT_TABLE_DUMP_V2: |
||
726 |
return "table-v2"; |
||
727 |
case MRT_ALL_IN: |
||
728 |
return "all in"; |
||
729 |
case MRT_ALL_OUT: |
||
730 |
return "all out"; |
||
731 |
case MRT_UPDATE_IN: |
||
732 |
return "updates in"; |
||
733 |
case MRT_UPDATE_OUT: |
||
734 |
return "updates out"; |
||
735 |
} |
||
736 |
return "unfluffy MRT"; |
||
737 |
} |
||
738 |
|||
739 |
void |
||
740 |
print_mrt(struct bgpd_config *conf, u_int32_t pid, u_int32_t gid, |
||
741 |
const char *prep, const char *prep2) |
||
742 |
{ |
||
743 |
struct mrt *m; |
||
744 |
|||
745 |
✗✓ | 88 |
if (conf->mrt == NULL) |
746 |
return; |
||
747 |
|||
748 |
✗✓ | 88 |
LIST_FOREACH(m, conf->mrt, entry) |
749 |
if ((gid != 0 && m->group_id == gid) || |
||
750 |
(m->peer_id == pid && m->group_id == gid)) { |
||
751 |
printf("%s%sdump ", prep, prep2); |
||
752 |
if (m->rib[0]) |
||
753 |
printf("rib %s ", m->rib); |
||
754 |
printf("%s \"%s\"", mrt_type(m->type), |
||
755 |
MRT2MC(m)->name); |
||
756 |
if (MRT2MC(m)->ReopenTimerInterval == 0) |
||
757 |
printf("\n"); |
||
758 |
else |
||
759 |
printf(" %d\n", MRT2MC(m)->ReopenTimerInterval); |
||
760 |
} |
||
761 |
88 |
} |
|
762 |
|||
763 |
void |
||
764 |
print_groups(struct bgpd_config *conf, struct peer *peer_l) |
||
765 |
{ |
||
766 |
struct peer_config **peerlist; |
||
767 |
struct peer *p; |
||
768 |
u_int peer_cnt, i; |
||
769 |
u_int32_t prev_groupid; |
||
770 |
const char *tab = "\t"; |
||
771 |
const char *nada = ""; |
||
772 |
const char *c; |
||
773 |
|||
774 |
peer_cnt = 0; |
||
775 |
✓✓ | 100 |
for (p = peer_l; p != NULL; p = p->next) |
776 |
32 |
peer_cnt++; |
|
777 |
|||
778 |
✗✓ | 12 |
if ((peerlist = calloc(peer_cnt, sizeof(struct peer_config *))) == NULL) |
779 |
fatal("print_groups calloc"); |
||
780 |
|||
781 |
i = 0; |
||
782 |
✓✓ | 88 |
for (p = peer_l; p != NULL; p = p->next) |
783 |
32 |
peerlist[i++] = &p->conf; |
|
784 |
|||
785 |
12 |
qsort(peerlist, peer_cnt, sizeof(struct peer_config *), peer_compare); |
|
786 |
|||
787 |
prev_groupid = 0; |
||
788 |
✓✓ | 88 |
for (i = 0; i < peer_cnt; i++) { |
789 |
✓✓ | 32 |
if (peerlist[i]->groupid) { |
790 |
c = tab; |
||
791 |
✓✓ | 16 |
if (peerlist[i]->groupid != prev_groupid) { |
792 |
✓✓ | 8 |
if (prev_groupid) |
793 |
4 |
printf("}\n\n"); |
|
794 |
8 |
printf("group \"%s\" {\n", peerlist[i]->group); |
|
795 |
8 |
prev_groupid = peerlist[i]->groupid; |
|
796 |
8 |
} |
|
797 |
} else |
||
798 |
c = nada; |
||
799 |
|||
800 |
32 |
print_peer(peerlist[i], conf, c); |
|
801 |
} |
||
802 |
|||
803 |
✓✓ | 12 |
if (prev_groupid) |
804 |
4 |
printf("}\n\n"); |
|
805 |
|||
806 |
12 |
free(peerlist); |
|
807 |
12 |
} |
|
808 |
|||
809 |
int |
||
810 |
peer_compare(const void *aa, const void *bb) |
||
811 |
{ |
||
812 |
const struct peer_config * const *a; |
||
813 |
const struct peer_config * const *b; |
||
814 |
|||
815 |
120 |
a = aa; |
|
816 |
60 |
b = bb; |
|
817 |
|||
818 |
60 |
return ((*a)->groupid - (*b)->groupid); |
|
819 |
} |
||
820 |
|||
821 |
void |
||
822 |
print_config(struct bgpd_config *conf, struct rib_names *rib_l, |
||
823 |
struct network_head *net_l, struct peer *peer_l, |
||
824 |
struct filter_head *rules_l, struct mrt_head *mrt_l, |
||
825 |
struct rdomain_head *rdom_l) |
||
826 |
{ |
||
827 |
struct filter_rule *r; |
||
828 |
struct network *n; |
||
829 |
struct rde_rib *rr; |
||
830 |
struct rdomain *rd; |
||
831 |
|||
832 |
24 |
print_mainconf(conf); |
|
833 |
12 |
printf("\n"); |
|
834 |
✗✓ | 24 |
TAILQ_FOREACH(n, net_l, entry) |
835 |
print_network(&n->net, ""); |
||
836 |
12 |
printf("\n"); |
|
837 |
✗✓ | 24 |
SIMPLEQ_FOREACH(rd, rdom_l, entry) |
838 |
print_rdomain(rd); |
||
839 |
12 |
printf("\n"); |
|
840 |
✓✓ | 72 |
SIMPLEQ_FOREACH(rr, rib_l, entry) { |
841 |
✓✓ | 24 |
if (rr->flags & F_RIB_NOEVALUATE) |
842 |
12 |
printf("rde rib %s no evaluate\n", rr->name); |
|
843 |
✗✓ | 12 |
else if (rr->flags & F_RIB_NOFIB) |
844 |
printf("rde rib %s\n", rr->name); |
||
845 |
else |
||
846 |
12 |
printf("rde rib %s rtable %u fib-update %s\n", rr->name, |
|
847 |
12 |
rr->rtableid, rr->flags & F_RIB_NOFIBSYNC ? |
|
848 |
"no" : "yes"); |
||
849 |
} |
||
850 |
12 |
printf("\n"); |
|
851 |
12 |
print_mrt(conf, 0, 0, "", ""); |
|
852 |
12 |
printf("\n"); |
|
853 |
12 |
print_groups(conf, peer_l); |
|
854 |
12 |
printf("\n"); |
|
855 |
✓✓ | 392 |
TAILQ_FOREACH(r, rules_l, entry) |
856 |
184 |
print_rule(peer_l, r); |
|
857 |
12 |
} |
Generated by: GCOVR (Version 3.3) |