summaryrefslogtreecommitdiffstats
path: root/ospfd
diff options
context:
space:
mode:
authorrgirada <rgirada@vmware.com>2020-09-01 09:58:47 +0200
committerrgirada <rgirada@vmware.com>2020-11-02 07:02:37 +0100
commit423e71c45a0b15c43decb1b7d3a35fb3f438e32c (patch)
tree84c72387e55c8082f685b799dc183bb1d4cc902c /ospfd
parentospfd: ospf summarisation core handlers (diff)
downloadfrr-423e71c45a0b15c43decb1b7d3a35fb3f438e32c.tar.xz
frr-423e71c45a0b15c43decb1b7d3a35fb3f438e32c.zip
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>
Diffstat (limited to 'ospfd')
-rw-r--r--ospfd/ospf_asbr.c132
-rw-r--r--ospfd/ospf_asbr.h15
-rw-r--r--ospfd/ospf_vty.c222
3 files changed, 366 insertions, 3 deletions
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index c5586f7d9..639f9cb35 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -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;
+}
diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h
index ea5860f9a..7759d4545 100644
--- a/ospfd/ospf_asbr.h
+++ b/ospfd/ospf_asbr.h
@@ -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 */
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 7e41880bc..c608613bb 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -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);