forked from Mirror/frr
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>
This commit is contained in:
parent
54cd060799
commit
df94f9a91d
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue