if (uj) {
json = json_object_new_object();
} else {
- vty_out(vty, "%sSource Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE);
+ vty_out(vty, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
+ vty_out(vty, "%sInstalled Source Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE);
}
for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
struct interface *ifp_in;
first_oif = 1;
- if (!c_oil->installed)
- continue;
-
pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
json_object_object_add(json_source, in_ifname, json_ifp_in);
}
} else {
- vty_out(vty, "%-15s %-15s %-5s ",
+ vty_out(vty, "%-9d %-15s %-15s %-7s ",
+ c_oil->installed,
src_str,
grp_str,
ifp_in->name);
json_object_string_add(json_ifp_out, "group", grp_str);
json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
+ json_object_int_add(json_ifp_out, "installed", c_oil->installed);
json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
} else {
if (first_oif)
{
first_oif = 0;
- vty_out(vty, "%s", out_ifname);
+ vty_out(vty, "%s(%c%c%c%c)", out_ifname,
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ');
}
else
- vty_out(vty, ",%s", out_ifname);
+ vty_out(vty, ", %s(%c%c%c%c)", out_ifname,
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
+ (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ' );
}
}
if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE)
json_object_boolean_true_add(json_ifp_out, "protocolSource");
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR)
+ json_object_boolean_true_add(json_ifp_out, "protocolInherited");
+
json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
strcpy(proto, "SRC");
}
+ if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) {
+ strcpy(proto, "STAR");
+ }
+
vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
src_str,
grp_str,
struct listnode *up_node;
for (ALL_LIST_ELEMENTS_RO (ch->upstream->sources, up_node, child))
- pim_channel_del_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+ pim_channel_del_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
}
}
continue;
if (!pim_upstream_evaluate_join_desired (child))
- pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+ pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
/*
* If the S,G has no if channel and the c_oil still
* if channel. So remove it.
*/
if (!ch && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
- pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+ pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
}
}
if (ch->ifjoin_state == PIM_IFJOIN_JOIN)
if (pim_upstream_evaluate_join_desired (child))
{
- pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+ pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
}
}
if (pim_upstream_evaluate_join_desired (child))
{
- pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_PIM);
+ pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
}
}
up->sg_str, ifp->name, child->sg_str);
if (c_oil && !pim_upstream_evaluate_join_desired (child))
- pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_PIM);
+ pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
/*
* If the S,G has no if channel and the c_oil still
* if channel. So remove it.
*/
if (!chchannel && c_oil && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
- pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_PIM);
+ pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
}
}
delete_on_noinfo(ch);
if (PIM_DEBUG_MROUTE)
{
- struct prefix_sg sg;
-
- sg.src = c_oil->oil.mfcc_origin;
- sg.grp = c_oil->oil.mfcc_mcastgrp;
-
- zlog_debug("%s(%s), Added Route: %s to mroute table",
- __PRETTY_FUNCTION__, name, pim_str_sg_dump(&sg));
+ char buf[1000];
+ zlog_debug("%s(%s), Added Route: %s",
+ __PRETTY_FUNCTION__, name,
+ pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
}
c_oil->installed = 1;
if (PIM_DEBUG_MROUTE)
{
- struct prefix_sg sg;
-
- sg.src = c_oil->oil.mfcc_origin;
- sg.grp = c_oil->oil.mfcc_mcastgrp;
-
- zlog_debug("%s(%s), Deleted Route: %s from mroute table",
- __PRETTY_FUNCTION__, name, pim_str_sg_dump(&sg));
+ char buf[1000];
+ zlog_debug("%s(%s), Deleted Route: %s",
+ __PRETTY_FUNCTION__, name,
+ pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
}
+
c_oil->installed = 0;
return 0;
struct list *pim_channel_oil_list = NULL;
struct hash *pim_channel_oil_hash = NULL;
+char *
+pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size)
+{
+ struct prefix_sg sg;
+ int i;
+
+ memset (buf, 0, size);
+ sg.src = c_oil->oil.mfcc_origin;
+ sg.grp = c_oil->oil.mfcc_mcastgrp;
+ sprintf(buf, "%s IIF: %d, OIFS: ",
+ pim_str_sg_dump (&sg), c_oil->oil.mfcc_parent);
+
+ for (i = 0 ; i < MAXVIFS ; i++)
+ {
+ if (c_oil->oil.mfcc_ttls[i] != 0)
+ {
+ char buf1[10];
+ sprintf(buf1, "%d ", i);
+ strcat(buf, buf1);
+ }
+ }
+
+ return buf;
+}
+
static int
pim_channel_oil_compare (struct channel_oil *c1, struct channel_oil *c2)
{
}
/* Allow other protocol to request subscription of same interface to
- channel (S,G) multiple times, by silently ignoring further
- requests */
+ * channel (S,G), we need to note this information
+ */
if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & PIM_OIF_FLAG_PROTO_ANY) {
+ channel_oil->oif_creation[pim_ifp->mroute_vif_index] = pim_time_monotonic_sec();
+ channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
/* Check the OIF really exists before returning, and only log
warning otherwise */
if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) {
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- proto_mask, oif->name, pim_ifp->mroute_vif_index,
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
- source_str, group_str);
- }
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ zlog_warn("%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ proto_mask, oif->name, pim_ifp->mroute_vif_index,
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
}
return 0;
* IGMP - Learned from IGMP
* PIM - Learned from PIM
* SOURCE - Learned from Source multicast packet received
+ * STAR - Inherited
*/
#define PIM_OIF_FLAG_PROTO_IGMP (1 << 0)
#define PIM_OIF_FLAG_PROTO_PIM (1 << 1)
-#define PIM_OIF_FLAG_PROTO_SOURCE (2 << 1)
+#define PIM_OIF_FLAG_PROTO_SOURCE (1 << 2)
+#define PIM_OIF_FLAG_PROTO_STAR (1 << 3)
#define PIM_OIF_FLAG_PROTO_ANY (PIM_OIF_FLAG_PROTO_IGMP | \
PIM_OIF_FLAG_PROTO_PIM | \
- PIM_OIF_FLAG_PROTO_SOURCE)
+ PIM_OIF_FLAG_PROTO_SOURCE | \
+ PIM_OIF_FLAG_PROTO_STAR)
/*
* We need a pimreg vif id from the kernel.
uint32_t proto_mask);
int pim_channel_oil_empty (struct channel_oil *c_oil);
+
+char *pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size);
#endif /* PIM_OIL_H */
if (pim_upstream_evaluate_join_desired_interface (up, ch))
{
- pim_channel_add_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+ int flag = PIM_OIF_FLAG_PROTO_PIM;
+
+ if (ch->sg.src.s_addr == INADDR_ANY && ch->upstream != up)
+ flag = PIM_OIF_FLAG_PROTO_STAR;
+ pim_channel_add_oif (up->channel_oil, ch->interface, flag);
output_intf++;
}
}