BGP: Report capabilities in show protocols all
This commit is contained in:
parent
eeba61ccd5
commit
256cc8ee08
3 changed files with 118 additions and 14 deletions
125
proto/bgp/bgp.c
125
proto/bgp/bgp.c
|
@ -1756,11 +1756,118 @@ bgp_get_status(struct proto *P, byte *buf)
|
||||||
bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2);
|
bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bgp_show_afis(int code, char *s, u32 *afis, uint count)
|
||||||
|
{
|
||||||
|
buffer b;
|
||||||
|
LOG_BUFFER_INIT(b);
|
||||||
|
|
||||||
|
buffer_puts(&b, s);
|
||||||
|
|
||||||
|
for (u32 *af = afis; af < (afis + count); af++)
|
||||||
|
{
|
||||||
|
const struct bgp_af_desc *desc = bgp_get_af_desc(*af);
|
||||||
|
if (desc)
|
||||||
|
buffer_print(&b, " %s", desc->name);
|
||||||
|
else
|
||||||
|
buffer_print(&b, " <%u/%u>", BGP_AFI(*af), BGP_SAFI(*af));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.pos == b.end)
|
||||||
|
strcpy(b.end - 32, " ... <too long>");
|
||||||
|
|
||||||
|
cli_msg(code, b.start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bgp_show_capabilities(struct bgp_proto *p UNUSED, struct bgp_caps *caps)
|
||||||
|
{
|
||||||
|
struct bgp_af_caps *ac;
|
||||||
|
uint any_mp_bgp = 0;
|
||||||
|
uint any_gr_able = 0;
|
||||||
|
uint any_add_path = 0;
|
||||||
|
u32 *afl1 = alloca(caps->af_count * sizeof(u32));
|
||||||
|
u32 *afl2 = alloca(caps->af_count * sizeof(u32));
|
||||||
|
uint afn1, afn2;
|
||||||
|
|
||||||
|
WALK_AF_CAPS(caps, ac)
|
||||||
|
{
|
||||||
|
any_mp_bgp |= ac->ready;
|
||||||
|
any_gr_able |= ac->gr_able;
|
||||||
|
any_add_path |= ac->add_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (any_mp_bgp)
|
||||||
|
{
|
||||||
|
cli_msg(-1006, " Multiprotocol");
|
||||||
|
|
||||||
|
afn1 = 0;
|
||||||
|
WALK_AF_CAPS(caps, ac)
|
||||||
|
if (ac->ready)
|
||||||
|
afl1[afn1++] = ac->afi;
|
||||||
|
|
||||||
|
bgp_show_afis(-1006, " AF announced:", afl1, afn1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caps->route_refresh)
|
||||||
|
cli_msg(-1006, " Route refresh");
|
||||||
|
|
||||||
|
if (caps->ext_messages)
|
||||||
|
cli_msg(-1006, " Extended message");
|
||||||
|
|
||||||
|
if (caps->gr_aware)
|
||||||
|
cli_msg(-1006, " Graceful restart");
|
||||||
|
|
||||||
|
if (any_gr_able)
|
||||||
|
{
|
||||||
|
/* Continues from gr_aware */
|
||||||
|
cli_msg(-1006, " Restart time: %u", caps->gr_time);
|
||||||
|
if (caps->gr_flags & BGP_GRF_RESTART)
|
||||||
|
cli_msg(-1006, " Restart recovery");
|
||||||
|
|
||||||
|
afn1 = afn2 = 0;
|
||||||
|
WALK_AF_CAPS(caps, ac)
|
||||||
|
{
|
||||||
|
if (ac->gr_able)
|
||||||
|
afl1[afn1++] = ac->afi;
|
||||||
|
|
||||||
|
if (ac->gr_af_flags & BGP_GRF_FORWARDING)
|
||||||
|
afl2[afn2++] = ac->afi;
|
||||||
|
}
|
||||||
|
|
||||||
|
bgp_show_afis(-1006, " AF supported:", afl1, afn1);
|
||||||
|
bgp_show_afis(-1006, " AF preserved:", afl2, afn2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caps->as4_support)
|
||||||
|
cli_msg(-1006, " 4-octet AS numbers");
|
||||||
|
|
||||||
|
if (any_add_path)
|
||||||
|
{
|
||||||
|
cli_msg(-1006, " ADD-PATH");
|
||||||
|
|
||||||
|
afn1 = afn2 = 0;
|
||||||
|
WALK_AF_CAPS(caps, ac)
|
||||||
|
{
|
||||||
|
if (ac->add_path & BGP_ADD_PATH_RX)
|
||||||
|
afl1[afn1++] = ac->afi;
|
||||||
|
|
||||||
|
if (ac->add_path & BGP_ADD_PATH_TX)
|
||||||
|
afl2[afn2++] = ac->afi;
|
||||||
|
}
|
||||||
|
|
||||||
|
bgp_show_afis(-1006, " RX:", afl1, afn1);
|
||||||
|
bgp_show_afis(-1006, " TX:", afl2, afn2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caps->enhanced_refresh)
|
||||||
|
cli_msg(-1006, " Enhanced refresh");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bgp_show_proto_info(struct proto *P)
|
bgp_show_proto_info(struct proto *P)
|
||||||
{
|
{
|
||||||
struct bgp_proto *p = (struct bgp_proto *) P;
|
struct bgp_proto *p = (struct bgp_proto *) P;
|
||||||
struct bgp_conn *c = p->conn;
|
|
||||||
|
|
||||||
cli_msg(-1006, " BGP state: %s", bgp_state_dsc(p));
|
cli_msg(-1006, " BGP state: %s", bgp_state_dsc(p));
|
||||||
cli_msg(-1006, " Neighbor address: %I%J", p->cf->remote_ip, p->cf->iface);
|
cli_msg(-1006, " Neighbor address: %I%J", p->cf->remote_ip, p->cf->iface);
|
||||||
|
@ -1789,15 +1896,11 @@ bgp_show_proto_info(struct proto *P)
|
||||||
else if (P->proto_state == PS_UP)
|
else if (P->proto_state == PS_UP)
|
||||||
{
|
{
|
||||||
cli_msg(-1006, " Neighbor ID: %R", p->remote_id);
|
cli_msg(-1006, " Neighbor ID: %R", p->remote_id);
|
||||||
|
cli_msg(-1006, " Local capabilities");
|
||||||
|
bgp_show_capabilities(p, p->conn->local_caps);
|
||||||
|
cli_msg(-1006, " Neighbor capabilities");
|
||||||
|
bgp_show_capabilities(p, p->conn->remote_caps);
|
||||||
/* XXXX
|
/* XXXX
|
||||||
cli_msg(-1006, " Neighbor caps: %s%s%s%s%s%s%s",
|
|
||||||
c->peer_refresh_support ? " refresh" : "",
|
|
||||||
c->peer_enhanced_refresh_support ? " enhanced-refresh" : "",
|
|
||||||
c->peer_gr_able ? " restart-able" : (c->peer_gr_aware ? " restart-aware" : ""),
|
|
||||||
c->peer_as4_support ? " AS4" : "",
|
|
||||||
(c->peer_add_path & ADD_PATH_RX) ? " add-path-rx" : "",
|
|
||||||
(c->peer_add_path & ADD_PATH_TX) ? " add-path-tx" : "",
|
|
||||||
c->peer_ext_messages_support ? " ext-messages" : "");
|
|
||||||
cli_msg(-1006, " Session: %s%s%s%s%s%s%s%s",
|
cli_msg(-1006, " Session: %s%s%s%s%s%s%s%s",
|
||||||
p->is_internal ? "internal" : "external",
|
p->is_internal ? "internal" : "external",
|
||||||
p->cf->multihop ? " multihop" : "",
|
p->cf->multihop ? " multihop" : "",
|
||||||
|
@ -1810,9 +1913,9 @@ bgp_show_proto_info(struct proto *P)
|
||||||
*/
|
*/
|
||||||
cli_msg(-1006, " Source address: %I", p->source_addr);
|
cli_msg(-1006, " Source address: %I", p->source_addr);
|
||||||
cli_msg(-1006, " Hold timer: %d/%d",
|
cli_msg(-1006, " Hold timer: %d/%d",
|
||||||
tm_remains(c->hold_timer), c->hold_time);
|
tm_remains(p->conn->hold_timer), p->conn->hold_time);
|
||||||
cli_msg(-1006, " Keepalive timer: %d/%d",
|
cli_msg(-1006, " Keepalive timer: %d/%d",
|
||||||
tm_remains(c->keepalive_timer), c->keepalive_time);
|
tm_remains(p->conn->keepalive_timer), p->conn->keepalive_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((p->last_error_class != BE_NONE) &&
|
if ((p->last_error_class != BE_NONE) &&
|
||||||
|
|
|
@ -174,6 +174,10 @@ struct bgp_caps {
|
||||||
struct bgp_af_caps af_data[0]; /* Per-AF capability data */
|
struct bgp_af_caps af_data[0]; /* Per-AF capability data */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define WALK_AF_CAPS(caps,ac) \
|
||||||
|
for (ac = caps->af_data; ac < &caps->af_data[caps->af_count]; ac++)
|
||||||
|
|
||||||
|
|
||||||
struct bgp_socket {
|
struct bgp_socket {
|
||||||
node n; /* Node in global bgp_sockets */
|
node n; /* Node in global bgp_sockets */
|
||||||
sock *sk; /* Real listening socket */
|
sock *sk; /* Real listening socket */
|
||||||
|
|
|
@ -185,9 +185,6 @@ bgp_create_notification(struct bgp_conn *conn, byte *buf)
|
||||||
|
|
||||||
/* Capability negotiation as per RFC 5492 */
|
/* Capability negotiation as per RFC 5492 */
|
||||||
|
|
||||||
#define WALK_AF_CAPS(caps,ac) \
|
|
||||||
for (ac = caps->af_data; ac < &caps->af_data[caps->af_count]; ac++)
|
|
||||||
|
|
||||||
const struct bgp_af_caps *
|
const struct bgp_af_caps *
|
||||||
bgp_find_af_caps(struct bgp_caps *caps, u32 afi)
|
bgp_find_af_caps(struct bgp_caps *caps, u32 afi)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue