BGP: Partial support for IPv4 routes with IPv6 next hop (RFC 5549)
Mostly capability signalling
This commit is contained in:
parent
5509e17d0c
commit
d8022d26fc
5 changed files with 60 additions and 0 deletions
|
@ -1285,6 +1285,8 @@ bgp_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct li
|
||||||
if (src == NULL)
|
if (src == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// XXXX: Check next hop AF
|
||||||
|
|
||||||
/* IBGP route reflection, RFC 4456 */
|
/* IBGP route reflection, RFC 4456 */
|
||||||
if (p->is_internal && src->is_internal && (p->local_as == src->local_as))
|
if (p->is_internal && src->is_internal && (p->local_as == src->local_as))
|
||||||
{
|
{
|
||||||
|
|
|
@ -521,6 +521,7 @@ bgp_conn_enter_established_state(struct bgp_conn *conn)
|
||||||
if (peer->gr_aware)
|
if (peer->gr_aware)
|
||||||
c->load_state = BFS_LOADING;
|
c->load_state = BFS_LOADING;
|
||||||
|
|
||||||
|
c->ext_next_hop = c->cf->ext_next_hop && (bgp_channel_is_ipv6(c) || rem->ext_next_hop);
|
||||||
c->add_path_rx = (loc->add_path & BGP_ADD_PATH_RX) && (rem->add_path & BGP_ADD_PATH_TX);
|
c->add_path_rx = (loc->add_path & BGP_ADD_PATH_RX) && (rem->add_path & BGP_ADD_PATH_TX);
|
||||||
c->add_path_tx = (loc->add_path & BGP_ADD_PATH_TX) && (rem->add_path & BGP_ADD_PATH_RX);
|
c->add_path_tx = (loc->add_path & BGP_ADD_PATH_TX) && (rem->add_path & BGP_ADD_PATH_RX);
|
||||||
|
|
||||||
|
@ -1788,6 +1789,7 @@ bgp_show_capabilities(struct bgp_proto *p UNUSED, struct bgp_caps *caps)
|
||||||
uint any_mp_bgp = 0;
|
uint any_mp_bgp = 0;
|
||||||
uint any_gr_able = 0;
|
uint any_gr_able = 0;
|
||||||
uint any_add_path = 0;
|
uint any_add_path = 0;
|
||||||
|
uint any_ext_next_hop = 0;
|
||||||
u32 *afl1 = alloca(caps->af_count * sizeof(u32));
|
u32 *afl1 = alloca(caps->af_count * sizeof(u32));
|
||||||
u32 *afl2 = alloca(caps->af_count * sizeof(u32));
|
u32 *afl2 = alloca(caps->af_count * sizeof(u32));
|
||||||
uint afn1, afn2;
|
uint afn1, afn2;
|
||||||
|
@ -1797,6 +1799,7 @@ bgp_show_capabilities(struct bgp_proto *p UNUSED, struct bgp_caps *caps)
|
||||||
any_mp_bgp |= ac->ready;
|
any_mp_bgp |= ac->ready;
|
||||||
any_gr_able |= ac->gr_able;
|
any_gr_able |= ac->gr_able;
|
||||||
any_add_path |= ac->add_path;
|
any_add_path |= ac->add_path;
|
||||||
|
any_ext_next_hop |= ac->ext_next_hop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (any_mp_bgp)
|
if (any_mp_bgp)
|
||||||
|
@ -1814,6 +1817,18 @@ bgp_show_capabilities(struct bgp_proto *p UNUSED, struct bgp_caps *caps)
|
||||||
if (caps->route_refresh)
|
if (caps->route_refresh)
|
||||||
cli_msg(-1006, " Route refresh");
|
cli_msg(-1006, " Route refresh");
|
||||||
|
|
||||||
|
if (any_ext_next_hop)
|
||||||
|
{
|
||||||
|
cli_msg(-1006, " Extended next hop");
|
||||||
|
|
||||||
|
afn1 = 0;
|
||||||
|
WALK_AF_CAPS(caps, ac)
|
||||||
|
if (ac->ext_next_hop)
|
||||||
|
afl1[afn1++] = ac->afi;
|
||||||
|
|
||||||
|
bgp_show_afis(-1006, " IPv6 nexthop:", afl1, afn1);
|
||||||
|
}
|
||||||
|
|
||||||
if (caps->ext_messages)
|
if (caps->ext_messages)
|
||||||
cli_msg(-1006, " Extended message");
|
cli_msg(-1006, " Extended message");
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,7 @@ struct bgp_channel_config {
|
||||||
u8 gw_mode; /* How we compute route gateway from next_hop attr, see GW_* */
|
u8 gw_mode; /* How we compute route gateway from next_hop attr, see GW_* */
|
||||||
u8 secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
|
u8 secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
|
||||||
u8 gr_able; /* Allow full graceful restart for the channel */
|
u8 gr_able; /* Allow full graceful restart for the channel */
|
||||||
|
u8 ext_next_hop; /* Allow both IPv4 and IPv6 next hops */
|
||||||
u8 add_path; /* Use ADD-PATH extension [RFC 7911] */
|
u8 add_path; /* Use ADD-PATH extension [RFC 7911] */
|
||||||
|
|
||||||
struct rtable_config *igp_table; /* Table used for recursive next hop lookups */
|
struct rtable_config *igp_table; /* Table used for recursive next hop lookups */
|
||||||
|
@ -154,6 +155,7 @@ struct bgp_af_caps {
|
||||||
u8 ready; /* Multiprotocol capability, RFC 4760 */
|
u8 ready; /* Multiprotocol capability, RFC 4760 */
|
||||||
u8 gr_able; /* Graceful restart support, RFC 4724 */
|
u8 gr_able; /* Graceful restart support, RFC 4724 */
|
||||||
u8 gr_af_flags; /* Graceful restart per-AF flags */
|
u8 gr_af_flags; /* Graceful restart per-AF flags */
|
||||||
|
u8 ext_next_hop; /* Extended IPv6 next hop, RFC 5549 */
|
||||||
u8 add_path; /* Multiple paths support, RFC 7911 */
|
u8 add_path; /* Multiple paths support, RFC 7911 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -274,6 +276,8 @@ struct bgp_channel {
|
||||||
u8 gr_ready; /* Neighbor could do GR on this AF */
|
u8 gr_ready; /* Neighbor could do GR on this AF */
|
||||||
u8 gr_active; /* Neighbor is doing GR and keeping fwd state */
|
u8 gr_active; /* Neighbor is doing GR and keeping fwd state */
|
||||||
|
|
||||||
|
u8 ext_next_hop; /* Session allows both IPv4 and IPv6 next hops */
|
||||||
|
|
||||||
u8 add_path_rx; /* Session expects receive of ADD-PATH extended NLRI */
|
u8 add_path_rx; /* Session expects receive of ADD-PATH extended NLRI */
|
||||||
u8 add_path_tx; /* Session expects transmit of ADD-PATH extended NLRI */
|
u8 add_path_tx; /* Session expects transmit of ADD-PATH extended NLRI */
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,7 @@ bgp_channel_item:
|
||||||
| GATEWAY RECURSIVE { BGP_CC->gw_mode = GW_RECURSIVE; }
|
| GATEWAY RECURSIVE { BGP_CC->gw_mode = GW_RECURSIVE; }
|
||||||
| SECONDARY bool { BGP_CC->secondary = $2; }
|
| SECONDARY bool { BGP_CC->secondary = $2; }
|
||||||
| GRACEFUL RESTART bool { BGP_CC->gr_able = $3; }
|
| GRACEFUL RESTART bool { BGP_CC->gr_able = $3; }
|
||||||
|
| EXTENDED NEXT HOP bool { BGP_CC->ext_next_hop = $4; }
|
||||||
| ADD PATHS RX { BGP_CC->add_path = BGP_ADD_PATH_RX; }
|
| ADD PATHS RX { BGP_CC->add_path = BGP_ADD_PATH_RX; }
|
||||||
| ADD PATHS TX { BGP_CC->add_path = BGP_ADD_PATH_TX; }
|
| ADD PATHS TX { BGP_CC->add_path = BGP_ADD_PATH_TX; }
|
||||||
| ADD PATHS bool { BGP_CC->add_path = $3 ? BGP_ADD_PATH_FULL : 0; }
|
| ADD PATHS bool { BGP_CC->add_path = $3 ? BGP_ADD_PATH_FULL : 0; }
|
||||||
|
|
|
@ -228,6 +228,7 @@ bgp_write_capabilities(struct bgp_conn *conn, byte *buf)
|
||||||
struct bgp_channel *c;
|
struct bgp_channel *c;
|
||||||
struct bgp_caps *caps;
|
struct bgp_caps *caps;
|
||||||
struct bgp_af_caps *ac;
|
struct bgp_af_caps *ac;
|
||||||
|
uint any_ext_next_hop = 0;
|
||||||
uint any_add_path = 0;
|
uint any_add_path = 0;
|
||||||
byte *data;
|
byte *data;
|
||||||
|
|
||||||
|
@ -259,6 +260,9 @@ bgp_write_capabilities(struct bgp_conn *conn, byte *buf)
|
||||||
ac->afi = c->afi;
|
ac->afi = c->afi;
|
||||||
ac->ready = 1;
|
ac->ready = 1;
|
||||||
|
|
||||||
|
ac->ext_next_hop = bgp_channel_is_ipv4(c) && c->cf->ext_next_hop;
|
||||||
|
any_ext_next_hop |= ac->ext_next_hop;
|
||||||
|
|
||||||
ac->add_path = c->cf->add_path;
|
ac->add_path = c->cf->add_path;
|
||||||
any_add_path |= ac->add_path;
|
any_add_path |= ac->add_path;
|
||||||
|
|
||||||
|
@ -298,6 +302,23 @@ bgp_write_capabilities(struct bgp_conn *conn, byte *buf)
|
||||||
*buf++ = 0; /* Capability data length */
|
*buf++ = 0; /* Capability data length */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (any_ext_next_hop)
|
||||||
|
{
|
||||||
|
*buf++ = 5; /* Capability 5: Support for extended next hop */
|
||||||
|
*buf++ = 0; /* Capability data length, will be fixed later */
|
||||||
|
data = buf;
|
||||||
|
|
||||||
|
WALK_AF_CAPS(caps, ac)
|
||||||
|
if (ac->ext_next_hop)
|
||||||
|
{
|
||||||
|
put_af4(buf, ac->afi);
|
||||||
|
put_u16(buf+4, BGP_AFI_IPV6);
|
||||||
|
buf += 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[-1] = buf - data;
|
||||||
|
}
|
||||||
|
|
||||||
if (caps->ext_messages)
|
if (caps->ext_messages)
|
||||||
{
|
{
|
||||||
*buf++ = 6; /* Capability 6: Support for extended messages */
|
*buf++ = 6; /* Capability 6: Support for extended messages */
|
||||||
|
@ -394,6 +415,23 @@ bgp_read_capabilities(struct bgp_conn *conn, struct bgp_caps *caps, byte *pos, i
|
||||||
caps->route_refresh = 1;
|
caps->route_refresh = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 5: /* Extended next hop encoding capability, RFC 5549 */
|
||||||
|
if (cl % 6)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
for (i = 0; i < cl; i += 6)
|
||||||
|
{
|
||||||
|
/* Specified only for IPv4 prefixes with IPv6 next hops */
|
||||||
|
if ((get_u16(pos+2+i+0) != BGP_AFI_IPV4) ||
|
||||||
|
(get_u16(pos+2+i+4) != BGP_AFI_IPV6))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
af = get_af4(pos+2+i);
|
||||||
|
ac = bgp_get_af_caps(caps, af);
|
||||||
|
ac->ext_next_hop = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 6: /* Extended message length capability, RFC draft */
|
case 6: /* Extended message length capability, RFC draft */
|
||||||
if (cl != 0)
|
if (cl != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
Loading…
Reference in a new issue