#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)
/* 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,
}
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,
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;