diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-04-07 16:16:23 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-04-20 21:55:50 +0200 |
commit | df94f9a91dbff3e0b04928d564484dfc4bf55aed (patch) | |
tree | 1cee9cc829182d1dd28342c5a5ef25390e674eac /pimd | |
parent | Merge pull request #379 from pguibert6WIND/frrouting_issue309_2 (diff) | |
download | frr-df94f9a91dbff3e0b04928d564484dfc4bf55aed.tar.xz frr-df94f9a91dbff3e0b04928d564484dfc4bf55aed.zip |
pimd: Add prefix list handling to spt-switchover
To the 'ip pim spt-switchover infinity-and-beyond' command
add 'prefix-list <PLIST>'. To the command.
Use this as the basis to deny (Not immediate switchover)
or permit (Immediate switchover), based upon matching
the group address and the prefix-list.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'pimd')
-rw-r--r-- | pimd/pim_cmd.c | 62 | ||||
-rw-r--r-- | pimd/pim_ifchannel.c | 22 | ||||
-rw-r--r-- | pimd/pim_memory.c | 1 | ||||
-rw-r--r-- | pimd/pim_memory.h | 1 | ||||
-rw-r--r-- | pimd/pim_upstream.c | 45 | ||||
-rw-r--r-- | pimd/pim_upstream.h | 4 | ||||
-rw-r--r-- | pimd/pim_vty.c | 10 | ||||
-rw-r--r-- | pimd/pimd.c | 5 | ||||
-rw-r--r-- | pimd/pimd.h | 5 |
9 files changed, 139 insertions, 16 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index de2b7cbba..f04fafdaf 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -3416,6 +3416,33 @@ pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const cha return CMD_SUCCESS; } +static int +pim_cmd_spt_switchover (enum pim_spt_switchover spt, const char *plist) +{ + pimg->spt.switchover = spt; + + switch (pimg->spt.switchover) + { + case PIM_SPT_IMMEDIATE: + if (pimg->spt.plist) + XFREE (MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist); + + pim_upstream_add_lhr_star_pimreg (); + break; + case PIM_SPT_INFINITY: + pim_upstream_remove_lhr_star_pimreg (plist); + + if (pimg->spt.plist) + XFREE (MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist); + + if (plist) + pimg->spt.plist = XSTRDUP (MTYPE_PIM_SPT_PLIST_NAME, plist); + break; + } + + return CMD_SUCCESS; +} + DEFUN (ip_pim_spt_switchover_infinity, ip_pim_spt_switchover_infinity_cmd, "ip pim spt-switchover infinity-and-beyond", @@ -3424,10 +3451,20 @@ DEFUN (ip_pim_spt_switchover_infinity, "SPT-Switchover\n" "Never switch to SPT Tree\n") { - pimg->spt_switchover = PIM_SPT_INFINITY; + return pim_cmd_spt_switchover (PIM_SPT_INFINITY, NULL); +} - pim_upstream_remove_lhr_star_pimreg(); - return CMD_SUCCESS; +DEFUN (ip_pim_spt_switchover_infinity_plist, + ip_pim_spt_switchover_infinity_plist_cmd, + "ip pim spt-switchover infinity-and-beyond prefix-list WORD", + IP_STR + PIM_STR + "SPT-Switchover\n" + "Never switch to SPT Tree\n" + "Prefix-List to control which groups to switch\n" + "Prefix-List name\n") +{ + return pim_cmd_spt_switchover (PIM_SPT_INFINITY, argv[5]->arg); } DEFUN (no_ip_pim_spt_switchover_infinity, @@ -3439,10 +3476,21 @@ DEFUN (no_ip_pim_spt_switchover_infinity, "SPT_Switchover\n" "Never switch to SPT Tree\n") { - pimg->spt_switchover = PIM_SPT_IMMEDIATE; + return pim_cmd_spt_switchover (PIM_SPT_IMMEDIATE, NULL); +} - pim_upstream_add_lhr_star_pimreg(); - return CMD_SUCCESS; +DEFUN (no_ip_pim_spt_switchover_infinity_plist, + no_ip_pim_spt_switchover_infinity_plist_cmd, + "no ip pim spt-switchover infinity-and-beyond prefix-list WORD", + NO_STR + IP_STR + PIM_STR + "SPT_Switchover\n" + "Never switch to SPT Tree\n" + "Prefix-List to control which groups to switch\n" + "Prefix-List name\n") +{ + return pim_cmd_spt_switchover (PIM_SPT_IMMEDIATE, NULL); } DEFUN (ip_pim_joinprune_time, @@ -6217,7 +6265,9 @@ void pim_cmd_init() 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, &ip_pim_spt_switchover_infinity_plist_cmd); install_element (CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd); + install_element (CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_plist_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 ebd36f878..fc84a5c2f 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -27,6 +27,7 @@ #include "vrf.h" #include "hash.h" #include "jhash.h" +#include "prefix.h" #include "pimd.h" #include "pim_str.h" @@ -1006,8 +1007,25 @@ pim_ifchannel_local_membership_add(struct interface *ifp, pim_upstream_switch (child, PIM_UPSTREAM_JOINED); } } - if (pimg->spt_switchover != PIM_SPT_INFINITY) - pim_channel_add_oif(up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); + + if (pimg->spt.switchover == PIM_SPT_INFINITY) + { + if (pimg->spt.plist) + { + struct prefix_list *plist = prefix_list_lookup (AFI_IP, pimg->spt.plist); + struct prefix g; + g.family = AF_INET; + g.prefixlen = IPV4_MAX_PREFIXLEN; + g.u.prefix4 = up->sg.grp; + + if (prefix_list_apply (plist, &g) == PREFIX_DENY) + { + pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); + } + } + } + else + pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); } return 1; diff --git a/pimd/pim_memory.c b/pimd/pim_memory.c index 2acca6f49..ab92665b9 100644 --- a/pimd/pim_memory.c +++ b/pimd/pim_memory.c @@ -52,3 +52,4 @@ DEFINE_MTYPE(PIMD, PIM_JP_AGG_SOURCE, "PIM JP AGG Source") DEFINE_MTYPE(PIMD, PIM_PIM_INSTANCE, "PIM global state") DEFINE_MTYPE(PIMD, PIM_NEXTHOP_CACHE, "PIM nexthop cache state") DEFINE_MTYPE(PIMD, PIM_SSM_INFO, "PIM SSM configuration") +DEFINE_MTYPE(PIMD, PIM_SPT_PLIST_NAME, "PIM SPT Prefix List Name") diff --git a/pimd/pim_memory.h b/pimd/pim_memory.h index 02446de46..e366377c8 100644 --- a/pimd/pim_memory.h +++ b/pimd/pim_memory.h @@ -51,5 +51,6 @@ DECLARE_MTYPE(PIM_JP_AGG_SOURCE) DECLARE_MTYPE(PIM_PIM_INSTANCE) DECLARE_MTYPE(PIM_NEXTHOP_CACHE) DECLARE_MTYPE(PIM_SSM_INFO) +DECLARE_MTYPE(PIM_SPT_PLIST_NAME); #endif /* _QUAGGA_PIM_MEMORY_H */ diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 5743dac65..167588dae 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1695,10 +1695,41 @@ pim_upstream_add_lhr_star_pimreg (void) } void -pim_upstream_remove_lhr_star_pimreg (void) +pim_upstream_spt_prefix_list_update (struct prefix_list *pl) +{ + const char *pname = prefix_list_name (pl); + + if (pimg->spt.plist && strcmp (pimg->spt.plist, pname) == 0) + { + pim_upstream_remove_lhr_star_pimreg (pname); + } +} + +/* + * nlist -> The new prefix list + * + * Per Group Application of pimreg to the OIL + * If the prefix list tells us DENY then + * we need to Switchover to SPT immediate + * so add the pimreg. + * If the prefix list tells us to ACCEPT than + * we need to Never do the SPT so remove + * the interface + * + */ +void +pim_upstream_remove_lhr_star_pimreg (const char *nlist) { struct pim_upstream *up; struct listnode *node; + struct prefix_list *np; + struct prefix g; + enum prefix_list_type apply_new; + + np = prefix_list_lookup (AFI_IP, nlist); + + g.family = AF_INET; + g.prefixlen = IPV4_MAX_PREFIXLEN; for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, node, up)) { @@ -1708,7 +1739,17 @@ pim_upstream_remove_lhr_star_pimreg (void) if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags)) continue; - pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); + if (!nlist) + { + pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); + continue; + } + g.u.prefix4 = up->sg.grp; + apply_new = prefix_list_apply (np, &g); + if (apply_new == PREFIX_DENY) + pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); + else + pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP); } } diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index a1af4483a..ec40f3c24 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -200,5 +200,7 @@ 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); +void pim_upstream_remove_lhr_star_pimreg (const char *nlist); + +void pim_upstream_spt_prefix_list_update (struct prefix_list *pl); #endif /* PIM_UPSTREAM_H */ diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 3d52dc9c4..c8322b629 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -182,10 +182,14 @@ int pim_global_config_write(struct vty *vty) ssm->plist_name, VTY_NEWLINE); ++writes; } - if (pimg->spt_switchover == PIM_SPT_INFINITY) + if (pimg->spt.switchover == PIM_SPT_INFINITY) { - vty_out (vty, "ip pim spt-switchover infinity-and-beyond%s", - VTY_NEWLINE); + if (pimg->spt.plist) + vty_out (vty, "ip pim spt-switchover infinity-and-beyond prefix-list %s%s", + pimg->spt.plist, VTY_NEWLINE); + else + vty_out (vty, "ip pim spt-switchover infinity-and-beyond%s", + VTY_NEWLINE); ++writes; } diff --git a/pimd/pimd.c b/pimd/pimd.c index eaef4ff5c..a8a2a806e 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -194,6 +194,7 @@ pim_prefix_list_update (struct prefix_list *plist) { pim_rp_prefix_list_update (plist); pim_ssm_prefix_list_update (plist); + pim_upstream_spt_prefix_list_update (plist); } static void @@ -249,7 +250,9 @@ 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->spt.switchover = PIM_SPT_IMMEDIATE; + pim->spt.plist = NULL; + 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 6c3dcfafc..246be17d4 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -248,7 +248,10 @@ struct pim_instance afi_t afi; vrf_id_t vrf_id; - enum pim_spt_switchover spt_switchover; + struct { + enum pim_spt_switchover switchover; + char *plist; + } spt; struct hash *rpf_hash; void *ssm_info; /* per-vrf SSM configuration */ |