summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nest/proto.c5
-rw-r--r--nest/protocol.h1
-rw-r--r--proto/bgp/bgp.c113
-rw-r--r--proto/bgp/bgp.h2
-rw-r--r--proto/bgp/packets.c9
-rw-r--r--proto/ospf/ospf.c23
-rw-r--r--proto/ospf/rt.c3
7 files changed, 116 insertions, 40 deletions
diff --git a/nest/proto.c b/nest/proto.c
index 78fca99..f55def5 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -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, "");
}
}
diff --git a/nest/protocol.h b/nest/protocol.h
index d94873e..5dac2a9 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -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);
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;