/*
- 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
-*/
+ * 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>
XFREE(MTYPE_PIM_STATIC_ROUTE, s_route);
}
-static struct static_route *static_route_alloc()
+static struct static_route *static_route_alloc(void)
{
- struct static_route *s_route;
-
- s_route = XCALLOC(MTYPE_PIM_STATIC_ROUTE, sizeof(*s_route));
- if (!s_route) {
- zlog_err("PIM XCALLOC(%zu) failure", sizeof(*s_route));
- return 0;
- }
- return s_route;
+ return XCALLOC(MTYPE_PIM_STATIC_ROUTE, sizeof(struct static_route));
}
-static struct static_route *static_route_new(unsigned int iif, unsigned int oif,
+static struct static_route *static_route_new(ifindex_t iif, ifindex_t oif,
struct in_addr group,
struct in_addr source)
{
struct static_route *s_route;
s_route = static_route_alloc();
- if (!s_route) {
- return 0;
- }
s_route->group = group;
s_route->source = source;
}
-int pim_static_add(struct interface *iif, struct interface *oif,
- struct in_addr group, struct in_addr source)
+int pim_static_add(struct pim_instance *pim, struct interface *iif,
+ struct interface *oif, struct in_addr group,
+ struct in_addr source)
{
struct listnode *node = NULL;
struct static_route *s_route = NULL;
ifindex_t iif_index = pim_iif ? pim_iif->mroute_vif_index : 0;
ifindex_t oif_index = pim_oif ? pim_oif->mroute_vif_index : 0;
- if (!iif_index || !oif_index) {
+ if (!iif_index || !oif_index || iif_index == -1 || oif_index == -1) {
zlog_warn(
"%s %s: Unable to add static route: Invalid interface index(iif=%d,oif=%d)",
__FILE__, __PRETTY_FUNCTION__, iif_index, oif_index);
return -4;
}
#endif
+ if (iif->vrf_id != oif->vrf_id) {
+ return -3;
+ }
- for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
+ 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
* back if it fails.
*/
original_s_route = static_route_alloc();
- if (!original_s_route) {
- return -5;
- }
memcpy(original_s_route, s_route,
sizeof(struct static_route));
} else {
/* input interface changed */
s_route->iif = iif_index;
- s_route->c_oil.oil.mfcc_parent = iif_index;
+ pim_channel_oil_change_iif(pim, &s_route->c_oil,
+ iif_index,
+ __PRETTY_FUNCTION__);
#ifdef PIM_ENFORCE_LOOPFREE_MFC
/* check to make sure the new input was not an
* match */
if (!node) {
s_route = static_route_new(iif_index, oif_index, group, source);
- listnode_add(qpim_static_route_list, s_route);
+ listnode_add(pim->static_routes, s_route);
}
+ s_route->c_oil.pim = pim;
+
if (pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__)) {
char gifaddr_str[INET_ADDRSTRLEN];
char sifaddr_str[INET_ADDRSTRLEN];
} else {
/* we never stored off a copy, so it must have been a
* fresh new route */
- listnode_delete(qpim_static_route_list, s_route);
+ listnode_delete(pim->static_routes, s_route);
pim_static_route_free(s_route);
}
return 0;
}
-int pim_static_del(struct interface *iif, struct interface *oif,
- struct in_addr group, struct in_addr source)
+int pim_static_del(struct pim_instance *pim, struct interface *iif,
+ struct interface *oif, struct in_addr group,
+ struct in_addr source)
{
struct listnode *node = NULL;
struct listnode *nextnode = NULL;
return -2;
}
- for (ALL_LIST_ELEMENTS(qpim_static_route_list, node, nextnode,
- s_route)) {
+ 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
s_route->c_oil.oif_creation[oif_index] = 0;
if (s_route->c_oil.oil_ref_count <= 0) {
- listnode_delete(qpim_static_route_list,
- s_route);
+ listnode_delete(pim->static_routes, s_route);
pim_static_route_free(s_route);
}
return 0;
}
-int pim_static_write_mroute(struct vty *vty, struct interface *ifp)
+int pim_static_write_mroute(struct pim_instance *pim, struct vty *vty,
+ struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
struct listnode *node;
if (!pim_ifp)
return 0;
- for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, sroute)) {
+ 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) {
for (i = 0; i < MAXVIFS; i++)
if (sroute->oif_ttls[i]) {
struct interface *oifp =
- pim_if_find_by_vif_index(i);
+ pim_if_find_by_vif_index(pim,
+ i);
if (sroute->source.s_addr == 0)
vty_out(vty,
- " ip mroute %s %s%s",
- oifp->name, gbuf,
- VTY_NEWLINE);
+ " ip mroute %s %s\n",
+ oifp->name, gbuf);
else
vty_out(vty,
- " ip mroute %s %s %s%s",
- oifp->name, gbuf, sbuf,
- VTY_NEWLINE);
+ " ip mroute %s %s %s\n",
+ oifp->name, gbuf, sbuf);
count++;
}
}