Skip to content

Commit

Permalink
Merge pull request FRRouting#17776 from nabahr/group-rpf-mode
Browse files Browse the repository at this point in the history
PIMD: RPF lookup mode per-group, per-source
  • Loading branch information
donaldsharp authored Jan 15, 2025
2 parents 5e41d30 + f75ec46 commit 5867c32
Show file tree
Hide file tree
Showing 21 changed files with 1,491 additions and 147 deletions.
14 changes: 13 additions & 1 deletion doc/user/pim.rst
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ PIM Routers
never do SM over. This command is vrf aware, to configure for a vrf, specify
the vrf in the router pim block.

.. clicmd:: rpf-lookup-mode MODE
.. clicmd:: rpf-lookup-mode MODE [group-list PREFIX_LIST] [source-list PREFIX_LIST]

MODE sets the method used to perform RPF lookups. Supported modes:

Expand Down Expand Up @@ -246,6 +246,18 @@ PIM Routers
configured to make the configuration immune against possible changes in
what the default behavior is.

If a group and/or source prefix list is provided, then the RPF lookup mode
will only apply to source, group addresses that match the given prefix list(s).
Not all RPF lookups have a valid group address when performing a lookup, e.g. RPF
to an RP only does a lookup to the RP address and has no specific group.
Lookups that do not have a specific group will only use lookup modes that do not
specify a group-list.
A global rpf lookup mode that does not have a group or source list is always installed
and, as documented above, uses the ``mrib-then-urib`` mode by default.
This can be changed with an rpf-lookup-mode MODE that does not specify group or source lists.
There can be any number of rpf lookup modes, as long as the combination of group and source
list is unique.

.. warning::

Unreachable routes do not receive special treatment and do not cause
Expand Down
2 changes: 1 addition & 1 deletion pimd/pim_bsr_rpdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ void pim_crp_nht_update(struct pim_instance *pim, struct pim_nexthop_cache *pnc)
rp = bsr_crp_rps_find(scope->ebsr_rps, &ref);
assertf(rp, "addr=%pPA", &ref.addr);

ok = pim_nht_pnc_is_valid(pim, pnc);
ok = pim_nht_pnc_is_valid(pim, pnc, PIMADDR_ANY);
if (ok == rp->nht_ok)
return;

Expand Down
28 changes: 19 additions & 9 deletions pimd/pim_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3296,7 +3296,7 @@ DEFUN (show_ip_rib,
return CMD_WARNING;
}

if (!pim_nht_lookup(vrf->info, &nexthop, addr, 0)) {
if (!pim_nht_lookup(vrf->info, &nexthop, addr, PIMADDR_ANY, false)) {
vty_out(vty,
"Failure querying RIB nexthop for unicast address %s\n",
addr_str);
Expand Down Expand Up @@ -8878,21 +8878,31 @@ DEFPY_ATTR(ip_pim_mlag,
}

DEFPY_YANG(pim_rpf_lookup_mode, pim_rpf_lookup_mode_cmd,
"[no] rpf-lookup-mode ![urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix]$mode",
"[no] rpf-lookup-mode\
![urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix]$mode\
[{group-list PREFIX_LIST$grp_list|source-list PREFIX_LIST$src_list}]",
NO_STR
"RPF lookup behavior\n"
"Lookup in unicast RIB only\n"
"Lookup in multicast RIB only\n"
"Try multicast RIB first, fall back to unicast RIB\n"
"Lookup both, use entry with lower distance\n"
"Lookup both, use entry with longer prefix\n")
{
if (no)
nb_cli_enqueue_change(vty, "./mcast-rpf-lookup", NB_OP_DESTROY, NULL);
else
nb_cli_enqueue_change(vty, "./mcast-rpf-lookup", NB_OP_MODIFY, mode);
"Lookup both, use entry with longer prefix\n"
"Set a specific mode matching group\n"
"Multicast group prefix list\n"
"Set a specific mode matching source address\n"
"Source address prefix list\n")
{
if (no) {
nb_cli_enqueue_change(vty, "./mode", NB_OP_DESTROY, NULL);
nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
} else {
nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
nb_cli_enqueue_change(vty, "./mode", NB_OP_MODIFY, mode);
}

return nb_cli_apply_changes(vty, NULL);
return nb_cli_apply_changes(vty, "./mcast-rpf-lookup[group-list='%s'][source-list='%s']",
(grp_list ? grp_list : ""), (src_list ? src_list : ""));
}

struct cmd_node pim_node = {
Expand Down
13 changes: 9 additions & 4 deletions pimd/pim_igmp_mtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ static bool mtrace_fwd_info_weak(struct pim_instance *pim,

memset(&nexthop, 0, sizeof(nexthop));

if (!pim_nht_lookup(pim, &nexthop, mtracep->src_addr, 1)) {
/* TODO Is there any valid group address to use for lookup? */
if (!pim_nht_lookup(pim, &nexthop, mtracep->src_addr, PIMADDR_ANY, true)) {
if (PIM_DEBUG_MTRACE)
zlog_debug("mtrace not found neighbor");
return false;
Expand Down Expand Up @@ -354,7 +355,8 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr,

if (interface == NULL) {
memset(&nexthop, 0, sizeof(nexthop));
if (!pim_nht_lookup(pim, &nexthop, ip_hdr->ip_dst, 0)) {
/* TODO Is there any valid group address to use for lookup? */
if (!pim_nht_lookup(pim, &nexthop, ip_hdr->ip_dst, PIMADDR_ANY, false)) {
if (PIM_DEBUG_MTRACE)
zlog_debug(
"Dropping mtrace packet, no route to destination");
Expand Down Expand Up @@ -535,8 +537,11 @@ static int mtrace_send_response(struct pim_instance *pim,
zlog_debug("mtrace response to RP");
} else {
memset(&nexthop, 0, sizeof(nexthop));
/* TODO: should use unicast rib lookup */
if (!pim_nht_lookup(pim, &nexthop, mtracep->rsp_addr, 1)) {
/* TODO: should use unicast rib lookup
* NEB 10/30/24 - Not sure why this needs the unicast rib...right now it will look up per the rpf mode
* Are any of the igmp_mtrace addresses a valid group address to use for lookups??
*/
if (!pim_nht_lookup(pim, &nexthop, mtracep->rsp_addr, PIMADDR_ANY, true)) {
if (PIM_DEBUG_MTRACE)
zlog_debug(
"Dropped response qid=%ud, no route to response address",
Expand Down
3 changes: 2 additions & 1 deletion pimd/pim_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "pim_upstream.h"
#include "pim_mroute.h"
#include "pim_autorp.h"
#include "pim_nht.h"

enum pim_spt_switchover {
PIM_SPT_IMMEDIATE,
Expand Down Expand Up @@ -116,7 +117,7 @@ struct pim_instance {
char *register_plist;

struct hash *nht_hash;
enum pim_rpf_lookup_mode rpf_mode;
struct pim_lookup_mode_head rpf_mode;

void *ssm_info; /* per-vrf SSM configuration */

Expand Down
6 changes: 4 additions & 2 deletions pimd/pim_mroute.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,8 @@ int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp, const char *buf,
* setting the SPTBIT to true
*/
if (!(pim_addr_is_any(up->upstream_register)) &&
pim_nht_lookup(pim_ifp->pim, &source, up->upstream_register, 0)) {
pim_nht_lookup(pim_ifp->pim, &source, up->upstream_register, up->sg.grp,
false)) {
pim_register_stop_send(source.interface, &sg,
pim_ifp->primary_address,
up->upstream_register);
Expand All @@ -580,7 +581,8 @@ int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp, const char *buf,
__func__);
} else {
if (I_am_RP(pim_ifp->pim, up->sg.grp)) {
if (pim_nht_lookup(pim_ifp->pim, &source, up->upstream_register, 0))
if (pim_nht_lookup(pim_ifp->pim, &source, up->upstream_register,
up->sg.grp, false))
pim_register_stop_send(
source.interface, &sg,
pim_ifp->primary_address,
Expand Down
2 changes: 1 addition & 1 deletion pimd/pim_msdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ bool pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp)
}

/* check if the MSDP peer is the nexthop for the RP */
if (pim_nht_lookup(mp->pim, &nexthop, rp, 0) &&
if (pim_nht_lookup(mp->pim, &nexthop, rp, PIMADDR_ANY, false) &&
nexthop.mrib_nexthop_addr.s_addr == mp->peer.s_addr) {
return true;
}
Expand Down
9 changes: 8 additions & 1 deletion pimd/pim_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,14 @@ const struct frr_yang_module_info frr_pim_info = {
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mcast-rpf-lookup",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_modify,
.create = routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mcast-rpf-lookup/mode",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_mode_modify
}
},
{
Expand Down
6 changes: 5 additions & 1 deletion pimd/pim_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_re
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_modify(
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_mode_modify(
struct nb_cb_modify_args *args);
int lib_interface_pim_address_family_dr_priority_modify(
struct nb_cb_modify_args *args);
Expand Down
55 changes: 45 additions & 10 deletions pimd/pim_nb_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1895,12 +1895,25 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_re
/*
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mcast-rpf-lookup
*/
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_modify(
struct nb_cb_modify_args *args)
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_create(
struct nb_cb_create_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
break;
}

return NB_OK;
}

int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_destroy(
struct nb_cb_destroy_args *args)
{
struct vrf *vrf;
struct pim_instance *pim;
enum pim_rpf_lookup_mode old_mode;

switch (args->event) {
case NB_EV_VALIDATE:
Expand All @@ -1910,15 +1923,37 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mc
case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
old_mode = pim->rpf_mode;
pim->rpf_mode = yang_dnode_get_enum(args->dnode, NULL);
pim_nht_change_rpf_mode(pim, yang_dnode_get_string(args->dnode, "group-list"),
yang_dnode_get_string(args->dnode, "source-list"),
MCAST_NO_CONFIG);
break;
}

if (pim->rpf_mode != old_mode &&
/* MCAST_MIX_MRIB_FIRST is the default if not configured */
(old_mode != MCAST_NO_CONFIG && pim->rpf_mode != MCAST_MIX_MRIB_FIRST)) {
pim_nht_mode_changed(pim);
}
return NB_OK;
}

/*
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mcast-rpf-lookup/mode
*/
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mcast_rpf_lookup_mode_modify(
struct nb_cb_modify_args *args)
{
struct vrf *vrf;
struct pim_instance *pim;
enum pim_rpf_lookup_mode mode = MCAST_NO_CONFIG;

switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;

case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
mode = yang_dnode_get_enum(args->dnode, NULL);
pim_nht_change_rpf_mode(pim, yang_dnode_get_string(args->dnode, "../group-list"),
yang_dnode_get_string(args->dnode, "../source-list"), mode);
break;
}

Expand Down
Loading

0 comments on commit 5867c32

Please sign in to comment.