void ospf6_abr_enable_area (struct ospf6_area *area) { struct ospf6_area *oa; struct ospf6_route *ro; struct listnode *node, *nnode; for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa)) { /* update B bit for each area */ OSPF6_ROUTER_LSA_SCHEDULE (oa); /* install other area's configured address range */ if (oa != area) { for (ro = ospf6_route_head (oa->range_table); ro; ro = ospf6_route_next (ro)) { if (CHECK_FLAG (ro->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)) ospf6_abr_originate_summary_to_area (ro, area); } } } /* install calculated routes to border routers */ for (ro = ospf6_route_head (area->ospf6->brouter_table); ro; ro = ospf6_route_next (ro)) ospf6_abr_originate_summary_to_area (ro, area); /* install calculated routes to network (may be rejected by ranges) */ for (ro = ospf6_route_head (area->ospf6->route_table); ro; ro = ospf6_route_next (ro)) ospf6_abr_originate_summary_to_area (ro, area); }
void ospf6_abr_disable_area (struct ospf6_area *area) { struct ospf6_area *oa; struct ospf6_route *ro; struct ospf6_lsa *old; struct listnode *node, *nnode; /* Withdraw all summary prefixes previously originated */ for (ro = ospf6_route_head (area->summary_prefix); ro; ro = ospf6_route_next (ro)) { old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id, area->ospf6->router_id, area->lsdb); if (old) ospf6_lsa_purge (old); ospf6_route_remove (ro, area->summary_prefix); } /* Withdraw all summary router-routes previously originated */ for (ro = ospf6_route_head (area->summary_router); ro; ro = ospf6_route_next (ro)) { old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id, area->ospf6->router_id, area->lsdb); if (old) ospf6_lsa_purge (old); ospf6_route_remove (ro, area->summary_router); } /* Schedule Router-LSA for each area (ABR status may change) */ for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa)) /* update B bit for each area */ OSPF6_ROUTER_LSA_SCHEDULE (oa); }
void ospf6_spf_table_finish (struct ospf6_route_table *result_table) { struct ospf6_route *route; struct ospf6_vertex *v; for (route = ospf6_route_head (result_table); route; route = ospf6_route_next (route)) { v = (struct ospf6_vertex *) route->route_option; ospf6_vertex_delete (v); ospf6_route_remove (route, result_table); } }
/* Make new area structure */ struct ospf6_area * ospf6_area_create (u_int32_t area_id, struct ospf6 *o) { struct ospf6_area *oa; struct ospf6_route *route; oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area)); inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name)); oa->area_id = area_id; oa->if_list = list_new (); oa->lsdb = ospf6_lsdb_create (oa); oa->lsdb->hook_add = ospf6_area_lsdb_hook_add; oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove; oa->lsdb_self = ospf6_lsdb_create (oa); oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS); oa->spf_table->scope = oa; oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES); oa->route_table->scope = oa; oa->route_table->hook_add = ospf6_area_route_hook_add; oa->route_table->hook_remove = ospf6_area_route_hook_remove; oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES); oa->range_table->scope = oa; oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES); oa->summary_prefix->scope = oa; oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS); oa->summary_router->scope = oa; /* set default options */ OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6); OSPF6_OPT_SET (oa->options, OSPF6_OPT_E); OSPF6_OPT_SET (oa->options, OSPF6_OPT_R); oa->ospf6 = o; listnode_add_sort (o->area_list, oa); /* import athoer area's routes as inter-area routes */ for (route = ospf6_route_head (o->route_table); route; route = ospf6_route_next (route)) ospf6_abr_originate_summary_to_area (route, oa); return oa; }
static void ospf6_asbr_redistribute_unset (int type) { struct ospf6_route *route; struct ospf6_external_info *info; ospf6_zebra_no_redistribute (type); for (route = ospf6_route_head (ospf6->external_table); route; route = ospf6_route_next (route)) { info = route->route_option; if (info->type != type) continue; ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex, &route->prefix); } }
static u_char * ospfv3AreaEntry (struct variable *v, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { struct ospf6_area *oa, *area = NULL; struct ospf6_lsa *lsa = NULL; u_int32_t area_id = 0; u_int32_t count; u_int16_t sum; struct listnode *node; unsigned int len; char a[16]; struct ospf6_route *ro; if (ospf6 == NULL) return NULL; if (smux_header_table(v, name, length, exact, var_len, write_method) == MATCH_FAILED) return NULL; len = *length - v->namelen; len = (len >= 1 ? sizeof 1 : 0); if (exact && len != 1) return NULL; if (len) area_id = htonl (name[v->namelen]); inet_ntop (AF_INET, &area_id, a, sizeof (a)); zlog_debug ("SNMP access by area: %s, exact=%d len=%d length=%lu", a, exact, len, (u_long)*length); for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) { if (area == NULL) { if (len == 0) /* return first area entry */ area = oa; else if (exact && ntohl (oa->area_id) == ntohl (area_id)) area = oa; else if (ntohl (oa->area_id) > ntohl (area_id)) area = oa; } } if (area == NULL) return NULL; *length = v->namelen + 1; name[v->namelen] = ntohl (area->area_id); inet_ntop (AF_INET, &area->area_id, a, sizeof (a)); zlog_debug ("SNMP found area: %s, exact=%d len=%d length=%lu", a, exact, len, (u_long)*length); switch (v->magic) { case OSPFv3IMPORTASEXTERN: /* No NSSA support */ return SNMP_INTEGER (IS_AREA_STUB(area)?2:1); case OSPFv3AREASPFRUNS: return SNMP_INTEGER (area->spf_calculation); case OSPFv3AREABDRRTRCOUNT: case OSPFv3AREAASBDRRTRCOUNT: count = 0; for (ro = ospf6_route_head (ospf6->brouter_table); ro; ro = ospf6_route_next (ro)) { if (ntohl (ro->path.area_id) != ntohl (area->area_id)) continue; if (v->magic == OSPFv3AREABDRRTRCOUNT && CHECK_FLAG (ro->path.router_bits, OSPF6_ROUTER_BIT_B)) count++; if (v->magic == OSPFv3AREAASBDRRTRCOUNT && CHECK_FLAG (ro->path.router_bits, OSPF6_ROUTER_BIT_E)) count++; } return SNMP_INTEGER (count); case OSPFv3AREASCOPELSACOUNT: return SNMP_INTEGER (area->lsdb->count); case OSPFv3AREASCOPELSACKSUMSUM: for (sum = 0, lsa = ospf6_lsdb_head (area->lsdb); lsa; lsa = ospf6_lsdb_next (lsa)) sum += ntohs (lsa->header->checksum); return SNMP_INTEGER (sum); case OSPFv3AREASUMMARY: return SNMP_INTEGER (2); /* sendAreaSummary */ case OSPFv3AREAROWSTATUS: return SNMP_INTEGER (1); /* Active */ case OSPFv3AREASTUBMETRIC: case OSPFv3AREANSSATRANSLATORROLE: case OSPFv3AREANSSATRANSLATORSTATE: case OSPFv3AREANSSATRANSLATORSTABINTERVAL: case OSPFv3AREANSSATRANSLATOREVENTS: case OSPFv3AREASTUBMETRICTYPE: case OSPFv3AREATEENABLED: /* Not implemented. */ return NULL; } return NULL; }
static int ospf6_spf_calculation_thread (struct thread *t) { struct ospf6_area *oa; struct ospf6 *ospf6; struct timeval start, end, runtime; struct listnode *node; struct ospf6_route *route; int areas_processed = 0; char rbuf[32]; ospf6 = (struct ospf6 *)THREAD_ARG (t); ospf6->t_spf_calc = NULL; /* execute SPF calculation */ quagga_gettime (QUAGGA_CLK_MONOTONIC, &start); for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { if (oa == ospf6->backbone) continue; if (IS_OSPF6_DEBUG_SPF (PROCESS)) zlog_debug ("SPF calculation for Area %s", oa->name); if (IS_OSPF6_DEBUG_SPF (DATABASE)) ospf6_spf_log_database (oa); ospf6_spf_calculation (ospf6->router_id, oa->spf_table, oa); ospf6_intra_route_calculation (oa); ospf6_intra_brouter_calculation (oa); areas_processed++; } if (ospf6->backbone) { if (IS_OSPF6_DEBUG_SPF (PROCESS)) zlog_debug ("SPF calculation for Backbone area %s", ospf6->backbone->name); if (IS_OSPF6_DEBUG_SPF (DATABASE)) ospf6_spf_log_database(ospf6->backbone); ospf6_spf_calculation(ospf6->router_id, ospf6->backbone->spf_table, ospf6->backbone); ospf6_intra_route_calculation(ospf6->backbone); ospf6_intra_brouter_calculation(ospf6->backbone); areas_processed++; } /* Redo summaries if required */ for (route = ospf6_route_head (ospf6->route_table); route; route = ospf6_route_next (route)) ospf6_abr_originate_summary(route); quagga_gettime (QUAGGA_CLK_MONOTONIC, &end); timersub (&end, &start, &runtime); ospf6->ts_spf_duration = runtime; ospf6_spf_reason_string(ospf6->spf_reason, rbuf, sizeof(rbuf)); if (IS_OSPF6_DEBUG_SPF (PROCESS) || IS_OSPF6_DEBUG_SPF (TIME)) zlog_debug ("SPF runtime: %lld sec %lld usec", (long long)runtime.tv_sec, (long long)runtime.tv_usec); zlog_info("SPF processing: # Areas: %d, SPF runtime: %lld sec %lld usec, " "Reason: %s\n", areas_processed, (long long)runtime.tv_sec, (long long)runtime.tv_usec, rbuf); ospf6->last_spf_reason = ospf6->spf_reason; ospf6_reset_spf_reason(ospf6); return 0; }