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 <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2015-10-28 11:00:37 -07:00 committed by Donald Sharp
parent 0fba6e638a
commit 1865a44a83
6 changed files with 167 additions and 152 deletions

View File

@ -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);

View File

@ -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();

View File

@ -48,7 +48,7 @@
*/
#ifndef MAXVIFS
#define MAXVIFS (32)
#define MAXVIFS (256)
#endif
#ifndef SIOCGETVIFCNT

View File

@ -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("<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: (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("<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: 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("<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: 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("<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;
}
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("<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: 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("<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: 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("<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: (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;
}

View File

@ -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 */

View File

@ -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("<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: (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("<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: 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("<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: 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("<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;
}
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("<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: 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("<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: 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("<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: (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)