pimd: allow restricting neighbors per interface

Just filter incoming packets against a specified prefix-list.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2021-08-19 16:46:30 +02:00 committed by Rafael Zalamena
parent 66434fc2ee
commit b84493132c
10 changed files with 170 additions and 0 deletions

View file

@ -1803,6 +1803,34 @@ DEFPY (interface_no_ipv6_mld_last_member_query_interval,
return gm_process_no_last_member_query_interval_cmd(vty); return gm_process_no_last_member_query_interval_cmd(vty);
} }
DEFPY_YANG(interface_ipv6_pim_neighbor_prefix_list,
interface_ipv6_pim_neighbor_prefix_list_cmd,
"[no] ipv6 pim allowed-neighbors prefix-list PREFIXLIST6_NAME$prefix_list",
NO_STR
IP_STR
PIM_STR
"Restrict allowed PIM neighbors\n"
"Use prefix-list to filter neighbors\n"
"Name of a prefix-list\n")
{
if (no)
nb_cli_enqueue_change(vty, "./neighbor-filter-prefix-list", NB_OP_DESTROY, NULL);
else
nb_cli_enqueue_change(vty, "./neighbor-filter-prefix-list", NB_OP_MODIFY,
prefix_list);
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
}
ALIAS(interface_ipv6_pim_neighbor_prefix_list,
interface_no_ipv6_pim_neighbor_prefix_list_cmd,
"no ipv6 pim allowed-neighbors [prefix-list]",
NO_STR
IP_STR
PIM_STR
"Restrict allowed PIM neighbors\n"
"Use prefix-list to filter neighbors\n")
DEFPY (show_ipv6_pim_rp, DEFPY (show_ipv6_pim_rp,
show_ipv6_pim_rp_cmd, show_ipv6_pim_rp_cmd,
"show ipv6 pim [vrf NAME] rp-info [X:X::X:X/M$group] [json$json]", "show ipv6 pim [vrf NAME] rp-info [X:X::X:X/M$group] [json$json]",
@ -2973,6 +3001,8 @@ void pim_cmd_init(void)
&interface_ipv6_mld_last_member_query_interval_cmd); &interface_ipv6_mld_last_member_query_interval_cmd);
install_element(INTERFACE_NODE, install_element(INTERFACE_NODE,
&interface_no_ipv6_mld_last_member_query_interval_cmd); &interface_no_ipv6_mld_last_member_query_interval_cmd);
install_element(INTERFACE_NODE, &interface_ipv6_pim_neighbor_prefix_list_cmd);
install_element(INTERFACE_NODE, &interface_no_ipv6_pim_neighbor_prefix_list_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_rp_cmd); install_element(VIEW_NODE, &show_ipv6_pim_rp_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_rp_vrf_all_cmd); install_element(VIEW_NODE, &show_ipv6_pim_rp_vrf_all_cmd);

View file

@ -6035,6 +6035,34 @@ DEFPY (interface_ip_igmp_proxy,
} }
DEFPY_YANG(interface_ip_pim_neighbor_prefix_list,
interface_ip_pim_neighbor_prefix_list_cmd,
"[no] ip pim allowed-neighbors prefix-list WORD",
NO_STR
IP_STR
"pim multicast routing\n"
"Restrict allowed PIM neighbors\n"
"Use prefix-list to filter neighbors\n"
"Name of a prefix-list\n")
{
if (no)
nb_cli_enqueue_change(vty, "./neighbor-filter-prefix-list", NB_OP_DESTROY, NULL);
else
nb_cli_enqueue_change(vty, "./neighbor-filter-prefix-list", NB_OP_MODIFY,
prefix_list);
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
}
ALIAS (interface_ip_pim_neighbor_prefix_list,
interface_no_ip_pim_neighbor_prefix_list_cmd,
"no ip pim allowed-neighbors [prefix-list]",
NO_STR
IP_STR
"pim multicast routing\n"
"Restrict allowed PIM neighbors\n"
"Use prefix-list to filter neighbors\n")
DEFUN (debug_igmp, DEFUN (debug_igmp,
debug_igmp_cmd, debug_igmp_cmd,
"debug igmp", "debug igmp",
@ -9169,6 +9197,8 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd); install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_boundary_acl_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_boundary_acl_cmd);
install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd); install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_neighbor_prefix_list_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_pim_neighbor_prefix_list_cmd);
// Static mroutes NEB // Static mroutes NEB
install_element(INTERFACE_NODE, &interface_ip_mroute_cmd); install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);

View file

@ -218,6 +218,7 @@ void pim_if_delete(struct interface *ifp)
if (pim_ifp->bfd_config.profile) if (pim_ifp->bfd_config.profile)
XFREE(MTYPE_TMP, pim_ifp->bfd_config.profile); XFREE(MTYPE_TMP, pim_ifp->bfd_config.profile);
XFREE(MTYPE_PIM_PLIST_NAME, pim_ifp->nbr_plist);
XFREE(MTYPE_PIM_INTERFACE, pim_ifp); XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
ifp->info = NULL; ifp->info = NULL;

View file

@ -121,6 +121,7 @@ struct pim_interface {
uint32_t pim_generation_id; uint32_t pim_generation_id;
uint16_t pim_propagation_delay_msec; /* config */ uint16_t pim_propagation_delay_msec; /* config */
uint16_t pim_override_interval_msec; /* config */ uint16_t pim_override_interval_msec; /* config */
char *nbr_plist;
struct list *pim_neighbor_list; /* list of struct pim_neighbor */ struct list *pim_neighbor_list; /* list of struct pim_neighbor */
struct list *upstream_switch_list; struct list *upstream_switch_list;
struct pim_ifchannel_rb ifchannel_rb; struct pim_ifchannel_rb ifchannel_rb;

View file

@ -314,6 +314,13 @@ const struct frr_yang_module_info frr_pim_info = {
.destroy = lib_interface_pim_address_family_hello_holdtime_destroy, .destroy = lib_interface_pim_address_family_hello_holdtime_destroy,
} }
}, },
{
.xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/neighbor-filter-prefix-list",
.cbs = {
.modify = lib_interface_pim_address_family_nbr_plist_modify,
.destroy = lib_interface_pim_address_family_nbr_plist_destroy,
}
},
{ {
.xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/bfd", .xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/bfd",
.cbs = { .cbs = {

View file

@ -110,6 +110,8 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mc
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int lib_interface_pim_address_family_dr_priority_modify( int lib_interface_pim_address_family_dr_priority_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int lib_interface_pim_address_family_nbr_plist_modify(struct nb_cb_modify_args *args);
int lib_interface_pim_address_family_nbr_plist_destroy(struct nb_cb_destroy_args *args);
int lib_interface_pim_address_family_create(struct nb_cb_create_args *args); int lib_interface_pim_address_family_create(struct nb_cb_create_args *args);
int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args *args); int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args *args);
int lib_interface_pim_address_family_pim_enable_modify( int lib_interface_pim_address_family_pim_enable_modify(

View file

@ -2163,6 +2163,55 @@ int lib_interface_pim_address_family_hello_holdtime_destroy(
return NB_OK; return NB_OK;
} }
/*
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/neighbor-filter-prefix-list
*/
int lib_interface_pim_address_family_nbr_plist_modify(struct nb_cb_modify_args *args)
{
struct interface *ifp;
struct pim_interface *pim_ifp;
const char *plist;
plist = yang_dnode_get_string(args->dnode, NULL);
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_ABORT:
case NB_EV_PREPARE:
break;
case NB_EV_APPLY:
ifp = nb_running_get_entry(args->dnode, NULL, true);
pim_ifp = ifp->info;
XFREE(MTYPE_PIM_PLIST_NAME, pim_ifp->nbr_plist);
pim_ifp->nbr_plist = XSTRDUP(MTYPE_PIM_PLIST_NAME, plist);
break;
}
return NB_OK;
}
int lib_interface_pim_address_family_nbr_plist_destroy(struct nb_cb_destroy_args *args)
{
struct interface *ifp;
struct pim_interface *pim_ifp;
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_ABORT:
case NB_EV_PREPARE:
break;
case NB_EV_APPLY:
ifp = nb_running_get_entry(args->dnode, NULL, true);
pim_ifp = ifp->info;
XFREE(MTYPE_PIM_PLIST_NAME, pim_ifp->nbr_plist);
break;
}
return NB_OK;
}
/* /*
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
*/ */

View file

@ -149,6 +149,9 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len,
uint32_t pim_msg_len = 0; uint32_t pim_msg_len = 0;
uint16_t pim_checksum; /* received checksum */ uint16_t pim_checksum; /* received checksum */
uint16_t checksum; /* computed checksum */ uint16_t checksum; /* computed checksum */
struct pim_interface *pim_ifp = ifp->info;
struct prefix src_prefix;
struct prefix_list *nbr_plist = NULL;
struct pim_neighbor *neigh; struct pim_neighbor *neigh;
struct pim_msg_header *header; struct pim_msg_header *header;
bool no_fwd; bool no_fwd;
@ -205,6 +208,41 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len,
return -1; return -1;
} }
switch (header->type) {
case PIM_MSG_TYPE_HELLO:
case PIM_MSG_TYPE_JOIN_PRUNE:
case PIM_MSG_TYPE_ASSERT:
if (pim_ifp == NULL || pim_ifp->nbr_plist == NULL)
break;
nbr_plist = prefix_list_lookup(PIM_AFI, pim_ifp->nbr_plist);
#if PIM_IPV == 4
src_prefix.family = AF_INET;
src_prefix.prefixlen = IPV4_MAX_BITLEN;
src_prefix.u.prefix4 = sg.src;
#else
src_prefix.family = AF_INET6;
src_prefix.prefixlen = IPV6_MAX_BITLEN;
src_prefix.u.prefix6 = sg.src;
#endif
if (nbr_plist &&
prefix_list_apply_ext(nbr_plist, NULL, &src_prefix, true) == PREFIX_PERMIT)
break;
#if PIM_IPV == 4
if (PIM_DEBUG_PIM_PACKETS)
zlog_debug("neighbor filter rejects packet %pI4 -> %pI4 on %s",
&ip_hdr->ip_src, &ip_hdr->ip_dst, ifp->name);
#else
if (PIM_DEBUG_PIM_PACKETS)
zlog_debug("neighbor filter rejects packet %pI6 -> %pI6 on %s", &sg.src,
&sg.grp, ifp->name);
#endif
return -1;
}
/* save received checksum */ /* save received checksum */
pim_checksum = header->checksum; pim_checksum = header->checksum;

View file

@ -477,6 +477,12 @@ int pim_config_write(struct vty *vty, int writes, struct interface *ifp,
++writes; ++writes;
} }
if (pim_ifp->nbr_plist) {
vty_out(vty, " " PIM_AF_NAME " pim allowed-neighbors prefix-list %s\n",
pim_ifp->nbr_plist);
++writes;
}
/* IF ip pim drpriority */ /* IF ip pim drpriority */
if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) { if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
vty_out(vty, " " PIM_AF_NAME " pim drpriority %u\n", vty_out(vty, " " PIM_AF_NAME " pim drpriority %u\n",

View file

@ -516,6 +516,12 @@ module frr-pim {
"Hello holdtime"; "Hello holdtime";
} }
leaf neighbor-filter-prefix-list {
type plist-ref;
description
"Prefix-List to filter allowed PIM neighbors.";
}
container bfd { container bfd {
presence presence
"Enable BFD support on the interface."; "Enable BFD support on the interface.";