summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_nexthop.c71
-rw-r--r--bgpd/bgp_nexthop.h10
-rw-r--r--bgpd/bgp_route.c21
-rw-r--r--bgpd/bgp_updgrp_packet.c6
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,