]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: allow restricting neighbors per interface
authorDavid Lamparter <equinox@opensourcerouting.org>
Thu, 19 Aug 2021 14:46:30 +0000 (16:46 +0200)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Wed, 19 Feb 2025 12:49:06 +0000 (09:49 -0300)
Just filter incoming packets against a specified prefix-list.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
pimd/pim6_cmd.c
pimd/pim_cmd.c
pimd/pim_iface.c
pimd/pim_iface.h
pimd/pim_nb.c
pimd/pim_nb.h
pimd/pim_nb_config.c
pimd/pim_pim.c
pimd/pim_vty.c
yang/frr-pim.yang

index 50357ca1d06bc8bc8432e4c386248993438b716e..8297911828cb73033f14f41e31346b3a81fb5e3c 100644 (file)
@@ -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);
index 4ad75a21e7f749e06da561eb6a393e3cfd8296b0..f838c401e3f91d80db354c4f85711665374ad9be 100644 (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,
        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);
index 8ec51ddc39f9e5b72edd00f330ecf8f406e26174..3408574cae5bc743f1ae04e503e46de0d035c994 100644 (file)
@@ -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;
index 606fda6721269f175412a53d7901d97a39a614ce..b0befcfcba43cdafc59e5d9afe4c484f24d94a78 100644 (file)
@@ -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;
index 3cd5c0f4e586e4a2a8d9bacb9bc844c74aa15dc1..9a2fc5f3cd71c6ece3bcbc1bfa6a1b983820fec4 100644 (file)
@@ -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 = {
index ce7b5e43af3cb1039567079a859cd3b9cdfb4783..e9faf875b060ce220dddc0a02d71d2e00b7d0b90 100644 (file)
@@ -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(
index d671ea3b65125b649bcbfc960e26d4d22939922f..1be5e9cb88eef831506a6c1e13dba21a808a0f2b 100644 (file)
@@ -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
  */
index a41bbacea79946e431d1515acfc35ba690998031..fb78e390229b451243759094b697906c31f559b8 100644 (file)
@@ -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;
 
index b2525998a6f135364cdff231311b2435df004bf8..e37703be2b181086d506242159a99963df9d5492 100644 (file)
@@ -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",
index 6b6870f666a3482abcc6e014d97ad9f8891ea07f..e0d8800f3ecfce5e983f28b4b479df53763cb6c4 100644 (file)
@@ -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.";