summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_lsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_lsa.c')
-rw-r--r--ospfd/ospf_lsa.c106
1 files changed, 85 insertions, 21 deletions
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 5d5ad08a..34cbc446 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -615,7 +615,8 @@ lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
links++;
- zlog_info ("PointToMultipoint: running ptomultip_set");
+ if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
+ zlog_info ("PointToMultipoint: running ptomultip_set");
/* Search neighbor, */
for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
@@ -628,8 +629,9 @@ lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
link_info_set (s, nbr->router_id, oi->address->u.prefix4,
LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
links++;
- zlog_info ("PointToMultipoint: set link to %s",
- inet_ntoa(oi->address->u.prefix4));
+ if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
+ zlog_info ("PointToMultipoint: set link to %s",
+ inet_ntoa(oi->address->u.prefix4));
}
return links;
@@ -648,7 +650,7 @@ router_lsa_link_set (struct stream *s, struct ospf_area *area)
struct interface *ifp = oi->ifp;
/* Check interface is up, OSPF is enable. */
- if (if_is_up (ifp))
+ if (if_is_operative (ifp))
{
if (oi->state != ISM_Down)
{
@@ -1402,7 +1404,7 @@ ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
{
struct ospf_interface *oi = getdata (n1);
- if (if_is_up (oi->ifp))
+ if (if_is_operative (oi->ifp))
if (oi->address->family == AF_INET)
if (prefix_match (oi->address, &nh))
return nexthop;
@@ -1423,7 +1425,7 @@ ospf_get_ip_from_ifp (struct ospf_interface *oi)
fwd.s_addr = 0;
- if (if_is_up (oi->ifp))
+ if (if_is_operative (oi->ifp))
return oi->address->u.prefix4;
return fwd;
@@ -1444,7 +1446,7 @@ ospf_get_nssa_ip (struct ospf_area *area)
{
struct ospf_interface *oi = getdata (n1);
- if (if_is_up (oi->ifp))
+ if (if_is_operative (oi->ifp))
if (oi->area->external_routing == OSPF_AREA_NSSA)
if (oi->address && oi->address->family == AF_INET)
{
@@ -1454,6 +1456,8 @@ ospf_get_nssa_ip (struct ospf_area *area)
return oi->address->u.prefix4;
}
}
+ if (best_default.s_addr != 0)
+ return best_default;
if (best_default.s_addr != 0)
return best_default;
@@ -1632,7 +1636,6 @@ ospf_install_flood_nssa (struct ospf *ospf,
/* make lsa duplicate, lock=1 */
new2 = ospf_lsa_dup (lsa);
-
new2->area = area;
new2->data->type = OSPF_AS_NSSA_LSA;
@@ -1662,13 +1665,13 @@ ospf_install_flood_nssa (struct ospf *ospf,
if (extlsa->e[0].fwd_addr.s_addr == 0)
extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
- if (IS_DEBUG_OSPF_NSSA)
- if (extlsa->e[0].fwd_addr.s_addr == 0)
- {
- zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
- ospf_lsa_discard(new2);
- return;
- }
+ if (extlsa->e[0].fwd_addr.s_addr == 0)
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
+ ospf_lsa_discard(new2);
+ return;
+ }
}
/* Re-calculate checksum. */
ospf_lsa_checksum (new2->data);
@@ -1857,6 +1860,39 @@ ospf_default_originate_timer (struct thread *thread)
return 0;
}
+#ifdef HAVE_NSSA
+/* Flush any NSSA LSAs for given prefix */
+void
+ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
+{
+ struct listnode *node;
+ struct ospf_lsa *lsa;
+ struct ospf_area *area;
+
+ for (node = listhead (ospf->areas); node; nextnode (node))
+ {
+ if (((area = getdata (node)) != NULL)
+ && (area->external_routing == OSPF_AREA_NSSA))
+ {
+ if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
+ ospf->router_id)))
+ {
+ if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
+ zlog_warn ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
+ inet_ntoa (p->prefix), p->prefixlen);
+ continue;
+ }
+ ospf_ls_retransmit_delete_nbr_area (area, lsa);
+ if (!IS_LSA_MAXAGE (lsa))
+ {
+ ospf_refresher_unregister_lsa (ospf, lsa);
+ ospf_lsa_flush_area (lsa, area);
+ }
+ }
+ }
+}
+#endif /* HAVE_NSSA */
+
/* Flush an AS-external-LSA from LSDB and routing domain. */
void
ospf_external_lsa_flush (struct ospf *ospf,
@@ -1877,6 +1913,13 @@ ospf_external_lsa_flush (struct ospf *ospf,
inet_ntoa (p->prefix), p->prefixlen);
return;
}
+#ifdef HAVE_NSSA
+ /* If LSA is selforiginated and there is NSSA area, flush
+ * Type-7 LSA's at first. */
+
+ if (IS_LSA_SELF(lsa) && (ospf->anyNSSA))
+ ospf_nssa_lsa_flush (ospf, p);
+#endif /* HAVE_NSSA */
/* Sweep LSA from Link State Retransmit List. */
ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
@@ -2186,6 +2229,13 @@ ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
ospf_ase_incremental_update (ospf, new);
}
+#ifdef HAVE_NSSA
+ /* There is no point to register selforiginate Type-7 LSA for
+ * refreshing. We rely on refreshing Type-5 LSA's */
+ if (IS_LSA_SELF (new) && (new->data->type == OSPF_AS_NSSA_LSA))
+ return new;
+#endif /* HAVE_NSSA */
+
/* Register self-originated LSA to refresh queue. */
if (IS_LSA_SELF (new))
ospf_refresher_register_lsa (ospf, new);
@@ -2216,6 +2266,12 @@ ospf_discard_from_db (struct ospf *ospf,
ospf_ls_retransmit_delete_nbr_as (ospf, old);
ospf_ase_unregister_external_lsa (old, ospf);
break;
+#ifdef HAVE_NSSA
+ case OSPF_AS_NSSA_LSA:
+ ospf_ls_retransmit_delete_nbr_area (old->area, old);
+ ospf_ase_unregister_external_lsa (old, ospf);
+ break;
+#endif /* HAVE_NSSA */
default:
ospf_ls_retransmit_delete_nbr_area (old->area, old);
break;
@@ -2587,7 +2643,6 @@ ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
ospf_spf_calculate_schedule (ospf);
break;
}
-
ospf_lsa_maxage (ospf, lsa);
}
@@ -2623,9 +2678,13 @@ ospf_lsa_maxage_walker (struct thread *thread)
LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
ospf_lsa_maxage_walker_remover (ospf, lsa);
#endif /* HAVE_OPAQUE_LSA */
+#ifdef HAVE_NSSA
+ LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
+ ospf_lsa_maxage_walker_remover (ospf, lsa);
+#endif /* HAVE_NSSA */
}
- /* for AS-eternal-LSAs. */
+ /* for AS-external-LSAs. */
if (ospf->lsdb)
{
LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
@@ -2676,6 +2735,9 @@ struct ospf_lsa *
ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
struct in_addr id, struct in_addr adv_router)
{
+ struct ospf *ospf = ospf_lookup();
+ assert(ospf);
+
switch (type)
{
case OSPF_ROUTER_LSA:
@@ -2695,7 +2757,7 @@ ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
#ifdef HAVE_OPAQUE_LSA
case OSPF_OPAQUE_AS_LSA:
#endif /* HAVE_OPAQUE_LSA */
- return ospf_lsdb_lookup_by_id (area->ospf->lsdb, type, id, adv_router);
+ return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
break;
default:
break;
@@ -2840,7 +2902,7 @@ ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
if (l1->data->length == 0)
return 1;
- assert (l1->data->length > OSPF_LSA_HEADER_SIZE);
+ assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
p1 = (char *) l1->data;
p2 = (char *) l2->data;
@@ -3218,9 +3280,9 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
case OSPF_OPAQUE_AS_LSA:
ospf_opaque_lsa_refresh (lsa);
break;
+#endif /* HAVE_OPAQUE_LSA */
default:
break;
-#endif /* HAVE_OPAQUE_LSA */
}
}
@@ -3260,6 +3322,8 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
ospf->lsa_refresh_queue.qs[index] = list_new ();
listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
lsa->refresh_list = index;
+ if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
+ zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index);
}
}
@@ -3324,7 +3388,7 @@ ospf_lsa_refresh_walker (struct thread *t)
next = node->next;
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
- zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p", lsa);
+ zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i);
list_delete_node (refresh_list, node);
ospf_lsa_unlock (lsa);