+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* PIM for Quagga: add the ability to configure multicast static routes
* Copyright (C) 2014 Nathan Bahr, ATCorp
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "linklist.h"
#include "pimd.h"
+#include "pim_instance.h"
#include "pim_oil.h"
#include "pim_static.h"
#include "pim_time.h"
}
static struct static_route *static_route_new(ifindex_t iif, ifindex_t oif,
- struct in_addr group,
- struct in_addr source)
+ pim_addr group,
+ pim_addr source)
{
struct static_route *s_route;
s_route = static_route_alloc();
s_route->iif = iif;
s_route->oif_ttls[oif] = 1;
s_route->c_oil.oil_ref_count = 1;
- s_route->c_oil.oil.mfcc_origin = source;
- s_route->c_oil.oil.mfcc_mcastgrp = group;
- s_route->c_oil.oil.mfcc_parent = iif;
- s_route->c_oil.oil.mfcc_ttls[oif] = 1;
+ *oil_origin(&s_route->c_oil) = source;
+ *oil_mcastgrp(&s_route->c_oil) = group;
+ *oil_parent(&s_route->c_oil) = iif;
+ oil_if_set(&s_route->c_oil, oif, 1);
s_route->c_oil.oif_creation[oif] = pim_time_monotonic_sec();
return s_route;
int pim_static_add(struct pim_instance *pim, struct interface *iif,
- struct interface *oif, struct in_addr group,
- struct in_addr source)
+ struct interface *oif, pim_addr group, pim_addr source)
{
struct listnode *node = NULL;
struct static_route *s_route = NULL;
}
for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
- if (s_route->group.s_addr == group.s_addr
- && s_route->source.s_addr == source.s_addr) {
- if (s_route->iif == iif_index
- && s_route->oif_ttls[oif_index]) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
- sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
- sizeof(sifaddr_str));
+ if (!pim_addr_cmp(s_route->group, group) &&
+ !pim_addr_cmp(s_route->source, source) &&
+ (s_route->iif == iif_index)) {
+
+ if (s_route->oif_ttls[oif_index]) {
zlog_warn(
- "%s %s: Unable to add static route: Route already exists (iif=%d,oif=%d,group=%s,source=%s)",
+ "%s %s: Unable to add static route: Route already exists (iif=%d,oif=%d,group=%pPAs,source=%pPAs)",
__FILE__, __func__, iif_index,
- oif_index, gifaddr_str, sifaddr_str);
+ oif_index, &group, &source);
return -3;
}
/* Route exists and has the same input interface, but
* adding a new output interface */
- if (s_route->iif == iif_index) {
- s_route->oif_ttls[oif_index] = 1;
- s_route->c_oil.oil.mfcc_ttls[oif_index] = 1;
- s_route->c_oil.oif_creation[oif_index] =
- pim_time_monotonic_sec();
- ++s_route->c_oil.oil_ref_count;
- } else {
- /* input interface changed */
- s_route->iif = iif_index;
- pim_static_mroute_iif_update(
- &s_route->c_oil, iif_index, __func__);
-
-#ifdef PIM_ENFORCE_LOOPFREE_MFC
- /* check to make sure the new input was not an
- * old output */
- if (s_route->oif_ttls[iif_index]) {
- s_route->oif_ttls[iif_index] = 0;
- s_route->c_oil.oif_creation[iif_index] =
- 0;
- s_route->c_oil.oil
- .mfcc_ttls[iif_index] = 0;
- --s_route->c_oil.oil_ref_count;
- }
-#endif
-
- /* now add the new output, if it is new */
- if (!s_route->oif_ttls[oif_index]) {
- s_route->oif_ttls[oif_index] = 1;
- s_route->c_oil.oif_creation[oif_index] =
- pim_time_monotonic_sec();
- s_route->c_oil.oil
- .mfcc_ttls[oif_index] = 1;
- ++s_route->c_oil.oil_ref_count;
- }
- }
-
+ s_route->oif_ttls[oif_index] = 1;
+ oil_if_set(&s_route->c_oil, oif_index, 1);
+ s_route->c_oil.oif_creation[oif_index] =
+ pim_time_monotonic_sec();
+ ++s_route->c_oil.oil_ref_count;
break;
}
}
s_route->c_oil.pim = pim;
if (pim_static_mroute_add(&s_route->c_oil, __func__)) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
- sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
- sizeof(sifaddr_str));
zlog_warn(
- "%s %s: Unable to add static route(iif=%d,oif=%d,group=%s,source=%s)",
- __FILE__, __func__, iif_index, oif_index, gifaddr_str,
- sifaddr_str);
+ "%s %s: Unable to add static route(iif=%d,oif=%d,group=%pPAs,source=%pPAs)",
+ __FILE__, __func__, iif_index, oif_index, &group,
+ &source);
/* Need to put s_route back to the way it was */
if (original_s_route) {
}
if (PIM_DEBUG_STATIC) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
- sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
- sizeof(sifaddr_str));
zlog_debug(
- "%s: Static route added(iif=%d,oif=%d,group=%s,source=%s)",
- __func__, iif_index, oif_index, gifaddr_str,
- sifaddr_str);
+ "%s: Static route added(iif=%d,oif=%d,group=%pPAs,source=%pPAs)",
+ __func__, iif_index, oif_index, &group,
+ &source);
}
return 0;
}
int pim_static_del(struct pim_instance *pim, struct interface *iif,
- struct interface *oif, struct in_addr group,
- struct in_addr source)
+ struct interface *oif, pim_addr group, pim_addr source)
{
struct listnode *node = NULL;
struct listnode *nextnode = NULL;
for (ALL_LIST_ELEMENTS(pim->static_routes, node, nextnode, s_route)) {
if (s_route->iif == iif_index
- && s_route->group.s_addr == group.s_addr
- && s_route->source.s_addr == source.s_addr
+ && !pim_addr_cmp(s_route->group, group)
+ && !pim_addr_cmp(s_route->source, source)
&& s_route->oif_ttls[oif_index]) {
s_route->oif_ttls[oif_index] = 0;
- s_route->c_oil.oil.mfcc_ttls[oif_index] = 0;
+ oil_if_set(&s_route->c_oil, oif_index, 0);
--s_route->c_oil.oil_ref_count;
/* If there are no more outputs then delete the whole
? pim_mroute_del(&s_route->c_oil, __func__)
: pim_static_mroute_add(&s_route->c_oil,
__func__)) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
- sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
- sizeof(sifaddr_str));
zlog_warn(
- "%s %s: Unable to remove static route(iif=%d,oif=%d,group=%s,source=%s)",
+ "%s %s: Unable to remove static route(iif=%d,oif=%d,group=%pPAs,source=%pPAs)",
__FILE__, __func__, iif_index,
- oif_index, gifaddr_str, sifaddr_str);
+ oif_index, &group, &source);
s_route->oif_ttls[oif_index] = 1;
- s_route->c_oil.oil.mfcc_ttls[oif_index] = 1;
+ oil_if_set(&s_route->c_oil, oif_index, 1);
++s_route->c_oil.oil_ref_count;
return -1;
}
if (PIM_DEBUG_STATIC) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
- sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
- sizeof(sifaddr_str));
zlog_debug(
- "%s: Static route removed(iif=%d,oif=%d,group=%s,source=%s)",
+ "%s: Static route removed(iif=%d,oif=%d,group=%pPAs,source=%pPAs)",
__func__, iif_index, oif_index,
- gifaddr_str, sifaddr_str);
+ &group, &source);
}
break;
}
if (!node) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
- sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
- sizeof(sifaddr_str));
zlog_warn(
- "%s %s: Unable to remove static route: Route does not exist(iif=%d,oif=%d,group=%s,source=%s)",
- __FILE__, __func__, iif_index, oif_index, gifaddr_str,
- sifaddr_str);
+ "%s %s: Unable to remove static route: Route does not exist(iif=%d,oif=%d,group=%pPAs,source=%pPAs)",
+ __FILE__, __func__, iif_index, oif_index, &group,
+ &source);
return -3;
}
struct listnode *node;
struct static_route *sroute;
int count = 0;
- char sbuf[INET_ADDRSTRLEN];
- char gbuf[INET_ADDRSTRLEN];
if (!pim_ifp)
return 0;
for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sroute)) {
- pim_inet4_dump("<ifaddr?>", sroute->group, gbuf, sizeof(gbuf));
- pim_inet4_dump("<ifaddr?>", sroute->source, sbuf, sizeof(sbuf));
if (sroute->iif == pim_ifp->mroute_vif_index) {
int i;
for (i = 0; i < MAXVIFS; i++)
struct interface *oifp =
pim_if_find_by_vif_index(pim,
i);
- if (sroute->source.s_addr == INADDR_ANY)
+ if (pim_addr_is_any(sroute->source))
vty_out(vty,
- " ip mroute %s %s\n",
- oifp->name, gbuf);
+ " " PIM_AF_NAME " mroute %s %pPA\n",
+ oifp->name, &sroute->group);
else
vty_out(vty,
- " ip mroute %s %s %s\n",
- oifp->name, gbuf, sbuf);
+ " " PIM_AF_NAME " mroute %s %pPA %pPA\n",
+ oifp->name, &sroute->group,
+ &sroute->source);
count++;
}
}