bgpd: Address LL peer not NHT when receiving connection attempt

The new LL code in:
8761cd6ddb

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>
This commit is contained in:
Donald Sharp 2021-04-12 14:16:30 -04:00
parent 0575d5a8f8
commit 996319e63d
5 changed files with 41 additions and 4 deletions

View 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);

View 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 */

View 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() */

View 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

View 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