PIM: prefix-list support for selecting RP

Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by:   CCR-5173

Ticket: CM-12819
This commit is contained in:
Daniel Walton 2016-09-13 19:41:33 +00:00 committed by Donald Sharp
parent a9b5987989
commit dfe43e25d8
16 changed files with 406 additions and 95 deletions

View File

@ -25,6 +25,7 @@
#include "if.h"
#include "prefix.h"
#include "zclient.h"
#include "plist.h"
#include "pimd.h"
#include "pim_mroute.h"
@ -2439,27 +2440,52 @@ DEFUN (show_ip_ssmpingd,
}
static int
pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group)
pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const char *plist)
{
int result;
result = pim_rp_new (rp, group);
if (result == -1)
result = pim_rp_new (rp, group, plist);
if (result == PIM_MALLOC_FAIL)
{
vty_out (vty, "%% Bad RP/group address specified: %s", rp);
vty_out (vty, "%% Out of memory%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (result == -2)
if (result == PIM_GROUP_BAD_ADDRESS)
{
vty_out (vty, "%% No Path to RP address specified: %s", rp);
return CMD_WARNING;
vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
return CMD_WARNING;
}
if (result == -3)
if (result == PIM_RP_BAD_ADDRESS)
{
vty_out (vty, "%% Group range specified cannot overlap");
return CMD_ERR_NO_MATCH;
vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
return CMD_WARNING;
}
if (result == PIM_RP_NO_PATH)
{
vty_out (vty, "%% No Path to RP address specified: %s%s", rp, VTY_NEWLINE);
return CMD_WARNING;
}
if (result == PIM_GROUP_OVERLAP)
{
vty_out (vty, "%% Group range specified cannot overlap%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (result == PIM_GROUP_PFXLIST_OVERLAP)
{
vty_out (vty, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (result == PIM_RP_PFXLIST_IN_USE)
{
vty_out (vty, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
@ -2526,23 +2552,43 @@ DEFUN (ip_pim_rp,
"ip address of RP\n")
{
int idx_ipv4 = 3;
return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg);
return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
}
DEFUN (ip_pim_rp_prefix_list,
ip_pim_rp_prefix_list_cmd,
"ip pim rp A.B.C.D prefix-list WORD",
IP_STR
"pim multicast routing\n"
"Rendevous Point\n"
"ip address of RP\n"
"group prefix-list filter\n"
"Name of a prefix-list\n")
{
return pim_rp_cmd_worker (vty, argv[3]->arg, NULL, argv[5]->arg);
}
static int
pim_no_rp_cmd_worker (struct vty *vty, const char *rp, const char *group)
pim_no_rp_cmd_worker (struct vty *vty, const char *rp, const char *group,
const char *plist)
{
int result = pim_rp_del (rp, group);
int result = pim_rp_del (rp, group, plist);
if (result == -1)
if (result == PIM_GROUP_BAD_ADDRESS)
{
vty_out (vty, "%% Unable to Decode specified RP");
vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
return CMD_WARNING;
}
if (result == -2)
if (result == PIM_RP_BAD_ADDRESS)
{
vty_out (vty, "%% Unable to find specified RP");
vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
return CMD_WARNING;
}
if (result == PIM_RP_NOT_FOUND)
{
vty_out (vty, "%% Unable to find specified RP%s", VTY_NEWLINE);
return CMD_WARNING;
}
@ -2559,7 +2605,21 @@ DEFUN (no_ip_pim_rp,
"ip address of RP\n")
{
int idx_ipv4 = 4;
return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg);
return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
}
DEFUN (no_ip_pim_rp_prefix_list,
no_ip_pim_rp_prefix_list_cmd,
"no ip pim rp A.B.C.D prefix-list WORD",
NO_STR
IP_STR
"pim multicast routing\n"
"Rendevous Point\n"
"ip address of RP\n"
"group prefix-list filter\n"
"Name of a prefix-list\n")
{
return pim_no_rp_cmd_worker (vty, argv[4]->arg, NULL, argv[6]->arg);
}
DEFUN (ip_multicast_routing,
@ -4821,6 +4881,8 @@ void pim_cmd_init()
install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
install_element (CONFIG_NODE, &ip_pim_rp_cmd);
install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
install_element (CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
install_element (CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
install_element (CONFIG_NODE, &ip_pim_keep_alive_cmd);
install_element (CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
install_element (CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);

View File

@ -24,6 +24,8 @@
#include "log.h"
#include "prefix.h"
#include "if.h"
#include "vty.h"
#include "plist.h"
#include "pimd.h"
#include "pim_str.h"

View File

@ -22,6 +22,9 @@
#include <zebra.h>
#include "log.h"
#include "prefix.h"
#include "vty.h"
#include "plist.h"
#include "pim_macro.h"
#include "pimd.h"

View File

@ -45,6 +45,7 @@
#include "pim_signals.h"
#include "pim_zebra.h"
#include "pim_msdp.h"
#include "pim_rp.h"
#ifdef PIM_ZCLIENT_DEBUG
extern int zclient_debug;
@ -208,6 +209,9 @@ int main(int argc, char** argv, char** envp) {
vrf_init ();
access_list_init();
prefix_list_init ();
prefix_list_add_hook (pim_rp_prefix_list_update);
prefix_list_delete_hook (pim_rp_prefix_list_update);
pim_route_map_init ();
pim_init();
pim_msdp_init ();

View File

@ -40,3 +40,4 @@ DEFINE_MTYPE(PIMD, PIM_SSMPINGD, "PIM sspimgd socket")
DEFINE_MTYPE(PIMD, PIM_STATIC_ROUTE, "PIM Static Route")
DEFINE_MTYPE(PIMD, PIM_BR, "PIM Bridge Router info")
DEFINE_MTYPE(PIMD, PIM_RP, "PIM RP info")
DEFINE_MTYPE(PIMD, PIM_FILTER_NAME, "PIM Filter Name")

View File

@ -39,5 +39,6 @@ DECLARE_MTYPE(PIM_SSMPINGD)
DECLARE_MTYPE(PIM_STATIC_ROUTE)
DECLARE_MTYPE(PIM_BR)
DECLARE_MTYPE(PIM_RP)
DECLARE_MTYPE(PIM_FILTER_NAME)
#endif /* _QUAGGA_PIM_MEMORY_H */

View File

@ -24,6 +24,8 @@
#include "privs.h"
#include "if.h"
#include "prefix.h"
#include "vty.h"
#include "plist.h"
#include "pimd.h"
#include "pim_rpf.h"

View File

@ -23,6 +23,9 @@
#include "if.h"
#include "log.h"
#include "prefix.h"
#include "vty.h"
#include "plist.h"
#include "pimd.h"
#include "pim_vty.h"

View File

@ -25,6 +25,8 @@
#include "if.h"
#include "thread.h"
#include "prefix.h"
#include "vty.h"
#include "plist.h"
#include "pimd.h"
#include "pim_mroute.h"

View File

@ -28,6 +28,7 @@
#include "memory.h"
#include "vty.h"
#include "vrf.h"
#include "plist.h"
#include "pimd.h"
#include "pim_vty.h"
@ -44,6 +45,7 @@ struct rp_info
struct prefix group;
struct pim_rpf rp;
int i_am_rp;
char *plist;
};
static struct list *qpim_rp_list = NULL;
@ -70,6 +72,24 @@ pim_rp_list_cmp (void *v1, void *v2)
if (rp1 && !rp2)
return 1;
/*
* Sort by RP IP address
*/
if (rp1->rp.rpf_addr.u.prefix4.s_addr < rp2->rp.rpf_addr.u.prefix4.s_addr)
return -1;
if (rp1->rp.rpf_addr.u.prefix4.s_addr > rp2->rp.rpf_addr.u.prefix4.s_addr)
return 1;
/*
* Sort by group IP address
*/
if (rp1->group.u.prefix4.s_addr < rp2->group.u.prefix4.s_addr)
return -1;
if (rp1->group.u.prefix4.s_addr > rp2->group.u.prefix4.s_addr)
return 1;
if (rp1 == tail)
return 1;
@ -106,6 +126,50 @@ pim_rp_free (void)
list_free (qpim_rp_list);
}
/*
* Given an RP's prefix-list, return the RP's rp_info for that prefix-list
*/
static struct rp_info *
pim_rp_find_prefix_list (struct in_addr rp, const char *plist)
{
struct listnode *node;
struct rp_info *rp_info;
for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
{
if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr &&
rp_info->plist && strcmp(rp_info->plist, plist) == 0)
{
return rp_info;
}
}
return NULL;
}
/*
* Return true if plist is used by any rp_info
*/
static int
pim_rp_prefix_list_used (const char *plist)
{
struct listnode *node;
struct rp_info *rp_info;
for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
{
if (rp_info->plist && strcmp(rp_info->plist, plist) == 0)
{
return 1;
}
}
return 0;
}
/*
* Given an RP's address, return the RP's rp_info that is an exact match for 'group'
*/
static struct rp_info *
pim_rp_find_exact (struct in_addr rp, struct prefix *group)
{
@ -122,37 +186,67 @@ pim_rp_find_exact (struct in_addr rp, struct prefix *group)
return NULL;
}
static struct rp_info *
pim_rp_find_match (struct in_addr rp, struct prefix *group)
{
struct listnode *node;
struct rp_info *rp_info;
for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
{
if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr &&
prefix_match (&rp_info->group, group))
return rp_info;
}
return NULL;
}
/*
* Given a group, return the rp_info for that group
*/
static struct rp_info *
pim_rp_find_match_group (struct prefix *group)
{
struct listnode *node;
struct rp_info *rp_info;
struct prefix_list *plist;
for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
{
if (prefix_match (&rp_info->group, group))
return rp_info;
if (rp_info->plist)
{
plist = prefix_list_lookup (AFI_IP, rp_info->plist);
if (plist && prefix_list_apply (plist, group) == PREFIX_PERMIT)
return rp_info;
}
else
{
if (prefix_match (&rp_info->group, group))
return rp_info;
}
}
return NULL;
}
/*
* When the user makes "ip pim rp" configuration changes or if they change the
* prefix-list(s) used by these statements we must tickle the upstream state
* for each group to make them re-lookup who their RP should be.
*
* This is a placeholder function for now.
*/
static void
pim_rp_refresh_group_to_rp_mapping()
{
}
void
pim_rp_prefix_list_update (struct prefix_list *plist)
{
struct listnode *node;
struct rp_info *rp_info;
int refresh_needed = 0;
for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
{
if (rp_info->plist && strcmp(rp_info->plist, prefix_list_name (plist)) == 0)
{
refresh_needed = 1;
break;
}
}
if (refresh_needed)
pim_rp_refresh_group_to_rp_mapping();
}
static void
pim_rp_check_interfaces (struct rp_info *rp_info)
{
@ -172,19 +266,19 @@ pim_rp_check_interfaces (struct rp_info *rp_info)
}
int
pim_rp_new (const char *rp, const char *group_range)
pim_rp_new (const char *rp, const char *group_range, const char *plist)
{
int result;
struct rp_info *rp_info;
struct rp_info *rp_all;
struct prefix group_all;
str2prefix ("224.0.0.0/4", &group_all);
rp_all = pim_rp_find_match_group(&group_all);
struct listnode *node, *nnode;
struct rp_info *tmp_rp_info;
char buffer[BUFSIZ];
rp_info = XCALLOC (MTYPE_PIM_RP, sizeof (*rp_info));
if (!rp)
return -1;
if (!rp_info)
return PIM_MALLOC_FAIL;
if (group_range == NULL)
result = str2prefix ("224.0.0.0/4", &rp_info->group);
@ -192,54 +286,147 @@ pim_rp_new (const char *rp, const char *group_range)
result = str2prefix (group_range, &rp_info->group);
if (!result)
return -1;
{
XFREE (MTYPE_PIM_RP, rp_info);
return PIM_GROUP_BAD_ADDRESS;
}
rp_info->rp.rpf_addr.family = AF_INET;
result = inet_pton (rp_info->rp.rpf_addr.family, rp, &rp_info->rp.rpf_addr.u.prefix4);
if (result <= 0)
return -1;
/*
* Take over the 224.0.0.0/4 group if the rp is INADDR_NONE
*/
if (prefix_same (&rp_all->group, &rp_info->group) &&
pim_rpf_addr_is_inaddr_none (&rp_all->rp))
{
rp_all->rp.rpf_addr = rp_info->rp.rpf_addr;
XFREE (MTYPE_PIM_RP, rp_info);
if (!pim_rp_setup ())
return -2;
pim_rp_check_interfaces (rp_all);
return 0;
}
if (pim_rp_find_exact (rp_info->rp.rpf_addr.u.prefix4, &rp_info->group))
{
XFREE (MTYPE_PIM_RP, rp_info);
return 0;
return PIM_RP_BAD_ADDRESS;
}
if (pim_rp_find_match (rp_info->rp.rpf_addr.u.prefix4, &rp_info->group))
if (plist)
{
if (prefix_same (&group_all, &rp_info->group))
/*
* Return if the prefix-list is already configured for this RP
*/
if (pim_rp_find_prefix_list (rp_info->rp.rpf_addr.u.prefix4, plist))
{
return 0;
XFREE (MTYPE_PIM_RP, rp_info);
return PIM_SUCCESS;
}
XFREE (MTYPE_PIM_RP, rp_info);
return -3;
/*
* Barf if the prefix-list is already configured for an RP
*/
if (pim_rp_prefix_list_used (plist))
{
XFREE (MTYPE_PIM_RP, rp_info);
return PIM_RP_PFXLIST_IN_USE;
}
/*
* Free any existing rp_info entries for this RP
*/
for (ALL_LIST_ELEMENTS (qpim_rp_list, node, nnode, tmp_rp_info))
{
if (rp_info->rp.rpf_addr.u.prefix4.s_addr == tmp_rp_info->rp.rpf_addr.u.prefix4.s_addr)
{
if (tmp_rp_info->plist)
pim_rp_del (rp, NULL, tmp_rp_info->plist);
else
pim_rp_del (rp, prefix2str(&tmp_rp_info->group, buffer, BUFSIZ), NULL);
}
}
rp_info->plist = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist);
}
else
{
str2prefix ("224.0.0.0/4", &group_all);
rp_all = pim_rp_find_match_group(&group_all);
/*
* Barf if group is a non-multicast subnet
*/
if (! prefix_match (&rp_all->group, &rp_info->group))
{
XFREE (MTYPE_PIM_RP, rp_info);
return PIM_GROUP_BAD_ADDRESS;
}
/*
* Remove any prefix-list rp_info entries for this RP
*/
for (ALL_LIST_ELEMENTS (qpim_rp_list, node, nnode, tmp_rp_info))
{
if (tmp_rp_info->plist &&
rp_info->rp.rpf_addr.u.prefix4.s_addr == tmp_rp_info->rp.rpf_addr.u.prefix4.s_addr)
{
pim_rp_del (rp, NULL, tmp_rp_info->plist);
}
}
/*
* Take over the 224.0.0.0/4 group if the rp is INADDR_NONE
*/
if (prefix_same (&rp_all->group, &rp_info->group) &&
pim_rpf_addr_is_inaddr_none (&rp_all->rp))
{
rp_all->rp.rpf_addr = rp_info->rp.rpf_addr;
XFREE (MTYPE_PIM_RP, rp_info);
if (!pim_rp_setup ())
return PIM_RP_NO_PATH;
pim_rp_check_interfaces (rp_all);
return PIM_SUCCESS;
}
/*
* Return if the group is already configured for this RP
*/
if (pim_rp_find_exact (rp_info->rp.rpf_addr.u.prefix4, &rp_info->group))
{
XFREE (MTYPE_PIM_RP, rp_info);
return PIM_SUCCESS;
}
/*
* Barf if this group is already covered by some other RP
*/
tmp_rp_info = pim_rp_find_match_group (&rp_info->group);
if (tmp_rp_info)
{
if (tmp_rp_info->plist)
{
XFREE (MTYPE_PIM_RP, rp_info);
return PIM_GROUP_PFXLIST_OVERLAP;
}
else
{
/*
* If the only RP that covers this group is an RP configured for
* 224.0.0.0/4 that is fine, ignore that one. For all others
* though we must return PIM_GROUP_OVERLAP
*/
if (! prefix_same (&group_all, &tmp_rp_info->group))
{
XFREE (MTYPE_PIM_RP, rp_info);
return PIM_GROUP_OVERLAP;
}
}
}
}
listnode_add_sort (qpim_rp_list, rp_info);
if (!pim_rp_setup ())
return -2;
return PIM_RP_NO_PATH;
pim_rp_check_interfaces (rp_info);
return 0;
pim_rp_refresh_group_to_rp_mapping();
return PIM_SUCCESS;
}
int
pim_rp_del (const char *rp, const char *group_range)
pim_rp_del (const char *rp, const char *group_range, const char *plist)
{
struct prefix group;
struct in_addr rp_addr;
@ -248,35 +435,46 @@ pim_rp_del (const char *rp, const char *group_range)
struct rp_info *rp_all;
int result;
str2prefix ("224.0.0.0/4", &g_all);
if (group_range == NULL)
result = str2prefix ("224.0.0.0/4", &group);
else
result = str2prefix (group_range, &group);
if (!result)
return -1;
rp_all = pim_rp_find_match_group (&g_all);
return PIM_GROUP_BAD_ADDRESS;
result = inet_pton (AF_INET, rp, &rp_addr);
if (result <= 0)
return -1;
return PIM_RP_BAD_ADDRESS;
if (plist)
rp_info = pim_rp_find_prefix_list (rp_addr, plist);
else
rp_info = pim_rp_find_exact (rp_addr, &group);
rp_info = pim_rp_find_exact (rp_addr, &group);
if (!rp_info)
return -2;
return PIM_RP_NOT_FOUND;
if (rp_info->plist)
{
XFREE(MTYPE_PIM_FILTER_NAME, rp_info->plist);
rp_info->plist = NULL;
}
str2prefix ("224.0.0.0/4", &g_all);
rp_all = pim_rp_find_match_group (&g_all);
if (rp_all == rp_info)
{
rp_all->rp.rpf_addr.family = AF_INET;
rp_all->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
rp_all->i_am_rp = 0;
return 0;
return PIM_SUCCESS;
}
listnode_delete (qpim_rp_list, rp_info);
return 0;
pim_rp_refresh_group_to_rp_mapping();
return PIM_SUCCESS;
}
int
@ -430,7 +628,8 @@ pim_rp_config_write (struct vty *vty)
{
struct listnode *node;
struct rp_info *rp_info;
char buffer[32];
char rp_buffer[32];
char group_buffer[32];
int count = 0;
for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
@ -438,13 +637,15 @@ pim_rp_config_write (struct vty *vty)
if (pim_rpf_addr_is_inaddr_none (&rp_info->rp))
continue;
if (!pim_rpf_addr_is_inaddr_none (&rp_info->rp))
{
char buf[32];
vty_out(vty, "ip pim rp %s %s%s", inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, buffer, 32),
prefix2str(&rp_info->group, buf, 32), VTY_NEWLINE);
count++;
}
if (rp_info->plist)
vty_out(vty, "ip pim rp %s prefix-list %s%s",
inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp_buffer, 32),
rp_info->plist, VTY_NEWLINE);
else
vty_out(vty, "ip pim rp %s %s%s",
inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp_buffer, 32),
prefix2str(&rp_info->group, group_buffer, 32), VTY_NEWLINE);
count++;
}
return count;
@ -486,18 +687,25 @@ pim_rp_show_information (struct vty *vty)
struct rp_info *rp_info;
struct listnode *node;
vty_out (vty, "RP Addr Group Oif I_am_RP%s", VTY_NEWLINE);
vty_out (vty, "RP address group/prefix-list OIF I am RP%s", VTY_NEWLINE);
for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
{
if (!pim_rpf_addr_is_inaddr_none (&rp_info->rp))
{
char buf[48];
vty_out (vty, "%-10s %-10s %-10s%-10d%s",
inet_ntoa (rp_info->rp.rpf_addr.u.prefix4),
prefix2str(&rp_info->group, buf, 48),
rp_info->rp.source_nexthop.interface->name,
rp_info->i_am_rp, VTY_NEWLINE);
vty_out (vty, "%-15s ", inet_ntoa (rp_info->rp.rpf_addr.u.prefix4));
if (rp_info->plist)
vty_out (vty, "%-18s ", rp_info->plist);
else
vty_out (vty, "%-18s ", prefix2str(&rp_info->group, buf, 48));
vty_out (vty, "%-10s ", rp_info->rp.source_nexthop.interface->name);
if (rp_info->i_am_rp)
vty_out (vty, "yes%s", VTY_NEWLINE);
else
vty_out (vty, "no%s", VTY_NEWLINE);
}
}
return;
}

View File

@ -24,8 +24,9 @@
void pim_rp_init (void);
void pim_rp_free (void);
int pim_rp_new (const char *rp, const char *group);
int pim_rp_del (const char *rp, const char *group);
int pim_rp_new (const char *rp, const char *group, const char *plist);
int pim_rp_del (const char *rp, const char *group, const char *plist);
void pim_rp_prefix_list_update (struct prefix_list *plist);
int pim_rp_config_write (struct vty *vty);

View File

@ -28,6 +28,8 @@
#include "memory.h"
#include "thread.h"
#include "linklist.h"
#include "vty.h"
#include "plist.h"
#include "pimd.h"
#include "pim_pim.h"

View File

@ -23,7 +23,10 @@
#include "if.h"
#include "linklist.h"
#include "prefix.h"
#include "vty.h"
#include "vrf.h"
#include "plist.h"
#include "pimd.h"
#include "pim_vty.h"

View File

@ -29,6 +29,8 @@
#include "zclient.h"
#include "stream.h"
#include "network.h"
#include "vty.h"
#include "plist.h"
#include "pimd.h"
#include "pim_pim.h"

View File

@ -24,6 +24,9 @@
#include "log.h"
#include "memory.h"
#include "if.h"
#include "prefix.h"
#include "vty.h"
#include "plist.h"
#include "pimd.h"
#include "pim_cmd.h"

View File

@ -71,6 +71,18 @@
#define PIM_MASK_STATIC (1 << 17)
#define PIM_MASK_PIM_REG (1 << 18)
/* PIM error codes */
#define PIM_SUCCESS 0
#define PIM_MALLOC_FAIL -1
#define PIM_GROUP_BAD_ADDRESS -2
#define PIM_GROUP_OVERLAP -3
#define PIM_GROUP_PFXLIST_OVERLAP -4
#define PIM_RP_BAD_ADDRESS -5
#define PIM_RP_NO_PATH -6
#define PIM_RP_NOT_FOUND -7
#define PIM_RP_PFXLIST_IN_USE -8
const char *const PIM_ALL_SYSTEMS;
const char *const PIM_ALL_ROUTERS;
const char *const PIM_ALL_PIM_ROUTERS;