From dfe43e25d86672eef58044455be09a8c3840ca3a Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 13 Sep 2016 19:41:33 +0000 Subject: [PATCH] PIM: prefix-list support for selecting RP Signed-off-by: Daniel Walton Reviewed-by: CCR-5173 Ticket: CM-12819 --- pimd/pim_cmd.c | 98 ++++++++++--- pimd/pim_join.c | 2 + pimd/pim_macro.c | 3 + pimd/pim_main.c | 4 + pimd/pim_memory.c | 1 + pimd/pim_memory.h | 1 + pimd/pim_mroute.c | 2 + pimd/pim_msg.c | 3 + pimd/pim_register.c | 2 + pimd/pim_rp.c | 332 +++++++++++++++++++++++++++++++++++--------- pimd/pim_rp.h | 5 +- pimd/pim_upstream.c | 2 + pimd/pim_vty.c | 3 + pimd/pim_zebra.c | 2 + pimd/pimd.c | 3 + pimd/pimd.h | 12 ++ 16 files changed, 393 insertions(+), 82 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index fd4da2929..9b58b891e 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -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, "%% Out of memory%s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (result == PIM_GROUP_BAD_ADDRESS) + { + vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE); + return CMD_WARNING; + } + + if (result == PIM_RP_BAD_ADDRESS) { - vty_out (vty, "%% Bad RP/group address specified: %s", rp); + vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE); return CMD_WARNING; } - if (result == -2) + if (result == PIM_RP_NO_PATH) { - vty_out (vty, "%% No Path to RP address specified: %s", rp); - return CMD_WARNING; + 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 == -3) + if (result == PIM_RP_PFXLIST_IN_USE) { - vty_out (vty, "%% Group range specified cannot overlap"); - return CMD_ERR_NO_MATCH; + 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 == PIM_GROUP_BAD_ADDRESS) + { + vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE); + return CMD_WARNING; + } - if (result == -1) + if (result == PIM_RP_BAD_ADDRESS) { - vty_out (vty, "%% Unable to Decode specified RP"); + vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE); return CMD_WARNING; } - if (result == -2) + if (result == PIM_RP_NOT_FOUND) { - vty_out (vty, "%% Unable to find specified RP"); + 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); diff --git a/pimd/pim_join.c b/pimd/pim_join.c index 1f722e763..7bec6c7ec 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -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" diff --git a/pimd/pim_macro.c b/pimd/pim_macro.c index 4bcb62a90..177de6667 100644 --- a/pimd/pim_macro.c +++ b/pimd/pim_macro.c @@ -22,6 +22,9 @@ #include #include "log.h" +#include "prefix.h" +#include "vty.h" +#include "plist.h" #include "pim_macro.h" #include "pimd.h" diff --git a/pimd/pim_main.c b/pimd/pim_main.c index 53c7e092a..1ddc1eac5 100644 --- a/pimd/pim_main.c +++ b/pimd/pim_main.c @@ -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 (); diff --git a/pimd/pim_memory.c b/pimd/pim_memory.c index 9994ea5d6..219dd9681 100644 --- a/pimd/pim_memory.c +++ b/pimd/pim_memory.c @@ -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") diff --git a/pimd/pim_memory.h b/pimd/pim_memory.h index 3d3f14467..fc0dd91f8 100644 --- a/pimd/pim_memory.h +++ b/pimd/pim_memory.h @@ -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 */ diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 1bd1b4457..1f64a6e29 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -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" diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c index 62e0bb1a3..0eadb5eb3 100644 --- a/pimd/pim_msg.c +++ b/pimd/pim_msg.c @@ -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" diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 4131c5ef0..ebc46f60e 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -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" diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index daf825f6d..78dc0e855 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -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,8 +126,11 @@ 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_exact (struct in_addr rp, struct prefix *group) +pim_rp_find_prefix_list (struct in_addr rp, const char *plist) { struct listnode *node; struct rp_info *rp_info; @@ -115,15 +138,40 @@ pim_rp_find_exact (struct in_addr rp, struct prefix *group) 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_same (&rp_info->group, group)) - return rp_info; + 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_match (struct in_addr rp, struct prefix *group) +pim_rp_find_exact (struct in_addr rp, struct prefix *group) { struct listnode *node; struct rp_info *rp_info; @@ -131,28 +179,74 @@ pim_rp_find_match (struct in_addr rp, struct prefix *group) 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)) + prefix_same (&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)) + if (result <= 0) { - 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; + return PIM_RP_BAD_ADDRESS; } - if (pim_rp_find_exact (rp_info->rp.rpf_addr.u.prefix4, &rp_info->group)) + if (plist) { - XFREE (MTYPE_PIM_RP, rp_info); - return 0; - } + /* + * 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)) + { + XFREE (MTYPE_PIM_RP, rp_info); + return PIM_SUCCESS; + } + + /* + * 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); + } + } - if (pim_rp_find_match (rp_info->rp.rpf_addr.u.prefix4, &rp_info->group)) + rp_info->plist = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist); + } + else { - if (prefix_same (&group_all, &rp_info->group)) + 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)) { - return 0; + XFREE (MTYPE_PIM_RP, rp_info); + return PIM_GROUP_BAD_ADDRESS; } - XFREE (MTYPE_PIM_RP, rp_info); - return -3; + /* + * 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; } diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index c9dfa201f..230f4f08f 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -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); diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 66c5268f9..7f1357783 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -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" diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 85df83287..3eb04d347 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -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" diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index d4eb2d325..cfdc447fc 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -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" diff --git a/pimd/pimd.c b/pimd/pimd.c index 94c8f20e9..dff3f75ae 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -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" diff --git a/pimd/pimd.h b/pimd/pimd.h index f7a02f937..46b3e5ce7 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -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; -- 2.39.2