mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 21:37:08 +00:00
pim6d: IPv6-adjust mroute code
This is just hitting the pim_mroute code with a hammer until it doesn't print warnings anymore. This is NOT quite tested or working yet, it just compiles. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
89e2cbd38f
commit
a9338fa449
@ -1526,6 +1526,13 @@ AC_CHECK_HEADERS([linux/mroute.h], [], [],[
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS([linux/mroute6.h], [], [],[
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#define _LINUX_IN_H /* For Linux <= 2.6.25 */
|
||||||
|
#include <linux/types.h>
|
||||||
|
])
|
||||||
|
|
||||||
m4_define([FRR_INCLUDES],
|
m4_define([FRR_INCLUDES],
|
||||||
FRR_INCLUDES
|
FRR_INCLUDES
|
||||||
[#ifdef HAVE_LINUX_MROUTE_H
|
[#ifdef HAVE_LINUX_MROUTE_H
|
||||||
|
@ -306,8 +306,8 @@ void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
|
|||||||
* supplying the implied
|
* supplying the implied
|
||||||
* if channel. So remove it.
|
* if channel. So remove it.
|
||||||
*/
|
*/
|
||||||
if (c_oil->oil.mfcc_ttls
|
if (oil_if_has(c_oil,
|
||||||
[pim_ifp->mroute_vif_index])
|
pim_ifp->mroute_vif_index))
|
||||||
pim_channel_del_inherited_oif(
|
pim_channel_del_inherited_oif(
|
||||||
c_oil, ch->interface,
|
c_oil, ch->interface,
|
||||||
__func__);
|
__func__);
|
||||||
@ -1291,7 +1291,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, pim_sgaddr *sg)
|
|||||||
if (!pim_upstream_evaluate_join_desired_interface(
|
if (!pim_upstream_evaluate_join_desired_interface(
|
||||||
child, ch, starch) ||
|
child, ch, starch) ||
|
||||||
(!chchannel &&
|
(!chchannel &&
|
||||||
c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])) {
|
oil_if_has(c_oil, pim_ifp->mroute_vif_index))) {
|
||||||
pim_channel_del_inherited_oif(c_oil, ifp,
|
pim_channel_del_inherited_oif(c_oil, ifp,
|
||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,7 @@ static int pim_mroute_set(struct pim_instance *pim, int enable)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PIM_IPV == 4
|
||||||
static const char *const igmpmsgtype2str[IGMPMSG_WRVIFWHOLE + 1] = {
|
static const char *const igmpmsgtype2str[IGMPMSG_WRVIFWHOLE + 1] = {
|
||||||
"<unknown_upcall?>", "NOCACHE", "WRONGVIF", "WHOLEPKT", "WRVIFWHOLE"};
|
"<unknown_upcall?>", "NOCACHE", "WRONGVIF", "WHOLEPKT", "WRVIFWHOLE"};
|
||||||
|
|
||||||
@ -227,7 +228,7 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
|
|||||||
up->channel_oil->cc.pktcnt++;
|
up->channel_oil->cc.pktcnt++;
|
||||||
// resolve mfcc_parent prior to mroute_add in channel_add_oif
|
// resolve mfcc_parent prior to mroute_add in channel_add_oif
|
||||||
if (up->rpf.source_nexthop.interface &&
|
if (up->rpf.source_nexthop.interface &&
|
||||||
up->channel_oil->oil.mfcc_parent >= MAXVIFS) {
|
*oil_parent(up->channel_oil) >= MAXVIFS) {
|
||||||
pim_upstream_mroute_iif_update(up->channel_oil, __func__);
|
pim_upstream_mroute_iif_update(up->channel_oil, __func__);
|
||||||
}
|
}
|
||||||
pim_register_join(up);
|
pim_register_join(up);
|
||||||
@ -676,6 +677,14 @@ static int pim_mroute_msg(struct pim_instance *pim, const char *buf,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else /* PIM_IPV != 4 */
|
||||||
|
|
||||||
|
static int pim_mroute_msg(struct pim_instance *pim, const char *buf,
|
||||||
|
int buf_size, ifindex_t ifindex)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* PIM_IPV != 4 */
|
||||||
|
|
||||||
static int mroute_read(struct thread *t)
|
static int mroute_read(struct thread *t)
|
||||||
{
|
{
|
||||||
@ -800,7 +809,7 @@ int pim_mroute_socket_disable(struct pim_instance *pim)
|
|||||||
would be used for multicast forwarding, a corresponding multicast
|
would be used for multicast forwarding, a corresponding multicast
|
||||||
interface must be added to the kernel.
|
interface must be added to the kernel.
|
||||||
*/
|
*/
|
||||||
int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr,
|
int pim_mroute_add_vif(struct interface *ifp, pim_addr ifaddr,
|
||||||
unsigned char flags)
|
unsigned char flags)
|
||||||
{
|
{
|
||||||
struct pim_interface *pim_ifp = ifp->info;
|
struct pim_interface *pim_ifp = ifp->info;
|
||||||
@ -839,15 +848,10 @@ int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr,
|
|||||||
err = setsockopt(pim_ifp->pim->mroute_socket, IPPROTO_IP, MRT_ADD_VIF,
|
err = setsockopt(pim_ifp->pim->mroute_socket, IPPROTO_IP, MRT_ADD_VIF,
|
||||||
(void *)&vc, sizeof(vc));
|
(void *)&vc, sizeof(vc));
|
||||||
if (err) {
|
if (err) {
|
||||||
char ifaddr_str[INET_ADDRSTRLEN];
|
|
||||||
|
|
||||||
pim_inet4_dump("<ifaddr?>", ifaddr, ifaddr_str,
|
|
||||||
sizeof(ifaddr_str));
|
|
||||||
|
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"%s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_VIF,vif_index=%d,ifaddr=%s,flag=%d): errno=%d: %s",
|
"%s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_VIF,vif_index=%d,ifaddr=%pPAs,flag=%d): errno=%d: %s",
|
||||||
__func__, pim_ifp->pim->mroute_socket, ifp->ifindex,
|
__func__, pim_ifp->pim->mroute_socket, ifp->ifindex,
|
||||||
ifaddr_str, flags, errno, safe_strerror(errno));
|
&ifaddr, flags, errno, safe_strerror(errno));
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -921,26 +925,26 @@ bool pim_mroute_allow_iif_in_oil(struct channel_oil *c_oil,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void pim_mroute_copy(struct mfcctl *oil,
|
static inline void pim_mroute_copy(struct channel_oil *out,
|
||||||
struct channel_oil *c_oil)
|
struct channel_oil *in)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
oil->mfcc_origin = c_oil->oil.mfcc_origin;
|
*oil_origin(out) = *oil_origin(in);
|
||||||
oil->mfcc_mcastgrp = c_oil->oil.mfcc_mcastgrp;
|
*oil_mcastgrp(out) = *oil_mcastgrp(in);
|
||||||
oil->mfcc_parent = c_oil->oil.mfcc_parent;
|
*oil_parent(out) = *oil_parent(in);
|
||||||
|
|
||||||
for (i = 0; i < MAXVIFS; ++i) {
|
for (i = 0; i < MAXVIFS; ++i) {
|
||||||
if ((oil->mfcc_parent == i) &&
|
if (*oil_parent(out) == i &&
|
||||||
!pim_mroute_allow_iif_in_oil(c_oil, i)) {
|
!pim_mroute_allow_iif_in_oil(in, i)) {
|
||||||
oil->mfcc_ttls[i] = 0;
|
oil_if_set(out, i, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c_oil->oif_flags[i] & PIM_OIF_FLAG_MUTE)
|
if (in->oif_flags[i] & PIM_OIF_FLAG_MUTE)
|
||||||
oil->mfcc_ttls[i] = 0;
|
oil_if_set(out, i, 0);
|
||||||
else
|
else
|
||||||
oil->mfcc_ttls[i] = c_oil->oil.mfcc_ttls[i];
|
oil_if_set(out, i, oil_if_has(in, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,7 +954,7 @@ static inline void pim_mroute_copy(struct mfcctl *oil,
|
|||||||
static int pim_mroute_add(struct channel_oil *c_oil, const char *name)
|
static int pim_mroute_add(struct channel_oil *c_oil, const char *name)
|
||||||
{
|
{
|
||||||
struct pim_instance *pim = c_oil->pim;
|
struct pim_instance *pim = c_oil->pim;
|
||||||
struct mfcctl tmp_oil = { {0} };
|
struct channel_oil tmp_oil[1] = { };
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
pim->mroute_add_last = pim_time_monotonic_sec();
|
pim->mroute_add_last = pim_time_monotonic_sec();
|
||||||
@ -959,14 +963,14 @@ static int pim_mroute_add(struct channel_oil *c_oil, const char *name)
|
|||||||
/* Copy the oil to a temporary structure to fixup (without need to
|
/* Copy the oil to a temporary structure to fixup (without need to
|
||||||
* later restore) before sending the mroute add to the dataplane
|
* later restore) before sending the mroute add to the dataplane
|
||||||
*/
|
*/
|
||||||
pim_mroute_copy(&tmp_oil, c_oil);
|
pim_mroute_copy(tmp_oil, c_oil);
|
||||||
|
|
||||||
/* The linux kernel *expects* the incoming
|
/* The linux kernel *expects* the incoming
|
||||||
* vif to be part of the outgoing list
|
* vif to be part of the outgoing list
|
||||||
* in the case of a (*,G).
|
* in the case of a (*,G).
|
||||||
*/
|
*/
|
||||||
if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY) {
|
if (pim_addr_is_any(*oil_origin(c_oil))) {
|
||||||
tmp_oil.mfcc_ttls[c_oil->oil.mfcc_parent] = 1;
|
oil_if_set(tmp_oil, *oil_parent(c_oil), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -976,19 +980,19 @@ static int pim_mroute_add(struct channel_oil *c_oil, const char *name)
|
|||||||
* the packets to be forwarded. Then set it
|
* the packets to be forwarded. Then set it
|
||||||
* to the correct IIF afterwords.
|
* to the correct IIF afterwords.
|
||||||
*/
|
*/
|
||||||
if (!c_oil->installed && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY
|
if (!c_oil->installed && !pim_addr_is_any(*oil_origin(c_oil))
|
||||||
&& c_oil->oil.mfcc_parent != 0) {
|
&& *oil_parent(c_oil) != 0) {
|
||||||
tmp_oil.mfcc_parent = 0;
|
*oil_parent(tmp_oil) = 0;
|
||||||
}
|
}
|
||||||
err = setsockopt(pim->mroute_socket, IPPROTO_IP, MRT_ADD_MFC,
|
err = setsockopt(pim->mroute_socket, IPPROTO_IP, MRT_ADD_MFC,
|
||||||
&tmp_oil, sizeof(tmp_oil));
|
&tmp_oil->oil, sizeof(tmp_oil->oil));
|
||||||
|
|
||||||
if (!err && !c_oil->installed
|
if (!err && !c_oil->installed
|
||||||
&& c_oil->oil.mfcc_origin.s_addr != INADDR_ANY
|
&& !pim_addr_is_any(*oil_origin(c_oil))
|
||||||
&& c_oil->oil.mfcc_parent != 0) {
|
&& *oil_parent(c_oil) != 0) {
|
||||||
tmp_oil.mfcc_parent = c_oil->oil.mfcc_parent;
|
*oil_parent(tmp_oil) = *oil_parent(c_oil);
|
||||||
err = setsockopt(pim->mroute_socket, IPPROTO_IP, MRT_ADD_MFC,
|
err = setsockopt(pim->mroute_socket, IPPROTO_IP, MRT_ADD_MFC,
|
||||||
&tmp_oil, sizeof(tmp_oil));
|
&tmp_oil->oil, sizeof(tmp_oil->oil));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -1043,7 +1047,7 @@ static int pim_upstream_mroute_update(struct channel_oil *c_oil,
|
|||||||
{
|
{
|
||||||
char buf[1000];
|
char buf[1000];
|
||||||
|
|
||||||
if (c_oil->oil.mfcc_parent >= MAXVIFS) {
|
if (*oil_parent(c_oil) >= MAXVIFS) {
|
||||||
/* the c_oil cannot be installed as a mroute yet */
|
/* the c_oil cannot be installed as a mroute yet */
|
||||||
if (PIM_DEBUG_MROUTE)
|
if (PIM_DEBUG_MROUTE)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -1090,13 +1094,13 @@ int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name)
|
|||||||
|
|
||||||
iif = pim_upstream_get_mroute_iif(c_oil, name);
|
iif = pim_upstream_get_mroute_iif(c_oil, name);
|
||||||
|
|
||||||
if (c_oil->oil.mfcc_parent != iif) {
|
if (*oil_parent(c_oil) != iif) {
|
||||||
c_oil->oil.mfcc_parent = iif;
|
*oil_parent(c_oil) = iif;
|
||||||
if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY &&
|
if (pim_addr_is_any(*oil_origin(c_oil)) &&
|
||||||
c_oil->up)
|
c_oil->up)
|
||||||
pim_upstream_all_sources_iif_update(c_oil->up);
|
pim_upstream_all_sources_iif_update(c_oil->up);
|
||||||
} else {
|
} else {
|
||||||
c_oil->oil.mfcc_parent = iif;
|
*oil_parent(c_oil) = iif;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pim_upstream_mroute_update(c_oil, name);
|
return pim_upstream_mroute_update(c_oil, name);
|
||||||
@ -1111,13 +1115,13 @@ int pim_upstream_mroute_iif_update(struct channel_oil *c_oil, const char *name)
|
|||||||
char buf[1000];
|
char buf[1000];
|
||||||
|
|
||||||
iif = pim_upstream_get_mroute_iif(c_oil, name);
|
iif = pim_upstream_get_mroute_iif(c_oil, name);
|
||||||
if (c_oil->oil.mfcc_parent == iif) {
|
if (*oil_parent(c_oil) == iif) {
|
||||||
/* no change */
|
/* no change */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
c_oil->oil.mfcc_parent = iif;
|
*oil_parent(c_oil) = iif;
|
||||||
|
|
||||||
if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY &&
|
if (pim_addr_is_any(*oil_origin(c_oil)) &&
|
||||||
c_oil->up)
|
c_oil->up)
|
||||||
pim_upstream_all_sources_iif_update(c_oil->up);
|
pim_upstream_all_sources_iif_update(c_oil->up);
|
||||||
|
|
||||||
@ -1140,10 +1144,10 @@ void pim_static_mroute_iif_update(struct channel_oil *c_oil,
|
|||||||
int input_vif_index,
|
int input_vif_index,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
if (c_oil->oil.mfcc_parent == input_vif_index)
|
if (*oil_parent(c_oil) == input_vif_index)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
c_oil->oil.mfcc_parent = input_vif_index;
|
*oil_parent(c_oil) = input_vif_index;
|
||||||
if (input_vif_index == MAXVIFS)
|
if (input_vif_index == MAXVIFS)
|
||||||
pim_mroute_del(c_oil, name);
|
pim_mroute_del(c_oil, name);
|
||||||
else
|
else
|
||||||
@ -1163,7 +1167,7 @@ int pim_mroute_del(struct channel_oil *c_oil, const char *name)
|
|||||||
char buf[1000];
|
char buf[1000];
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s %s: vifi %d for route is %s not installed, do not need to send del req. ",
|
"%s %s: vifi %d for route is %s not installed, do not need to send del req. ",
|
||||||
__FILE__, __func__, c_oil->oil.mfcc_parent,
|
__FILE__, __func__, *oil_parent(c_oil),
|
||||||
pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
|
pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
return -2;
|
return -2;
|
||||||
@ -1196,7 +1200,6 @@ int pim_mroute_del(struct channel_oil *c_oil, const char *name)
|
|||||||
void pim_mroute_update_counters(struct channel_oil *c_oil)
|
void pim_mroute_update_counters(struct channel_oil *c_oil)
|
||||||
{
|
{
|
||||||
struct pim_instance *pim = c_oil->pim;
|
struct pim_instance *pim = c_oil->pim;
|
||||||
struct sioc_sg_req sgreq;
|
|
||||||
|
|
||||||
c_oil->cc.oldpktcnt = c_oil->cc.pktcnt;
|
c_oil->cc.oldpktcnt = c_oil->cc.pktcnt;
|
||||||
c_oil->cc.oldbytecnt = c_oil->cc.bytecnt;
|
c_oil->cc.oldbytecnt = c_oil->cc.bytecnt;
|
||||||
@ -1207,24 +1210,27 @@ void pim_mroute_update_counters(struct channel_oil *c_oil)
|
|||||||
if (PIM_DEBUG_MROUTE) {
|
if (PIM_DEBUG_MROUTE) {
|
||||||
pim_sgaddr sg;
|
pim_sgaddr sg;
|
||||||
|
|
||||||
sg.src = c_oil->oil.mfcc_origin;
|
sg.src = *oil_origin(c_oil);
|
||||||
sg.grp = c_oil->oil.mfcc_mcastgrp;
|
sg.grp = *oil_mcastgrp(c_oil);
|
||||||
zlog_debug("Channel%pSG is not installed no need to collect data from kernel",
|
zlog_debug("Channel%pSG is not installed no need to collect data from kernel",
|
||||||
&sg);
|
&sg);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PIM_IPV == 4
|
||||||
|
struct sioc_sg_req sgreq;
|
||||||
|
|
||||||
memset(&sgreq, 0, sizeof(sgreq));
|
memset(&sgreq, 0, sizeof(sgreq));
|
||||||
sgreq.src = c_oil->oil.mfcc_origin;
|
sgreq.src = *oil_origin(c_oil);
|
||||||
sgreq.grp = c_oil->oil.mfcc_mcastgrp;
|
sgreq.grp = *oil_mcastgrp(c_oil);
|
||||||
|
|
||||||
pim_zlookup_sg_statistics(c_oil);
|
pim_zlookup_sg_statistics(c_oil);
|
||||||
if (ioctl(pim->mroute_socket, SIOCGETSGCNT, &sgreq)) {
|
if (ioctl(pim->mroute_socket, SIOCGETSGCNT, &sgreq)) {
|
||||||
pim_sgaddr sg;
|
pim_sgaddr sg;
|
||||||
|
|
||||||
sg.src = c_oil->oil.mfcc_origin;
|
sg.src = *oil_origin(c_oil);
|
||||||
sg.grp = c_oil->oil.mfcc_mcastgrp;
|
sg.grp = *oil_mcastgrp(c_oil);
|
||||||
|
|
||||||
zlog_warn("ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=%pSG: errno=%d: %s",
|
zlog_warn("ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=%pSG: errno=%d: %s",
|
||||||
(unsigned long)SIOCGETSGCNT, &sg,
|
(unsigned long)SIOCGETSGCNT, &sg,
|
||||||
@ -1235,6 +1241,6 @@ void pim_mroute_update_counters(struct channel_oil *c_oil)
|
|||||||
c_oil->cc.pktcnt = sgreq.pktcnt;
|
c_oil->cc.pktcnt = sgreq.pktcnt;
|
||||||
c_oil->cc.bytecnt = sgreq.bytecnt;
|
c_oil->cc.bytecnt = sgreq.bytecnt;
|
||||||
c_oil->cc.wrong_if = sgreq.wrong_if;
|
c_oil->cc.wrong_if = sgreq.wrong_if;
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#define PIM_MROUTE_MIN_TTL (1)
|
#define PIM_MROUTE_MIN_TTL (1)
|
||||||
|
|
||||||
|
#if PIM_IPV == 4
|
||||||
#if defined(HAVE_LINUX_MROUTE_H)
|
#if defined(HAVE_LINUX_MROUTE_H)
|
||||||
#include <linux/mroute.h>
|
#include <linux/mroute.h>
|
||||||
#else
|
#else
|
||||||
@ -157,6 +158,19 @@ struct igmpmsg {
|
|||||||
struct in_addr im_src, im_dst;
|
struct in_addr im_src, im_dst;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_LINUX_MROUTE_H */
|
||||||
|
|
||||||
|
typedef struct mfcctl pim_mfcctl;
|
||||||
|
|
||||||
|
#else /* PIM_IPV != 4 */
|
||||||
|
#if defined(HAVE_LINUX_MROUTE6_H)
|
||||||
|
#include <linux/mroute6.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct mf6cctl pim_mfcctl;
|
||||||
|
|
||||||
|
#define MAXVIFS IF_SETSIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef IGMPMSG_WRVIFWHOLE
|
#ifndef IGMPMSG_WRVIFWHOLE
|
||||||
@ -172,7 +186,7 @@ struct channel_oil;
|
|||||||
int pim_mroute_socket_enable(struct pim_instance *pim);
|
int pim_mroute_socket_enable(struct pim_instance *pim);
|
||||||
int pim_mroute_socket_disable(struct pim_instance *pim);
|
int pim_mroute_socket_disable(struct pim_instance *pim);
|
||||||
|
|
||||||
int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr,
|
int pim_mroute_add_vif(struct interface *ifp, pim_addr ifaddr,
|
||||||
unsigned char flags);
|
unsigned char flags);
|
||||||
int pim_mroute_del_vif(struct interface *ifp);
|
int pim_mroute_del_vif(struct interface *ifp);
|
||||||
|
|
||||||
|
224
pimd/pim_oil.c
224
pimd/pim_oil.c
@ -42,15 +42,15 @@ char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size)
|
|||||||
pim_sgaddr sg;
|
pim_sgaddr sg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sg.src = c_oil->oil.mfcc_origin;
|
sg.src = *oil_origin(c_oil);
|
||||||
sg.grp = c_oil->oil.mfcc_mcastgrp;
|
sg.grp = *oil_mcastgrp(c_oil);
|
||||||
ifp = pim_if_find_by_vif_index(c_oil->pim, c_oil->oil.mfcc_parent);
|
ifp = pim_if_find_by_vif_index(c_oil->pim, *oil_parent(c_oil));
|
||||||
snprintfrr(buf, size, "%pSG IIF: %s, OIFS: ", &sg,
|
snprintfrr(buf, size, "%pSG IIF: %s, OIFS: ", &sg,
|
||||||
ifp ? ifp->name : "(?)");
|
ifp ? ifp->name : "(?)");
|
||||||
|
|
||||||
out = buf + strlen(buf);
|
out = buf + strlen(buf);
|
||||||
for (i = 0; i < MAXVIFS; i++) {
|
for (i = 0; i < MAXVIFS; i++) {
|
||||||
if (c_oil->oil.mfcc_ttls[i] != 0) {
|
if (oil_if_has(c_oil, i) != 0) {
|
||||||
ifp = pim_if_find_by_vif_index(c_oil->pim, i);
|
ifp = pim_if_find_by_vif_index(c_oil->pim, i);
|
||||||
snprintf(out, buf + size - out, "%s ",
|
snprintf(out, buf + size - out, "%s ",
|
||||||
ifp ? ifp->name : "(?)");
|
ifp ? ifp->name : "(?)");
|
||||||
@ -61,25 +61,19 @@ char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pim_channel_oil_compare(const struct channel_oil *c1,
|
int pim_channel_oil_compare(const struct channel_oil *cc1,
|
||||||
const struct channel_oil *c2)
|
const struct channel_oil *cc2)
|
||||||
{
|
{
|
||||||
if (ntohl(c1->oil.mfcc_mcastgrp.s_addr)
|
struct channel_oil *c1 = (struct channel_oil *)cc1;
|
||||||
< ntohl(c2->oil.mfcc_mcastgrp.s_addr))
|
struct channel_oil *c2 = (struct channel_oil *)cc2;
|
||||||
return -1;
|
int rv;
|
||||||
|
|
||||||
if (ntohl(c1->oil.mfcc_mcastgrp.s_addr)
|
|
||||||
> ntohl(c2->oil.mfcc_mcastgrp.s_addr))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (ntohl(c1->oil.mfcc_origin.s_addr)
|
|
||||||
< ntohl(c2->oil.mfcc_origin.s_addr))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ntohl(c1->oil.mfcc_origin.s_addr)
|
|
||||||
> ntohl(c2->oil.mfcc_origin.s_addr))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
|
rv = pim_addr_cmp(*oil_mcastgrp(c1), *oil_mcastgrp(c2));
|
||||||
|
if (rv)
|
||||||
|
return rv;
|
||||||
|
rv = pim_addr_cmp(*oil_origin(c1), *oil_origin(c2));
|
||||||
|
if (rv)
|
||||||
|
return rv;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,8 +103,8 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
|
|||||||
struct channel_oil *c_oil = NULL;
|
struct channel_oil *c_oil = NULL;
|
||||||
struct channel_oil lookup;
|
struct channel_oil lookup;
|
||||||
|
|
||||||
lookup.oil.mfcc_mcastgrp = sg->grp;
|
*oil_mcastgrp(&lookup) = sg->grp;
|
||||||
lookup.oil.mfcc_origin = sg->src;
|
*oil_origin(&lookup) = sg->src;
|
||||||
|
|
||||||
c_oil = rb_pim_oil_find(&pim->channel_oil_head, &lookup);
|
c_oil = rb_pim_oil_find(&pim->channel_oil_head, &lookup);
|
||||||
|
|
||||||
@ -151,10 +145,10 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
|
|||||||
|
|
||||||
c_oil = XCALLOC(MTYPE_PIM_CHANNEL_OIL, sizeof(*c_oil));
|
c_oil = XCALLOC(MTYPE_PIM_CHANNEL_OIL, sizeof(*c_oil));
|
||||||
|
|
||||||
c_oil->oil.mfcc_mcastgrp = sg->grp;
|
*oil_mcastgrp(c_oil) = sg->grp;
|
||||||
c_oil->oil.mfcc_origin = sg->src;
|
*oil_origin(c_oil) = sg->src;
|
||||||
|
|
||||||
c_oil->oil.mfcc_parent = MAXVIFS;
|
*oil_parent(c_oil) = MAXVIFS;
|
||||||
c_oil->oil_ref_count = 1;
|
c_oil->oil_ref_count = 1;
|
||||||
c_oil->installed = 0;
|
c_oil->installed = 0;
|
||||||
c_oil->up = pim_upstream_find(pim, sg);
|
c_oil->up = pim_upstream_find(pim, sg);
|
||||||
@ -172,8 +166,8 @@ struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil,
|
|||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
if (PIM_DEBUG_MROUTE) {
|
if (PIM_DEBUG_MROUTE) {
|
||||||
pim_sgaddr sg = {.src = c_oil->oil.mfcc_mcastgrp,
|
pim_sgaddr sg = {.src = *oil_mcastgrp(c_oil),
|
||||||
.grp = c_oil->oil.mfcc_origin};
|
.grp = *oil_origin(c_oil)};
|
||||||
|
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s(%s): Del oil for %pSG, Ref Count: %d (Predecrement)",
|
"%s(%s): Del oil for %pSG, Ref Count: %d (Predecrement)",
|
||||||
@ -228,23 +222,15 @@ int pim_channel_del_oif(struct channel_oil *channel_oil, struct interface *oif,
|
|||||||
*/
|
*/
|
||||||
if (!(channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask)) {
|
if (!(channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask)) {
|
||||||
if (PIM_DEBUG_MROUTE) {
|
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(
|
zlog_debug(
|
||||||
"%s %s: no existing protocol mask %u(%u) for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
|
"%s %s: no existing protocol mask %u(%u) for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%pPAs,%pPAs)",
|
||||||
__FILE__, __func__, proto_mask,
|
__FILE__, __func__, proto_mask,
|
||||||
channel_oil
|
channel_oil
|
||||||
->oif_flags[pim_ifp->mroute_vif_index],
|
->oif_flags[pim_ifp->mroute_vif_index],
|
||||||
oif->name, pim_ifp->mroute_vif_index,
|
oif->name, pim_ifp->mroute_vif_index,
|
||||||
channel_oil->oil
|
oil_if_has(channel_oil, pim_ifp->mroute_vif_index),
|
||||||
.mfcc_ttls[pim_ifp->mroute_vif_index],
|
oil_origin(channel_oil),
|
||||||
source_str, group_str);
|
oil_mcastgrp(channel_oil));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -254,44 +240,29 @@ int pim_channel_del_oif(struct channel_oil *channel_oil, struct interface *oif,
|
|||||||
if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] &
|
if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] &
|
||||||
PIM_OIF_FLAG_PROTO_ANY) {
|
PIM_OIF_FLAG_PROTO_ANY) {
|
||||||
if (PIM_DEBUG_MROUTE) {
|
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(
|
zlog_debug(
|
||||||
"%s %s: other protocol masks remain for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
|
"%s %s: other protocol masks remain for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%pPAs,%pPAs)",
|
||||||
__FILE__, __func__, oif->name,
|
__FILE__, __func__, oif->name,
|
||||||
pim_ifp->mroute_vif_index,
|
pim_ifp->mroute_vif_index,
|
||||||
channel_oil->oil
|
oil_if_has(channel_oil, pim_ifp->mroute_vif_index),
|
||||||
.mfcc_ttls[pim_ifp->mroute_vif_index],
|
oil_origin(channel_oil),
|
||||||
source_str, group_str);
|
oil_mcastgrp(channel_oil));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = 0;
|
oil_if_set(channel_oil, pim_ifp->mroute_vif_index, false);
|
||||||
/* clear mute; will be re-evaluated when the OIF becomes valid again */
|
/* clear mute; will be re-evaluated when the OIF becomes valid again */
|
||||||
channel_oil->oif_flags[pim_ifp->mroute_vif_index] &= ~PIM_OIF_FLAG_MUTE;
|
channel_oil->oif_flags[pim_ifp->mroute_vif_index] &= ~PIM_OIF_FLAG_MUTE;
|
||||||
|
|
||||||
if (pim_upstream_mroute_add(channel_oil, __func__)) {
|
if (pim_upstream_mroute_add(channel_oil, __func__)) {
|
||||||
if (PIM_DEBUG_MROUTE) {
|
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(
|
zlog_debug(
|
||||||
"%s %s: could not remove output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)",
|
"%s %s: could not remove output interface %s (vif_index=%d) for channel (S,G)=(%pPAs,%pPAs)",
|
||||||
__FILE__, __func__, oif->name,
|
__FILE__, __func__, oif->name,
|
||||||
pim_ifp->mroute_vif_index, source_str,
|
pim_ifp->mroute_vif_index,
|
||||||
group_str);
|
oil_origin(channel_oil),
|
||||||
|
oil_mcastgrp(channel_oil));
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -299,16 +270,12 @@ int pim_channel_del_oif(struct channel_oil *channel_oil, struct interface *oif,
|
|||||||
--channel_oil->oil_size;
|
--channel_oil->oil_size;
|
||||||
|
|
||||||
if (PIM_DEBUG_MROUTE) {
|
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(
|
zlog_debug(
|
||||||
"%s(%s): (S,G)=(%s,%s): proto_mask=%u IIF:%d OIF=%s vif_index=%d",
|
"%s(%s): (S,G)=(%pPAs,%pPAs): proto_mask=%u IIF:%d OIF=%s vif_index=%d",
|
||||||
__func__, caller, source_str, group_str, proto_mask,
|
__func__, caller, oil_origin(channel_oil),
|
||||||
channel_oil->oil.mfcc_parent, oif->name,
|
oil_mcastgrp(channel_oil),
|
||||||
|
proto_mask,
|
||||||
|
*oil_parent(channel_oil), oif->name,
|
||||||
pim_ifp->mroute_vif_index);
|
pim_ifp->mroute_vif_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +364,7 @@ void pim_channel_update_oif_mute(struct channel_oil *c_oil,
|
|||||||
bool new_mute;
|
bool new_mute;
|
||||||
|
|
||||||
/* If pim_ifp is not a part of the OIL there is nothing to do */
|
/* If pim_ifp is not a part of the OIL there is nothing to do */
|
||||||
if (!c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
|
if (!oil_if_has(c_oil, pim_ifp->mroute_vif_index))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
old_mute = !!(c_oil->oif_flags[pim_ifp->mroute_vif_index] &
|
old_mute = !!(c_oil->oif_flags[pim_ifp->mroute_vif_index] &
|
||||||
@ -455,21 +422,13 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
|
|||||||
channel (S,G) multiple times */
|
channel (S,G) multiple times */
|
||||||
if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask) {
|
if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask) {
|
||||||
if (PIM_DEBUG_MROUTE) {
|
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(
|
zlog_debug(
|
||||||
"%s %s: existing protocol mask %u requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
|
"%s %s: existing protocol mask %u requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%pPAs,%pPAs)",
|
||||||
__FILE__, __func__, proto_mask, oif->name,
|
__FILE__, __func__, proto_mask, oif->name,
|
||||||
pim_ifp->mroute_vif_index,
|
pim_ifp->mroute_vif_index,
|
||||||
channel_oil->oil
|
oil_if_has(channel_oil, pim_ifp->mroute_vif_index),
|
||||||
.mfcc_ttls[pim_ifp->mroute_vif_index],
|
oil_origin(channel_oil),
|
||||||
source_str, group_str);
|
oil_mcastgrp(channel_oil));
|
||||||
}
|
}
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
@ -487,36 +446,21 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
|
|||||||
channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
|
channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
|
||||||
/* Check the OIF really exists before returning, and only log
|
/* Check the OIF really exists before returning, and only log
|
||||||
warning otherwise */
|
warning otherwise */
|
||||||
if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) {
|
if (oil_if_has(channel_oil, pim_ifp->mroute_vif_index) < 1) {
|
||||||
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(
|
zlog_warn(
|
||||||
"%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
|
"%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%pPAs,%pPAs)",
|
||||||
__FILE__, __func__, proto_mask, oif->name,
|
__FILE__, __func__, proto_mask, oif->name,
|
||||||
pim_ifp->mroute_vif_index,
|
pim_ifp->mroute_vif_index,
|
||||||
channel_oil->oil
|
oil_if_has(channel_oil, pim_ifp->mroute_vif_index),
|
||||||
.mfcc_ttls[pim_ifp->mroute_vif_index],
|
oil_origin(channel_oil),
|
||||||
source_str, group_str);
|
oil_mcastgrp(channel_oil));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PIM_DEBUG_MROUTE) {
|
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(
|
zlog_debug(
|
||||||
"%s(%s): (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d added to 0x%x",
|
"%s(%s): (S,G)=(%pPAs,%pPAs): proto_mask=%u OIF=%s vif_index=%d added to 0x%x",
|
||||||
__func__, caller, source_str, group_str,
|
__func__, caller, oil_origin(channel_oil),
|
||||||
|
oil_mcastgrp(channel_oil),
|
||||||
proto_mask, oif->name,
|
proto_mask, oif->name,
|
||||||
pim_ifp->mroute_vif_index,
|
pim_ifp->mroute_vif_index,
|
||||||
channel_oil
|
channel_oil
|
||||||
@ -525,29 +469,21 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_ttl = channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index];
|
old_ttl = oil_if_has(channel_oil, pim_ifp->mroute_vif_index);
|
||||||
|
|
||||||
if (old_ttl > 0) {
|
if (old_ttl > 0) {
|
||||||
if (PIM_DEBUG_MROUTE) {
|
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(
|
zlog_debug(
|
||||||
"%s %s: interface %s (vif_index=%d) is existing output for channel (S,G)=(%s,%s)",
|
"%s %s: interface %s (vif_index=%d) is existing output for channel (S,G)=(%pPAs,%pPAs)",
|
||||||
__FILE__, __func__, oif->name,
|
__FILE__, __func__, oif->name,
|
||||||
pim_ifp->mroute_vif_index, source_str,
|
pim_ifp->mroute_vif_index,
|
||||||
group_str);
|
oil_origin(channel_oil),
|
||||||
|
oil_mcastgrp(channel_oil));
|
||||||
}
|
}
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] =
|
oil_if_set(channel_oil, pim_ifp->mroute_vif_index, PIM_MROUTE_MIN_TTL);
|
||||||
PIM_MROUTE_MIN_TTL;
|
|
||||||
|
|
||||||
/* Some OIFs are held in a muted state i.e. the PIM state machine
|
/* Some OIFs are held in a muted state i.e. the PIM state machine
|
||||||
* decided to include the OIF but additional status check such as
|
* decided to include the OIF but additional status check such as
|
||||||
@ -564,26 +500,19 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
|
|||||||
/* channel_oil->oil.mfcc_parent != MAXVIFS indicate this entry is not
|
/* channel_oil->oil.mfcc_parent != MAXVIFS indicate this entry is not
|
||||||
* valid to get installed in kernel.
|
* valid to get installed in kernel.
|
||||||
*/
|
*/
|
||||||
if (channel_oil->oil.mfcc_parent != MAXVIFS) {
|
if (*oil_parent(channel_oil) != MAXVIFS) {
|
||||||
if (pim_upstream_mroute_add(channel_oil, __func__)) {
|
if (pim_upstream_mroute_add(channel_oil, __func__)) {
|
||||||
if (PIM_DEBUG_MROUTE) {
|
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(
|
zlog_debug(
|
||||||
"%s %s: could not add output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)",
|
"%s %s: could not add output interface %s (vif_index=%d) for channel (S,G)=(%pPAs,%pPAs)",
|
||||||
__FILE__, __func__, oif->name,
|
__FILE__, __func__, oif->name,
|
||||||
pim_ifp->mroute_vif_index, source_str,
|
pim_ifp->mroute_vif_index,
|
||||||
group_str);
|
oil_origin(channel_oil),
|
||||||
|
oil_mcastgrp(channel_oil));
|
||||||
}
|
}
|
||||||
|
|
||||||
channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index]
|
oil_if_set(channel_oil, pim_ifp->mroute_vif_index,
|
||||||
= old_ttl;
|
old_ttl);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -594,15 +523,11 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
|
|||||||
channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
|
channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
|
||||||
|
|
||||||
if (PIM_DEBUG_MROUTE) {
|
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(
|
zlog_debug(
|
||||||
"%s(%s): (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d: DONE",
|
"%s(%s): (S,G)=(%pPAs,%pPAs): proto_mask=%u OIF=%s vif_index=%d: DONE",
|
||||||
__func__, caller, source_str, group_str, proto_mask,
|
__func__, caller, oil_origin(channel_oil),
|
||||||
|
oil_mcastgrp(channel_oil),
|
||||||
|
proto_mask,
|
||||||
oif->name, pim_ifp->mroute_vif_index);
|
oif->name, pim_ifp->mroute_vif_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,8 +536,6 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
|
|||||||
|
|
||||||
int pim_channel_oil_empty(struct channel_oil *c_oil)
|
int pim_channel_oil_empty(struct channel_oil *c_oil)
|
||||||
{
|
{
|
||||||
static struct mfcctl null_oil;
|
|
||||||
|
|
||||||
if (!c_oil)
|
if (!c_oil)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -620,6 +543,13 @@ int pim_channel_oil_empty(struct channel_oil *c_oil)
|
|||||||
* non-NULL.
|
* non-NULL.
|
||||||
* pimreg device (in all vrfs) uses a vifi of
|
* pimreg device (in all vrfs) uses a vifi of
|
||||||
* 0 (PIM_OIF_PIM_REGISTER_VIF) so we simply mfcc_ttls[0] */
|
* 0 (PIM_OIF_PIM_REGISTER_VIF) so we simply mfcc_ttls[0] */
|
||||||
|
#if PIM_IPV == 4
|
||||||
|
static pim_mfcctl null_oil;
|
||||||
|
|
||||||
return !memcmp(&c_oil->oil.mfcc_ttls[1], &null_oil.mfcc_ttls[1],
|
return !memcmp(&c_oil->oil.mfcc_ttls[1], &null_oil.mfcc_ttls[1],
|
||||||
sizeof(null_oil.mfcc_ttls) - sizeof(null_oil.mfcc_ttls[0]));
|
sizeof(null_oil.mfcc_ttls) - sizeof(null_oil.mfcc_ttls[0]));
|
||||||
|
#else
|
||||||
|
CPP_NOTICE("FIXME STUB");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ struct channel_oil {
|
|||||||
|
|
||||||
struct rb_pim_oil_item oil_rb;
|
struct rb_pim_oil_item oil_rb;
|
||||||
|
|
||||||
struct mfcctl oil;
|
pim_mfcctl oil;
|
||||||
int installed;
|
int installed;
|
||||||
int oil_inherited_rescan;
|
int oil_inherited_rescan;
|
||||||
int oil_size;
|
int oil_size;
|
||||||
@ -110,6 +110,61 @@ struct channel_oil {
|
|||||||
time_t mroute_creation;
|
time_t mroute_creation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if PIM_IPV == 4
|
||||||
|
static inline pim_addr *oil_origin(struct channel_oil *c_oil)
|
||||||
|
{
|
||||||
|
return &c_oil->oil.mfcc_origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pim_addr *oil_mcastgrp(struct channel_oil *c_oil)
|
||||||
|
{
|
||||||
|
return &c_oil->oil.mfcc_mcastgrp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline vifi_t *oil_parent(struct channel_oil *c_oil)
|
||||||
|
{
|
||||||
|
return &c_oil->oil.mfcc_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t oil_if_has(struct channel_oil *c_oil, vifi_t ifi)
|
||||||
|
{
|
||||||
|
return c_oil->oil.mfcc_ttls[ifi];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void oil_if_set(struct channel_oil *c_oil, vifi_t ifi, uint8_t set)
|
||||||
|
{
|
||||||
|
c_oil->oil.mfcc_ttls[ifi] = set;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline pim_addr *oil_origin(struct channel_oil *c_oil)
|
||||||
|
{
|
||||||
|
return &c_oil->oil.mf6cc_origin.sin6_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pim_addr *oil_mcastgrp(struct channel_oil *c_oil)
|
||||||
|
{
|
||||||
|
return &c_oil->oil.mf6cc_mcastgrp.sin6_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline mifi_t *oil_parent(struct channel_oil *c_oil)
|
||||||
|
{
|
||||||
|
return &c_oil->oil.mf6cc_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool oil_if_has(struct channel_oil *c_oil, mifi_t ifi)
|
||||||
|
{
|
||||||
|
return !!IF_ISSET(ifi, &c_oil->oil.mf6cc_ifset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void oil_if_set(struct channel_oil *c_oil, mifi_t ifi, bool set)
|
||||||
|
{
|
||||||
|
if (set)
|
||||||
|
IF_SET(ifi, &c_oil->oil.mf6cc_ifset);
|
||||||
|
else
|
||||||
|
IF_CLR(ifi, &c_oil->oil.mf6cc_ifset);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int pim_channel_oil_compare(const struct channel_oil *c1,
|
extern int pim_channel_oil_compare(const struct channel_oil *c1,
|
||||||
const struct channel_oil *c2);
|
const struct channel_oil *c2);
|
||||||
DECLARE_RBTREE_UNIQ(rb_pim_oil, struct channel_oil, oil_rb,
|
DECLARE_RBTREE_UNIQ(rb_pim_oil, struct channel_oil, oil_rb,
|
||||||
|
@ -1997,7 +1997,7 @@ static bool pim_upstream_kat_start_ok(struct pim_upstream *up)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
pim_ifp = ifp->info;
|
pim_ifp = ifp->info;
|
||||||
if (pim_ifp->mroute_vif_index != c_oil->oil.mfcc_parent)
|
if (pim_ifp->mroute_vif_index != *oil_parent(c_oil))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (pim_if_connected_to_source(up->rpf.source_nexthop.interface,
|
if (pim_if_connected_to_source(up->rpf.source_nexthop.interface,
|
||||||
|
Loading…
Reference in New Issue
Block a user