]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Address LL peer not NHT when receiving connection attempt 8456/head
authorDonald Sharp <sharpd@nvidia.com>
Mon, 12 Apr 2021 18:16:30 +0000 (14:16 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Thu, 15 Apr 2021 17:16:28 +0000 (13:16 -0400)
The new LL code in:
8761cd6ddb5437767625f58c8e9cc3ccda7887ab

Introduced the idea of the bgp unnumbered peers using interface up/down
events to track the bgp peers nexthop.  This code was not properly
working when a connection was received from a peer in some circumstances.

Effectively the connection from a peer was immediately skipping state transitions
and FRR was never properly tracking the peers nexthop.  When we receive the
connection attempt, let's track the nexthop now.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
bgpd/bgp_fsm.c
bgpd/bgp_fsm.h
bgpd/bgp_network.c
bgpd/bgp_nht.c
bgpd/bgp_nht.h

index 45a856a4591fc5f0f7a834fe88acd7eaf7a73c2b..88c44fc984d898222aa006f3fe62f847fc653b85 100644 (file)
@@ -101,7 +101,7 @@ static int bgp_delayopen_timer(struct thread *);
 static int bgp_start(struct peer *);
 
 /* Register peer with NHT */
-static int bgp_peer_reg_with_nht(struct peer *peer)
+int bgp_peer_reg_with_nht(struct peer *peer)
 {
        int connected = 0;
 
@@ -340,6 +340,8 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
         * needed, even on a passive connection.
         */
        bgp_peer_reg_with_nht(peer);
+       if (from_peer)
+               bgp_replace_nexthop_by_peer(from_peer, peer);
 
        bgp_reads_on(peer);
        bgp_writes_on(peer);
index bcf697e153fb4275d3d777d4c4c54c6b820fc555..12cbad3eb83b0e164a70888fa92268ff5b0fb606 100644 (file)
@@ -179,4 +179,5 @@ const char *print_peer_gr_mode(enum peer_mode pr_mode);
 const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd);
 const char *print_global_gr_mode(enum global_mode gl_mode);
 const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd);
+int bgp_peer_reg_with_nht(struct peer *peer);
 #endif /* _QUAGGA_BGP_FSM_H */
index 4821ce8ddbf4000fe04bebba50a86c152e683a5a..8d9024e07c512e7d1a0c3efe8615260806e7cc5f 100644 (file)
@@ -569,6 +569,7 @@ static int bgp_accept(struct thread *thread)
        peer1->doppelganger = peer;
        peer->fd = bgp_sock;
        vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer));
+       bgp_peer_reg_with_nht(peer);
        bgp_fsm_change_status(peer, Active);
        BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */
 
index 9c8d7878c513ac2bca0105b44f0672873d13a7c4..7ccfae4ba4c288e513f137ee5ff8c3b2b0e43036 100644 (file)
@@ -98,6 +98,31 @@ void bgp_unlink_nexthop(struct bgp_path_info *path)
        bgp_unlink_nexthop_check(bnc);
 }
 
+void bgp_replace_nexthop_by_peer(struct peer *from, struct peer *to)
+{
+       struct prefix pp;
+       struct prefix pt;
+       struct bgp_nexthop_cache *bncp, *bnct;
+       afi_t afi;
+
+       if (!sockunion2hostprefix(&from->su, &pp))
+               return;
+
+       afi = family2afi(pp.family);
+       bncp = bnc_find(&from->bgp->nexthop_cache_table[afi], &pp, 0);
+
+       if (!sockunion2hostprefix(&to->su, &pt))
+               return;
+
+       bnct = bnc_find(&to->bgp->nexthop_cache_table[afi], &pt, 0);
+
+       if (bnct != bncp)
+               return;
+
+       if (bnct)
+               bnct->nht_info = to;
+}
+
 void bgp_unlink_nexthop_by_peer(struct peer *peer)
 {
        struct prefix p;
@@ -273,8 +298,16 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
                        (bgp_path_info_extra_get(pi))->igpmetric = bnc->metric;
                else if (pi->extra)
                        pi->extra->igpmetric = 0;
-       } else if (peer)
-               bnc->nht_info = (void *)peer; /* NHT peer reference */
+       } else if (peer) {
+               /*
+                * Let's not accidently save the peer data for a peer
+                * we are going to throw away in a second or so.
+                * When we come back around we'll fix up this
+                * data properly in replace_nexthop_by_peer
+                */
+               if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+                       bnc->nht_info = (void *)peer; /* NHT peer reference */
+       }
 
        /*
         * We are cheating here.  Views have no associated underlying
index a1683e15114edb8a7da51da2157d5549e26c2e3a..9268b225ca02888cb3eb95c9aa0bbd21883685b0 100644 (file)
@@ -51,7 +51,7 @@ extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
  */
 extern void bgp_unlink_nexthop(struct bgp_path_info *p);
 void bgp_unlink_nexthop_by_peer(struct peer *peer);
-
+void bgp_replace_nexthop_by_peer(struct peer *from, struct peer *to);
 /**
  * bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
  * nexthop entry. If no paths reference the nexthop, it will be unregistered