From f0fd3f2be6a3746376a268ce71bf68011d747132 Mon Sep 17 00:00:00 2001
From: Stian Skjelstad <stian@barnfind.no>
Date: Thu, 11 Jun 2015 15:52:51 +0200
Subject: [PATCH 3/4] Forget about addresses when prefix (router advertisement)
 times out

---
 src/core/ipv6/nd6.c | 74 ++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 48 insertions(+), 26 deletions(-)

diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c
index c74e35a..69b3d91 100644
--- a/src/core/ipv6/nd6.c
+++ b/src/core/ipv6/nd6.c
@@ -743,41 +743,63 @@ nd6_tmr(void)
 
   /* Process prefix entries. */
   for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) {
-    if (prefix_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) {
-      prefix_list[i].invalidation_timer = 0;
-    }
-    if ((prefix_list[i].invalidation_timer > 0) &&
-        (prefix_list[i].netif != NULL)) {
-      prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000;
+    if (prefix_list[i].netif) {
+      if (prefix_list[i].invalidation_timer <= ND6_TMR_INTERVAL / 1000) {
+        /* Entry timed out, remove it */
+        prefix_list[i].invalidation_timer = 0;
+
+#if LWIP_IPV6_AUTOCONFIG
+        /* If any addresses were configured with this prefix, remove them */
+        if (prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED)
+        {
+          s8_t j;
+
+          for (j = 1; j < LWIP_IPV6_NUM_ADDRESSES; j++) {
+            if ((netif_ip6_addr_state(prefix_list[i].netif, j) != IP6_ADDR_INVALID) &&
+                ip6_addr_netcmp(&prefix_list[i].prefix, netif_ip6_addr(prefix_list[i].netif, j))) {
+              netif_ip6_addr_set_state(prefix_list[i].netif, j, IP6_ADDR_INVALID);
+              prefix_list[i].flags = 0;
+
+              /* Exit loop. */
+              break;
+            }
+          }
+        }
+#endif
+        prefix_list[i].netif = NULL;
+        prefix_list[i].flags = 0;
+      } else {
+        prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000;
 
 #if LWIP_IPV6_AUTOCONFIG
-      /* Initiate address autoconfiguration for this prefix, if conditions are met. */
-      if (prefix_list[i].netif->ip6_autoconfig_enabled &&
-          (prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_AUTONOMOUS) &&
-          !(prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED)) {
-        s8_t j;
-        /* Try to get an address on this netif that is invalid.
-         * Skip 0 index (link-local address) */
-        for (j = 1; j < LWIP_IPV6_NUM_ADDRESSES; j++) {
-          if (netif_ip6_addr_state(prefix_list[i].netif, j) == IP6_ADDR_INVALID) {
+        /* Initiate address autoconfiguration for this prefix, if conditions are met. */
+        if (prefix_list[i].netif->ip6_autoconfig_enabled &&
+            (prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_AUTONOMOUS) &&
+            !(prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED)) {
+          s8_t j;
+          /* Try to get an address on this netif that is invalid.
+           * Skip 0 index (link-local address) */
+          for (j = 1; j < LWIP_IPV6_NUM_ADDRESSES; j++) {
+            if (netif_ip6_addr_state(prefix_list[i].netif, j) == IP6_ADDR_INVALID) {
             /* Generate an address using this prefix and interface ID from link-local address. */
-            prefix_list[i].netif->ip6_addr[j].addr[0] = prefix_list[i].prefix.addr[0];
-            prefix_list[i].netif->ip6_addr[j].addr[1] = prefix_list[i].prefix.addr[1];
-            prefix_list[i].netif->ip6_addr[j].addr[2] = prefix_list[i].netif->ip6_addr[0].addr[2];
-            prefix_list[i].netif->ip6_addr[j].addr[3] = prefix_list[i].netif->ip6_addr[0].addr[3];
+              prefix_list[i].netif->ip6_addr[j].addr[0] = prefix_list[i].prefix.addr[0];
+              prefix_list[i].netif->ip6_addr[j].addr[1] = prefix_list[i].prefix.addr[1];
+              prefix_list[i].netif->ip6_addr[j].addr[2] = prefix_list[i].netif->ip6_addr[0].addr[2];
+              prefix_list[i].netif->ip6_addr[j].addr[3] = prefix_list[i].netif->ip6_addr[0].addr[3];
 
-            /* Mark it as tentative (DAD will be performed if configured). */
-            netif_ip6_addr_set_state(prefix_list[i].netif, j, IP6_ADDR_TENTATIVE);
+              /* Mark it as tentative (DAD will be performed if configured). */
+              netif_ip6_addr_set_state(prefix_list[i].netif, j, IP6_ADDR_TENTATIVE);
 
-            /* Mark this prefix with ADDRESS_GENERATED, so that we don't try again. */
-            prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED;
+              /* Mark this prefix with ADDRESS_GENERATED, so that we don't try again. */
+              prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED;
 
-            /* Exit loop. */
-            break;
+              /* Exit loop. */
+              break;
+            }
           }
         }
-      }
 #endif /* LWIP_IPV6_AUTOCONFIG */
+      }
     }
   }
 
-- 
1.9.5.msysgit.0

