diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2017-01-24 02:00:35 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2017-01-24 02:00:35 +0100 |
commit | d8022d26fc64121c3416abfdb4c38fcbaf81c12e (patch) | |
tree | bd49b3cfcc9e075d2dae57f6fb95d015629bbcc0 /proto/bgp/packets.c | |
parent | 5509e17d0c1b4e75d5911864f75ba119769e5725 (diff) |
BGP: Partial support for IPv4 routes with IPv6 next hop (RFC 5549)
Mostly capability signalling
Diffstat (limited to 'proto/bgp/packets.c')
-rw-r--r-- | proto/bgp/packets.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index a7df1c63..dbc5fe12 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -228,6 +228,7 @@ bgp_write_capabilities(struct bgp_conn *conn, byte *buf) struct bgp_channel *c; struct bgp_caps *caps; struct bgp_af_caps *ac; + uint any_ext_next_hop = 0; uint any_add_path = 0; byte *data; @@ -259,6 +260,9 @@ bgp_write_capabilities(struct bgp_conn *conn, byte *buf) ac->afi = c->afi; 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; any_add_path |= ac->add_path; @@ -298,6 +302,23 @@ bgp_write_capabilities(struct bgp_conn *conn, byte *buf) *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) { *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; 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 */ if (cl != 0) goto err; |