forked from Mirror/frr
pimd: MSDP SA filtering
Implement MSDP peer incoming/outgoing SA filter. Note ---- Cisco extended access list has a special meaning: the first address is the source address to filter. Example: ! The rules below filter some LAN prefix to be leaked out access-list filter-lan-source deny ip 192.168.0.0 0.0.255.255 224.0.0.0 0.255.255.255 access-list filter-lan-source permit any router pim msdp peer 192.168.0.1 sa-filter filter-lan-source out ! The rules below filter some special management group from being ! learned access-list filter-management-group deny 230.0.0.0 0.255.255.255 access-list filter-management-group permit any router pim msdp peer 192.168.0.1 sa-filter filter-management-group in Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
bfae003b62
commit
be3bfe5daa
|
@ -6486,6 +6486,69 @@ DEFPY_ATTR(no_ip_pim_msdp_peer,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFPY(msdp_peer_sa_filter, msdp_peer_sa_filter_cmd,
|
||||||
|
"msdp peer A.B.C.D$peer sa-filter ACL_NAME$acl_name <in|out>$dir",
|
||||||
|
CFG_MSDP_STR
|
||||||
|
"Configure MSDP peer\n"
|
||||||
|
"MSDP Peer address\n"
|
||||||
|
"SA access-list filter\n"
|
||||||
|
"SA access-list name\n"
|
||||||
|
"Filter incoming SAs\n"
|
||||||
|
"Filter outgoing SAs\n")
|
||||||
|
{
|
||||||
|
const struct lyd_node *peer_node;
|
||||||
|
char xpath[XPATH_MAXLEN + 24];
|
||||||
|
|
||||||
|
snprintf(xpath, sizeof(xpath), "%s/msdp-peer[peer-ip='%s']",
|
||||||
|
VTY_CURR_XPATH, peer_str);
|
||||||
|
peer_node = yang_dnode_get(vty->candidate_config->dnode, xpath);
|
||||||
|
if (peer_node == NULL) {
|
||||||
|
vty_out(vty, "%% MSDP peer %s not yet configured\n", peer_str);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(dir, "in") == 0)
|
||||||
|
nb_cli_enqueue_change(vty, "./sa-filter-in", NB_OP_MODIFY,
|
||||||
|
acl_name);
|
||||||
|
else
|
||||||
|
nb_cli_enqueue_change(vty, "./sa-filter-out", NB_OP_MODIFY,
|
||||||
|
acl_name);
|
||||||
|
|
||||||
|
return nb_cli_apply_changes(vty, "%s", xpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFPY(no_msdp_peer_sa_filter, no_ip_msdp_peer_sa_filter_cmd,
|
||||||
|
"no msdp peer A.B.C.D$peer sa-filter ACL_NAME <in|out>$dir",
|
||||||
|
NO_STR
|
||||||
|
CFG_MSDP_STR
|
||||||
|
"Configure MSDP peer\n"
|
||||||
|
"MSDP Peer address\n"
|
||||||
|
"SA access-list filter\n"
|
||||||
|
"SA access-list name\n"
|
||||||
|
"Filter incoming SAs\n"
|
||||||
|
"Filter outgoing SAs\n")
|
||||||
|
{
|
||||||
|
const struct lyd_node *peer_node;
|
||||||
|
char xpath[XPATH_MAXLEN + 24];
|
||||||
|
|
||||||
|
snprintf(xpath, sizeof(xpath), "%s/msdp-peer[peer-ip='%s']",
|
||||||
|
VTY_CURR_XPATH, peer_str);
|
||||||
|
peer_node = yang_dnode_get(vty->candidate_config->dnode, xpath);
|
||||||
|
if (peer_node == NULL) {
|
||||||
|
vty_out(vty, "%% MSDP peer %s not yet configured\n", peer_str);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(dir, "in") == 0)
|
||||||
|
nb_cli_enqueue_change(vty, "./sa-filter-in", NB_OP_DESTROY,
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
|
nb_cli_enqueue_change(vty, "./sa-filter-out", NB_OP_DESTROY,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return nb_cli_apply_changes(vty, "%s", xpath);
|
||||||
|
}
|
||||||
|
|
||||||
DEFPY(pim_msdp_mesh_group_member,
|
DEFPY(pim_msdp_mesh_group_member,
|
||||||
pim_msdp_mesh_group_member_cmd,
|
pim_msdp_mesh_group_member_cmd,
|
||||||
"msdp mesh-group WORD$gname member A.B.C.D$maddr",
|
"msdp mesh-group WORD$gname member A.B.C.D$maddr",
|
||||||
|
@ -8259,6 +8322,8 @@ void pim_cmd_init(void)
|
||||||
install_element(PIM_NODE, &no_pim_msdp_peer_cmd);
|
install_element(PIM_NODE, &no_pim_msdp_peer_cmd);
|
||||||
install_element(PIM_NODE, &pim_msdp_timers_cmd);
|
install_element(PIM_NODE, &pim_msdp_timers_cmd);
|
||||||
install_element(PIM_NODE, &no_pim_msdp_timers_cmd);
|
install_element(PIM_NODE, &no_pim_msdp_timers_cmd);
|
||||||
|
install_element(PIM_NODE, &msdp_peer_sa_filter_cmd);
|
||||||
|
install_element(PIM_NODE, &no_ip_msdp_peer_sa_filter_cmd);
|
||||||
install_element(PIM_NODE, &pim_msdp_mesh_group_member_cmd);
|
install_element(PIM_NODE, &pim_msdp_mesh_group_member_cmd);
|
||||||
install_element(PIM_NODE, &no_pim_msdp_mesh_group_member_cmd);
|
install_element(PIM_NODE, &no_pim_msdp_mesh_group_member_cmd);
|
||||||
install_element(PIM_NODE, &pim_msdp_mesh_group_source_cmd);
|
install_element(PIM_NODE, &pim_msdp_mesh_group_source_cmd);
|
||||||
|
|
|
@ -1317,6 +1317,15 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim)
|
||||||
|
|
||||||
vty_out(vty, " msdp peer %pI4 source %pI4\n", &mp->peer,
|
vty_out(vty, " msdp peer %pI4 source %pI4\n", &mp->peer,
|
||||||
&mp->local);
|
&mp->local);
|
||||||
|
|
||||||
|
if (mp->acl_in)
|
||||||
|
vty_out(vty, " msdp peer %pI4 sa-filter %s in\n",
|
||||||
|
&mp->peer, mp->acl_in);
|
||||||
|
|
||||||
|
if (mp->acl_out)
|
||||||
|
vty_out(vty, " msdp peer %pI4 sa-filter %s out\n",
|
||||||
|
&mp->peer, mp->acl_out);
|
||||||
|
|
||||||
written = true;
|
written = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,11 @@ struct pim_msdp_peer {
|
||||||
|
|
||||||
/* timestamps */
|
/* timestamps */
|
||||||
int64_t uptime;
|
int64_t uptime;
|
||||||
|
|
||||||
|
/** SA input access list name. */
|
||||||
|
char *acl_in;
|
||||||
|
/** SA output access list name. */
|
||||||
|
char *acl_out;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pim_msdp_mg_mbr {
|
struct pim_msdp_mg_mbr {
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#include <lib/log.h>
|
#include <lib/log.h>
|
||||||
|
#include <lib/filter.h>
|
||||||
#include <lib/network.h>
|
#include <lib/network.h>
|
||||||
|
#include <lib/prefix.h>
|
||||||
#include <lib/stream.h>
|
#include <lib/stream.h>
|
||||||
#include "frrevent.h"
|
#include "frrevent.h"
|
||||||
#include <lib/vty.h>
|
#include <lib/vty.h>
|
||||||
|
@ -322,8 +324,8 @@ void pim_msdp_pkt_ka_tx(struct pim_msdp_peer *mp)
|
||||||
pim_msdp_pkt_send(mp, s);
|
pim_msdp_pkt_send(mp, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pim_msdp_pkt_sa_push_to_one_peer(struct pim_instance *pim,
|
static void pim_msdp_pkt_sa_push(struct pim_instance *pim,
|
||||||
struct pim_msdp_peer *mp)
|
struct pim_msdp_peer *mp)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
|
|
||||||
|
@ -338,25 +340,6 @@ static void pim_msdp_pkt_sa_push_to_one_peer(struct pim_instance *pim,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push the stream into the obuf fifo of all the peers */
|
|
||||||
static void pim_msdp_pkt_sa_push(struct pim_instance *pim,
|
|
||||||
struct pim_msdp_peer *mp)
|
|
||||||
{
|
|
||||||
struct listnode *mpnode;
|
|
||||||
|
|
||||||
if (mp) {
|
|
||||||
pim_msdp_pkt_sa_push_to_one_peer(pim, mp);
|
|
||||||
} else {
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
|
|
||||||
if (PIM_DEBUG_MSDP_INTERNAL) {
|
|
||||||
zlog_debug("MSDP peer %s pim_msdp_pkt_sa_push",
|
|
||||||
mp->key_str);
|
|
||||||
}
|
|
||||||
pim_msdp_pkt_sa_push_to_one_peer(pim, mp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt,
|
static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt,
|
||||||
struct in_addr rp)
|
struct in_addr rp)
|
||||||
{
|
{
|
||||||
|
@ -384,6 +367,90 @@ static void pim_msdp_pkt_sa_fill_one(struct pim_msdp_sa *sa)
|
||||||
stream_put_ipv4(sa->pim->msdp.work_obuf, sa->sg.src.s_addr);
|
stream_put_ipv4(sa->pim->msdp.work_obuf, sa->sg.src.s_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool msdp_cisco_match(const struct filter *filter,
|
||||||
|
const struct in_addr *source,
|
||||||
|
const struct in_addr *group)
|
||||||
|
{
|
||||||
|
const struct filter_cisco *cfilter = &filter->u.cfilter;
|
||||||
|
uint32_t source_addr;
|
||||||
|
uint32_t group_addr;
|
||||||
|
|
||||||
|
group_addr = group->s_addr & ~cfilter->mask_mask.s_addr;
|
||||||
|
|
||||||
|
if (cfilter->extended) {
|
||||||
|
source_addr = source->s_addr & ~cfilter->addr_mask.s_addr;
|
||||||
|
if (group_addr == cfilter->mask.s_addr &&
|
||||||
|
source_addr == cfilter->addr.s_addr)
|
||||||
|
return true;
|
||||||
|
} else if (group_addr == cfilter->addr.s_addr)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum filter_type msdp_access_list_apply(struct access_list *access,
|
||||||
|
const struct in_addr *source,
|
||||||
|
const struct in_addr *group)
|
||||||
|
{
|
||||||
|
struct filter *filter;
|
||||||
|
struct prefix group_prefix;
|
||||||
|
|
||||||
|
if (access == NULL)
|
||||||
|
return FILTER_DENY;
|
||||||
|
|
||||||
|
for (filter = access->head; filter; filter = filter->next) {
|
||||||
|
if (filter->cisco) {
|
||||||
|
if (msdp_cisco_match(filter, source, group))
|
||||||
|
return filter->type;
|
||||||
|
} else {
|
||||||
|
group_prefix.family = AF_INET;
|
||||||
|
group_prefix.prefixlen = IPV4_MAX_BITLEN;
|
||||||
|
group_prefix.u.prefix4.s_addr = group->s_addr;
|
||||||
|
if (access_list_apply(access, &group_prefix))
|
||||||
|
return filter->type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FILTER_DENY;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool msdp_peer_sa_filter(const struct pim_msdp_peer *mp,
|
||||||
|
const struct pim_msdp_sa *sa)
|
||||||
|
{
|
||||||
|
struct access_list *acl;
|
||||||
|
|
||||||
|
/* No output filter configured, just quit. */
|
||||||
|
if (mp->acl_out == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Find access list and test it. */
|
||||||
|
acl = access_list_lookup(AFI_IP, mp->acl_out);
|
||||||
|
if (msdp_access_list_apply(acl, &sa->sg.src, &sa->sg.grp) == FILTER_DENY)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Count the number of SAs to be sent for a specific peer. */
|
||||||
|
static size_t pim_msdp_peer_sa_count(const struct pim_instance *pim,
|
||||||
|
const struct pim_msdp_peer *peer)
|
||||||
|
{
|
||||||
|
const struct pim_msdp_sa *sa;
|
||||||
|
const struct listnode *node;
|
||||||
|
size_t sa_count = 0;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, node, sa)) {
|
||||||
|
if (!CHECK_FLAG(sa->flags, PIM_MSDP_SAF_LOCAL))
|
||||||
|
continue;
|
||||||
|
if (msdp_peer_sa_filter(peer, sa))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sa_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sa_count;
|
||||||
|
}
|
||||||
|
|
||||||
static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
|
static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
|
||||||
struct pim_msdp_peer *mp)
|
struct pim_msdp_peer *mp)
|
||||||
{
|
{
|
||||||
|
@ -393,7 +460,7 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
|
||||||
struct prefix group_all;
|
struct prefix group_all;
|
||||||
struct in_addr rp;
|
struct in_addr rp;
|
||||||
int sa_count;
|
int sa_count;
|
||||||
int local_cnt = pim->msdp.local_cnt;
|
int local_cnt = pim_msdp_peer_sa_count(pim, mp);
|
||||||
|
|
||||||
sa_count = 0;
|
sa_count = 0;
|
||||||
if (PIM_DEBUG_MSDP_INTERNAL) {
|
if (PIM_DEBUG_MSDP_INTERNAL) {
|
||||||
|
@ -418,6 +485,15 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
|
||||||
* peers */
|
* peers */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msdp_peer_sa_filter(mp, sa)) {
|
||||||
|
if (PIM_DEBUG_MSDP_EVENTS)
|
||||||
|
zlog_debug("MSDP peer %pI4 filter SA out %s",
|
||||||
|
&mp->peer, sa->sg_str);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* add sa into scratch pad */
|
/* add sa into scratch pad */
|
||||||
pim_msdp_pkt_sa_fill_one(sa);
|
pim_msdp_pkt_sa_fill_one(sa);
|
||||||
++sa_count;
|
++sa_count;
|
||||||
|
@ -457,15 +533,32 @@ static void pim_msdp_pkt_sa_tx_done(struct pim_instance *pim)
|
||||||
|
|
||||||
void pim_msdp_pkt_sa_tx(struct pim_instance *pim)
|
void pim_msdp_pkt_sa_tx(struct pim_instance *pim)
|
||||||
{
|
{
|
||||||
pim_msdp_pkt_sa_gen(pim, NULL /* mp */);
|
struct pim_msdp_peer *mp;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, mp))
|
||||||
|
pim_msdp_pkt_sa_gen(pim, mp);
|
||||||
|
|
||||||
pim_msdp_pkt_sa_tx_done(pim);
|
pim_msdp_pkt_sa_tx_done(pim);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa)
|
void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa)
|
||||||
{
|
{
|
||||||
|
struct pim_msdp_peer *mp;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */, sa->rp);
|
pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */, sa->rp);
|
||||||
pim_msdp_pkt_sa_fill_one(sa);
|
pim_msdp_pkt_sa_fill_one(sa);
|
||||||
pim_msdp_pkt_sa_push(sa->pim, NULL);
|
for (ALL_LIST_ELEMENTS_RO(sa->pim->msdp.peer_list, node, mp)) {
|
||||||
|
if (msdp_peer_sa_filter(mp, sa)) {
|
||||||
|
if (PIM_DEBUG_MSDP_EVENTS)
|
||||||
|
zlog_debug("MSDP peer %pI4 filter SA out %s",
|
||||||
|
&mp->peer, sa->sg_str);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pim_msdp_pkt_sa_push(sa->pim, mp);
|
||||||
|
}
|
||||||
pim_msdp_pkt_sa_tx_done(sa->pim);
|
pim_msdp_pkt_sa_tx_done(sa->pim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,6 +580,15 @@ void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp,
|
||||||
/* Fills the message contents. */
|
/* Fills the message contents. */
|
||||||
sa.pim = mp->pim;
|
sa.pim = mp->pim;
|
||||||
sa.sg = sg;
|
sa.sg = sg;
|
||||||
|
|
||||||
|
/* Don't push it if filtered. */
|
||||||
|
if (msdp_peer_sa_filter(mp, &sa)) {
|
||||||
|
if (PIM_DEBUG_MSDP_EVENTS)
|
||||||
|
zlog_debug("MSDP peer %pI4 filter SA out (%pI4, %pI4)",
|
||||||
|
&mp->peer, &sa.sg.src, &sa.sg.grp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pim_msdp_pkt_sa_fill_one(&sa);
|
pim_msdp_pkt_sa_fill_one(&sa);
|
||||||
|
|
||||||
/* Pushes the message. */
|
/* Pushes the message. */
|
||||||
|
@ -511,6 +613,7 @@ static void pim_msdp_pkt_ka_rx(struct pim_msdp_peer *mp, int len)
|
||||||
|
|
||||||
static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
|
static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
|
||||||
{
|
{
|
||||||
|
struct access_list *acl;
|
||||||
int prefix_len;
|
int prefix_len;
|
||||||
pim_sgaddr sg;
|
pim_sgaddr sg;
|
||||||
struct listnode *peer_node;
|
struct listnode *peer_node;
|
||||||
|
@ -534,6 +637,19 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
|
||||||
if (PIM_DEBUG_MSDP_PACKETS) {
|
if (PIM_DEBUG_MSDP_PACKETS) {
|
||||||
zlog_debug(" sg %pSG", &sg);
|
zlog_debug(" sg %pSG", &sg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Filter incoming SA with configured access list. */
|
||||||
|
if (mp->acl_in) {
|
||||||
|
acl = access_list_lookup(AFI_IP, mp->acl_in);
|
||||||
|
if (msdp_access_list_apply(acl, &sg.src, &sg.grp) ==
|
||||||
|
FILTER_DENY) {
|
||||||
|
if (PIM_DEBUG_MSDP_EVENTS)
|
||||||
|
zlog_debug("MSDP peer %pI4 filter SA in (%pI4, %pI4)",
|
||||||
|
&mp->peer, &sg.src, &sg.grp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pim_msdp_sa_ref(mp->pim, mp, &sg, rp);
|
pim_msdp_sa_ref(mp->pim, mp, &sg, rp);
|
||||||
|
|
||||||
/* Forwards the SA to the peers that are not in the RPF to the RP nor in
|
/* Forwards the SA to the peers that are not in the RPF to the RP nor in
|
||||||
|
|
|
@ -57,5 +57,7 @@ void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa);
|
||||||
void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp);
|
void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp);
|
||||||
void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp,
|
void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp,
|
||||||
struct in_addr rp, pim_sgaddr sg);
|
struct in_addr rp, pim_sgaddr sg);
|
||||||
|
bool msdp_peer_sa_filter(const struct pim_msdp_peer *mp,
|
||||||
|
const struct pim_msdp_sa *sa);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -163,6 +163,20 @@ const struct frr_yang_module_info frr_pim_info = {
|
||||||
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify,
|
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/sa-filter-in",
|
||||||
|
.cbs = {
|
||||||
|
.modify = pim_msdp_peer_sa_filter_in_modify,
|
||||||
|
.destroy = pim_msdp_peer_sa_filter_in_destroy,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/sa-filter-out",
|
||||||
|
.cbs = {
|
||||||
|
.modify = pim_msdp_peer_sa_filter_out_modify,
|
||||||
|
.destroy = pim_msdp_peer_sa_filter_out_destroy,
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag",
|
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag",
|
||||||
.cbs = {
|
.cbs = {
|
||||||
|
|
|
@ -65,6 +65,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
|
||||||
struct nb_cb_destroy_args *args);
|
struct nb_cb_destroy_args *args);
|
||||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
|
||||||
struct nb_cb_modify_args *args);
|
struct nb_cb_modify_args *args);
|
||||||
|
int pim_msdp_peer_sa_filter_in_modify(struct nb_cb_modify_args *args);
|
||||||
|
int pim_msdp_peer_sa_filter_in_destroy(struct nb_cb_destroy_args *args);
|
||||||
|
int pim_msdp_peer_sa_filter_out_modify(struct nb_cb_modify_args *args);
|
||||||
|
int pim_msdp_peer_sa_filter_out_destroy(struct nb_cb_destroy_args *args);
|
||||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
|
||||||
struct nb_cb_create_args *args);
|
struct nb_cb_create_args *args);
|
||||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
|
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
|
||||||
|
|
|
@ -1286,6 +1286,94 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
|
||||||
}
|
}
|
||||||
#endif /* PIM_IPV != 6 */
|
#endif /* PIM_IPV != 6 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/sa-filter-in
|
||||||
|
*/
|
||||||
|
int pim_msdp_peer_sa_filter_in_modify(struct nb_cb_modify_args *args)
|
||||||
|
{
|
||||||
|
struct pim_msdp_peer *mp;
|
||||||
|
|
||||||
|
switch (args->event) {
|
||||||
|
case NB_EV_VALIDATE:
|
||||||
|
case NB_EV_PREPARE:
|
||||||
|
case NB_EV_ABORT:
|
||||||
|
/* NOTHING */
|
||||||
|
break;
|
||||||
|
case NB_EV_APPLY:
|
||||||
|
mp = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
XFREE(MTYPE_TMP, mp->acl_in);
|
||||||
|
mp->acl_in = XSTRDUP(MTYPE_TMP,
|
||||||
|
yang_dnode_get_string(args->dnode, NULL));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pim_msdp_peer_sa_filter_in_destroy(struct nb_cb_destroy_args *args)
|
||||||
|
{
|
||||||
|
struct pim_msdp_peer *mp;
|
||||||
|
|
||||||
|
switch (args->event) {
|
||||||
|
case NB_EV_VALIDATE:
|
||||||
|
case NB_EV_PREPARE:
|
||||||
|
case NB_EV_ABORT:
|
||||||
|
/* NOTHING */
|
||||||
|
break;
|
||||||
|
case NB_EV_APPLY:
|
||||||
|
mp = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
XFREE(MTYPE_TMP, mp->acl_in);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/sa-filter-out
|
||||||
|
*/
|
||||||
|
int pim_msdp_peer_sa_filter_out_modify(struct nb_cb_modify_args *args)
|
||||||
|
{
|
||||||
|
struct pim_msdp_peer *mp;
|
||||||
|
|
||||||
|
switch (args->event) {
|
||||||
|
case NB_EV_VALIDATE:
|
||||||
|
case NB_EV_PREPARE:
|
||||||
|
case NB_EV_ABORT:
|
||||||
|
/* NOTHING */
|
||||||
|
break;
|
||||||
|
case NB_EV_APPLY:
|
||||||
|
mp = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
XFREE(MTYPE_TMP, mp->acl_out);
|
||||||
|
mp->acl_out = XSTRDUP(MTYPE_TMP,
|
||||||
|
yang_dnode_get_string(args->dnode, NULL));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pim_msdp_peer_sa_filter_out_destroy(struct nb_cb_destroy_args *args)
|
||||||
|
{
|
||||||
|
struct pim_msdp_peer *mp;
|
||||||
|
|
||||||
|
switch (args->event) {
|
||||||
|
case NB_EV_VALIDATE:
|
||||||
|
case NB_EV_PREPARE:
|
||||||
|
case NB_EV_ABORT:
|
||||||
|
/* NOTHING */
|
||||||
|
break;
|
||||||
|
case NB_EV_APPLY:
|
||||||
|
mp = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
XFREE(MTYPE_TMP, mp->acl_out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue