Just filter incoming packets against a specified prefix-list.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
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]",
&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);
}
+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",
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);
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;
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;
.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 = {
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(
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
*/
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;
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;
++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",
"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.";