pimd,yang: Expand rpf-lookup-mode command

Add options for group-list and source-list, both of which take a prefix list name.
The prefix list is used to determine the lookup mode for specific sources and/or groups.
Any number of lookup modes can be configured as long as the combination of group
and source list is unique.
A global lookup mode (empty group and source lists) is always added and defaults to mrib-then-urib
as it currently functions. The global lookup mode can be changed as it current exists with the command
`rpf-lookup-mode MODE`.
When determinig which mode to use, match source (and group if provided) against the lists, if they are set.
If a lookup does not specify a group, then only use lookup modes that do not have a group list defined.
A lookup by definition will have a source, so no special handling there.

Signed-off-by: Nathan Bahr <nbahr@atcorp.com>
This commit is contained in:
Nathan Bahr 2024-10-30 21:16:30 +00:00
parent 7e3d4048a6
commit 8b00575fbb
8 changed files with 120 additions and 32 deletions

View File

@ -8878,21 +8878,31 @@ done:
}
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")
"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, "./mcast-rpf-lookup", NB_OP_DESTROY, NULL);
else
nb_cli_enqueue_change(vty, "./mcast-rpf-lookup", NB_OP_MODIFY, mode);
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 = {

View File

@ -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
}
},
{

View File

@ -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);

View File

@ -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:
@ -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;
}

View File

@ -161,6 +161,20 @@ static struct pim_nexthop_cache_rib *pim_pnc_get_rib(struct pim_instance *pim,
return pnc_rib;
}
void pim_nht_change_rpf_mode(struct pim_instance *pim, const char *group_plist,
const char *source_plist, enum pim_rpf_lookup_mode mode)
{
/* TODO */
}
int pim_lookup_mode_write(struct pim_instance *pim, struct vty *vty)
{
/* TODO */
return 0;
}
bool pim_nht_pnc_is_valid(struct pim_instance *pim, struct pim_nexthop_cache *pnc)
{
switch (pim->rpf_mode) {

View File

@ -54,6 +54,13 @@ struct pnc_hash_walk_data {
struct interface *ifp;
};
/* Change the RPF lookup config, may trigger updates to RP's and Upstreams registered for matching cache entries */
void pim_nht_change_rpf_mode(struct pim_instance *pim, const char *group_plist,
const char *source_plist, enum pim_rpf_lookup_mode mode);
/* Write the rpf lookup mode configuration */
int pim_lookup_mode_write(struct pim_instance *pim, struct vty *vty);
/* Verify that we have nexthop information in the cache entry */
bool pim_nht_pnc_is_valid(struct pim_instance *pim, struct pim_nexthop_cache *pnc);

View File

@ -29,6 +29,7 @@
#include "pim_bfd.h"
#include "pim_bsm.h"
#include "pim_vxlan.h"
#include "pim_nht.h"
#include "pim6_mld.h"
int pim_debug_config_write(struct vty *vty)
@ -275,15 +276,7 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
}
}
if (pim->rpf_mode != MCAST_NO_CONFIG) {
++writes;
vty_out(vty, " rpf-lookup-mode %s\n",
pim->rpf_mode == MCAST_URIB_ONLY ? "urib-only"
: pim->rpf_mode == MCAST_MRIB_ONLY ? "mrib-only"
: pim->rpf_mode == MCAST_MIX_MRIB_FIRST ? "mrib-then-urib"
: pim->rpf_mode == MCAST_MIX_DISTANCE ? "lower-distance"
: "longer-prefix");
}
writes += pim_lookup_mode_write(pim, vty);
return writes;
}

View File

@ -202,11 +202,29 @@ module frr-pim {
description
"A grouping defining per address family pim global attributes";
leaf mcast-rpf-lookup {
type mcast-rpf-lookup-mode;
default "none";
list mcast-rpf-lookup {
key "group-list source-list";
description
"Multicast RPF lookup behavior.";
"RPF lookup modes.";
leaf group-list {
type plist-ref;
description
"Multicast group prefix list.";
}
leaf source-list {
type plist-ref;
description
"Unicast source address prefix list.";
}
leaf mode {
type mcast-rpf-lookup-mode;
default "none";
description
"Multicast RPF lookup behavior.";
}
}
leaf ecmp {