Merge pull request #10646 from mobash-rasool/pim-rp-changes-new

This commit is contained in:
David Lamparter 2022-03-08 12:26:37 +01:00 committed by GitHub
commit 838a8858d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 438 additions and 398 deletions

View File

@ -392,6 +392,62 @@ DEFPY (interface_no_ipv6_mroute,
source_str); source_str);
} }
DEFPY (ipv6_pim_rp,
ipv6_pim_rp_cmd,
"ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp",
IPV6_STR
PIM_STR
"Rendezvous Point\n"
"ipv6 address of RP\n"
"Group Address range to cover\n")
{
const char *group_str = (gp_str) ? gp_str : "FF00::0/8";
return pim_process_rp_cmd(vty, rp_str, group_str);
}
DEFPY (no_ipv6_pim_rp,
no_ipv6_pim_rp_cmd,
"no ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp",
NO_STR
IPV6_STR
PIM_STR
"Rendezvous Point\n"
"ipv6 address of RP\n"
"Group Address range to cover\n")
{
const char *group_str = (gp_str) ? gp_str : "FF00::0/8";
return pim_process_no_rp_cmd(vty, rp_str, group_str);
}
DEFPY (ipv6_pim_rp_prefix_list,
ipv6_pim_rp_prefix_list_cmd,
"ipv6 pim rp X:X::X:X$rp prefix-list WORD$plist",
IPV6_STR
PIM_STR
"Rendezvous Point\n"
"ipv6 address of RP\n"
"group prefix-list filter\n"
"Name of a prefix-list\n")
{
return pim_process_rp_plist_cmd(vty, rp_str, plist);
}
DEFPY (no_ipv6_pim_rp_prefix_list,
no_ipv6_pim_rp_prefix_list_cmd,
"no ipv6 pim rp X:X::X:X$rp prefix-list WORD$plist",
NO_STR
IPV6_STR
PIM_STR
"Rendezvous Point\n"
"ipv6 address of RP\n"
"group prefix-list filter\n"
"Name of a prefix-list\n")
{
return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
}
void pim_cmd_init(void) void pim_cmd_init(void)
{ {
if_cmd_init(pim_interface_config_write); if_cmd_init(pim_interface_config_write);
@ -427,4 +483,12 @@ void pim_cmd_init(void)
&interface_no_ipv6_pim_boundary_oil_cmd); &interface_no_ipv6_pim_boundary_oil_cmd);
install_element(INTERFACE_NODE, &interface_ipv6_mroute_cmd); install_element(INTERFACE_NODE, &interface_ipv6_mroute_cmd);
install_element(INTERFACE_NODE, &interface_no_ipv6_mroute_cmd); install_element(INTERFACE_NODE, &interface_no_ipv6_mroute_cmd);
install_element(CONFIG_NODE, &ipv6_pim_rp_cmd);
install_element(VRF_NODE, &ipv6_pim_rp_cmd);
install_element(CONFIG_NODE, &no_ipv6_pim_rp_cmd);
install_element(VRF_NODE, &no_ipv6_pim_rp_cmd);
install_element(CONFIG_NODE, &ipv6_pim_rp_prefix_list_cmd);
install_element(VRF_NODE, &ipv6_pim_rp_prefix_list_cmd);
install_element(CONFIG_NODE, &no_ipv6_pim_rp_prefix_list_cmd);
install_element(VRF_NODE, &no_ipv6_pim_rp_prefix_list_cmd);
} }

View File

@ -133,3 +133,25 @@ void pim_reg_del_on_couldreg_fail(struct interface *ifp)
{ {
} }
bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
{
return false;
}
void pim_bsm_proc_free(struct pim_instance *pim)
{
}
void pim_bsm_proc_init(struct pim_instance *pim)
{
}
struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
struct prefix *grp)
{
return NULL;
}
void pim_bsm_write_config(struct vty *vty, struct interface *ifp)
{
}

View File

@ -36,6 +36,7 @@
#include "pim_bsm.h" #include "pim_bsm.h"
#include "pim_time.h" #include "pim_time.h"
#include "pim_zebra.h" #include "pim_zebra.h"
#include "pim_util.h"
/* Functions forward declaration */ /* Functions forward declaration */
static void pim_bs_timer_start(struct bsm_scope *scope, int bs_timeout); static void pim_bs_timer_start(struct bsm_scope *scope, int bs_timeout);
@ -284,7 +285,7 @@ static void pim_on_g2rp_timer(struct thread *t)
struct rp_info *rp_info; struct rp_info *rp_info;
struct route_node *rn; struct route_node *rn;
uint16_t elapse; uint16_t elapse;
struct in_addr bsrp_addr; pim_addr bsrp_addr;
bsrp = THREAD_ARG(t); bsrp = THREAD_ARG(t);
THREAD_OFF(bsrp->g2rp_timer); THREAD_OFF(bsrp->g2rp_timer);
@ -324,10 +325,9 @@ static void pim_on_g2rp_timer(struct thread *t)
if (rp_info->rp_src != RP_SRC_STATIC) { if (rp_info->rp_src != RP_SRC_STATIC) {
/* If new rp available, change it else delete the existing */ /* If new rp available, change it else delete the existing */
if (bsrp) { if (bsrp) {
bsrp_addr = bsrp->rp_address;
pim_g2rp_timer_start( pim_g2rp_timer_start(
bsrp, (bsrp->rp_holdtime - bsrp->elapse_time)); bsrp, (bsrp->rp_holdtime - bsrp->elapse_time));
pim_rp_change(pim, bsrp_addr, bsgrp_node->group, pim_rp_change(pim, bsrp->rp_address, bsgrp_node->group,
RP_SRC_BSR); RP_SRC_BSR);
} else { } else {
pim_rp_del(pim, bsrp_addr, bsgrp_node->group, NULL, pim_rp_del(pim, bsrp_addr, bsgrp_node->group, NULL,
@ -417,7 +417,7 @@ static void pim_instate_pend_list(struct bsgrp_node *bsgrp_node)
pend = bsm_rpinfos_first(bsgrp_node->partial_bsrp_list); pend = bsm_rpinfos_first(bsgrp_node->partial_bsrp_list);
if (!str2prefix("224.0.0.0/4", &group_all)) if (!pim_get_all_mcast_group(&group_all))
return; return;
rp_all = pim_rp_find_match_group(pim, &group_all); rp_all = pim_rp_find_match_group(pim, &group_all);
@ -628,7 +628,7 @@ void pim_bsm_clear(struct pim_instance *pim)
pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info); pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info);
if (!str2prefix("224.0.0.0/4", &g_all)) if (!pim_get_all_mcast_group(&g_all))
return; return;
rp_all = pim_rp_find_match_group(pim, &g_all); rp_all = pim_rp_find_match_group(pim, &g_all);

View File

@ -115,7 +115,7 @@ struct bsm_rpinfo {
uint32_t elapse_time; /* upd at expiry of elected RP node */ uint32_t elapse_time; /* upd at expiry of elected RP node */
uint16_t rp_prio; /* RP priority */ uint16_t rp_prio; /* RP priority */
uint16_t rp_holdtime; /* RP holdtime - g2rp timer value */ uint16_t rp_holdtime; /* RP holdtime - g2rp timer value */
struct in_addr rp_address; /* RP Address */ pim_addr rp_address; /* RP Address */
struct bsgrp_node *bsgrp_node; /* Back ptr to bsgrp_node */ struct bsgrp_node *bsgrp_node; /* Back ptr to bsgrp_node */
struct thread *g2rp_timer; /* Run only for elected RP node */ struct thread *g2rp_timer; /* Run only for elected RP node */
}; };

View File

@ -6997,98 +6997,36 @@ DEFUN (no_ip_pim_v6_secondary,
return nb_cli_apply_changes(vty, NULL); return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (ip_pim_rp, DEFPY (ip_pim_rp,
ip_pim_rp_cmd, ip_pim_rp_cmd,
"ip pim rp A.B.C.D [A.B.C.D/M]", "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
IP_STR IP_STR
"pim multicast routing\n" "pim multicast routing\n"
"Rendevous Point\n" "Rendevous Point\n"
"ip address of RP\n" "ip address of RP\n"
"Group Address range to cover\n") "Group Address range to cover\n")
{ {
const char *vrfname; const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
int idx_rp = 3, idx_group = 4;
char rp_group_xpath[XPATH_MAXLEN];
int result = 0;
struct prefix group;
struct in_addr rp_addr;
const char *group_str =
(argc == 5) ? argv[idx_group]->arg : "224.0.0.0/4";
result = str2prefix(group_str, &group); return pim_process_rp_cmd(vty, rp_str, group_str);
if (result) {
struct prefix temp;
prefix_copy(&temp, &group);
apply_mask(&temp);
if (!prefix_same(&group, &temp)) {
vty_out(vty, "%% Inconsistent address and mask: %s\n",
group_str);
return CMD_WARNING_CONFIG_FAILED;
}
}
if (!result) {
vty_out(vty, "%% Bad group address specified: %s\n",
group_str);
return CMD_WARNING_CONFIG_FAILED;
}
result = inet_pton(AF_INET, argv[idx_rp]->arg, &rp_addr);
if (result <= 0) {
vty_out(vty, "%% Bad RP address specified: %s\n",
argv[idx_rp]->arg);
return CMD_WARNING_CONFIG_FAILED;
}
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_group_xpath, sizeof(rp_group_xpath),
FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4",
argv[idx_rp]->arg);
strlcat(rp_group_xpath, "/group-list", sizeof(rp_group_xpath));
nb_cli_enqueue_change(vty, rp_group_xpath, NB_OP_CREATE, group_str);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (ip_pim_rp_prefix_list, DEFPY (ip_pim_rp_prefix_list,
ip_pim_rp_prefix_list_cmd, ip_pim_rp_prefix_list_cmd,
"ip pim rp A.B.C.D prefix-list WORD", "ip pim rp A.B.C.D$rp prefix-list WORD$plist",
IP_STR IP_STR
"pim multicast routing\n" "pim multicast routing\n"
"Rendevous Point\n" "Rendezvous Point\n"
"ip address of RP\n" "ip address of RP\n"
"group prefix-list filter\n" "group prefix-list filter\n"
"Name of a prefix-list\n") "Name of a prefix-list\n")
{ {
int idx_rp = 3, idx_plist = 5; return pim_process_rp_plist_cmd(vty, rp_str, plist);
const char *vrfname;
char rp_plist_xpath[XPATH_MAXLEN];
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_plist_xpath, sizeof(rp_plist_xpath),
FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4",
argv[idx_rp]->arg);
strlcat(rp_plist_xpath, "/prefix-list", sizeof(rp_plist_xpath));
nb_cli_enqueue_change(vty, rp_plist_xpath, NB_OP_MODIFY,
argv[idx_plist]->arg);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (no_ip_pim_rp, DEFPY (no_ip_pim_rp,
no_ip_pim_rp_cmd, no_ip_pim_rp_cmd,
"no ip pim rp A.B.C.D [A.B.C.D/M]", "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
NO_STR NO_STR
IP_STR IP_STR
"pim multicast routing\n" "pim multicast routing\n"
@ -7096,106 +7034,23 @@ DEFUN (no_ip_pim_rp,
"ip address of RP\n" "ip address of RP\n"
"Group Address range to cover\n") "Group Address range to cover\n")
{ {
int idx_rp = 4, idx_group = 5; const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
const char *group_str =
(argc == 6) ? argv[idx_group]->arg : "224.0.0.0/4";
char group_list_xpath[XPATH_MAXLEN];
char group_xpath[XPATH_MAXLEN];
char rp_xpath[XPATH_MAXLEN];
int printed;
const char *vrfname;
const struct lyd_node *group_dnode;
vrfname = pim_cli_get_vrf_name(vty); return pim_process_no_rp_cmd(vty, rp_str, group_str);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4",
argv[idx_rp]->arg);
printed = snprintf(group_list_xpath, sizeof(group_list_xpath),
"%s/group-list", rp_xpath);
if (printed >= (int)(sizeof(group_list_xpath))) {
vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
XPATH_MAXLEN);
return CMD_WARNING_CONFIG_FAILED;
}
printed = snprintf(group_xpath, sizeof(group_xpath), "%s[.='%s']",
group_list_xpath, group_str);
if (printed >= (int)(sizeof(group_xpath))) {
vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
XPATH_MAXLEN);
return CMD_WARNING_CONFIG_FAILED;
}
if (!yang_dnode_exists(vty->candidate_config->dnode, group_xpath)) {
vty_out(vty, "%% Unable to find specified RP\n");
return NB_OK;
}
group_dnode = yang_dnode_get(vty->candidate_config->dnode, group_xpath);
if (yang_is_last_list_dnode(group_dnode))
nb_cli_enqueue_change(vty, rp_xpath, NB_OP_DESTROY, NULL);
else
nb_cli_enqueue_change(vty, group_list_xpath, NB_OP_DESTROY,
group_str);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (no_ip_pim_rp_prefix_list, DEFPY (no_ip_pim_rp_prefix_list,
no_ip_pim_rp_prefix_list_cmd, no_ip_pim_rp_prefix_list_cmd,
"no ip pim rp A.B.C.D prefix-list WORD", "no ip pim rp A.B.C.D$rp prefix-list WORD$plist",
NO_STR NO_STR
IP_STR IP_STR
"pim multicast routing\n" "pim multicast routing\n"
"Rendevous Point\n" "Rendezvous Point\n"
"ip address of RP\n" "ip address of RP\n"
"group prefix-list filter\n" "group prefix-list filter\n"
"Name of a prefix-list\n") "Name of a prefix-list\n")
{ {
int idx_rp = 4; return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
int idx_plist = 6;
char rp_xpath[XPATH_MAXLEN];
char plist_xpath[XPATH_MAXLEN];
const char *vrfname;
const struct lyd_node *plist_dnode;
const char *plist;
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4",
argv[idx_rp]->arg);
snprintf(plist_xpath, sizeof(plist_xpath), FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4",
argv[idx_rp]->arg);
strlcat(plist_xpath, "/prefix-list", sizeof(plist_xpath));
plist_dnode = yang_dnode_get(vty->candidate_config->dnode, plist_xpath);
if (!plist_dnode) {
vty_out(vty, "%% Unable to find specified RP\n");
return NB_OK;
}
plist = yang_dnode_get_string(plist_dnode, plist_xpath);
if (strcmp(argv[idx_plist]->arg, plist)) {
vty_out(vty, "%% Unable to find specified RP\n");
return NB_OK;
}
nb_cli_enqueue_change(vty, rp_xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (ip_pim_ssm_prefix_list, DEFUN (ip_pim_ssm_prefix_list,

View File

@ -499,3 +499,158 @@ int pim_process_no_ip_mroute_cmd(struct vty *vty, const char *interface,
FRR_PIM_AF_XPATH_VAL, source_str, FRR_PIM_AF_XPATH_VAL, source_str,
group_str); group_str);
} }
int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
const char *group_str)
{
const char *vrfname;
char rp_group_xpath[XPATH_MAXLEN];
int result = 0;
struct prefix group;
pim_addr rp_addr;
result = str2prefix(group_str, &group);
if (result) {
struct prefix temp;
prefix_copy(&temp, &group);
apply_mask(&temp);
if (!prefix_same(&group, &temp)) {
vty_out(vty, "%% Inconsistent address and mask: %s\n",
group_str);
return CMD_WARNING_CONFIG_FAILED;
}
}
if (!result) {
vty_out(vty, "%% Bad group address specified: %s\n", group_str);
return CMD_WARNING_CONFIG_FAILED;
}
result = inet_pton(PIM_AF, rp_str, &rp_addr);
if (result <= 0) {
vty_out(vty, "%% Bad RP address specified: %s\n", rp_str);
return CMD_WARNING_CONFIG_FAILED;
}
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_group_xpath, sizeof(rp_group_xpath),
FRR_PIM_STATIC_RP_XPATH, "frr-pim:pimd", "pim", vrfname,
FRR_PIM_AF_XPATH_VAL, rp_str);
strlcat(rp_group_xpath, "/group-list", sizeof(rp_group_xpath));
nb_cli_enqueue_change(vty, rp_group_xpath, NB_OP_CREATE, group_str);
return nb_cli_apply_changes(vty, NULL);
}
int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
const char *group_str)
{
char group_list_xpath[XPATH_MAXLEN];
char group_xpath[XPATH_MAXLEN];
char rp_xpath[XPATH_MAXLEN];
int printed;
const char *vrfname;
const struct lyd_node *group_dnode;
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
printed = snprintf(group_list_xpath, sizeof(group_list_xpath),
"%s/group-list", rp_xpath);
if (printed >= (int)(sizeof(group_list_xpath))) {
vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
XPATH_MAXLEN);
return CMD_WARNING_CONFIG_FAILED;
}
printed = snprintf(group_xpath, sizeof(group_xpath), "%s[.='%s']",
group_list_xpath, group_str);
if (printed >= (int)(sizeof(group_xpath))) {
vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
XPATH_MAXLEN);
return CMD_WARNING_CONFIG_FAILED;
}
if (!yang_dnode_exists(vty->candidate_config->dnode, group_xpath)) {
vty_out(vty, "%% Unable to find specified RP\n");
return NB_OK;
}
group_dnode = yang_dnode_get(vty->candidate_config->dnode, group_xpath);
if (yang_is_last_list_dnode(group_dnode))
nb_cli_enqueue_change(vty, rp_xpath, NB_OP_DESTROY, NULL);
else
nb_cli_enqueue_change(vty, group_list_xpath, NB_OP_DESTROY,
group_str);
return nb_cli_apply_changes(vty, NULL);
}
int pim_process_rp_plist_cmd(struct vty *vty, const char *rp_str,
const char *prefix_list)
{
const char *vrfname;
char rp_plist_xpath[XPATH_MAXLEN];
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_plist_xpath, sizeof(rp_plist_xpath),
FRR_PIM_STATIC_RP_XPATH, "frr-pim:pimd", "pim", vrfname,
FRR_PIM_AF_XPATH_VAL, rp_str);
strlcat(rp_plist_xpath, "/prefix-list", sizeof(rp_plist_xpath));
nb_cli_enqueue_change(vty, rp_plist_xpath, NB_OP_MODIFY, prefix_list);
return nb_cli_apply_changes(vty, NULL);
}
int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
const char *prefix_list)
{
char rp_xpath[XPATH_MAXLEN];
char plist_xpath[XPATH_MAXLEN];
const char *vrfname;
const struct lyd_node *plist_dnode;
const char *plist;
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
snprintf(plist_xpath, sizeof(plist_xpath), FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
strlcat(plist_xpath, "/prefix-list", sizeof(plist_xpath));
plist_dnode = yang_dnode_get(vty->candidate_config->dnode, plist_xpath);
if (!plist_dnode) {
vty_out(vty, "%% Unable to find specified RP\n");
return NB_OK;
}
plist = yang_dnode_get_string(plist_dnode, plist_xpath);
if (strcmp(prefix_list, plist)) {
vty_out(vty, "%% Unable to find specified RP\n");
return NB_OK;
}
nb_cli_enqueue_change(vty, rp_xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
}

View File

@ -35,6 +35,14 @@ int pim_process_rp_kat_cmd(struct vty *vty, const char *rpkat);
int pim_process_no_rp_kat_cmd(struct vty *vty); int pim_process_no_rp_kat_cmd(struct vty *vty);
int pim_process_register_suppress_cmd(struct vty *vty, const char *rst); int pim_process_register_suppress_cmd(struct vty *vty, const char *rst);
int pim_process_no_register_suppress_cmd(struct vty *vty); int pim_process_no_register_suppress_cmd(struct vty *vty);
int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
const char *group_str);
int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
const char *group_str);
int pim_process_rp_plist_cmd(struct vty *vty, const char *rp_str,
const char *prefix_list);
int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
const char *prefix_list);
int pim_process_ip_pim_cmd(struct vty *vty); int pim_process_ip_pim_cmd(struct vty *vty);
int pim_process_no_ip_pim_cmd(struct vty *vty); int pim_process_no_ip_pim_cmd(struct vty *vty);

View File

@ -34,6 +34,7 @@
#include "pim_util.h" #include "pim_util.h"
#include "log.h" #include "log.h"
#include "lib_errors.h" #include "lib_errors.h"
#include "pim_util.h"
#if PIM_IPV == 6 #if PIM_IPV == 6
#define pim6_msdp_err(funcname, argtype) \ #define pim6_msdp_err(funcname, argtype) \
@ -256,21 +257,17 @@ static int pim_ssm_cmd_worker(struct pim_instance *pim, const char *plist,
return ret; return ret;
} }
static int pim_rp_cmd_worker(struct pim_instance *pim, static int pim_rp_cmd_worker(struct pim_instance *pim, pim_addr rp_addr,
struct in_addr rp_addr, struct prefix group, const char *plist,
struct prefix group, const char *plist, char *errmsg, size_t errmsg_len)
char *errmsg, size_t errmsg_len)
{ {
char rp_str[INET_ADDRSTRLEN];
int result; int result;
inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str));
result = pim_rp_new(pim, rp_addr, group, plist, RP_SRC_STATIC); result = pim_rp_new(pim, rp_addr, group, plist, RP_SRC_STATIC);
if (result == PIM_RP_NO_PATH) { if (result == PIM_RP_NO_PATH) {
snprintf(errmsg, errmsg_len, snprintfrr(errmsg, errmsg_len,
"No Path to RP address specified: %s", rp_str); "No Path to RP address specified: %pPA", &rp_addr);
return NB_ERR_INCONSISTENCY; return NB_ERR_INCONSISTENCY;
} }
@ -295,16 +292,13 @@ static int pim_rp_cmd_worker(struct pim_instance *pim,
return NB_OK; return NB_OK;
} }
static int pim_no_rp_cmd_worker(struct pim_instance *pim, static int pim_no_rp_cmd_worker(struct pim_instance *pim, pim_addr rp_addr,
struct in_addr rp_addr, struct prefix group, struct prefix group, const char *plist,
const char *plist,
char *errmsg, size_t errmsg_len) char *errmsg, size_t errmsg_len)
{ {
char rp_str[INET_ADDRSTRLEN];
char group_str[PREFIX2STR_BUFFER]; char group_str[PREFIX2STR_BUFFER];
int result; int result;
inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str));
prefix2str(&group, group_str, sizeof(group_str)); prefix2str(&group, group_str, sizeof(group_str));
result = pim_rp_del(pim, rp_addr, group, plist, RP_SRC_STATIC); result = pim_rp_del(pim, rp_addr, group, plist, RP_SRC_STATIC);
@ -316,8 +310,8 @@ static int pim_no_rp_cmd_worker(struct pim_instance *pim,
} }
if (result == PIM_RP_BAD_ADDRESS) { if (result == PIM_RP_BAD_ADDRESS) {
snprintf(errmsg, errmsg_len, snprintfrr(errmsg, errmsg_len, "Bad RP address specified: %pPA",
"Bad RP address specified: %s", rp_str); &rp_addr);
return NB_ERR_INCONSISTENCY; return NB_ERR_INCONSISTENCY;
} }
@ -2340,7 +2334,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
struct vrf *vrf; struct vrf *vrf;
struct pim_instance *pim; struct pim_instance *pim;
struct prefix group; struct prefix group;
struct ipaddr rp_addr; pim_addr rp_addr;
const char *plist; const char *plist;
int result = 0; int result = 0;
@ -2352,31 +2346,30 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
case NB_EV_APPLY: case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true); vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info; pim = vrf->info;
yang_dnode_get_ip(&rp_addr, args->dnode, "./rp-address"); yang_dnode_get_pimaddr(&rp_addr, args->dnode, "./rp-address");
if (yang_dnode_get(args->dnode, "./group-list")) { if (yang_dnode_get(args->dnode, "./group-list")) {
yang_dnode_get_ipv4p(&group, args->dnode, yang_dnode_get_prefix(&group, args->dnode,
"./group-list"); "./group-list");
apply_mask_ipv4((struct prefix_ipv4 *)&group); apply_mask(&group);
result = pim_no_rp_cmd_worker(pim, rp_addr.ip._v4_addr, result = pim_no_rp_cmd_worker(pim, rp_addr, group, NULL,
group, NULL, args->errmsg, args->errmsg,
args->errmsg_len); args->errmsg_len);
} }
else if (yang_dnode_get(args->dnode, "./prefix-list")) { else if (yang_dnode_get(args->dnode, "./prefix-list")) {
plist = yang_dnode_get_string(args->dnode, plist = yang_dnode_get_string(args->dnode,
"./prefix-list"); "./prefix-list");
if (!str2prefix("224.0.0.0/4", &group)) { if (!pim_get_all_mcast_group(&group)) {
flog_err( flog_err(
EC_LIB_DEVELOPMENT, EC_LIB_DEVELOPMENT,
"Unable to convert 224.0.0.0/4 to prefix"); "Unable to convert 224.0.0.0/4 to prefix");
return NB_ERR_INCONSISTENCY; return NB_ERR_INCONSISTENCY;
} }
result = pim_no_rp_cmd_worker(pim, rp_addr.ip._v4_addr, result = pim_no_rp_cmd_worker(pim, rp_addr, group,
group, plist, plist, args->errmsg,
args->errmsg, args->errmsg_len);
args->errmsg_len);
} }
if (result) if (result)
@ -2396,7 +2389,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
struct vrf *vrf; struct vrf *vrf;
struct pim_instance *pim; struct pim_instance *pim;
struct prefix group; struct prefix group;
struct ipaddr rp_addr; pim_addr rp_addr;
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
@ -2406,12 +2399,11 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
case NB_EV_APPLY: case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true); vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info; pim = vrf->info;
yang_dnode_get_ip(&rp_addr, args->dnode, "../rp-address"); yang_dnode_get_pimaddr(&rp_addr, args->dnode, "../rp-address");
yang_dnode_get_ipv4p(&group, args->dnode, NULL); yang_dnode_get_prefix(&group, args->dnode, NULL);
apply_mask_ipv4((struct prefix_ipv4 *)&group); apply_mask(&group);
return pim_rp_cmd_worker(pim, rp_addr, group, NULL,
return pim_rp_cmd_worker(pim, rp_addr.ip._v4_addr, group, args->errmsg, args->errmsg_len);
NULL, args->errmsg, args->errmsg_len);
} }
return NB_OK; return NB_OK;
@ -2423,7 +2415,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
struct vrf *vrf; struct vrf *vrf;
struct pim_instance *pim; struct pim_instance *pim;
struct prefix group; struct prefix group;
struct ipaddr rp_addr; pim_addr rp_addr;
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
@ -2433,13 +2425,12 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
case NB_EV_APPLY: case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true); vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info; pim = vrf->info;
yang_dnode_get_ip(&rp_addr, args->dnode, "../rp-address"); yang_dnode_get_pimaddr(&rp_addr, args->dnode, "../rp-address");
yang_dnode_get_ipv4p(&group, args->dnode, NULL); yang_dnode_get_prefix(&group, args->dnode, NULL);
apply_mask_ipv4((struct prefix_ipv4 *)&group); apply_mask(&group);
return pim_no_rp_cmd_worker(pim, rp_addr.ip._v4_addr, group, return pim_no_rp_cmd_worker(pim, rp_addr, group, NULL,
NULL, args->errmsg, args->errmsg, args->errmsg_len);
args->errmsg_len);
} }
return NB_OK; return NB_OK;
@ -2454,7 +2445,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
struct vrf *vrf; struct vrf *vrf;
struct pim_instance *pim; struct pim_instance *pim;
struct prefix group; struct prefix group;
struct ipaddr rp_addr; pim_addr rp_addr;
const char *plist; const char *plist;
switch (args->event) { switch (args->event) {
@ -2466,14 +2457,14 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
vrf = nb_running_get_entry(args->dnode, NULL, true); vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info; pim = vrf->info;
plist = yang_dnode_get_string(args->dnode, NULL); plist = yang_dnode_get_string(args->dnode, NULL);
yang_dnode_get_ip(&rp_addr, args->dnode, "../rp-address"); yang_dnode_get_pimaddr(&rp_addr, args->dnode, "../rp-address");
if (!str2prefix("224.0.0.0/4", &group)) { if (!pim_get_all_mcast_group(&group)) {
flog_err(EC_LIB_DEVELOPMENT, flog_err(EC_LIB_DEVELOPMENT,
"Unable to convert 224.0.0.0/4 to prefix"); "Unable to convert 224.0.0.0/4 to prefix");
return NB_ERR_INCONSISTENCY; return NB_ERR_INCONSISTENCY;
} }
return pim_rp_cmd_worker(pim, rp_addr.ip._v4_addr, group, return pim_rp_cmd_worker(pim, rp_addr, group, plist,
plist, args->errmsg, args->errmsg_len); args->errmsg, args->errmsg_len);
} }
return NB_OK; return NB_OK;
@ -2485,7 +2476,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
struct vrf *vrf; struct vrf *vrf;
struct pim_instance *pim; struct pim_instance *pim;
struct prefix group; struct prefix group;
struct ipaddr rp_addr; pim_addr rp_addr;
const char *plist; const char *plist;
switch (args->event) { switch (args->event) {
@ -2496,16 +2487,15 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
case NB_EV_APPLY: case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true); vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info; pim = vrf->info;
yang_dnode_get_ip(&rp_addr, args->dnode, "../rp-address"); yang_dnode_get_pimaddr(&rp_addr, args->dnode, "../rp-address");
plist = yang_dnode_get_string(args->dnode, NULL); plist = yang_dnode_get_string(args->dnode, NULL);
if (!str2prefix("224.0.0.0/4", &group)) { if (!pim_get_all_mcast_group(&group)) {
flog_err(EC_LIB_DEVELOPMENT, flog_err(EC_LIB_DEVELOPMENT,
"Unable to convert 224.0.0.0/4 to prefix"); "Unable to convert 224.0.0.0/4 to prefix");
return NB_ERR_INCONSISTENCY; return NB_ERR_INCONSISTENCY;
} }
return pim_no_rp_cmd_worker(pim, rp_addr.ip._v4_addr, group, return pim_no_rp_cmd_worker(pim, rp_addr, group, plist,
plist, args->errmsg, args->errmsg, args->errmsg_len);
args->errmsg_len);
break; break;
} }

View File

@ -48,6 +48,7 @@
#include "pim_oil.h" #include "pim_oil.h"
#include "pim_zebra.h" #include "pim_zebra.h"
#include "pim_bsm.h" #include "pim_bsm.h"
#include "pim_util.h"
/* Cleanup pim->rpf_hash each node data */ /* Cleanup pim->rpf_hash each node data */
void pim_rp_list_hash_clean(void *data) void pim_rp_list_hash_clean(void *data)
@ -113,7 +114,7 @@ void pim_rp_init(struct pim_instance *pim)
rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info)); rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info));
if (!str2prefix("224.0.0.0/4", &rp_info->group)) { if (!pim_get_all_mcast_group(&rp_info->group)) {
flog_err(EC_LIB_DEVELOPMENT, flog_err(EC_LIB_DEVELOPMENT,
"Unable to convert 224.0.0.0/4 to prefix"); "Unable to convert 224.0.0.0/4 to prefix");
list_delete(&pim->rp_list); list_delete(&pim->rp_list);
@ -148,15 +149,17 @@ void pim_rp_free(struct pim_instance *pim)
* Given an RP's prefix-list, return the RP's rp_info for that prefix-list * Given an RP's prefix-list, return the RP's rp_info for that prefix-list
*/ */
static struct rp_info *pim_rp_find_prefix_list(struct pim_instance *pim, static struct rp_info *pim_rp_find_prefix_list(struct pim_instance *pim,
struct in_addr rp, pim_addr rp, const char *plist)
const char *plist)
{ {
struct listnode *node; struct listnode *node;
struct rp_info *rp_info; struct rp_info *rp_info;
struct prefix rp_prefix;
pim_addr_to_prefix(&rp_prefix, rp);
for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) { for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr if (prefix_same(&rp_prefix, &rp_info->rp.rpf_addr) &&
&& rp_info->plist && strcmp(rp_info->plist, plist) == 0) { rp_info->plist && strcmp(rp_info->plist, plist) == 0) {
return rp_info; return rp_info;
} }
} }
@ -185,16 +188,17 @@ static int pim_rp_prefix_list_used(struct pim_instance *pim, const char *plist)
* Given an RP's address, return the RP's rp_info that is an exact match for * Given an RP's address, return the RP's rp_info that is an exact match for
* 'group' * 'group'
*/ */
static struct rp_info *pim_rp_find_exact(struct pim_instance *pim, static struct rp_info *pim_rp_find_exact(struct pim_instance *pim, pim_addr rp,
struct in_addr rp,
const struct prefix *group) const struct prefix *group)
{ {
struct listnode *node; struct listnode *node;
struct rp_info *rp_info; struct rp_info *rp_info;
struct prefix rp_prefix;
pim_addr_to_prefix(&rp_prefix, rp);
for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) { for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr if (prefix_same(&rp_prefix, &rp_info->rp.rpf_addr) &&
&& prefix_same(&rp_info->group, group)) prefix_same(&rp_info->group, group))
return rp_info; return rp_info;
} }
@ -238,7 +242,7 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
bp = NULL; bp = NULL;
for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) { for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
if (rp_info->plist) { if (rp_info->plist) {
plist = prefix_list_lookup(AFI_IP, rp_info->plist); plist = prefix_list_lookup(PIM_AFI, rp_info->plist);
if (prefix_list_apply_ext(plist, &entry, group, true) if (prefix_list_apply_ext(plist, &entry, group, true)
== PREFIX_DENY || !entry) == PREFIX_DENY || !entry)
@ -412,11 +416,10 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
} }
int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix group, int pim_rp_new(struct pim_instance *pim, pim_addr rp_addr, struct prefix group,
const char *plist, enum rp_source rp_src_flag) const char *plist, enum rp_source rp_src_flag)
{ {
int result = 0; int result = 0;
char rp[INET_ADDRSTRLEN];
struct rp_info *rp_info; struct rp_info *rp_info;
struct rp_info *rp_all; struct rp_info *rp_all;
struct prefix group_all; struct prefix group_all;
@ -428,25 +431,20 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix g
struct pim_upstream *up; struct pim_upstream *up;
bool upstream_updated = false; bool upstream_updated = false;
if (rp_addr.s_addr == INADDR_ANY) if (pim_addr_is_any(rp_addr))
return PIM_RP_BAD_ADDRESS; return PIM_RP_BAD_ADDRESS;
rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info)); rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info));
rp_info->rp.rpf_addr.family = AF_INET; pim_addr_to_prefix(&rp_info->rp.rpf_addr, rp_addr);
rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
rp_info->rp.rpf_addr.u.prefix4 = rp_addr;
prefix_copy(&rp_info->group, &group); prefix_copy(&rp_info->group, &group);
rp_info->rp_src = rp_src_flag; rp_info->rp_src = rp_src_flag;
inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp, sizeof(rp));
if (plist) { if (plist) {
/* /*
* Return if the prefix-list is already configured for this RP * Return if the prefix-list is already configured for this RP
*/ */
if (pim_rp_find_prefix_list(pim, rp_info->rp.rpf_addr.u.prefix4, if (pim_rp_find_prefix_list(pim, rp_addr, plist)) {
plist)) {
XFREE(MTYPE_PIM_RP, rp_info); XFREE(MTYPE_PIM_RP, rp_info);
return PIM_SUCCESS; return PIM_SUCCESS;
} }
@ -464,14 +462,14 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix g
*/ */
for (ALL_LIST_ELEMENTS(pim->rp_list, node, nnode, for (ALL_LIST_ELEMENTS(pim->rp_list, node, nnode,
tmp_rp_info)) { tmp_rp_info)) {
if (rp_info->rp.rpf_addr.u.prefix4.s_addr if (prefix_same(&rp_info->rp.rpf_addr,
== tmp_rp_info->rp.rpf_addr.u.prefix4.s_addr) { &tmp_rp_info->rp.rpf_addr)) {
if (tmp_rp_info->plist) if (tmp_rp_info->plist)
pim_rp_del_config(pim, rp, NULL, pim_rp_del_config(pim, rp_addr, NULL,
tmp_rp_info->plist); tmp_rp_info->plist);
else else
pim_rp_del_config( pim_rp_del_config(
pim, rp, pim, rp_addr,
prefix2str(&tmp_rp_info->group, prefix2str(&tmp_rp_info->group,
buffer, BUFSIZ), buffer, BUFSIZ),
NULL); NULL);
@ -481,7 +479,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix g
rp_info->plist = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist); rp_info->plist = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist);
} else { } else {
if (!str2prefix("224.0.0.0/4", &group_all)) { if (!pim_get_all_mcast_group(&group_all)) {
XFREE(MTYPE_PIM_RP, rp_info); XFREE(MTYPE_PIM_RP, rp_info);
return PIM_GROUP_BAD_ADDRESS; return PIM_GROUP_BAD_ADDRESS;
} }
@ -500,11 +498,10 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix g
*/ */
for (ALL_LIST_ELEMENTS(pim->rp_list, node, nnode, for (ALL_LIST_ELEMENTS(pim->rp_list, node, nnode,
tmp_rp_info)) { tmp_rp_info)) {
if (tmp_rp_info->plist if (tmp_rp_info->plist &&
&& rp_info->rp.rpf_addr.u.prefix4.s_addr prefix_same(&rp_info->rp.rpf_addr,
== tmp_rp_info->rp.rpf_addr.u.prefix4 &tmp_rp_info->rp.rpf_addr)) {
.s_addr) { pim_rp_del_config(pim, rp_addr, NULL,
pim_rp_del_config(pim, rp, NULL,
tmp_rp_info->plist); tmp_rp_info->plist);
} }
} }
@ -519,10 +516,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix g
XFREE(MTYPE_PIM_RP, rp_info); XFREE(MTYPE_PIM_RP, rp_info);
/* Register addr with Zebra NHT */ /* Register addr with Zebra NHT */
nht_p.family = AF_INET; nht_p = rp_all->rp.rpf_addr;
nht_p.prefixlen = IPV4_MAX_BITLEN;
nht_p.u.prefix4 =
rp_all->rp.rpf_addr.u.prefix4; // RP address
if (PIM_DEBUG_PIM_NHT_RP) if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug( zlog_debug(
"%s: NHT Register rp_all addr %pFX grp %pFX ", "%s: NHT Register rp_all addr %pFX grp %pFX ",
@ -564,8 +558,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix g
/* /*
* Return if the group is already configured for this RP * Return if the group is already configured for this RP
*/ */
tmp_rp_info = pim_rp_find_exact( tmp_rp_info = pim_rp_find_exact(pim, rp_addr, &rp_info->group);
pim, rp_info->rp.rpf_addr.u.prefix4, &rp_info->group);
if (tmp_rp_info) { if (tmp_rp_info) {
if ((tmp_rp_info->rp_src != rp_src_flag) if ((tmp_rp_info->rp_src != rp_src_flag)
&& (rp_src_flag == RP_SRC_STATIC)) && (rp_src_flag == RP_SRC_STATIC))
@ -601,8 +594,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix g
} }
result = pim_rp_change( result = pim_rp_change(
pim, pim, rp_addr,
rp_info->rp.rpf_addr.u.prefix4,
tmp_rp_info->group, tmp_rp_info->group,
rp_src_flag); rp_src_flag);
XFREE(MTYPE_PIM_RP, rp_info); XFREE(MTYPE_PIM_RP, rp_info);
@ -643,9 +635,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix g
pim_rp_refresh_group_to_rp_mapping(pim); pim_rp_refresh_group_to_rp_mapping(pim);
/* Register addr with Zebra NHT */ /* Register addr with Zebra NHT */
nht_p.family = AF_INET; nht_p = rp_info->rp.rpf_addr;
nht_p.prefixlen = IPV4_MAX_BITLEN;
nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
if (PIM_DEBUG_PIM_NHT_RP) if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ", zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ",
__func__, &nht_p, &rp_info->group); __func__, &nht_p, &rp_info->group);
@ -657,32 +647,30 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, struct prefix g
return PIM_SUCCESS; return PIM_SUCCESS;
} }
int pim_rp_del_config(struct pim_instance *pim, const char *rp, void pim_rp_del_config(struct pim_instance *pim, pim_addr rp_addr,
const char *group_range, const char *plist) const char *group_range, const char *plist)
{ {
struct prefix group; struct prefix group;
struct in_addr rp_addr;
int result; int result;
if (group_range == NULL) if (group_range == NULL)
result = str2prefix("224.0.0.0/4", &group); result = pim_get_all_mcast_group(&group);
else else
result = str2prefix(group_range, &group); result = str2prefix(group_range, &group);
if (!result) if (!result) {
return PIM_GROUP_BAD_ADDRESS; if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
"%s: String to prefix failed for %pPAs group",
__func__, &rp_addr);
return;
}
result = inet_pton(AF_INET, rp, &rp_addr); pim_rp_del(pim, rp_addr, group, plist, RP_SRC_STATIC);
if (result <= 0)
return PIM_RP_BAD_ADDRESS;
result = pim_rp_del(pim, rp_addr, group, plist, RP_SRC_STATIC);
return result;
} }
int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, int pim_rp_del(struct pim_instance *pim, pim_addr rp_addr, struct prefix group,
struct prefix group, const char *plist, const char *plist, enum rp_source rp_src_flag)
enum rp_source rp_src_flag)
{ {
struct prefix g_all; struct prefix g_all;
struct rp_info *rp_info; struct rp_info *rp_info;
@ -694,12 +682,8 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
struct pim_upstream *up; struct pim_upstream *up;
struct bsgrp_node *bsgrp = NULL; struct bsgrp_node *bsgrp = NULL;
struct bsm_rpinfo *bsrp = NULL; struct bsm_rpinfo *bsrp = NULL;
char rp_str[INET_ADDRSTRLEN];
bool upstream_updated = false; bool upstream_updated = false;
if (!inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str)))
snprintf(rp_str, sizeof(rp_str), "<rp?>");
if (plist) if (plist)
rp_info = pim_rp_find_prefix_list(pim, rp_addr, plist); rp_info = pim_rp_find_prefix_list(pim, rp_addr, plist);
else else
@ -714,8 +698,8 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
} }
if (PIM_DEBUG_PIM_TRACE) if (PIM_DEBUG_PIM_TRACE)
zlog_debug("%s: Delete RP %s for the group %pFX", __func__, zlog_debug("%s: Delete RP %pPA for the group %pFX", __func__,
rp_str, &group); &rp_addr, &group);
/* While static RP is getting deleted, we need to check if dynamic RP /* While static RP is getting deleted, we need to check if dynamic RP
* present for the same group in BSM RP table, then install the dynamic * present for the same group in BSM RP table, then install the dynamic
@ -727,19 +711,11 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
if (bsgrp) { if (bsgrp) {
bsrp = bsm_rpinfos_first(bsgrp->bsrp_list); bsrp = bsm_rpinfos_first(bsgrp->bsrp_list);
if (bsrp) { if (bsrp) {
if (PIM_DEBUG_PIM_TRACE) { if (PIM_DEBUG_PIM_TRACE)
char bsrp_str[INET_ADDRSTRLEN];
if (!inet_ntop(AF_INET, bsrp, bsrp_str,
sizeof(bsrp_str)))
snprintf(bsrp_str,
sizeof(bsrp_str),
"<bsrp?>");
zlog_debug( zlog_debug(
"%s: BSM RP %s found for the group %pFX", "%s: BSM RP %pPA found for the group %pFX",
__func__, bsrp_str, &group); __func__, &bsrp->rp_address,
} &group);
return pim_rp_change(pim, bsrp->rp_address, return pim_rp_change(pim, bsrp->rp_address,
group, RP_SRC_BSR); group, RP_SRC_BSR);
} }
@ -752,15 +728,13 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
} }
/* Deregister addr with Zebra NHT */ /* Deregister addr with Zebra NHT */
nht_p.family = AF_INET; nht_p = rp_info->rp.rpf_addr;
nht_p.prefixlen = IPV4_MAX_BITLEN;
nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
if (PIM_DEBUG_PIM_NHT_RP) if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: Deregister RP addr %pFX with Zebra ", __func__, zlog_debug("%s: Deregister RP addr %pFX with Zebra ", __func__,
&nht_p); &nht_p);
pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info); pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info);
if (!str2prefix("224.0.0.0/4", &g_all)) if (!pim_get_all_mcast_group(&g_all))
return PIM_RP_BAD_ADDRESS; return PIM_RP_BAD_ADDRESS;
rp_all = pim_rp_find_match_group(pim, &g_all); rp_all = pim_rp_find_match_group(pim, &g_all);
@ -851,7 +825,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
return PIM_SUCCESS; return PIM_SUCCESS;
} }
int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr, int pim_rp_change(struct pim_instance *pim, pim_addr new_rp_addr,
struct prefix group, enum rp_source rp_src_flag) struct prefix group, enum rp_source rp_src_flag)
{ {
struct prefix nht_p; struct prefix nht_p;
@ -860,6 +834,7 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
struct rp_info *rp_info = NULL; struct rp_info *rp_info = NULL;
struct pim_upstream *up; struct pim_upstream *up;
bool upstream_updated = false; bool upstream_updated = false;
pim_addr old_rp_addr;
rn = route_node_lookup(pim->rp_table, &group); rn = route_node_lookup(pim->rp_table, &group);
if (!rn) { if (!rn) {
@ -875,7 +850,8 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
return result; return result;
} }
if (rp_info->rp.rpf_addr.u.prefix4.s_addr == new_rp_addr.s_addr) { old_rp_addr = pim_addr_from_prefix(&rp_info->rp.rpf_addr);
if (!pim_addr_cmp(new_rp_addr, old_rp_addr)) {
if (rp_info->rp_src != rp_src_flag) { if (rp_info->rp_src != rp_src_flag) {
rp_info->rp_src = rp_src_flag; rp_info->rp_src = rp_src_flag;
route_unlock_node(rn); route_unlock_node(rn);
@ -883,12 +859,13 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
} }
} }
nht_p.family = AF_INET; nht_p.family = PIM_AF;
nht_p.prefixlen = IPV4_MAX_BITLEN; nht_p.prefixlen = PIM_MAX_BITLEN;
/* Deregister old RP addr with Zebra NHT */ /* Deregister old RP addr with Zebra NHT */
if (rp_info->rp.rpf_addr.u.prefix4.s_addr != INADDR_ANY) {
nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; if (!pim_addr_is_any(old_rp_addr)) {
nht_p = rp_info->rp.rpf_addr;
if (PIM_DEBUG_PIM_NHT_RP) if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: Deregister RP addr %pFX with Zebra ", zlog_debug("%s: Deregister RP addr %pFX with Zebra ",
__func__, &nht_p); __func__, &nht_p);
@ -898,7 +875,8 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
pim_rp_nexthop_del(rp_info); pim_rp_nexthop_del(rp_info);
listnode_delete(pim->rp_list, rp_info); listnode_delete(pim->rp_list, rp_info);
/* Update the new RP address*/ /* Update the new RP address*/
rp_info->rp.rpf_addr.u.prefix4 = new_rp_addr;
pim_addr_to_prefix(&rp_info->rp.rpf_addr, new_rp_addr);
rp_info->rp_src = rp_src_flag; rp_info->rp_src = rp_src_flag;
rp_info->i_am_rp = 0; rp_info->i_am_rp = 0;
@ -923,7 +901,7 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
pim_zebra_update_all_interfaces(pim); pim_zebra_update_all_interfaces(pim);
/* Register new RP addr with Zebra NHT */ /* Register new RP addr with Zebra NHT */
nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; nht_p = rp_info->rp.rpf_addr;
if (PIM_DEBUG_PIM_NHT_RP) if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ", zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ",
__func__, &nht_p, &rp_info->group); __func__, &nht_p, &rp_info->group);
@ -1053,7 +1031,6 @@ void pim_i_am_rp_re_evaluate(struct pim_instance *pim)
} }
} }
#if PIM_IPV == 4
/* /*
* I_am_RP(G) is true if the group-to-RP mapping indicates that * I_am_RP(G) is true if the group-to-RP mapping indicates that
* this router is the RP for the group. * this router is the RP for the group.
@ -1066,10 +1043,7 @@ int pim_rp_i_am_rp(struct pim_instance *pim, pim_addr group)
struct rp_info *rp_info; struct rp_info *rp_info;
memset(&g, 0, sizeof(g)); memset(&g, 0, sizeof(g));
g.family = AF_INET; pim_addr_to_prefix(&g, group);
g.prefixlen = IPV4_MAX_BITLEN;
g.u.prefix4 = group;
rp_info = pim_rp_find_match_group(pim, &g); rp_info = pim_rp_find_match_group(pim, &g);
if (rp_info) if (rp_info)
@ -1088,9 +1062,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, pim_addr group)
struct rp_info *rp_info; struct rp_info *rp_info;
memset(&g, 0, sizeof(g)); memset(&g, 0, sizeof(g));
g.family = AF_INET; pim_addr_to_prefix(&g, group);
g.prefixlen = IPV4_MAX_BITLEN;
g.u.prefix4 = group;
rp_info = pim_rp_find_match_group(pim, &g); rp_info = pim_rp_find_match_group(pim, &g);
@ -1098,9 +1070,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, pim_addr group)
struct prefix nht_p; struct prefix nht_p;
/* Register addr with Zebra NHT */ /* Register addr with Zebra NHT */
nht_p.family = AF_INET; nht_p = rp_info->rp.rpf_addr;
nht_p.prefixlen = IPV4_MAX_BITLEN;
nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
if (PIM_DEBUG_PIM_NHT_RP) if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug( zlog_debug(
"%s: NHT Register RP addr %pFX grp %pFX with Zebra", "%s: NHT Register RP addr %pFX grp %pFX with Zebra",
@ -1131,53 +1101,35 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up,
struct prefix g; struct prefix g;
memset(&g, 0, sizeof(g)); memset(&g, 0, sizeof(g));
g.family = AF_INET;
g.prefixlen = IPV4_MAX_BITLEN; pim_addr_to_prefix(&g, group);
g.u.prefix4 = group;
rp_info = pim_rp_find_match_group(pim, &g); rp_info = pim_rp_find_match_group(pim, &g);
if (!rp_info || ((pim_rpf_addr_is_inaddr_any(&rp_info->rp)) && if (!rp_info || ((pim_rpf_addr_is_inaddr_any(&rp_info->rp)) &&
(source.s_addr == INADDR_ANY))) { (pim_addr_is_any(source)))) {
if (PIM_DEBUG_PIM_NHT_RP) if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: Received a (*,G) with no RP configured", zlog_debug("%s: Received a (*,G) with no RP configured",
__func__); __func__);
up->s_addr = INADDR_ANY; *up = PIMADDR_ANY;
return 0; return 0;
} }
*up = (source.s_addr == INADDR_ANY) ? rp_info->rp.rpf_addr.u.prefix4 if (pim_addr_is_any(source))
: source; *up = pim_addr_from_prefix(&rp_info->rp.rpf_addr);
else
*up = source;
return 1; return 1;
} }
#else
CPP_NOTICE("functions stubbed out for IPv6");
int pim_rp_i_am_rp(struct pim_instance *pim, pim_addr group)
{
return 0;
}
struct pim_rpf *pim_rp_g(struct pim_instance *pim, pim_addr group)
{
return NULL;
}
int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up,
pim_addr source, pim_addr group)
{
return 0;
}
#endif
int pim_rp_config_write(struct pim_instance *pim, struct vty *vty, int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
const char *spaces) const char *spaces)
{ {
struct listnode *node; struct listnode *node;
struct rp_info *rp_info; struct rp_info *rp_info;
char rp_buffer[32];
int count = 0; int count = 0;
pim_addr rp_addr;
for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) { for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
if (pim_rpf_addr_is_inaddr_any(&rp_info->rp)) if (pim_rpf_addr_is_inaddr_any(&rp_info->rp))
@ -1186,18 +1138,15 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
if (rp_info->rp_src == RP_SRC_BSR) if (rp_info->rp_src == RP_SRC_BSR)
continue; continue;
rp_addr = pim_addr_from_prefix(&rp_info->rp.rpf_addr);
if (rp_info->plist) if (rp_info->plist)
vty_out(vty, "%sip pim rp %s prefix-list %s\n", spaces, vty_out(vty,
inet_ntop(AF_INET, "%s" PIM_AF_NAME
&rp_info->rp.rpf_addr.u.prefix4, " pim rp %pPA prefix-list %s\n",
rp_buffer, 32), spaces, &rp_addr, rp_info->plist);
rp_info->plist);
else else
vty_out(vty, "%sip pim rp %s %pFX\n", spaces, vty_out(vty, "%s" PIM_AF_NAME " pim rp %pPA %pFX\n",
inet_ntop(AF_INET, spaces, &rp_addr, &rp_info->group);
&rp_info->rp.rpf_addr.u.prefix4,
rp_buffer, 32),
&rp_info->group);
count++; count++;
} }

View File

@ -47,15 +47,13 @@ void pim_rp_free(struct pim_instance *pim);
void pim_rp_list_hash_clean(void *data); void pim_rp_list_hash_clean(void *data);
int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, int pim_rp_new(struct pim_instance *pim, pim_addr rp_addr, struct prefix group,
struct prefix group, const char *plist, const char *plist, enum rp_source rp_src_flag);
enum rp_source rp_src_flag); void pim_rp_del_config(struct pim_instance *pim, pim_addr rp_addr,
int pim_rp_del_config(struct pim_instance *pim, const char *rp, const char *group, const char *plist);
const char *group, const char *plist); int pim_rp_del(struct pim_instance *pim, pim_addr rp_addr, struct prefix group,
int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, const char *plist, enum rp_source rp_src_flag);
struct prefix group, const char *plist, int pim_rp_change(struct pim_instance *pim, pim_addr new_rp_addr,
enum rp_source rp_src_flag);
int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
struct prefix group, enum rp_source rp_src_flag); struct prefix group, enum rp_source rp_src_flag);
void pim_rp_prefix_list_update(struct pim_instance *pim, void pim_rp_prefix_list_update(struct pim_instance *pim,
struct prefix_list *plist); struct prefix_list *plist);

View File

@ -71,17 +71,15 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
return false; return false;
#endif #endif
if (!pim_addr_cmp(nexthop->last_lookup, addr) if ((!pim_addr_cmp(nexthop->last_lookup, addr)) &&
&& (nexthop->last_lookup_time > pim->last_route_change_time)) { (nexthop->last_lookup_time > pim->last_route_change_time)) {
if (PIM_DEBUG_PIM_NHT) { if (PIM_DEBUG_PIM_NHT)
char nexthop_str[PREFIX_STRLEN];
pim_addr_dump("<nexthop?>", &nexthop->mrib_nexthop_addr,
nexthop_str, sizeof(nexthop_str));
zlog_debug( zlog_debug(
"%s: Using last lookup for %pPAs at %lld, %" PRId64" addr %s", "%s: Using last lookup for %pPAs at %lld, %" PRId64
" addr %pFX",
__func__, &addr, nexthop->last_lookup_time, __func__, &addr, nexthop->last_lookup_time,
pim->last_route_change_time, nexthop_str); pim->last_route_change_time,
} &nexthop->mrib_nexthop_addr);
pim->nexthop_lookups_avoided++; pim->nexthop_lookups_avoided++;
return true; return true;
} else { } else {
@ -140,18 +138,13 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
} }
if (found) { if (found) {
if (PIM_DEBUG_ZEBRA) { if (PIM_DEBUG_ZEBRA)
char nexthop_str[PREFIX_STRLEN];
pim_addr_dump("<nexthop?>",
&nexthop_tab[i].nexthop_addr, nexthop_str,
sizeof(nexthop_str));
zlog_debug( zlog_debug(
"%s %s: found nexthop %s for address %pPAs: interface %s ifindex=%d metric=%d pref=%d", "%s %s: found nexthop %pFX for address %pPAs: interface %s ifindex=%d metric=%d pref=%d",
__FILE__, __func__, nexthop_str, &addr, __FILE__, __func__,
ifp->name, first_ifindex, &nexthop_tab[i].nexthop_addr, &addr, ifp->name,
nexthop_tab[i].route_metric, first_ifindex, nexthop_tab[i].route_metric,
nexthop_tab[i].protocol_distance); nexthop_tab[i].protocol_distance);
}
/* update nexthop data */ /* update nexthop data */
nexthop->interface = ifp; nexthop->interface = ifp;
nexthop->mrib_nexthop_addr = nexthop_tab[i].nexthop_addr; nexthop->mrib_nexthop_addr = nexthop_tab[i].nexthop_addr;
@ -215,7 +208,6 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
bool neigh_needed = true; bool neigh_needed = true;
uint32_t saved_mrib_route_metric; uint32_t saved_mrib_route_metric;
pim_addr rpf_addr; pim_addr rpf_addr;
pim_addr saved_rpf_addr;
if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags)) if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags))
return PIM_RPF_OK; return PIM_RPF_OK;
@ -264,19 +256,14 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
/* detect change in pim_nexthop */ /* detect change in pim_nexthop */
if (nexthop_mismatch(&rpf->source_nexthop, &saved.source_nexthop)) { if (nexthop_mismatch(&rpf->source_nexthop, &saved.source_nexthop)) {
if (PIM_DEBUG_ZEBRA) { if (PIM_DEBUG_ZEBRA)
char nhaddr_str[PREFIX_STRLEN]; zlog_debug("%s(%s): (S,G)=%s source nexthop now is: interface=%s address=%pFX pref=%d metric=%d",
pim_addr_dump("<addr?>",
&rpf->source_nexthop.mrib_nexthop_addr,
nhaddr_str, sizeof(nhaddr_str));
zlog_debug("%s(%s): (S,G)=%s source nexthop now is: interface=%s address=%s pref=%d metric=%d",
__func__, caller, __func__, caller,
up->sg_str, up->sg_str,
rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>", rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>",
nhaddr_str, &rpf->source_nexthop.mrib_nexthop_addr,
rpf->source_nexthop.mrib_metric_preference, rpf->source_nexthop.mrib_metric_preference,
rpf->source_nexthop.mrib_route_metric); rpf->source_nexthop.mrib_route_metric);
}
pim_upstream_update_join_desired(pim, up); pim_upstream_update_join_desired(pim, up);
pim_upstream_update_could_assert(up); pim_upstream_update_could_assert(up);
@ -300,10 +287,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
} }
/* detect change in RPF'(S,G) */ /* detect change in RPF'(S,G) */
if (!prefix_same(&saved.rpf_addr, &rpf->rpf_addr) ||
saved_rpf_addr = pim_addr_from_prefix(&saved.rpf_addr);
if (pim_addr_cmp(saved_rpf_addr, rpf_addr) ||
saved.source_nexthop.interface != rpf->source_nexthop.interface) { saved.source_nexthop.interface != rpf->source_nexthop.interface) {
pim_rpf_cost_change(pim, up, saved_mrib_route_metric); pim_rpf_cost_change(pim, up, saved_mrib_route_metric);
return PIM_RPF_CHANGED; return PIM_RPF_CHANGED;
@ -418,7 +402,7 @@ unsigned int pim_rpf_hash_key(const void *arg)
{ {
const struct pim_nexthop_cache *r = arg; const struct pim_nexthop_cache *r = arg;
#if PIM_IPV == 4 || !defined(PIM_V6_TEMP_BREAK) #if PIM_IPV == 4
return jhash_1word(r->rpf.rpf_addr.u.prefix4.s_addr, 0); return jhash_1word(r->rpf.rpf_addr.u.prefix4.s_addr, 0);
#else #else
return jhash2(r->rpf.rpf_addr.u.prefix6.s6_addr32, return jhash2(r->rpf.rpf_addr.u.prefix6.s6_addr32,

View File

@ -152,3 +152,17 @@ bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp)
pl = prefix_list_lookup(PIM_AFI, pim_ifp->boundary_oil_plist); pl = prefix_list_lookup(PIM_AFI, pim_ifp->boundary_oil_plist);
return pl ? prefix_list_apply(pl, &grp_pfx) == PREFIX_DENY : false; return pl ? prefix_list_apply(pl, &grp_pfx) == PREFIX_DENY : false;
} }
/* This function returns all multicast group */
int pim_get_all_mcast_group(struct prefix *prefix)
{
#if PIM_IPV == 4
if (!str2prefix("224.0.0.0/4", prefix))
return 0;
#else
if (!str2prefix("FF00::0/8", prefix))
return 0;
#endif
return 1;
}

View File

@ -36,4 +36,5 @@ void pim_pkt_dump(const char *label, const uint8_t *buf, int size);
int pim_is_group_224_0_0_0_24(struct in_addr group_addr); int pim_is_group_224_0_0_0_24(struct in_addr group_addr);
int pim_is_group_224_4(struct in_addr group_addr); int pim_is_group_224_4(struct in_addr group_addr);
bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp); bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp);
int pim_get_all_mcast_group(struct prefix *prefix);
#endif /* PIM_UTIL_H */ #endif /* PIM_UTIL_H */

View File

@ -21,7 +21,6 @@ pim_common = \
pimd/pim_assert.c \ pimd/pim_assert.c \
pimd/pim_bfd.c \ pimd/pim_bfd.c \
pimd/pim_br.c \ pimd/pim_br.c \
pimd/pim_bsm.c \
pimd/pim_cmd_common.c \ pimd/pim_cmd_common.c \
pimd/pim_errors.c \ pimd/pim_errors.c \
pimd/pim_hello.c \ pimd/pim_hello.c \
@ -59,6 +58,7 @@ pim_common = \
pimd_pimd_SOURCES = \ pimd_pimd_SOURCES = \
$(pim_common) \ $(pim_common) \
pimd/pim_bsm.c \
pimd/pim_cmd.c \ pimd/pim_cmd.c \
pimd/pim_igmp.c \ pimd/pim_igmp.c \
pimd/pim_igmp_mtrace.c \ pimd/pim_igmp_mtrace.c \