mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 14:17:20 +00:00
pimd: Fixup tracking of where we got OIF's from.
This commit does these three things: 1) Add code to 'show ip pim state' to show where OIF's got their decision to include that interface 2) Add code in pim_mroute_[add|del] to display what we think we are adding to the kernel 3) Add code to properly track where we got the incoming request from and to appropriately not remove a OIL if we have state still Ticket: CM-14034 Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Don Slice <dslice@cumulusnetworks.com> Reviewed-by: Chirag Shah <chirag@cumulusnetworks.com>
This commit is contained in:
parent
8613585e1f
commit
781a1745c0
@ -1367,7 +1367,8 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
|
||||
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)) {
|
||||
@ -1379,9 +1380,6 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
|
||||
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);
|
||||
@ -1426,7 +1424,8 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
|
||||
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);
|
||||
@ -1455,16 +1454,25 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
|
||||
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) ? '*' : ' ' );
|
||||
}
|
||||
}
|
||||
|
||||
@ -2963,6 +2971,9 @@ static void show_mroute(struct vty *vty, u_char uj)
|
||||
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);
|
||||
@ -2987,6 +2998,10 @@ static void show_mroute(struct vty *vty, u_char uj)
|
||||
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,
|
||||
|
@ -153,7 +153,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,7 +270,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
|
||||
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
|
||||
@ -278,7 +278,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
|
||||
* 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)
|
||||
@ -292,7 +292,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -964,7 +964,7 @@ void pim_ifchannel_local_membership_add(struct interface *ifp,
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1008,7 +1008,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
|
||||
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
|
||||
@ -1016,7 +1016,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
|
||||
* 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);
|
||||
|
@ -812,13 +812,10 @@ int pim_mroute_add(struct channel_oil *c_oil, const char *name)
|
||||
|
||||
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;
|
||||
@ -850,14 +847,12 @@ int pim_mroute_del (struct channel_oil *c_oil, const char *name)
|
||||
|
||||
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;
|
||||
|
@ -36,6 +36,31 @@
|
||||
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)
|
||||
{
|
||||
@ -353,25 +378,26 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
@ -29,13 +29,16 @@
|
||||
* 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.
|
||||
@ -96,4 +99,6 @@ int pim_channel_del_oif (struct channel_oil *c_oil,
|
||||
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 */
|
||||
|
@ -1288,7 +1288,11 @@ pim_upstream_inherited_olist_decide (struct pim_upstream *up)
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user