diff options
author | Timo Teräs <timo.teras@iki.fi> | 2016-03-30 13:44:03 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2016-03-30 14:29:40 +0300 |
commit | 8cb40c91cdfb00ddf04e88d3ecd40403890d90f7 (patch) | |
tree | 6d6a3de27525820abb740f1fa8347b6f03986bad /ospf6d/ospf6_intra.c | |
parent | 86c5d2ee68f7b9c00ae4aeb5c8b3c5d82c5ebffc (diff) | |
download | quagga-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.c | 142 |
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)) |