diff options
author | rgirada <rgirada@vmware.com> | 2020-09-01 09:58:47 +0200 |
---|---|---|
committer | rgirada <rgirada@vmware.com> | 2020-11-02 07:02:37 +0100 |
commit | 423e71c45a0b15c43decb1b7d3a35fb3f438e32c (patch) | |
tree | 84c72387e55c8082f685b799dc183bb1d4cc902c /ospfd | |
parent | ospfd: ospf summarisation core handlers (diff) | |
download | frr-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.c | 132 | ||||
-rw-r--r-- | ospfd/ospf_asbr.h | 15 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 222 |
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); |