Add rpf-lookup-mode MODE vty command under router pim block.
Including NB piping and config write. Using the mode still pending.
Signed-off-by: Nathan Bahr <nbahr@atcorp.com>
return ret;
}
+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_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);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
struct cmd_node pim_node = {
.name = "pim",
.node = PIM_NODE,
install_element(PIM_NODE, &pim_bsr_candidate_rp_group_cmd);
install_element(PIM_NODE, &pim_bsr_candidate_bsr_cmd);
+ install_element(PIM_NODE, &pim_rpf_lookup_mode_cmd);
+
install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
char *register_plist;
struct hash *rpf_hash;
+ enum pim_rpf_lookup_mode rpf_mode;
void *ssm_info; /* per-vrf SSM configuration */
.destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy,
}
},
+ {
+ .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,
+ }
+ },
{
.xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family",
.cbs = {
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(
+ 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_create(struct nb_cb_create_args *args);
return NB_OK;
}
+/*
+ * 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)
+{
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ enum pim_rpf_lookup_mode old_mode;
+
+ 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;
+ old_mode = pim->rpf_mode;
+ pim->rpf_mode = yang_dnode_get_enum(args->dnode, NULL);
+
+ /* TODO: Signal to redo lookups? */
+ break;
+ }
+
+ return NB_OK;
+}
+
/*
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family
*/
#ifdef PIM_ENFORCE_LOOPFREE_MFC
iif = nb_running_get_entry(args->dnode, NULL, false);
- if (!iif) {
+ if (!iif)
return NB_OK;
- }
pim_iifp = iif->info;
pim = pim_iifp->pim;
enum pim_rpf_result { PIM_RPF_OK = 0, PIM_RPF_CHANGED, PIM_RPF_FAILURE };
+/* RPF lookup behaviour */
+enum pim_rpf_lookup_mode {
+ MCAST_NO_CONFIG = 0, /* MIX_MRIB_FIRST, but no show in config write */
+ MCAST_MRIB_ONLY, /* MRIB only */
+ MCAST_URIB_ONLY, /* URIB only */
+ MCAST_MIX_MRIB_FIRST, /* MRIB, if nothing at all then URIB */
+ MCAST_MIX_DISTANCE, /* MRIB & URIB, lower distance wins */
+ MCAST_MIX_PFXLEN, /* MRIB & URIB, longer prefix wins */
+ /* on equal value, MRIB wins for last 2 */
+};
+
struct pim_upstream;
unsigned int pim_rpf_hash_key(const void *arg);
}
}
+ 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");
+ }
+
return writes;
}
type string;
}
+ /*
+ * Multicast RPF mode configurable type
+ */
+
+ typedef mcast-rpf-lookup-mode {
+ type enumeration {
+ enum "none" {
+ value 0;
+ description
+ "No mode set.";
+ }
+ enum "mrib-only" {
+ value 1;
+ description
+ "Lookup in unicast RIB only.";
+ }
+ enum "urib-only" {
+ value 2;
+ description
+ "Lookup in multicast RIB only.";
+ }
+ enum "mrib-then-urib" {
+ value 3;
+ description
+ "Try multicast RIB first, fall back to unicast RIB.";
+ }
+ enum "lower-distance" {
+ value 4;
+ description
+ "Lookup both unicast and mcast, use entry with lower distance.";
+ }
+ enum "longer-prefix" {
+ value 5;
+ description
+ "Lookup both unicast and mcast, use entry with longer prefix.";
+ }
+ }
+ description
+ "Multicast RPF lookup behavior";
+ }
+
/*
* Groupings
*/
description
"A grouping defining per address family pim global attributes";
+ leaf mcast-rpf-lookup {
+ type mcast-rpf-lookup-mode;
+ default "none";
+ description
+ "Multicast RPF lookup behavior.";
+ }
+
leaf ecmp {
type boolean;
default "false";
description
"Enable PIM ECMP.";
}
-
+
leaf ecmp-rebalance {
type boolean;
default "false";
description
"Enable PIM ECMP Rebalance.";
}
-
+
leaf keep-alive-timer {
type uint16 {
range "1..max";
description
"Keep alive Timer in seconds.";
}
-
+
leaf rp-keep-alive-timer {
type uint16 {
range "1..max";