Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301 USA
- $QuaggaId: $Format:%an, %ai, %h$ $
*/
#include <zebra.h>
#include "zclient.h"
#include "stream.h"
#include "network.h"
+#include "vty.h"
+#include "plist.h"
#include "pimd.h"
#include "pim_pim.h"
return 0;
p = c->address;
- if (p->family != AF_INET)
- return 0;
-
+
if (PIM_DEBUG_ZEBRA) {
char buf[BUFSIZ];
prefix2str(p, buf, BUFSIZ);
#endif
}
+ if (p->family != AF_INET)
+ {
+ struct pim_interface *pim_ifp = c->ifp->info;
+ struct listnode *cnode;
+ struct connected *conn;
+ int v4addrs = 0;
+
+ for (ALL_LIST_ELEMENTS_RO (c->ifp->connected, cnode, conn))
+ {
+ if (conn->address->family == AF_INET)
+ v4addrs++;
+ }
+ if (!v4addrs && pim_ifp)
+ {
+ pim_ifp->primary_address = pim_find_primary_addr (c->ifp);
+ pim_if_addr_add_all (c->ifp);
+ pim_if_add_vif (c->ifp);
+ }
+ return 0;
+ }
+
pim_rp_check_rp (old, p->u.prefix4);
if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
pim_if_addr_add(c);
+ if (if_is_loopback (c->ifp))
+ {
+ struct listnode *ifnode;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
+ {
+ if (!if_is_loopback (ifp) && if_is_operative (ifp))
+ pim_if_addr_add_all (ifp);
+ }
+ }
+
return 0;
}
for (ALL_LIST_ELEMENTS(qpim_upstream_list, up_node, up_nextnode, up)) {
struct in_addr old_rpf_addr;
+ struct interface *old_interface;
enum pim_rpf_result rpf_result;
- rpf_result = pim_rpf_update(up, &old_rpf_addr, NULL);
+ old_interface = up->rpf.source_nexthop.interface;
+ rpf_result = pim_rpf_update(up, &old_rpf_addr);
if (rpf_result == PIM_RPF_FAILURE)
continue;
if (rpf_result == PIM_RPF_CHANGED) {
if (up->join_state == PIM_UPSTREAM_JOINED) {
-
+ /*
+ * If we come up real fast we can be here
+ * where the mroute has not been installed
+ * so install it.
+ */
+ if (up->channel_oil && !up->channel_oil->installed)
+ pim_mroute_add (up->channel_oil);
+
/*
RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages
/* send Prune(S,G) to the old upstream neighbor */
- pim_joinprune_send(up->rpf.source_nexthop.interface,
- old_rpf_addr,
- up->source_addr,
- up->group_addr,
- 0 /* prune */);
+ pim_joinprune_send(old_interface, old_rpf_addr,
+ &up->sg, 0 /* prune */);
/* send Join(S,G) to the current upstream neighbor */
pim_joinprune_send(up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr,
- up->source_addr,
- up->group_addr,
+ up->rpf.rpf_addr.u.prefix4,
+ &up->sg,
1 /* join */);
pim_upstream_join_timer_restart(up);
int input_iface_vif_index;
int old_vif_index;
- if (!pim_rp_set_upstream_addr (&vif_source, c_oil->oil.mfcc_origin))
+ if (!pim_rp_set_upstream_addr (&vif_source, c_oil->oil.mfcc_origin, c_oil->oil.mfcc_mcastgrp))
return;
input_iface_vif_index = fib_lookup_if_vif_index (vif_source);
zlog_debug("%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d",
__FILE__, __PRETTY_FUNCTION__,
source_str, group_str,
- old_iif ? old_iif->name : "<old_iif?>", c_oil->oil.mfcc_parent,
- new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
+ old_iif->name, c_oil->oil.mfcc_parent,
+ new_iif->name, input_iface_vif_index);
}
/* new iif loops to existing oif ? */
zlog_debug("%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d",
__FILE__, __PRETTY_FUNCTION__,
source_str, group_str,
- new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
+ new_iif->name, input_iface_vif_index);
}
del_oif(c_oil, new_iif, PIM_OIF_FLAG_PROTO_ANY);
old_vif_index = c_oil->oil.mfcc_parent;
c_oil->oil.mfcc_parent = input_iface_vif_index;
- zlog_debug ("FF");
/* update kernel multicast forwarding cache (MFC) */
if (pim_mroute_add(c_oil))
{
qpim_rpf_cache_refresh_last = pim_time_monotonic_sec();
++qpim_rpf_cache_refresh_events;
+ pim_rp_setup ();
return 0;
}
sched_rpf_cache_refresh();
+ pim_rp_setup ();
return 0;
}
__PRETTY_FUNCTION__);
}
- zassert(!qpim_zclient_lookup);
- qpim_zclient_lookup = zclient_lookup_new();
- zassert(qpim_zclient_lookup);
+ zclient_lookup_new();
}
void igmp_anysource_forward_start(struct igmp_group *group)
static int fib_lookup_if_vif_index(struct in_addr addr)
{
- struct pim_zlookup_nexthop nexthop_tab[PIM_NEXTHOP_IFINDEX_TAB_SIZE];
+ struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
int num_ifindex;
int vif_index;
ifindex_t first_ifindex;
- num_ifindex = zclient_lookup_nexthop(qpim_zclient_lookup, nexthop_tab,
- PIM_NEXTHOP_IFINDEX_TAB_SIZE, addr,
+ num_ifindex = zclient_lookup_nexthop(nexthop_tab,
+ MULTIPATH_NUM, addr,
PIM_NEXTHOP_LOOKUP_MAX);
if (num_ifindex < 1) {
char addr_str[100];
void igmp_source_forward_start(struct igmp_source *source)
{
struct igmp_group *group;
+ struct prefix_sg sg;
int result;
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = source->source_addr;
+ sg.grp = source->source_group->group_addr;
+
if (PIM_DEBUG_IGMP_TRACE) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: (S,G)=(%s,%s) igmp_sock=%d oif=%s fwd=%d",
+ zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
__PRETTY_FUNCTION__,
- source_str, group_str,
+ pim_str_sg_dump (&sg),
source->source_group->group_igmp_sock->fd,
source->source_group->group_igmp_sock->interface->name,
IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
struct in_addr vif_source;
struct pim_interface *pim_oif;
- if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr))
+ if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr, sg.grp))
return;
int input_iface_vif_index = fib_lookup_if_vif_index(vif_source);
if (input_iface_vif_index == pim_oif->mroute_vif_index) {
/* ignore request for looped MFC entry */
if (PIM_DEBUG_IGMP_TRACE) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: ignoring request for looped MFC entry (S,G)=(%s,%s): igmp_sock=%d oif=%s vif_index=%d",
+ zlog_debug("%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d",
__PRETTY_FUNCTION__,
- source_str, group_str,
+ pim_str_sg_dump (&sg),
source->source_group->group_igmp_sock->fd,
source->source_group->group_igmp_sock->interface->name,
input_iface_vif_index);
return;
}
- source->source_channel_oil = pim_channel_oil_add(group->group_addr,
- source->source_addr,
+ source->source_channel_oil = pim_channel_oil_add(&sg,
input_iface_vif_index);
if (!source->source_channel_oil) {
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s %s: could not create OIL for channel (S,G)=(%s,%s)",
+ zlog_warn("%s %s: could not create OIL for channel (S,G)=%s",
__FILE__, __PRETTY_FUNCTION__,
- source_str, group_str);
+ pim_str_sg_dump (&sg));
return;
}
}
Feed IGMPv3-gathered local membership information into PIM
per-interface (S,G) state.
*/
- pim_ifchannel_local_membership_add(group->group_igmp_sock->interface,
- source->source_addr, group->group_addr);
+ pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, &sg);
IGMP_SOURCE_DO_FORWARDING(source->source_flags);
}
void igmp_source_forward_stop(struct igmp_source *source)
{
struct igmp_group *group;
+ struct prefix_sg sg;
int result;
+ memset (&sg, 0, sizeof (struct prefix_sg));
+ sg.src = source->source_addr;
+ sg.grp = source->source_group->group_addr;
+
if (PIM_DEBUG_IGMP_TRACE) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: (S,G)=(%s,%s) igmp_sock=%d oif=%s fwd=%d",
+ zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
__PRETTY_FUNCTION__,
- source_str, group_str,
+ pim_str_sg_dump (&sg),
source->source_group->group_igmp_sock->fd,
source->source_group->group_igmp_sock->interface->name,
IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
per-interface (S,G) state.
*/
pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
- source->source_addr, group->group_addr);
+ &sg);
IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
}
char group_str[100];
char upstream_str[100];
- pim_inet4_dump("<source?>", ch->sg.u.sg.src, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", ch->sg.u.sg.grp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", ch->sg.src, source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", ch->sg.grp, group_str, sizeof(group_str));
pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str, sizeof(upstream_str));
zlog_debug("%s: (S,G)=(%s,%s) oif=%s(%s)",
__PRETTY_FUNCTION__,
int input_iface_vif_index = fib_lookup_if_vif_index(up->upstream_addr);
if (input_iface_vif_index < 1) {
char source_str[100];
- pim_inet4_dump("<source?>", up->source_addr, source_str, sizeof(source_str));
+ pim_inet4_dump("<source?>", up->sg.src, source_str, sizeof(source_str));
zlog_warn("%s %s: could not find input interface for source %s",
__FILE__, __PRETTY_FUNCTION__,
source_str);
return;
}
- up->channel_oil = pim_channel_oil_add(up->group_addr, up->source_addr,
+ up->channel_oil = pim_channel_oil_add(&up->sg,
input_iface_vif_index);
if (!up->channel_oil) {
- char group_str[100];
- char source_str[100];
- pim_inet4_dump("<group?>", up->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", up->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s %s: could not create OIL for channel (S,G)=(%s,%s)",
+ zlog_warn("%s %s: could not create OIL for channel (S,G)=%s",
__FILE__, __PRETTY_FUNCTION__,
- source_str, group_str);
+ pim_str_sg_dump (&up->sg));
return;
}
}
struct pim_upstream *up = ch->upstream;
if (PIM_DEBUG_PIM_TRACE) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", ch->sg.u.sg.src, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", ch->sg.u.sg.grp, group_str, sizeof(group_str));
- zlog_debug("%s: (S,G)=(%s,%s) oif=%s",
+ zlog_debug("%s: (S,G)=%s oif=%s",
__PRETTY_FUNCTION__,
- source_str, group_str, ch->interface->name);
+ pim_str_sg_dump (&ch->sg), ch->interface->name);
}
if (!up->channel_oil) {
- char source_str[100];
- char group_str[100];
- pim_inet4_dump("<source?>", ch->sg.u.sg.src, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", ch->sg.u.sg.grp, group_str, sizeof(group_str));
- zlog_warn("%s: (S,G)=(%s,%s) oif=%s missing channel OIL",
- __PRETTY_FUNCTION__,
- source_str, group_str, ch->interface->name);
+ zlog_warn("%s: (S,G)=%s oif=%s missing channel OIL",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&ch->sg), ch->interface->name);
return;
}