mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 09:46:54 +00:00
pim6d: IPv6-adjust iface primary/DR addrs
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
01adb431d3
commit
034db86b72
@ -955,7 +955,7 @@ bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
|
|||||||
pim_ifp = ifp->info;
|
pim_ifp = ifp->info;
|
||||||
|
|
||||||
/* DR only forwards BSM packet */
|
/* 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)
|
if (PIM_DEBUG_BSM)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: It is not DR, so don't forward BSM packet",
|
"%s: It is not DR, so don't forward BSM packet",
|
||||||
|
@ -299,27 +299,20 @@ static int detect_primary_address_change(struct interface *ifp,
|
|||||||
const char *caller)
|
const char *caller)
|
||||||
{
|
{
|
||||||
struct pim_interface *pim_ifp = ifp->info;
|
struct pim_interface *pim_ifp = ifp->info;
|
||||||
struct in_addr new_prim_addr;
|
pim_addr new_prim_addr;
|
||||||
int changed;
|
int changed;
|
||||||
|
|
||||||
if (force_prim_as_any)
|
if (force_prim_as_any)
|
||||||
new_prim_addr.s_addr = INADDR_ANY;
|
new_prim_addr = PIMADDR_ANY;
|
||||||
else
|
else
|
||||||
new_prim_addr = pim_find_primary_addr(ifp);
|
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) {
|
if (PIM_DEBUG_ZEBRA)
|
||||||
char new_prim_str[INET_ADDRSTRLEN];
|
zlog_debug("%s: old=%pPA new=%pPA on interface %s: %s",
|
||||||
char old_prim_str[INET_ADDRSTRLEN];
|
__func__, &pim_ifp->primary_address, &new_prim_addr,
|
||||||
pim_inet4_dump("<new?>", new_prim_addr, new_prim_str,
|
ifp->name, changed ? "changed" : "unchanged");
|
||||||
sizeof(new_prim_str));
|
|
||||||
pim_inet4_dump("<old?>", 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 (changed) {
|
if (changed) {
|
||||||
/* Before updating pim_ifp send Hello time with 0 hold time */
|
/* 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)) {
|
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;
|
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
|
/* don't add the primary address into the secondary
|
||||||
* address list */
|
* address list */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pim_sec_addr_add(pim_ifp, p)) {
|
if (pim_sec_addr_add(pim_ifp, ifc->address)) {
|
||||||
changed = 1;
|
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 */
|
* 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;
|
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;
|
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;
|
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 connected *ifc;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct in_addr addr = {0};
|
|
||||||
int v4_addrs = 0;
|
int v4_addrs = 0;
|
||||||
int v6_addrs = 0;
|
int v6_addrs = 0;
|
||||||
struct pim_interface *pim_ifp = ifp->info;
|
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)) {
|
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++;
|
v6_addrs++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->u.prefix4.s_addr == INADDR_ANY) {
|
|
||||||
zlog_warn(
|
|
||||||
"%s: null IPv4 address connected to interface %s",
|
|
||||||
__func__, ifp->name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
v4_addrs++;
|
|
||||||
|
|
||||||
if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
|
if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return p->u.prefix4;
|
if (ifc->address->family != PIM_AF)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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
|
* If we have no v4_addrs and v6 is configured
|
||||||
* We probably are using unnumbered
|
* 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))
|
if (lo_ifp && (lo_ifp != ifp))
|
||||||
return pim_find_primary_addr(lo_ifp);
|
return pim_find_primary_addr(lo_ifp);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
addr.s_addr = PIM_NET_INADDR_ANY;
|
return PIMADDR_ANY;
|
||||||
|
|
||||||
return addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pim_iface_next_vif_index(struct interface *ifp)
|
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 listnode *cnode;
|
||||||
struct connected *c;
|
struct connected *c;
|
||||||
@ -1475,12 +1471,10 @@ struct prefix *pim_if_connected_to_source(struct interface *ifp, struct in_addr
|
|||||||
if (!ifp)
|
if (!ifp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
p.family = AF_INET;
|
pim_addr_to_prefix(&p, src);
|
||||||
p.u.prefix4 = src;
|
|
||||||
p.prefixlen = IPV4_MAX_BITLEN;
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
|
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
|
||||||
if (c->address->family != AF_INET)
|
if (c->address->family != PIM_AF)
|
||||||
continue;
|
continue;
|
||||||
if (prefix_match(c->address, &p))
|
if (prefix_match(c->address, &p))
|
||||||
return c->address;
|
return c->address;
|
||||||
|
@ -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);
|
long pim_if_t_suppressed_msec(struct interface *ifp);
|
||||||
int pim_if_t_override_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,
|
ferr_r pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr,
|
||||||
struct in_addr source_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);
|
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);
|
||||||
int pim_update_source_set(struct interface *ifp, struct in_addr source);
|
int pim_update_source_set(struct interface *ifp, pim_addr source);
|
||||||
|
|
||||||
bool pim_if_is_vrf_device(struct interface *ifp);
|
bool pim_if_is_vrf_device(struct interface *ifp);
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ static void dr_election_by_pri(struct interface *ifp)
|
|||||||
int pim_if_dr_election(struct interface *ifp)
|
int pim_if_dr_election(struct interface *ifp)
|
||||||
{
|
{
|
||||||
struct pim_interface *pim_ifp = ifp->info;
|
struct pim_interface *pim_ifp = ifp->info;
|
||||||
struct in_addr old_dr_addr;
|
pim_addr old_dr_addr;
|
||||||
|
|
||||||
++pim_ifp->pim_dr_election_count;
|
++pim_ifp->pim_dr_election_count;
|
||||||
|
|
||||||
@ -120,18 +120,13 @@ int pim_if_dr_election(struct interface *ifp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* DR changed ? */
|
/* DR changed ? */
|
||||||
if (old_dr_addr.s_addr != pim_ifp->pim_dr_addr.s_addr) {
|
if (pim_addr_cmp(old_dr_addr, pim_ifp->pim_dr_addr)) {
|
||||||
|
|
||||||
if (PIM_DEBUG_PIM_EVENTS) {
|
if (PIM_DEBUG_PIM_EVENTS)
|
||||||
char dr_old_str[INET_ADDRSTRLEN];
|
zlog_debug(
|
||||||
char dr_new_str[INET_ADDRSTRLEN];
|
"%s: DR was %pPA now is %pPA on interface %s",
|
||||||
pim_inet4_dump("<old_dr?>", old_dr_addr, dr_old_str,
|
__func__, &old_dr_addr, &pim_ifp->pim_dr_addr,
|
||||||
sizeof(dr_old_str));
|
ifp->name);
|
||||||
pim_inet4_dump("<new_dr?>", 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
pim_ifp->pim_dr_election_last =
|
pim_ifp->pim_dr_election_last =
|
||||||
pim_time_monotonic_sec(); /* timestamp */
|
pim_time_monotonic_sec(); /* timestamp */
|
||||||
|
@ -322,9 +322,11 @@ static int pim_rp_check_interface_addrs(struct rp_info *rp_info,
|
|||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct pim_secondary_addr *sec_addr;
|
struct pim_secondary_addr *sec_addr;
|
||||||
|
pim_addr rpf_addr;
|
||||||
|
|
||||||
if (pim_ifp->primary_address.s_addr
|
rpf_addr = pim_addr_from_prefix(&rp_info->rp.rpf_addr);
|
||||||
== rp_info->rp.rpf_addr.u.prefix4.s_addr)
|
|
||||||
|
if (!pim_addr_cmp(pim_ifp->primary_address, rpf_addr))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!pim_ifp->sec_addr_list) {
|
if (!pim_ifp->sec_addr_list) {
|
||||||
|
@ -341,13 +341,9 @@ int pim_interface_config_write(struct vty *vty)
|
|||||||
|
|
||||||
/* update source */
|
/* update source */
|
||||||
if (!pim_addr_is_any(pim_ifp->update_source)) {
|
if (!pim_addr_is_any(pim_ifp->update_source)) {
|
||||||
char src_str[INET_ADDRSTRLEN];
|
vty_out(vty,
|
||||||
pim_inet4_dump("<src?>",
|
" ip pim use-source %pPA\n",
|
||||||
pim_ifp->update_source,
|
&pim_ifp->update_source);
|
||||||
src_str,
|
|
||||||
sizeof(src_str));
|
|
||||||
vty_out(vty, " ip pim use-source %s\n",
|
|
||||||
src_str);
|
|
||||||
++writes;
|
++writes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,12 +141,14 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
|
if (p->family != PIM_AF)
|
||||||
/* trying to add primary address */
|
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);
|
||||||
|
|
||||||
struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
|
if (pim_addr_cmp(primary_addr, addr)) {
|
||||||
if (p->family != AF_INET
|
|
||||||
|| primary_addr.s_addr != p->u.prefix4.s_addr) {
|
|
||||||
if (PIM_DEBUG_ZEBRA)
|
if (PIM_DEBUG_ZEBRA)
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"%s: %s : forcing secondary flag on %pFX",
|
"%s: %s : forcing secondary flag on %pFX",
|
||||||
|
Loading…
Reference in New Issue
Block a user