summaryrefslogtreecommitdiff
path: root/pimd/pim_rp.c
diff options
context:
space:
mode:
authorwhitespace / reindent <invalid@invalid.invalid>2017-08-09 11:49:42 +0200
committerwhitespace / reindent <invalid@invalid.invalid>2017-08-09 12:03:17 +0200
commitac4d0be5874fafd14212d6007fff7495edc9b152 (patch)
tree5e2f0d3189de928c849f9983406389ade3b098cb /pimd/pim_rp.c
parent76a86854181c27819e5cf71b12ae1fa5ccd9e02a (diff)
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.c1640
1 files changed, 829 insertions, 811 deletions
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 6c4504d9b0..fbcbe688c2 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -12,7 +12,7 @@
* 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,
@@ -49,157 +49,146 @@
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.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.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,479 +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 (sec_addr->addr.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr) {
- return 1;
- }
- }
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
+ if (sec_addr->addr.s_addr
+ == rp_info->rp.rpf_addr.u.prefix4.s_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;
- 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;
+ 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();
+ }
}
/*
@@ -690,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;
}
/*
@@ -714,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;
}
/*
@@ -780,220 +762,256 @@ 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%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;
+ 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%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;
}
-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%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];
-
- 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%s", VTY_NEWLINE);
- else
- vty_out (vty, "no%s", VTY_NEWLINE);
- }
-
- 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%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
- 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%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];
+
+ 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%s", VTY_NEWLINE);
+ else
+ vty_out(vty, "no%s", VTY_NEWLINE);
+ }
+
+ 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%s", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY),
+ VTY_NEWLINE);
+ 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);
+ }
+ }
+ }
+ }
+ }
+ }
}