mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 05:27:16 +02:00
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:
parent
66434fc2ee
commit
b84493132c
|
@ -1803,6 +1803,34 @@ DEFPY (interface_no_ipv6_mld_last_member_query_interval,
|
|||
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,
|
||||
show_ipv6_pim_rp_cmd,
|
||||
"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);
|
||||
install_element(INTERFACE_NODE,
|
||||
&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_vrf_all_cmd);
|
||||
|
|
|
@ -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,
|
||||
debug_igmp_cmd,
|
||||
"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_ip_pim_boundary_acl_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
|
||||
install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
|
||||
|
|
|
@ -218,6 +218,7 @@ void pim_if_delete(struct interface *ifp)
|
|||
if (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);
|
||||
|
||||
ifp->info = NULL;
|
||||
|
|
|
@ -121,6 +121,7 @@ struct pim_interface {
|
|||
uint32_t pim_generation_id;
|
||||
uint16_t pim_propagation_delay_msec; /* config */
|
||||
uint16_t pim_override_interval_msec; /* config */
|
||||
char *nbr_plist;
|
||||
struct list *pim_neighbor_list; /* list of struct pim_neighbor */
|
||||
struct list *upstream_switch_list;
|
||||
struct pim_ifchannel_rb ifchannel_rb;
|
||||
|
|
|
@ -314,6 +314,13 @@ const struct frr_yang_module_info frr_pim_info = {
|
|||
.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",
|
||||
.cbs = {
|
||||
|
|
|
@ -110,6 +110,8 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mc
|
|||
struct nb_cb_modify_args *args);
|
||||
int lib_interface_pim_address_family_dr_priority_modify(
|
||||
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_destroy(struct nb_cb_destroy_args *args);
|
||||
int lib_interface_pim_address_family_pim_enable_modify(
|
||||
|
|
|
@ -2163,6 +2163,55 @@ int lib_interface_pim_address_family_hello_holdtime_destroy(
|
|||
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -149,6 +149,9 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len,
|
|||
uint32_t pim_msg_len = 0;
|
||||
uint16_t pim_checksum; /* received 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_msg_header *header;
|
||||
bool no_fwd;
|
||||
|
@ -205,6 +208,41 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len,
|
|||
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 */
|
||||
pim_checksum = header->checksum;
|
||||
|
||||
|
|
|
@ -477,6 +477,12 @@ int pim_config_write(struct vty *vty, int writes, struct interface *ifp,
|
|||
++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 (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
|
||||
vty_out(vty, " " PIM_AF_NAME " pim drpriority %u\n",
|
||||
|
|
|
@ -516,6 +516,12 @@ module frr-pim {
|
|||
"Hello holdtime";
|
||||
}
|
||||
|
||||
leaf neighbor-filter-prefix-list {
|
||||
type plist-ref;
|
||||
description
|
||||
"Prefix-List to filter allowed PIM neighbors.";
|
||||
}
|
||||
|
||||
container bfd {
|
||||
presence
|
||||
"Enable BFD support on the interface.";
|
||||
|
|
Loading…
Reference in a new issue