Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pimd: filter neighbors by address #17914

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/user/pim.rst
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,10 @@ is in a vrf, enter the interface command with the vrf keyword at the end.
reports on the interface. Refer to the next `ip igmp` command for IGMP
management.

.. clicmd:: ip pim allowed-neighbors prefix-list PREFIX_LIST

Only establish sessions with PIM neighbors allowed by the prefix-list.

.. clicmd:: ip pim use-source A.B.C.D

If you have multiple addresses configured on a particular interface
Expand Down
4 changes: 4 additions & 0 deletions doc/user/pimv6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ is in a vrf, enter the interface command with the vrf keyword at the end.
reports on the interface. Refer to the next ``ipv6 mld`` command for MLD
management.

.. clicmd:: ipv6 pim allowed-neighbors prefix-list PREFIX_LIST

Only establish sessions with PIM neighbors allowed by the prefix-list.

.. clicmd:: ipv6 pim use-source X:X::X:X

If you have multiple addresses configured on a particular interface
Expand Down
30 changes: 30 additions & 0 deletions pimd/pim6_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1753,6 +1753,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]",
Expand Down Expand Up @@ -2893,6 +2921,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);
Expand Down
30 changes: 30 additions & 0 deletions pimd/pim_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -5985,6 +5985,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",
Expand Down Expand Up @@ -9116,6 +9144,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);
Expand Down
1 change: 1 addition & 0 deletions pimd/pim_iface.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,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;
Expand Down
1 change: 1 addition & 0 deletions pimd/pim_iface.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,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;
Expand Down
7 changes: 7 additions & 0 deletions pimd/pim_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
2 changes: 2 additions & 0 deletions pimd/pim_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
49 changes: 49 additions & 0 deletions pimd/pim_nb_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
38 changes: 38 additions & 0 deletions pimd/pim_pim.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
6 changes: 6 additions & 0 deletions pimd/pim_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,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",
Expand Down
Empty file.
53 changes: 53 additions & 0 deletions tests/topotests/multicast_features/r1/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
log commands
!
!ip prefix-list pim-eth0-neighbors permit 192.168.2.0/24
!ipv6 prefix-list pimv6-eth0-neighbors permit 2001:db8:2::/64
!
interface r1-eth0
ip address 192.168.1.1/24
ip pim
ipv6 address 2001:db8:1::1/64
ipv6 pim
!
interface r1-eth1
ip address 192.168.2.1/24
ip pim
ip pim allowed-neighbors prefix-list pim-eth0-neighbors
ipv6 address 2001:db8:2::1/64
ipv6 pim
ipv6 pim allowed-neighbors prefix-list pimv6-eth0-neighbors
!
interface r1-eth2
ip address 192.168.100.1/24
ip igmp
ip pim passive
ipv6 address 2001:db8:ffff::1/128
ipv6 mld
ipv6 pim passive
!
interface lo
ip address 10.254.254.1/32
ip pim
ip pim use-source 10.254.254.1
!
router bgp 65100
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.1.2 remote-as 65200
neighbor 192.168.2.2 remote-as 65300
!
address-family ipv4 unicast
redistribute connected
exit-address-family
address-family ipv6 unicast
redistribute connected
neighbor 192.168.1.2 activate
neighbor 192.168.2.2 activate
exit-address-family
!
router pim
rp 10.254.254.1
!
router pim6
rp 2001:db8:ffff::1
!
37 changes: 37 additions & 0 deletions tests/topotests/multicast_features/r2/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
log commands
!
interface r2-eth0
ip address 192.168.1.2/24
ip pim
ipv6 address 2001:db8:1::2/64
ipv6 pim
!
interface r2-eth1
ip address 192.168.101.1/24
ip igmp
ip pim passive
!
interface lo
ip address 10.254.254.2/32
ipv6 address 2001:db8:ffff::2/128
ipv6 pim passive
!
router bgp 65200
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.1.1 remote-as 65100
!
address-family ipv4 unicast
redistribute connected
exit-address-family
address-family ipv6 unicast
redistribute connected
neighbor 192.168.1.1 activate
exit-address-family
!
router pim
rp 10.254.254.2
!
router pim6
rp 2001:db8:ffff::2
!
34 changes: 34 additions & 0 deletions tests/topotests/multicast_features/r3/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
log commands
!
interface r3-eth0
ip address 192.168.2.2/24
ip pim
ipv6 address 2001:db8:2::2/64
ipv6 pim
!
interface lo
ip address 10.254.254.3/32
ip pim
ip pim use-source 10.254.254.3
ipv6 address 2001:db8:ffff::3/128
ipv6 pim passive
!
router bgp 65300
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.2.1 remote-as 65100
!
address-family ipv4 unicast
redistribute connected
exit-address-family
address-family ipv6 unicast
redistribute connected
neighbor 192.168.2.1 activate
exit-address-family
!
router pim
rp 10.254.254.1
!
router pim6
rp 2001:db8:ffff::1
!
Loading
Loading