summaryrefslogtreecommitdiff
path: root/pimd
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2021-08-19 16:46:30 +0200
committerRafael Zalamena <rzalamena@opensourcerouting.org>2025-02-19 09:49:06 -0300
commitb84493132c2470fee3daf1be7262e88b86265e47 (patch)
treefa14914c9be00e65439946c0881583b27247c548 /pimd
parent66434fc2eea13c83b60f46212e85d33d03ec9c3d (diff)
pimd: allow restricting neighbors per interface
Just filter incoming packets against a specified prefix-list. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim6_cmd.c30
-rw-r--r--pimd/pim_cmd.c30
-rw-r--r--pimd/pim_iface.c1
-rw-r--r--pimd/pim_iface.h1
-rw-r--r--pimd/pim_nb.c7
-rw-r--r--pimd/pim_nb.h2
-rw-r--r--pimd/pim_nb_config.c49
-rw-r--r--pimd/pim_pim.c38
-rw-r--r--pimd/pim_vty.c6
9 files changed, 164 insertions, 0 deletions
diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c
index 50357ca1d0..8297911828 100644
--- a/pimd/pim6_cmd.c
+++ b/pimd/pim6_cmd.c
@@ -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);
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 4ad75a21e7..f838c401e3 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -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);
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 8ec51ddc39..3408574cae 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -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;
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index 606fda6721..b0befcfcba 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -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;
diff --git a/pimd/pim_nb.c b/pimd/pim_nb.c
index 3cd5c0f4e5..9a2fc5f3cd 100644
--- a/pimd/pim_nb.c
+++ b/pimd/pim_nb.c
@@ -315,6 +315,13 @@ const struct frr_yang_module_info frr_pim_info = {
}
},
{
+ .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 = {
.create = lib_interface_pim_address_family_bfd_create,
diff --git a/pimd/pim_nb.h b/pimd/pim_nb.h
index ce7b5e43af..e9faf875b0 100644
--- a/pimd/pim_nb.h
+++ b/pimd/pim_nb.h
@@ -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(
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c
index d671ea3b65..1be5e9cb88 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -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
*/
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index a41bbacea7..fb78e39022 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -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;
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index b2525998a6..e37703be2b 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -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",