From b8113a5e92cb19a0910041d5708f4eafeb713b54 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Wed, 7 Apr 2010 00:19:23 +0200 Subject: Implements BGP 'show protocols' info details. --- proto/bgp/bgp.c | 113 ++++++++++++++++++++++++++++++++++++++++++---------- proto/bgp/bgp.h | 2 +- proto/bgp/packets.c | 9 ++--- proto/ospf/ospf.c | 23 ++++++----- proto/ospf/rt.c | 3 +- 5 files changed, 110 insertions(+), 40 deletions(-) (limited to 'proto') diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 4410c04..378cc85 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -60,6 +60,7 @@ #include "nest/protocol.h" #include "nest/route.h" #include "nest/locks.h" +#include "nest/cli.h" #include "conf/conf.h" #include "lib/socket.h" #include "lib/resource.h" @@ -930,39 +931,108 @@ static char *bgp_err_classes[] = { "", "Error: ", "Socket: ", "Received: ", "BGP static char *bgp_misc_errors[] = { "", "Neighbor lost", "Invalid next hop", "Kernel MD5 auth failed" }; static char *bgp_auto_errors[] = { "", "Route limit exceeded"}; - -static void -bgp_get_status(struct proto *P, byte *buf) +static const char * +bgp_last_errmsg(struct bgp_proto *p) { - struct bgp_proto *p = (struct bgp_proto *) P; - - const byte *err1 = bgp_err_classes[p->last_error_class]; - const byte *err2 = ""; - byte errbuf[32]; - switch (p->last_error_class) { case BE_MISC: - err2 = bgp_misc_errors[p->last_error_code]; - break; + return bgp_misc_errors[p->last_error_code]; case BE_SOCKET: - err2 = (p->last_error_code == 0) ? "Connection closed" : strerror(p->last_error_code); - break; + return (p->last_error_code == 0) ? "Connection closed" : strerror(p->last_error_code); case BE_BGP_RX: case BE_BGP_TX: - err2 = bgp_error_dsc(errbuf, p->last_error_code >> 16, p->last_error_code & 0xFF); - break; + return bgp_error_dsc(p->last_error_code >> 16, p->last_error_code & 0xFF); case BE_AUTO_DOWN: - err2 = bgp_auto_errors[p->last_error_code]; - break; + return bgp_auto_errors[p->last_error_code]; + default: + return ""; } +} + +static const char * +bgp_state_dsc(struct bgp_proto *p) +{ + //if (p->p.proto_state == PS_DOWN) + // return "Down"; + + int state = MAX(p->incoming_conn.state, p->outgoing_conn.state); + if ((state == BS_IDLE) && (p->start_state >= BSS_CONNECT) && p->cf->passive) + return "Passive"; + + return bgp_state_names[state]; +} + +static void +bgp_get_status(struct proto *P, byte *buf) +{ + struct bgp_proto *p = (struct bgp_proto *) P; + + const char *err1 = bgp_err_classes[p->last_error_class]; + const char *err2 = bgp_last_errmsg(p); if (P->proto_state == PS_DOWN) bsprintf(buf, "%s%s", err1, err2); else - bsprintf(buf, "%-14s%s%s", - bgp_state_names[MAX(p->incoming_conn.state, p->outgoing_conn.state)], - err1, err2); + bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2); +} + +static void +bgp_show_proto_info(struct proto *P) +{ + struct bgp_proto *p = (struct bgp_proto *) P; + struct bgp_conn *c = p->conn; + + if (P->proto_state == PS_DOWN) + return; + + cli_msg(-1006, " BGP state: %s", bgp_state_dsc(p)); + + if (P->proto_state == PS_START) + { + struct bgp_conn *oc = &p->outgoing_conn; + + if ((p->start_state < BSS_CONNECT) && + (p->startup_timer->expires)) + cli_msg(-1006, " Error wait: %d/%d", + p->startup_timer->expires - now, p->startup_delay); + + if ((oc->state == BS_ACTIVE) && + (oc->connect_retry_timer->expires)) + cli_msg(-1006, " Start delay: %d/%d", + oc->connect_retry_timer->expires - now, p->cf->start_delay_time); + } + else if (P->proto_state == PS_UP) + { + cli_msg(-1006, " Session: %s%s%s%s", + p->is_internal ? "internal" : "external", + p->rr_client ? " route-reflector" : "", + p->rs_client ? " route-server" : "", + p->as4_session ? " AS4" : ""); + cli_msg(-1006, " Neighbor AS: %u", p->remote_as); + cli_msg(-1006, " Neighbor ID: %R", p->remote_id); + cli_msg(-1006, " Neighbor address: %I", p->cf->remote_ip); + cli_msg(-1006, " Nexthop address: %I", p->next_hop); + cli_msg(-1006, " Source address: %I", p->source_addr); + cli_msg(-1006, " Neighbor caps: %s%s", + c->peer_refresh_support ? " refresh" : "", + c->peer_as4_support ? " AS4" : ""); + if (p->cf->route_limit) + cli_msg(-1006, " Route limit: %d/%d", + p->p.stats.imp_routes, p->cf->route_limit); + cli_msg(-1006, " Hold timer: %d/%d", + c->hold_timer->expires - now, c->hold_time); + cli_msg(-1006, " Keepalive timer: %d/%d", + c->keepalive_timer->expires - now, c->keepalive_time); + } + + if ((p->last_error_class != BE_NONE) && + (p->last_error_class != BE_MAN_DOWN)) + { + const char *err1 = bgp_err_classes[p->last_error_class]; + const char *err2 = bgp_last_errmsg(p); + cli_msg(-1006, " Last error: %s%s", err1, err2); + } } static int @@ -993,8 +1063,9 @@ struct protocol proto_bgp = { init: bgp_init, start: bgp_start, shutdown: bgp_shutdown, + reconfigure: bgp_reconfigure, get_status: bgp_get_status, get_attr: bgp_get_attr, - reconfigure: bgp_reconfigure, get_route_info: bgp_get_route_info, + show_proto_info: bgp_show_proto_info }; diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 1a29195..39a87a6 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -196,7 +196,7 @@ void bgp_schedule_packet(struct bgp_conn *conn, int type); void bgp_kick_tx(void *vconn); void bgp_tx(struct birdsock *sk); int bgp_rx(struct birdsock *sk, int size); -const byte * bgp_error_dsc(byte *buff, unsigned code, unsigned subcode); +const char * bgp_error_dsc(unsigned code, unsigned subcode); void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len); /* Packet types */ diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 2baa6e3..af7ce0c 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -1077,16 +1077,16 @@ static struct { /** * bgp_error_dsc - return BGP error description - * @buff: temporary buffer * @code: BGP error code * @subcode: BGP error subcode * * bgp_error_dsc() returns error description for BGP errors * which might be static string or given temporary buffer. */ -const byte * -bgp_error_dsc(byte *buff, unsigned code, unsigned subcode) +const char * +bgp_error_dsc(unsigned code, unsigned subcode) { + static char buff[32]; unsigned i; for (i=0; i < ARRAY_SIZE(bgp_msg_table); i++) if (bgp_msg_table[i].major == code && bgp_msg_table[i].minor == subcode) @@ -1102,7 +1102,6 @@ void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len) { const byte *name; - byte namebuf[32]; byte *t, argbuf[36]; unsigned i; @@ -1110,7 +1109,7 @@ bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned if (code == 6 && class == BE_BGP_TX) return; - name = bgp_error_dsc(namebuf, code, subcode); + name = bgp_error_dsc(code, subcode); t = argbuf; if (len) { diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 5ed8abb..107e3a4 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -1533,15 +1533,16 @@ ospf_sh_lsadb(struct proto *p) struct protocol proto_ospf = { - name:"OSPF", - template:"ospf%d", - attr_class:EAP_OSPF, - init:ospf_init, - dump:ospf_dump, - start:ospf_start, - shutdown:ospf_shutdown, - get_route_info:ospf_get_route_info, - get_attr:ospf_get_attr, - get_status:ospf_get_status, - reconfigure:ospf_reconfigure + name: "OSPF", + template: "ospf%d", + attr_class: EAP_OSPF, + init: ospf_init, + dump: ospf_dump, + start: ospf_start, + shutdown: ospf_shutdown, + reconfigure: ospf_reconfigure, + get_status: ospf_get_status, + get_attr: ospf_get_attr, + get_route_info: ospf_get_route_info + // show_proto_info: ospf_sh }; diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index 5c0b3fa..c3798e7 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -152,12 +152,11 @@ static struct ospf_iface * find_stub_src(struct ospf_area *oa, ip_addr px, int pxlen) { struct ospf_iface *iff; - struct ifa *addr; WALK_LIST(iff, oa->po->iface_list) if ((iff->type != OSPF_IT_VLINK) && (iff->oa == oa) && - ipa_equal(iff->addr->px, px) && + ipa_equal(iff->addr->prefix, px) && (iff->addr->pxlen == pxlen)) return iff; -- cgit v1.2.3