diff options
Diffstat (limited to 'bgpd/bgp_nht.c')
| -rw-r--r-- | bgpd/bgp_nht.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 9c8d7878c5..7ccfae4ba4 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -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 |
