diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2023-11-23 20:54:22 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2023-11-23 20:54:22 +0100 |
commit | 3fb06fea1d14ef147a567052391a5b359704e971 (patch) | |
tree | 692750a6792e18fc1dcf50c277d0cde275577815 /proto/bgp/packets.c | |
parent | b6923f6386b04340d6b2b6a75fbe83c392f207ca (diff) |
BGP: Add options to require BGP capabilities
Some BGP capabilities change the BGP behavior in a significant way, so if
the configuration depends on it, it is better to not establish BGP
session when the capability is not available.
Add several BGP option to require individual BGP capabilities during
session negotiation.
Diffstat (limited to 'proto/bgp/packets.c')
-rw-r--r-- | proto/bgp/packets.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 395169a4..1e5a226f 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -694,7 +694,7 @@ err: return -1; } -static int +int bgp_check_capabilities(struct bgp_conn *conn) { struct bgp_proto *p = conn->bgp; @@ -706,6 +706,29 @@ bgp_check_capabilities(struct bgp_conn *conn) /* This is partially overlapping with bgp_conn_enter_established_state(), but we need to run this just after we receive OPEN message */ + if (p->cf->require_refresh && !remote->route_refresh) + return 0; + + if (p->cf->require_enhanced_refresh && !remote->enhanced_refresh) + return 0; + + if (p->cf->require_as4 && !remote->as4_support) + return 0; + + if (p->cf->require_extended_messages && !remote->ext_messages) + return 0; + + if (p->cf->require_hostname && !remote->hostname) + return 0; + + if (p->cf->require_gr && !remote->gr_aware) + return 0; + + if (p->cf->require_llgr && !remote->llgr_aware) + return 0; + + /* No check for require_roles, as it uses error code 2.11 instead of 2.7 */ + BGP_WALK_CHANNELS(p, c) { const struct bgp_af_caps *loc = bgp_find_af_caps(local, c->afi); @@ -719,7 +742,18 @@ bgp_check_capabilities(struct bgp_conn *conn) return 0; if (active) + { + if (c->cf->require_ext_next_hop && !rem->ext_next_hop) + return 0; + + if (c->cf->require_add_path && (loc->add_path & BGP_ADD_PATH_RX) && !(rem->add_path & BGP_ADD_PATH_TX)) + return 0; + + if (c->cf->require_add_path && (loc->add_path & BGP_ADD_PATH_TX) && !(rem->add_path & BGP_ADD_PATH_RX)) + return 0; + count++; + } } /* We need at least one channel active */ @@ -905,7 +939,7 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len) if (!id || (p->is_internal && id == p->local_id)) { bgp_error(conn, 2, 3, pkt+24, -4); return; } - /* RFC 5492 4 - check for required capabilities */ + /* RFC 5492 5 - check for required capabilities */ if (p->cf->capabilities && !bgp_check_capabilities(conn)) { bgp_error(conn, 2, 7, NULL, 0); return; } |