| 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) |