mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 02:37:21 +00:00
pimd: rp_new & rp_del split into 2 tier functions & implement rp_change
pim_rp_new split into pim_rp_new_config and pim_rp_new. pim_rp_new_config is called by CLI. pim_rp_new will be called by pim_rp_new_config and bsm rp config. pim_rp_del is split into pim_rp_del_config and pim_rp_del pim_rp_del_config is called by CLI. pim_rp_del is called by pim_rp_del_config and bsm rp config Signed-off-by: Saravanan K <saravanank@vmware.com>
This commit is contained in:
parent
16c926c85d
commit
d0e418b42c
@ -36,8 +36,7 @@ static int pim_on_bs_timer(struct thread *t);
|
||||
static void pim_bs_timer_stop(struct bsm_scope *scope);
|
||||
|
||||
/* pim_bsm_write_config - Write the interface pim bsm configuration.*/
|
||||
void
|
||||
pim_bsm_write_config(struct vty *vty, struct interface *ifp)
|
||||
void pim_bsm_write_config(struct vty *vty, struct interface *ifp)
|
||||
{
|
||||
struct pim_interface *pim_ifp = ifp->info;
|
||||
|
||||
@ -49,7 +48,7 @@ pim_bsm_write_config(struct vty *vty, struct interface *ifp)
|
||||
}
|
||||
}
|
||||
|
||||
static void pim_free_bsgrp_data(struct bsgrp_node * bsgrp_node)
|
||||
static void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node)
|
||||
{
|
||||
if (bsgrp_node->bsrp_list)
|
||||
list_delete(&bsgrp_node->bsrp_list);
|
||||
@ -90,8 +89,8 @@ void pim_bsm_proc_free(struct pim_instance *pim)
|
||||
if (pim->global_scope.bsm_list)
|
||||
list_delete(&pim->global_scope.bsm_list);
|
||||
|
||||
for(rn = route_top(pim->global_scope.bsrp_table);
|
||||
rn; rn = route_next(rn)) {
|
||||
for (rn = route_top(pim->global_scope.bsrp_table); rn;
|
||||
rn = route_next(rn)) {
|
||||
bsgrp = rn->info;
|
||||
if (!bsgrp)
|
||||
continue;
|
||||
@ -111,8 +110,7 @@ static void pim_bs_timer_stop(struct bsm_scope *scope)
|
||||
{
|
||||
if (PIM_DEBUG_BSM)
|
||||
zlog_debug("%s : BS timer being stopped of sz: %d",
|
||||
__PRETTY_FUNCTION__,
|
||||
scope->sz_id);
|
||||
__PRETTY_FUNCTION__, scope->sz_id);
|
||||
THREAD_OFF(scope->bs_timer);
|
||||
}
|
||||
|
||||
@ -121,15 +119,33 @@ static void pim_bs_timer_start(struct bsm_scope *scope, int bs_timeout)
|
||||
if (!scope) {
|
||||
if (PIM_DEBUG_BSM)
|
||||
zlog_debug("%s : Invalid scope(NULL).",
|
||||
__PRETTY_FUNCTION__);
|
||||
__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
THREAD_OFF(scope->bs_timer);
|
||||
|
||||
if (PIM_DEBUG_BSM)
|
||||
zlog_debug("%s : starting bs timer for scope %d with timeout %d secs",
|
||||
__PRETTY_FUNCTION__, scope->sz_id, bs_timeout);
|
||||
__PRETTY_FUNCTION__, scope->sz_id, bs_timeout);
|
||||
thread_add_timer(router->master, pim_on_bs_timer, scope, bs_timeout,
|
||||
&scope->bs_timer);
|
||||
&scope->bs_timer);
|
||||
}
|
||||
|
||||
struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
|
||||
struct prefix *grp)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct bsgrp_node *bsgrp;
|
||||
|
||||
rn = route_node_lookup(scope->bsrp_table, grp);
|
||||
if (!rn) {
|
||||
if (PIM_DEBUG_BSM)
|
||||
zlog_debug("%s: Route node doesn't exist for the group",
|
||||
__PRETTY_FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
bsgrp = rn->info;
|
||||
route_unlock_node(rn);
|
||||
|
||||
return bsgrp;
|
||||
}
|
||||
|
@ -31,25 +31,24 @@
|
||||
#include "pim_msg.h"
|
||||
|
||||
/* Defines */
|
||||
#define PIM_GBL_SZ_ID 0 /* global scope zone id set to 0 */
|
||||
#define PIM_BS_TIME 60 /* RFC 5059 - Sec 5 */
|
||||
#define PIM_GBL_SZ_ID 0 /* global scope zone id set to 0 */
|
||||
#define PIM_BS_TIME 60 /* RFC 5059 - Sec 5 */
|
||||
#define PIM_BSR_DEFAULT_TIMEOUT 130 /* RFC 5059 - Sec 5 */
|
||||
|
||||
/* These structures are only encoded IPv4 specific */
|
||||
#define PIM_BSM_HDR_LEN sizeof(struct bsm_hdr)
|
||||
#define PIM_BSM_GRP_LEN sizeof(struct bsmmsg_grpinfo)
|
||||
#define PIM_BSM_RP_LEN sizeof(struct bsmmsg_rpinfo)
|
||||
#define PIM_BSM_HDR_LEN sizeof(struct bsm_hdr)
|
||||
#define PIM_BSM_GRP_LEN sizeof(struct bsmmsg_grpinfo)
|
||||
#define PIM_BSM_RP_LEN sizeof(struct bsmmsg_rpinfo)
|
||||
|
||||
#define PIM_MIN_BSM_LEN \
|
||||
(PIM_HDR_LEN + PIM_BSM_HDR_LEN + PIM_BSM_GRP_LEN + PIM_BSM_RP_LEN)
|
||||
|
||||
#define PIM_MIN_BSM_LEN (PIM_HDR_LEN + \
|
||||
PIM_BSM_HDR_LEN + \
|
||||
PIM_BSM_GRP_LEN + \
|
||||
PIM_BSM_RP_LEN)
|
||||
/* Datastructures
|
||||
* ==============
|
||||
*/
|
||||
|
||||
/* Non candidate BSR states */
|
||||
enum ncbsr_state{
|
||||
enum ncbsr_state {
|
||||
NO_INFO = 0,
|
||||
ACCEPT_ANY,
|
||||
ACCEPT_PREFERRED
|
||||
@ -57,19 +56,19 @@ enum ncbsr_state{
|
||||
|
||||
/* BSM scope - bsm processing is per scope */
|
||||
struct bsm_scope {
|
||||
int sz_id; /* scope zone id */
|
||||
enum ncbsr_state state; /* non candidate BSR state */
|
||||
bool accept_nofwd_bsm; /* no fwd bsm accepted for scope */
|
||||
int sz_id; /* scope zone id */
|
||||
enum ncbsr_state state; /* non candidate BSR state */
|
||||
bool accept_nofwd_bsm; /* no fwd bsm accepted for scope */
|
||||
struct in_addr current_bsr; /* current elected BSR for the sz */
|
||||
uint32_t current_bsr_prio; /* current BSR priority */
|
||||
int64_t current_bsr_first_ts; /* current BSR elected time */
|
||||
int64_t current_bsr_last_ts; /* Last BSM received from E-BSR */
|
||||
uint16_t bsm_frag_tag; /* Last received frag tag from E-BSR */
|
||||
uint8_t hashMasklen; /* Mask in hash calc RFC 7761 4.7.2 */
|
||||
uint16_t bsm_frag_tag; /* Last received frag tag from E-BSR */
|
||||
uint8_t hashMasklen; /* Mask in hash calc RFC 7761 4.7.2 */
|
||||
struct pim_instance *pim; /* Back pointer to pim instance */
|
||||
struct list *bsm_list; /* list of bsm frag for frowarding */
|
||||
struct list *bsm_list; /* list of bsm frag for frowarding */
|
||||
struct route_table *bsrp_table; /* group2rp mapping rcvd from BSR */
|
||||
struct thread *bs_timer; /* Boot strap timer */
|
||||
struct thread *bs_timer; /* Boot strap timer */
|
||||
struct thread *sz_timer;
|
||||
};
|
||||
|
||||
@ -85,12 +84,12 @@ struct bsm_info {
|
||||
* this node maintains the list of rp for the group.
|
||||
*/
|
||||
struct bsgrp_node {
|
||||
struct prefix group; /* Group range */
|
||||
struct bsm_scope *scope; /* Back ptr to scope */
|
||||
struct list *bsrp_list; /* list of RPs adv by BSR */
|
||||
struct prefix group; /* Group range */
|
||||
struct bsm_scope *scope; /* Back ptr to scope */
|
||||
struct list *bsrp_list; /* list of RPs adv by BSR */
|
||||
struct list *partial_bsrp_list; /* maintained until all RPs received */
|
||||
int pend_rp_cnt; /* Total RP - Received RP */
|
||||
uint16_t frag_tag; /* frag tag to identify the fragment */
|
||||
int pend_rp_cnt; /* Total RP - Received RP */
|
||||
uint16_t frag_tag; /* frag tag to identify the fragment */
|
||||
};
|
||||
|
||||
/* This is the list node of bsrp_list and partial bsrp list in
|
||||
@ -168,24 +167,26 @@ struct bsm_hdr {
|
||||
uint8_t hm_len;
|
||||
uint8_t bsr_prio;
|
||||
struct pim_encoded_ipv4_unicast bsr_addr;
|
||||
}__attribute__((packed));
|
||||
} __attribute__((packed));
|
||||
|
||||
struct bsmmsg_grpinfo {
|
||||
struct pim_encoded_group_ipv4 group;
|
||||
uint8_t rp_count;
|
||||
uint8_t frag_rp_count;
|
||||
uint16_t reserved;
|
||||
}__attribute__((packed));
|
||||
} __attribute__((packed));
|
||||
|
||||
struct bsmmsg_rpinfo {
|
||||
struct pim_encoded_ipv4_unicast rpaddr;
|
||||
uint16_t rp_holdtime;
|
||||
uint8_t rp_pri;
|
||||
uint8_t reserved;
|
||||
}__attribute__((packed));
|
||||
} __attribute__((packed));
|
||||
|
||||
/* API */
|
||||
void pim_bsm_proc_init(struct pim_instance *pim);
|
||||
void pim_bsm_proc_free(struct pim_instance *pim);
|
||||
void pim_bsm_write_config(struct vty *vty, struct interface *ifp);
|
||||
struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
|
||||
struct prefix *grp);
|
||||
#endif
|
||||
|
@ -5210,7 +5210,13 @@ static int pim_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
|
||||
{
|
||||
int result;
|
||||
|
||||
result = pim_rp_new(pim, rp, group, plist);
|
||||
result = pim_rp_new_config(pim, rp, group, plist);
|
||||
|
||||
if (result == PIM_GROUP_BAD_ADDR_MASK_COMBO) {
|
||||
vty_out(vty, "%% Inconsistent address and mask: %s\n",
|
||||
group);
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
if (result == PIM_GROUP_BAD_ADDRESS) {
|
||||
vty_out(vty, "%% Bad group address specified: %s\n", group);
|
||||
@ -5536,7 +5542,7 @@ static int pim_no_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
|
||||
const char *rp, const char *group,
|
||||
const char *plist)
|
||||
{
|
||||
int result = pim_rp_del(pim, rp, group, plist);
|
||||
int result = pim_rp_del_config(pim, rp, group, plist);
|
||||
|
||||
if (result == PIM_GROUP_BAD_ADDRESS) {
|
||||
vty_out(vty, "%% Bad group address specified: %s\n", group);
|
||||
|
307
pimd/pim_rp.c
307
pimd/pim_rp.c
@ -48,6 +48,7 @@
|
||||
#include "pim_mroute.h"
|
||||
#include "pim_oil.h"
|
||||
#include "pim_zebra.h"
|
||||
#include "pim_bsm.h"
|
||||
|
||||
/* Cleanup pim->rpf_hash each node data */
|
||||
void pim_rp_list_hash_clean(void *data)
|
||||
@ -406,10 +407,45 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
|
||||
pim_zebra_update_all_interfaces(pim);
|
||||
}
|
||||
|
||||
int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
const char *group_range, const char *plist)
|
||||
int pim_rp_new_config(struct pim_instance *pim, const char *rp,
|
||||
const char *group_range, const char *plist)
|
||||
{
|
||||
int result = 0;
|
||||
struct prefix group;
|
||||
struct in_addr rp_addr;
|
||||
|
||||
if (group_range == NULL)
|
||||
result = str2prefix("224.0.0.0/4", &group);
|
||||
else {
|
||||
result = str2prefix(group_range, &group);
|
||||
if (result) {
|
||||
struct prefix temp;
|
||||
|
||||
prefix_copy(&temp, &group);
|
||||
apply_mask(&temp);
|
||||
if (!prefix_same(&group, &temp))
|
||||
return PIM_GROUP_BAD_ADDR_MASK_COMBO;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
return PIM_GROUP_BAD_ADDRESS;
|
||||
|
||||
result = inet_pton(AF_INET, rp, &rp_addr);
|
||||
|
||||
if (result <= 0)
|
||||
return PIM_RP_BAD_ADDRESS;
|
||||
|
||||
result = pim_rp_new(pim, rp_addr, group, plist, RP_SRC_STATIC);
|
||||
return result;
|
||||
}
|
||||
|
||||
int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
|
||||
struct prefix group, const char *plist,
|
||||
enum rp_source rp_src_flag)
|
||||
{
|
||||
int result = 0;
|
||||
char rp[INET_ADDRSTRLEN];
|
||||
struct rp_info *rp_info;
|
||||
struct rp_info *rp_all;
|
||||
struct prefix group_all;
|
||||
@ -417,41 +453,19 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
struct rp_info *tmp_rp_info;
|
||||
char buffer[BUFSIZ];
|
||||
struct prefix nht_p;
|
||||
struct prefix temp;
|
||||
struct route_node *rn;
|
||||
struct pim_upstream *up;
|
||||
struct listnode *upnode;
|
||||
|
||||
rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info));
|
||||
|
||||
if (group_range == NULL)
|
||||
result = str2prefix("224.0.0.0/4", &rp_info->group);
|
||||
else {
|
||||
result = str2prefix(group_range, &rp_info->group);
|
||||
if (result) {
|
||||
prefix_copy(&temp, &rp_info->group);
|
||||
apply_mask(&temp);
|
||||
if (!prefix_same(&rp_info->group, &temp)) {
|
||||
XFREE(MTYPE_PIM_RP, rp_info);
|
||||
return PIM_GROUP_BAD_ADDR_MASK_COMBO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
XFREE(MTYPE_PIM_RP, rp_info);
|
||||
return PIM_GROUP_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
rp_info->rp.rpf_addr.family = AF_INET;
|
||||
rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN;
|
||||
result = inet_pton(rp_info->rp.rpf_addr.family, rp,
|
||||
&rp_info->rp.rpf_addr.u.prefix4);
|
||||
rp_info->rp.rpf_addr.u.prefix4 = rp_addr;
|
||||
prefix_copy(&rp_info->group, &group);
|
||||
rp_info->rp_src = rp_src_flag;
|
||||
|
||||
if (result <= 0) {
|
||||
XFREE(MTYPE_PIM_RP, rp_info);
|
||||
return PIM_RP_BAD_ADDRESS;
|
||||
}
|
||||
inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp, sizeof(rp));
|
||||
|
||||
if (plist) {
|
||||
/*
|
||||
@ -479,10 +493,10 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
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(pim, rp, NULL,
|
||||
tmp_rp_info->plist);
|
||||
pim_rp_del_config(pim, rp, NULL,
|
||||
tmp_rp_info->plist);
|
||||
else
|
||||
pim_rp_del(
|
||||
pim_rp_del_config(
|
||||
pim, rp,
|
||||
prefix2str(&tmp_rp_info->group,
|
||||
buffer, BUFSIZ),
|
||||
@ -516,7 +530,8 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
&& rp_info->rp.rpf_addr.u.prefix4.s_addr
|
||||
== tmp_rp_info->rp.rpf_addr.u.prefix4
|
||||
.s_addr) {
|
||||
pim_rp_del(pim, rp, NULL, tmp_rp_info->plist);
|
||||
pim_rp_del_config(pim, rp, NULL,
|
||||
tmp_rp_info->plist);
|
||||
}
|
||||
}
|
||||
|
||||
@ -526,6 +541,7 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
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;
|
||||
rp_all->rp_src = rp_src_flag;
|
||||
XFREE(MTYPE_PIM_RP, rp_info);
|
||||
|
||||
/* Register addr with Zebra NHT */
|
||||
@ -556,8 +572,8 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
grp.family = AF_INET;
|
||||
grp.prefixlen = IPV4_MAX_BITLEN;
|
||||
grp.u.prefix4 = up->sg.grp;
|
||||
trp_info = pim_rp_find_match_group(pim,
|
||||
&grp);
|
||||
trp_info = pim_rp_find_match_group(
|
||||
pim, &grp);
|
||||
if (trp_info == rp_all)
|
||||
pim_upstream_update(pim, up);
|
||||
}
|
||||
@ -565,7 +581,6 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
|
||||
pim_rp_check_interfaces(pim, rp_all);
|
||||
pim_rp_refresh_group_to_rp_mapping(pim);
|
||||
|
||||
pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_all,
|
||||
false, NULL);
|
||||
|
||||
@ -573,17 +588,20 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
&rp_all->rp.source_nexthop,
|
||||
&nht_p, &rp_all->group, 1))
|
||||
return PIM_RP_NO_PATH;
|
||||
|
||||
return PIM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return if the group is already configured for this RP
|
||||
*/
|
||||
if (pim_rp_find_exact(pim, rp_info->rp.rpf_addr.u.prefix4,
|
||||
&rp_info->group)) {
|
||||
tmp_rp_info = pim_rp_find_exact(
|
||||
pim, rp_info->rp.rpf_addr.u.prefix4, &rp_info->group);
|
||||
if (tmp_rp_info) {
|
||||
if ((tmp_rp_info->rp_src != rp_src_flag)
|
||||
&& (rp_src_flag == RP_SRC_STATIC))
|
||||
tmp_rp_info->rp_src = rp_src_flag;
|
||||
XFREE(MTYPE_PIM_RP, rp_info);
|
||||
return PIM_SUCCESS;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -605,8 +623,20 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
*/
|
||||
if (prefix_same(&rp_info->group,
|
||||
&tmp_rp_info->group)) {
|
||||
if ((rp_src_flag == RP_SRC_STATIC)
|
||||
&& (tmp_rp_info->rp_src
|
||||
== RP_SRC_STATIC)) {
|
||||
XFREE(MTYPE_PIM_RP, rp_info);
|
||||
return PIM_GROUP_OVERLAP;
|
||||
}
|
||||
|
||||
result = pim_rp_change(
|
||||
pim,
|
||||
rp_info->rp.rpf_addr.u.prefix4,
|
||||
tmp_rp_info->group,
|
||||
rp_src_flag);
|
||||
XFREE(MTYPE_PIM_RP, rp_info);
|
||||
return PIM_GROUP_OVERLAP;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -655,7 +685,6 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
zlog_debug("%s: NHT Register RP addr %s grp %s with Zebra ",
|
||||
__PRETTY_FUNCTION__, buf, buf1);
|
||||
}
|
||||
|
||||
pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false, NULL);
|
||||
if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, &nht_p,
|
||||
&rp_info->group, 1))
|
||||
@ -664,21 +693,12 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
return PIM_SUCCESS;
|
||||
}
|
||||
|
||||
int pim_rp_del(struct pim_instance *pim, const char *rp,
|
||||
const char *group_range, const char *plist)
|
||||
int pim_rp_del_config(struct pim_instance *pim, 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;
|
||||
struct route_node *rn;
|
||||
bool was_plist = false;
|
||||
struct rp_info *trp_info;
|
||||
struct pim_upstream *up;
|
||||
struct listnode *upnode;
|
||||
|
||||
if (group_range == NULL)
|
||||
result = str2prefix("224.0.0.0/4", &group);
|
||||
@ -692,6 +712,32 @@ int pim_rp_del(struct pim_instance *pim, const char *rp,
|
||||
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,
|
||||
struct prefix group, const char *plist,
|
||||
enum rp_source rp_src_flag)
|
||||
{
|
||||
struct prefix g_all;
|
||||
struct rp_info *rp_info;
|
||||
struct rp_info *rp_all;
|
||||
struct prefix nht_p;
|
||||
struct route_node *rn;
|
||||
bool was_plist = false;
|
||||
struct rp_info *trp_info;
|
||||
struct pim_upstream *up;
|
||||
struct listnode *upnode;
|
||||
struct bsgrp_node *bsgrp = NULL;
|
||||
struct bsm_rpinfo *bsrp = NULL;
|
||||
char grp_str[PREFIX2STR_BUFFER];
|
||||
char rp_str[INET_ADDRSTRLEN];
|
||||
|
||||
if (!inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str)))
|
||||
sprintf(rp_str, "<rp?>");
|
||||
prefix2str(&group, grp_str, sizeof(grp_str));
|
||||
|
||||
if (plist)
|
||||
rp_info = pim_rp_find_prefix_list(pim, rp_addr, plist);
|
||||
else
|
||||
@ -705,6 +751,42 @@ int pim_rp_del(struct pim_instance *pim, const char *rp,
|
||||
was_plist = true;
|
||||
}
|
||||
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug("%s: Delete RP %s for the group %s",
|
||||
__PRETTY_FUNCTION__, rp_str, grp_str);
|
||||
|
||||
/* 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
|
||||
* RP for the group node into the main rp table
|
||||
*/
|
||||
if (rp_src_flag == RP_SRC_STATIC) {
|
||||
bsgrp = pim_bsm_get_bsgrp_node(&pim->global_scope, &group);
|
||||
|
||||
if (bsgrp) {
|
||||
bsrp = listnode_head(bsgrp->bsrp_list);
|
||||
if (bsrp) {
|
||||
if (PIM_DEBUG_TRACE) {
|
||||
char bsrp_str[INET_ADDRSTRLEN];
|
||||
|
||||
if (!inet_ntop(AF_INET, bsrp, bsrp_str,
|
||||
sizeof(bsrp_str)))
|
||||
sprintf(bsrp_str, "<bsrp?>");
|
||||
|
||||
zlog_debug("%s: BSM RP %s found for the group %s",
|
||||
__PRETTY_FUNCTION__,
|
||||
bsrp_str, grp_str);
|
||||
}
|
||||
return pim_rp_change(pim, bsrp->rp_address,
|
||||
group, RP_SRC_BSR);
|
||||
}
|
||||
} else {
|
||||
if (PIM_DEBUG_TRACE)
|
||||
zlog_debug(
|
||||
"%s: BSM RP not found for the group %s",
|
||||
__PRETTY_FUNCTION__, grp_str);
|
||||
}
|
||||
}
|
||||
|
||||
/* Deregister addr with Zebra NHT */
|
||||
nht_p.family = AF_INET;
|
||||
nht_p.prefixlen = IPV4_MAX_BITLEN;
|
||||
@ -727,8 +809,9 @@ int pim_rp_del(struct pim_instance *pim, const char *rp,
|
||||
/* Find the upstream (*, G) whose upstream address is
|
||||
* same as the deleted RP
|
||||
*/
|
||||
if ((up->upstream_addr.s_addr == rp_addr.s_addr) &&
|
||||
(up->sg.src.s_addr == INADDR_ANY)) {
|
||||
if ((up->upstream_addr.s_addr
|
||||
== rp_info->rp.rpf_addr.u.prefix4.s_addr)
|
||||
&& (up->sg.src.s_addr == INADDR_ANY)) {
|
||||
struct prefix grp;
|
||||
grp.family = AF_INET;
|
||||
grp.prefixlen = IPV4_MAX_BITLEN;
|
||||
@ -778,8 +861,9 @@ int pim_rp_del(struct pim_instance *pim, const char *rp,
|
||||
/* Find the upstream (*, G) whose upstream address is same as
|
||||
* the deleted RP
|
||||
*/
|
||||
if ((up->upstream_addr.s_addr == rp_addr.s_addr) &&
|
||||
(up->sg.src.s_addr == INADDR_ANY)) {
|
||||
if ((up->upstream_addr.s_addr
|
||||
== rp_info->rp.rpf_addr.u.prefix4.s_addr)
|
||||
&& (up->sg.src.s_addr == INADDR_ANY)) {
|
||||
struct prefix grp;
|
||||
|
||||
grp.family = AF_INET;
|
||||
@ -791,9 +875,9 @@ int pim_rp_del(struct pim_instance *pim, const char *rp,
|
||||
/* RP not found for the group grp */
|
||||
if (pim_rpf_addr_is_inaddr_none(&trp_info->rp)) {
|
||||
pim_upstream_rpf_clear(pim, up);
|
||||
pim_rp_set_upstream_addr(pim,
|
||||
&up->upstream_addr,
|
||||
up->sg.src, up->sg.grp);
|
||||
pim_rp_set_upstream_addr(
|
||||
pim, &up->upstream_addr, up->sg.src,
|
||||
up->sg.grp);
|
||||
}
|
||||
|
||||
/* RP found for the group grp */
|
||||
@ -806,6 +890,105 @@ int pim_rp_del(struct pim_instance *pim, const char *rp,
|
||||
return PIM_SUCCESS;
|
||||
}
|
||||
|
||||
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 nht_p;
|
||||
struct route_node *rn;
|
||||
int result = 0;
|
||||
struct rp_info *rp_info = NULL;
|
||||
struct pim_upstream *up;
|
||||
struct listnode *upnode;
|
||||
|
||||
rn = route_node_lookup(pim->rp_table, &group);
|
||||
if (!rn) {
|
||||
result = pim_rp_new(pim, new_rp_addr, group, NULL, rp_src_flag);
|
||||
return result;
|
||||
}
|
||||
|
||||
rp_info = rn->info;
|
||||
|
||||
if (!rp_info) {
|
||||
route_unlock_node(rn);
|
||||
result = pim_rp_new(pim, new_rp_addr, group, NULL, rp_src_flag);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (rp_info->rp.rpf_addr.u.prefix4.s_addr == new_rp_addr.s_addr) {
|
||||
if (rp_info->rp_src != rp_src_flag) {
|
||||
rp_info->rp_src = rp_src_flag;
|
||||
route_unlock_node(rn);
|
||||
return PIM_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Deregister old RP addr with Zebra NHT */
|
||||
if (rp_info->rp.rpf_addr.u.prefix4.s_addr != INADDR_ANY) {
|
||||
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_NHT_RP) {
|
||||
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(pim, &nht_p, NULL, rp_info, false);
|
||||
}
|
||||
|
||||
pim_rp_nexthop_del(rp_info);
|
||||
listnode_delete(pim->rp_list, rp_info);
|
||||
/* Update the new RP address*/
|
||||
rp_info->rp.rpf_addr.u.prefix4 = new_rp_addr;
|
||||
rp_info->rp_src = rp_src_flag;
|
||||
rp_info->i_am_rp = 0;
|
||||
|
||||
listnode_add_sort(pim->rp_list, rp_info);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
||||
if (up->sg.src.s_addr == INADDR_ANY) {
|
||||
struct prefix grp;
|
||||
struct rp_info *trp_info;
|
||||
|
||||
grp.family = AF_INET;
|
||||
grp.prefixlen = IPV4_MAX_BITLEN;
|
||||
grp.u.prefix4 = up->sg.grp;
|
||||
trp_info = pim_rp_find_match_group(pim, &grp);
|
||||
|
||||
if (trp_info == rp_info)
|
||||
pim_upstream_update(pim, up);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register new RP addr with Zebra NHT */
|
||||
nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
|
||||
if (PIM_DEBUG_PIM_NHT_RP) {
|
||||
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);
|
||||
}
|
||||
|
||||
pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false, NULL);
|
||||
if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, &nht_p,
|
||||
&rp_info->group, 1)) {
|
||||
route_unlock_node(rn);
|
||||
return PIM_RP_NO_PATH;
|
||||
}
|
||||
|
||||
pim_rp_check_interfaces(pim, rp_info);
|
||||
|
||||
route_unlock_node(rn);
|
||||
|
||||
pim_rp_refresh_group_to_rp_mapping(pim);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void pim_rp_setup(struct pim_instance *pim)
|
||||
{
|
||||
struct listnode *node;
|
||||
@ -1032,6 +1215,9 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
|
||||
if (pim_rpf_addr_is_inaddr_none(&rp_info->rp))
|
||||
continue;
|
||||
|
||||
if (rp_info->rp_src == RP_SRC_BSR)
|
||||
continue;
|
||||
|
||||
if (rp_info->plist)
|
||||
vty_out(vty, "%sip pim rp %s prefix-list %s\n", spaces,
|
||||
inet_ntop(AF_INET,
|
||||
@ -1127,8 +1313,7 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
|
||||
json_row, "group",
|
||||
prefix2str(&rp_info->group, buf,
|
||||
48));
|
||||
json_object_string_add(json_row,
|
||||
"source",
|
||||
json_object_string_add(json_row, "source",
|
||||
source);
|
||||
|
||||
json_object_array_add(json_rp_rows, json_row);
|
||||
|
@ -46,10 +46,18 @@ void pim_rp_free(struct pim_instance *pim);
|
||||
|
||||
void pim_rp_list_hash_clean(void *data);
|
||||
|
||||
int pim_rp_new(struct pim_instance *pim, const char *rp, const char *group,
|
||||
const char *plist);
|
||||
int pim_rp_del(struct pim_instance *pim, const char *rp, const char *group,
|
||||
const char *plist);
|
||||
int pim_rp_new_config(struct pim_instance *pim, const char *rp,
|
||||
const char *group, const char *plist);
|
||||
int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
|
||||
struct prefix group, const char *plist,
|
||||
enum rp_source rp_src_flag);
|
||||
int pim_rp_del_config(struct pim_instance *pim, const char *rp,
|
||||
const char *group, const char *plist);
|
||||
int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
|
||||
struct prefix group, const char *plist,
|
||||
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);
|
||||
void pim_rp_prefix_list_update(struct pim_instance *pim,
|
||||
struct prefix_list *plist);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user