mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 08:57:29 +00:00
pimd: Allow (*,G) joins to join a (s,g) that pre-exists
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
219e00134c
commit
6c62910301
@ -34,6 +34,8 @@
|
||||
#include "pim_iface.h"
|
||||
#include "pim_hello.h"
|
||||
#include "pim_ifchannel.h"
|
||||
#include "pim_rpf.h"
|
||||
#include "pim_rp.h"
|
||||
|
||||
static void on_trace(const char *label,
|
||||
struct interface *ifp, struct in_addr src)
|
||||
@ -76,6 +78,25 @@ static void recv_join(struct interface *ifp,
|
||||
/* Restart join expiry timer */
|
||||
pim_ifchannel_join_add(ifp, neigh->source_addr, upstream,
|
||||
&sg, source_flags, holdtime);
|
||||
|
||||
if (I_am_RP (group) && source.s_addr == INADDR_ANY)
|
||||
{
|
||||
struct pim_upstream *up;
|
||||
|
||||
up = pim_upstream_find_non_any (&sg);
|
||||
|
||||
if (up)
|
||||
{
|
||||
zlog_debug("%s %s: Join(S,G)=%s from %s",
|
||||
__FILE__, __PRETTY_FUNCTION__,
|
||||
pim_str_sg_dump (&up->sg), pim_str_sg_dump (&sg));
|
||||
|
||||
pim_rp_set_upstream_addr (&up->upstream_addr, up->sg.u.sg.src);
|
||||
pim_nexthop_lookup (&up->rpf.source_nexthop, up->upstream_addr, NULL);
|
||||
pim_ifchannel_join_add (ifp, neigh->source_addr, upstream, &up->sg, source_flags, holdtime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void recv_prune(struct interface *ifp,
|
||||
@ -106,6 +127,22 @@ static void recv_prune(struct interface *ifp,
|
||||
}
|
||||
|
||||
pim_ifchannel_prune(ifp, upstream, &sg, source_flags, holdtime);
|
||||
|
||||
if (I_am_RP (group) && source.s_addr == INADDR_ANY)
|
||||
{
|
||||
struct pim_upstream *up;
|
||||
|
||||
up = pim_upstream_find_non_any (&sg);
|
||||
|
||||
if (up)
|
||||
{
|
||||
zlog_debug("%s %s: Prune(S,G)=%s from %s",
|
||||
__FILE__, __PRETTY_FUNCTION__,
|
||||
pim_str_sg_dump (&up->sg), pim_str_sg_dump (&sg));
|
||||
pim_ifchannel_prune (ifp, upstream, &up->sg, source_flags, holdtime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int pim_joinprune_recv(struct interface *ifp,
|
||||
|
@ -374,6 +374,27 @@ static struct pim_upstream *pim_upstream_new(struct prefix *sg,
|
||||
return up;
|
||||
}
|
||||
|
||||
/*
|
||||
* For a given sg, find any non * source
|
||||
*/
|
||||
struct pim_upstream *pim_upstream_find_non_any (struct prefix *sg)
|
||||
{
|
||||
struct listnode *up_node;
|
||||
struct prefix any = *sg;
|
||||
struct pim_upstream *up;
|
||||
|
||||
any.u.sg.src.s_addr = INADDR_ANY;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (qpim_upstream_list, up_node, up))
|
||||
{
|
||||
if ((any.u.sg.grp.s_addr == up->sg.u.sg.grp.s_addr) &&
|
||||
(up->sg.u.sg.src.s_addr != any.u.sg.src.s_addr))
|
||||
return up;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct pim_upstream *pim_upstream_find(struct prefix *sg)
|
||||
{
|
||||
struct listnode *up_node;
|
||||
|
@ -122,6 +122,7 @@ struct pim_upstream {
|
||||
void pim_upstream_free(struct pim_upstream *up);
|
||||
void pim_upstream_delete(struct pim_upstream *up);
|
||||
struct pim_upstream *pim_upstream_find (struct prefix *sg);
|
||||
struct pim_upstream *pim_upstream_find_non_any (struct prefix *sg);
|
||||
struct pim_upstream *pim_upstream_add (struct prefix *sg,
|
||||
struct interface *ifp);
|
||||
void pim_upstream_del(struct pim_upstream *up);
|
||||
|
Loading…
Reference in New Issue
Block a user