summaryrefslogtreecommitdiff
path: root/proto/bgp
diff options
context:
space:
mode:
Diffstat (limited to 'proto/bgp')
-rw-r--r--proto/bgp/bgp.c113
-rw-r--r--proto/bgp/bgp.h2
-rw-r--r--proto/bgp/packets.c9
3 files changed, 97 insertions, 27 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
};
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 1a291952..39a87a61 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 2baa6e34..af7ce0c4 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)
{