diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 1e7071a..00bb577 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -77,7 +77,7 @@ static void bgp_close(struct bgp_proto *p, int apply_md5); static void bgp_connect(struct bgp_proto *p); static void bgp_active(struct bgp_proto *p); static sock *bgp_setup_listen_sk(ip_addr addr, unsigned port, u32 flags); - +static void bgp_sh_proto_summary(struct proto *p); /** * bgp_open - open a BGP instance @@ -1339,6 +1339,82 @@ bgp_show_proto_info(struct proto *P) } } +void +bgp_sh_summary(struct symbol *sym) +{ + struct proto_config *pc = NULL; + + if (sym) + { + if (sym->class != SYM_PROTO) + cf_error("%s: Not a protocol", sym->name); + pc = (struct proto_config *)sym->def; + if (pc->protocol != &proto_bgp) + cf_error("%s: Not a BGP protocol", sym->name); + } + else + { + if (EMPTY_LIST(config->protos)) + { + cli_msg(1006, "No protocols match"); + return; + } + } + +#ifdef IPV6 + cli_msg(-2002, "%-10s %s\n%12s %-19s %-20s %s", "Proto", "Peer", "AS", "Last state change", "Prefixes rcvd/best", "State/Last error" ); +#else + cli_msg(-2002, "%-10s %-15s %10s %-19s %-20s %s", "Proto", "Peer", "AS", "Last state change", "Prefixes rcvd/best", "State/Last error" ); +#endif + + if (pc) + { + /* Show single protocol info */ + bgp_sh_proto_summary(pc->proto); + cli_msg(0, ""); + return; + } + + WALK_LIST(pc, config->protos) + { + if ((pc->protocol != &proto_bgp) || (!pc->proto)) + continue; + + bgp_sh_proto_summary(pc->proto); + } + + cli_msg(0, ""); +} + +static void +bgp_sh_proto_summary(struct proto *p) +{ + struct bgp_proto *bp; + byte tbuf[TM_DATETIME_BUFFER_SIZE]; + char rs[20]; + char ps[256]; + + /* Get protocol data */ + tm_format_datetime(tbuf, &config->tf_proto, p->last_state_change); + + struct proto_stats *s = &p->stats; + bsnprintf(rs, sizeof(rs), "%u/%u", s->imp_routes, s->pref_routes); + + p->proto->get_status(p, ps); + + /* Get BGP protocol from protocol */ + bp = (struct bgp_proto *) p; + + /* Display summary */ +#ifdef IPV6 + cli_msg(-1006, "%-10s %I\n%12u %-19s %-20s %s", +#else + cli_msg(-1006, "%-10s %-15I %10u %-19s %-20s %s", +#endif + p->name, bp->cf->remote_ip, + bp->remote_as, tbuf, rs, ps); +} + struct protocol proto_bgp = { name: "BGP", template: "bgp%d", diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 59313ef..7b77281 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -228,6 +228,8 @@ static inline void set_next_hop(byte *b, ip_addr addr) { ((ip_addr *) b)[0] = ad static inline void set_next_hop(byte *b, ip_addr addr) { ((ip_addr *) b)[0] = addr; } #endif +void bgp_sh_summary(struct symbol *sym); + void bgp_attach_attr(struct ea_list **to, struct linpool *pool, unsigned attr, uintptr_t val); byte *bgp_attach_attr_wa(struct ea_list **to, struct linpool *pool, unsigned attr, unsigned len); struct rta *bgp_decode_attrs(struct bgp_conn *conn, byte *attr, unsigned int len, struct linpool *pool, int mandatory, struct attr_helper *ah); diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index f76fbf2..82b3761 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -152,6 +152,11 @@ CF_ADDTO(dynamic_attr, BGP_EXT_COMMUNITY CF_ENUM(T_ENUM_BGP_ORIGIN, ORIGIN_, IGP, EGP, INCOMPLETE) +CF_CLI_HELP(SHOW BGP, , [[Show BGP protocol information]]) + +CF_CLI(SHOW BGP SUMMARY, optsym, [], [[Show BGP peers summary]]) +{ bgp_sh_summary($4); }; + CF_CODE CF_END