void ospf_abr_process_network_rt (struct ospf *ospf, struct route_table *rt) { struct ospf_area *area; struct ospf_route *or; struct route_node *rn; if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt(): Start"); for (rn = route_top (rt); rn; rn = route_next (rn)) { if ((or = rn->info) == NULL) continue; if (!(area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt(): area %s no longer exists", inet_ntoa (or->u.std.area_id)); continue; } if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt(): this is a route to %s/%d", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen); if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt(): " "this is an External router, skipping"); continue; } if (or->cost >= OSPF_LS_INFINITY) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt():" " this route's cost is infinity, skipping"); continue; } if (or->type == OSPF_DESTINATION_DISCARD) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt():" " this is a discard entry, skipping"); continue; } if (or->path_type == OSPF_PATH_INTRA_AREA && !ospf_abr_should_announce (ospf, &rn->p, or)) { if (IS_DEBUG_OSPF_EVENT) zlog_info("ospf_abr_process_network_rt(): denied by export-list"); continue; } if (or->path_type == OSPF_PATH_INTRA_AREA && !ospf_abr_plist_out_check (area, or, &rn->p)) { if (IS_DEBUG_OSPF_EVENT) zlog_info("ospf_abr_process_network_rt(): denied by prefix-list"); continue; } if ((or->path_type == OSPF_PATH_INTER_AREA) && !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt():" " this is route is not backbone one, skipping"); continue; } if ((ospf->abr_type == OSPF_ABR_CISCO) || (ospf->abr_type == OSPF_ABR_IBM)) if (!ospf_act_bb_connection (ospf) && or->path_type != OSPF_PATH_INTRA_AREA) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt(): ALT ABR: " "No BB connection, skip not intra-area routes"); continue; } if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt(): announcing"); ospf_abr_announce_network (ospf, rn, or); } if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_network_rt(): Stop"); }
static void ospf_update_network_route (struct ospf *ospf, struct route_table *rt, struct route_table *rtrs, struct summary_lsa *lsa, struct prefix_ipv4 *p, struct ospf_area *area) { struct route_node *rn; struct ospf_route *or, *abr_or, *new_or; struct prefix_ipv4 abr; u_int32_t cost; abr.family = AF_INET; abr.prefix =lsa->header.adv_router; abr.prefixlen = IPV4_MAX_BITLEN; apply_mask_ipv4 (&abr); abr_or = ospf_find_abr_route (rtrs, &abr, area); if (abr_or == NULL) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_update_network_route(): can't find a route to the ABR"); return; } cost = abr_or->cost + GET_METRIC (lsa->metric); rn = route_node_lookup (rt, (struct prefix *) p); if (! rn) { if (ospf->abr_type != OSPF_ABR_SHORTCUT) return; /* Standard ABR can update only already installed backbone paths */ if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_update_network_route(): " "Allowing Shortcut ABR to add new route"); new_or = ospf_route_new (); new_or->type = OSPF_DESTINATION_NETWORK; new_or->id = lsa->header.id; new_or->mask = lsa->mask; new_or->u.std.options = lsa->header.options; new_or->u.std.origin = (struct lsa_header *) lsa; new_or->cost = cost; new_or->u.std.area_id = area->area_id; new_or->u.std.external_routing = area->external_routing; new_or->path_type = OSPF_PATH_INTER_AREA; ospf_route_add (rt, p, new_or, abr_or); return; } else { route_unlock_node (rn); if (rn->info == NULL) return; } or = rn->info; if (or->path_type != OSPF_PATH_INTRA_AREA && or->path_type != OSPF_PATH_INTER_AREA) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_update_network_route(): ERR: path type is wrong"); return; } if (ospf->abr_type == OSPF_ABR_SHORTCUT) { if (or->path_type == OSPF_PATH_INTRA_AREA && !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_update_network_route(): Shortcut: " "this intra-area path is not backbone"); return; } } else /* Not Shortcut ABR */ { if (!OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_update_network_route(): " "route is not BB-associated"); return; /* We can update only BB routes */ } } if (or->cost < cost) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_update_network_route(): new route is worse"); return; } if (or->cost == cost) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_update_network_route(): " "new route is same distance, adding nexthops"); ospf_route_copy_nexthops (or, abr_or->paths); } if (or->cost > cost) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_update_network_route(): " "new route is better, overriding nexthops"); ospf_route_subst_nexthops (or, abr_or->paths); or->cost = cost; if ((ospf->abr_type == OSPF_ABR_SHORTCUT) && !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) { or->path_type = OSPF_PATH_INTER_AREA; or->u.std.area_id = area->area_id; or->u.std.external_routing = area->external_routing; /* Note that we can do this only in Shortcut ABR mode, because standard ABR must leave the route type and area unchanged */ } } }
void ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt) { struct ospf_route *or; struct route_node *rn; struct list *l; if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_router_rt(): Start"); for (rn = route_top (rt); rn; rn = route_next (rn)) { listnode node; char flag = 0; struct ospf_route *best = NULL; if (rn->info == NULL) continue; l = rn->info; if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_router_rt(): this is a route to %s", inet_ntoa (rn->p.u.prefix4)); for (node = listhead (l); node; nextnode (node)) { or = getdata (node); if (or == NULL) continue; if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id)) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_router_rt(): area %s no longer exists", inet_ntoa (or->u.std.area_id)); continue; } if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL)) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_router_rt(): " "This is not an ASBR, skipping"); continue; } if (!flag) { best = ospf_find_asbr_route (ospf, rt, (struct prefix_ipv4 *) &rn->p); flag = 1; } if (best == NULL) continue; if (or != best) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_router_rt(): " "This route is not the best among possible, skipping"); continue; } if (or->path_type == OSPF_PATH_INTER_AREA && !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_router_rt(): " "This route is not a backbone one, skipping"); continue; } if (or->cost >= OSPF_LS_INFINITY) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_router_rt(): " "This route has LS_INFINITY metric, skipping"); continue; } if (ospf->abr_type == OSPF_ABR_CISCO || ospf->abr_type == OSPF_ABR_IBM) if (!ospf_act_bb_connection (ospf) && or->path_type != OSPF_PATH_INTRA_AREA) { if (IS_DEBUG_OSPF_EVENT) zlog_info("ospf_abr_process_network_rt(): ALT ABR: " "No BB connection, skip not intra-area routes"); continue; } ospf_abr_announce_rtr (ospf, (struct prefix_ipv4 *) &rn->p, or); } } if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_abr_process_router_rt(): Stop"); }