From a7b2b1e29862f82d8a68bda2c72a460cd26aa5a8 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 5 Apr 2017 12:08:53 -0400 Subject: [PATCH] pimd: Add the ability to never SPT switchover Add the ability to allow pim to determine if we should allow spt-switchover or not on the LHR. Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 31 +++++++++++++++++++++++++++++++ pimd/pim_ifchannel.c | 3 ++- pimd/pim_upstream.c | 36 ++++++++++++++++++++++++++++++++++++ pimd/pim_upstream.h | 3 +++ pimd/pim_vty.c | 6 ++++++ pimd/pimd.c | 1 + pimd/pimd.h | 8 ++++++++ 7 files changed, 87 insertions(+), 1 deletion(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 4b12f48314..de2b7cbba6 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -3416,6 +3416,35 @@ pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const cha return CMD_SUCCESS; } +DEFUN (ip_pim_spt_switchover_infinity, + ip_pim_spt_switchover_infinity_cmd, + "ip pim spt-switchover infinity-and-beyond", + IP_STR + PIM_STR + "SPT-Switchover\n" + "Never switch to SPT Tree\n") +{ + pimg->spt_switchover = PIM_SPT_INFINITY; + + pim_upstream_remove_lhr_star_pimreg(); + return CMD_SUCCESS; +} + +DEFUN (no_ip_pim_spt_switchover_infinity, + no_ip_pim_spt_switchover_infinity_cmd, + "no ip pim spt-switchover infinity-and-beyond", + NO_STR + IP_STR + PIM_STR + "SPT_Switchover\n" + "Never switch to SPT Tree\n") +{ + pimg->spt_switchover = PIM_SPT_IMMEDIATE; + + pim_upstream_add_lhr_star_pimreg(); + return CMD_SUCCESS; +} + DEFUN (ip_pim_joinprune_time, ip_pim_joinprune_time_cmd, "ip pim join-prune-interval <60-600>", @@ -6187,6 +6216,8 @@ void pim_cmd_init() install_element (CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd); install_element (CONFIG_NODE, &ip_pim_register_suppress_cmd); install_element (CONFIG_NODE, &no_ip_pim_register_suppress_cmd); + install_element (CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd); + install_element (CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd); install_element (CONFIG_NODE, &ip_pim_joinprune_time_cmd); install_element (CONFIG_NODE, &no_ip_pim_joinprune_time_cmd); install_element (CONFIG_NODE, &ip_pim_keep_alive_cmd); diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index e1697960e4..ebd36f8782 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -1006,7 +1006,8 @@ pim_ifchannel_local_membership_add(struct interface *ifp, pim_upstream_switch (child, PIM_UPSTREAM_JOINED); } } - pim_channel_add_oif(up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); + if (pimg->spt_switchover != PIM_SPT_INFINITY) + pim_channel_add_oif(up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); } return 1; diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 3e81aaf496..5743dac654 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1676,6 +1676,42 @@ pim_upstream_sg_running (void *arg) return; } +void +pim_upstream_add_lhr_star_pimreg (void) +{ + struct pim_upstream *up; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, node, up)) + { + if (up->sg.src.s_addr != INADDR_ANY) + continue; + + if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags)) + continue; + + pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); + } +} + +void +pim_upstream_remove_lhr_star_pimreg (void) +{ + struct pim_upstream *up; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, node, up)) + { + if (up->sg.src.s_addr != INADDR_ANY) + continue; + + if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags)) + continue; + + pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); + } +} + void pim_upstream_init (void) { diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 94bc5a55b9..a1af4483ac 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -198,4 +198,7 @@ void pim_upstream_terminate (void); void join_timer_start (struct pim_upstream *up); int pim_upstream_compare (void *arg1, void *arg2); void pim_upstream_register_reevaluate (void); + +void pim_upstream_add_lhr_star_pimreg (void); +void pim_upstream_remove_lhr_star_pimreg (void); #endif /* PIM_UPSTREAM_H */ diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index f4bfcc5ce0..3d52dc9c41 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -182,6 +182,12 @@ int pim_global_config_write(struct vty *vty) ssm->plist_name, VTY_NEWLINE); ++writes; } + if (pimg->spt_switchover == PIM_SPT_INFINITY) + { + vty_out (vty, "ip pim spt-switchover infinity-and-beyond%s", + VTY_NEWLINE); + ++writes; + } if (qpim_ssmpingd_list) { struct listnode *node; diff --git a/pimd/pimd.c b/pimd/pimd.c index bdbd251e20..eaef4ff5c0 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -249,6 +249,7 @@ pim_instance_init (vrf_id_t vrf_id, afi_t afi) pim->vrf_id = vrf_id; pim->afi = afi; + pim->spt_switchover = PIM_SPT_IMMEDIATE; pim->rpf_hash = hash_create_size (256, pim_rpf_hash_key, pim_rpf_equal); if (PIM_DEBUG_ZEBRA) diff --git a/pimd/pimd.h b/pimd/pimd.h index 69aee28f8f..6c3dcfafca 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -237,11 +237,19 @@ extern int32_t qpim_register_probe_time; #define PIM_DONT_DEBUG_MSDP_PACKETS (qpim_debugs &= ~PIM_MASK_MSDP_PACKETS) #define PIM_DONT_DEBUG_MSDP_INTERNAL (qpim_debugs &= ~PIM_MASK_MSDP_INTERNAL) +enum pim_spt_switchover { + PIM_SPT_IMMEDIATE, + PIM_SPT_INFINITY, +}; + /* Per VRF PIM DB */ struct pim_instance { afi_t afi; vrf_id_t vrf_id; + + enum pim_spt_switchover spt_switchover; + struct hash *rpf_hash; void *ssm_info; /* per-vrf SSM configuration */ }; -- 2.39.5