summaryrefslogtreecommitdiff
path: root/ospfd/ospfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospfd.c')
-rw-r--r--ospfd/ospfd.c114
1 files changed, 69 insertions, 45 deletions
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 3718f82c05..d8be19db9a 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -312,6 +312,8 @@ static struct ospf *ospf_new(unsigned short instance, const char *name)
ospf_gr_helper_init(new);
+ ospf_asbr_external_aggregator_init(new);
+
QOBJ_REG(new, ospf);
new->fd = -1;
@@ -385,6 +387,8 @@ struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name)
struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
{
struct ospf *ospf;
+ struct vrf *vrf;
+ struct interface *ifp;
/* vrf name provided call inst and name based api
* in case of no name pass default ospf instance */
@@ -398,10 +402,39 @@ struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
ospf = ospf_new(instance, name);
ospf_add(ospf);
- if (ospf->router_id_static.s_addr == INADDR_ANY)
- ospf_router_id_update(ospf);
-
ospf_opaque_type11_lsa_init(ospf);
+
+ if (ospf->vrf_id != VRF_UNKNOWN)
+ ospf->oi_running = 1;
+
+ /* Activate 'ip ospf area x' configured interfaces for given
+ * vrf. Activate area on vrf x aware interfaces.
+ * vrf_enable callback calls router_id_update which
+ * internally will call ospf_if_update to trigger
+ * network_run_state
+ */
+ vrf = vrf_lookup_by_id(ospf->vrf_id);
+
+ FOR_ALL_INTERFACES (vrf, ifp) {
+ struct ospf_if_params *params;
+ struct route_node *rn;
+ uint32_t count = 0;
+
+ params = IF_DEF_PARAMS(ifp);
+ if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+ count++;
+
+ for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
+ if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area))
+ count++;
+
+ if (count > 0) {
+ ospf_interface_area_set(ospf, ifp);
+ ospf->if_ospf_cli_count += count;
+ }
+ }
+
+ ospf_router_id_update(ospf);
}
return ospf;
@@ -417,9 +450,6 @@ struct ospf *ospf_get_instance(unsigned short instance, bool *created)
ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/);
ospf_add(ospf);
- if (ospf->router_id_static.s_addr == INADDR_ANY)
- ospf_router_id_update(ospf);
-
ospf_opaque_type11_lsa_init(ospf);
}
@@ -581,11 +611,10 @@ void ospf_finish(struct ospf *ospf)
/* Final cleanup of ospf instance */
static void ospf_finish_final(struct ospf *ospf)
{
- struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
+ struct vrf *vrf;
struct route_node *rn;
struct ospf_nbr_nbma *nbr_nbma;
struct ospf_lsa *lsa;
- struct interface *ifp;
struct ospf_interface *oi;
struct ospf_area *area;
struct ospf_vl_data *vl_data;
@@ -628,15 +657,6 @@ static void ospf_finish_final(struct ospf *ospf)
if (ospf->vrf_id == VRF_DEFAULT)
ospf_ldp_sync_gbl_exit(ospf, true);
- /* Remove any ospf interface config params */
- FOR_ALL_INTERFACES (vrf, ifp) {
- struct ospf_if_params *params;
-
- params = IF_DEF_PARAMS(ifp);
- if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
- UNSET_IF_PARAM(params, if_area);
- }
-
/* Reset interface. */
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
ospf_if_free(oi);
@@ -698,6 +718,7 @@ static void ospf_finish_final(struct ospf *ospf)
OSPF_TIMER_OFF(ospf->t_opaque_lsa_self);
OSPF_TIMER_OFF(ospf->t_sr_update);
OSPF_TIMER_OFF(ospf->t_default_routemap_timer);
+ OSPF_TIMER_OFF(ospf->t_external_aggr);
LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
ospf_discard_from_db(ospf, ospf->lsdb, lsa);
@@ -766,6 +787,22 @@ static void ospf_finish_final(struct ospf *ospf)
ospf_distance_reset(ospf);
route_table_finish(ospf->distance_table);
+ /* Release extrenal Aggregator table */
+ for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
+ struct ospf_external_aggr_rt *aggr;
+
+ aggr = rn->info;
+
+ if (aggr) {
+ ospf_external_aggregator_free(aggr);
+ rn->info = NULL;
+ route_unlock_node(rn);
+ }
+ }
+
+ route_table_finish(ospf->rt_aggr_tbl);
+
+
list_delete(&ospf->areas);
list_delete(&ospf->oi_write_q);
@@ -1144,32 +1181,6 @@ void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
update_redistributed(ospf, 0); /* interfaces possibly removed */
}
-bool ospf_interface_area_is_already_set(struct ospf *ospf,
- struct interface *ifp)
-{
- struct route_node *rn_oi;
-
- if (!ospf)
- return false; /* Ospf not ready yet */
-
- /* Find interfaces that may need to be removed. */
- for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
- rn_oi = route_next(rn_oi)) {
- struct ospf_interface *oi = rn_oi->info;
-
- if (oi == NULL)
- continue;
-
- if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
- continue;
- /* at least one route covered by interface
- * that implies already done
- */
- return true;
- }
- return false;
-}
-
/* Check whether interface matches given network
* returns: 1, true. 0, false
*/
@@ -1592,7 +1603,8 @@ int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id, int argc)
OSPF_NSSA_TRANS_STABLE_DEFAULT;
ospf_area_type_set(area, OSPF_AREA_DEFAULT);
} else {
- area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
+ ospf_area_nssa_translator_role_set(ospf, area_id,
+ OSPF_NSSA_ROLE_CANDIDATE);
}
ospf_area_check_free(ospf, area_id);
@@ -1609,7 +1621,19 @@ int ospf_area_nssa_translator_role_set(struct ospf *ospf,
if (area == NULL)
return 0;
- area->NSSATranslatorRole = role;
+ if (role != area->NSSATranslatorRole) {
+ if ((area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS)
+ || (role == OSPF_NSSA_ROLE_ALWAYS)) {
+ /* RFC 3101 3.1
+ * if new role is OSPF_NSSA_ROLE_ALWAYS we need to set
+ * Nt bit, if the role was OSPF_NSSA_ROLE_ALWAYS we need
+ * to clear Nt bit
+ */
+ area->NSSATranslatorRole = role;
+ ospf_router_lsa_update_area(area);
+ } else
+ area->NSSATranslatorRole = role;
+ }
return 1;
}