ospfd: External LSA summarisation config commands.

Description:
	The following config commands introduced for external route
	aggregation.

	[no] summary-address A.B.C.D/M [tag (1-4294967295)]
	[no] summary-address A.B.C.D/M no-advertise
	aggregation timer (5-1800)
	no aggregation timer

Signed-off-by: Rajesh Girada <rgirada@vmware.com>
This commit is contained in:
rgirada 2020-09-01 00:58:47 -07:00
parent 63f0e9415c
commit 423e71c45a
3 changed files with 366 additions and 3 deletions

View File

@ -331,6 +331,18 @@ void ospf_redistribute_withdraw(struct ospf *ospf, uint8_t type,
}
/* External Route Aggregator Handlers */
bool is_valid_summary_addr(struct prefix_ipv4 *p)
{
/* Default prefix validation*/
if (p->prefix.s_addr == INADDR_ANY)
return false;
/*Host route shouldn't be configured as summary addres*/
if (p->prefixlen == IPV4_MAX_PREFIXLEN)
return false;
return true;
}
void ospf_asbr_external_aggregator_init(struct ospf *instance)
{
instance->rt_aggr_tbl = route_table_init();
@ -1084,3 +1096,123 @@ static void ospf_external_aggr_timer(struct ospf *ospf,
thread_add_timer(master, ospf_asbr_external_aggr_process, ospf,
ospf->aggr_delay_interval, &ospf->t_external_aggr);
}
int ospf_asbr_external_aggregator_set(struct ospf *ospf, struct prefix_ipv4 *p,
route_tag_t tag)
{
struct ospf_external_aggr_rt *aggregator;
aggregator = ospf_extrenal_aggregator_lookup(ospf, p);
if (aggregator) {
if (CHECK_FLAG(aggregator->flags,
OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
UNSET_FLAG(aggregator->flags,
OSPF_EXTERNAL_AGGRT_NO_ADVERTISE);
else if (aggregator->tag == tag)
return OSPF_SUCCESS;
aggregator->tag = tag;
ospf_external_aggr_timer(ospf, aggregator,
OSPF_ROUTE_AGGR_MODIFY);
} else {
aggregator = ospf_external_aggregator_new(p);
if (!aggregator)
return OSPF_FAILURE;
aggregator->tag = tag;
ospf_external_aggr_add(ospf, aggregator);
ospf_external_aggr_timer(ospf, aggregator, OSPF_ROUTE_AGGR_ADD);
}
return OSPF_SUCCESS;
}
int ospf_asbr_external_aggregator_unset(struct ospf *ospf,
struct prefix_ipv4 *p, route_tag_t tag)
{
struct route_node *rn;
struct ospf_external_aggr_rt *aggr;
rn = route_node_lookup(ospf->rt_aggr_tbl, (struct prefix *)p);
if (!rn)
return OSPF_INVALID;
aggr = rn->info;
if (tag && (tag != aggr->tag))
return OSPF_INVALID;
if (!OSPF_EXTERNAL_RT_COUNT(aggr)) {
ospf_external_aggr_delete(ospf, rn);
ospf_external_aggregator_free(aggr);
return OSPF_SUCCESS;
}
ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_DEL);
return OSPF_SUCCESS;
}
int ospf_asbr_external_rt_no_advertise(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct ospf_external_aggr_rt *aggr;
route_tag_t tag = 0;
aggr = ospf_extrenal_aggregator_lookup(ospf, p);
if (aggr) {
if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
return OSPF_SUCCESS;
SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE);
aggr->tag = tag;
if (!OSPF_EXTERNAL_RT_COUNT(aggr))
return OSPF_SUCCESS;
ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_MODIFY);
} else {
aggr = ospf_external_aggregator_new(p);
if (!aggr)
return OSPF_FAILURE;
SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE);
ospf_external_aggr_add(ospf, aggr);
ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_ADD);
}
return OSPF_SUCCESS;
}
int ospf_asbr_external_rt_advertise(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct route_node *rn;
struct ospf_external_aggr_rt *aggr;
rn = route_node_lookup(ospf->rt_aggr_tbl, (struct prefix *)p);
if (!rn)
return OSPF_INVALID;
aggr = rn->info;
if (!CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
return OSPF_INVALID;
UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE);
if (!OSPF_EXTERNAL_RT_COUNT(aggr))
return OSPF_SUCCESS;
ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_MODIFY);
return OSPF_SUCCESS;
}
int ospf_external_aggregator_timer_set(struct ospf *ospf, unsigned int interval)
{
ospf->aggr_delay_interval = interval;
return OSPF_SUCCESS;
}

View File

@ -132,15 +132,13 @@ extern struct ospf_lsa *ospf_external_info_find_lsa(struct ospf *,
/* External Route Aggregator */
extern void ospf_asbr_external_aggregator_init(struct ospf *instance);
extern void ospf_external_aggregator_free(struct ospf_external_aggr_rt *aggr);
extern bool is_valid_summary_addr(struct prefix_ipv4 *p);
extern struct ospf_external_aggr_rt *
ospf_external_aggr_match(struct ospf *ospf, struct prefix_ipv4 *p);
extern void ospf_unlink_ei_from_aggr(struct ospf *ospf,
struct ospf_external_aggr_rt *aggr,
struct external_info *ei);
extern struct ospf_lsa *
ospf_originate_summary_lsa(struct ospf *ospf,
struct ospf_external_aggr_rt *aggr,
@ -153,4 +151,15 @@ extern struct ospf_external_aggr_rt *
ospf_extrenal_aggregator_lookup(struct ospf *ospf, struct prefix_ipv4 *p);
void ospf_unset_all_aggr_flag(struct ospf *ospf);
extern int ospf_asbr_external_aggregator_set(struct ospf *ospf,
struct prefix_ipv4 *p,
route_tag_t tag);
extern int ospf_asbr_external_aggregator_unset(struct ospf *ospf,
struct prefix_ipv4 *p,
route_tag_t tag);
extern int ospf_asbr_external_rt_no_advertise(struct ospf *ospf,
struct prefix_ipv4 *p);
extern int ospf_asbr_external_rt_advertise(struct ospf *ospf,
struct prefix_ipv4 *p);
#endif /* _ZEBRA_OSPF_ASBR_H */

View File

@ -9202,6 +9202,88 @@ DEFPY(ospf_gr_helper_planned_only,
return CMD_SUCCESS;
}
/* External Route Aggregation */
DEFUN (ospf_external_route_aggregation,
ospf_external_route_aggregation_cmd,
"summary-address A.B.C.D/M [tag (1-4294967295)]",
"External summary address\n"
"Summary address prefix (a.b.c.d/m) \n"
"Router tag \n"
"Router tag value\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
struct prefix_ipv4 p;
int idx = 1;
route_tag_t tag = 0;
int ret = OSPF_SUCCESS;
str2prefix_ipv4(argv[idx]->arg, &p);
if (is_prefix_default(&p)) {
vty_out(vty,
"Default address shouldn't be configured as summary address.\n");
return CMD_SUCCESS;
}
/* Apply mask for given prefix. */
apply_mask((struct prefix *)&p);
if (!is_valid_summary_addr(&p)) {
vty_out(vty, "Not a valid summary address.\n");
return CMD_WARNING_CONFIG_FAILED;
}
if (argc > 2)
tag = strtoul(argv[idx + 2]->arg, NULL, 10);
ret = ospf_asbr_external_aggregator_set(ospf, &p, tag);
if (ret == OSPF_INVALID)
vty_out(vty, "Inavlid configuration!!\n");
return CMD_SUCCESS;
}
DEFUN (no_ospf_external_route_aggregation,
no_ospf_external_route_aggregation_cmd,
"no summary-address A.B.C.D/M [tag (1-4294967295)]",
NO_STR
"External summary address\n"
"Summary address prefix (a.b.c.d/m)\n"
"Router tag\n"
"Router tag value\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
struct prefix_ipv4 p;
int idx = 2;
route_tag_t tag = 0;
int ret = OSPF_SUCCESS;
str2prefix_ipv4(argv[idx]->arg, &p);
if (is_prefix_default(&p)) {
vty_out(vty,
"Default address shouldn't be configured as summary address.\n");
return CMD_SUCCESS;
}
/* Apply mask for given prefix. */
apply_mask((struct prefix *)&p);
if (!is_valid_summary_addr(&p)) {
vty_out(vty, "Not a valid summary address.\n");
return CMD_WARNING_CONFIG_FAILED;
}
if (argc > 3)
tag = strtoul(argv[idx + 2]->arg, NULL, 10);
ret = ospf_asbr_external_aggregator_unset(ospf, &p, tag);
if (ret == OSPF_INVALID)
vty_out(vty, "Inavlid configuration!!\n");
return CMD_SUCCESS;
}
DEFPY(no_ospf_gr_helper_planned_only,
no_ospf_gr_helper_planned_only_cmd,
"no graceful-restart helper planned-only",
@ -9454,6 +9536,93 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf,
}
}
}
return CMD_SUCCESS;
}
DEFUN (ospf_external_route_aggregation_no_adrvertise,
ospf_external_route_aggregation_no_adrvertise_cmd,
"summary-address A.B.C.D/M no-advertise",
"External summary address\n"
"Summary address prefix (a.b.c.d/m) \n"
"Don't advertise summary route \n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
struct prefix_ipv4 p;
int idx = 1;
int ret = OSPF_SUCCESS;
str2prefix_ipv4(argv[idx]->arg, &p);
if (is_prefix_default(&p)) {
vty_out(vty,
"Default address shouldn't be configured as summary address.\n");
return CMD_SUCCESS;
}
/* Apply mask for given prefix. */
apply_mask((struct prefix *)&p);
if (!is_valid_summary_addr(&p)) {
vty_out(vty, "Not a valid summary address.\n");
return CMD_WARNING_CONFIG_FAILED;
}
ret = ospf_asbr_external_rt_no_advertise(ospf, &p);
if (ret == OSPF_INVALID)
vty_out(vty, "Inavlid configuration!!\n");
return CMD_SUCCESS;
}
DEFUN (no_ospf_external_route_aggregation_no_adrvertise,
no_ospf_external_route_aggregation_no_adrvertise_cmd,
"no summary-address A.B.C.D/M no-advertise",
NO_STR
"External summary address\n"
"Summary address prefix (a.b.c.d/m) \n"
"Adverise summary route to the AS \n.")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
struct prefix_ipv4 p;
int idx = 2;
int ret = OSPF_SUCCESS;
str2prefix_ipv4(argv[idx]->arg, &p);
if (is_prefix_default(&p)) {
vty_out(vty,
"Default address shouldn't be configured as summary address.\n");
return CMD_SUCCESS;
}
/* Apply mask for given prefix. */
apply_mask((struct prefix *)&p);
if (!is_valid_summary_addr(&p)) {
vty_out(vty, "Not a valid summary address.\n");
return CMD_WARNING_CONFIG_FAILED;
}
ret = ospf_asbr_external_rt_advertise(ospf, &p);
if (ret == OSPF_INVALID)
vty_out(vty, "Inavlid configuration!!\n");
return CMD_SUCCESS;
}
DEFUN (ospf_route_aggregation_timer,
ospf_route_aggregation_timer_cmd,
"aggregation timer (5-1800)",
"External route aggregation\n"
"Delay timer (in seconds)\n"
"Timer interval(in seconds)\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
unsigned int interval = 0;
interval = strtoul(argv[2]->arg, NULL, 10);
ospf_external_aggregator_timer_set(ospf, interval);
return CMD_SUCCESS;
}
@ -9560,6 +9729,21 @@ DEFPY (show_ip_ospf_gr_helper,
return CMD_SUCCESS;
}
/* Graceful Restart HELPER commands end */
DEFUN (no_ospf_route_aggregation_timer,
no_ospf_route_aggregation_timer_cmd,
"no aggregation timer",
NO_STR
"External route aggregation\n"
"Delay timer\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
ospf_external_aggregator_timer_set(ospf, OSPF_EXTL_AGGR_DEFAULT_DELAY);
return CMD_SUCCESS;
}
/* External Route Aggregation End */
static void config_write_stub_router(struct vty *vty, struct ospf *ospf)
{
@ -10926,6 +11110,30 @@ static int config_write_ospf_gr_helper(struct vty *vty, struct ospf *ospf)
hash_walk(ospf->enable_rtr_list,
ospf_cfg_write_helper_dis_rtr_walkcb, vty);
}
return 0;
}
static int config_write_ospf_external_aggregator(struct vty *vty,
struct ospf *ospf)
{
struct route_node *rn;
/* print 'summary-address A.B.C.D/M' */
for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn))
if (rn->info) {
struct ospf_external_aggr_rt *aggr = rn->info;
vty_out(vty, " summary-address %pI4/%d ",
&aggr->p.prefix, aggr->p.prefixlen);
if (aggr->tag)
vty_out(vty, " tag %u ", aggr->tag);
if (CHECK_FLAG(aggr->flags,
OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
vty_out(vty, " no-advertise");
vty_out(vty, "\n");
}
return 0;
}
@ -11099,6 +11307,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
/* Print gr helper configs */
config_write_ospf_gr_helper(vty, ospf);
/* Print external route aggregation. */
config_write_ospf_external_aggregator(vty, ospf);
/* passive-interface print. */
if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
vty_out(vty, " passive-interface default\n");
@ -11370,6 +11581,17 @@ static void ospf_vty_zebra_init(void)
install_element(OSPF_NODE, &no_ospf_gr_helper_supported_grace_time_cmd);
install_element(OSPF_NODE, &ospf_gr_helper_planned_only_cmd);
install_element(OSPF_NODE, &no_ospf_gr_helper_planned_only_cmd);
/* External LSA summarisation config commands.*/
install_element(OSPF_NODE, &ospf_external_route_aggregation_cmd);
install_element(OSPF_NODE, &no_ospf_external_route_aggregation_cmd);
install_element(OSPF_NODE,
&ospf_external_route_aggregation_no_adrvertise_cmd);
install_element(OSPF_NODE,
&no_ospf_external_route_aggregation_no_adrvertise_cmd);
install_element(OSPF_NODE, &ospf_route_aggregation_timer_cmd);
install_element(OSPF_NODE, &no_ospf_route_aggregation_timer_cmd);
#if 0
install_element (OSPF_NODE, &ospf_distance_source_cmd);
install_element (OSPF_NODE, &no_ospf_distance_source_cmd);