summaryrefslogtreecommitdiff
path: root/proto/ospf
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2019-02-17 01:54:01 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2019-02-17 01:54:01 +0100
commitbf8d7bba9ef3c6d95661f97dc71fa7a6b2cf0b87 (patch)
tree0e006f5f19433838c3ed47dc154fb483c414bee0 /proto/ospf
parent4a3f5b36173299d44e26dc18db4e5d103875f8c4 (diff)
OSPF: Reset LSAs during area type change
When area is reconfigured to a different type, we need to flush LSAs as they may not be valid (e.g. NSSA-LSA for non-NSSA area). Also, when we have have just one OSPF area and that changes type, we could restart OSPF as there is no state to keep anyway. That solves issue with different handling of external routes exported to OSPF based of main area type.
Diffstat (limited to 'proto/ospf')
-rw-r--r--proto/ospf/ospf.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index 4fdcac58..ef2a0df4 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -599,17 +599,25 @@ ospf_area_reconfigure(struct ospf_area *oa, struct ospf_area_config *nac)
{
struct ospf_proto *p = oa->po;
struct ospf_area_config *oac = oa->ac;
- struct ospf_iface *ifa;
+ struct ospf_iface *ifa, *ifx;
oa->ac = nac;
oa->options = nac->type | ospf_opts(p);
if (nac->type != oac->type)
{
- /* Force restart of area interfaces */
- WALK_LIST(ifa, p->iface_list)
+ log(L_INFO "%s: Restarting area %R", p->p.name, oa->areaid);
+
+ /* Remove area interfaces, will be re-added later */
+ WALK_LIST_DELSAFE(ifa, ifx, p->iface_list)
if (ifa->oa == oa)
- ifa->marked = 2;
+ {
+ ospf_iface_shutdown(ifa);
+ ospf_iface_remove(ifa);
+ }
+
+ /* Flush area LSAs */
+ ospf_flush_area(p, oa->areaid);
}
/* Handle net_list */
@@ -639,7 +647,7 @@ ospf_reconfigure(struct proto *P, struct proto_config *CF)
struct ospf_proto *p = (struct ospf_proto *) P;
struct ospf_config *old = (struct ospf_config *) (P->cf);
struct ospf_config *new = (struct ospf_config *) CF;
- struct ospf_area_config *nac;
+ struct ospf_area_config *oac, *nac;
struct ospf_area *oa, *oax;
struct ospf_iface *ifa, *ifx;
struct ospf_iface_patt *ip;
@@ -659,6 +667,15 @@ ospf_reconfigure(struct proto *P, struct proto_config *CF)
if (old->abr != new->abr)
return 0;
+ if (p->areano == 1)
+ {
+ oac = HEAD(old->area_list);
+ nac = HEAD(new->area_list);
+
+ if (oac->type != nac->type)
+ return 0;
+ }
+
if (old->vpn_pe != new->vpn_pe)
return 0;
@@ -674,7 +691,7 @@ ospf_reconfigure(struct proto *P, struct proto_config *CF)
p->ecmp = new->ecmp;
p->tick = new->tick;
p->disp_timer->recurrent = p->tick S;
- tm_start(p->disp_timer, 100 MS);
+ tm_start(p->disp_timer, 10 MS);
/* Mark all areas and ifaces */
WALK_LIST(oa, p->area_list)