mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 11:11:36 +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_iface.h"
|
||||||
#include "pim_hello.h"
|
#include "pim_hello.h"
|
||||||
#include "pim_ifchannel.h"
|
#include "pim_ifchannel.h"
|
||||||
|
#include "pim_rpf.h"
|
||||||
|
#include "pim_rp.h"
|
||||||
|
|
||||||
static void on_trace(const char *label,
|
static void on_trace(const char *label,
|
||||||
struct interface *ifp, struct in_addr src)
|
struct interface *ifp, struct in_addr src)
|
||||||
@ -76,6 +78,25 @@ static void recv_join(struct interface *ifp,
|
|||||||
/* Restart join expiry timer */
|
/* Restart join expiry timer */
|
||||||
pim_ifchannel_join_add(ifp, neigh->source_addr, upstream,
|
pim_ifchannel_join_add(ifp, neigh->source_addr, upstream,
|
||||||
&sg, source_flags, holdtime);
|
&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,
|
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);
|
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,
|
int pim_joinprune_recv(struct interface *ifp,
|
||||||
|
@ -374,6 +374,27 @@ static struct pim_upstream *pim_upstream_new(struct prefix *sg,
|
|||||||
return up;
|
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 pim_upstream *pim_upstream_find(struct prefix *sg)
|
||||||
{
|
{
|
||||||
struct listnode *up_node;
|
struct listnode *up_node;
|
||||||
|
@ -122,6 +122,7 @@ struct pim_upstream {
|
|||||||
void pim_upstream_free(struct pim_upstream *up);
|
void pim_upstream_free(struct pim_upstream *up);
|
||||||
void pim_upstream_delete(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 (struct prefix *sg);
|
||||||
|
struct pim_upstream *pim_upstream_find_non_any (struct prefix *sg);
|
||||||
struct pim_upstream *pim_upstream_add (struct prefix *sg,
|
struct pim_upstream *pim_upstream_add (struct prefix *sg,
|
||||||
struct interface *ifp);
|
struct interface *ifp);
|
||||||
void pim_upstream_del(struct pim_upstream *up);
|
void pim_upstream_del(struct pim_upstream *up);
|
||||||
|
Loading…
Reference in New Issue
Block a user