2020-10-23 10:40:39 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2020 VmWare
|
|
|
|
* Sarita Patra
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but 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, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "pimd.h"
|
|
|
|
#include "pim_nb.h"
|
|
|
|
#include "lib/northbound_cli.h"
|
2020-10-23 13:46:39 +02:00
|
|
|
#include "pim_igmpv3.h"
|
2020-10-23 14:06:06 +02:00
|
|
|
#include "pim_pim.h"
|
2020-10-23 14:27:06 +02:00
|
|
|
#include "pim_mlag.h"
|
2020-10-23 14:43:16 +02:00
|
|
|
#include "pim_bfd.h"
|
2020-10-23 14:59:37 +02:00
|
|
|
#include "pim_static.h"
|
2020-10-23 15:58:51 +02:00
|
|
|
#include "pim_ssm.h"
|
|
|
|
#include "pim_ssmpingd.h"
|
2020-10-23 16:39:22 +02:00
|
|
|
#include "pim_vxlan.h"
|
2020-10-23 13:46:39 +02:00
|
|
|
|
2020-10-23 14:06:06 +02:00
|
|
|
static void pim_if_membership_clear(struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
zassert(pim_ifp);
|
|
|
|
|
|
|
|
if (PIM_IF_TEST_PIM(pim_ifp->options)
|
|
|
|
&& PIM_IF_TEST_IGMP(pim_ifp->options)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pim_ifchannel_membership_clear(ifp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* When PIM is disabled on interface, IGMPv3 local membership
|
|
|
|
* information is not injected into PIM interface state.
|
|
|
|
|
|
|
|
* The function pim_if_membership_refresh() fetches all IGMPv3 local
|
|
|
|
* membership information into PIM. It is intented to be called
|
|
|
|
* whenever PIM is enabled on the interface in order to collect missed
|
|
|
|
* local membership information.
|
|
|
|
*/
|
|
|
|
static void pim_if_membership_refresh(struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
zassert(pim_ifp);
|
|
|
|
|
|
|
|
if (!PIM_IF_TEST_PIM(pim_ifp->options))
|
|
|
|
return;
|
|
|
|
if (!PIM_IF_TEST_IGMP(pim_ifp->options))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* First clear off membership from all PIM (S,G) entries on the
|
|
|
|
* interface
|
|
|
|
*/
|
|
|
|
|
|
|
|
pim_ifchannel_membership_clear(ifp);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
|
|
|
|
* the interface
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* scan igmp sockets */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
|
|
|
|
struct listnode *grpnode;
|
|
|
|
struct igmp_group *grp;
|
|
|
|
|
|
|
|
/* scan igmp groups */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode,
|
|
|
|
grp)) {
|
|
|
|
struct listnode *srcnode;
|
|
|
|
struct igmp_source *src;
|
|
|
|
|
|
|
|
/* scan group sources */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
|
|
|
|
srcnode, src)) {
|
|
|
|
|
|
|
|
if (IGMP_SOURCE_TEST_FORWARDING(
|
|
|
|
src->source_flags)) {
|
|
|
|
struct prefix_sg sg;
|
|
|
|
|
|
|
|
memset(&sg, 0,
|
|
|
|
sizeof(struct prefix_sg));
|
|
|
|
sg.src = src->source_addr;
|
|
|
|
sg.grp = grp->group_addr;
|
|
|
|
pim_ifchannel_local_membership_add(
|
|
|
|
ifp, &sg, false /*is_vxlan*/);
|
|
|
|
}
|
|
|
|
|
|
|
|
} /* scan group sources */
|
|
|
|
} /* scan igmp groups */
|
|
|
|
} /* scan igmp sockets */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Finally delete every PIM (S,G) entry lacking all state info
|
|
|
|
*/
|
|
|
|
|
|
|
|
pim_ifchannel_delete_on_noinfo(ifp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pim_cmd_interface_add(struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
pim_ifp = pim_if_new(ifp, false, true, false, false);
|
|
|
|
else
|
|
|
|
PIM_IF_DO_PIM(pim_ifp->options);
|
|
|
|
|
|
|
|
pim_if_addr_add_all(ifp);
|
|
|
|
pim_if_membership_refresh(ifp);
|
|
|
|
|
|
|
|
pim_if_create_pimreg(pim_ifp->pim);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pim_cmd_interface_delete(struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct pim_interface *pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
PIM_IF_DONT_PIM(pim_ifp->options);
|
|
|
|
|
|
|
|
pim_if_membership_clear(ifp);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* pim_sock_delete() removes all neighbors from
|
|
|
|
* pim_ifp->pim_neighbor_list.
|
|
|
|
*/
|
|
|
|
pim_sock_delete(ifp, "pim unconfigured on interface");
|
|
|
|
|
|
|
|
if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
|
|
|
|
pim_if_addr_del_all(ifp);
|
|
|
|
pim_if_delete(ifp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2020-10-23 13:46:39 +02:00
|
|
|
|
2020-10-23 14:59:37 +02:00
|
|
|
static int interface_pim_use_src_cmd_worker(struct interface *ifp,
|
|
|
|
struct in_addr source_addr,
|
|
|
|
char *errmsg, size_t errmsg_len)
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
int ret = NB_OK;
|
|
|
|
|
|
|
|
result = pim_update_source_set(ifp, source_addr);
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case PIM_SUCCESS:
|
|
|
|
break;
|
|
|
|
case PIM_IFACE_NOT_FOUND:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"Pim not enabled on this interface %s",
|
|
|
|
ifp->name);
|
|
|
|
break;
|
|
|
|
case PIM_UPDATE_SOURCE_DUP:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len, "Source already set");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len, "Source set failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-23 15:45:33 +02:00
|
|
|
static int pim_cmd_spt_switchover(struct pim_instance *pim,
|
|
|
|
enum pim_spt_switchover spt,
|
|
|
|
const char *plist)
|
|
|
|
{
|
|
|
|
pim->spt.switchover = spt;
|
|
|
|
|
|
|
|
switch (pim->spt.switchover) {
|
|
|
|
case PIM_SPT_IMMEDIATE:
|
|
|
|
XFREE(MTYPE_PIM_PLIST_NAME, pim->spt.plist);
|
|
|
|
|
|
|
|
pim_upstream_add_lhr_star_pimreg(pim);
|
|
|
|
break;
|
|
|
|
case PIM_SPT_INFINITY:
|
|
|
|
pim_upstream_remove_lhr_star_pimreg(pim, plist);
|
|
|
|
|
|
|
|
XFREE(MTYPE_PIM_PLIST_NAME, pim->spt.plist);
|
|
|
|
|
|
|
|
if (plist)
|
|
|
|
pim->spt.plist = XSTRDUP(MTYPE_PIM_PLIST_NAME, plist);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
2020-10-23 15:58:51 +02:00
|
|
|
static int pim_ssm_cmd_worker(struct pim_instance *pim, const char *plist,
|
|
|
|
char *errmsg, size_t errmsg_len)
|
|
|
|
{
|
|
|
|
int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
|
|
|
|
int ret = NB_ERR;
|
|
|
|
|
|
|
|
if (result == PIM_SSM_ERR_NONE)
|
|
|
|
return NB_OK;
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case PIM_SSM_ERR_NO_VRF:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"VRF doesn't exist");
|
|
|
|
break;
|
|
|
|
case PIM_SSM_ERR_DUP:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"duplicate config");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"ssm range config failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-23 16:29:44 +02:00
|
|
|
static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim,
|
|
|
|
const char *mg,
|
|
|
|
char *errmsg, size_t errmsg_len)
|
|
|
|
{
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
|
|
|
|
result = pim_msdp_mg_del(pim, mg);
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_MG:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% mesh-group does not exist");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"mesh-group source del failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return result ? NB_ERR : NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
|
|
|
|
const char *mg,
|
|
|
|
struct in_addr mbr_ip,
|
|
|
|
char *errmsg, size_t errmsg_len)
|
|
|
|
{
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
int ret = NB_OK;
|
|
|
|
|
|
|
|
result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_OOM:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% Out of memory");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_MG_MBR_EXISTS:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% mesh-group member exists");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% Only one mesh-group allowed currently");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% member add failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
|
|
|
|
const char *mg,
|
|
|
|
struct in_addr mbr_ip,
|
|
|
|
char *errmsg,
|
|
|
|
size_t errmsg_len)
|
|
|
|
{
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
|
|
|
|
result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_MG:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% mesh-group does not exist");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_MG_MBR:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% mesh-group member does not exist");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% mesh-group member del failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return result ? NB_ERR : NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
|
|
|
|
const char *mg,
|
|
|
|
struct in_addr src_ip,
|
|
|
|
char *errmsg, size_t errmsg_len)
|
|
|
|
{
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
|
|
|
|
result = pim_msdp_mg_src_add(pim, mg, src_ip);
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_OOM:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% Out of memory");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% Only one mesh-group allowed currently");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% source add failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return result ? NB_ERR : NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
|
|
|
|
const char *mg,
|
|
|
|
char *errmsg,
|
|
|
|
size_t errmsg_len)
|
|
|
|
{
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
|
|
|
|
result = pim_msdp_mg_src_del(pim, mg);
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_MG:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% mesh-group does not exist");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% mesh-group source del failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return result ? NB_ERR : NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ip_msdp_peer_cmd_worker(struct pim_instance *pim,
|
|
|
|
struct in_addr peer_addr,
|
|
|
|
struct in_addr local_addr,
|
|
|
|
char *errmsg, size_t errmsg_len)
|
|
|
|
{
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
int ret = NB_OK;
|
|
|
|
|
|
|
|
result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
|
|
|
|
NULL /* mp_p */);
|
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_OOM:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% Out of memory");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_PEER_EXISTS:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% Peer exists");
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% Only one mesh-group allowed currently");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = NB_ERR;
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% peer add failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim,
|
|
|
|
struct in_addr peer_addr,
|
|
|
|
char *errmsg, size_t errmsg_len)
|
|
|
|
{
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
|
|
|
|
result = pim_msdp_peer_del(pim, peer_addr);
|
|
|
|
switch (result) {
|
|
|
|
case PIM_MSDP_ERR_NONE:
|
|
|
|
break;
|
|
|
|
case PIM_MSDP_ERR_NO_PEER:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% Peer does not exist");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"%% peer del failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return result ? NB_ERR : NB_OK;
|
|
|
|
}
|
|
|
|
|
2020-10-23 16:52:41 +02:00
|
|
|
static int pim_rp_cmd_worker(struct pim_instance *pim,
|
|
|
|
struct in_addr rp_addr,
|
|
|
|
struct prefix group, const char *plist,
|
|
|
|
char *errmsg, size_t errmsg_len)
|
|
|
|
{
|
|
|
|
char rp_str[INET_ADDRSTRLEN];
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (result == PIM_RP_NO_PATH) {
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"No Path to RP address specified: %s", rp_str);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result == PIM_GROUP_OVERLAP) {
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"Group range specified cannot exact match another");
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result == PIM_GROUP_PFXLIST_OVERLAP) {
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"This group is already covered by a RP prefix-list");
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result == PIM_RP_PFXLIST_IN_USE) {
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"The same prefix-list cannot be applied to multiple RPs");
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pim_no_rp_cmd_worker(struct pim_instance *pim,
|
|
|
|
struct in_addr rp_addr, struct prefix group,
|
|
|
|
const char *plist,
|
|
|
|
char *errmsg, size_t errmsg_len)
|
|
|
|
{
|
|
|
|
char rp_str[INET_ADDRSTRLEN];
|
|
|
|
char group_str[PREFIX2STR_BUFFER];
|
|
|
|
int result;
|
|
|
|
|
|
|
|
inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str));
|
|
|
|
prefix2str(&group, group_str, sizeof(group_str));
|
|
|
|
|
|
|
|
result = pim_rp_del(pim, rp_addr, group, plist, RP_SRC_STATIC);
|
|
|
|
|
|
|
|
if (result == PIM_GROUP_BAD_ADDRESS) {
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"Bad group address specified: %s", group_str);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result == PIM_RP_BAD_ADDRESS) {
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"Bad RP address specified: %s", rp_str);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result == PIM_RP_NOT_FOUND) {
|
|
|
|
snprintf(errmsg, errmsg_len,
|
|
|
|
"Unable to find specified RP");
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
2020-10-23 16:29:44 +02:00
|
|
|
|
2020-10-23 13:46:39 +02:00
|
|
|
static bool is_pim_interface(const struct lyd_node *dnode)
|
|
|
|
{
|
|
|
|
char if_xpath[XPATH_MAXLEN];
|
|
|
|
const struct lyd_node *pim_enable_dnode;
|
|
|
|
const struct lyd_node *igmp_enable_dnode;
|
|
|
|
|
|
|
|
yang_dnode_get_path(dnode, if_xpath, sizeof(if_xpath));
|
|
|
|
pim_enable_dnode = yang_dnode_get(dnode, "%s/frr-pim:pim/pim-enable",
|
|
|
|
if_xpath);
|
|
|
|
igmp_enable_dnode = yang_dnode_get(dnode, "%s/frr-igmp:igmp/igmp-enable",
|
|
|
|
if_xpath);
|
|
|
|
|
|
|
|
if (((pim_enable_dnode) &&
|
|
|
|
(yang_dnode_get_bool(pim_enable_dnode, "."))) ||
|
|
|
|
((igmp_enable_dnode) &&
|
|
|
|
(yang_dnode_get_bool(igmp_enable_dnode, "."))))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pim_cmd_igmp_start(struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
uint8_t need_startup = 0;
|
|
|
|
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp) {
|
|
|
|
(void)pim_if_new(ifp, true, false, false, false);
|
|
|
|
need_startup = 1;
|
|
|
|
} else {
|
|
|
|
if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
|
|
|
|
PIM_IF_DO_IGMP(pim_ifp->options);
|
|
|
|
need_startup = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 'ip igmp' executed multiple times, with need_startup
|
|
|
|
* avoid multiple if add all and membership refresh
|
|
|
|
*/
|
|
|
|
if (need_startup) {
|
|
|
|
pim_if_addr_add_all(ifp);
|
|
|
|
pim_if_membership_refresh(ifp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* CLI reconfiguration affects the interface level (struct pim_interface).
|
|
|
|
* This function propagates the reconfiguration to every active socket
|
|
|
|
* for that interface.
|
|
|
|
*/
|
|
|
|
static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
|
|
|
|
{
|
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
|
|
|
zassert(igmp);
|
|
|
|
|
|
|
|
/* other querier present? */
|
|
|
|
|
|
|
|
if (igmp->t_other_querier_timer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* this is the querier */
|
|
|
|
|
|
|
|
zassert(igmp->interface);
|
|
|
|
zassert(igmp->interface->info);
|
|
|
|
|
|
|
|
ifp = igmp->interface;
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (PIM_DEBUG_IGMP_TRACE) {
|
|
|
|
char ifaddr_str[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
|
|
|
|
sizeof(ifaddr_str));
|
|
|
|
zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
|
|
|
|
__func__, ifaddr_str, ifp->name,
|
|
|
|
pim_ifp->igmp_default_query_interval);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* igmp_startup_mode_on() will reset QQI:
|
|
|
|
|
|
|
|
* igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
|
|
|
|
*/
|
|
|
|
igmp_startup_mode_on(igmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
|
|
|
|
{
|
|
|
|
if (igmp->mtrace_only)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (igmp->t_igmp_query_timer) {
|
|
|
|
/* other querier present */
|
|
|
|
zassert(igmp->t_igmp_query_timer);
|
|
|
|
zassert(!igmp->t_other_querier_timer);
|
|
|
|
|
|
|
|
pim_igmp_general_query_off(igmp);
|
|
|
|
pim_igmp_general_query_on(igmp);
|
|
|
|
|
|
|
|
zassert(igmp->t_igmp_query_timer);
|
|
|
|
zassert(!igmp->t_other_querier_timer);
|
|
|
|
} else {
|
|
|
|
/* this is the querier */
|
|
|
|
|
|
|
|
zassert(!igmp->t_igmp_query_timer);
|
|
|
|
zassert(igmp->t_other_querier_timer);
|
|
|
|
|
|
|
|
pim_igmp_other_querier_timer_off(igmp);
|
|
|
|
pim_igmp_other_querier_timer_on(igmp);
|
|
|
|
|
|
|
|
zassert(!igmp->t_igmp_query_timer);
|
|
|
|
zassert(igmp->t_other_querier_timer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void change_query_interval(struct pim_interface *pim_ifp,
|
|
|
|
int query_interval)
|
|
|
|
{
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
|
|
|
|
pim_ifp->igmp_default_query_interval = query_interval;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
|
|
|
|
igmp_sock_query_interval_reconfig(igmp);
|
|
|
|
igmp_sock_query_reschedule(igmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void change_query_max_response_time(struct pim_interface *pim_ifp,
|
|
|
|
int query_max_response_time_dsec)
|
|
|
|
{
|
|
|
|
struct listnode *sock_node;
|
|
|
|
struct igmp_sock *igmp;
|
|
|
|
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec =
|
|
|
|
query_max_response_time_dsec;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Below we modify socket/group/source timers in order to quickly
|
|
|
|
* reflect the change. Otherwise, those timers would args->eventually
|
|
|
|
* catch up.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* scan all sockets */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
|
|
|
|
struct listnode *grp_node;
|
|
|
|
struct igmp_group *grp;
|
|
|
|
|
|
|
|
/* reschedule socket general query */
|
|
|
|
igmp_sock_query_reschedule(igmp);
|
|
|
|
|
|
|
|
/* scan socket groups */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
|
|
|
|
grp)) {
|
|
|
|
struct listnode *src_node;
|
|
|
|
struct igmp_source *src;
|
|
|
|
|
|
|
|
/* reset group timers for groups in EXCLUDE mode */
|
|
|
|
if (grp->group_filtermode_isexcl)
|
|
|
|
igmp_group_reset_gmi(grp);
|
|
|
|
|
|
|
|
/* scan group sources */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
|
|
|
|
src_node, src)) {
|
|
|
|
|
|
|
|
/* reset source timers for sources with running
|
|
|
|
* timers
|
|
|
|
*/
|
|
|
|
if (src->t_source_timer)
|
|
|
|
igmp_source_reset_gmi(igmp, grp, src);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
|
|
|
|
int routing_control_plane_protocols_name_validate(
|
|
|
|
struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
name = yang_dnode_get_string(args->dnode, "./name");
|
|
|
|
if (!strmatch(name, "pim")) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"pim supports only one instance with name pimd");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-pim:pim/packets
|
|
|
|
*/
|
|
|
|
int pim_packets_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 15:13:07 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 15:13:07 +02:00
|
|
|
router->packet_process = yang_dnode_get_uint8(args->dnode,
|
|
|
|
NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-pim:pim/join-prune-interval
|
|
|
|
*/
|
|
|
|
int pim_join_prune_interval_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 15:13:07 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 15:13:07 +02:00
|
|
|
router->t_periodic = yang_dnode_get_uint16(args->dnode, NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-pim:pim/register-suppress-time
|
|
|
|
*/
|
|
|
|
int pim_register_suppress_time_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 15:13:07 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 15:13:07 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 15:13:07 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
pim->keep_alive_time = yang_dnode_get_uint16(args->dnode, NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/ecmp
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_ecmp_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 15:31:39 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 15:31:39 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
pim->ecmp_enable = yang_dnode_get_bool(args->dnode, NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/ecmp-rebalance
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_ecmp_rebalance_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 15:31:39 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 15:31:39 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
pim->ecmp_rebalance_enable =
|
|
|
|
yang_dnode_get_bool(args->dnode, NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/keep-alive-timer
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_keep_alive_timer_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 15:31:39 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 15:31:39 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 15:31:39 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
pim->keep_alive_time = yang_dnode_get_uint16(args->dnode, NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/rp-keep-alive-timer
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_rp_keep_alive_timer_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 15:31:39 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 15:31:39 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 15:31:39 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
pim->rp_keep_alive_time = yang_dnode_get_uint16(args->dnode,
|
|
|
|
NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
/* TODO: implement me. */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
/* TODO: implement me. */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/send-v6-secondary
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 15:45:33 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 15:45:33 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 15:45:33 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
pim->send_v6_secondary = yang_dnode_get_bool(args->dnode, NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
2020-10-23 15:45:33 +02:00
|
|
|
/*
|
|
|
|
* XPath:
|
|
|
|
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover
|
|
|
|
*/
|
|
|
|
void routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_apply_finish(
|
|
|
|
struct nb_cb_apply_finish_args *args)
|
|
|
|
{
|
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
int spt_switch_action;
|
|
|
|
const char *prefix_list = NULL;
|
|
|
|
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
spt_switch_action = yang_dnode_get_enum(args->dnode, "./spt-action");
|
|
|
|
|
|
|
|
switch (spt_switch_action) {
|
|
|
|
case PIM_SPT_INFINITY:
|
|
|
|
if (yang_dnode_exists(args->dnode,
|
|
|
|
"./spt-infinity-prefix-list"))
|
|
|
|
prefix_list = yang_dnode_get_string(
|
|
|
|
args->dnode, "./spt-infinity-prefix-list");
|
|
|
|
|
|
|
|
pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY,
|
|
|
|
prefix_list);
|
|
|
|
break;
|
|
|
|
case PIM_SPT_IMMEDIATE:
|
|
|
|
pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-action
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_action_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-infinity-prefix-list
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-prefix-list
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 15:58:51 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
const char *plist_name;
|
|
|
|
int result;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 15:58:51 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 15:58:51 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
plist_name = yang_dnode_get_string(args->dnode, NULL);
|
|
|
|
result = pim_ssm_cmd_worker(pim, plist_name, args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 15:58:51 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
int result;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 15:58:51 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 15:58:51 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
result = pim_ssm_cmd_worker(pim, NULL, args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-pingd-source-ip
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
2020-10-23 15:58:51 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
int result;
|
|
|
|
struct ipaddr source_addr;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 15:58:51 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
yang_dnode_get_ip(&source_addr, args->dnode, NULL);
|
|
|
|
result = pim_ssmpingd_start(pim, source_addr.ip._v4_addr);
|
|
|
|
if (result) {
|
|
|
|
char source_str[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
ipaddr2str(&source_addr, source_str,
|
|
|
|
sizeof(source_str));
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"%% Failure starting ssmpingd for source %s: %d",
|
|
|
|
source_str, result);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 15:58:51 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
int result;
|
|
|
|
struct ipaddr source_addr;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 15:58:51 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 15:58:51 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
yang_dnode_get_ip(&source_addr, args->dnode, NULL);
|
|
|
|
result = pim_ssmpingd_stop(pim, source_addr.ip._v4_addr);
|
|
|
|
if (result) {
|
|
|
|
char source_str[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
ipaddr2str(&source_addr, source_str,
|
|
|
|
sizeof(source_str));
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"%% Failure stopping ssmpingd for source %s: %d",
|
|
|
|
source_str, result);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-group
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 16:29:44 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
const char *mesh_group_name;
|
|
|
|
int result;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 16:29:44 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 16:29:44 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
mesh_group_name = yang_dnode_get_string(args->dnode, ".");
|
|
|
|
|
|
|
|
result = ip_no_msdp_mesh_group_cmd_worker(pim, mesh_group_name,
|
|
|
|
args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
|
|
|
|
if (result != PIM_MSDP_ERR_NONE)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-group/mesh-group-name
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_mesh_group_name_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 16:29:44 +02:00
|
|
|
const char *mesh_group_name;
|
|
|
|
const char *mesh_group_name_old;
|
|
|
|
char xpath[XPATH_MAXLEN];
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 16:29:44 +02:00
|
|
|
mesh_group_name = yang_dnode_get_string(args->dnode, ".");
|
|
|
|
yang_dnode_get_path(args->dnode, xpath, sizeof(xpath));
|
|
|
|
|
|
|
|
if (yang_dnode_exists(running_config->dnode, xpath) == false)
|
|
|
|
break;
|
|
|
|
|
|
|
|
mesh_group_name_old = yang_dnode_get_string(running_config->dnode,
|
|
|
|
xpath);
|
|
|
|
if (strcmp(mesh_group_name, mesh_group_name_old)) {
|
|
|
|
/* currently only one mesh-group can exist at a time */
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Only one mesh-group allowed currently");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_mesh_group_name_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-group/member-ip
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_member_ip_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
2020-10-23 16:29:44 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
const char *mesh_group_name;
|
|
|
|
struct ipaddr mbr_ip;
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 16:29:44 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 16:29:44 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
mesh_group_name = yang_dnode_get_string(args->dnode,
|
|
|
|
"../mesh-group-name");
|
|
|
|
yang_dnode_get_ip(&mbr_ip, args->dnode, NULL);
|
|
|
|
|
|
|
|
result = ip_msdp_mesh_group_member_cmd_worker(
|
|
|
|
pim, mesh_group_name, mbr_ip.ip._v4_addr,
|
|
|
|
args->errmsg, args->errmsg_len);
|
|
|
|
|
|
|
|
if (result != PIM_MSDP_ERR_NONE)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_member_ip_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 16:29:44 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
const char *mesh_group_name;
|
|
|
|
struct ipaddr mbr_ip;
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 16:29:44 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 16:29:44 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
mesh_group_name = yang_dnode_get_string(args->dnode,
|
|
|
|
"../mesh-group-name");
|
|
|
|
yang_dnode_get_ip(&mbr_ip, args->dnode, NULL);
|
|
|
|
|
|
|
|
result = ip_no_msdp_mesh_group_member_cmd_worker(
|
|
|
|
pim, mesh_group_name, mbr_ip.ip._v4_addr,
|
|
|
|
args->errmsg, args->errmsg_len);
|
|
|
|
|
|
|
|
if (result != PIM_MSDP_ERR_NONE)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-group/source-ip
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_source_ip_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 16:29:44 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
const char *mesh_group_name;
|
|
|
|
struct ipaddr src_ip;
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 16:29:44 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 16:29:44 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
mesh_group_name = yang_dnode_get_string(args->dnode,
|
|
|
|
"../mesh-group-name");
|
|
|
|
yang_dnode_get_ip(&src_ip, args->dnode, NULL);
|
|
|
|
|
|
|
|
result = ip_msdp_mesh_group_source_cmd_worker(
|
|
|
|
pim, mesh_group_name, src_ip.ip._v4_addr,
|
|
|
|
args->errmsg, args->errmsg_len);
|
|
|
|
|
|
|
|
if (result != PIM_MSDP_ERR_NONE)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_source_ip_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 16:29:44 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
const char *mesh_group_name;
|
|
|
|
enum pim_msdp_err result;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 16:29:44 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 16:29:44 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
mesh_group_name = yang_dnode_get_string(args->dnode,
|
|
|
|
"../mesh-group-name");
|
|
|
|
|
|
|
|
result = ip_no_msdp_mesh_group_source_cmd_worker(
|
|
|
|
pim, mesh_group_name, args->errmsg, args->errmsg_len);
|
|
|
|
|
|
|
|
if (result != PIM_MSDP_ERR_NONE)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 16:29:44 +02:00
|
|
|
int result;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
struct ipaddr peer_ip;
|
|
|
|
struct vrf *vrf;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 16:29:44 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 16:29:44 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
yang_dnode_get_ip(&peer_ip, args->dnode, "./peer-ip");
|
|
|
|
result = ip_no_msdp_peer_cmd_worker(pim, peer_ip.ip._v4_addr,
|
|
|
|
args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/source-ip
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 16:29:44 +02:00
|
|
|
int result;
|
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
struct ipaddr peer_ip;
|
|
|
|
struct ipaddr source_ip;
|
|
|
|
const struct lyd_node *mesh_group_name_dnode;
|
|
|
|
const char *mesh_group_name;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 16:29:44 +02:00
|
|
|
mesh_group_name_dnode =
|
|
|
|
yang_dnode_get(args->dnode,
|
|
|
|
"../../msdp-mesh-group/mesh-group-name");
|
|
|
|
if (mesh_group_name_dnode) {
|
|
|
|
mesh_group_name =
|
|
|
|
yang_dnode_get_string(mesh_group_name_dnode,
|
|
|
|
".");
|
|
|
|
if (strcmp(mesh_group_name, "default")) {
|
|
|
|
/* currently only one mesh-group can exist at a time */
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"%% Only one mesh-group allowed currently");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 16:29:44 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 16:29:44 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
yang_dnode_get_ip(&peer_ip, args->dnode, "../peer-ip");
|
|
|
|
yang_dnode_get_ip(&source_ip, args->dnode, NULL);
|
|
|
|
|
|
|
|
result = ip_msdp_peer_cmd_worker(pim, peer_ip.ip._v4_addr,
|
|
|
|
source_ip.ip._v4_addr,
|
|
|
|
args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 16:39:22 +02:00
|
|
|
struct in_addr addr;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 16:39:22 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
addr.s_addr = 0;
|
|
|
|
pim_vxlan_mlag_update(true/*mlag_enable*/,
|
|
|
|
false/*peer_state*/, MLAG_ROLE_NONE,
|
|
|
|
NULL/*peerlink*/, &addr);
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
2020-10-23 16:39:22 +02:00
|
|
|
/*
|
|
|
|
* XPath:
|
|
|
|
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
|
|
|
|
*/
|
|
|
|
void routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_apply_finish(
|
|
|
|
struct nb_cb_apply_finish_args *args)
|
|
|
|
{
|
|
|
|
const char *ifname;
|
|
|
|
uint32_t role;
|
|
|
|
bool peer_state;
|
|
|
|
struct interface *ifp;
|
|
|
|
struct ipaddr reg_addr;
|
|
|
|
|
|
|
|
ifname = yang_dnode_get_string(args->dnode, "./peerlink-rif");
|
|
|
|
ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
|
|
|
|
if (!ifp) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"No such interface name %s", ifname);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
role = yang_dnode_get_enum(args->dnode, "./my-role");
|
|
|
|
peer_state = yang_dnode_get_bool(args->dnode, "./peer-state");
|
|
|
|
yang_dnode_get_ip(®_addr, args->dnode, "./reg-address");
|
|
|
|
|
|
|
|
pim_vxlan_mlag_update(true, peer_state, role, ifp,
|
|
|
|
®_addr.ip._v4_addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peerlink-rif
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/reg-address
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/my-role
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_my_role_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peer-state
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peer_state_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/register-accept-list
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 16:39:22 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
const char *plist;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 16:39:22 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
plist = yang_dnode_get_string(args->dnode, NULL);
|
|
|
|
|
|
|
|
XFREE(MTYPE_PIM_PLIST_NAME, pim->register_plist);
|
|
|
|
pim->register_plist = XSTRDUP(MTYPE_PIM_PLIST_NAME, plist);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
|
2020-10-23 16:39:22 +02:00
|
|
|
return NB_OK;
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 16:39:22 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 16:39:22 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 16:39:22 +02:00
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
|
|
|
|
XFREE(MTYPE_PIM_PLIST_NAME, pim->register_plist);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_pim_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 14:06:06 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 14:06:06 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
if (!pim_ifp)
|
|
|
|
return NB_OK;
|
|
|
|
|
|
|
|
if (!pim_cmd_interface_delete(ifp)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Unable to delete interface information %s",
|
|
|
|
ifp->name);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/pim-enable
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_pim_enable_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:06:06 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
int mcast_if_count;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:06:06 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
mcast_if_count =
|
|
|
|
yang_get_list_elements_count(if_dnode);
|
|
|
|
|
|
|
|
/* Limiting mcast interfaces to number of VIFs */
|
|
|
|
if (mcast_if_count == MAXVIFS) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Max multicast interfaces(%d) reached.",
|
|
|
|
MAXVIFS);
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:06:06 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:06:06 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
|
|
|
|
if (yang_dnode_get_bool(args->dnode, NULL)) {
|
|
|
|
if (!pim_cmd_interface_add(ifp)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Could not enable PIM SM on interface %s",
|
|
|
|
ifp->name);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
if (!pim_ifp)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
|
|
|
if (!pim_cmd_interface_delete(ifp)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Unable to delete interface information");
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/hello-interval
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_hello_interval_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:27:06 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:27:06 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:27:06 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
pim_ifp->pim_hello_period =
|
|
|
|
yang_dnode_get_uint8(args->dnode, NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/hello-holdtime
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_hello_holdtime_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:27:06 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:27:06 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:27:06 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
pim_ifp->pim_default_holdtime =
|
|
|
|
yang_dnode_get_uint8(args->dnode, NULL);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
2020-10-23 14:27:06 +02:00
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_pim_hello_holdtime_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 14:27:06 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:27:06 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:27:06 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
pim_ifp->pim_default_holdtime = -1;
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/bfd
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_bfd_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_pim_bfd_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 14:43:16 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:43:16 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
if (!is_pim_interface(if_dnode)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Pim not enabled on this interface");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:43:16 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:43:16 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode->parent, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
if (pim_ifp->bfd_info) {
|
|
|
|
pim_bfd_reg_dereg_all_nbr(ifp,
|
|
|
|
ZEBRA_BFD_DEST_DEREGISTER);
|
|
|
|
bfd_info_free(&(pim_ifp->bfd_info));
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
2020-10-23 14:43:16 +02:00
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/bfd
|
|
|
|
*/
|
|
|
|
void lib_interface_pim_bfd_apply_finish(struct nb_cb_apply_finish_args *args)
|
|
|
|
{
|
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
uint32_t min_rx;
|
|
|
|
uint32_t min_tx;
|
|
|
|
uint8_t detect_mult;
|
|
|
|
|
|
|
|
ifp = nb_running_get_entry(args->dnode->parent, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp) {
|
|
|
|
zlog_debug("Pim not enabled on this interface");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
min_rx = yang_dnode_get_uint16(args->dnode, "./min-rx-interval");
|
|
|
|
min_tx = yang_dnode_get_uint16(args->dnode, "./min-tx-interval");
|
|
|
|
detect_mult = yang_dnode_get_uint8(args->dnode, "./detect_mult");
|
|
|
|
|
|
|
|
if ((min_rx == BFD_DEF_MIN_RX) && (min_tx == BFD_DEF_MIN_TX)
|
|
|
|
&& (detect_mult == BFD_DEF_DETECT_MULT))
|
|
|
|
pim_bfd_if_param_set(ifp, min_rx, min_tx, detect_mult, 1);
|
|
|
|
else
|
|
|
|
pim_bfd_if_param_set(ifp, min_rx, min_tx, detect_mult, 0);
|
|
|
|
|
|
|
|
nb_running_set_entry(args->dnode, pim_ifp->bfd_info);
|
|
|
|
}
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/bfd/min-rx-interval
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_bfd_min_rx_interval_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/bfd/min-tx-interval
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_bfd_min_tx_interval_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/bfd/detect_mult
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_bfd_detect_mult_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/bsm
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_bsm_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:27:06 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:27:06 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
pim_ifp->bsm_enable = yang_dnode_get_bool(args->dnode, NULL);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
|
2020-10-23 14:27:06 +02:00
|
|
|
return NB_OK;
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/unicast-bsm
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_unicast_bsm_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:27:06 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:27:06 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:27:06 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
pim_ifp->ucast_bsm_accept =
|
|
|
|
yang_dnode_get_bool(args->dnode, NULL);
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/active-active
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_active_active_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:27:06 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:27:06 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:27:06 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
if (yang_dnode_get_bool(args->dnode, NULL)) {
|
|
|
|
if (PIM_DEBUG_MLAG)
|
|
|
|
zlog_debug(
|
|
|
|
"Configuring PIM active-active on Interface: %s",
|
|
|
|
ifp->name);
|
|
|
|
pim_if_configure_mlag_dualactive(pim_ifp);
|
|
|
|
} else {
|
|
|
|
if (PIM_DEBUG_MLAG)
|
|
|
|
zlog_debug(
|
|
|
|
"UnConfiguring PIM active-active on Interface: %s",
|
|
|
|
ifp->name);
|
|
|
|
pim_if_unconfigure_mlag_dualactive(pim_ifp);
|
|
|
|
}
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
2020-10-23 14:27:06 +02:00
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/dr-priority
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_dr_priority_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:27:06 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
uint32_t old_dr_prio;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:27:06 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
if (!is_pim_interface(if_dnode)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Pim not enabled on this interface");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:27:06 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:27:06 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
old_dr_prio = pim_ifp->pim_dr_priority;
|
|
|
|
pim_ifp->pim_dr_priority = yang_dnode_get_uint32(args->dnode,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (old_dr_prio != pim_ifp->pim_dr_priority) {
|
|
|
|
pim_if_dr_election(ifp);
|
|
|
|
pim_hello_restart_now(ifp);
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_address_family_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/use-source
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_address_family_use_source_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:59:37 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct ipaddr source_addr;
|
|
|
|
int result;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:59:37 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
if (!is_pim_interface(if_dnode)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Pim not enabled on this interface");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:59:37 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:59:37 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
yang_dnode_get_ip(&source_addr, args->dnode, NULL);
|
|
|
|
|
|
|
|
result = interface_pim_use_src_cmd_worker(
|
|
|
|
ifp, source_addr.ip._v4_addr,
|
|
|
|
args->errmsg, args->errmsg_len);
|
|
|
|
|
|
|
|
if (result != PIM_SUCCESS)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_pim_address_family_use_source_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 14:59:37 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct in_addr source_addr = {INADDR_ANY};
|
|
|
|
int result;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:59:37 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
if (!is_pim_interface(if_dnode)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Pim not enabled on this interface");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:59:37 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:59:37 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
|
|
|
|
result = interface_pim_use_src_cmd_worker(ifp, source_addr,
|
|
|
|
args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
|
|
|
|
if (result != PIM_SUCCESS)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-oil
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_address_family_multicast_boundary_oil_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:59:37 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
const char *plist;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:59:37 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
if (!is_pim_interface(if_dnode)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Pim not enabled on this interface");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:59:37 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:59:37 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
plist = yang_dnode_get_string(args->dnode, NULL);
|
|
|
|
|
|
|
|
if (pim_ifp->boundary_oil_plist)
|
|
|
|
XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
|
|
|
|
|
|
|
|
pim_ifp->boundary_oil_plist =
|
|
|
|
XSTRDUP(MTYPE_PIM_INTERFACE, plist);
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_pim_address_family_multicast_boundary_oil_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 14:59:37 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:59:37 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
if (!is_pim_interface(if_dnode)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"%% Enable PIM and/or IGMP on this interface first");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:59:37 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:59:37 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
if (pim_ifp->boundary_oil_plist)
|
|
|
|
XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_address_family_mroute_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_pim_address_family_mroute_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 14:59:37 +02:00
|
|
|
struct pim_instance *pim;
|
|
|
|
struct pim_interface *pim_iifp;
|
|
|
|
struct interface *iif;
|
|
|
|
struct interface *oif;
|
|
|
|
const char *oifname;
|
|
|
|
struct ipaddr source_addr;
|
|
|
|
struct ipaddr group_addr;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:59:37 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
if (!is_pim_interface(if_dnode)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"%% Enable PIM and/or IGMP on this interface first");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:59:37 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:59:37 +02:00
|
|
|
iif = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_iifp = iif->info;
|
|
|
|
pim = pim_iifp->pim;
|
|
|
|
|
|
|
|
oifname = yang_dnode_get_string(args->dnode, "./oif");
|
|
|
|
oif = if_lookup_by_name(oifname, pim->vrf_id);
|
|
|
|
|
|
|
|
if (!oif) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"No such interface name %s",
|
|
|
|
oifname);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
yang_dnode_get_ip(&source_addr, args->dnode, "./source-addr");
|
|
|
|
yang_dnode_get_ip(&group_addr, args->dnode, "./group-addr");
|
|
|
|
|
|
|
|
if (pim_static_del(pim, iif, oif, group_addr.ip._v4_addr,
|
|
|
|
source_addr.ip._v4_addr)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Failed to remove static mroute");
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute/oif
|
|
|
|
*/
|
|
|
|
int lib_interface_pim_address_family_mroute_oif_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 14:59:37 +02:00
|
|
|
struct pim_instance *pim;
|
|
|
|
struct pim_interface *pim_iifp;
|
|
|
|
struct interface *iif;
|
|
|
|
struct interface *oif;
|
|
|
|
const char *oifname;
|
|
|
|
struct ipaddr source_addr;
|
|
|
|
struct ipaddr group_addr;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 14:59:37 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
if (!is_pim_interface(if_dnode)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"%% Enable PIM and/or IGMP on this interface first");
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 14:59:37 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 14:59:37 +02:00
|
|
|
iif = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_iifp = iif->info;
|
|
|
|
pim = pim_iifp->pim;
|
|
|
|
|
|
|
|
oifname = yang_dnode_get_string(args->dnode, NULL);
|
|
|
|
oif = if_lookup_by_name(oifname, pim->vrf_id);
|
|
|
|
|
|
|
|
if (!oif) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"No such interface name %s",
|
|
|
|
oifname);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
yang_dnode_get_ip(&source_addr, args->dnode, "../source-addr");
|
|
|
|
yang_dnode_get_ip(&group_addr, args->dnode, "../group-addr");
|
|
|
|
|
|
|
|
if (pim_static_add(pim, iif, oif, group_addr.ip._v4_addr,
|
|
|
|
source_addr.ip._v4_addr)) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Failed to add static mroute");
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_pim_address_family_mroute_oif_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
/* TODO: implement me. */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 16:52:41 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
struct prefix group;
|
|
|
|
struct ipaddr rp_addr;
|
|
|
|
const char *plist;
|
|
|
|
int result = 0;
|
2020-10-23 10:40:39 +02:00
|
|
|
|
2020-10-23 16:52:41 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
yang_dnode_get_ip(&rp_addr, args->dnode, "./rp-address");
|
|
|
|
|
|
|
|
if (yang_dnode_get(args->dnode, "./group-list")) {
|
|
|
|
yang_dnode_get_ipv4p(&group, args->dnode,
|
|
|
|
"./group-list");
|
|
|
|
result = pim_no_rp_cmd_worker(pim, rp_addr.ip._v4_addr,
|
|
|
|
group, NULL, args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (yang_dnode_get(args->dnode, "./prefix-list")) {
|
|
|
|
plist = yang_dnode_get_string(args->dnode,
|
|
|
|
"./prefix-list");
|
|
|
|
str2prefix("224.0.0.0/4", &group);
|
|
|
|
result = pim_no_rp_cmd_worker(pim, rp_addr.ip._v4_addr,
|
|
|
|
group, plist,
|
|
|
|
args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list/group-list
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
2020-10-23 16:52:41 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
struct prefix group;
|
|
|
|
struct ipaddr rp_addr;
|
2020-10-23 10:40:39 +02:00
|
|
|
|
2020-10-23 16:52:41 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
yang_dnode_get_ip(&rp_addr, args->dnode, "../rp-address");
|
|
|
|
yang_dnode_get_ipv4p(&group, args->dnode, NULL);
|
|
|
|
|
|
|
|
return pim_rp_cmd_worker(pim, rp_addr.ip._v4_addr, group,
|
|
|
|
NULL, args->errmsg, args->errmsg_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 16:52:41 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
struct prefix group;
|
|
|
|
struct ipaddr rp_addr;
|
2020-10-23 10:40:39 +02:00
|
|
|
|
2020-10-23 16:52:41 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
yang_dnode_get_ip(&rp_addr, args->dnode, "../rp-address");
|
|
|
|
yang_dnode_get_ipv4p(&group, args->dnode, NULL);
|
|
|
|
|
|
|
|
return pim_no_rp_cmd_worker(pim, rp_addr.ip._v4_addr, group,
|
|
|
|
NULL, args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list/prefix-list
|
|
|
|
*/
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 16:52:41 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
struct prefix group;
|
|
|
|
struct ipaddr rp_addr;
|
|
|
|
const char *plist;
|
2020-10-23 10:40:39 +02:00
|
|
|
|
2020-10-23 16:52:41 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
plist = yang_dnode_get_string(args->dnode, NULL);
|
|
|
|
yang_dnode_get_ip(&rp_addr, args->dnode, "../rp-address");
|
|
|
|
str2prefix("224.0.0.0/4", &group);
|
|
|
|
return pim_rp_cmd_worker(pim, rp_addr.ip._v4_addr, group,
|
|
|
|
plist, args->errmsg, args->errmsg_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 16:52:41 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct pim_instance *pim;
|
|
|
|
struct prefix group;
|
|
|
|
struct ipaddr rp_addr;
|
|
|
|
const char *plist;
|
2020-10-23 10:40:39 +02:00
|
|
|
|
2020-10-23 16:52:41 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim = vrf->info;
|
|
|
|
yang_dnode_get_ip(&rp_addr, args->dnode, "../rp-address");
|
|
|
|
plist = yang_dnode_get_string(args->dnode, NULL);
|
|
|
|
str2prefix("224.0.0.0/4", &group);
|
|
|
|
return pim_no_rp_cmd_worker(pim, rp_addr.ip._v4_addr, group,
|
|
|
|
plist, args->errmsg,
|
|
|
|
args->errmsg_len);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-igmp:igmp
|
|
|
|
*/
|
|
|
|
int lib_interface_igmp_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_igmp_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 13:46:39 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
return NB_OK;
|
|
|
|
|
|
|
|
PIM_IF_DONT_IGMP(pim_ifp->options);
|
|
|
|
|
|
|
|
pim_if_membership_clear(ifp);
|
|
|
|
|
|
|
|
pim_if_addr_del_all_igmp(ifp);
|
|
|
|
|
|
|
|
if (!PIM_IF_TEST_PIM(pim_ifp->options))
|
|
|
|
pim_if_delete(ifp);
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-igmp:igmp/igmp-enable
|
|
|
|
*/
|
|
|
|
int lib_interface_igmp_igmp_enable_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
bool igmp_enable;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
int mcast_if_count;
|
|
|
|
const char *ifp_name;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 13:46:39 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
ifp_name = yang_dnode_get_string(if_dnode, ".");
|
|
|
|
mcast_if_count =
|
|
|
|
yang_get_list_elements_count(if_dnode);
|
|
|
|
/* Limiting mcast interfaces to number of VIFs */
|
|
|
|
if (mcast_if_count == MAXVIFS) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s",
|
|
|
|
MAXVIFS, ifp_name);
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 13:46:39 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
igmp_enable = yang_dnode_get_bool(args->dnode, NULL);
|
|
|
|
|
|
|
|
if (igmp_enable)
|
|
|
|
return pim_cmd_igmp_start(ifp);
|
|
|
|
|
|
|
|
else {
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
|
|
|
PIM_IF_DONT_IGMP(pim_ifp->options);
|
|
|
|
|
|
|
|
pim_if_membership_clear(ifp);
|
|
|
|
|
|
|
|
pim_if_addr_del_all_igmp(ifp);
|
|
|
|
|
|
|
|
if (!PIM_IF_TEST_PIM(pim_ifp->options))
|
|
|
|
pim_if_delete(ifp);
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-igmp:igmp/version
|
|
|
|
*/
|
|
|
|
int lib_interface_igmp_version_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
int igmp_version, old_version = 0;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 13:46:39 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 13:46:39 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
|
|
|
|
if (!pim_ifp)
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
|
|
|
|
igmp_version = yang_dnode_get_uint8(args->dnode, NULL);
|
|
|
|
old_version = pim_ifp->igmp_version;
|
|
|
|
pim_ifp->igmp_version = igmp_version;
|
|
|
|
|
|
|
|
old_version = igmp_version;
|
|
|
|
|
|
|
|
/* Current and new version is different refresh existing
|
|
|
|
* membership. Going from 3 -> 2 or 2 -> 3.
|
|
|
|
*/
|
|
|
|
if (old_version != igmp_version)
|
|
|
|
pim_if_membership_refresh(ifp);
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_igmp_version_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 13:46:39 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 13:46:39 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-igmp:igmp/query-interval
|
|
|
|
*/
|
|
|
|
int lib_interface_igmp_query_interval_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
int query_interval;
|
|
|
|
int query_interval_dsec;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 13:46:39 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
query_interval = yang_dnode_get_uint16(args->dnode, NULL);
|
|
|
|
query_interval_dsec = 10 * query_interval;
|
|
|
|
if (query_interval_dsec <=
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Can't set general query interval %d dsec <= query max response time %d dsec.",
|
|
|
|
query_interval_dsec,
|
|
|
|
pim_ifp->igmp_query_max_response_time_dsec);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
change_query_interval(pim_ifp, query_interval);
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-igmp:igmp/query-max-response-time
|
|
|
|
*/
|
|
|
|
int lib_interface_igmp_query_max_response_time_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
int query_max_response_time_dsec;
|
|
|
|
int default_query_interval_dsec;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 13:46:39 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
query_max_response_time_dsec =
|
|
|
|
yang_dnode_get_uint8(args->dnode, NULL);
|
|
|
|
default_query_interval_dsec =
|
|
|
|
10 * pim_ifp->igmp_default_query_interval;
|
|
|
|
|
|
|
|
if (query_max_response_time_dsec
|
|
|
|
>= default_query_interval_dsec) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Can't set query max response time %d sec >= general query interval %d sec",
|
|
|
|
query_max_response_time_dsec,
|
|
|
|
pim_ifp->igmp_default_query_interval);
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
|
|
|
change_query_max_response_time(pim_ifp,
|
|
|
|
query_max_response_time_dsec);
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-igmp:igmp/last-member-query-interval
|
|
|
|
*/
|
|
|
|
int lib_interface_igmp_last_member_query_interval_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
int last_member_query_interval;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 13:46:39 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 13:46:39 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
last_member_query_interval = yang_dnode_get_uint8(args->dnode,
|
|
|
|
NULL);
|
|
|
|
pim_ifp->igmp_specific_query_max_response_time_dsec =
|
|
|
|
last_member_query_interval;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-igmp:igmp/robustness-variable
|
|
|
|
*/
|
|
|
|
int lib_interface_igmp_robustness_variable_modify(struct nb_cb_modify_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct pim_interface *pim_ifp;
|
|
|
|
int last_member_query_count;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 13:46:39 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 13:46:39 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
pim_ifp = ifp->info;
|
|
|
|
last_member_query_count = yang_dnode_get_uint8(args->dnode,
|
|
|
|
NULL);
|
|
|
|
pim_ifp->igmp_last_member_query_count = last_member_query_count;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-igmp:igmp/address-family
|
|
|
|
*/
|
|
|
|
int lib_interface_igmp_address_family_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_igmp_address_family_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
case NB_EV_APPLY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XPath: /frr-interface:lib/interface/frr-igmp:igmp/address-family/static-group
|
|
|
|
*/
|
|
|
|
int lib_interface_igmp_address_family_static_group_create(struct nb_cb_create_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct ipaddr source_addr;
|
|
|
|
struct ipaddr group_addr;
|
|
|
|
int result;
|
|
|
|
const char *ifp_name;
|
|
|
|
const struct lyd_node *if_dnode;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
2020-10-23 13:46:39 +02:00
|
|
|
if_dnode = yang_dnode_get_parent(args->dnode, "interface");
|
|
|
|
if (!is_pim_interface(if_dnode)) {
|
|
|
|
ifp_name = yang_dnode_get_string(if_dnode, ".");
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"multicast not enabled on interface %s",
|
|
|
|
ifp_name);
|
|
|
|
return NB_ERR_VALIDATION;
|
|
|
|
}
|
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
|
|
|
break;
|
2020-10-23 13:46:39 +02:00
|
|
|
case NB_EV_APPLY:
|
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
yang_dnode_get_ip(&source_addr, args->dnode, "./source-addr");
|
|
|
|
yang_dnode_get_ip(&group_addr, args->dnode, "./group-addr");
|
|
|
|
|
|
|
|
result = pim_if_igmp_join_add(ifp, group_addr.ip._v4_addr,
|
|
|
|
source_addr.ip._v4_addr);
|
|
|
|
if (result) {
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"Failure joining IGMP group");
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
2020-10-23 10:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lib_interface_igmp_address_family_static_group_destroy(struct nb_cb_destroy_args *args)
|
|
|
|
{
|
2020-10-23 13:46:39 +02:00
|
|
|
struct interface *ifp;
|
|
|
|
struct ipaddr source_addr;
|
|
|
|
struct ipaddr group_addr;
|
|
|
|
int result;
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
switch (args->event) {
|
|
|
|
case NB_EV_VALIDATE:
|
|
|
|
case NB_EV_PREPARE:
|
|
|
|
case NB_EV_ABORT:
|
2020-10-23 13:46:39 +02:00
|
|
|
break;
|
2020-10-23 10:40:39 +02:00
|
|
|
case NB_EV_APPLY:
|
2020-10-23 13:46:39 +02:00
|
|
|
ifp = nb_running_get_entry(args->dnode, NULL, true);
|
|
|
|
yang_dnode_get_ip(&source_addr, args->dnode, "./source-addr");
|
|
|
|
yang_dnode_get_ip(&group_addr, args->dnode, "./group-addr");
|
|
|
|
|
|
|
|
result = pim_if_igmp_join_del(ifp, group_addr.ip._v4_addr,
|
|
|
|
source_addr.ip._v4_addr);
|
|
|
|
|
|
|
|
if (result) {
|
|
|
|
char src_str[INET_ADDRSTRLEN];
|
|
|
|
char grp_str[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
ipaddr2str(&source_addr, src_str, sizeof(src_str));
|
|
|
|
ipaddr2str(&group_addr, grp_str, sizeof(grp_str));
|
|
|
|
|
|
|
|
snprintf(args->errmsg, args->errmsg_len,
|
|
|
|
"%% Failure leaving IGMP group %s %s on interface %s: %d",
|
|
|
|
src_str, grp_str, ifp->name, result);
|
|
|
|
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
|
|
|
}
|
|
|
|
|
2020-10-23 10:40:39 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NB_OK;
|
|
|
|
}
|