mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-02 22:24:23 +00:00
pimd: Allow SPT switchover
This allows SPT switchover for S,G upon receipt of packets on the LHR. 1) When we create a *,G from a IGMP Group Report, install the *,G route with the pimreg device on the OIL. 2) When a packet hits the LHR that matches the *,G, we will get a WHOLEPKT callback from the kernel and if we cannot find the S,G, that means we have matched it on the LHR via the *,G mroute. Create the S,G start the KAT and run inherited_olist. 3) When the S,G times out, safely remove the S,G via the KAT expiry 4) When the *,G is removed, remove any S,G associated with it via the LHR flag. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
0e374d906d
commit
850a9f99b8
@ -1006,6 +1006,7 @@ pim_ifchannel_local_membership_add(struct interface *ifp,
|
|||||||
pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
|
pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pim_channel_add_oif(up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -200,6 +200,23 @@ pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const char *buf)
|
|||||||
|
|
||||||
up = pim_upstream_find(&sg);
|
up = pim_upstream_find(&sg);
|
||||||
if (!up) {
|
if (!up) {
|
||||||
|
struct prefix_sg star = sg;
|
||||||
|
star.src.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
up = pim_upstream_find(&star);
|
||||||
|
|
||||||
|
if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags))
|
||||||
|
{
|
||||||
|
up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_SRC_LHR, __PRETTY_FUNCTION__);
|
||||||
|
pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
|
||||||
|
pim_upstream_inherited_olist (up);
|
||||||
|
pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
|
||||||
|
|
||||||
|
if (PIM_DEBUG_MROUTE)
|
||||||
|
zlog_debug ("%s: Creating %s upstream on LHR",
|
||||||
|
__PRETTY_FUNCTION__, up->sg_str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (PIM_DEBUG_MROUTE_DETAIL) {
|
if (PIM_DEBUG_MROUTE_DETAIL) {
|
||||||
zlog_debug("%s: Unable to find upstream channel WHOLEPKT%s",
|
zlog_debug("%s: Unable to find upstream channel WHOLEPKT%s",
|
||||||
__PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
|
__PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
|
||||||
|
@ -198,7 +198,20 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
|
|||||||
upstream_channel_oil_detach(up);
|
upstream_channel_oil_detach(up);
|
||||||
|
|
||||||
if (up->sources)
|
if (up->sources)
|
||||||
list_delete (up->sources);
|
{
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct pim_upstream *child;
|
||||||
|
for (ALL_LIST_ELEMENTS (up->sources, node, nnode, child))
|
||||||
|
{
|
||||||
|
if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
|
||||||
|
{
|
||||||
|
PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
|
||||||
|
pim_upstream_del(child, __PRETTY_FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_delete (up->sources);
|
||||||
|
}
|
||||||
up->sources = NULL;
|
up->sources = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1083,26 +1096,31 @@ pim_upstream_keep_alive_timer (struct thread *t)
|
|||||||
up->t_ka_timer = NULL;
|
up->t_ka_timer = NULL;
|
||||||
|
|
||||||
if (I_am_RP (up->sg.grp))
|
if (I_am_RP (up->sg.grp))
|
||||||
{
|
{
|
||||||
pim_br_clear_pmbr (&up->sg);
|
pim_br_clear_pmbr (&up->sg);
|
||||||
/*
|
/*
|
||||||
* We need to do more here :)
|
* We need to do more here :)
|
||||||
* But this is the start.
|
* But this is the start.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* source is no longer active - pull the SA from MSDP's cache */
|
/* source is no longer active - pull the SA from MSDP's cache */
|
||||||
pim_msdp_sa_local_del(&up->sg);
|
pim_msdp_sa_local_del(&up->sg);
|
||||||
|
|
||||||
/* if entry was created because of activity we need to deref it */
|
/* if entry was created because of activity we need to deref it */
|
||||||
if (PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
|
if (PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
|
||||||
{
|
{
|
||||||
pim_upstream_fhr_kat_expiry(up);
|
pim_upstream_fhr_kat_expiry(up);
|
||||||
if (PIM_DEBUG_TRACE)
|
if (PIM_DEBUG_TRACE)
|
||||||
zlog_debug ("kat expired on %s; remove stream reference", up->sg_str);
|
zlog_debug ("kat expired on %s; remove stream reference", up->sg_str);
|
||||||
PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags);
|
PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags);
|
||||||
pim_upstream_del(up, __PRETTY_FUNCTION__);
|
pim_upstream_del(up, __PRETTY_FUNCTION__);
|
||||||
}
|
}
|
||||||
|
else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags))
|
||||||
|
{
|
||||||
|
PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(up->flags);
|
||||||
|
pim_upstream_del(up, __PRETTY_FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1633,25 +1651,28 @@ pim_upstream_sg_running (void *arg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pim_upstream_kat_start_ok(up)) {
|
if (pim_upstream_kat_start_ok(up))
|
||||||
/* Add a source reference to the stream if
|
|
||||||
* one doesn't already exist */
|
|
||||||
if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
|
|
||||||
{
|
{
|
||||||
if (PIM_DEBUG_TRACE)
|
/* Add a source reference to the stream if
|
||||||
zlog_debug ("source reference created on kat restart %s", up->sg_str);
|
* one doesn't already exist */
|
||||||
|
if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
|
||||||
|
{
|
||||||
|
if (PIM_DEBUG_TRACE)
|
||||||
|
zlog_debug ("source reference created on kat restart %s", up->sg_str);
|
||||||
|
|
||||||
pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM);
|
pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM);
|
||||||
PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
|
PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
|
||||||
pim_upstream_fhr_kat_start(up);
|
pim_upstream_fhr_kat_start(up);
|
||||||
|
}
|
||||||
|
pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
|
||||||
}
|
}
|
||||||
|
else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags))
|
||||||
pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
|
pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
|
||||||
}
|
|
||||||
|
|
||||||
if (up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE)
|
if (up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE)
|
||||||
{
|
{
|
||||||
pim_upstream_set_sptbit(up, up->rpf.source_nexthop.interface);
|
pim_upstream_set_sptbit(up, up->rpf.source_nexthop.interface);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
#define PIM_UPSTREAM_FLAG_MASK_SRC_STREAM (1 << 5)
|
#define PIM_UPSTREAM_FLAG_MASK_SRC_STREAM (1 << 5)
|
||||||
#define PIM_UPSTREAM_FLAG_MASK_SRC_MSDP (1 << 6)
|
#define PIM_UPSTREAM_FLAG_MASK_SRC_MSDP (1 << 6)
|
||||||
#define PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE (1 << 7)
|
#define PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE (1 << 7)
|
||||||
|
#define PIM_UPSTREAM_FLAG_MASK_SRC_LHR (1 << 8)
|
||||||
|
#define PIM_UPSTREAM_FLAG_ALL 0xFFFFFFFF
|
||||||
|
|
||||||
#define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
|
#define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
|
||||||
#define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
|
#define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
|
||||||
@ -43,6 +45,7 @@
|
|||||||
#define PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
|
#define PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
|
||||||
#define PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
|
#define PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
|
||||||
#define PIM_UPSTREAM_FLAG_TEST_SEND_SG_RPT_PRUNE(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
|
#define PIM_UPSTREAM_FLAG_TEST_SEND_SG_RPT_PRUNE(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
|
||||||
|
#define PIM_UPSTREAM_FLAG_TEST_SRC_LHR(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
|
||||||
|
|
||||||
#define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
|
#define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
|
||||||
#define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
|
#define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
|
||||||
@ -52,6 +55,7 @@
|
|||||||
#define PIM_UPSTREAM_FLAG_SET_SRC_STREAM(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
|
#define PIM_UPSTREAM_FLAG_SET_SRC_STREAM(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
|
||||||
#define PIM_UPSTREAM_FLAG_SET_SRC_MSDP(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
|
#define PIM_UPSTREAM_FLAG_SET_SRC_MSDP(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
|
||||||
#define PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
|
#define PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
|
||||||
|
#define PIM_UPSTREAM_FLAG_SET_SRC_LHR(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
|
||||||
|
|
||||||
#define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
|
#define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
|
||||||
#define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
|
#define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
|
||||||
@ -61,6 +65,7 @@
|
|||||||
#define PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
|
#define PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
|
||||||
#define PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
|
#define PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
|
||||||
#define PIM_UPSTREAM_FLAG_UNSET_SEND_SG_RPT_PRUNE(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
|
#define PIM_UPSTREAM_FLAG_UNSET_SEND_SG_RPT_PRUNE(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
|
||||||
|
#define PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
|
||||||
|
|
||||||
enum pim_upstream_state {
|
enum pim_upstream_state {
|
||||||
PIM_UPSTREAM_NOTJOINED,
|
PIM_UPSTREAM_NOTJOINED,
|
||||||
|
Loading…
Reference in New Issue
Block a user