summaryrefslogtreecommitdiff
path: root/proto/bgp/bgp.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2010-04-07 00:19:23 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2010-04-07 00:19:23 +0200
commitb8113a5e92cb19a0910041d5708f4eafeb713b54 (patch)
treec4882fd498ecd33c12363272368277ca239466da /proto/bgp/bgp.c
parentc429d4a4ba2cc8778634461e8adea33e0f0ae022 (diff)
Implements BGP 'show protocols' info details.
Diffstat (limited to 'proto/bgp/bgp.c')
-rw-r--r--proto/bgp/bgp.c113
1 files changed, 92 insertions, 21 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 4410c043..378cc85d 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
};