pimd: React as secondary address change for any address change
diff --git a/pimd/CAVEATS b/pimd/CAVEATS
index 7e2820b..9f07bda 100644
--- a/pimd/CAVEATS
+++ b/pimd/CAVEATS
@@ -115,6 +115,7 @@
 
 C15 Changes in interface secondary address list are not immediately
     detected.
+    See also detect_secondary_address_change
     See also TODO T31.
 
 C16 AMT Draft (mboned-auto-multicast) is not supported.
diff --git a/pimd/TODO b/pimd/TODO
index 80835e4..2308573 100644
--- a/pimd/TODO
+++ b/pimd/TODO
@@ -264,6 +264,7 @@
 T31 If an interface changes one of its secondary IP addresses, a Hello
     message with an updated Address_List option and a non-zero
     HoldTime should be sent immediately.
+    See also detect_secondary_address_change
     See also CAVEAT C15.
     See also RFC 4601: 4.3.1.  Sending Hello Messages
 
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index fdbb79b..770bd4e 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -273,17 +273,20 @@
   }
 
   pim_ifp = ifp->info;
-
-  if (pim_ifp) {
-    if (PIM_IF_TEST_PIM(pim_ifp->options)) {
-      pim_addr_change(ifp);
-    }
+  if (!pim_ifp) {
+    return;
   }
+
+  if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
+    return;
+  }
+
+  pim_addr_change(ifp);
 }
 
-static void detect_primary_address_change(struct interface *ifp,
-					  int force_prim_as_any,
-					  const char *caller)
+static int detect_primary_address_change(struct interface *ifp,
+					 int force_prim_as_any,
+					 const char *caller)
 {
   struct pim_interface *pim_ifp;
   struct in_addr new_prim_addr;
@@ -291,7 +294,7 @@
 
   pim_ifp = ifp->info;
   if (!pim_ifp)
-    return;
+    return 0;
 
   if (force_prim_as_any)
     new_prim_addr = qpim_inaddr_any;
@@ -317,6 +320,55 @@
 
     on_primary_address_change(ifp, caller, old_addr, new_prim_addr);
   }
+
+  return changed;
+}
+
+static void detect_secondary_address_change(struct interface *ifp,
+					    const char *caller)
+{
+  struct pim_interface *pim_ifp;
+  int changed;
+
+  pim_ifp = ifp->info;
+  if (!pim_ifp)
+    return;
+
+  changed = 1; /* true */
+  zlog_debug("FIXME T31 C15 %s: on interface %s: acting on any addr change",
+	     __PRETTY_FUNCTION__, ifp->name);
+
+  if (PIM_DEBUG_ZEBRA) {
+    zlog_debug("%s: on interface %s: %s",
+	       __PRETTY_FUNCTION__, 
+	       ifp->name, changed ? "changed" : "unchanged");
+  }
+
+  if (!changed) {
+    return;
+  }
+
+  if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
+    return;
+  }
+
+  pim_addr_change(ifp);
+}
+
+static void detect_address_change(struct interface *ifp,
+				 int force_prim_as_any,
+				 const char *caller)
+{
+  int prim_changed;
+
+  prim_changed = detect_primary_address_change(ifp, force_prim_as_any, caller);
+  if (prim_changed) {
+    /* no need to detect secondary change because
+       the reaction would be the same */
+    return;
+  }
+
+  detect_secondary_address_change(ifp, caller);
 }
 
 void pim_if_addr_add(struct connected *ifc)
@@ -348,7 +400,7 @@
 
   ifaddr = ifc->address->u.prefix4;
 
-  detect_primary_address_change(ifp, 0, __PRETTY_FUNCTION__);
+  detect_address_change(ifp, 0, __PRETTY_FUNCTION__);
 
   if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
     struct igmp_sock *igmp;
@@ -465,7 +517,7 @@
 	       "secondary" : "primary");
   }
 
-  detect_primary_address_change(ifp, force_prim_as_any, __PRETTY_FUNCTION__);
+  detect_address_change(ifp, force_prim_as_any, __PRETTY_FUNCTION__);
 
   pim_if_addr_del_igmp(ifc);
   pim_if_addr_del_pim(ifc);