diff options
Diffstat (limited to 'bgpd/bgp_mpath.c')
-rw-r--r-- | bgpd/bgp_mpath.c | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index 8e78aafe..3d17ec85 100644 --- a/bgpd/bgp_mpath.c +++ b/bgpd/bgp_mpath.c @@ -74,7 +74,7 @@ bgp_mpath_is_configured (struct bgp *bgp, afi_t afi, safi_t safi) */ int bgp_maximum_paths_set (struct bgp *bgp, afi_t afi, safi_t safi, - int peertype, u_int16_t maxpaths) + int peertype, u_int16_t maxpaths, u_int16_t options) { if (!bgp || (afi >= AFI_MAX) || (safi >= SAFI_MAX)) return -1; @@ -83,6 +83,7 @@ bgp_maximum_paths_set (struct bgp *bgp, afi_t afi, safi_t safi, { case BGP_PEER_IBGP: bgp->maxpaths[afi][safi].maxpaths_ibgp = maxpaths; + bgp->maxpaths[afi][safi].ibgp_flags |= options; break; case BGP_PEER_EBGP: bgp->maxpaths[afi][safi].maxpaths_ebgp = maxpaths; @@ -110,6 +111,7 @@ bgp_maximum_paths_unset (struct bgp *bgp, afi_t afi, safi_t safi, { case BGP_PEER_IBGP: bgp->maxpaths[afi][safi].maxpaths_ibgp = BGP_DEFAULT_MAXPATHS; + bgp->maxpaths[afi][safi].ibgp_flags = 0; break; case BGP_PEER_EBGP: bgp->maxpaths[afi][safi].maxpaths_ebgp = BGP_DEFAULT_MAXPATHS; @@ -139,26 +141,45 @@ bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2) compare = IPV4_ADDR_CMP (&bi1->attr->nexthop, &bi2->attr->nexthop); - if (!compare && ae1 && ae2 && (ae1->mp_nexthop_len == ae2->mp_nexthop_len)) + if (!compare && ae1 && ae2) { - switch (ae1->mp_nexthop_len) + if (ae1->mp_nexthop_len == ae2->mp_nexthop_len) + { + switch (ae1->mp_nexthop_len) + { + case 4: + case 12: + compare = IPV4_ADDR_CMP (&ae1->mp_nexthop_global_in, + &ae2->mp_nexthop_global_in); + break; + case 16: + compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global, + &ae2->mp_nexthop_global); + break; + case 32: + compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global, + &ae2->mp_nexthop_global); + if (!compare) + compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_local, + &ae2->mp_nexthop_local); + break; + } + } + + /* This can happen if one IPv6 peer sends you global and link-local + * nexthops but another IPv6 peer only sends you global + */ + else if (ae1->mp_nexthop_len == 16 || ae1->mp_nexthop_len == 32) { - case 4: - case 12: - compare = IPV4_ADDR_CMP (&ae1->mp_nexthop_global_in, - &ae2->mp_nexthop_global_in); - break; - case 16: - compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global, - &ae2->mp_nexthop_global); - break; - case 32: compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global, &ae2->mp_nexthop_global); if (!compare) - compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_local, - &ae2->mp_nexthop_local); - break; + { + if (ae1->mp_nexthop_len < ae2->mp_nexthop_len) + compare = -1; + else + compare = 1; + } } } @@ -427,7 +448,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best, struct listnode *mp_node, *mp_next_node; struct bgp_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath; int mpath_changed, debug; - char pfx_buf[INET_ADDRSTRLEN], nh_buf[2][INET_ADDRSTRLEN]; + char pfx_buf[INET6_ADDRSTRLEN], nh_buf[2][INET6_ADDRSTRLEN]; struct bgp_maxpaths_cfg *mpath_cfg = NULL; mpath_changed = 0; @@ -437,8 +458,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best, old_mpath_count = 0; prev_mpath = new_best; mp_node = listhead (mp_list); - - debug = BGP_DEBUG (events, EVENTS); + debug = bgp_debug_update(NULL, &rn->p, 1) || bgp_debug_update(NULL, &rn->p, 0); if (debug) prefix2str (&rn->p, pfx_buf, sizeof (pfx_buf)); |