]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Fix rtadv startup when config read in is before interface up
authorDonald Sharp <sharpd@nvidia.com>
Fri, 17 Jun 2022 15:23:31 +0000 (11:23 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Fri, 24 Jun 2022 11:18:41 +0000 (07:18 -0400)
When a interface is configured with this:
int eva
  ipv6 nd ra-interval 5
  no ipv6 nd suppress-ra
!

And then subsuquently the interface is created and brought up, FRR
would both error on joining the RA multicast address and never
properly work in this state.

Delay the startup of the join and start of the Router Advertisements
until after the ifindex has actually been found.

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

index b24dc89a68b873e9dee8782b99bfba1af25b663c..5d4ed1e424c48f80f85d4578467e7453a3950460 100644 (file)
@@ -1205,6 +1205,29 @@ void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p)
        rtadv_prefix_reset(zif, &rp);
 }
 
+static void rtadv_start_interface_events(struct zebra_vrf *zvrf,
+                                        struct zebra_if *zif)
+{
+       struct adv_if *adv_if = NULL;
+
+       if (zif->ifp->ifindex == IFINDEX_INTERNAL) {
+               if (IS_ZEBRA_DEBUG_EVENT)
+                       zlog_debug(
+                               "%s(%s) has not configured an ifindex yet, delaying until we have one",
+                               zif->ifp->name, zvrf->vrf->name);
+               return;
+       }
+
+       adv_if = adv_if_add(zvrf, zif->ifp->name);
+       if (adv_if != NULL)
+               return; /* Already added */
+
+       if_join_all_router(zvrf->rtadv.sock, zif->ifp);
+
+       if (adv_if_list_count(&zvrf->rtadv.adv_if) == 1)
+               rtadv_event(zvrf, RTADV_START, 0);
+}
+
 static void ipv6_nd_suppress_ra_set(struct interface *ifp,
                                    enum ipv6_nd_suppress_ra_status status)
 {
@@ -1249,14 +1272,7 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp,
                                        RTADV_NUM_FAST_REXMITS;
                        }
 
-                       adv_if = adv_if_add(zvrf, ifp->name);
-                       if (adv_if != NULL)
-                               return; /* Alread added */
-
-                       if_join_all_router(zvrf->rtadv.sock, ifp);
-
-                       if (adv_if_list_count(&zvrf->rtadv.adv_if) == 1)
-                               rtadv_event(zvrf, RTADV_START, 0);
+                       rtadv_start_interface_events(zvrf, zif);
                }
        }
 }
@@ -2780,6 +2796,8 @@ static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
 
 void rtadv_if_up(struct zebra_if *zif)
 {
+       struct zebra_vrf *zvrf = rtadv_interface_get_zvrf(zif->ifp);
+
        /* Enable fast tx of RA if enabled && RA interval is not in msecs */
        if (zif->rtadv.AdvSendAdvertisements &&
            (zif->rtadv.MaxRtrAdvInterval >= 1000) &&
@@ -2787,6 +2805,13 @@ void rtadv_if_up(struct zebra_if *zif)
                zif->rtadv.inFastRexmit = 1;
                zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
        }
+
+       /*
+        * startup the state machine, if it hasn't been already
+        * due to a delayed ifindex on startup ordering
+        */
+       if (zif->rtadv.AdvSendAdvertisements)
+               rtadv_start_interface_events(zvrf, zif);
 }
 
 void rtadv_if_init(struct zebra_if *zif)