diff options
| author | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:03:14 +0200 |
|---|---|---|
| committer | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:04:07 +0200 |
| commit | d62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch) | |
| tree | 3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /pimd/pim_rp.c | |
| parent | 888ac268a0077fc9ebd1218cec6ae472af0bfc40 (diff) | |
*: reindentreindent-master-after
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'pimd/pim_rp.c')
| -rw-r--r-- | pimd/pim_rp.c | 1640 |
1 files changed, 826 insertions, 814 deletions
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 28300dbdff..2fe0143a87 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -48,158 +48,147 @@ static struct list *qpim_rp_list = NULL; static struct rp_info *tail = NULL; -static void -pim_rp_info_free (struct rp_info *rp_info) +static void pim_rp_info_free(struct rp_info *rp_info) { - XFREE (MTYPE_PIM_RP, rp_info); + XFREE(MTYPE_PIM_RP, rp_info); } -int -pim_rp_list_cmp (void *v1, void *v2) +int pim_rp_list_cmp(void *v1, void *v2) { - struct rp_info *rp1 = (struct rp_info *)v1; - struct rp_info *rp2 = (struct rp_info *)v2; - - /* - * 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; - - return 0; + struct rp_info *rp1 = (struct rp_info *)v1; + struct rp_info *rp2 = (struct rp_info *)v2; + + /* + * 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; + + return 0; } -void -pim_rp_init (void) +void pim_rp_init(void) { - struct rp_info *rp_info; + struct rp_info *rp_info; - qpim_rp_list = list_new (); - qpim_rp_list->del = (void (*)(void *))pim_rp_info_free; - qpim_rp_list->cmp = pim_rp_list_cmp; + qpim_rp_list = list_new(); + qpim_rp_list->del = (void (*)(void *))pim_rp_info_free; + qpim_rp_list->cmp = pim_rp_list_cmp; - rp_info = XCALLOC (MTYPE_PIM_RP, sizeof (*rp_info)); + rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info)); - if (!rp_info) - return; + if (!rp_info) + return; - str2prefix ("224.0.0.0/4", &rp_info->group); - rp_info->group.family = AF_INET; - rp_info->rp.rpf_addr.family = AF_INET; - rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN; - rp_info->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE; - tail = rp_info; + str2prefix("224.0.0.0/4", &rp_info->group); + rp_info->group.family = AF_INET; + rp_info->rp.rpf_addr.family = AF_INET; + rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN; + rp_info->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE; + tail = rp_info; - listnode_add (qpim_rp_list, rp_info); + listnode_add(qpim_rp_list, rp_info); } -void -pim_rp_free (void) +void pim_rp_free(void) { - if (qpim_rp_list) - list_delete (qpim_rp_list); - qpim_rp_list = NULL; + if (qpim_rp_list) + list_delete(qpim_rp_list); + qpim_rp_list = NULL; } /* * 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) +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; + 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) +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; + 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' + * 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) +static struct rp_info *pim_rp_find_exact(struct in_addr rp, + struct prefix *group) { - struct listnode *node; - struct rp_info *rp_info; + 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_same (&rp_info->group, group)) - return 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_same(&rp_info->group, group)) + return rp_info; + } - return NULL; + return NULL; } /* * Given a group, return the rp_info for that group */ -static struct rp_info * -pim_rp_find_match_group (struct prefix *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 (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; + struct listnode *node; + struct rp_info *rp_info; + struct prefix_list *plist; + + for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, 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; } /* @@ -209,480 +198,475 @@ pim_rp_find_match_group (struct prefix *group) * * This is a placeholder function for now. */ -static void -pim_rp_refresh_group_to_rp_mapping() +static void pim_rp_refresh_group_to_rp_mapping() { - pim_msdp_i_am_rp_changed(); + pim_msdp_i_am_rp_changed(); } -void -pim_rp_prefix_list_update (struct prefix_list *plist) +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(); + 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 int -pim_rp_check_interface_addrs(struct rp_info *rp_info, - struct pim_interface *pim_ifp) +static int pim_rp_check_interface_addrs(struct rp_info *rp_info, + struct pim_interface *pim_ifp) { - struct listnode *node; - struct pim_secondary_addr *sec_addr; + struct listnode *node; + struct pim_secondary_addr *sec_addr; - if (pim_ifp->primary_address.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr) - return 1; + if (pim_ifp->primary_address.s_addr + == rp_info->rp.rpf_addr.u.prefix4.s_addr) + return 1; - if (!pim_ifp->sec_addr_list) { - return 0; - } + if (!pim_ifp->sec_addr_list) { + return 0; + } - for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) { - if (prefix_same(&sec_addr->addr, &rp_info->rp.rpf_addr)) { - return 1; - } - } + for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) { + if (prefix_same(&sec_addr->addr, &rp_info->rp.rpf_addr)) { + return 1; + } + } - return 0; + return 0; } -static void -pim_rp_check_interfaces (struct rp_info *rp_info) +static void pim_rp_check_interfaces(struct rp_info *rp_info) { - struct listnode *node; - struct interface *ifp; + struct listnode *node; + struct interface *ifp; - rp_info->i_am_rp = 0; - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) - { - struct pim_interface *pim_ifp = ifp->info; + rp_info->i_am_rp = 0; + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + struct pim_interface *pim_ifp = ifp->info; - if (!pim_ifp) - continue; + if (!pim_ifp) + continue; - if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) { - rp_info->i_am_rp = 1; - } - } + if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) { + rp_info->i_am_rp = 1; + } + } } -int -pim_rp_new (const char *rp, const char *group_range, const char *plist) +int pim_rp_new(const char *rp, const char *group_range, const char *plist) { - int result = 0; - struct rp_info *rp_info; - struct rp_info *rp_all; - struct prefix group_all; - struct listnode *node, *nnode; - struct rp_info *tmp_rp_info; - char buffer[BUFSIZ]; - struct prefix nht_p; - struct pim_nexthop_cache pnc; - - rp_info = XCALLOC (MTYPE_PIM_RP, sizeof (*rp_info)); - if (!rp_info) - return PIM_MALLOC_FAIL; - - if (group_range == NULL) - result = str2prefix ("224.0.0.0/4", &rp_info->group); - else - result = str2prefix (group_range, &rp_info->group); - - if (!result) - { - XFREE (MTYPE_PIM_RP, rp_info); - return PIM_GROUP_BAD_ADDRESS; - } - - rp_info->rp.rpf_addr.family = AF_INET; - rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN; - result = inet_pton (rp_info->rp.rpf_addr.family, rp, &rp_info->rp.rpf_addr.u.prefix4); - - if (result <= 0) - { - XFREE (MTYPE_PIM_RP, rp_info); - return PIM_RP_BAD_ADDRESS; - } - - if (plist) - { - /* - * 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); - } - } - - 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); - - /* Register addr with Zebra NHT */ - nht_p.family = AF_INET; - nht_p.prefixlen = IPV4_MAX_BITLEN; - nht_p.u.prefix4 = rp_all->rp.rpf_addr.u.prefix4; //RP address - if (PIM_DEBUG_PIM_TRACE) - { - char buf[PREFIX2STR_BUFFER]; - char buf1[PREFIX2STR_BUFFER]; - prefix2str (&nht_p, buf, sizeof (buf)); - prefix2str (&rp_all->group, buf1, sizeof (buf1)); - zlog_debug ("%s: NHT Register rp_all addr %s grp %s ", - __PRETTY_FUNCTION__, buf, buf1); - } - memset (&pnc, 0, sizeof (struct pim_nexthop_cache)); - if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_all, &pnc)) == 1) - { - //Compute PIM RPF using Cached nexthop - if ((pim_ecmp_nexthop_search (&pnc, &rp_all->rp.source_nexthop, - &nht_p, &rp_all->group, 1)) != 0) - return PIM_RP_NO_PATH; - } - else - { - if (pim_nexthop_lookup (&rp_all->rp.source_nexthop, rp_all->rp.rpf_addr.u.prefix4, 1) != 0) - return PIM_RP_NO_PATH; - } - pim_rp_check_interfaces (rp_all); - pim_rp_refresh_group_to_rp_mapping (); - 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); - - /* Register addr with Zebra NHT */ - nht_p.family = AF_INET; - nht_p.prefixlen = IPV4_MAX_BITLEN; - nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - if (PIM_DEBUG_PIM_TRACE) - { - char buf[PREFIX2STR_BUFFER]; - char buf1[PREFIX2STR_BUFFER]; - prefix2str (&nht_p, buf, sizeof (buf)); - prefix2str (&rp_info->group, buf1, sizeof (buf1)); - zlog_debug ("%s: NHT Register RP addr %s grp %s with Zebra ", - __PRETTY_FUNCTION__, buf, buf1); - } - - memset (&pnc, 0, sizeof (struct pim_nexthop_cache)); - if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1) - { - //Compute PIM RPF using Cached nexthop - if (pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop, - &nht_p, &rp_info->group, 1) != 0) - return PIM_RP_NO_PATH; - } - else - { - if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1) != 0) - return PIM_RP_NO_PATH; - } - - pim_rp_check_interfaces (rp_info); - pim_rp_refresh_group_to_rp_mapping (); - return PIM_SUCCESS; + int result = 0; + struct rp_info *rp_info; + struct rp_info *rp_all; + struct prefix group_all; + struct listnode *node, *nnode; + struct rp_info *tmp_rp_info; + char buffer[BUFSIZ]; + struct prefix nht_p; + struct pim_nexthop_cache pnc; + + rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info)); + if (!rp_info) + return PIM_MALLOC_FAIL; + + if (group_range == NULL) + result = str2prefix("224.0.0.0/4", &rp_info->group); + else + result = str2prefix(group_range, &rp_info->group); + + if (!result) { + XFREE(MTYPE_PIM_RP, rp_info); + return PIM_GROUP_BAD_ADDRESS; + } + + rp_info->rp.rpf_addr.family = AF_INET; + rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN; + result = inet_pton(rp_info->rp.rpf_addr.family, rp, + &rp_info->rp.rpf_addr.u.prefix4); + + if (result <= 0) { + XFREE(MTYPE_PIM_RP, rp_info); + return PIM_RP_BAD_ADDRESS; + } + + if (plist) { + /* + * 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); + } + } + + 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); + + /* Register addr with Zebra NHT */ + nht_p.family = AF_INET; + nht_p.prefixlen = IPV4_MAX_BITLEN; + nht_p.u.prefix4 = + rp_all->rp.rpf_addr.u.prefix4; // RP address + if (PIM_DEBUG_PIM_TRACE) { + char buf[PREFIX2STR_BUFFER]; + char buf1[PREFIX2STR_BUFFER]; + prefix2str(&nht_p, buf, sizeof(buf)); + prefix2str(&rp_all->group, buf1, sizeof(buf1)); + zlog_debug( + "%s: NHT Register rp_all addr %s grp %s ", + __PRETTY_FUNCTION__, buf, buf1); + } + memset(&pnc, 0, sizeof(struct pim_nexthop_cache)); + if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_all, + &pnc)) + == 1) { + // Compute PIM RPF using Cached nexthop + if ((pim_ecmp_nexthop_search( + &pnc, &rp_all->rp.source_nexthop, + &nht_p, &rp_all->group, 1)) + != 0) + return PIM_RP_NO_PATH; + } else { + if (pim_nexthop_lookup( + &rp_all->rp.source_nexthop, + rp_all->rp.rpf_addr.u.prefix4, 1) + != 0) + return PIM_RP_NO_PATH; + } + pim_rp_check_interfaces(rp_all); + pim_rp_refresh_group_to_rp_mapping(); + 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); + + /* Register addr with Zebra NHT */ + nht_p.family = AF_INET; + nht_p.prefixlen = IPV4_MAX_BITLEN; + nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; + if (PIM_DEBUG_PIM_TRACE) { + char buf[PREFIX2STR_BUFFER]; + char buf1[PREFIX2STR_BUFFER]; + prefix2str(&nht_p, buf, sizeof(buf)); + prefix2str(&rp_info->group, buf1, sizeof(buf1)); + zlog_debug("%s: NHT Register RP addr %s grp %s with Zebra ", + __PRETTY_FUNCTION__, buf, buf1); + } + + memset(&pnc, 0, sizeof(struct pim_nexthop_cache)); + if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_info, &pnc)) == 1) { + // Compute PIM RPF using Cached nexthop + if (pim_ecmp_nexthop_search(&pnc, &rp_info->rp.source_nexthop, + &nht_p, &rp_info->group, 1) + != 0) + return PIM_RP_NO_PATH; + } else { + if (pim_nexthop_lookup(&rp_info->rp.source_nexthop, + rp_info->rp.rpf_addr.u.prefix4, 1) + != 0) + return PIM_RP_NO_PATH; + } + + pim_rp_check_interfaces(rp_info); + pim_rp_refresh_group_to_rp_mapping(); + return PIM_SUCCESS; } -int -pim_rp_del (const char *rp, const char *group_range, const char *plist) +int pim_rp_del(const char *rp, const char *group_range, const char *plist) { - struct prefix group; - struct in_addr rp_addr; - struct prefix g_all; - struct rp_info *rp_info; - struct rp_info *rp_all; - int result; - struct prefix nht_p; - - if (group_range == NULL) - result = str2prefix ("224.0.0.0/4", &group); - else - result = str2prefix (group_range, &group); - - if (!result) - return PIM_GROUP_BAD_ADDRESS; - - result = inet_pton (AF_INET, rp, &rp_addr); - if (result <= 0) - 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); - - if (!rp_info) - return PIM_RP_NOT_FOUND; - - if (rp_info->plist) - { - XFREE(MTYPE_PIM_FILTER_NAME, rp_info->plist); - rp_info->plist = NULL; - } - - /* Deregister addr with Zebra NHT */ - nht_p.family = AF_INET; - nht_p.prefixlen = IPV4_MAX_BITLEN; - nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - if (PIM_DEBUG_PIM_TRACE) - { - char buf[PREFIX2STR_BUFFER]; - prefix2str (&nht_p, buf, sizeof (buf)); - zlog_debug ("%s: Deregister RP addr %s with Zebra ", __PRETTY_FUNCTION__, - buf); - } - pim_delete_tracked_nexthop (&nht_p, NULL, rp_info); - - 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 PIM_SUCCESS; - } - - listnode_delete (qpim_rp_list, rp_info); - pim_rp_refresh_group_to_rp_mapping (); - return PIM_SUCCESS; + struct prefix group; + struct in_addr rp_addr; + struct prefix g_all; + struct rp_info *rp_info; + struct rp_info *rp_all; + int result; + struct prefix nht_p; + + if (group_range == NULL) + result = str2prefix("224.0.0.0/4", &group); + else + result = str2prefix(group_range, &group); + + if (!result) + return PIM_GROUP_BAD_ADDRESS; + + result = inet_pton(AF_INET, rp, &rp_addr); + if (result <= 0) + 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); + + if (!rp_info) + return PIM_RP_NOT_FOUND; + + if (rp_info->plist) { + XFREE(MTYPE_PIM_FILTER_NAME, rp_info->plist); + rp_info->plist = NULL; + } + + /* Deregister addr with Zebra NHT */ + nht_p.family = AF_INET; + nht_p.prefixlen = IPV4_MAX_BITLEN; + nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; + if (PIM_DEBUG_PIM_TRACE) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(&nht_p, buf, sizeof(buf)); + zlog_debug("%s: Deregister RP addr %s with Zebra ", + __PRETTY_FUNCTION__, buf); + } + pim_delete_tracked_nexthop(&nht_p, NULL, rp_info); + + 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 PIM_SUCCESS; + } + + listnode_delete(qpim_rp_list, rp_info); + pim_rp_refresh_group_to_rp_mapping(); + return PIM_SUCCESS; } -int -pim_rp_setup (void) +int pim_rp_setup(void) { - struct listnode *node; - struct rp_info *rp_info; - int ret = 0; - struct prefix nht_p; - struct pim_nexthop_cache pnc; - - for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info)) - { - if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE) - continue; - - nht_p.family = AF_INET; - nht_p.prefixlen = IPV4_MAX_BITLEN; - nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - memset (&pnc, 0, sizeof (struct pim_nexthop_cache)); - if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1) - { - //Compute PIM RPF using Cached nexthop - if ((pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop, - &nht_p, &rp_info->group, 1)) != 0) - ret++; - } - else - { - if (PIM_DEBUG_ZEBRA) - { - char buf[PREFIX2STR_BUFFER]; - prefix2str (&nht_p, buf, sizeof (buf)); - zlog_debug ("%s: NHT Local Nexthop not found for RP %s ", - __PRETTY_FUNCTION__, buf); - } - if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1) != 0) - { - if (PIM_DEBUG_PIM_TRACE) - zlog_debug ("Unable to lookup nexthop for rp specified"); - ret++; - } - } - } - - if (ret) - return 0; - - return 1; + struct listnode *node; + struct rp_info *rp_info; + int ret = 0; + struct prefix nht_p; + struct pim_nexthop_cache pnc; + + for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) { + if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE) + continue; + + nht_p.family = AF_INET; + nht_p.prefixlen = IPV4_MAX_BITLEN; + nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; + memset(&pnc, 0, sizeof(struct pim_nexthop_cache)); + if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_info, &pnc)) + == 1) { + // Compute PIM RPF using Cached nexthop + if ((pim_ecmp_nexthop_search( + &pnc, &rp_info->rp.source_nexthop, &nht_p, + &rp_info->group, 1)) + != 0) + ret++; + } else { + if (PIM_DEBUG_ZEBRA) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(&nht_p, buf, sizeof(buf)); + zlog_debug( + "%s: NHT Local Nexthop not found for RP %s ", + __PRETTY_FUNCTION__, buf); + } + if (pim_nexthop_lookup(&rp_info->rp.source_nexthop, + rp_info->rp.rpf_addr.u.prefix4, + 1) + != 0) { + if (PIM_DEBUG_PIM_TRACE) + zlog_debug( + "Unable to lookup nexthop for rp specified"); + ret++; + } + } + } + + if (ret) + return 0; + + return 1; } /* * Checks to see if we should elect ourself the actual RP when new if * addresses are added against an interface. */ -void -pim_rp_check_on_if_add(struct pim_interface *pim_ifp) +void pim_rp_check_on_if_add(struct pim_interface *pim_ifp) { - struct listnode *node; - struct rp_info *rp_info; - bool i_am_rp_changed = false; - - if (qpim_rp_list == NULL) - return; - - for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info)) { - if (pim_rpf_addr_is_inaddr_none (&rp_info->rp)) - continue; - - /* if i_am_rp is already set nothing to be done (adding new addresses - * is not going to make a difference). */ - if (rp_info->i_am_rp) { - continue; - } - - if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) { - i_am_rp_changed = true; - rp_info->i_am_rp = 1; - if (PIM_DEBUG_ZEBRA) { - char rp[PREFIX_STRLEN]; - pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr, rp, sizeof(rp)); - zlog_debug("%s: %s: i am rp", __func__, rp); - } - } - } - - if (i_am_rp_changed) { - pim_msdp_i_am_rp_changed(); - } + struct listnode *node; + struct rp_info *rp_info; + bool i_am_rp_changed = false; + + if (qpim_rp_list == NULL) + return; + + for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) { + if (pim_rpf_addr_is_inaddr_none(&rp_info->rp)) + continue; + + /* if i_am_rp is already set nothing to be done (adding new + * addresses + * is not going to make a difference). */ + if (rp_info->i_am_rp) { + continue; + } + + if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) { + i_am_rp_changed = true; + rp_info->i_am_rp = 1; + if (PIM_DEBUG_ZEBRA) { + char rp[PREFIX_STRLEN]; + pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr, + rp, sizeof(rp)); + zlog_debug("%s: %s: i am rp", __func__, rp); + } + } + } + + if (i_am_rp_changed) { + pim_msdp_i_am_rp_changed(); + } } /* up-optimized re-evaluation of "i_am_rp". this is used when ifaddresses * are removed. Removing numbers is an uncommon event in an active network * so I have made no attempt to optimize it. */ -void -pim_i_am_rp_re_evaluate(void) +void pim_i_am_rp_re_evaluate(void) { - struct listnode *node; - struct rp_info *rp_info; - bool i_am_rp_changed = false; - int old_i_am_rp; - - if (qpim_rp_list == NULL) - return; - - for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) { - if (pim_rpf_addr_is_inaddr_none(&rp_info->rp)) - continue; - - old_i_am_rp = rp_info->i_am_rp; - pim_rp_check_interfaces(rp_info); - - if (old_i_am_rp != rp_info->i_am_rp) { - i_am_rp_changed = true; - if (PIM_DEBUG_ZEBRA) { - char rp[PREFIX_STRLEN]; - pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr, rp, sizeof(rp)); - if (rp_info->i_am_rp) { - zlog_debug("%s: %s: i am rp", __func__, rp); - } else { - zlog_debug("%s: %s: i am no longer rp", __func__, rp); - } - } - } - } - - if (i_am_rp_changed) { - pim_msdp_i_am_rp_changed(); - } + struct listnode *node; + struct rp_info *rp_info; + bool i_am_rp_changed = false; + int old_i_am_rp; + + if (qpim_rp_list == NULL) + return; + + for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) { + if (pim_rpf_addr_is_inaddr_none(&rp_info->rp)) + continue; + + old_i_am_rp = rp_info->i_am_rp; + pim_rp_check_interfaces(rp_info); + + if (old_i_am_rp != rp_info->i_am_rp) { + i_am_rp_changed = true; + if (PIM_DEBUG_ZEBRA) { + char rp[PREFIX_STRLEN]; + pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr, + rp, sizeof(rp)); + if (rp_info->i_am_rp) { + zlog_debug("%s: %s: i am rp", __func__, + rp); + } else { + zlog_debug("%s: %s: i am no longer rp", + __func__, rp); + } + } + } + } + + if (i_am_rp_changed) { + pim_msdp_i_am_rp_changed(); + } } /* @@ -691,23 +675,22 @@ pim_i_am_rp_re_evaluate(void) * * Since we only have static RP, all groups are part of this RP */ -int -pim_rp_i_am_rp (struct in_addr group) +int pim_rp_i_am_rp(struct in_addr group) { - struct prefix g; - struct rp_info *rp_info; + struct prefix g; + struct rp_info *rp_info; - memset (&g, 0, sizeof (g)); - g.family = AF_INET; - g.prefixlen = 32; - g.u.prefix4 = group; + memset(&g, 0, sizeof(g)); + g.family = AF_INET; + g.prefixlen = 32; + g.u.prefix4 = group; - rp_info = pim_rp_find_match_group (&g); + rp_info = pim_rp_find_match_group(&g); - if (rp_info) - return rp_info->i_am_rp; + if (rp_info) + return rp_info->i_am_rp; - return 0; + return 0; } /* @@ -715,62 +698,60 @@ pim_rp_i_am_rp (struct in_addr group) * * Return the RP that the Group belongs too. */ -struct pim_rpf * -pim_rp_g (struct in_addr group) +struct pim_rpf *pim_rp_g(struct in_addr group) { - struct prefix g; - struct rp_info *rp_info; - - memset (&g, 0, sizeof (g)); - g.family = AF_INET; - g.prefixlen = 32; - g.u.prefix4 = group; - - rp_info = pim_rp_find_match_group (&g); - - if (rp_info) - { - struct prefix nht_p; - struct pim_nexthop_cache pnc; - /* Register addr with Zebra NHT */ - nht_p.family = AF_INET; - nht_p.prefixlen = IPV4_MAX_BITLEN; - nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - if (PIM_DEBUG_PIM_TRACE) - { - char buf[PREFIX2STR_BUFFER]; - char buf1[PREFIX2STR_BUFFER]; - prefix2str (&nht_p, buf, sizeof (buf)); - prefix2str (&rp_info->group, buf1, sizeof (buf1)); - zlog_debug ("%s: NHT Register RP addr %s grp %s with Zebra", - __PRETTY_FUNCTION__, buf, buf1); - } - memset (&pnc, 0, sizeof (struct pim_nexthop_cache)); - if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1) - { - //Compute PIM RPF using Cached nexthop - pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop, - &nht_p, &rp_info->group, 1); - } - else - { - if (PIM_DEBUG_ZEBRA) - { - char buf[PREFIX2STR_BUFFER]; - char buf1[PREFIX2STR_BUFFER]; - prefix2str (&nht_p, buf, sizeof (buf)); - prefix2str (&g, buf1, sizeof (buf1)); - zlog_debug ("%s: Nexthop cache not found for RP %s grp %s register with Zebra", - __PRETTY_FUNCTION__, buf, buf1); - } - pim_rpf_set_refresh_time (); - pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1); - } - return (&rp_info->rp); - } - - // About to Go Down - return NULL; + struct prefix g; + struct rp_info *rp_info; + + memset(&g, 0, sizeof(g)); + g.family = AF_INET; + g.prefixlen = 32; + g.u.prefix4 = group; + + rp_info = pim_rp_find_match_group(&g); + + if (rp_info) { + struct prefix nht_p; + struct pim_nexthop_cache pnc; + /* Register addr with Zebra NHT */ + nht_p.family = AF_INET; + nht_p.prefixlen = IPV4_MAX_BITLEN; + nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; + if (PIM_DEBUG_PIM_TRACE) { + char buf[PREFIX2STR_BUFFER]; + char buf1[PREFIX2STR_BUFFER]; + prefix2str(&nht_p, buf, sizeof(buf)); + prefix2str(&rp_info->group, buf1, sizeof(buf1)); + zlog_debug( + "%s: NHT Register RP addr %s grp %s with Zebra", + __PRETTY_FUNCTION__, buf, buf1); + } + memset(&pnc, 0, sizeof(struct pim_nexthop_cache)); + if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_info, &pnc)) + == 1) { + // Compute PIM RPF using Cached nexthop + pim_ecmp_nexthop_search(&pnc, + &rp_info->rp.source_nexthop, + &nht_p, &rp_info->group, 1); + } else { + if (PIM_DEBUG_ZEBRA) { + char buf[PREFIX2STR_BUFFER]; + char buf1[PREFIX2STR_BUFFER]; + prefix2str(&nht_p, buf, sizeof(buf)); + prefix2str(&g, buf1, sizeof(buf1)); + zlog_debug( + "%s: Nexthop cache not found for RP %s grp %s register with Zebra", + __PRETTY_FUNCTION__, buf, buf1); + } + pim_rpf_set_refresh_time(); + pim_nexthop_lookup(&rp_info->rp.source_nexthop, + rp_info->rp.rpf_addr.u.prefix4, 1); + } + return (&rp_info->rp); + } + + // About to Go Down + return NULL; } /* @@ -781,222 +762,253 @@ pim_rp_g (struct in_addr group) * then return failure. * */ -int -pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source, struct in_addr group) +int pim_rp_set_upstream_addr(struct in_addr *up, struct in_addr source, + struct in_addr group) { - struct rp_info *rp_info; - struct prefix g; + struct rp_info *rp_info; + struct prefix g; - memset (&g, 0, sizeof (g)); - g.family = AF_INET; - g.prefixlen = 32; - g.u.prefix4 = group; + memset(&g, 0, sizeof(g)); + g.family = AF_INET; + g.prefixlen = 32; + g.u.prefix4 = group; - rp_info = pim_rp_find_match_group (&g); + rp_info = pim_rp_find_match_group(&g); - if ((pim_rpf_addr_is_inaddr_none (&rp_info->rp)) && (source.s_addr == INADDR_ANY)) - { - if (PIM_DEBUG_PIM_TRACE) - zlog_debug("%s: Received a (*,G) with no RP configured", __PRETTY_FUNCTION__); - return 0; - } + if ((pim_rpf_addr_is_inaddr_none(&rp_info->rp)) + && (source.s_addr == INADDR_ANY)) { + if (PIM_DEBUG_PIM_TRACE) + zlog_debug("%s: Received a (*,G) with no RP configured", + __PRETTY_FUNCTION__); + return 0; + } - *up = (source.s_addr == INADDR_ANY) ? rp_info->rp.rpf_addr.u.prefix4 : source; + *up = (source.s_addr == INADDR_ANY) ? rp_info->rp.rpf_addr.u.prefix4 + : source; - return 1; + return 1; } -int -pim_rp_config_write (struct vty *vty) +int pim_rp_config_write(struct vty *vty) { - struct listnode *node; - struct rp_info *rp_info; - char rp_buffer[32]; - char group_buffer[32]; - int count = 0; - - for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info)) - { - if (pim_rpf_addr_is_inaddr_none (&rp_info->rp)) - continue; - - if (rp_info->plist) - vty_out (vty, "ip pim rp %s prefix-list %s\n", - inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp_buffer, 32), - rp_info->plist); - else - vty_out (vty, "ip pim rp %s %s\n", - inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp_buffer, 32), - prefix2str(&rp_info->group, group_buffer, 32)); - count++; - } - - return count; + struct listnode *node; + struct rp_info *rp_info; + char rp_buffer[32]; + char group_buffer[32]; + int count = 0; + + for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) { + if (pim_rpf_addr_is_inaddr_none(&rp_info->rp)) + continue; + + if (rp_info->plist) + vty_out(vty, "ip pim rp %s prefix-list %s\n", + inet_ntop(AF_INET, + &rp_info->rp.rpf_addr.u.prefix4, + rp_buffer, 32), + rp_info->plist); + else + vty_out(vty, "ip pim rp %s %s\n", + inet_ntop(AF_INET, + &rp_info->rp.rpf_addr.u.prefix4, + rp_buffer, 32), + prefix2str(&rp_info->group, group_buffer, 32)); + count++; + } + + return count; } -int -pim_rp_check_is_my_ip_address (struct in_addr group, struct in_addr dest_addr) +int pim_rp_check_is_my_ip_address(struct in_addr group, + struct in_addr dest_addr) { - struct rp_info *rp_info; - struct prefix g; - - memset (&g, 0, sizeof (g)); - g.family = AF_INET; - g.prefixlen = 32; - g.u.prefix4 = group; - - rp_info = pim_rp_find_match_group (&g); - /* - * See if we can short-cut some? - * This might not make sense if we ever leave a static RP - * type of configuration. - * Note - Premature optimization might bite our patooeys' here. - */ - if (I_am_RP(group)) - { - if (dest_addr.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr) - return 1; - } - - if (if_lookup_exact_address (&dest_addr, AF_INET, VRF_DEFAULT)) - return 1; - - return 0; + struct rp_info *rp_info; + struct prefix g; + + memset(&g, 0, sizeof(g)); + g.family = AF_INET; + g.prefixlen = 32; + g.u.prefix4 = group; + + rp_info = pim_rp_find_match_group(&g); + /* + * See if we can short-cut some? + * This might not make sense if we ever leave a static RP + * type of configuration. + * Note - Premature optimization might bite our patooeys' here. + */ + if (I_am_RP(group)) { + if (dest_addr.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr) + return 1; + } + + if (if_lookup_exact_address(&dest_addr, AF_INET, VRF_DEFAULT)) + return 1; + + return 0; } -void -pim_rp_show_information (struct vty *vty, u_char uj) +void pim_rp_show_information(struct vty *vty, u_char uj) { - struct rp_info *rp_info; - struct rp_info *prev_rp_info = NULL; - struct listnode *node; - - json_object *json = NULL; - json_object *json_rp_rows = NULL; - json_object *json_row = NULL; - - if (uj) - json = json_object_new_object(); - else - vty_out (vty, - "RP address group/prefix-list OIF I am RP\n"); - - for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info)) - { - if (!pim_rpf_addr_is_inaddr_none (&rp_info->rp)) - { - char buf[48]; - - if (uj) - { - /* - * If we have moved on to a new RP then add the entry for the previous RP - */ - if (prev_rp_info && - prev_rp_info->rp.rpf_addr.u.prefix4.s_addr != rp_info->rp.rpf_addr.u.prefix4.s_addr) - { - json_object_object_add(json, inet_ntoa (prev_rp_info->rp.rpf_addr.u.prefix4), json_rp_rows); - json_rp_rows = NULL; - } - - if (!json_rp_rows) - json_rp_rows = json_object_new_array(); - - json_row = json_object_new_object(); - if (rp_info->rp.source_nexthop.interface) - json_object_string_add(json_row, "outboundInterface", rp_info->rp.source_nexthop.interface->name); - - if (rp_info->i_am_rp) - json_object_boolean_true_add(json_row, "iAmRP"); - - if (rp_info->plist) - json_object_string_add(json_row, "prefixList", rp_info->plist); - else - json_object_string_add(json_row, "group", prefix2str(&rp_info->group, buf, 48)); - - json_object_array_add(json_rp_rows, json_row); - } - else - { - 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)); - - if (rp_info->rp.source_nexthop.interface) - vty_out (vty, "%-10s ", rp_info->rp.source_nexthop.interface->name); - else - vty_out (vty, "%-10s ", "(Unknown)"); - - if (rp_info->i_am_rp) - vty_out (vty, "yes\n"); - else - vty_out (vty, "no\n"); - } - - prev_rp_info = rp_info; - } - } - - if (uj) { - if (prev_rp_info && json_rp_rows) - json_object_object_add(json, inet_ntoa (prev_rp_info->rp.rpf_addr.u.prefix4), json_rp_rows); - - vty_out (vty, "%s\n", - json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } + struct rp_info *rp_info; + struct rp_info *prev_rp_info = NULL; + struct listnode *node; + + json_object *json = NULL; + json_object *json_rp_rows = NULL; + json_object *json_row = NULL; + + if (uj) + json = json_object_new_object(); + else + vty_out(vty, + "RP address group/prefix-list OIF I am RP\n"); + + for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) { + if (!pim_rpf_addr_is_inaddr_none(&rp_info->rp)) { + char buf[48]; + + if (uj) { + /* + * If we have moved on to a new RP then add the + * entry for the previous RP + */ + if (prev_rp_info + && prev_rp_info->rp.rpf_addr.u.prefix4 + .s_addr + != rp_info->rp.rpf_addr.u.prefix4 + .s_addr) { + json_object_object_add( + json, + inet_ntoa(prev_rp_info->rp + .rpf_addr.u + .prefix4), + json_rp_rows); + json_rp_rows = NULL; + } + + if (!json_rp_rows) + json_rp_rows = json_object_new_array(); + + json_row = json_object_new_object(); + if (rp_info->rp.source_nexthop.interface) + json_object_string_add( + json_row, "outboundInterface", + rp_info->rp.source_nexthop + .interface->name); + + if (rp_info->i_am_rp) + json_object_boolean_true_add(json_row, + "iAmRP"); + + if (rp_info->plist) + json_object_string_add(json_row, + "prefixList", + rp_info->plist); + else + json_object_string_add( + json_row, "group", + prefix2str(&rp_info->group, buf, + 48)); + + json_object_array_add(json_rp_rows, json_row); + } else { + 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)); + + if (rp_info->rp.source_nexthop.interface) + vty_out(vty, "%-10s ", + rp_info->rp.source_nexthop + .interface->name); + else + vty_out(vty, "%-10s ", "(Unknown)"); + + if (rp_info->i_am_rp) + vty_out(vty, "yes\n"); + else + vty_out(vty, "no\n"); + } + + prev_rp_info = rp_info; + } + } + + if (uj) { + if (prev_rp_info && json_rp_rows) + json_object_object_add( + json, + inet_ntoa(prev_rp_info->rp.rpf_addr.u.prefix4), + json_rp_rows); + + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } } -void -pim_resolve_rp_nh (void) +void pim_resolve_rp_nh(void) { - struct listnode *node = NULL; - struct rp_info *rp_info = NULL; - struct nexthop *nh_node = NULL; - struct prefix nht_p; - struct pim_nexthop_cache pnc; - struct pim_neighbor *nbr = NULL; - - for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info)) - { - if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE) - continue; - - nht_p.family = AF_INET; - nht_p.prefixlen = IPV4_MAX_BITLEN; - nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - memset (&pnc, 0, sizeof (struct pim_nexthop_cache)); - if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1) - { - for (nh_node = pnc.nexthop; nh_node; nh_node = nh_node->next) - { - if (nh_node->gate.ipv4.s_addr == 0) - { - nbr = pim_neighbor_find_if (if_lookup_by_index - (nh_node->ifindex, VRF_DEFAULT)); - if (nbr) - { - nh_node->gate.ipv4 = nbr->source_addr; - if (PIM_DEBUG_TRACE) - { - char str[PREFIX_STRLEN]; - char str1[INET_ADDRSTRLEN]; - struct interface *ifp1 = if_lookup_by_index(nh_node->ifindex, - VRF_DEFAULT); - pim_inet4_dump ("<nht_nbr?>", nbr->source_addr, - str1, sizeof (str1)); - pim_addr_dump ("<nht_addr?>", &nht_p, str, - sizeof (str)); - zlog_debug ("%s: addr %s new nexthop addr %s interface %s", - __PRETTY_FUNCTION__, str, str1, - ifp1->name); - } - } - } - } - } - } + struct listnode *node = NULL; + struct rp_info *rp_info = NULL; + struct nexthop *nh_node = NULL; + struct prefix nht_p; + struct pim_nexthop_cache pnc; + struct pim_neighbor *nbr = NULL; + + for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) { + if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE) + continue; + + nht_p.family = AF_INET; + nht_p.prefixlen = IPV4_MAX_BITLEN; + nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; + memset(&pnc, 0, sizeof(struct pim_nexthop_cache)); + if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_info, &pnc)) + == 1) { + for (nh_node = pnc.nexthop; nh_node; + nh_node = nh_node->next) { + if (nh_node->gate.ipv4.s_addr == 0) { + nbr = pim_neighbor_find_if( + if_lookup_by_index( + nh_node->ifindex, + VRF_DEFAULT)); + if (nbr) { + nh_node->gate.ipv4 = + nbr->source_addr; + if (PIM_DEBUG_TRACE) { + char str[PREFIX_STRLEN]; + char str1 + [INET_ADDRSTRLEN]; + struct interface *ifp1 = + if_lookup_by_index( + nh_node->ifindex, + VRF_DEFAULT); + pim_inet4_dump( + "<nht_nbr?>", + nbr->source_addr, + str1, + sizeof(str1)); + pim_addr_dump( + "<nht_addr?>", + &nht_p, str, + sizeof(str)); + zlog_debug( + "%s: addr %s new nexthop addr %s interface %s", + __PRETTY_FUNCTION__, + str, str1, + ifp1->name); + } + } + } + } + } + } } |
