diff options
author | Everton Marques <everton.marques@gmail.com> | 2014-07-16 15:51:37 -0300 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2015-02-04 06:07:57 +0100 |
commit | 306c99eae67a7966a3994be1007f03665eb6682b (patch) | |
tree | d15449843211da7e2fc1cf05189792744a9a2256 | |
parent | f6e16b9f3592a3213e94f44b71caa311e0270cd9 (diff) | |
download | quagga-306c99eae67a7966a3994be1007f03665eb6682b.tar.bz2 quagga-306c99eae67a7966a3994be1007f03665eb6682b.tar.xz |
pimd: FIXED C14 T32 Detection of interface primary address changes may fail.
-rw-r--r-- | pimd/CAVEATS | 4 | ||||
-rw-r--r-- | pimd/TODO | 4 | ||||
-rw-r--r-- | pimd/pim_iface.c | 37 | ||||
-rw-r--r-- | pimd/pim_zebra.c | 38 |
4 files changed, 67 insertions, 16 deletions
diff --git a/pimd/CAVEATS b/pimd/CAVEATS index ba6426dd..7e2820b3 100644 --- a/pimd/CAVEATS +++ b/pimd/CAVEATS @@ -109,8 +109,8 @@ C13 Can't detect change of primary address before the actual change. See also pim_sock_delete(). -C14 Detection of interface primary address changes may fail when there - are multiple addresses. +C14 FIXED Detection of interface primary address changes may fail when + there are multiple addresses. See also TODO T32. C15 Changes in interface secondary address list are not immediately @@ -267,8 +267,8 @@ T31 If an interface changes one of its secondary IP addresses, a Hello See also CAVEAT C15. See also RFC 4601: 4.3.1. Sending Hello Messages -T32 Detection of interface primary address changes may fail when there - are multiple addresses. +T32 FIXED Detection of interface primary address changes may fail when + there are multiple addresses. See also CAVEAT C14. pim_find_primary_addr() should return interface primary address diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 72626eca..3dee7519 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -286,6 +286,7 @@ static void detect_primary_address_change(struct interface *ifp, { struct pim_interface *pim_ifp; struct in_addr new_prim_addr; + int changed; pim_ifp = ifp->info; if (!pim_ifp) @@ -293,17 +294,20 @@ static void detect_primary_address_change(struct interface *ifp, new_prim_addr = pim_find_primary_addr(ifp); + changed = new_prim_addr.s_addr != pim_ifp->primary_address.s_addr; + if (PIM_DEBUG_ZEBRA) { char new_prim_str[100]; char old_prim_str[100]; pim_inet4_dump("<new?>", new_prim_addr, new_prim_str, sizeof(new_prim_str)); pim_inet4_dump("<old?>", pim_ifp->primary_address, old_prim_str, sizeof(old_prim_str)); - zlog_debug("%s: old primary addr %s, new primary addr %s on interface %s", + zlog_debug("%s: old=%s new=%s on interface %s: %s", __PRETTY_FUNCTION__, - old_prim_str, new_prim_str, ifp->name); + old_prim_str, new_prim_str, ifp->name, + changed ? "changed" : "unchanged"); } - if (new_prim_addr.s_addr != pim_ifp->primary_address.s_addr) { + if (changed) { struct in_addr old_addr = pim_ifp->primary_address; pim_ifp->primary_address = new_prim_addr; @@ -328,6 +332,16 @@ void pim_if_addr_add(struct connected *ifc) if (!if_is_operative(ifp)) return; + if (PIM_DEBUG_ZEBRA) { + char buf[BUFSIZ]; + prefix2str(ifc->address, buf, BUFSIZ); + zlog_debug("%s: %s connected IP address %s %s", + __PRETTY_FUNCTION__, + ifp->name, buf, + CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? + "secondary" : "primary"); + } + ifaddr = ifc->address->u.prefix4; detect_primary_address_change(ifp, __PRETTY_FUNCTION__); @@ -437,6 +451,16 @@ void pim_if_addr_del(struct connected *ifc) ifp = ifc->ifp; zassert(ifp); + if (PIM_DEBUG_ZEBRA) { + char buf[BUFSIZ]; + prefix2str(ifc->address, buf, BUFSIZ); + zlog_debug("%s: %s disconnected IP address %s %s", + __PRETTY_FUNCTION__, + ifp->name, buf, + CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? + "secondary" : "primary"); + } + detect_primary_address_change(ifp, __PRETTY_FUNCTION__); pim_if_addr_del_igmp(ifc); @@ -523,7 +547,7 @@ void pim_if_addr_del_all_pim(struct interface *ifp) } } -static struct in_addr find_first_addr(struct interface *ifp) +static struct in_addr find_first_nonsec_addr(struct interface *ifp) { struct connected *ifc; struct listnode *node; @@ -541,6 +565,9 @@ static struct in_addr find_first_addr(struct interface *ifp) continue; } + if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY)) + continue; + return p->u.prefix4; } @@ -551,7 +578,7 @@ static struct in_addr find_first_addr(struct interface *ifp) struct in_addr pim_find_primary_addr(struct interface *ifp) { - return find_first_addr(ifp); + return find_first_nonsec_addr(ifp); } /* diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 820b0efc..f0aa84f0 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -203,10 +203,12 @@ static void dump_if_address(struct interface *ifp) if (p->family != AF_INET) continue; - zlog_debug("%s %s: interface %s address %s", + zlog_debug("%s %s: interface %s address %s %s", __FILE__, __PRETTY_FUNCTION__, ifp->name, - inet_ntoa(p->u.prefix4)); + inet_ntoa(p->u.prefix4), + CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? + "secondary" : "primary"); } } #endif @@ -238,15 +240,36 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient, if (PIM_DEBUG_ZEBRA) { char buf[BUFSIZ]; prefix2str(p, buf, BUFSIZ); - zlog_debug("%s: %s connected IP address %s flags %u", + zlog_debug("%s: %s connected IP address %s flags %u %s", __PRETTY_FUNCTION__, - c->ifp->name, buf, c->flags); + c->ifp->name, buf, c->flags, + CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); #ifdef PIM_DEBUG_IFADDR_DUMP dump_if_address(c->ifp); #endif } + if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) { + /* trying to add primary address */ + + struct in_addr primary_addr = pim_find_primary_addr(c->ifp); + if (primary_addr.s_addr != p->u.prefix4.s_addr) { + /* but we had a primary address already */ + + char buf[BUFSIZ]; + char old[100]; + + prefix2str(p, buf, BUFSIZ); + pim_inet4_dump("<old?>", primary_addr, old, sizeof(old)); + + zlog_warn("%s: %s primary addr old=%s: forcing secondary flag on new=%s", + __PRETTY_FUNCTION__, + c->ifp->name, old, buf); + SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY); + } + } + pim_if_addr_add(c); return 0; @@ -279,15 +302,16 @@ static int pim_zebra_if_address_del(int command, struct zclient *client, if (PIM_DEBUG_ZEBRA) { char buf[BUFSIZ]; prefix2str(p, buf, BUFSIZ); - zlog_debug("%s: %s disconnected IP address %s flags %u", + zlog_debug("%s: %s disconnected IP address %s flags %u %s", __PRETTY_FUNCTION__, - c->ifp->name, buf, c->flags); + c->ifp->name, buf, c->flags, + CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); #ifdef PIM_DEBUG_IFADDR_DUMP dump_if_address(c->ifp); #endif } - + pim_if_addr_del(c); return 0; |