]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Clear capabilities field when resetting a bgp neighbor
authorAlexander Skorichenko <askorichenko@netgate.com>
Wed, 14 Jul 2021 20:43:37 +0000 (16:43 -0400)
committerAlexander Skorichenko <askorichenko@netgate.com>
Wed, 14 Jul 2021 20:43:37 +0000 (16:43 -0400)
Currently, the following sequence of events between peers could
result in erroneous capability reports on the peer
with enabled dont-capability-negotiate option:
- having some of the capabilities advertised to a bgp neighbor,
- then disabling capability negotiation to that neighbor,
- then resetting connection to it,
- and no capabilities are actually sent to the neighbor,
- but "show bgp neighbors" on the host still displays them
as advertised to the neighbor.

There are two possibilities for establishing a new connection
- the established connection was initiated by us with bgp_start(),
- the connection was initiated on the neighbor side and processed by
us via bgp_accept() in bgp_network.c.
The former case results in "show bgp neighbors" displaying only
"received" in capabilities, as the peer's cap is initiated to zero
in bgp_start().
In the latter case, if bgp_accept() happens before bgp_start()
is called, then new peer capabilities are being transferred
from its previous record before being zeroed in bgp_start().
This results in "show bgp neighbors" still displaying
"advertised and received" in capabilities.

Following the logic of a similar af_cap field clearing,
treated correctly in both cases, we
- reset peer's capability during bgp_stop()
- don't pass it over to a new peer structure in bgp_accept().
This fix prevents transferring of the previous capabilities record
to a new peer instance in arbitrary reconnect scenario.

Signed-off-by: Alexander Skorichenko <askorichenko@netgate.com>
bgpd/bgp_fsm.c
bgpd/bgpd.c

index 54eec8ab7b2a836d5d652aa455cc3bc726085caa..133af397f26cdb1ed07b9b6dd776f8ae1f169cc4 100644 (file)
@@ -1378,6 +1378,9 @@ int bgp_stop(struct peer *peer)
                peer->fd = -1;
        }
 
+       /* Reset capabilities. */
+       peer->cap = 0;
+
        FOREACH_AFI_SAFI (afi, safi) {
                /* Reset all negotiated variables */
                peer->afc_nego[afi][safi] = 0;
index 77c2f618ba15ddb34470dc58c5ee53e7181cc9ad..d2ff0207c5edce1173118ab84dcb75b9e0f2612a 100644 (file)
@@ -1454,7 +1454,6 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
 
        /* peer flags apply */
        peer_dst->flags = peer_src->flags;
-       peer_dst->cap = peer_src->cap;
 
        peer_dst->peer_gr_present_state = peer_src->peer_gr_present_state;
        peer_dst->peer_gr_new_status_flag = peer_src->peer_gr_new_status_flag;