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)
|
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, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
119
proto/bgp/bgp.c
119
proto/bgp/bgp.c
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1540,8 +1540,9 @@ struct protocol proto_ospf = {
|
||||||
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,
|
||||||
reconfigure:ospf_reconfigure
|
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)
|
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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue