]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Prevent the ebgp ipv6 sender from changing of nexthop in a special case.
authorBiswajit Sadhu <sadhub@vmware.com>
Sat, 27 Apr 2019 11:27:21 +0000 (04:27 -0700)
committerBiswajit Sadhu <sadhub@vmware.com>
Sat, 27 Apr 2019 11:27:21 +0000 (04:27 -0700)
Prevent the ebgp sender from changing the nexthop( which is same as the ebgp neighbour ipv6 address),
while sending updates to its ipv6 neighbor.So,if the nexthop of the ipv6 route is same as the ipv6
neighbour address do not change the next hop to your own ip.

Signed-off-by: Biswajit Sadhu <sadhub@vmware.com>
bgpd/bgp_nexthop.c
bgpd/bgp_nexthop.h
bgpd/bgp_route.c
bgpd/bgp_updgrp_packet.c

index de97b73c7210ab41d1b534d4e33b4af72c1130b0..b84a4adbf3dcce315a6cc2a030f18664872bde1e 100644 (file)
@@ -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)
 {
index f06fae5706a9203a61f6b0e59946d1f016e5e461..d35f1ad5207d64b855cfdd3b0582c61478852276 100644 (file)
@@ -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);
index 063cc24dc1bd69918e6397b14c9ba8d97a4161c7..bfc82590c160203123203c6abf68a4835b42cfee 100644 (file)
@@ -1854,13 +1854,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
index 66e306cba23d4bad8c504066e2df6dc32e7912a7..c02e5371553659ebefc211d6d68a9cf127024170 100644 (file)
@@ -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,