From 1865a44a8336ffd2e890268bb6da117d933147c7 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 28 Oct 2015 11:00:37 -0700 Subject: [PATCH] pimd: Move add_oif into pim_oil.c This commit does two things: (A) Sets up #defines for the pimreg to be used in pim_mroute.c (B) Moves add_oif into pim_oil.c where it belongs Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 2 +- pimd/pim_mroute.c | 4 +- pimd/pim_mroute.h | 2 +- pimd/pim_oil.c | 142 ++++++++++++++++++++++++++++++++++++++++++ pimd/pim_oil.h | 15 +++++ pimd/pim_zebra.c | 154 ++-------------------------------------------- 6 files changed, 167 insertions(+), 152 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 705aa72ead..a82c02de0f 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2143,7 +2143,7 @@ DEFUN (show_ip_multicast, qpim_mroute_oif_highest_vif_index, VTY_NEWLINE); vty_out(vty, "Maximum highest VifIndex: %d%s", - MAXVIFS - 2, + PIM_MAX_USABLE_VIFS, VTY_NEWLINE); vty_out(vty, "%s", VTY_NEWLINE); diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index cdd2dbc6dd..70e7712a16 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -103,7 +103,7 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg mc.mfcc_origin = msg->im_src; mc.mfcc_mcastgrp = msg->im_dst; mc.mfcc_parent = ifp->ifindex; - mc.mfcc_ttls[MAXVIFS-1] = 1; + mc.mfcc_ttls[PIM_OIF_PIM_REGISTER_VIF] = 1; pim_mroute_add(&mc); return 0; } @@ -379,7 +379,7 @@ int pim_mroute_socket_enable() } qpim_mroute_socket_fd = fd; - pim_mroute_add_vif(MAXVIFS-1, pimreg, VIFF_REGISTER); + pim_mroute_add_vif(PIM_OIF_PIM_REGISTER_VIF, pimreg, VIFF_REGISTER); qpim_mroute_socket_creation = pim_time_monotonic_sec(); mroute_read_on(); diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h index c6fd19b22c..a32c792d78 100644 --- a/pimd/pim_mroute.h +++ b/pimd/pim_mroute.h @@ -48,7 +48,7 @@ */ #ifndef MAXVIFS -#define MAXVIFS (32) +#define MAXVIFS (256) #endif #ifndef SIOCGETVIFCNT diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index 1aaece3f45..c366285620 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -138,3 +138,145 @@ void pim_channel_oil_del(struct channel_oil *c_oil) pim_channel_oil_delete(c_oil); } } + +int pim_channel_add_oif(struct channel_oil *channel_oil, + struct interface *oif, + uint32_t proto_mask) +{ + struct pim_interface *pim_ifp; + int old_ttl; + + zassert(channel_oil); + + pim_ifp = oif->info; + + if (PIM_DEBUG_MROUTE) { + char group_str[100]; + char source_str[100]; + pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); + pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); + zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d", + __FILE__, __PRETTY_FUNCTION__, + source_str, group_str, + proto_mask, oif->name, pim_ifp->mroute_vif_index); + } + + if (pim_ifp->mroute_vif_index < 1) { + zlog_warn("%s %s: interface %s vif_index=%d < 1", + __FILE__, __PRETTY_FUNCTION__, + oif->name, pim_ifp->mroute_vif_index); + return -1; + } + +#ifdef PIM_ENFORCE_LOOPFREE_MFC + /* + Prevent creating MFC entry with OIF=IIF. + + This is a protection against implementation mistakes. + + PIM protocol implicitely ensures loopfree multicast topology. + + IGMP must be protected against adding looped MFC entries created + by both source and receiver attached to the same interface. See + TODO T22. + */ + if (pim_ifp->mroute_vif_index == channel_oil->oil.mfcc_parent) { + char group_str[100]; + char source_str[100]; + pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); + pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); + zlog_warn("%s %s: refusing protocol mask %u request for IIF=OIF=%s (vif_index=%d) for channel (S,G)=(%s,%s)", + __FILE__, __PRETTY_FUNCTION__, + proto_mask, oif->name, pim_ifp->mroute_vif_index, + source_str, group_str); + return -2; + } +#endif + + zassert(qpim_mroute_oif_highest_vif_index < MAXVIFS); + zassert(pim_ifp->mroute_vif_index <= qpim_mroute_oif_highest_vif_index); + + /* Prevent single protocol from subscribing same interface to + channel (S,G) multiple times */ + if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask) { + char group_str[100]; + char source_str[100]; + pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); + pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); + zlog_warn("%s %s: existing protocol mask %u requested 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 -3; + } + + /* Allow other protocol to request subscription of same interface to + channel (S,G) multiple times, by silently ignoring further + requests */ + if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & PIM_OIF_FLAG_PROTO_ANY) { + + /* Check the OIF really exists before returning, and only log + warning otherwise */ + if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) { + char group_str[100]; + char source_str[100]; + pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); + pim_inet4_dump("", 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; + } + + old_ttl = channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index]; + + if (old_ttl > 0) { + char group_str[100]; + char source_str[100]; + pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); + pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); + zlog_warn("%s %s: interface %s (vif_index=%d) is existing output for channel (S,G)=(%s,%s)", + __FILE__, __PRETTY_FUNCTION__, + oif->name, pim_ifp->mroute_vif_index, + source_str, group_str); + return -4; + } + + channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = PIM_MROUTE_MIN_TTL; + + if (pim_mroute_add(&channel_oil->oil)) { + char group_str[100]; + char source_str[100]; + pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); + pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); + zlog_warn("%s %s: could not add output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)", + __FILE__, __PRETTY_FUNCTION__, + oif->name, pim_ifp->mroute_vif_index, + source_str, group_str); + + channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = old_ttl; + return -5; + } + + channel_oil->oif_creation[pim_ifp->mroute_vif_index] = pim_time_monotonic_sec(); + ++channel_oil->oil_size; + channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask; + + if (PIM_DEBUG_MROUTE) { + char group_str[100]; + char source_str[100]; + pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); + pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); + zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d: DONE", + __FILE__, __PRETTY_FUNCTION__, + source_str, group_str, + proto_mask, oif->name, pim_ifp->mroute_vif_index); + } + + return 0; +} diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h index 16d2dd7e4b..f0a14a9baa 100644 --- a/pimd/pim_oil.h +++ b/pimd/pim_oil.h @@ -39,6 +39,17 @@ PIM_OIF_FLAG_PROTO_PIM | \ PIM_OIF_FLAG_PROTO_SOURCE) +/* + * We need a pimreg vif id from the kernel. + * Since ifindex == vif id for most cases and the number + * of expected interfaces is at most 100, using MAXVIFS -1 + * is probably ok. + * Don't come running to me if this assumption is bad, + * fix it. + */ +#define PIM_OIF_PIM_REGISTER_VIF (MAXVIFS - 1) +#define PIM_MAX_USABLE_VIFS (MAXVIFS - 2) + /* qpim_channel_oil_list holds a list of struct channel_oil. @@ -60,4 +71,8 @@ struct channel_oil *pim_channel_oil_add(struct in_addr group_addr, int input_vif_index); void pim_channel_oil_del(struct channel_oil *c_oil); +int pim_channel_add_oif(struct channel_oil *c_oil, + struct interface *oif, + uint32_t proto_mask); + #endif /* PIM_OIL_H */ diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 5add833658..1df2f70513 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -803,148 +803,6 @@ static int fib_lookup_if_vif_index(struct in_addr addr) return vif_index; } -static int add_oif(struct channel_oil *channel_oil, - struct interface *oif, - uint32_t proto_mask) -{ - struct pim_interface *pim_ifp; - int old_ttl; - - zassert(channel_oil); - - pim_ifp = oif->info; - - if (PIM_DEBUG_MROUTE) { - char group_str[100]; - char source_str[100]; - pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); - pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); - zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d", - __FILE__, __PRETTY_FUNCTION__, - source_str, group_str, - proto_mask, oif->name, pim_ifp->mroute_vif_index); - } - - if (pim_ifp->mroute_vif_index < 1) { - zlog_warn("%s %s: interface %s vif_index=%d < 1", - __FILE__, __PRETTY_FUNCTION__, - oif->name, pim_ifp->mroute_vif_index); - return -1; - } - -#ifdef PIM_ENFORCE_LOOPFREE_MFC - /* - Prevent creating MFC entry with OIF=IIF. - - This is a protection against implementation mistakes. - - PIM protocol implicitely ensures loopfree multicast topology. - - IGMP must be protected against adding looped MFC entries created - by both source and receiver attached to the same interface. See - TODO T22. - */ - if (pim_ifp->mroute_vif_index == channel_oil->oil.mfcc_parent) { - char group_str[100]; - char source_str[100]; - pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); - pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); - zlog_warn("%s %s: refusing protocol mask %u request for IIF=OIF=%s (vif_index=%d) for channel (S,G)=(%s,%s)", - __FILE__, __PRETTY_FUNCTION__, - proto_mask, oif->name, pim_ifp->mroute_vif_index, - source_str, group_str); - return -2; - } -#endif - - zassert(qpim_mroute_oif_highest_vif_index < MAXVIFS); - zassert(pim_ifp->mroute_vif_index <= qpim_mroute_oif_highest_vif_index); - - /* Prevent single protocol from subscribing same interface to - channel (S,G) multiple times */ - if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask) { - char group_str[100]; - char source_str[100]; - pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); - pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); - zlog_warn("%s %s: existing protocol mask %u requested 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 -3; - } - - /* Allow other protocol to request subscription of same interface to - channel (S,G) multiple times, by silently ignoring further - requests */ - if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & PIM_OIF_FLAG_PROTO_ANY) { - - /* Check the OIF really exists before returning, and only log - warning otherwise */ - if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) { - char group_str[100]; - char source_str[100]; - pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); - pim_inet4_dump("", 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; - } - - old_ttl = channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index]; - - if (old_ttl > 0) { - char group_str[100]; - char source_str[100]; - pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); - pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); - zlog_warn("%s %s: interface %s (vif_index=%d) is existing output for channel (S,G)=(%s,%s)", - __FILE__, __PRETTY_FUNCTION__, - oif->name, pim_ifp->mroute_vif_index, - source_str, group_str); - return -4; - } - - channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = PIM_MROUTE_MIN_TTL; - - if (pim_mroute_add(&channel_oil->oil)) { - char group_str[100]; - char source_str[100]; - pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); - pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); - zlog_warn("%s %s: could not add output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)", - __FILE__, __PRETTY_FUNCTION__, - oif->name, pim_ifp->mroute_vif_index, - source_str, group_str); - - channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = old_ttl; - return -5; - } - - channel_oil->oif_creation[pim_ifp->mroute_vif_index] = pim_time_monotonic_sec(); - ++channel_oil->oil_size; - channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask; - - if (PIM_DEBUG_MROUTE) { - char group_str[100]; - char source_str[100]; - pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); - pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); - zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d: DONE", - __FILE__, __PRETTY_FUNCTION__, - source_str, group_str, - proto_mask, oif->name, pim_ifp->mroute_vif_index); - } - - return 0; -} - static int del_oif(struct channel_oil *channel_oil, struct interface *oif, uint32_t proto_mask) @@ -1164,9 +1022,9 @@ void igmp_source_forward_start(struct igmp_source *source) } } - result = add_oif(source->source_channel_oil, - group->group_igmp_sock->interface, - PIM_OIF_FLAG_PROTO_IGMP); + result = pim_channel_add_oif(source->source_channel_oil, + group->group_igmp_sock->interface, + PIM_OIF_FLAG_PROTO_IGMP); if (result) { zlog_warn("%s: add_oif() failed with return=%d", __func__, result); @@ -1285,9 +1143,9 @@ void pim_forward_start(struct pim_ifchannel *ch) } } - add_oif(up->channel_oil, - ch->interface, - PIM_OIF_FLAG_PROTO_PIM); + pim_channel_add_oif(up->channel_oil, + ch->interface, + PIM_OIF_FLAG_PROTO_PIM); } void pim_forward_stop(struct pim_ifchannel *ch) -- 2.39.5