📄 ospf6_route.c
字号:
prev->next = route; } table->count++; ospf6_route_count_assert (table); SET_FLAG (route->flag, OSPF6_ROUTE_ADD); if (table->hook_add) (*table->hook_add) (route); return route;}voidospf6_route_remove (struct ospf6_route *route, struct ospf6_route_table *table){ struct route_node *node; struct ospf6_route *current; char buf[64]; if (route->type == OSPF6_DEST_TYPE_LINKSTATE) ospf6_linkstate_prefix2str (&route->prefix, buf, sizeof (buf)); else prefix2str (&route->prefix, buf, sizeof (buf)); if (IS_OSPF6_DEBUG_ROUTE (TABLE)) zlog_info ("route remove: %s", buf); node = route_node_lookup (table->table, &route->prefix); assert (node); /* find the route to remove, making sure that the route pointer is from the route table. */ current = node->info; while (current && ospf6_route_is_same (current, route)) { if (current == route) break; current = current->next; } assert (current == route); /* adjust doubly linked list */ if (route->prev) route->prev->next = route->next; if (route->next) route->next->prev = route->prev; if (node->info == route) { if (route->next && ospf6_route_is_same (route->next, route)) { node->info = route->next; SET_FLAG (route->next->flag, OSPF6_ROUTE_BEST); } else node->info = NULL; /* should unlock route_node here ? */ } table->count--; ospf6_route_count_assert (table); SET_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED); if (table->hook_remove) (*table->hook_remove) (route); ospf6_route_unlock (route);}struct ospf6_route *ospf6_route_head (struct ospf6_route_table *table){ struct route_node *node; struct ospf6_route *route; node = route_top (table->table); if (node == NULL) return NULL; /* skip to the real existing entry */ while (node && node->info == NULL) node = route_next (node); if (node == NULL) return NULL; route_unlock_node (node); assert (node->info); route = (struct ospf6_route *) node->info; assert (route->prev == NULL); ospf6_route_lock (route); return route;}struct ospf6_route *ospf6_route_next (struct ospf6_route *route){ struct ospf6_route *next = route->next; ospf6_route_unlock (route); if (next) ospf6_route_lock (next); return next;}struct ospf6_route *ospf6_route_best_next (struct ospf6_route *route){ struct route_node *rnode; struct ospf6_route *next; rnode = route->rnode; route_lock_node (rnode); rnode = route_next (rnode); while (rnode && rnode->info == NULL) rnode = route_next (rnode); if (rnode == NULL) return NULL; route_unlock_node (rnode); assert (rnode->info); next = (struct ospf6_route *) rnode->info; ospf6_route_unlock (route); ospf6_route_lock (next); return next;}/* Macro version of check_bit (). */#define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1)struct ospf6_route *ospf6_route_match_head (struct prefix *prefix, struct ospf6_route_table *table){ struct route_node *node; struct ospf6_route *route; /* Walk down tree. */ node = table->table->top; while (node && node->p.prefixlen < prefix->prefixlen && prefix_match (&node->p, prefix)) node = node->link[CHECK_BIT(&prefix->u.prefix, node->p.prefixlen)]; if (node) route_lock_node (node); while (node && node->info == NULL) node = route_next (node); if (node == NULL) return NULL; route_unlock_node (node); if (! prefix_match (prefix, &node->p)) return NULL; route = node->info; ospf6_route_lock (route); return route;}struct ospf6_route *ospf6_route_match_next (struct prefix *prefix, struct ospf6_route *route){ struct ospf6_route *next; next = ospf6_route_next (route); if (next && ! prefix_match (prefix, &next->prefix)) { ospf6_route_unlock (next); next = NULL; } return next;}voidospf6_route_remove_all (struct ospf6_route_table *table){ struct ospf6_route *route; for (route = ospf6_route_head (table); route; route = ospf6_route_next (route)) ospf6_route_remove (route, table);}struct ospf6_route_table *ospf6_route_table_create (){ struct ospf6_route_table *new; new = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_route_table)); new->table = route_table_init (); return new;}voidospf6_route_table_delete (struct ospf6_route_table *table){ ospf6_route_remove_all (table); route_table_finish (table->table); XFREE (MTYPE_OSPF6_ROUTE, table);}/* VTY commands */voidospf6_route_show (struct vty *vty, struct ospf6_route *route){ int i; char destination[64], nexthop[64]; char duration[16], ifname[IFNAMSIZ]; struct timeval now, res; gettimeofday (&now, (struct timezone *) NULL); timersub (&now, &route->changed, &res); timerstring (&res, duration, sizeof (duration)); /* destination */ if (route->type == OSPF6_DEST_TYPE_LINKSTATE) ospf6_linkstate_prefix2str (&route->prefix, destination, sizeof (destination)); else if (route->type == OSPF6_DEST_TYPE_ROUTER) inet_ntop (route->prefix.family, &route->prefix.u.prefix, destination, sizeof (destination)); else prefix2str (&route->prefix, destination, sizeof (destination)); /* nexthop */ inet_ntop (AF_INET6, &route->nexthop[0].address, nexthop, sizeof (nexthop)); if (! if_indextoname (route->nexthop[0].ifindex, ifname)) snprintf (ifname, sizeof (ifname), "%d", route->nexthop[0].ifindex); vty_out (vty, "%c%1s %2s %-30s %-25s %6s %s%s", (ospf6_route_is_best (route) ? '*' : ' '), OSPF6_DEST_TYPE_SUBSTR (route->type), OSPF6_PATH_TYPE_SUBSTR (route->path.type), destination, nexthop, ifname, duration, VNL); for (i = 1; ospf6_nexthop_is_set (&route->nexthop[i]) && i < OSPF6_MULTI_PATH_LIMIT; i++) { /* nexthop */ inet_ntop (AF_INET6, &route->nexthop[i].address, nexthop, sizeof (nexthop)); if (! if_indextoname (route->nexthop[i].ifindex, ifname)) snprintf (ifname, sizeof (ifname), "%d", route->nexthop[i].ifindex); vty_out (vty, "%c%1s %2s %-30s %-25s %6s %s%s", ' ', "", "", "", nexthop, ifname, "", VNL); }}voidospf6_route_show_detail (struct vty *vty, struct ospf6_route *route){ char destination[64], nexthop[64], ifname[IFNAMSIZ]; char area_id[16], id[16], adv_router[16], capa[16], options[16]; struct timeval now, res; char duration[16]; int i; gettimeofday (&now, (struct timezone *) NULL); /* destination */ if (route->type == OSPF6_DEST_TYPE_LINKSTATE) ospf6_linkstate_prefix2str (&route->prefix, destination, sizeof (destination)); else if (route->type == OSPF6_DEST_TYPE_ROUTER) inet_ntop (route->prefix.family, &route->prefix.u.prefix, destination, sizeof (destination)); else prefix2str (&route->prefix, destination, sizeof (destination)); vty_out (vty, "Destination: %s%s", destination, VNL); /* destination type */ vty_out (vty, "Destination type: %s%s", OSPF6_DEST_TYPE_NAME (route->type), VNL); /* Time */ timersub (&now, &route->installed, &res); timerstring (&res, duration, sizeof (duration)); vty_out (vty, "Installed Time: %s ago%s", duration, VNL); timersub (&now, &route->changed, &res); timerstring (&res, duration, sizeof (duration)); vty_out (vty, " Changed Time: %s ago%s", duration, VNL); /* Debugging info */ vty_out (vty, "Lock: %d Flags: %s%s%s%s%s", route->lock, (CHECK_FLAG (route->flag, OSPF6_ROUTE_BEST) ? "B" : "-"), (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ? "A" : "-"), (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"), (CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"), VNL); vty_out (vty, "Memory: prev: %p this: %p next: %p%s", route->prev, route, route->next, VNL); /* Path section */ /* Area-ID */ inet_ntop (AF_INET, &route->path.area_id, area_id, sizeof (area_id)); vty_out (vty, "Associated Area: %s%s", area_id, VNL); /* Path type */ vty_out (vty, "Path Type: %s%s", OSPF6_PATH_TYPE_NAME (route->path.type), VNL); /* LS Origin */ inet_ntop (AF_INET, &route->path.origin.id, id, sizeof (id)); inet_ntop (AF_INET, &route->path.origin.adv_router, adv_router, sizeof (adv_router)); vty_out (vty, "LS Origin: %s Id: %s Adv: %s%s", ospf6_lstype_name (route->path.origin.type), id, adv_router, VNL); /* Options */ ospf6_options_printbuf (route->path.options, options, sizeof (options)); vty_out (vty, "Options: %s%s", options, VNL); /* Router Bits */ ospf6_capability_printbuf (route->path.router_bits, capa, sizeof (capa)); vty_out (vty, "Router Bits: %s%s", capa, VNL); /* Prefix Options */ vty_out (vty, "Prefix Options: xxx%s", VNL); /* Metrics */ vty_out (vty, "Metric Type: %d%s", route->path.metric_type, VNL); vty_out (vty, "Metric: %d (%d)%s", route->path.cost, route->path.cost_e2, VNL); /* Nexthops */ vty_out (vty, "Nexthop:%s", VNL); for (i = 0; ospf6_nexthop_is_set (&route->nexthop[i]) && i < OSPF6_MULTI_PATH_LIMIT; i++) { /* nexthop */ inet_ntop (AF_INET6, &route->nexthop[i].address, nexthop, sizeof (nexthop)); if (! if_indextoname (route->nexthop[i].ifindex, ifname)) snprintf (ifname, sizeof (ifname), "%d", route->nexthop[i].ifindex); vty_out (vty, " %s %s%s", nexthop, ifname, VNL); } vty_out (vty, "%s", VNL);}voidospf6_route_show_table_summary (struct vty *vty, struct ospf6_route_table *table){ struct ospf6_route *route, *prev = NULL; int i, pathtype[OSPF6_PATH_TYPE_MAX]; int number = 0; int nhinval = 0, ecmp = 0; int alternative = 0, destination = 0; for (i = 0; i < OSPF6_PATH_TYPE_MAX; i++) pathtype[i] = 0; for (route = ospf6_route_head (table); route; route = ospf6_route_next (route)) { if (prev == NULL || ! ospf6_route_is_same (prev, route)) destination++; else alternative++; if (! ospf6_nexthop_is_set (&route->nexthop[0])) nhinval++; else if (ospf6_nexthop_is_set (&route->nexthop[1])) ecmp++; pathtype[route->path.type]++; number++; prev = route; } assert (number == table->count); vty_out (vty, "Number of OSPFv3 routes: %d%s", number, VNL); vty_out (vty, "Number of Destination: %d%s", destination, VNL); vty_out (vty, "Number of Alternative routes: %d%s", alternative, VNL); vty_out (vty, "Number of Equal Cost Multi Path: %d%s", ecmp, VNL); for (i = OSPF6_PATH_TYPE_INTRA; i <= OSPF6_PATH_TYPE_EXTERNAL2; i++) { vty_out (vty, "Number of %s routes: %d%s", OSPF6_PATH_TYPE_NAME (i), pathtype[i], VNL); }}voidospf6_route_show_table_prefix (struct vty *vty, struct prefix *prefix, struct ospf6_route_table *table){ struct ospf6_route *route; route = ospf6_route_lookup (prefix, table); if (route == NULL) return; ospf6_route_lock (route); while (route && ospf6_route_is_prefix (prefix, route)) { /* Specifying a prefix will always display details */ ospf6_route_show_detail (vty, route); route = ospf6_route_next (route); } if (route) ospf6_route_unlock (route);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -