📄 ospf6_abr.c
字号:
ospf6_lsdb_next (&node)) ospf6_abr_router_lsa_add (node.lsa);}voidospf6_abr_abr_entry_remove (struct ospf6_route_req *abr_entry){ struct ospf6_lsdb_node node; struct prefix_ls *abr_id; struct ospf6_area *area; if (IS_OSPF6_DUMP_ABR) zlog_info ("ABR: Area Border Router removed"); abr_id = (struct prefix_ls *) &abr_entry->route.prefix; area = ospf6_area_lookup (abr_entry->path.area_id, ospf6); if (! area) { if (IS_OSPF6_DUMP_ABR) zlog_info ("ABR: Can't find associated area"); return; } /* for each inter-prefix LSA this ABR originated */ for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_INTER_PREFIX), abr_id->adv_router.s_addr, area->lsdb); ! ospf6_lsdb_is_end (&node); ospf6_lsdb_next (&node)) ospf6_abr_prefix_lsa_remove (node.lsa); /* for each inter-router LSA this ABR originated */ for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_INTER_ROUTER), abr_id->adv_router.s_addr, area->lsdb); ! ospf6_lsdb_is_end (&node); ospf6_lsdb_next (&node)) ospf6_abr_router_lsa_remove (node.lsa);}/* Inter-Area-Prefix-LSA Origination */static voidospf6_abr_prefix_lsa_update_add (struct ospf6_route_req *request, struct ospf6_area *area){ char buffer [MAXLSASIZE]; u_int16_t size; struct ospf6_inter_area_prefix_lsa *iep; char *p; if (IS_OSPF6_DUMP_ABR) zlog_info ("Update Inter-Prefix for %s: ID: %lu", area->str, (u_long) ntohl (request->route_id)); /* prepare buffer */ memset (buffer, 0, sizeof (buffer)); size = sizeof (struct ospf6_inter_area_prefix_lsa); iep = (struct ospf6_inter_area_prefix_lsa *) buffer; p = (char *) (iep + 1); /* prefixlen */ iep->prefix.prefix_length = request->route.prefix.prefixlen; /* PrefixOptions */ iep->prefix.prefix_options = request->path.prefix_options; /* set Prefix */ memcpy (p, &request->route.prefix.u.prefix6, OSPF6_PREFIX_SPACE (request->route.prefix.prefixlen)); ospf6_prefix_apply_mask (&iep->prefix); size += OSPF6_PREFIX_SPACE (request->route.prefix.prefixlen); ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_INTER_PREFIX), htonl (request->route_id), ospf6->router_id, (char *) iep, size, area);}static voidospf6_abr_prefix_lsa_update_remove (struct ospf6_route_req *request, struct ospf6_area *area){ struct ospf6_lsa *lsa; lsa = ospf6_lsdb_lookup_lsdb (htons (OSPF6_LSA_TYPE_INTER_PREFIX), htonl (request->route_id), ospf6->router_id, area->lsdb); if (lsa) ospf6_lsa_premature_aging (lsa);}static voidospf6_abr_prefix_lsa_update (int type, struct ospf6_route_req *request){ struct ospf6_route_req route, target; listnode node; struct ospf6_area *area; struct ospf6_interface *o6i; if (request->route.type != OSPF6_DEST_TYPE_NETWORK) return; /* assert this is best path; if not, return */ ospf6_route_lookup (&route, &request->route.prefix, request->table); if (memcmp (&route.path, &request->path, sizeof (route.path))) return; if (target.path.cost >= LS_INFINITY || target.path.cost_e2 >= LS_INFINITY) { if (IS_OSPF6_DUMP_ABR) zlog_info ("ABR: Exceeds LS Infinity, ignore"); return; } ospf6_route_lookup (&target, &request->route.prefix, request->table); if (type == REMOVE) { ospf6_route_next (&route); if (! memcmp (&route.route, &request->route, sizeof (route.route))) { type = ADD; ospf6_route_next (&target); } } for (node = listhead (ospf6->area_list); node; nextnode (node)) { area = getdata (node); if (target.path.area_id == area->area_id) continue; o6i = ospf6_interface_lookup_by_index (target.nexthop.ifindex); if (o6i && o6i->area && o6i->area->area_id == area->area_id) { zlog_info ("ABR: Logical equivalent of split horizon, skip for %s", area->str); continue; } if (area->area_id == ntohs (0) && /* Backbone */ target.path.type != OSPF6_PATH_TYPE_INTRA) continue; /* XXX, stub area check */ /* XXX, aggregate */ /* if either the area of the route or the area trying to advertise is backbone, do not aggregate */ if (type == ADD) ospf6_abr_prefix_lsa_update_add (&target, area); else ospf6_abr_prefix_lsa_update_remove (&target, area); }}voidospf6_abr_route_add (struct ospf6_route_req *request){ ospf6_abr_prefix_lsa_update (ADD, request);}voidospf6_abr_route_remove (struct ospf6_route_req *request){ ospf6_abr_prefix_lsa_update (REMOVE, request);}intospf6_abr_prefix_lsa_refresh (void *data){ struct ospf6_lsa *lsa = data; struct ospf6_inter_area_prefix_lsa *ier; struct prefix_ipv6 prefix6; struct ospf6_route_req route; ier = OSPF6_LSA_HEADER_END (lsa->header); memset (&prefix6, 0, sizeof (prefix6)); prefix6.family = AF_INET6; prefix6.prefixlen = ier->prefix.prefix_length; ospf6_prefix_in6_addr (&ier->prefix, &prefix6.prefix); ospf6_route_lookup (&route, (struct prefix *) &prefix6, ospf6->route_table); assert (! ospf6_route_end (&route)); ospf6_abr_prefix_lsa_update (ADD, &route); return 0;}intospf6_abr_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa){ struct ospf6_inter_area_prefix_lsa *ier; char prefix[128]; assert (lsa->header); ier = OSPF6_LSA_HEADER_END (lsa->header); ospf6_prefix_string (&ier->prefix, prefix, sizeof (prefix)); vty_out (vty, " Metric: %d%s", ntohl (ier->metric & htonl (0x000fffff)), VTY_NEWLINE); vty_out (vty, " Prefix: %s%s", prefix, VTY_NEWLINE); return 0;}intospf6_abr_prefix_lsa_hook_add (void *data){ struct ospf6_lsa *lsa = data; ospf6_abr_prefix_lsa_add (lsa); return 0;}intospf6_abr_prefix_lsa_hook_remove (void *data){ struct ospf6_lsa *lsa = data; ospf6_abr_prefix_lsa_remove (lsa); return 0;}voidospf6_abr_database_hook_inter_prefix (struct ospf6_lsa *old, struct ospf6_lsa *new){ if (old) ospf6_abr_prefix_lsa_hook_remove (old); if (new && ! IS_LSA_MAXAGE (new)) ospf6_abr_prefix_lsa_hook_add (new);}voidospf6_abr_register_inter_prefix (){ struct ospf6_lsa_slot slot; memset (&slot, 0, sizeof (slot)); slot.type = htons (OSPF6_LSA_TYPE_INTER_PREFIX); slot.name = "Inter-Prefix"; slot.func_show = ospf6_abr_prefix_lsa_show; slot.func_refresh = ospf6_abr_prefix_lsa_refresh; ospf6_lsa_slot_register (&slot); ospf6_lsdb_hook[OSPF6_LSA_TYPE_INTER_PREFIX & OSPF6_LSTYPE_CODE_MASK].hook = ospf6_abr_database_hook_inter_prefix;}intospf6_abr_router_lsa_hook_add (void *data){ struct ospf6_lsa *lsa = data; ospf6_abr_router_lsa_add (lsa); return 0;}intospf6_abr_router_lsa_hook_remove (void *data){ struct ospf6_lsa *lsa = data; ospf6_abr_router_lsa_remove (lsa); return 0;}intospf6_abr_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa){ return 0;}intospf6_abr_router_lsa_refresh (void *data){ return 0;}voidospf6_abr_database_hook_inter_router (struct ospf6_lsa *old, struct ospf6_lsa *new){ if (old) ospf6_abr_router_lsa_hook_remove (old); if (new && ! IS_LSA_MAXAGE (new)) ospf6_abr_router_lsa_hook_add (new);}voidospf6_abr_register_inter_router (){ struct ospf6_lsa_slot slot; memset (&slot, 0, sizeof (slot)); slot.type = htons (OSPF6_LSA_TYPE_INTER_ROUTER); slot.name = "Inter-Router"; slot.func_show = ospf6_abr_router_lsa_show; slot.func_refresh = ospf6_abr_router_lsa_refresh; ospf6_lsa_slot_register (&slot); ospf6_lsdb_hook[OSPF6_LSA_TYPE_INTER_ROUTER & OSPF6_LSTYPE_CODE_MASK].hook = ospf6_abr_database_hook_inter_router;}voidospf6_abr_inter_route_calculation (struct ospf6_area *area){ struct ospf6_lsdb_node node; /* for each inter-prefix LSA */ for (ospf6_lsdb_type (&node, htons (OSPF6_LSA_TYPE_INTER_PREFIX), area->lsdb); ! ospf6_lsdb_is_end (&node); ospf6_lsdb_next (&node)) ospf6_abr_prefix_lsa_add (node.lsa);}voidospf6_abr_init (){ abr_index = ospf6_dump_install ("abr", "Area Border Router Function\n"); ospf6_abr_register_inter_prefix (); ospf6_abr_register_inter_router ();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -