Implements BGP 'show protocols' info details.

This commit is contained in:
Ondrej Zajicek 2010-04-07 00:19:23 +02:00
parent c429d4a4ba
commit b8113a5e92
7 changed files with 119 additions and 43 deletions

View file

@ -871,6 +871,8 @@ proto_cmd_show(struct proto *p, unsigned int verbose, int cnt)
{ {
if (p->cf->dsc) if (p->cf->dsc)
cli_msg(-1006, " Description: %s", p->cf->dsc); cli_msg(-1006, " Description: %s", p->cf->dsc);
if (p->cf->router_id)
cli_msg(-1006, " Router ID: %R", p->cf->router_id);
cli_msg(-1006, " Preference: %d", p->preference); cli_msg(-1006, " Preference: %d", p->preference);
cli_msg(-1006, " Input filter: %s", filter_name(p->in_filter)); cli_msg(-1006, " Input filter: %s", filter_name(p->in_filter));
cli_msg(-1006, " Output filter: %s", filter_name(p->out_filter)); cli_msg(-1006, " Output filter: %s", filter_name(p->out_filter));
@ -885,6 +887,9 @@ proto_cmd_show(struct proto *p, unsigned int verbose, int cnt)
proto_do_show_stats(p); proto_do_show_stats(p);
} }
if (p->proto->show_proto_info)
p->proto->show_proto_info(p);
cli_msg(-1006, ""); cli_msg(-1006, "");
} }
} }

View file

@ -51,6 +51,7 @@ struct protocol {
void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */ void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */ void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */
int (*get_attr)(struct eattr *, byte *buf, int buflen); /* ASCIIfy dynamic attribute (returns GA_*) */ int (*get_attr)(struct eattr *, byte *buf, int buflen); /* ASCIIfy dynamic attribute (returns GA_*) */
void (*show_proto_info)(struct proto *); /* Show protocol info (for `show protocols all' command) */
}; };
void protos_build(void); void protos_build(void);

View file

@ -60,6 +60,7 @@
#include "nest/protocol.h" #include "nest/protocol.h"
#include "nest/route.h" #include "nest/route.h"
#include "nest/locks.h" #include "nest/locks.h"
#include "nest/cli.h"
#include "conf/conf.h" #include "conf/conf.h"
#include "lib/socket.h" #include "lib/socket.h"
#include "lib/resource.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_misc_errors[] = { "", "Neighbor lost", "Invalid next hop", "Kernel MD5 auth failed" };
static char *bgp_auto_errors[] = { "", "Route limit exceeded"}; static char *bgp_auto_errors[] = { "", "Route limit exceeded"};
static const char *
bgp_last_errmsg(struct bgp_proto *p)
{
switch (p->last_error_class)
{
case BE_MISC:
return bgp_misc_errors[p->last_error_code];
case BE_SOCKET:
return (p->last_error_code == 0) ? "Connection closed" : strerror(p->last_error_code);
case BE_BGP_RX:
case BE_BGP_TX:
return bgp_error_dsc(p->last_error_code >> 16, p->last_error_code & 0xFF);
case BE_AUTO_DOWN:
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 static void
bgp_get_status(struct proto *P, byte *buf) bgp_get_status(struct proto *P, byte *buf)
{ {
struct bgp_proto *p = (struct bgp_proto *) P; struct bgp_proto *p = (struct bgp_proto *) P;
const byte *err1 = bgp_err_classes[p->last_error_class]; const char *err1 = bgp_err_classes[p->last_error_class];
const byte *err2 = ""; const char *err2 = bgp_last_errmsg(p);
byte errbuf[32];
switch (p->last_error_class)
{
case BE_MISC:
err2 = bgp_misc_errors[p->last_error_code];
break;
case BE_SOCKET:
err2 = (p->last_error_code == 0) ? "Connection closed" : strerror(p->last_error_code);
break;
case BE_BGP_RX:
case BE_BGP_TX:
err2 = bgp_error_dsc(errbuf, p->last_error_code >> 16, p->last_error_code & 0xFF);
break;
case BE_AUTO_DOWN:
err2 = bgp_auto_errors[p->last_error_code];
break;
}
if (P->proto_state == PS_DOWN) if (P->proto_state == PS_DOWN)
bsprintf(buf, "%s%s", err1, err2); bsprintf(buf, "%s%s", err1, err2);
else else
bsprintf(buf, "%-14s%s%s", bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2);
bgp_state_names[MAX(p->incoming_conn.state, p->outgoing_conn.state)], }
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 static int
@ -993,8 +1063,9 @@ struct protocol proto_bgp = {
init: bgp_init, init: bgp_init,
start: bgp_start, start: bgp_start,
shutdown: bgp_shutdown, shutdown: bgp_shutdown,
reconfigure: bgp_reconfigure,
get_status: bgp_get_status, get_status: bgp_get_status,
get_attr: bgp_get_attr, get_attr: bgp_get_attr,
reconfigure: bgp_reconfigure,
get_route_info: bgp_get_route_info, get_route_info: bgp_get_route_info,
show_proto_info: bgp_show_proto_info
}; };

View file

@ -196,7 +196,7 @@ void bgp_schedule_packet(struct bgp_conn *conn, int type);
void bgp_kick_tx(void *vconn); void bgp_kick_tx(void *vconn);
void bgp_tx(struct birdsock *sk); void bgp_tx(struct birdsock *sk);
int bgp_rx(struct birdsock *sk, int size); 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); void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len);
/* Packet types */ /* Packet types */

View file

@ -1077,16 +1077,16 @@ static struct {
/** /**
* bgp_error_dsc - return BGP error description * bgp_error_dsc - return BGP error description
* @buff: temporary buffer
* @code: BGP error code * @code: BGP error code
* @subcode: BGP error subcode * @subcode: BGP error subcode
* *
* bgp_error_dsc() returns error description for BGP errors * bgp_error_dsc() returns error description for BGP errors
* which might be static string or given temporary buffer. * which might be static string or given temporary buffer.
*/ */
const byte * const char *
bgp_error_dsc(byte *buff, unsigned code, unsigned subcode) bgp_error_dsc(unsigned code, unsigned subcode)
{ {
static char buff[32];
unsigned i; unsigned i;
for (i=0; i < ARRAY_SIZE(bgp_msg_table); i++) for (i=0; i < ARRAY_SIZE(bgp_msg_table); i++)
if (bgp_msg_table[i].major == code && bgp_msg_table[i].minor == subcode) 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) bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len)
{ {
const byte *name; const byte *name;
byte namebuf[32];
byte *t, argbuf[36]; byte *t, argbuf[36];
unsigned i; 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) if (code == 6 && class == BE_BGP_TX)
return; return;
name = bgp_error_dsc(namebuf, code, subcode); name = bgp_error_dsc(code, subcode);
t = argbuf; t = argbuf;
if (len) if (len)
{ {

View file

@ -1533,15 +1533,16 @@ ospf_sh_lsadb(struct proto *p)
struct protocol proto_ospf = { struct protocol proto_ospf = {
name:"OSPF", name: "OSPF",
template:"ospf%d", template: "ospf%d",
attr_class:EAP_OSPF, attr_class: EAP_OSPF,
init:ospf_init, init: ospf_init,
dump:ospf_dump, dump: ospf_dump,
start:ospf_start, start: ospf_start,
shutdown:ospf_shutdown, shutdown: ospf_shutdown,
get_route_info:ospf_get_route_info, reconfigure: ospf_reconfigure,
get_attr:ospf_get_attr, get_status: ospf_get_status,
get_status:ospf_get_status, get_attr: ospf_get_attr,
reconfigure:ospf_reconfigure get_route_info: ospf_get_route_info
// show_proto_info: ospf_sh
}; };

View file

@ -152,12 +152,11 @@ static struct ospf_iface *
find_stub_src(struct ospf_area *oa, ip_addr px, int pxlen) find_stub_src(struct ospf_area *oa, ip_addr px, int pxlen)
{ {
struct ospf_iface *iff; struct ospf_iface *iff;
struct ifa *addr;
WALK_LIST(iff, oa->po->iface_list) WALK_LIST(iff, oa->po->iface_list)
if ((iff->type != OSPF_IT_VLINK) && if ((iff->type != OSPF_IT_VLINK) &&
(iff->oa == oa) && (iff->oa == oa) &&
ipa_equal(iff->addr->px, px) && ipa_equal(iff->addr->prefix, px) &&
(iff->addr->pxlen == pxlen)) (iff->addr->pxlen == pxlen))
return iff; return iff;