]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Ensure v6 LL address is available before establishing peering
authorDonald Sharp <sharpd@nvidia.com>
Wed, 30 Jun 2021 14:25:43 +0000 (10:25 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Wed, 30 Jun 2021 14:33:21 +0000 (10:33 -0400)
There are startup situations where we will attempt to connect to a remote
peer before bgp has received the v6 LL address.  If we do not have this address
we must not allow the connection to come up until we have one available to use
in those situations where we must have a v6 LL address.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
bgpd/bgp_zebra.c

index 5d3176537bb2816fddaffc14000498035419afad..ec71e17034d31d6d6e785f024aa5a6a24e404029 100644 (file)
@@ -683,7 +683,7 @@ static int if_get_ipv6_global(struct interface *ifp, struct in6_addr *addr)
        return 0;
 }
 
-static int if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
+static bool if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
 {
        struct listnode *cnode;
        struct connected *connected;
@@ -695,10 +695,10 @@ static int if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
                if (cp->family == AF_INET6)
                        if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6)) {
                                memcpy(addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
-                               return 1;
+                               return true;
                        }
        }
-       return 0;
+       return false;
 }
 
 static int if_get_ipv4_address(struct interface *ifp, struct in_addr *addr)
@@ -724,6 +724,7 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
 {
        int ret = 0;
        struct interface *ifp = NULL;
+       bool v6_ll_avail = true;
 
        memset(nexthop, 0, sizeof(struct bgp_nexthop));
 
@@ -793,12 +794,20 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
                         * route-map to
                         * specify the global IPv6 nexthop.
                         */
-                       if_get_ipv6_local(ifp, &nexthop->v6_global);
+                       v6_ll_avail =
+                               if_get_ipv6_local(ifp, &nexthop->v6_global);
                        memcpy(&nexthop->v6_local, &nexthop->v6_global,
                               IPV6_MAX_BYTELEN);
                } else
-                       if_get_ipv6_local(ifp, &nexthop->v6_local);
+                       v6_ll_avail =
+                               if_get_ipv6_local(ifp, &nexthop->v6_local);
 
+               /*
+                * If we are a v4 connection and we are not doing unnumbered
+                * not having a v6 LL address is ok
+                */
+               if (!v6_ll_avail && !peer->conf_if)
+                       v6_ll_avail = true;
                if (if_lookup_by_ipv4(&remote->sin.sin_addr, peer->bgp->vrf_id))
                        peer->shared_network = 1;
                else
@@ -824,7 +833,8 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
                                                   remote->sin6.sin6_scope_id,
                                                   peer->bgp->vrf_id);
                        if (direct)
-                               if_get_ipv6_local(ifp, &nexthop->v6_local);
+                               v6_ll_avail = if_get_ipv6_local(
+                                       ifp, &nexthop->v6_local);
                } else
                /* Link-local address. */
                {
@@ -871,7 +881,7 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
 
        /* If we have identified the local interface, there is no error for now.
         */
-       return true;
+       return v6_ll_avail;
 }
 
 static struct in6_addr *