From 034db86b72933be426d220c8ff1c6d31810fb860 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 14 Jan 2022 17:52:36 +0100 Subject: [PATCH] pim6d: IPv6-adjust iface primary/DR addrs Signed-off-by: David Lamparter --- pimd/pim_bsm.c | 2 +- pimd/pim_iface.c | 80 +++++++++++++++++++++------------------------ pimd/pim_iface.h | 6 ++-- pimd/pim_neighbor.c | 21 +++++------- pimd/pim_rp.c | 6 ++-- pimd/pim_vty.c | 10 ++---- pimd/pim_zebra.c | 14 ++++---- 7 files changed, 64 insertions(+), 75 deletions(-) diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index 6702feb657..add9b7fe69 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -955,7 +955,7 @@ bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp) pim_ifp = ifp->info; /* DR only forwards BSM packet */ - if (pim_ifp->pim_dr_addr.s_addr == pim_ifp->primary_address.s_addr) { + if (!pim_addr_cmp(pim_ifp->pim_dr_addr, pim_ifp->primary_address)) { if (PIM_DEBUG_BSM) zlog_debug( "%s: It is not DR, so don't forward BSM packet", diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index bd458b479a..1cdc46df6a 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -299,27 +299,20 @@ static int detect_primary_address_change(struct interface *ifp, const char *caller) { struct pim_interface *pim_ifp = ifp->info; - struct in_addr new_prim_addr; + pim_addr new_prim_addr; int changed; if (force_prim_as_any) - new_prim_addr.s_addr = INADDR_ANY; + new_prim_addr = PIMADDR_ANY; else new_prim_addr = pim_find_primary_addr(ifp); - changed = new_prim_addr.s_addr != pim_ifp->primary_address.s_addr; + changed = pim_addr_cmp(new_prim_addr, pim_ifp->primary_address); - if (PIM_DEBUG_ZEBRA) { - char new_prim_str[INET_ADDRSTRLEN]; - char old_prim_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", new_prim_addr, new_prim_str, - sizeof(new_prim_str)); - pim_inet4_dump("", pim_ifp->primary_address, old_prim_str, - sizeof(old_prim_str)); - zlog_debug("%s: old=%s new=%s on interface %s: %s", __func__, - old_prim_str, new_prim_str, ifp->name, - changed ? "changed" : "unchanged"); - } + if (PIM_DEBUG_ZEBRA) + zlog_debug("%s: old=%pPA new=%pPA on interface %s: %s", + __func__, &pim_ifp->primary_address, &new_prim_addr, + ifp->name, changed ? "changed" : "unchanged"); if (changed) { /* Before updating pim_ifp send Hello time with 0 hold time */ @@ -401,19 +394,18 @@ static int pim_sec_addr_update(struct interface *ifp) } for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { - struct prefix *p = ifc->address; + pim_addr addr = pim_addr_from_prefix(ifc->address); - if (p->u.prefix4.s_addr == INADDR_ANY) { + if (pim_addr_is_any(addr)) continue; - } - if (pim_ifp->primary_address.s_addr == p->u.prefix4.s_addr) { + if (!pim_addr_cmp(addr, pim_ifp->primary_address)) { /* don't add the primary address into the secondary * address list */ continue; } - if (pim_sec_addr_add(pim_ifp, p)) { + if (pim_sec_addr_add(pim_ifp, ifc->address)) { changed = 1; } } @@ -480,7 +472,7 @@ static void detect_address_change(struct interface *ifp, int force_prim_as_any, * address change on all of them when the lo address changes */ } -int pim_update_source_set(struct interface *ifp, struct in_addr source) +int pim_update_source_set(struct interface *ifp, pim_addr source) { struct pim_interface *pim_ifp = ifp->info; @@ -488,7 +480,7 @@ int pim_update_source_set(struct interface *ifp, struct in_addr source) return PIM_IFACE_NOT_FOUND; } - if (pim_ifp->update_source.s_addr == source.s_addr) { + if (!pim_addr_cmp(pim_ifp->update_source, source)) { return PIM_UPDATE_SOURCE_DUP; } @@ -827,11 +819,10 @@ void pim_if_addr_del_all_igmp(struct interface *ifp) } } -struct in_addr pim_find_primary_addr(struct interface *ifp) +pim_addr pim_find_primary_addr(struct interface *ifp) { struct connected *ifc; struct listnode *node; - struct in_addr addr = {0}; int v4_addrs = 0; int v6_addrs = 0; struct pim_interface *pim_ifp = ifp->info; @@ -841,28 +832,35 @@ struct in_addr pim_find_primary_addr(struct interface *ifp) } for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { - struct prefix *p = ifc->address; + pim_addr addr; - if (p->family != AF_INET) { + switch (ifc->address->family) { + case AF_INET: + v4_addrs++; + break; + case AF_INET6: v6_addrs++; + break; + default: continue; } - if (p->u.prefix4.s_addr == INADDR_ANY) { - zlog_warn( - "%s: null IPv4 address connected to interface %s", - __func__, ifp->name); + if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) continue; - } - - v4_addrs++; - if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) + if (ifc->address->family != PIM_AF) continue; - return p->u.prefix4; + addr = pim_addr_from_prefix(ifc->address); + +#if PIM_IPV == 6 + if (!IN6_IS_ADDR_LINKLOCAL(&addr)) + continue; +#endif + return addr; } +#if PIM_IPV == 4 /* * If we have no v4_addrs and v6 is configured * We probably are using unnumbered @@ -882,10 +880,8 @@ struct in_addr pim_find_primary_addr(struct interface *ifp) if (lo_ifp && (lo_ifp != ifp)) return pim_find_primary_addr(lo_ifp); } - - addr.s_addr = PIM_NET_INADDR_ANY; - - return addr; +#endif + return PIMADDR_ANY; } static int pim_iface_next_vif_index(struct interface *ifp) @@ -1466,7 +1462,7 @@ void pim_if_create_pimreg(struct pim_instance *pim) } } -struct prefix *pim_if_connected_to_source(struct interface *ifp, struct in_addr src) +struct prefix *pim_if_connected_to_source(struct interface *ifp, pim_addr src) { struct listnode *cnode; struct connected *c; @@ -1475,12 +1471,10 @@ struct prefix *pim_if_connected_to_source(struct interface *ifp, struct in_addr if (!ifp) return NULL; - p.family = AF_INET; - p.u.prefix4 = src; - p.prefixlen = IPV4_MAX_BITLEN; + pim_addr_to_prefix(&p, src); for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) { - if (c->address->family != AF_INET) + if (c->address->family != PIM_AF) continue; if (prefix_match(c->address, &p)) return c->address; diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index 6278cb6722..00ec8e7427 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -231,7 +231,7 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp, pim_addr addr); long pim_if_t_suppressed_msec(struct interface *ifp); int pim_if_t_override_msec(struct interface *ifp); -struct in_addr pim_find_primary_addr(struct interface *ifp); +pim_addr pim_find_primary_addr(struct interface *ifp); ferr_r pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr, struct in_addr source_addr); @@ -251,8 +251,8 @@ void pim_if_update_assert_tracking_desired(struct interface *ifp); void pim_if_create_pimreg(struct pim_instance *pim); -struct prefix *pim_if_connected_to_source(struct interface *ifp, struct in_addr src); -int pim_update_source_set(struct interface *ifp, struct in_addr source); +struct prefix *pim_if_connected_to_source(struct interface *ifp, pim_addr src); +int pim_update_source_set(struct interface *ifp, pim_addr source); bool pim_if_is_vrf_device(struct interface *ifp); diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 546c210af1..6e3d2739e7 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -107,7 +107,7 @@ static void dr_election_by_pri(struct interface *ifp) int pim_if_dr_election(struct interface *ifp) { struct pim_interface *pim_ifp = ifp->info; - struct in_addr old_dr_addr; + pim_addr old_dr_addr; ++pim_ifp->pim_dr_election_count; @@ -120,18 +120,13 @@ int pim_if_dr_election(struct interface *ifp) } /* DR changed ? */ - if (old_dr_addr.s_addr != pim_ifp->pim_dr_addr.s_addr) { - - if (PIM_DEBUG_PIM_EVENTS) { - char dr_old_str[INET_ADDRSTRLEN]; - char dr_new_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", old_dr_addr, dr_old_str, - sizeof(dr_old_str)); - pim_inet4_dump("", pim_ifp->pim_dr_addr, - dr_new_str, sizeof(dr_new_str)); - zlog_debug("%s: DR was %s now is %s on interface %s", - __func__, dr_old_str, dr_new_str, ifp->name); - } + if (pim_addr_cmp(old_dr_addr, pim_ifp->pim_dr_addr)) { + + if (PIM_DEBUG_PIM_EVENTS) + zlog_debug( + "%s: DR was %pPA now is %pPA on interface %s", + __func__, &old_dr_addr, &pim_ifp->pim_dr_addr, + ifp->name); pim_ifp->pim_dr_election_last = pim_time_monotonic_sec(); /* timestamp */ diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index fb448632db..a5183c9e9b 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -322,9 +322,11 @@ static int pim_rp_check_interface_addrs(struct rp_info *rp_info, { struct listnode *node; struct pim_secondary_addr *sec_addr; + pim_addr rpf_addr; - if (pim_ifp->primary_address.s_addr - == rp_info->rp.rpf_addr.u.prefix4.s_addr) + rpf_addr = pim_addr_from_prefix(&rp_info->rp.rpf_addr); + + if (!pim_addr_cmp(pim_ifp->primary_address, rpf_addr)) return 1; if (!pim_ifp->sec_addr_list) { diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index c543c63eeb..8130aac872 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -341,13 +341,9 @@ int pim_interface_config_write(struct vty *vty) /* update source */ if (!pim_addr_is_any(pim_ifp->update_source)) { - char src_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", - pim_ifp->update_source, - src_str, - sizeof(src_str)); - vty_out(vty, " ip pim use-source %s\n", - src_str); + vty_out(vty, + " ip pim use-source %pPA\n", + &pim_ifp->update_source); ++writes; } diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index adb1ebed93..11b13db318 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -141,12 +141,14 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS) #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 (p->family != AF_INET - || primary_addr.s_addr != p->u.prefix4.s_addr) { + if (p->family != PIM_AF) + SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY); + else if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) { + /* trying to add primary address? */ + pim_addr primary_addr = pim_find_primary_addr(c->ifp); + pim_addr addr = pim_addr_from_prefix(p); + + if (pim_addr_cmp(primary_addr, addr)) { if (PIM_DEBUG_ZEBRA) zlog_warn( "%s: %s : forcing secondary flag on %pFX", -- 2.39.5