1*e3db1f63Sclaudio /* $OpenBSD: printconf.c,v 1.181 2025/01/27 15:22:11 claudio Exp $ */ 2977216a6Shenning 3977216a6Shenning /* 4977216a6Shenning * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 5280f24a4Sphessler * Copyright (c) 2016 Job Snijders <job@instituut.net> 6280f24a4Sphessler * Copyright (c) 2016 Peter Hessler <phessler@openbsd.org> 7977216a6Shenning * 8977216a6Shenning * Permission to use, copy, modify, and distribute this software for any 9977216a6Shenning * purpose with or without fee is hereby granted, provided that the above 10977216a6Shenning * copyright notice and this permission notice appear in all copies. 11977216a6Shenning * 12977216a6Shenning * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13977216a6Shenning * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14977216a6Shenning * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15977216a6Shenning * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16977216a6Shenning * WHATSOEVER RESULTING FROM LOSS OF USE, DATA, PROFITS OR MIND, WHETHER IN 17977216a6Shenning * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 18977216a6Shenning * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19977216a6Shenning */ 20977216a6Shenning 21b2cd1366Sguenther #include <limits.h> 22977216a6Shenning #include <stdio.h> 23cbcb38a8Shenning #include <stdlib.h> 24425bb0f0Shenning #include <string.h> 25977216a6Shenning 26977216a6Shenning #include "bgpd.h" 27977216a6Shenning #include "session.h" 2898daafc0Sclaudio #include "rde.h" 295e3f6f95Sbenno #include "log.h" 30977216a6Shenning 314ea66b69Sclaudio void print_prefix(struct filter_prefix *p); 32e7adcfeaSclaudio const char *community_type(struct community *c); 33e7adcfeaSclaudio void print_community(struct community *c); 3439386878Sclaudio void print_origin(uint8_t); 3598d902b5Sclaudio void print_set(struct filter_set_head *); 36020327f0Shenning void print_mainconf(struct bgpd_config *); 374e0c4e97Sclaudio void print_l3vpn_targets(struct filter_set_head *, const char *); 384e0c4e97Sclaudio void print_l3vpn(struct l3vpn *); 3939386878Sclaudio const char *print_af(uint8_t); 401274ebf8Sclaudio void print_network(struct network_config *, const char *); 417d4aa781Sclaudio void print_flowspec(struct flowspec_config *, const char *); 4259e404fbSclaudio void print_as_sets(struct as_set_head *); 43441aaadcSbenno void print_prefixsets(struct prefixset_head *); 446f1dba6eSclaudio void print_originsets(struct prefixset_head *); 456aa533f4Sclaudio void print_roa(struct roa_tree *); 46ff84f55eSclaudio void print_aspa(struct aspa_tree *); 47bd9df44eSclaudio void print_rtrs(struct rtr_config_head *); 48d7629114Sclaudio void print_peer(struct peer *, struct bgpd_config *, const char *); 4993662c4eSclaudio const char *print_auth_alg(enum auth_alg); 5093662c4eSclaudio const char *print_enc_alg(enum auth_enc_alg); 5186729c90Sclaudio void print_announce(struct peer_config *, const char *); 52708dc8caSbenno void print_as(struct filter_rule *); 5382fc6237Sclaudio void print_rule(struct bgpd_config *, struct filter_rule *); 54866636d1Sclaudio const char *mrt_type(enum mrt_type); 5539386878Sclaudio void print_mrt(struct bgpd_config *, uint32_t, uint32_t, 56d288d268Sclaudio const char *, const char *); 5782fc6237Sclaudio void print_groups(struct bgpd_config *); 58cbcb38a8Shenning int peer_compare(const void *, const void *); 59977216a6Shenning 60977216a6Shenning void 614ea66b69Sclaudio print_prefix(struct filter_prefix *p) 62977216a6Shenning { 6339386878Sclaudio uint8_t max_len = 0; 640d3ce282Sclaudio 650d3ce282Sclaudio switch (p->addr.aid) { 660d3ce282Sclaudio case AID_INET: 670d3ce282Sclaudio case AID_VPN_IPv4: 680d3ce282Sclaudio max_len = 32; 69d77f1165Sclaudio break; 700d3ce282Sclaudio case AID_INET6: 71290f96faSdenis case AID_VPN_IPv6: 720d3ce282Sclaudio max_len = 128; 730d3ce282Sclaudio break; 740d3ce282Sclaudio case AID_UNSPEC: 750d3ce282Sclaudio /* no prefix to print */ 760d3ce282Sclaudio return; 770d3ce282Sclaudio } 780d3ce282Sclaudio 794ea66b69Sclaudio printf("%s/%u", log_addr(&p->addr), p->len); 800d3ce282Sclaudio 810d3ce282Sclaudio switch (p->op) { 820d3ce282Sclaudio case OP_NONE: 83d77f1165Sclaudio break; 84977216a6Shenning case OP_NE: 850d3ce282Sclaudio printf(" prefixlen != %u", p->len_min); 86977216a6Shenning break; 870d3ce282Sclaudio case OP_XRANGE: 880d3ce282Sclaudio printf(" prefixlen %u >< %u ", p->len_min, p->len_max); 89977216a6Shenning break; 900d3ce282Sclaudio case OP_RANGE: 916f1dba6eSclaudio if (p->len_min == p->len_max && p->len != p->len_min) 925d31d72bSclaudio printf(" prefixlen = %u", p->len_min); 935bbea992Sclaudio else if (p->len == p->len_min && p->len_max == max_len) 940d3ce282Sclaudio printf(" or-longer"); 956f1dba6eSclaudio else if (p->len == p->len_min && p->len != p->len_max) 965bbea992Sclaudio printf(" maxlen %u", p->len_max); 970d3ce282Sclaudio else if (p->len_max == max_len) 980d3ce282Sclaudio printf(" prefixlen >= %u", p->len_min); 990d3ce282Sclaudio else 1000d3ce282Sclaudio printf(" prefixlen %u - %u", p->len_min, p->len_max); 101977216a6Shenning break; 102977216a6Shenning default: 1030d3ce282Sclaudio printf(" prefixlen %u ??? %u", p->len_min, p->len_max); 104977216a6Shenning break; 105977216a6Shenning } 106977216a6Shenning } 107977216a6Shenning 108dd87f852Sclaudio const char * 109e7adcfeaSclaudio community_type(struct community *c) 1107d5dac02Sclaudio { 11139386878Sclaudio switch ((uint8_t)c->flags) { 112dd87f852Sclaudio case COMMUNITY_TYPE_BASIC: 113dd87f852Sclaudio return "community"; 114dd87f852Sclaudio case COMMUNITY_TYPE_LARGE: 115dd87f852Sclaudio return "large-community"; 11636e003c6Sclaudio case COMMUNITY_TYPE_EXT: 11736e003c6Sclaudio return "ext-community"; 118dd87f852Sclaudio default: 119dd87f852Sclaudio return "???"; 120dd87f852Sclaudio } 1217d5dac02Sclaudio } 1227d5dac02Sclaudio 1237d5dac02Sclaudio void 124e7adcfeaSclaudio print_community(struct community *c) 125280f24a4Sphessler { 12636e003c6Sclaudio struct in_addr addr; 127f8162053Sclaudio int type; 12839386878Sclaudio uint8_t subtype; 12936e003c6Sclaudio 13039386878Sclaudio switch ((uint8_t)c->flags) { 131dd87f852Sclaudio case COMMUNITY_TYPE_BASIC: 132e7adcfeaSclaudio switch ((c->flags >> 8) & 0xff) { 133dd87f852Sclaudio case COMMUNITY_ANY: 134280f24a4Sphessler printf("*:"); 135dd87f852Sclaudio break; 136dd87f852Sclaudio case COMMUNITY_NEIGHBOR_AS: 137280f24a4Sphessler printf("neighbor-as:"); 138dd87f852Sclaudio break; 139dd87f852Sclaudio case COMMUNITY_LOCAL_AS: 140a07e3c3cSphessler printf("local-as:"); 141dd87f852Sclaudio break; 142dd87f852Sclaudio default: 143e7adcfeaSclaudio printf("%u:", c->data1); 144dd87f852Sclaudio break; 145280f24a4Sphessler } 146e7adcfeaSclaudio switch ((c->flags >> 16) & 0xff) { 147dd87f852Sclaudio case COMMUNITY_ANY: 148dd87f852Sclaudio printf("* "); 149dd87f852Sclaudio break; 150dd87f852Sclaudio case COMMUNITY_NEIGHBOR_AS: 151dd87f852Sclaudio printf("neighbor-as "); 152dd87f852Sclaudio break; 153dd87f852Sclaudio case COMMUNITY_LOCAL_AS: 154dd87f852Sclaudio printf("local-as "); 155dd87f852Sclaudio break; 156dd87f852Sclaudio default: 157e7adcfeaSclaudio printf("%u ", c->data2); 158dd87f852Sclaudio break; 159dd87f852Sclaudio } 160dd87f852Sclaudio break; 161dd87f852Sclaudio case COMMUNITY_TYPE_LARGE: 162e7adcfeaSclaudio switch ((c->flags >> 8) & 0xff) { 163dd87f852Sclaudio case COMMUNITY_ANY: 164dd87f852Sclaudio printf("*:"); 165dd87f852Sclaudio break; 166dd87f852Sclaudio case COMMUNITY_NEIGHBOR_AS: 167dd87f852Sclaudio printf("neighbor-as:"); 168dd87f852Sclaudio break; 169dd87f852Sclaudio case COMMUNITY_LOCAL_AS: 170dd87f852Sclaudio printf("local-as:"); 171dd87f852Sclaudio break; 172dd87f852Sclaudio default: 173e7adcfeaSclaudio printf("%u:", c->data1); 174dd87f852Sclaudio break; 175dd87f852Sclaudio } 176e7adcfeaSclaudio switch ((c->flags >> 16) & 0xff) { 177dd87f852Sclaudio case COMMUNITY_ANY: 178dd87f852Sclaudio printf("*:"); 179dd87f852Sclaudio break; 180dd87f852Sclaudio case COMMUNITY_NEIGHBOR_AS: 181dd87f852Sclaudio printf("neighbor-as:"); 182dd87f852Sclaudio break; 183dd87f852Sclaudio case COMMUNITY_LOCAL_AS: 184dd87f852Sclaudio printf("local-as:"); 185dd87f852Sclaudio break; 186dd87f852Sclaudio default: 187e7adcfeaSclaudio printf("%u:", c->data2); 188dd87f852Sclaudio break; 189dd87f852Sclaudio } 190e7adcfeaSclaudio switch ((c->flags >> 24) & 0xff) { 191dd87f852Sclaudio case COMMUNITY_ANY: 192dd87f852Sclaudio printf("* "); 193dd87f852Sclaudio break; 194dd87f852Sclaudio case COMMUNITY_NEIGHBOR_AS: 195dd87f852Sclaudio printf("neighbor-as "); 196dd87f852Sclaudio break; 197dd87f852Sclaudio case COMMUNITY_LOCAL_AS: 198dd87f852Sclaudio printf("local-as "); 199dd87f852Sclaudio break; 200dd87f852Sclaudio default: 201e7adcfeaSclaudio printf("%u ", c->data3); 202dd87f852Sclaudio break; 203dd87f852Sclaudio } 204dd87f852Sclaudio break; 20536e003c6Sclaudio case COMMUNITY_TYPE_EXT: 206e7adcfeaSclaudio if ((c->flags >> 24 & 0xff) == COMMUNITY_ANY) { 2070e6216fdSclaudio printf("* * "); 2080e6216fdSclaudio break; 2090e6216fdSclaudio } 210e7adcfeaSclaudio type = (int32_t)c->data3 >> 8; 211e7adcfeaSclaudio subtype = c->data3; 212e7adcfeaSclaudio printf("%s ", log_ext_subtype(type, subtype)); 213e7adcfeaSclaudio if ((c->flags >> 8 & 0xff) == COMMUNITY_ANY) { 2140e6216fdSclaudio printf("* "); 2150e6216fdSclaudio break; 2160e6216fdSclaudio } 2170e6216fdSclaudio 218e7adcfeaSclaudio switch (type) { 219bf8e2920Sclaudio case EXT_COMMUNITY_TRANS_TWO_AS: 22036e003c6Sclaudio case EXT_COMMUNITY_TRANS_FOUR_AS: 221a1957465Sclaudio case EXT_COMMUNITY_GEN_TWO_AS: 222a1957465Sclaudio case EXT_COMMUNITY_GEN_FOUR_AS: 223e7adcfeaSclaudio if ((c->flags >> 8 & 0xff) == COMMUNITY_NEIGHBOR_AS) 2240e6216fdSclaudio printf("neighbor-as:"); 225e7adcfeaSclaudio else if ((c->flags >> 8 & 0xff) == COMMUNITY_LOCAL_AS) 2260e6216fdSclaudio printf("local-as:"); 2270e6216fdSclaudio else 228e7adcfeaSclaudio printf("%s:", log_as(c->data1)); 229536f41e5Sclaudio break; 230bf8e2920Sclaudio case EXT_COMMUNITY_TRANS_IPV4: 231a1957465Sclaudio case EXT_COMMUNITY_GEN_IPV4: 232e7adcfeaSclaudio addr.s_addr = htonl(c->data1); 2330e6216fdSclaudio printf("%s:", inet_ntoa(addr)); 2340e6216fdSclaudio break; 2350e6216fdSclaudio } 2360e6216fdSclaudio 237e7adcfeaSclaudio switch (type) { 2380e6216fdSclaudio case EXT_COMMUNITY_TRANS_TWO_AS: 2390e6216fdSclaudio case EXT_COMMUNITY_TRANS_FOUR_AS: 2400e6216fdSclaudio case EXT_COMMUNITY_TRANS_IPV4: 241a1957465Sclaudio case EXT_COMMUNITY_GEN_TWO_AS: 242a1957465Sclaudio case EXT_COMMUNITY_GEN_FOUR_AS: 243a1957465Sclaudio case EXT_COMMUNITY_GEN_IPV4: 244e7adcfeaSclaudio if ((c->flags >> 16 & 0xff) == COMMUNITY_ANY) 2450e6216fdSclaudio printf("* "); 246e7adcfeaSclaudio else if ((c->flags >> 16 & 0xff) == 247e7adcfeaSclaudio COMMUNITY_NEIGHBOR_AS) 2480e6216fdSclaudio printf("neighbor-as "); 249e7adcfeaSclaudio else if ((c->flags >> 16 & 0xff) == COMMUNITY_LOCAL_AS) 2500e6216fdSclaudio printf("local-as "); 2510e6216fdSclaudio else 252e7adcfeaSclaudio printf("%u ", c->data2); 253bf8e2920Sclaudio break; 254bf8e2920Sclaudio case EXT_COMMUNITY_NON_TRANS_OPAQUE: 255e7adcfeaSclaudio if (subtype == EXT_COMMUNITY_SUBTYPE_OVS) { 256e7adcfeaSclaudio switch (c->data2) { 257bf8e2920Sclaudio case EXT_COMMUNITY_OVS_VALID: 258bf8e2920Sclaudio printf("valid "); 259bf8e2920Sclaudio break; 260bf8e2920Sclaudio case EXT_COMMUNITY_OVS_NOTFOUND: 261bf8e2920Sclaudio printf("not-found "); 262bf8e2920Sclaudio break; 263bf8e2920Sclaudio case EXT_COMMUNITY_OVS_INVALID: 264bf8e2920Sclaudio printf("invalid "); 265bf8e2920Sclaudio break; 266bf8e2920Sclaudio } 267536f41e5Sclaudio break; 2680e6216fdSclaudio } 269e7adcfeaSclaudio printf("0x%x%08x ", c->data1 & 0xffff, c->data2); 2700e6216fdSclaudio break; 271e7adcfeaSclaudio case EXT_COMMUNITY_TRANS_OPAQUE: 272e7adcfeaSclaudio case EXT_COMMUNITY_TRANS_EVPN: 273536f41e5Sclaudio default: 274e7adcfeaSclaudio printf("0x%x%08x ", c->data1 & 0xffff, c->data2); 275536f41e5Sclaudio break; 276536f41e5Sclaudio } 277536f41e5Sclaudio } 27836e003c6Sclaudio } 279536f41e5Sclaudio 280536f41e5Sclaudio void 28139386878Sclaudio print_origin(uint8_t o) 282cd3afea8Shenning { 283cd3afea8Shenning if (o == ORIGIN_IGP) 284cd3afea8Shenning printf("igp "); 285cd3afea8Shenning else if (o == ORIGIN_EGP) 286cd3afea8Shenning printf("egp "); 287cd3afea8Shenning else if (o == ORIGIN_INCOMPLETE) 288cd3afea8Shenning printf("incomplete "); 289cd3afea8Shenning else 290cd3afea8Shenning printf("%u ", o); 291cd3afea8Shenning } 292cd3afea8Shenning 293cd3afea8Shenning void 29498d902b5Sclaudio print_set(struct filter_set_head *set) 295866636d1Sclaudio { 29698d902b5Sclaudio struct filter_set *s; 29798d902b5Sclaudio 29876630fdaSclaudio if (TAILQ_EMPTY(set)) 29998d902b5Sclaudio return; 30098d902b5Sclaudio 301866636d1Sclaudio printf("set { "); 30276630fdaSclaudio TAILQ_FOREACH(s, set, entry) { 30398d902b5Sclaudio switch (s->type) { 30498d902b5Sclaudio case ACTION_SET_LOCALPREF: 30598d902b5Sclaudio printf("localpref %u ", s->action.metric); 30698d902b5Sclaudio break; 3072704869fSclaudio case ACTION_SET_RELATIVE_LOCALPREF: 3082704869fSclaudio printf("localpref %+d ", s->action.relative); 3092704869fSclaudio break; 31098d902b5Sclaudio case ACTION_SET_MED: 31198d902b5Sclaudio printf("metric %u ", s->action.metric); 31298d902b5Sclaudio break; 3132704869fSclaudio case ACTION_SET_RELATIVE_MED: 3142704869fSclaudio printf("metric %+d ", s->action.relative); 3152704869fSclaudio break; 316aa5d92feSclaudio case ACTION_SET_WEIGHT: 317aa5d92feSclaudio printf("weight %u ", s->action.metric); 318aa5d92feSclaudio break; 319aa5d92feSclaudio case ACTION_SET_RELATIVE_WEIGHT: 320aa5d92feSclaudio printf("weight %+d ", s->action.relative); 321aa5d92feSclaudio break; 32298d902b5Sclaudio case ACTION_SET_NEXTHOP: 32398d902b5Sclaudio printf("nexthop %s ", log_addr(&s->action.nexthop)); 32498d902b5Sclaudio break; 32598d902b5Sclaudio case ACTION_SET_NEXTHOP_REJECT: 326c29e5df5Shenning printf("nexthop reject "); 32798d902b5Sclaudio break; 32898d902b5Sclaudio case ACTION_SET_NEXTHOP_BLACKHOLE: 329c29e5df5Shenning printf("nexthop blackhole "); 33098d902b5Sclaudio break; 331ce9d64eaSclaudio case ACTION_SET_NEXTHOP_NOMODIFY: 332ce9d64eaSclaudio printf("nexthop no-modify "); 333ce9d64eaSclaudio break; 3347c989460Shenning case ACTION_SET_NEXTHOP_SELF: 3357c989460Shenning printf("nexthop self "); 3367c989460Shenning break; 33798d902b5Sclaudio case ACTION_SET_PREPEND_SELF: 33898d902b5Sclaudio printf("prepend-self %u ", s->action.prepend); 33998d902b5Sclaudio break; 34098d902b5Sclaudio case ACTION_SET_PREPEND_PEER: 34198d902b5Sclaudio printf("prepend-neighbor %u ", s->action.prepend); 34298d902b5Sclaudio break; 343d7a2dcd7Sclaudio case ACTION_SET_AS_OVERRIDE: 344d7a2dcd7Sclaudio printf("as-override "); 345d7a2dcd7Sclaudio break; 346aaa4f5dfSclaudio case ACTION_DEL_COMMUNITY: 347dd87f852Sclaudio printf("%s delete ", 348dd87f852Sclaudio community_type(&s->action.community)); 349dd87f852Sclaudio print_community(&s->action.community); 350aaa4f5dfSclaudio break; 35198d902b5Sclaudio case ACTION_SET_COMMUNITY: 352dd87f852Sclaudio printf("%s ", community_type(&s->action.community)); 353dd87f852Sclaudio print_community(&s->action.community); 354280f24a4Sphessler break; 35598d902b5Sclaudio case ACTION_PFTABLE: 35698d902b5Sclaudio printf("pftable %s ", s->action.pftable); 35798d902b5Sclaudio break; 35815aea9d4Sclaudio case ACTION_RTLABEL: 35915aea9d4Sclaudio printf("rtlabel %s ", s->action.rtlabel); 36015aea9d4Sclaudio break; 361cd3afea8Shenning case ACTION_SET_ORIGIN: 362cd3afea8Shenning printf("origin "); 363cd3afea8Shenning print_origin(s->action.origin); 364cd3afea8Shenning break; 36515aea9d4Sclaudio case ACTION_RTLABEL_ID: 366e2691ddeSclaudio case ACTION_PFTABLE_ID: 36723676e2aSclaudio case ACTION_SET_NEXTHOP_REF: 36815aea9d4Sclaudio /* not possible */ 369e2691ddeSclaudio printf("king bula saiz: config broken"); 37015aea9d4Sclaudio break; 371866636d1Sclaudio } 372866636d1Sclaudio } 37398d902b5Sclaudio printf("}"); 37498d902b5Sclaudio } 375866636d1Sclaudio 376866636d1Sclaudio void 377020327f0Shenning print_mainconf(struct bgpd_config *conf) 378020327f0Shenning { 379020327f0Shenning struct in_addr ina; 380f99a9452Shenning struct listen_addr *la; 381020327f0Shenning 3820c88bf70Sclaudio printf("AS %s", log_as(conf->as)); 3830c88bf70Sclaudio if (conf->as > USHRT_MAX && conf->short_as != AS_TRANS) 3840c88bf70Sclaudio printf(" %u", conf->short_as); 385bcd6516bSclaudio ina.s_addr = htonl(conf->bgpid); 3860c88bf70Sclaudio printf("\nrouter-id %s\n", inet_ntoa(ina)); 3871daa807cSclaudio 3881daa807cSclaudio printf("socket \"%s\"\n", conf->csock); 3891daa807cSclaudio if (conf->rcsock) 3901daa807cSclaudio printf("socket \"%s\" restricted\n", conf->rcsock); 391043e486bSclaudio if (conf->holdtime != INTERVAL_HOLD) 392020327f0Shenning printf("holdtime %u\n", conf->holdtime); 393043e486bSclaudio if (conf->min_holdtime != MIN_HOLDTIME) 394020327f0Shenning printf("holdtime min %u\n", conf->min_holdtime); 395043e486bSclaudio if (conf->connectretry != INTERVAL_CONNECTRETRY) 396471e75faSreyk printf("connect-retry %u\n", conf->connectretry); 3976c15f943Sclaudio if (conf->staletime != INTERVAL_STALE) 3986c15f943Sclaudio printf("staletime %u\n", conf->staletime); 399020327f0Shenning 40088ca7a8dSclaudio if (conf->flags & BGPD_FLAG_DECISION_ROUTEAGE) 40188ca7a8dSclaudio printf("rde route-age evaluate\n"); 40214aa7f77Sclaudio if (conf->flags & BGPD_FLAG_DECISION_MED_ALWAYS) 40314aa7f77Sclaudio printf("rde med compare always\n"); 40405ebbbf6Sclaudio if (conf->flags & BGPD_FLAG_DECISION_ALL_PATHS) 40505ebbbf6Sclaudio printf("rde evaluate all\n"); 40614aa7f77Sclaudio 407*e3db1f63Sclaudio if (conf->flags & BGPD_FLAG_PERMIT_AS_SET) 408*e3db1f63Sclaudio printf("reject as-set no\n"); 409aa528464Sclaudio 410020327f0Shenning if (conf->log & BGPD_LOG_UPDATES) 411020327f0Shenning printf("log updates\n"); 412020327f0Shenning 4133c001116Sclaudio TAILQ_FOREACH(la, conf->listen_addrs, entry) { 4143c001116Sclaudio struct bgpd_addr addr; 4153c001116Sclaudio uint16_t port; 4163c001116Sclaudio 4173c001116Sclaudio sa2addr((struct sockaddr *)&la->sa, &addr, &port); 4183c001116Sclaudio printf("listen on %s", 419255fe563Sclaudio log_sockaddr((struct sockaddr *)&la->sa, la->sa_len)); 4203c001116Sclaudio if (port != BGP_PORT) 4213c001116Sclaudio printf(" port %hu", port); 4223c001116Sclaudio printf("\n"); 4233c001116Sclaudio } 4247fedd3ccSclaudio 425faf535a4Sclaudio if (conf->flags & BGPD_FLAG_NEXTHOP_BGP) 426faf535a4Sclaudio printf("nexthop qualify via bgp\n"); 427faf535a4Sclaudio if (conf->flags & BGPD_FLAG_NEXTHOP_DEFAULT) 428faf535a4Sclaudio printf("nexthop qualify via default\n"); 429ce68a032Sclaudio if (conf->fib_priority != kr_default_prio()) 430043e486bSclaudio printf("fib-priority %hhu\n", conf->fib_priority); 431043e486bSclaudio printf("\n"); 432610bcb44Sclaudio } 433faf535a4Sclaudio 434610bcb44Sclaudio void 4354e0c4e97Sclaudio print_l3vpn_targets(struct filter_set_head *set, const char *tgt) 436610bcb44Sclaudio { 437610bcb44Sclaudio struct filter_set *s; 438610bcb44Sclaudio TAILQ_FOREACH(s, set, entry) { 439610bcb44Sclaudio printf("\t%s ", tgt); 44036e003c6Sclaudio print_community(&s->action.community); 4417fedd3ccSclaudio printf("\n"); 4427fedd3ccSclaudio } 4437fedd3ccSclaudio } 444610bcb44Sclaudio 445610bcb44Sclaudio void 4464e0c4e97Sclaudio print_l3vpn(struct l3vpn *vpn) 447610bcb44Sclaudio { 4481274ebf8Sclaudio struct network *n; 4491274ebf8Sclaudio 4504e0c4e97Sclaudio printf("vpn \"%s\" on %s {\n", vpn->descr, vpn->ifmpe); 451f3d22dbcSclaudio printf("\t%s\n", log_rd(vpn->rd)); 4524e0c4e97Sclaudio 4534e0c4e97Sclaudio print_l3vpn_targets(&vpn->export, "export-target"); 4544e0c4e97Sclaudio print_l3vpn_targets(&vpn->import, "import-target"); 4554e0c4e97Sclaudio 4564e0c4e97Sclaudio if (vpn->flags & F_RIB_NOFIBSYNC) 457610bcb44Sclaudio printf("\tfib-update no\n"); 458610bcb44Sclaudio else 459610bcb44Sclaudio printf("\tfib-update yes\n"); 460610bcb44Sclaudio 4614e0c4e97Sclaudio TAILQ_FOREACH(n, &vpn->net_l, entry) 4621274ebf8Sclaudio print_network(&n->net, "\t"); 4631274ebf8Sclaudio 464610bcb44Sclaudio printf("}\n"); 465e6f00aedSclaudio } 466610bcb44Sclaudio 467610bcb44Sclaudio const char * 46839386878Sclaudio print_af(uint8_t aid) 469610bcb44Sclaudio { 470610bcb44Sclaudio /* 471610bcb44Sclaudio * Hack around the fact that aid2str() will return "IPv4 unicast" 4727d4aa781Sclaudio * for AID_INET. AID_INET, AID_INET6 and the flowspec AID need 4737d4aa781Sclaudio * special handling and the other AID should never end up here. 474610bcb44Sclaudio */ 4757d4aa781Sclaudio if (aid == AID_INET || aid == AID_FLOWSPECv4) 476610bcb44Sclaudio return ("inet"); 4777d4aa781Sclaudio if (aid == AID_INET6 || aid == AID_FLOWSPECv6) 478610bcb44Sclaudio return ("inet6"); 479610bcb44Sclaudio return (aid2str(aid)); 480020327f0Shenning } 481020327f0Shenning 482020327f0Shenning void 4831274ebf8Sclaudio print_network(struct network_config *n, const char *c) 484294d4e13Shenning { 485610bcb44Sclaudio switch (n->type) { 486610bcb44Sclaudio case NETWORK_STATIC: 4871274ebf8Sclaudio printf("%snetwork %s static", c, print_af(n->prefix.aid)); 488610bcb44Sclaudio break; 489610bcb44Sclaudio case NETWORK_CONNECTED: 4901274ebf8Sclaudio printf("%snetwork %s connected", c, print_af(n->prefix.aid)); 491610bcb44Sclaudio break; 492f6296dcfSphessler case NETWORK_RTLABEL: 493f6296dcfSphessler printf("%snetwork %s rtlabel \"%s\"", c, 494f6296dcfSphessler print_af(n->prefix.aid), rtlabel_id2name(n->rtlabel)); 495f6296dcfSphessler break; 4968d028d67Sbenno case NETWORK_PRIORITY: 4978d028d67Sbenno printf("%snetwork %s priority %d", c, 4988d028d67Sbenno print_af(n->prefix.aid), n->priority); 4998d028d67Sbenno break; 50047feec7cSbenno case NETWORK_PREFIXSET: 50147feec7cSbenno printf("%snetwork prefix-set %s", c, n->psname); 50247feec7cSbenno break; 503610bcb44Sclaudio default: 5041274ebf8Sclaudio printf("%snetwork %s/%u", c, log_addr(&n->prefix), 5051274ebf8Sclaudio n->prefixlen); 506610bcb44Sclaudio break; 507610bcb44Sclaudio } 50876630fdaSclaudio if (!TAILQ_EMPTY(&n->attrset)) 5096a49a14cSclaudio printf(" "); 510866636d1Sclaudio print_set(&n->attrset); 511866636d1Sclaudio printf("\n"); 512294d4e13Shenning } 513294d4e13Shenning 5147d4aa781Sclaudio static void 5157d4aa781Sclaudio print_flowspec_list(struct flowspec *f, int type, int is_v6) 5167d4aa781Sclaudio { 5177d4aa781Sclaudio const uint8_t *comp; 5187d4aa781Sclaudio const char *fmt; 5197d4aa781Sclaudio int complen, off = 0; 5207d4aa781Sclaudio 5217d4aa781Sclaudio if (flowspec_get_component(f->data, f->len, type, is_v6, 5227d4aa781Sclaudio &comp, &complen) != 1) 5237d4aa781Sclaudio return; 5247d4aa781Sclaudio 5257d4aa781Sclaudio printf("%s ", flowspec_fmt_label(type)); 5267d4aa781Sclaudio fmt = flowspec_fmt_num_op(comp, complen, &off); 5277d4aa781Sclaudio if (off == -1) { 5287d4aa781Sclaudio printf("%s ", fmt); 5297d4aa781Sclaudio } else { 5307d4aa781Sclaudio printf("{ %s ", fmt); 5317d4aa781Sclaudio do { 5327d4aa781Sclaudio fmt = flowspec_fmt_num_op(comp, complen, &off); 5337d4aa781Sclaudio printf("%s ", fmt); 5347d4aa781Sclaudio } while (off != -1); 5357d4aa781Sclaudio printf("} "); 5367d4aa781Sclaudio } 5377d4aa781Sclaudio } 5387d4aa781Sclaudio 5397d4aa781Sclaudio static void 5407d4aa781Sclaudio print_flowspec_flags(struct flowspec *f, int type, int is_v6) 5417d4aa781Sclaudio { 5427d4aa781Sclaudio const uint8_t *comp; 5437d4aa781Sclaudio const char *fmt, *flags; 5447d4aa781Sclaudio int complen, off = 0; 5457d4aa781Sclaudio 5467d4aa781Sclaudio switch (type) { 5477d4aa781Sclaudio case FLOWSPEC_TYPE_TCP_FLAGS: 5487d4aa781Sclaudio flags = FLOWSPEC_TCP_FLAG_STRING; 5497d4aa781Sclaudio break; 5507d4aa781Sclaudio case FLOWSPEC_TYPE_FRAG: 5517d4aa781Sclaudio if (!is_v6) 5527d4aa781Sclaudio flags = FLOWSPEC_FRAG_STRING4; 5537d4aa781Sclaudio else 5547d4aa781Sclaudio flags = FLOWSPEC_FRAG_STRING6; 5557d4aa781Sclaudio break; 5560adb143fSclaudio default: 5570adb143fSclaudio printf("??? "); 5580adb143fSclaudio return; 5597d4aa781Sclaudio } 5607d4aa781Sclaudio 5610adb143fSclaudio if (flowspec_get_component(f->data, f->len, type, is_v6, 5620adb143fSclaudio &comp, &complen) != 1) 5630adb143fSclaudio return; 5640adb143fSclaudio 5650adb143fSclaudio printf("%s ", flowspec_fmt_label(type)); 5660adb143fSclaudio 5677d4aa781Sclaudio fmt = flowspec_fmt_bin_op(comp, complen, &off, flags); 5687d4aa781Sclaudio if (off == -1) { 5697d4aa781Sclaudio printf("%s ", fmt); 5707d4aa781Sclaudio } else { 5717d4aa781Sclaudio printf("{ %s ", fmt); 5727d4aa781Sclaudio do { 5737d4aa781Sclaudio fmt = flowspec_fmt_bin_op(comp, complen, &off, flags); 5747d4aa781Sclaudio printf("%s ", fmt); 5757d4aa781Sclaudio } while (off != -1); 5767d4aa781Sclaudio printf("} "); 5777d4aa781Sclaudio } 5787d4aa781Sclaudio } 5797d4aa781Sclaudio 5807d4aa781Sclaudio static void 5817d4aa781Sclaudio print_flowspec_addr(struct flowspec *f, int type, int is_v6) 5827d4aa781Sclaudio { 5837d4aa781Sclaudio struct bgpd_addr addr; 5847d4aa781Sclaudio uint8_t plen; 5857d4aa781Sclaudio 5867d4aa781Sclaudio flowspec_get_addr(f->data, f->len, type, is_v6, &addr, &plen, NULL); 5877d4aa781Sclaudio if (plen == 0) 5887d4aa781Sclaudio printf("%s any ", flowspec_fmt_label(type)); 5897d4aa781Sclaudio else 5907d4aa781Sclaudio printf("%s %s/%u ", flowspec_fmt_label(type), 5917d4aa781Sclaudio log_addr(&addr), plen); 5927d4aa781Sclaudio } 5937d4aa781Sclaudio 5947d4aa781Sclaudio void 5957d4aa781Sclaudio print_flowspec(struct flowspec_config *fconf, const char *c) 5967d4aa781Sclaudio { 5977d4aa781Sclaudio struct flowspec *f = fconf->flow; 5987d4aa781Sclaudio int is_v6 = (f->aid == AID_FLOWSPECv6); 5997d4aa781Sclaudio 6007d4aa781Sclaudio printf("%sflowspec %s ", c, print_af(f->aid)); 6017d4aa781Sclaudio 6027d4aa781Sclaudio print_flowspec_list(f, FLOWSPEC_TYPE_PROTO, is_v6); 6037d4aa781Sclaudio 6047d4aa781Sclaudio print_flowspec_addr(f, FLOWSPEC_TYPE_SOURCE, is_v6); 6057d4aa781Sclaudio print_flowspec_list(f, FLOWSPEC_TYPE_SRC_PORT, is_v6); 6067d4aa781Sclaudio 6077d4aa781Sclaudio print_flowspec_addr(f, FLOWSPEC_TYPE_DEST, is_v6); 6087d4aa781Sclaudio print_flowspec_list(f, FLOWSPEC_TYPE_DST_PORT, is_v6); 6097d4aa781Sclaudio 6107d4aa781Sclaudio print_flowspec_list(f, FLOWSPEC_TYPE_DSCP, is_v6); 6117d4aa781Sclaudio print_flowspec_list(f, FLOWSPEC_TYPE_PKT_LEN, is_v6); 6127d4aa781Sclaudio print_flowspec_flags(f, FLOWSPEC_TYPE_TCP_FLAGS, is_v6); 6137d4aa781Sclaudio print_flowspec_flags(f, FLOWSPEC_TYPE_FRAG, is_v6); 6147d4aa781Sclaudio 6157d4aa781Sclaudio /* TODO: fixup the code handling to be like in the parser */ 6167d4aa781Sclaudio print_flowspec_list(f, FLOWSPEC_TYPE_ICMP_TYPE, is_v6); 6177d4aa781Sclaudio print_flowspec_list(f, FLOWSPEC_TYPE_ICMP_CODE, is_v6); 6187d4aa781Sclaudio 6197d4aa781Sclaudio print_set(&fconf->attrset); 6207d4aa781Sclaudio printf("\n"); 6217d4aa781Sclaudio } 6227d4aa781Sclaudio 623294d4e13Shenning void 62459e404fbSclaudio print_as_sets(struct as_set_head *as_sets) 62559e404fbSclaudio { 62659e404fbSclaudio struct as_set *aset; 62739386878Sclaudio uint32_t *as; 62859e404fbSclaudio size_t i, n; 62959e404fbSclaudio int len; 63059e404fbSclaudio 63159e404fbSclaudio SIMPLEQ_FOREACH(aset, as_sets, entry) { 63259e404fbSclaudio printf("as-set \"%s\" {\n\t", aset->name); 63359e404fbSclaudio as = set_get(aset->set, &n); 63459e404fbSclaudio for (i = 0, len = 8; i < n; i++) { 63559e404fbSclaudio if (len > 72) { 63659e404fbSclaudio printf("\n\t"); 63759e404fbSclaudio len = 8; 63859e404fbSclaudio } 63959e404fbSclaudio len += printf("%u ", as[i]); 64059e404fbSclaudio } 64159e404fbSclaudio printf("\n}\n\n"); 64259e404fbSclaudio } 64359e404fbSclaudio } 64459e404fbSclaudio 64559e404fbSclaudio void 646441aaadcSbenno print_prefixsets(struct prefixset_head *psh) 647441aaadcSbenno { 648441aaadcSbenno struct prefixset *ps; 649441aaadcSbenno struct prefixset_item *psi; 650441aaadcSbenno 651441aaadcSbenno SIMPLEQ_FOREACH(ps, psh, entry) { 652b7fbf694Sclaudio int count = 0; 6534ea66b69Sclaudio printf("prefix-set \"%s\" {", ps->name); 654d32b24c8Sclaudio RB_FOREACH(psi, prefixset_tree, &ps->psitems) { 6554ea66b69Sclaudio if (count++ % 2 == 0) 6564ea66b69Sclaudio printf("\n\t"); 6574ea66b69Sclaudio else 6584ea66b69Sclaudio printf(", "); 6594ea66b69Sclaudio print_prefix(&psi->p); 660b7fbf694Sclaudio } 661b7fbf694Sclaudio printf("\n}\n\n"); 662441aaadcSbenno } 663441aaadcSbenno } 664441aaadcSbenno 665441aaadcSbenno void 6666f1dba6eSclaudio print_originsets(struct prefixset_head *psh) 667502ece1dSclaudio { 668502ece1dSclaudio struct prefixset *ps; 6696aa533f4Sclaudio struct roa *roa; 6706aa533f4Sclaudio struct bgpd_addr addr; 671502ece1dSclaudio 672502ece1dSclaudio SIMPLEQ_FOREACH(ps, psh, entry) { 6736f1dba6eSclaudio printf("origin-set \"%s\" {", ps->name); 6746aa533f4Sclaudio RB_FOREACH(roa, roa_tree, &ps->roaitems) { 675502ece1dSclaudio printf("\n\t"); 6766aa533f4Sclaudio addr.aid = roa->aid; 6776aa533f4Sclaudio addr.v6 = roa->prefix.inet6; 6786aa533f4Sclaudio printf("%s/%u", log_addr(&addr), roa->prefixlen); 6796aa533f4Sclaudio if (roa->prefixlen != roa->maxlen) 6806aa533f4Sclaudio printf(" maxlen %u", roa->maxlen); 6816aa533f4Sclaudio printf(" source-as %u", roa->asnum); 682502ece1dSclaudio } 683502ece1dSclaudio printf("\n}\n\n"); 684502ece1dSclaudio } 685502ece1dSclaudio } 686502ece1dSclaudio 687502ece1dSclaudio void 6886aa533f4Sclaudio print_roa(struct roa_tree *r) 6896f1dba6eSclaudio { 6906aa533f4Sclaudio struct roa *roa; 6916f1dba6eSclaudio 6926aa533f4Sclaudio if (RB_EMPTY(r)) 6936f1dba6eSclaudio return; 6946f1dba6eSclaudio 6956f1dba6eSclaudio printf("roa-set {"); 6966aa533f4Sclaudio RB_FOREACH(roa, roa_tree, r) { 6976290e740Sclaudio printf("\n\t%s", log_roa(roa)); 6986f1dba6eSclaudio } 6996f1dba6eSclaudio printf("\n}\n\n"); 7006f1dba6eSclaudio } 7016f1dba6eSclaudio 7026f1dba6eSclaudio void 703ff84f55eSclaudio print_aspa(struct aspa_tree *a) 704ff84f55eSclaudio { 705ff84f55eSclaudio struct aspa_set *aspa; 706ff84f55eSclaudio 707ff84f55eSclaudio if (RB_EMPTY(a)) 708ff84f55eSclaudio return; 709ff84f55eSclaudio 710ff84f55eSclaudio printf("aspa-set {"); 711ff84f55eSclaudio RB_FOREACH(aspa, aspa_tree, a) { 7126290e740Sclaudio printf("\n\t%s", log_aspa(aspa)); 713ff84f55eSclaudio } 714ff84f55eSclaudio printf("\n}\n\n"); 715ff84f55eSclaudio } 716ff84f55eSclaudio 717a2dc744eSclaudio static void 718a2dc744eSclaudio print_auth(struct auth_config *auth, const char *c) 719a2dc744eSclaudio { 720a2dc744eSclaudio char *method; 721a2dc744eSclaudio 722a2dc744eSclaudio if (auth->method == AUTH_MD5SIG) 723a2dc744eSclaudio printf("%s\ttcp md5sig\n", c); 724a2dc744eSclaudio else if (auth->method == AUTH_IPSEC_MANUAL_ESP || 725a2dc744eSclaudio auth->method == AUTH_IPSEC_MANUAL_AH) { 726a2dc744eSclaudio if (auth->method == AUTH_IPSEC_MANUAL_ESP) 727a2dc744eSclaudio method = "esp"; 728a2dc744eSclaudio else 729a2dc744eSclaudio method = "ah"; 730a2dc744eSclaudio 731a2dc744eSclaudio printf("%s\tipsec %s in spi %u %s XXXXXX", c, method, 732a2dc744eSclaudio auth->spi_in, print_auth_alg(auth->auth_alg_in)); 733a2dc744eSclaudio if (auth->enc_alg_in) 734a2dc744eSclaudio printf(" %s XXXXXX", print_enc_alg(auth->enc_alg_in)); 735a2dc744eSclaudio printf("\n"); 736a2dc744eSclaudio 737a2dc744eSclaudio printf("%s\tipsec %s out spi %u %s XXXXXX", c, method, 738a2dc744eSclaudio auth->spi_out, print_auth_alg(auth->auth_alg_out)); 739a2dc744eSclaudio if (auth->enc_alg_out) 740a2dc744eSclaudio printf(" %s XXXXXX", 741a2dc744eSclaudio print_enc_alg(auth->enc_alg_out)); 742a2dc744eSclaudio printf("\n"); 743a2dc744eSclaudio } else if (auth->method == AUTH_IPSEC_IKE_AH) 744a2dc744eSclaudio printf("%s\tipsec ah ike\n", c); 745a2dc744eSclaudio else if (auth->method == AUTH_IPSEC_IKE_ESP) 746a2dc744eSclaudio printf("%s\tipsec esp ike\n", c); 747a2dc744eSclaudio 748a2dc744eSclaudio } 749a2dc744eSclaudio 750ff84f55eSclaudio void 751bd9df44eSclaudio print_rtrs(struct rtr_config_head *rh) 752bd9df44eSclaudio { 753bd9df44eSclaudio struct rtr_config *r; 754bd9df44eSclaudio 755bd9df44eSclaudio SIMPLEQ_FOREACH(r, rh, entry) { 756bd9df44eSclaudio printf("rtr %s {\n", log_addr(&r->remote_addr)); 757bd9df44eSclaudio printf("\tdescr \"%s\"\n", r->descr); 758bd9df44eSclaudio printf("\tport %u\n", r->remote_port); 759bd9df44eSclaudio if (r->local_addr.aid != AID_UNSPEC) 760bd9df44eSclaudio printf("local-addr %s\n", log_addr(&r->local_addr)); 761a2dc744eSclaudio print_auth(&r->auth, ""); 762bd9df44eSclaudio printf("}\n\n"); 763bd9df44eSclaudio } 764bd9df44eSclaudio } 765bd9df44eSclaudio 766bd9df44eSclaudio void 767d7629114Sclaudio print_peer(struct peer *peer, struct bgpd_config *conf, const char *c) 768020327f0Shenning { 769c7bd57b6Sclaudio struct in_addr ina; 770d7629114Sclaudio struct peer_config *p = &peer->conf; 771020327f0Shenning 772d6c2e4e8Sclaudio if ((p->remote_addr.aid == AID_INET && p->remote_masklen != 32) || 773d6c2e4e8Sclaudio (p->remote_addr.aid == AID_INET6 && p->remote_masklen != 128)) 7746bf392efShenning printf("%sneighbor %s/%u {\n", c, log_addr(&p->remote_addr), 7756bf392efShenning p->remote_masklen); 7766bf392efShenning else 777020327f0Shenning printf("%sneighbor %s {\n", c, log_addr(&p->remote_addr)); 778d8abd003Shenning if (p->descr[0]) 779020327f0Shenning printf("%s\tdescr \"%s\"\n", c, p->descr); 78098daafc0Sclaudio if (p->rib[0]) 78198daafc0Sclaudio printf("%s\trib \"%s\"\n", c, p->rib); 7826bf392efShenning if (p->remote_as) 7830c88bf70Sclaudio printf("%s\tremote-as %s\n", c, log_as(p->remote_as)); 784f0bc600cSphessler if (p->local_as != conf->as) { 785f0bc600cSphessler printf("%s\tlocal-as %s", c, log_as(p->local_as)); 786f0bc600cSphessler if (p->local_as > USHRT_MAX && p->local_short_as != AS_TRANS) 787f0bc600cSphessler printf(" %u", p->local_short_as); 788f0bc600cSphessler printf("\n"); 789f0bc600cSphessler } 790dbdbcd65Shenning if (p->down) 791dbdbcd65Shenning printf("%s\tdown\n", c); 792020327f0Shenning if (p->distance > 1) 793020327f0Shenning printf("%s\tmultihop %u\n", c, p->distance); 794020327f0Shenning if (p->passive) 795020327f0Shenning printf("%s\tpassive\n", c); 796589de3c2Sclaudio if (p->local_addr_v4.aid) 797589de3c2Sclaudio printf("%s\tlocal-address %s\n", c, 798589de3c2Sclaudio log_addr(&p->local_addr_v4)); 799589de3c2Sclaudio if (p->local_addr_v6.aid) 800589de3c2Sclaudio printf("%s\tlocal-address %s\n", c, 801589de3c2Sclaudio log_addr(&p->local_addr_v6)); 8023c001116Sclaudio if (p->remote_port != BGP_PORT) 8033c001116Sclaudio printf("%s\tport %hu\n", c, p->remote_port); 804c0c94bccSclaudio if (p->role != ROLE_NONE) 805c0c94bccSclaudio printf("%s\trole %s\n", c, log_policy(p->role)); 80668030d48Shenning if (p->max_prefix) { 80768030d48Shenning printf("%s\tmax-prefix %u", c, p->max_prefix); 80868030d48Shenning if (p->max_prefix_restart) 80968030d48Shenning printf(" restart %u", p->max_prefix_restart); 81068030d48Shenning printf("\n"); 81168030d48Shenning } 812c84ce86dSclaudio if (p->max_out_prefix) { 813c84ce86dSclaudio printf("%s\tmax-prefix %u out", c, p->max_out_prefix); 814c84ce86dSclaudio if (p->max_out_prefix_restart) 815c84ce86dSclaudio printf(" restart %u", p->max_out_prefix_restart); 816c84ce86dSclaudio printf("\n"); 817c84ce86dSclaudio } 818020327f0Shenning if (p->holdtime) 819020327f0Shenning printf("%s\tholdtime %u\n", c, p->holdtime); 820020327f0Shenning if (p->min_holdtime) 821020327f0Shenning printf("%s\tholdtime min %u\n", c, p->min_holdtime); 8226c15f943Sclaudio if (p->staletime) 8236c15f943Sclaudio printf("%s\tstaletime %u\n", c, p->staletime); 824f390b1a7Sclaudio if (p->export_type == EXPORT_NONE) 825f390b1a7Sclaudio printf("%s\texport none\n", c); 826f390b1a7Sclaudio else if (p->export_type == EXPORT_DEFAULT_ROUTE) 827f390b1a7Sclaudio printf("%s\texport default-route\n", c); 828c7bd57b6Sclaudio if (p->enforce_as == ENFORCE_AS_ON) 829c7bd57b6Sclaudio printf("%s\tenforce neighbor-as yes\n", c); 830c7bd57b6Sclaudio else 831c7bd57b6Sclaudio printf("%s\tenforce neighbor-as no\n", c); 8326c1bc9bcSphessler if (p->enforce_local_as == ENFORCE_AS_ON) 8336c1bc9bcSphessler printf("%s\tenforce local-as yes\n", c); 8346c1bc9bcSphessler else 8356c1bc9bcSphessler printf("%s\tenforce local-as no\n", c); 836c7bd57b6Sclaudio if (p->reflector_client) { 837c7bd57b6Sclaudio if (conf->clusterid == 0) 838c7bd57b6Sclaudio printf("%s\troute-reflector\n", c); 839c7bd57b6Sclaudio else { 840bcd6516bSclaudio ina.s_addr = htonl(conf->clusterid); 841c7bd57b6Sclaudio printf("%s\troute-reflector %s\n", c, 842c7bd57b6Sclaudio inet_ntoa(ina)); 843c7bd57b6Sclaudio } 844c7bd57b6Sclaudio } 84527428f9dShenning if (p->demote_group[0]) 84627428f9dShenning printf("%s\tdemote %s\n", c, p->demote_group); 847dc228c27Shenning if (p->if_depend[0]) 848dc228c27Shenning printf("%s\tdepend on \"%s\"\n", c, p->if_depend); 849241ce197Shenning if (p->flags & PEERFLAG_TRANS_AS) 850181a1be0Shenning printf("%s\ttransparent-as yes\n", c); 851a27194f9Shenning 85205ebbbf6Sclaudio if (conf->flags & BGPD_FLAG_DECISION_ALL_PATHS) { 85305ebbbf6Sclaudio if (!(p->flags & PEERFLAG_EVALUATE_ALL)) 85405ebbbf6Sclaudio printf("%s\trde evaluate default\n", c); 85505ebbbf6Sclaudio } else { 85605ebbbf6Sclaudio if (p->flags & PEERFLAG_EVALUATE_ALL) 85705ebbbf6Sclaudio printf("%s\trde evaluate all\n", c); 85805ebbbf6Sclaudio } 85905ebbbf6Sclaudio 860*e3db1f63Sclaudio if (conf->flags & BGPD_FLAG_PERMIT_AS_SET) { 861*e3db1f63Sclaudio if (!(p->flags & PEERFLAG_PERMIT_AS_SET)) 862aa528464Sclaudio printf("%s\treject as-set yes\n", c); 863*e3db1f63Sclaudio } else { 864*e3db1f63Sclaudio if (p->flags & PEERFLAG_PERMIT_AS_SET) 865*e3db1f63Sclaudio printf("%s\treject as-set no\n", c); 866aa528464Sclaudio } 867aa528464Sclaudio 8687285b4d6Sphessler if (p->flags & PEERFLAG_LOG_UPDATES) 8697285b4d6Sphessler printf("%s\tlog updates\n", c); 8707285b4d6Sphessler 871a2dc744eSclaudio print_auth(&peer->auth_conf, c); 872866636d1Sclaudio 873906a57b3Shenning if (p->ttlsec) 874906a57b3Shenning printf("%s\tttl-security yes\n", c); 875906a57b3Shenning 87686729c90Sclaudio print_announce(p, c); 8776987aa3aShenning 878d288d268Sclaudio print_mrt(conf, p->id, p->groupid, c, "\t"); 879866636d1Sclaudio 880020327f0Shenning printf("%s}\n", c); 881020327f0Shenning } 882020327f0Shenning 883a27194f9Shenning const char * 88493662c4eSclaudio print_auth_alg(enum auth_alg alg) 885a27194f9Shenning { 886a27194f9Shenning switch (alg) { 88793662c4eSclaudio case AUTH_AALG_SHA1HMAC: 888a27194f9Shenning return ("sha1"); 88993662c4eSclaudio case AUTH_AALG_MD5HMAC: 890a27194f9Shenning return ("md5"); 891a27194f9Shenning default: 892a27194f9Shenning return ("???"); 893a27194f9Shenning } 894a27194f9Shenning } 895a27194f9Shenning 896a27194f9Shenning const char * 89793662c4eSclaudio print_enc_alg(enum auth_enc_alg alg) 898a27194f9Shenning { 899a27194f9Shenning switch (alg) { 90093662c4eSclaudio case AUTH_EALG_3DESCBC: 901a27194f9Shenning return ("3des"); 90293662c4eSclaudio case AUTH_EALG_AES: 903a27194f9Shenning return ("aes"); 904a27194f9Shenning default: 905a27194f9Shenning return ("???"); 906a27194f9Shenning } 907a27194f9Shenning } 908a27194f9Shenning 9095014683fSclaudio static const char * 9105014683fSclaudio print_addpath_mode(enum addpath_mode mode) 9115014683fSclaudio { 9125014683fSclaudio switch (mode) { 9135014683fSclaudio case ADDPATH_EVAL_NONE: 9145014683fSclaudio return "none"; 9155014683fSclaudio case ADDPATH_EVAL_BEST: 9165014683fSclaudio return "best"; 9175014683fSclaudio case ADDPATH_EVAL_ECMP: 9185014683fSclaudio return "ecmp"; 9195014683fSclaudio case ADDPATH_EVAL_AS_WIDE: 9205014683fSclaudio return "as-wide-best"; 9215014683fSclaudio case ADDPATH_EVAL_ALL: 9225014683fSclaudio return "all"; 923a6facc3cSclaudio default: 924a6facc3cSclaudio return "???"; 9255014683fSclaudio } 9265014683fSclaudio } 9275014683fSclaudio 92886729c90Sclaudio void 92986729c90Sclaudio print_announce(struct peer_config *p, const char *c) 9306987aa3aShenning { 93139386878Sclaudio uint8_t aid; 9324b1bc0cbSclaudio int match = 0; 93386729c90Sclaudio 934110c1584Sclaudio for (aid = AID_MIN; aid < AID_MAX; aid++) 9354b1bc0cbSclaudio if (p->capabilities.mp[aid] == 2) { 9364b1bc0cbSclaudio printf("%s\tannounce %s enforce\n", c, aid2str(aid)); 9374b1bc0cbSclaudio match = 1; 9384b1bc0cbSclaudio } else if (p->capabilities.mp[aid]) { 93986729c90Sclaudio printf("%s\tannounce %s\n", c, aid2str(aid)); 9404b1bc0cbSclaudio match = 1; 9414b1bc0cbSclaudio } 9424b1bc0cbSclaudio if (!match) { 9434b1bc0cbSclaudio printf("%s\tannounce IPv4 none\n", c); 9444b1bc0cbSclaudio printf("%s\tannounce IPv6 none\n", c); 9454b1bc0cbSclaudio } 9461114d9c2Sclaudio 9474b1bc0cbSclaudio if (p->capabilities.refresh == 2) 9484b1bc0cbSclaudio printf("%s\tannounce refresh enforce\n", c); 9494b1bc0cbSclaudio else if (p->capabilities.refresh == 0) 9501114d9c2Sclaudio printf("%s\tannounce refresh no\n", c); 9514b1bc0cbSclaudio 9524b1bc0cbSclaudio if (p->capabilities.enhanced_rr == 2) 9534b1bc0cbSclaudio printf("%s\tannounce enhanced refresh enforce\n", c); 9544b1bc0cbSclaudio else if (p->capabilities.enhanced_rr == 1) 95570078a52Sclaudio printf("%s\tannounce enhanced refresh yes\n", c); 9564b1bc0cbSclaudio 9574b1bc0cbSclaudio if (p->capabilities.grestart.restart == 2) 9584b1bc0cbSclaudio printf("%s\tannounce restart enforce\n", c); 9594b1bc0cbSclaudio else if (p->capabilities.grestart.restart == 0) 9601114d9c2Sclaudio printf("%s\tannounce restart no\n", c); 9614b1bc0cbSclaudio 9626c15f943Sclaudio if (p->capabilities.grestart.restart != 0 && 9636c15f943Sclaudio p->capabilities.grestart.grnotification) 9646c15f943Sclaudio printf("%s\tannounce graceful notification yes\n", c); 9656c15f943Sclaudio 9664b1bc0cbSclaudio if (p->capabilities.as4byte == 2) 9674b1bc0cbSclaudio printf("%s\tannounce as4byte enforce\n", c); 9684b1bc0cbSclaudio else if (p->capabilities.as4byte == 0) 9691114d9c2Sclaudio printf("%s\tannounce as4byte no\n", c); 9704b1bc0cbSclaudio 97125cbba3aSclaudio if (p->capabilities.ext_msg == 2) 97263aaa84cSclaudio printf("%s\tannounce extended message enforce\n", c); 97325cbba3aSclaudio else if (p->capabilities.ext_msg == 1) 97463aaa84cSclaudio printf("%s\tannounce extended message yes\n", c); 97525cbba3aSclaudio 976927cc6daSclaudio if (p->capabilities.ext_nh[AID_INET] == 2) 977927cc6daSclaudio printf("%s\tannounce extended nexthop enforce\n", c); 978927cc6daSclaudio else if (p->capabilities.ext_nh[AID_INET] == 1) 979927cc6daSclaudio printf("%s\tannounce extended nexthop yes\n", c); 980927cc6daSclaudio 9814b1bc0cbSclaudio if (p->capabilities.add_path[AID_MIN] & CAPA_AP_RECV_ENFORCE) 9824b1bc0cbSclaudio printf("%s\tannounce add-path recv enforce\n", c); 9834b1bc0cbSclaudio else if (p->capabilities.add_path[AID_MIN] & CAPA_AP_RECV) 9841114d9c2Sclaudio printf("%s\tannounce add-path recv yes\n", c); 9854b1bc0cbSclaudio 9864b1bc0cbSclaudio if (p->capabilities.add_path[AID_MIN] & CAPA_AP_SEND) { 9875014683fSclaudio printf("%s\tannounce add-path send %s", c, 9885014683fSclaudio print_addpath_mode(p->eval.mode)); 9895014683fSclaudio if (p->eval.extrapaths != 0) 9905014683fSclaudio printf(" plus %d", p->eval.extrapaths); 9915014683fSclaudio if (p->eval.maxpaths != 0) 9925014683fSclaudio printf(" max %d", p->eval.maxpaths); 9934b1bc0cbSclaudio if (p->capabilities.add_path[AID_MIN] & CAPA_AP_SEND_ENFORCE) 9944b1bc0cbSclaudio printf(" enforce"); 9955014683fSclaudio printf("\n"); 9965014683fSclaudio } 9974b1bc0cbSclaudio 9984b1bc0cbSclaudio if (p->capabilities.policy == 2) 9994b1bc0cbSclaudio printf("%s\tannounce policy enforce\n", c); 10004b1bc0cbSclaudio else if (p->capabilities.policy == 1) 10014b1bc0cbSclaudio printf("%s\tannounce policy yes\n", c); 10024b1bc0cbSclaudio else 10034b1bc0cbSclaudio printf("%s\tannounce policy no\n", c); 10046987aa3aShenning } 10056987aa3aShenning 1006043e486bSclaudio void 1007043e486bSclaudio print_as(struct filter_rule *r) 1008708dc8caSbenno { 1009a8e18e82Sclaudio if (r->match.as.flags & AS_FLAG_AS_SET_NAME) { 1010a8e18e82Sclaudio printf("as-set \"%s\" ", r->match.as.name); 1011a8e18e82Sclaudio return; 1012a8e18e82Sclaudio } 1013708dc8caSbenno switch (r->match.as.op) { 1014708dc8caSbenno case OP_RANGE: 1015708dc8caSbenno printf("%s - ", log_as(r->match.as.as_min)); 1016708dc8caSbenno printf("%s ", log_as(r->match.as.as_max)); 1017708dc8caSbenno break; 1018708dc8caSbenno case OP_XRANGE: 1019708dc8caSbenno printf("%s >< ", log_as(r->match.as.as_min)); 1020708dc8caSbenno printf("%s ", log_as(r->match.as.as_max)); 1021708dc8caSbenno break; 1022708dc8caSbenno case OP_NE: 1023052562feSclaudio printf("!= %s ", log_as(r->match.as.as_min)); 1024708dc8caSbenno break; 1025708dc8caSbenno default: 1026052562feSclaudio printf("%s ", log_as(r->match.as.as_min)); 1027708dc8caSbenno break; 1028708dc8caSbenno } 1029708dc8caSbenno } 1030708dc8caSbenno 1031020327f0Shenning void 103282fc6237Sclaudio print_rule(struct bgpd_config *conf, struct filter_rule *r) 1033977216a6Shenning { 1034977216a6Shenning struct peer *p; 1035dd87f852Sclaudio int i; 1036977216a6Shenning 1037977216a6Shenning if (r->action == ACTION_ALLOW) 1038977216a6Shenning printf("allow "); 1039977216a6Shenning else if (r->action == ACTION_DENY) 1040977216a6Shenning printf("deny "); 1041977216a6Shenning else 1042977216a6Shenning printf("match "); 1043977216a6Shenning if (r->quick) 1044977216a6Shenning printf("quick "); 1045977216a6Shenning 1046faa8a8beSclaudio if (r->rib[0]) 1047faa8a8beSclaudio printf("rib %s ", r->rib); 1048faa8a8beSclaudio 1049977216a6Shenning if (r->dir == DIR_IN) 1050977216a6Shenning printf("from "); 1051977216a6Shenning else if (r->dir == DIR_OUT) 1052977216a6Shenning printf("to "); 1053977216a6Shenning else 1054977216a6Shenning printf("eeeeeeeps. "); 1055977216a6Shenning 1056977216a6Shenning if (r->peer.peerid) { 10577876190cSclaudio RB_FOREACH(p, peer_head, &conf->peers) 105882fc6237Sclaudio if (p->conf.id == r->peer.peerid) 105982fc6237Sclaudio break; 1060977216a6Shenning if (p == NULL) 1061977216a6Shenning printf("? "); 1062977216a6Shenning else 1063977216a6Shenning printf("%s ", log_addr(&p->conf.remote_addr)); 1064977216a6Shenning } else if (r->peer.groupid) { 10657876190cSclaudio RB_FOREACH(p, peer_head, &conf->peers) 106682fc6237Sclaudio if (p->conf.groupid == r->peer.groupid) 106782fc6237Sclaudio break; 1068977216a6Shenning if (p == NULL) 1069977216a6Shenning printf("group ? "); 1070977216a6Shenning else 1071c81b3773Sclaudio printf("group \"%s\" ", p->conf.group); 107251e30accSphessler } else if (r->peer.remote_as) { 107351e30accSphessler printf("AS %s ", log_as(r->peer.remote_as)); 1074b28cd7d4Sphessler } else if (r->peer.ebgp) { 1075b28cd7d4Sphessler printf("ebgp "); 1076b28cd7d4Sphessler } else if (r->peer.ibgp) { 1077b28cd7d4Sphessler printf("ibgp "); 1078977216a6Shenning } else 1079977216a6Shenning printf("any "); 1080977216a6Shenning 10816f1dba6eSclaudio if (r->match.ovs.is_set) { 10826f1dba6eSclaudio switch (r->match.ovs.validity) { 10836f1dba6eSclaudio case ROA_VALID: 10846f1dba6eSclaudio printf("ovs valid "); 10856f1dba6eSclaudio break; 10866f1dba6eSclaudio case ROA_INVALID: 10876f1dba6eSclaudio printf("ovs invalid "); 10886f1dba6eSclaudio break; 10896f1dba6eSclaudio case ROA_NOTFOUND: 10906f1dba6eSclaudio printf("ovs not-found "); 10916f1dba6eSclaudio break; 10926f1dba6eSclaudio default: 10936f1dba6eSclaudio printf("ovs ??? %d ??? ", r->match.ovs.validity); 10946f1dba6eSclaudio } 10956f1dba6eSclaudio } 10966f1dba6eSclaudio 1097060f4cb2Sclaudio if (r->match.avs.is_set) { 1098060f4cb2Sclaudio switch (r->match.avs.validity) { 1099060f4cb2Sclaudio case ASPA_VALID: 1100060f4cb2Sclaudio printf("avs valid "); 1101060f4cb2Sclaudio break; 1102060f4cb2Sclaudio case ASPA_INVALID: 1103060f4cb2Sclaudio printf("avs invalid "); 1104060f4cb2Sclaudio break; 1105060f4cb2Sclaudio case ASPA_UNKNOWN: 1106060f4cb2Sclaudio printf("avs unknown "); 1107060f4cb2Sclaudio break; 1108060f4cb2Sclaudio default: 1109060f4cb2Sclaudio printf("avs ??? %d ??? ", r->match.avs.validity); 1110060f4cb2Sclaudio } 1111060f4cb2Sclaudio } 1112060f4cb2Sclaudio 11134ea66b69Sclaudio if (r->match.prefix.addr.aid != AID_UNSPEC) { 11144ea66b69Sclaudio printf("prefix "); 11154ea66b69Sclaudio print_prefix(&r->match.prefix); 11164ea66b69Sclaudio printf(" "); 11174ea66b69Sclaudio } 1118977216a6Shenning 11196f1dba6eSclaudio if (r->match.prefixset.name[0] != '\0') 1120441aaadcSbenno printf("prefix-set \"%s\" ", r->match.prefixset.name); 11219ed42aa2Sbenno if (r->match.prefixset.flags & PREFIXSET_FLAG_LONGER) 11229ed42aa2Sbenno printf("or-longer "); 1123441aaadcSbenno 11246f1dba6eSclaudio if (r->match.originset.name[0] != '\0') 11256f1dba6eSclaudio printf("origin-set \"%s\" ", r->match.originset.name); 11266f1dba6eSclaudio 1127e0a3dc9bSclaudio if (r->match.nexthop.flags) { 1128e0a3dc9bSclaudio if (r->match.nexthop.flags == FILTER_NEXTHOP_NEIGHBOR) 1129e0a3dc9bSclaudio printf("nexthop neighbor "); 1130e0a3dc9bSclaudio else 1131e0a3dc9bSclaudio printf("nexthop %s ", log_addr(&r->match.nexthop.addr)); 1132e0a3dc9bSclaudio } 1133e0a3dc9bSclaudio 1134977216a6Shenning if (r->match.as.type) { 1135977216a6Shenning if (r->match.as.type == AS_ALL) 1136708dc8caSbenno printf("AS "); 1137977216a6Shenning else if (r->match.as.type == AS_SOURCE) 1138708dc8caSbenno printf("source-as "); 1139977216a6Shenning else if (r->match.as.type == AS_TRANSIT) 1140708dc8caSbenno printf("transit-as "); 11414768e43cShenning else if (r->match.as.type == AS_PEER) 1142708dc8caSbenno printf("peer-as "); 1143977216a6Shenning else 1144708dc8caSbenno printf("unfluffy-as "); 1145708dc8caSbenno print_as(r); 1146977216a6Shenning } 1147977216a6Shenning 11484a044d31Sclaudio if (r->match.aslen.type) { 11494a044d31Sclaudio printf("%s %u ", r->match.aslen.type == ASLEN_MAX ? 11504a044d31Sclaudio "max-as-len" : "max-as-seq", r->match.aslen.aslen); 11514a044d31Sclaudio } 11524a044d31Sclaudio 1153dd87f852Sclaudio for (i = 0; i < MAX_COMM_MATCH; i++) { 1154e7adcfeaSclaudio struct community *c = &r->match.community[i]; 1155e7adcfeaSclaudio if (c->flags != 0) { 1156dd87f852Sclaudio printf("%s ", community_type(c)); 1157dd87f852Sclaudio print_community(c); 1158dd87f852Sclaudio } 11590df2230cSclaudio } 11600df2230cSclaudio 1161bd0e176eSclaudio if (r->match.maxcomm != 0) 1162bd0e176eSclaudio printf("max-communities %d ", r->match.maxcomm - 1); 1163bd0e176eSclaudio if (r->match.maxextcomm != 0) 1164bd0e176eSclaudio printf("max-ext-communities %d ", r->match.maxextcomm - 1); 1165bd0e176eSclaudio if (r->match.maxlargecomm != 0) 1166bd0e176eSclaudio printf("max-large-communities %d ", r->match.maxlargecomm - 1); 1167bd0e176eSclaudio 1168866636d1Sclaudio print_set(&r->set); 1169977216a6Shenning 1170977216a6Shenning printf("\n"); 1171977216a6Shenning } 1172020327f0Shenning 1173866636d1Sclaudio const char * 1174866636d1Sclaudio mrt_type(enum mrt_type t) 1175866636d1Sclaudio { 1176866636d1Sclaudio switch (t) { 1177866636d1Sclaudio case MRT_NONE: 1178dfafe578Sclaudio break; 1179866636d1Sclaudio case MRT_TABLE_DUMP: 1180866636d1Sclaudio return "table"; 1181dfafe578Sclaudio case MRT_TABLE_DUMP_MP: 1182dfafe578Sclaudio return "table-mp"; 1183566a7707Sclaudio case MRT_TABLE_DUMP_V2: 1184566a7707Sclaudio return "table-v2"; 1185866636d1Sclaudio case MRT_ALL_IN: 1186866636d1Sclaudio return "all in"; 1187866636d1Sclaudio case MRT_ALL_OUT: 1188866636d1Sclaudio return "all out"; 1189866636d1Sclaudio case MRT_UPDATE_IN: 1190866636d1Sclaudio return "updates in"; 1191866636d1Sclaudio case MRT_UPDATE_OUT: 1192866636d1Sclaudio return "updates out"; 1193866636d1Sclaudio } 1194866636d1Sclaudio return "unfluffy MRT"; 1195866636d1Sclaudio } 1196866636d1Sclaudio 1197866636d1Sclaudio void 119839386878Sclaudio print_mrt(struct bgpd_config *conf, uint32_t pid, uint32_t gid, 1199d288d268Sclaudio const char *prep, const char *prep2) 1200866636d1Sclaudio { 1201866636d1Sclaudio struct mrt *m; 1202866636d1Sclaudio 1203d288d268Sclaudio if (conf->mrt == NULL) 1204866636d1Sclaudio return; 1205866636d1Sclaudio 1206d288d268Sclaudio LIST_FOREACH(m, conf->mrt, entry) 12073ac41105Sclaudio if ((gid != 0 && m->group_id == gid) || 12083ac41105Sclaudio (m->peer_id == pid && m->group_id == gid)) { 120998daafc0Sclaudio printf("%s%sdump ", prep, prep2); 121098daafc0Sclaudio if (m->rib[0]) 121198daafc0Sclaudio printf("rib %s ", m->rib); 1212566a7707Sclaudio printf("%s \"%s\"", mrt_type(m->type), 121398daafc0Sclaudio MRT2MC(m)->name); 1214566a7707Sclaudio if (MRT2MC(m)->ReopenTimerInterval == 0) 1215566a7707Sclaudio printf("\n"); 1216866636d1Sclaudio else 1217566a7707Sclaudio printf(" %d\n", MRT2MC(m)->ReopenTimerInterval); 1218866636d1Sclaudio } 121963a28b9cSbenno if (!LIST_EMPTY(conf->mrt)) 122063a28b9cSbenno printf("\n"); 1221866636d1Sclaudio } 1222866636d1Sclaudio 1223020327f0Shenning void 122482fc6237Sclaudio print_groups(struct bgpd_config *conf) 1225cbcb38a8Shenning { 1226d7629114Sclaudio struct peer **peerlist; 1227cbcb38a8Shenning struct peer *p; 1228cbcb38a8Shenning u_int peer_cnt, i; 122939386878Sclaudio uint32_t prev_groupid; 1230cbcb38a8Shenning const char *c; 1231cbcb38a8Shenning 1232cbcb38a8Shenning peer_cnt = 0; 12337876190cSclaudio RB_FOREACH(p, peer_head, &conf->peers) 1234cbcb38a8Shenning peer_cnt++; 1235d7629114Sclaudio if ((peerlist = calloc(peer_cnt, sizeof(*peerlist))) == NULL) 1236cbcb38a8Shenning fatal("print_groups calloc"); 1237cbcb38a8Shenning i = 0; 12387876190cSclaudio RB_FOREACH(p, peer_head, &conf->peers) 1239d7629114Sclaudio peerlist[i++] = p; 1240cbcb38a8Shenning 1241d7629114Sclaudio qsort(peerlist, peer_cnt, sizeof(*peerlist), peer_compare); 1242cbcb38a8Shenning 1243cbcb38a8Shenning prev_groupid = 0; 1244cbcb38a8Shenning for (i = 0; i < peer_cnt; i++) { 1245d7629114Sclaudio if (peerlist[i]->conf.groupid) { 1246d7629114Sclaudio c = "\t"; 1247d7629114Sclaudio if (peerlist[i]->conf.groupid != prev_groupid) { 1248cbcb38a8Shenning if (prev_groupid) 1249cbcb38a8Shenning printf("}\n\n"); 1250d7629114Sclaudio printf("group \"%s\" {\n", 1251d7629114Sclaudio peerlist[i]->conf.group); 1252d7629114Sclaudio prev_groupid = peerlist[i]->conf.groupid; 1253cbcb38a8Shenning } 1254cbcb38a8Shenning } else 1255d7629114Sclaudio c = ""; 1256cbcb38a8Shenning 1257cbcb38a8Shenning print_peer(peerlist[i], conf, c); 1258cbcb38a8Shenning } 1259cbcb38a8Shenning 1260cbcb38a8Shenning if (prev_groupid) 1261cbcb38a8Shenning printf("}\n\n"); 1262cbcb38a8Shenning 1263cbcb38a8Shenning free(peerlist); 1264cbcb38a8Shenning } 1265cbcb38a8Shenning 1266cbcb38a8Shenning int 1267cbcb38a8Shenning peer_compare(const void *aa, const void *bb) 1268cbcb38a8Shenning { 1269d7629114Sclaudio const struct peer * const *a; 1270d7629114Sclaudio const struct peer * const *b; 1271cbcb38a8Shenning 1272cbcb38a8Shenning a = aa; 1273cbcb38a8Shenning b = bb; 1274cbcb38a8Shenning 1275d7629114Sclaudio return ((*a)->conf.groupid - (*b)->conf.groupid); 1276cbcb38a8Shenning } 1277cbcb38a8Shenning 1278cbcb38a8Shenning void 127982fc6237Sclaudio print_config(struct bgpd_config *conf, struct rib_names *rib_l) 1280020327f0Shenning { 1281020327f0Shenning struct filter_rule *r; 1282294d4e13Shenning struct network *n; 12837d4aa781Sclaudio struct flowspec_config *f; 128498daafc0Sclaudio struct rde_rib *rr; 12854e0c4e97Sclaudio struct l3vpn *vpn; 1286020327f0Shenning 1287020327f0Shenning print_mainconf(conf); 1288bd9df44eSclaudio print_rtrs(&conf->rtrs); 12896f1dba6eSclaudio print_roa(&conf->roa); 1290ff84f55eSclaudio print_aspa(&conf->aspa); 1291965dc109Sclaudio print_as_sets(&conf->as_sets); 12926f1dba6eSclaudio print_prefixsets(&conf->prefixsets); 12936f1dba6eSclaudio print_originsets(&conf->originsets); 129482fc6237Sclaudio TAILQ_FOREACH(n, &conf->networks, entry) 12951274ebf8Sclaudio print_network(&n->net, ""); 12967d4aa781Sclaudio RB_FOREACH(f, flowspec_tree, &conf->flowspecs) 12977d4aa781Sclaudio print_flowspec(f, ""); 129882fc6237Sclaudio if (!SIMPLEQ_EMPTY(&conf->l3vpns)) 1299610bcb44Sclaudio printf("\n"); 130082fc6237Sclaudio SIMPLEQ_FOREACH(vpn, &conf->l3vpns, entry) 13014e0c4e97Sclaudio print_l3vpn(vpn); 1302610bcb44Sclaudio printf("\n"); 130389ee02f7Sclaudio if (conf->filtered_in_locrib) 130489ee02f7Sclaudio printf("rde rib Loc-RIB include filtered\n"); 130598daafc0Sclaudio SIMPLEQ_FOREACH(rr, rib_l, entry) { 130698daafc0Sclaudio if (rr->flags & F_RIB_NOEVALUATE) 130798daafc0Sclaudio printf("rde rib %s no evaluate\n", rr->name); 1308459fcfe4Sclaudio else if (rr->flags & F_RIB_NOFIB) 130998daafc0Sclaudio printf("rde rib %s\n", rr->name); 1310459fcfe4Sclaudio else 1311459fcfe4Sclaudio printf("rde rib %s rtable %u fib-update %s\n", rr->name, 1312459fcfe4Sclaudio rr->rtableid, rr->flags & F_RIB_NOFIBSYNC ? 1313459fcfe4Sclaudio "no" : "yes"); 131498daafc0Sclaudio } 131598daafc0Sclaudio printf("\n"); 1316d288d268Sclaudio print_mrt(conf, 0, 0, "", ""); 131782fc6237Sclaudio print_groups(conf); 131882fc6237Sclaudio TAILQ_FOREACH(r, conf->filters, entry) 131982fc6237Sclaudio print_rule(conf, r); 1320020327f0Shenning } 1321