mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 22:50:14 +00:00
pimd: Allow ifchannel S,G's to know their *,G parent
Given a S,G ifchannel, create a parent pointer for any *,G state for that interface. When removing a *,G remove S,G pointers. We need to think about the case where their is a *,G but no S,G for a interface when we are determing. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
6997705858
commit
1a10fc742f
@ -38,6 +38,65 @@
|
|||||||
#include "pim_rpf.h"
|
#include "pim_rpf.h"
|
||||||
#include "pim_macro.h"
|
#include "pim_macro.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A (*,G) or a (*,*) is going away
|
||||||
|
* remove the parent pointer from
|
||||||
|
* those pointing at us
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
pim_ifchannel_remove_children (struct pim_ifchannel *ch)
|
||||||
|
{
|
||||||
|
struct pim_interface *pim_ifp = ch->interface->info;
|
||||||
|
struct listnode *ch_node;
|
||||||
|
struct pim_ifchannel *child;
|
||||||
|
|
||||||
|
// Basic sanity, (*,*) not currently supported
|
||||||
|
if ((ch->sg.u.sg.src.s_addr == INADDR_ANY) &&
|
||||||
|
(ch->sg.u.sg.grp.s_addr == INADDR_ANY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Basic sanity (S,G) have no children
|
||||||
|
if ((ch->sg.u.sg.src.s_addr != INADDR_ANY) &&
|
||||||
|
(ch->sg.u.sg.grp.s_addr != INADDR_ANY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (pim_ifp->pim_ifchannel_list, ch_node, child))
|
||||||
|
{
|
||||||
|
if (child->parent == ch)
|
||||||
|
child->parent = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A (*,G) or a (*,*) is being created
|
||||||
|
* find all the children that would point
|
||||||
|
* at us.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
pim_ifchannel_find_new_children (struct pim_ifchannel *ch)
|
||||||
|
{
|
||||||
|
struct pim_interface *pim_ifp = ch->interface->info;
|
||||||
|
struct pim_ifchannel *child;
|
||||||
|
struct listnode *ch_node;
|
||||||
|
|
||||||
|
// Basic Sanity that we are not being silly
|
||||||
|
if ((ch->sg.u.sg.src.s_addr != INADDR_ANY) &&
|
||||||
|
(ch->sg.u.sg.grp.s_addr != INADDR_ANY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((ch->sg.u.sg.src.s_addr == INADDR_ANY) &&
|
||||||
|
(ch->sg.u.sg.grp.s_addr == INADDR_ANY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (pim_ifp->pim_ifchannel_list, ch_node, child))
|
||||||
|
{
|
||||||
|
if ((ch->sg.u.sg.grp.s_addr != INADDR_ANY) &&
|
||||||
|
(child->sg.u.sg.grp.s_addr == ch->sg.u.sg.grp.s_addr) &&
|
||||||
|
(child != ch))
|
||||||
|
child->parent = ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pim_ifchannel_free(struct pim_ifchannel *ch)
|
void pim_ifchannel_free(struct pim_ifchannel *ch)
|
||||||
{
|
{
|
||||||
zassert(!ch->t_ifjoin_expiry_timer);
|
zassert(!ch->t_ifjoin_expiry_timer);
|
||||||
@ -54,6 +113,13 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
|
|||||||
pim_ifp = ch->interface->info;
|
pim_ifp = ch->interface->info;
|
||||||
zassert(pim_ifp);
|
zassert(pim_ifp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When this channel is removed
|
||||||
|
* we need to find all our children
|
||||||
|
* and make sure our pointers are fixed
|
||||||
|
*/
|
||||||
|
pim_ifchannel_remove_children (ch);
|
||||||
|
|
||||||
if (ch->ifjoin_state != PIM_IFJOIN_NOINFO) {
|
if (ch->ifjoin_state != PIM_IFJOIN_NOINFO) {
|
||||||
pim_upstream_update_join_desired(ch->upstream);
|
pim_upstream_update_join_desired(ch->upstream);
|
||||||
}
|
}
|
||||||
@ -260,8 +326,41 @@ void pim_ifchannel_delete_on_noinfo(struct interface *ifp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
|
/*
|
||||||
struct prefix *sg)
|
* For a given Interface, if we are given a S,G
|
||||||
|
* Find the *,G (If we have it).
|
||||||
|
* If we are passed a *,G, find the *,* ifchannel
|
||||||
|
* if we have it.
|
||||||
|
*/
|
||||||
|
static struct pim_ifchannel *
|
||||||
|
pim_ifchannel_find_parent (struct interface *ifp,
|
||||||
|
struct prefix *sg)
|
||||||
|
{
|
||||||
|
struct prefix parent_sg = *sg;
|
||||||
|
|
||||||
|
// (*,*) || (S,*)
|
||||||
|
if (((sg->u.sg.src.s_addr == INADDR_ANY) &&
|
||||||
|
(sg->u.sg.grp.s_addr == INADDR_ANY)) ||
|
||||||
|
((sg->u.sg.src.s_addr != INADDR_ANY) &&
|
||||||
|
(sg->u.sg.grp.s_addr == INADDR_ANY)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// (S,G)
|
||||||
|
if ((sg->u.sg.src.s_addr != INADDR_ANY) &&
|
||||||
|
(sg->u.sg.grp.s_addr != INADDR_ANY))
|
||||||
|
{
|
||||||
|
parent_sg.u.sg.src.s_addr = INADDR_ANY;
|
||||||
|
return pim_ifchannel_find (ifp, &parent_sg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// (*,G) -- Not going to find anything currently
|
||||||
|
parent_sg.u.sg.grp.s_addr = INADDR_ANY;
|
||||||
|
return pim_ifchannel_find (ifp, &parent_sg);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pim_ifchannel *
|
||||||
|
pim_ifchannel_add(struct interface *ifp,
|
||||||
|
struct prefix *sg)
|
||||||
{
|
{
|
||||||
struct pim_interface *pim_ifp;
|
struct pim_interface *pim_ifp;
|
||||||
struct pim_ifchannel *ch;
|
struct pim_ifchannel *ch;
|
||||||
@ -295,6 +394,8 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
|
|||||||
ch->upstream = up;
|
ch->upstream = up;
|
||||||
ch->interface = ifp;
|
ch->interface = ifp;
|
||||||
ch->sg = *sg;
|
ch->sg = *sg;
|
||||||
|
ch->parent = pim_ifchannel_find_parent (ifp, sg);
|
||||||
|
pim_ifchannel_find_new_children (ch);
|
||||||
ch->local_ifmembership = PIM_IFMEMBERSHIP_NOINFO;
|
ch->local_ifmembership = PIM_IFMEMBERSHIP_NOINFO;
|
||||||
|
|
||||||
ch->ifjoin_state = PIM_IFJOIN_NOINFO;
|
ch->ifjoin_state = PIM_IFJOIN_NOINFO;
|
||||||
|
@ -73,6 +73,7 @@ struct pim_assert_metric {
|
|||||||
Per-interface (S,G) state
|
Per-interface (S,G) state
|
||||||
*/
|
*/
|
||||||
struct pim_ifchannel {
|
struct pim_ifchannel {
|
||||||
|
struct pim_ifchannel *parent;
|
||||||
struct prefix sg;
|
struct prefix sg;
|
||||||
struct interface *interface; /* backpointer to interface */
|
struct interface *interface; /* backpointer to interface */
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
Loading…
Reference in New Issue
Block a user