Implements BGP 'show protocols' info details.
This commit is contained in:
parent
c429d4a4ba
commit
b8113a5e92
7 changed files with 119 additions and 43 deletions
|
@ -871,6 +871,8 @@ proto_cmd_show(struct proto *p, unsigned int verbose, int cnt)
|
|||
{
|
||||
if (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, " Input filter: %s", filter_name(p->in_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);
|
||||
}
|
||||
|
||||
if (p->proto->show_proto_info)
|
||||
p->proto->show_proto_info(p);
|
||||
|
||||
cli_msg(-1006, "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ struct protocol {
|
|||
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) */
|
||||
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);
|
||||
|
|
119
proto/bgp/bgp.c
119
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 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
|
||||
bgp_get_status(struct proto *P, byte *buf)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue