📄 ospf_ia.c
字号:
} or = rn->info; if (or->path_type != OSPF_PATH_INTRA_AREA && or->path_type != OSPF_PATH_INTER_AREA) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("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_info ("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_info ("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_info ("ospf_update_network_route(): new route is worse"); return; } if (or->cost == cost) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_update_network_route(): " "new route is same distance, adding nexthops"); ospf_route_copy_nexthops (or, abr_or->path); } if (or->cost > cost) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_update_network_route(): " "new route is better, overriding nexthops"); ospf_route_subst_nexthops (or, abr_or->path); 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;#ifdef HAVE_NSSA or->u.std.external_routing = area->external_routing;#endif /* HAVE_NSSA */ /* Note that we can do this only in Shortcut ABR mode, because standard ABR must leave the route type and area unchanged */ } }}voidospf_update_router_route (struct ospf *ospf, struct route_table *rtrs, struct summary_lsa *lsa, struct prefix_ipv4 *p, struct ospf_area *area){ 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_info ("ospf_update_router_route(): can't find a route to the ABR"); return; } cost = abr_or->cost + GET_METRIC (lsa->metric); /* First try to find a backbone path, because standard ABR can update only BB-associated paths */ if ((ospf->backbone == NULL) && (ospf->abr_type != OSPF_ABR_SHORTCUT)) /* no BB area, not Shortcut ABR, exiting */ return; or = ospf_find_asbr_route_through_area (rtrs, p, ospf->backbone); if (or == NULL) { if (ospf->abr_type != OSPF_ABR_SHORTCUT) /* route to ASBR through the BB not found the router is not Shortcut ABR, exiting */ return; else /* We're a Shortcut ABR*/ { /* Let it either add a new router or update the route through the same (non-BB) area. */ new_or = ospf_route_new (); new_or->type = OSPF_DESTINATION_ROUTER; 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;#ifdef HAVE_NSSA new_or->u.std.external_routing = area->external_routing;#endif /* HAVE_NSSA */ new_or->path_type = OSPF_PATH_INTER_AREA; new_or->u.std.flags = ROUTER_LSA_EXTERNAL; ospf_ia_router_route (ospf, rtrs, p, new_or, abr_or); return; } } /* At this point the "or" is always bb-associated */ if (!(or->u.std.flags & ROUTER_LSA_EXTERNAL)) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_upd_router_route(): the remote router is not an ASBR"); return; } if (or->path_type != OSPF_PATH_INTRA_AREA && or->path_type != OSPF_PATH_INTER_AREA) return; if (or->cost < cost) return; else if (or->cost == cost) ospf_route_copy_nexthops (or, abr_or->path); else if (or->cost > cost) { ospf_route_subst_nexthops (or, abr_or->path); or->cost = cost; /* Even if the ABR runs in Shortcut mode, we can't change the path type and area, because the "or" is always bb-associated at this point and even Shortcut ABR can't change these attributes */ }}intprocess_transit_summary_lsa (struct ospf_area *area, struct route_table *rt, struct route_table *rtrs, struct ospf_lsa *lsa){ struct ospf *ospf = area->ospf; struct summary_lsa *sl; struct prefix_ipv4 p; u_int32_t metric; if (lsa == NULL) return 0; sl = (struct summary_lsa *) lsa->data; if (IS_DEBUG_OSPF_EVENT) zlog_info ("process_transit_summaries(): LS ID: %s", inet_ntoa (lsa->data->id)); metric = GET_METRIC (sl->metric); if (metric == OSPF_LS_INFINITY) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("process_transit_summaries(): metric is infinity, skip"); return 0; } if (IS_LSA_MAXAGE (lsa)) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("process_transit_summaries(): This LSA is too old"); return 0; } if (ospf_lsa_is_self_originated (area->ospf, lsa)) { if (IS_DEBUG_OSPF_EVENT) zlog_info ("process_transit_summaries(): This LSA is mine, skip"); return 0; } p.family = AF_INET; p.prefix = sl->header.id; if (sl->header.type == OSPF_SUMMARY_LSA) p.prefixlen = ip_masklen (sl->mask); else p.prefixlen = IPV4_MAX_BITLEN; apply_mask_ipv4 (&p); if (sl->header.type == OSPF_SUMMARY_LSA) ospf_update_network_route (ospf, rt, rtrs, sl, &p, area); else ospf_update_router_route (ospf, rtrs, sl, &p, area); return 0;}voidospf_examine_transit_summaries (struct ospf_area *area, struct route_table *lsdb_rt, struct route_table *rt, struct route_table *rtrs){ struct ospf_lsa *lsa; struct route_node *rn; LSDB_LOOP (lsdb_rt, rn, lsa) process_transit_summary_lsa (area, rt, rtrs, lsa);}voidospf_ia_routing (struct ospf *ospf, struct route_table *rt, struct route_table *rtrs){ struct ospf_area * area; if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_ia_routing():start"); if (IS_OSPF_ABR (ospf)) { listnode node; struct ospf_area *area; switch (ospf->abr_type) { case OSPF_ABR_STAND: if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_ia_routing():Standard ABR"); if ((area = ospf->backbone)) { listnode node; if (IS_DEBUG_OSPF_EVENT) { zlog_info ("ospf_ia_routing():backbone area found"); zlog_info ("ospf_ia_routing():examining summaries"); } OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); for (node = listhead (ospf->areas); node; nextnode (node)) if ((area = getdata (node)) != NULL) if (area != ospf->backbone) if (ospf_area_is_transit (area)) OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs); } else if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_ia_routing():backbone area NOT found"); break; case OSPF_ABR_IBM: case OSPF_ABR_CISCO: if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_ia_routing():Alternative Cisco/IBM ABR"); area = ospf->backbone; /* Find the BB */ /* If we have an active BB connection */ if (area && ospf_act_bb_connection (ospf)) { if (IS_DEBUG_OSPF_EVENT) { zlog_info ("ospf_ia_routing(): backbone area found"); zlog_info ("ospf_ia_routing(): examining BB summaries"); } OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); for (node = listhead (ospf->areas); node; nextnode (node)) if ((area = getdata (node)) != NULL) if (area != ospf->backbone) if (ospf_area_is_transit (area)) OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs); } else { /* No active BB connection--consider all areas */ if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_ia_routing(): " "Active BB connection not found"); for (node = listhead (ospf->areas); node; nextnode (node)) if ((area = getdata (node)) != NULL) OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); } break; case OSPF_ABR_SHORTCUT: if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_ia_routing():Alternative Shortcut"); area = ospf->backbone; /* Find the BB */ /* If we have an active BB connection */ if (area && ospf_act_bb_connection (ospf)) { if (IS_DEBUG_OSPF_EVENT) { zlog_info ("ospf_ia_routing(): backbone area found"); zlog_info ("ospf_ia_routing(): examining BB summaries"); } OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); } for (node = listhead (ospf->areas); node; nextnode (node)) if ((area = getdata (node)) != NULL) if (area != ospf->backbone) if (ospf_area_is_transit (area) || ((area->shortcut_configured != OSPF_SHORTCUT_DISABLE) && ((ospf->backbone == NULL) || ((area->shortcut_configured == OSPF_SHORTCUT_ENABLE) && area->shortcut_capability)))) OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs); break; default: break; } } else { listnode node; if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_ia_routing():not ABR, considering all areas"); for (node = listhead (ospf->areas); node; nextnode (node)) if ((area = getdata (node)) != NULL) OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -