📄 ospf6_intra.c
字号:
zlog_info (" include prefix from %s", lsa->name); if (lsa->header->adv_router != oi->area->ospf6->router_id) { on = ospf6_neighbor_lookup (lsa->header->adv_router, oi); if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL) { if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info (" Neighbor not found or not Full, ignore"); continue; } } link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); prefix_num = (unsigned short) ntohl (link_lsa->prefix_num); start = (char *) link_lsa + sizeof (struct ospf6_link_lsa); end = (char *) lsa->header + ntohs (lsa->header->length); for (current = start; current < end && prefix_num; current += OSPF6_PREFIX_SIZE (op)) { op = (struct ospf6_prefix *) current; if (op->prefix_length == 0 || current + OSPF6_PREFIX_SIZE (op) > end) break; route = ospf6_route_create (); route->type = OSPF6_DEST_TYPE_NETWORK; route->prefix.family = AF_INET6; route->prefix.prefixlen = op->prefix_length; memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr)); memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op), OSPF6_PREFIX_SPACE (op->prefix_length)); route->path.origin.type = lsa->header->type; route->path.origin.id = lsa->header->id; route->path.origin.adv_router = lsa->header->adv_router; route->path.options[0] = link_lsa->options[0]; route->path.options[1] = link_lsa->options[1]; route->path.options[2] = link_lsa->options[2]; route->path.prefix_options = op->prefix_options; route->path.area_id = oi->area->area_id; route->path.type = OSPF6_PATH_TYPE_INTRA; if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) { prefix2str (&route->prefix, buf, sizeof (buf)); zlog_info (" include %s", buf); } ospf6_route_add (route, route_advertise); prefix_num--; } if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info ("Trailing garbage in %s", lsa->name); } op = (struct ospf6_prefix *) ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa)); prefix_num = 0; for (route = ospf6_route_head (route_advertise); route; route = ospf6_route_best_next (route)) { op->prefix_length = route->prefix.prefixlen; op->prefix_options = route->path.prefix_options; op->prefix_metric = htons (0); memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6, OSPF6_PREFIX_SPACE (op->prefix_length)); op = OSPF6_PREFIX_NEXT (op); prefix_num++; } ospf6_route_table_delete (route_advertise); if (prefix_num == 0) { if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info ("Quit to Advertise Intra-Prefix: no route to advertise"); return 0; } intra_prefix_lsa->prefix_num = htons (prefix_num); /* Fill LSA Header */ lsa_header->age = 0; lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX); lsa_header->id = htonl (oi->interface->ifindex); lsa_header->adv_router = oi->area->ospf6->router_id; lsa_header->seqnum = ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, lsa_header->adv_router, oi->area->lsdb); lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header); /* LSA checksum */ ospf6_lsa_checksum (lsa_header); /* create LSA */ lsa = ospf6_lsa_create (lsa_header); /* Originate */ ospf6_lsa_originate_area (lsa, oi->area); return 0;}voidospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa){ struct ospf6_area *oa; struct ospf6_intra_prefix_lsa *intra_prefix_lsa; struct prefix ls_prefix; struct ospf6_route *route, *ls_entry; int i, prefix_num; struct ospf6_prefix *op; char *start, *current, *end; char buf[64]; if (OSPF6_LSA_IS_MAXAGE (lsa)) return; if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) zlog_info ("%s found", lsa->name); oa = OSPF6_AREA (lsa->lsdb->data); intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) OSPF6_LSA_HEADER_END (lsa->header); if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER)) ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router, htonl (0), &ls_prefix); else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK)) ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router, intra_prefix_lsa->ref_id, &ls_prefix); else { if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) zlog_info ("Unknown reference LS-type: %#hx", ntohs (intra_prefix_lsa->ref_type)); return; } ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table); if (ls_entry == NULL) { if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) { ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf)); zlog_info ("LS entry does not exist: %s", buf); } return; } prefix_num = ntohs (intra_prefix_lsa->prefix_num); start = (caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa); end = OSPF6_LSA_END (lsa->header); for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op)) { op = (struct ospf6_prefix *) current; if (prefix_num == 0) break; if (end < current + OSPF6_PREFIX_SIZE (op)) break; route = ospf6_route_create (); memset (&route->prefix, 0, sizeof (struct prefix)); route->prefix.family = AF_INET6; route->prefix.prefixlen = op->prefix_length; ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op); route->type = OSPF6_DEST_TYPE_NETWORK; route->path.origin.type = lsa->header->type; route->path.origin.id = lsa->header->id; route->path.origin.adv_router = lsa->header->adv_router; route->path.prefix_options = op->prefix_options; route->path.area_id = oa->area_id; route->path.type = OSPF6_PATH_TYPE_INTRA; route->path.metric_type = 1; route->path.cost = ls_entry->path.cost + ntohs (op->prefix_metric); 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]); if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) { prefix2str (&route->prefix, buf, sizeof (buf)); zlog_info (" add %s", buf); } ospf6_route_add (route, oa->route_table); prefix_num--; } if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) zlog_info ("Trailing garbage ignored");}voidospf6_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; int prefix_num; struct ospf6_prefix *op; char *start, *current, *end; char buf[64]; if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) zlog_info ("%s disappearing", lsa->name); oa = OSPF6_AREA (lsa->lsdb->data); intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) OSPF6_LSA_HEADER_END (lsa->header); prefix_num = ntohs (intra_prefix_lsa->prefix_num); start = (caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa); end = OSPF6_LSA_END (lsa->header); for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op)) { op = (struct ospf6_prefix *) current; if (prefix_num == 0) break; if (end < current + OSPF6_PREFIX_SIZE (op)) break; prefix_num--; memset (&prefix, 0, sizeof (struct prefix)); prefix.family = AF_INET6; prefix.prefixlen = op->prefix_length; ospf6_prefix_in6_addr (&prefix.u.prefix6, op); route = ospf6_route_lookup (&prefix, oa->route_table); if (route == NULL) continue; for (ospf6_route_lock (route); route && ospf6_route_is_prefix (&prefix, route); route = ospf6_route_next (route)) { if (route->type != OSPF6_DEST_TYPE_NETWORK) continue; if (route->path.area_id != oa->area_id) continue; if (route->path.type != OSPF6_PATH_TYPE_INTRA) continue; if (route->path.origin.type != lsa->header->type || route->path.origin.id != lsa->header->id || route->path.origin.adv_router != lsa->header->adv_router) continue; if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) { prefix2str (&route->prefix, buf, sizeof (buf)); zlog_info ("remove %s", buf); } ospf6_route_remove (route, oa->route_table); } } if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) zlog_info ("Trailing garbage ignored");}voidospf6_intra_route_calculation (struct ospf6_area *oa){ struct ospf6_route *route; u_int16_t type; struct ospf6_lsa *lsa; void (*hook_add) (struct ospf6_route *) = NULL; void (*hook_remove) (struct ospf6_route *) = NULL; if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) zlog_info ("Re-examin intra-routes for area %s", oa->name); hook_add = oa->route_table->hook_add; hook_remove = oa->route_table->hook_remove; oa->route_table->hook_add = NULL; oa->route_table->hook_remove = NULL; for (route = ospf6_route_head (oa->route_table); route; route = ospf6_route_next (route)) route->flag = OSPF6_ROUTE_REMOVE; type = htons (OSPF6_LSTYPE_INTRA_PREFIX); for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa; lsa = ospf6_lsdb_type_next (type, lsa)) ospf6_intra_prefix_lsa_add (lsa); oa->route_table->hook_add = hook_add; oa->route_table->hook_remove = hook_remove; for (route = ospf6_route_head (oa->route_table); route; route = ospf6_route_next (route)) { if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) && CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD)) { UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE); UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD); } if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE)) ospf6_route_remove (route, oa->route_table); else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) || CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE)) { if (hook_add) (*hook_add) (route); } route->flag = 0; } if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) zlog_info ("Re-examin intra-routes for area %s: Done", oa->name);}voidospf6_intra_brouter_calculation (struct ospf6_area *oa){ struct ospf6_route *lsentry, *copy; void (*hook_add) (struct ospf6_route *) = NULL; void (*hook_remove) (struct ospf6_route *) = NULL; char buf[16]; if (IS_OSPF6_DEBUG_ROUTE (INTRA)) zlog_info ("Border-router calculation for area %s", oa->name); hook_add = oa->ospf6->brouter_table->hook_add; hook_remove = oa->ospf6->brouter_table->hook_remove; oa->ospf6->brouter_table->hook_add = NULL; oa->ospf6->brouter_table->hook_remove = NULL; /* withdraw the previous router entries for the area */ for (lsentry = ospf6_route_head (oa->ospf6->brouter_table); lsentry; lsentry = ospf6_route_next (lsentry)) { if (lsentry->path.area_id != oa->area_id) continue; lsentry->flag = OSPF6_ROUTE_REMOVE; } for (lsentry = ospf6_route_head (oa->spf_table); lsentry; lsentry = ospf6_route_next (lsentry)) { if (lsentry->type != OSPF6_DEST_TYPE_LINKSTATE) continue; if (ospf6_linkstate_prefix_id (&lsentry->prefix) != htonl (0)) continue; if (! CHECK_FLAG (lsentry->path.router_bits, OSPF6_ROUTER_BIT_E) && ! CHECK_FLAG (lsentry->path.router_bits, OSPF6_ROUTER_BIT_B)) continue; copy = ospf6_route_copy (lsentry); copy->type = OSPF6_DEST_TYPE_ROUTER; copy->path.area_id = oa->area_id; ospf6_route_add (copy, oa->ospf6->brouter_table); if (IS_OSPF6_DEBUG_ROUTE (INTRA)) { inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (©->prefix), buf, sizeof (buf)); zlog_info ("Re-install router entry %s", buf); } } oa->ospf6->brouter_table->hook_add = hook_add; oa->ospf6->brouter_table->hook_remove = hook_remove; for (lsentry = ospf6_route_head (oa->ospf6->brouter_table); lsentry; lsentry = ospf6_route_next (lsentry)) { if (lsentry->path.area_id != oa->area_id) continue; if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_WAS_REMOVED)) continue; if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_REMOVE) && CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_ADD)) { UNSET_FLAG (lsentry->flag, OSPF6_ROUTE_REMOVE); UNSET_FLAG (lsentry->flag, OSPF6_ROUTE_ADD); } if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_REMOVE)) ospf6_route_remove (lsentry, oa->ospf6->brouter_table); else if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_ADD) || CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_CHANGE)) { if (IS_OSPF6_DEBUG_ROUTE (INTRA)) { inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (&lsentry->prefix), buf, sizeof (buf)); zlog_info ("Call hook for router entry %s", buf); } if (hook_add) (*hook_add) (lsentry); } lsentry->flag = 0; } if (IS_OSPF6_DEBUG_ROUTE (INTRA)) zlog_info ("Border-router calculation for area %s: Done", oa->name);}struct ospf6_lsa_handler router_handler ={ OSPF6_LSTYPE_ROUTER, "Router", ospf6_router_lsa_show};struct ospf6_lsa_handler network_handler ={ OSPF6_LSTYPE_NETWORK, "Network", ospf6_network_lsa_show};struct ospf6_lsa_handler link_handler ={ OSPF6_LSTYPE_LINK, "Link", ospf6_link_lsa_show};struct ospf6_lsa_handler intra_prefix_handler ={ OSPF6_LSTYPE_INTRA_PREFIX, "Intra-Prefix", ospf6_intra_prefix_lsa_show};voidospf6_intra_init (){ ospf6_install_lsa_handler (&router_handler); ospf6_install_lsa_handler (&network_handler); ospf6_install_lsa_handler (&link_handler); ospf6_install_lsa_handler (&intra_prefix_handler);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -