summaryrefslogtreecommitdiff
path: root/ospfd/ospf_interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_interface.c')
-rw-r--r--ospfd/ospf_interface.c63
1 files changed, 36 insertions, 27 deletions
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 0969ae15bd..319db1efe2 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -147,17 +147,11 @@ void ospf_if_reset(struct interface *ifp)
}
}
-void ospf_if_reset_variables(struct ospf_interface *oi)
+static void ospf_if_default_variables(struct ospf_interface *oi)
{
/* Set default values. */
- /* don't clear this flag. oi->flag = OSPF_IF_DISABLE; */
- if (oi->vl_data)
- oi->type = OSPF_IFTYPE_VIRTUALLINK;
- else
- /* preserve network-type */
- if (oi->type != OSPF_IFTYPE_NBMA)
- oi->type = OSPF_IFTYPE_BROADCAST;
+ oi->type = OSPF_IFTYPE_BROADCAST;
oi->state = ISM_Down;
@@ -254,7 +248,7 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
oi->ls_ack_direct.ls_ack = list_new();
/* Set default values. */
- ospf_if_reset_variables(oi);
+ ospf_if_default_variables(oi);
/* Set pseudo neighbor to Null */
oi->nbr_self = NULL;
@@ -821,14 +815,41 @@ int ospf_if_up(struct ospf_interface *oi)
return 1;
}
-int ospf_if_down(struct ospf_interface *oi)
+/* This function will mark routes with next-hops matching the down
+ * OSPF interface as changed. It is used to assure routes that get
+ * removed from the zebra RIB when an interface goes down are
+ * reinstalled if the interface comes back up prior to an intervening
+ * SPF calculation.
+ */
+static void ospf_if_down_mark_routes_changed(struct route_table *table,
+ struct ospf_interface *oi)
{
- struct ospf *ospf;
struct route_node *rn;
struct ospf_route *or;
struct listnode *nh;
struct ospf_path *op;
+ for (rn = route_top(table); rn; rn = route_next(rn)) {
+ or = rn->info;
+
+ if (or == NULL)
+ continue;
+
+ for (nh = listhead(or->paths); nh;
+ nh = listnextnode_unchecked(nh)) {
+ op = listgetdata(nh);
+ if (op->ifindex == oi->ifp->ifindex) {
+ or->changed = true;
+ break;
+ }
+ }
+ }
+}
+
+int ospf_if_down(struct ospf_interface *oi)
+{
+ struct ospf *ospf;
+
if (oi == NULL)
return 0;
@@ -864,23 +885,11 @@ int ospf_if_down(struct ospf_interface *oi)
/* Shutdown packet reception and sending */
ospf_if_stream_unset(oi);
- if (!ospf->new_table)
- return 1;
- for (rn = route_top(ospf->new_table); rn; rn = route_next(rn)) {
- or = rn->info;
-
- if (!or)
- continue;
+ if (ospf->new_table)
+ ospf_if_down_mark_routes_changed(ospf->new_table, oi);
- for (nh = listhead(or->paths); nh;
- nh = listnextnode_unchecked(nh)) {
- op = listgetdata(nh);
- if (op->ifindex == oi->ifp->ifindex) {
- or->changed = true;
- break;
- }
- }
- }
+ if (ospf->new_external_route)
+ ospf_if_down_mark_routes_changed(ospf->new_external_route, oi);
return 1;
}