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);