router: speed up initial router advertisements
authorHans Dedecker <dedeckeh@gmail.com>
Fri, 16 Aug 2019 19:22:11 +0000 (21:22 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Mon, 26 Aug 2019 20:36:37 +0000 (22:36 +0200)
Speed up sending initial router advertisement messages as documented in
RFC2461 point 6.2.4

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
src/odhcpd.h
src/router.c
src/router.h

index 8715ca700bd236b17c851ca779f00d48611849ba..4a07252322d40d228bb0d1851e7560089e34a227 100644 (file)
@@ -212,6 +212,7 @@ struct interface {
        // RA runtime data
        struct odhcpd_event router_event;
        struct uloop_timeout timer_rs;
+       uint32_t ra_sent;
 
        // DHCPv6 runtime data
        struct odhcpd_event dhcpv6_event;
index 34d43b0af6bc95f51c5f8bbc4e198a0785c0a9d0..07dd146085cf2b55a6db0bff15792ac3239f2c78 100644 (file)
@@ -176,6 +176,7 @@ int router_setup_interface(struct interface *iface, bool enable)
                        }
 
                        iface->router_event.handle_dgram = handle_icmpv6;
+                       iface->ra_sent = 0;
                        odhcpd_register(&iface->router_event);
                } else {
                        uloop_timeout_cancel(&iface->timer_rs);
@@ -358,6 +359,13 @@ static int calc_adv_interval(struct interface *iface, uint32_t minvalid,
        msecs = (labs(msecs) % ((*maxival != minival) ? (*maxival - minival)*1000 : 500)) +
                        minival*1000;
 
+       /* RFC 2461 6.2.4 For the first MAX_INITIAL_RTR_ADVERTISEMENTS advertisements */
+       /* if the timer is bigger than MAX_INITIAL_RTR_ADVERT_INTERVAL it should be   */
+       /* set to MAX_INITIAL_RTR_ADVERT_INTERVAL                                     */
+       /* Off by one as an initial interval timer has already expired                */
+       if ((iface->ra_sent + 1) < MaxInitialRtAdvs && msecs > MaxInitialRtrAdvInterval*1000)
+               msecs = MaxInitialRtrAdvInterval*1000;
+
        return msecs;
 }
 
@@ -730,7 +738,8 @@ static int send_router_advert(struct interface *iface, const struct in6_addr *fr
 
        syslog(LOG_NOTICE, "Sending a RA on %s", iface->name);
 
-       odhcpd_send(iface->router_event.uloop.fd, &dest, iov, ARRAY_SIZE(iov), iface);
+       if (odhcpd_send(iface->router_event.uloop.fd, &dest, iov, ARRAY_SIZE(iov), iface) > 0)
+               iface->ra_sent++;
 
        free(pfxs);
        free(routes);
index bdfe52c43789e9203e4115a8ccac33daa5526db9..0444da8329a88c1b17ed27efb537f3992728ba87 100644 (file)
@@ -30,9 +30,11 @@ struct icmpv6_opt {
        (void*)(opt + opt->len) <= (void*)(end); opt += opt->len)
 
 
-#define MaxRtrAdvInterval      1800
-#define MinRtrAdvInterval      3
+#define MaxInitialRtrAdvInterval       16
+#define MaxInitialRtAdvs               3
+#define MaxRtrAdvInterval              1800
+#define MinRtrAdvInterval              3
 
-#define ND_RA_FLAG_PROXY       0x4
-#define ND_RA_PREF_HIGH                (1 << 3)
-#define ND_RA_PREF_LOW         (3 << 3)
+#define ND_RA_FLAG_PROXY               0x4
+#define ND_RA_PREF_HIGH                        (1 << 3)
+#define ND_RA_PREF_LOW                 (3 << 3)