summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_intra.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2016-03-30 13:44:03 +0300
committerTimo Teräs <timo.teras@iki.fi>2016-03-30 14:29:40 +0300
commit8cb40c91cdfb00ddf04e88d3ecd40403890d90f7 (patch)
tree6d6a3de27525820abb740f1fa8347b6f03986bad /ospf6d/ospf6_intra.c
parent86c5d2ee68f7b9c00ae4aeb5c8b3c5d82c5ebffc (diff)
downloadquagga-8cb40c91cdfb00ddf04e88d3ecd40403890d90f7.tar.bz2
quagga-8cb40c91cdfb00ddf04e88d3ecd40403890d90f7.tar.xz
cumulus take-3cumulus-take-3
Diffstat (limited to 'ospf6d/ospf6_intra.c')
-rw-r--r--ospf6d/ospf6_intra.c142
1 files changed, 76 insertions, 66 deletions
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 6606c96d..f2cade22 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -140,6 +140,31 @@ ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
return 0;
}
+static void
+ospf6_router_lsa_options_set (struct ospf6_area *oa,
+ struct ospf6_router_lsa *router_lsa)
+{
+ OSPF6_OPT_CLEAR_ALL (router_lsa->options);
+ memcpy (router_lsa->options, oa->options, 3);
+
+ if (ospf6_is_router_abr (ospf6))
+ SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
+ else
+ UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
+
+ if (!IS_AREA_STUB (oa) && ospf6_asbr_is_asbr (oa->ospf6))
+ {
+ SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
+ }
+ else
+ {
+ UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
+ }
+
+ UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
+ UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
+}
+
int
ospf6_router_is_stub_router (struct ospf6_lsa *lsa)
{
@@ -194,23 +219,7 @@ ospf6_router_lsa_originate (struct thread *thread)
router_lsa = (struct ospf6_router_lsa *)
((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
- OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
- OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
- OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
- OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
- OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
- OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
-
- if (ospf6_is_router_abr (ospf6))
- SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
- else
- UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
- if (ospf6_asbr_is_asbr (ospf6))
- SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
- else
- UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
- UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
- UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
+ ospf6_router_lsa_options_set (oa, router_lsa);
/* describe links for each interfaces */
lsdesc = (struct ospf6_router_lsdesc *)
@@ -228,7 +237,7 @@ ospf6_router_lsa_originate (struct thread *thread)
for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
if (on->state == OSPF6_NEIGHBOR_FULL)
count++;
-
+
if (count == 0)
continue;
@@ -246,30 +255,6 @@ ospf6_router_lsa_originate (struct thread *thread)
return 0;
}
- /* Fill LSA Header */
- lsa_header->age = 0;
- lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
- lsa_header->id = htonl (link_state_id);
- lsa_header->adv_router = oa->ospf6->router_id;
- lsa_header->seqnum =
- ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
- lsa_header->adv_router, oa->lsdb);
- lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
-
- /* LSA checksum */
- ospf6_lsa_checksum (lsa_header);
-
- /* create LSA */
- lsa = ospf6_lsa_create (lsa_header);
-
- /* Originate */
- ospf6_lsa_originate_area (lsa, oa);
-
- /* Reset setting for consecutive origination */
- memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
- 0, (caddr_t) lsdesc - (caddr_t) router_lsa);
- lsdesc = (struct ospf6_router_lsdesc *)
- ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
link_state_id ++;
}
@@ -338,7 +323,7 @@ ospf6_router_lsa_originate (struct thread *thread)
lsa_header->adv_router = oa->ospf6->router_id;
lsa_header->seqnum =
ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
- lsa_header->adv_router, oa->lsdb);
+ lsa_header->adv_router, oa->lsdb);
lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
/* LSA checksum */
@@ -355,14 +340,25 @@ ospf6_router_lsa_originate (struct thread *thread)
/* Do premature-aging of rest, undesired Router-LSAs */
type = ntohs (OSPF6_LSTYPE_ROUTER);
router = oa->ospf6->router_id;
+ count = 0;
for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
lsa = ospf6_lsdb_type_router_next (type, router, lsa))
{
if (ntohl (lsa->header->id) < link_state_id)
continue;
ospf6_lsa_purge (lsa);
+ count++;
}
+ /*
+ * Waiting till the LSA is actually removed from the database to trigger
+ * SPF delays network convergence. Unlike IPv4, for an ABR, when all
+ * interfaces associated with an area are gone, triggering an SPF right away
+ * helps convergence with inter-area routes.
+ */
+ if (count && !link_state_id)
+ ospf6_spf_schedule (oa->ospf6, OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED);
+
return 0;
}
@@ -459,7 +455,15 @@ ospf6_network_lsa_originate (struct thread *thread)
if (oi->state != OSPF6_INTERFACE_DR)
{
if (old)
- ospf6_lsa_purge (old);
+ {
+ ospf6_lsa_purge (old);
+ /*
+ * Waiting till the LSA is actually removed from the database to
+ * trigger SPF delays network convergence.
+ */
+ ospf6_spf_schedule (oi->area->ospf6,
+ OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED);
+ }
return 0;
}
@@ -468,11 +472,11 @@ ospf6_network_lsa_originate (struct thread *thread)
/* If none of neighbor is adjacent to us */
count = 0;
-
+
for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
if (on->state == OSPF6_NEIGHBOR_FULL)
count++;
-
+
if (count == 0)
{
if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
@@ -1078,7 +1082,7 @@ ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
if (on->state == OSPF6_NEIGHBOR_FULL)
full_count++;
-
+
if (full_count == 0)
{
if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
@@ -1214,7 +1218,7 @@ ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
struct prefix ls_prefix;
struct ospf6_route *route, *ls_entry;
- int i, prefix_num;
+ int prefix_num;
struct ospf6_prefix *op;
char *start, *current, *end;
char buf[64];
@@ -1275,14 +1279,13 @@ ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
break;
/* Appendix A.4.1.1 */
- if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU) ||
- CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_LA))
+ if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU))
{
if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
{
ospf6_linkstate_prefix2str ((struct prefix *)OSPF6_PREFIX_BODY(op),
buf, sizeof (buf));
- zlog_debug ("%s: Skipping Prefix %s has NU/LA option set",
+ zlog_debug ("%s: Skipping Prefix %s has NU option set",
__func__, buf);
}
continue;
@@ -1310,13 +1313,11 @@ ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
{
ifp = if_lookup_prefix(&route->prefix);
if (ifp)
- route->nexthop[0].ifindex = ifp->ifindex;
+ ospf6_route_add_nexthop (route, ifp->ifindex, NULL);
}
else
{
- for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) &&
- i < OSPF6_MULTI_PATH_LIMIT; i++)
- ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
+ ospf6_route_copy_nexthops (route, ls_entry);
}
if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
@@ -1339,7 +1340,7 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
struct ospf6_area *oa;
struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
struct prefix prefix;
- struct ospf6_route *route;
+ struct ospf6_route *route, *nroute;
int prefix_num;
struct ospf6_prefix *op;
char *start, *current, *end;
@@ -1377,8 +1378,9 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
for (ospf6_route_lock (route);
route && ospf6_route_is_prefix (&prefix, route);
- route = ospf6_route_next (route))
+ route = nroute)
{
+ nroute = ospf6_route_next (route);
if (route->type != OSPF6_DEST_TYPE_NETWORK)
continue;
if (route->path.area_id != oa->area_id)
@@ -1408,7 +1410,7 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
void
ospf6_intra_route_calculation (struct ospf6_area *oa)
{
- struct ospf6_route *route;
+ struct ospf6_route *route, *nroute;
u_int16_t type;
struct ospf6_lsa *lsa;
void (*hook_add) (struct ospf6_route *) = NULL;
@@ -1435,8 +1437,9 @@ ospf6_intra_route_calculation (struct ospf6_area *oa)
oa->route_table->hook_remove = hook_remove;
for (route = ospf6_route_head (oa->route_table); route;
- route = ospf6_route_next (route))
+ route = nroute)
{
+ nroute = ospf6_route_next (route);
if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
{
@@ -1452,7 +1455,11 @@ ospf6_intra_route_calculation (struct ospf6_area *oa)
if (hook_add)
(*hook_add) (route);
}
-
+ else
+ {
+ /* Redo the summaries as things might have changed */
+ ospf6_abr_originate_summary (route);
+ }
route->flag = 0;
}
@@ -1510,13 +1517,13 @@ ospf6_brouter_debug_print (struct ospf6_route *brouter)
id, adv_router);
zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
options, capa, brouter->path.metric_type,
- brouter->path.cost, brouter->path.cost_e2);
+ brouter->path.cost, brouter->path.u.cost_e2);
}
void
ospf6_intra_brouter_calculation (struct ospf6_area *oa)
{
- struct ospf6_route *brouter, *copy;
+ struct ospf6_route *brouter, *nbrouter, *copy;
void (*hook_add) (struct ospf6_route *) = NULL;
void (*hook_remove) (struct ospf6_route *) = NULL;
u_int32_t brouter_id;
@@ -1538,7 +1545,7 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa)
inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
if (brouter->path.area_id != oa->area_id)
continue;
- brouter->flag = OSPF6_ROUTE_REMOVE;
+ SET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
IS_OSPF6_DEBUG_ROUTE (MEMORY))
@@ -1585,8 +1592,9 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa)
oa->ospf6->brouter_table->hook_remove = hook_remove;
for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
- brouter = ospf6_route_next (brouter))
+ brouter = nbrouter)
{
+ nbrouter = ospf6_route_next (brouter);
brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
@@ -1631,9 +1639,11 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa)
IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
zlog_info ("brouter %s still exists via area %s",
brouter_name, oa->name);
+ /* But re-originate summaries */
+ ospf6_abr_originate_summary (brouter);
}
-
- brouter->flag = 0;
+ UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
+ UNSET_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE);
}
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))