diff options
| -rw-r--r-- | bgpd/bgp_nexthop.c | 71 | ||||
| -rw-r--r-- | bgpd/bgp_nexthop.h | 10 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 21 | ||||
| -rw-r--r-- | bgpd/bgp_updgrp_packet.c | 6 |
4 files changed, 101 insertions, 7 deletions
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index ea5e02d00e..a8c507832c 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -505,6 +505,77 @@ int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer) return (ret); } +int bgp_multiaccess_check_v6(struct in6_addr nexthop, struct peer *peer) +{ + struct bgp_node *rn1; + struct bgp_node *rn2; + struct prefix p; + int ret; + + p.family = AF_INET6; + p.prefixlen = IPV6_MAX_BITLEN; + p.u.prefix6 = nexthop; + + rn1 = bgp_node_match(peer->bgp->connected_table[AFI_IP6], &p); + if (!rn1) + return 0; + + p.family = AF_INET6; + p.prefixlen = IPV6_MAX_BITLEN; + p.u.prefix6 = peer->su.sin6.sin6_addr; + + rn2 = bgp_node_match(peer->bgp->connected_table[AFI_IP6], &p); + if (!rn2) { + bgp_unlock_node(rn1); + return 0; + } + + ret = (rn1 == rn2) ? 1 : 0; + + bgp_unlock_node(rn1); + bgp_unlock_node(rn2); + + return ret; +} + +int bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop, + struct update_subgroup *subgrp) +{ + struct bgp_node *rn1 = NULL, *rn2 = NULL; + struct peer_af *paf = NULL; + struct prefix p = {0}, np = {0}; + struct bgp *bgp = NULL; + + np.family = AF_INET6; + np.prefixlen = IPV6_MAX_BITLEN; + np.u.prefix6 = nexthop; + + p.family = AF_INET; + p.prefixlen = IPV6_MAX_BITLEN; + + bgp = SUBGRP_INST(subgrp); + rn1 = bgp_node_match(bgp->connected_table[AFI_IP6], &np); + if (!rn1) + return 0; + + SUBGRP_FOREACH_PEER (subgrp, paf) { + + p.u.prefix6 = paf->peer->su.sin6.sin6_addr; + rn2 = bgp_node_match(bgp->connected_table[AFI_IP6], &p); + if (rn1 == rn2) { + bgp_unlock_node(rn1); + bgp_unlock_node(rn2); + return 1; + } + + if (rn2) + bgp_unlock_node(rn2); + } + + bgp_unlock_node(rn1); + return 0; +} + int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, struct update_subgroup *subgrp) { diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h index f06fae5706..d35f1ad520 100644 --- a/bgpd/bgp_nexthop.h +++ b/bgpd/bgp_nexthop.h @@ -74,11 +74,19 @@ struct tip_addr { int refcnt; }; +struct bgp_addrv6 { + struct in6_addr addrv6; + struct list *ifp_name_list; +}; + extern void bgp_connected_add(struct bgp *bgp, struct connected *c); extern void bgp_connected_delete(struct bgp *bgp, struct connected *c); extern int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, struct update_subgroup *subgrp); -extern int bgp_multiaccess_check_v4(struct in_addr, struct peer *); +extern int bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop, + struct update_subgroup *subgrp); +extern int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer); +extern int bgp_multiaccess_check_v6(struct in6_addr nexthop, struct peer *peer); extern int bgp_config_write_scan_time(struct vty *); extern int bgp_nexthop_self(struct bgp *, struct in_addr); extern struct bgp_nexthop_cache *bnc_new(void); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index d5e12488d7..6b11565716 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1844,13 +1844,28 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi, * Note: 3rd party nexthop currently implemented for * IPv4 only. */ - if (!bgp_subgrp_multiaccess_check_v4(piattr->nexthop, - subgrp)) + if ((p->family == AF_INET) && + (!bgp_subgrp_multiaccess_check_v4( + piattr->nexthop, + subgrp))) subgroup_announce_reset_nhop( (peer_cap_enhe(peer, afi, safi) ? AF_INET6 : p->family), - attr); + attr); + + if ((p->family == AF_INET6) && + (!bgp_subgrp_multiaccess_check_v6( + piattr->mp_nexthop_global, + subgrp))) + subgroup_announce_reset_nhop( + (peer_cap_enhe(peer, afi, safi) + ? AF_INET6 + : p->family), + attr); + + + } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) { /* * This flag is used for leaked vpn-vrf routes diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 3556b236a7..688abae0e4 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -554,9 +554,9 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, mod_v6nhg = &peer->nexthop.v6_global; gnh_modified = 1; } else if ( - peer->sort == BGP_PEER_EBGP - && !CHECK_FLAG( - vec->flags, + (peer->sort == BGP_PEER_EBGP) + && (!bgp_multiaccess_check_v6(v6nhglobal, peer)) + && !CHECK_FLAG(vec->flags, BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED) && !peer_af_flag_check( peer, nhafi, paf->safi, |
