📄 ospf6_route.c
字号:
{ linklist_remove (add, table->hook_list[ADD]); linklist_remove (change, table->hook_list[CHANGE]); linklist_remove (remove, table->hook_list[REMOVE]);}intprefix_ls2str (struct prefix *p, char *str, int size){ char id[BUFSIZ], adv_router[BUFSIZ]; struct prefix_ls *pl = (struct prefix_ls *) p; inet_ntop (AF_INET, &pl->id, id, BUFSIZ); inet_ntop (AF_INET, &pl->adv_router, adv_router, BUFSIZ); snprintf (str, size, "%s-%s", adv_router, id); return 0;}voidospf6_route_log_request (char *what, char *where, struct ospf6_route_req *request){ char prefix[64]; char area_id[16]; char type[16], id[16], adv[16]; char address[64], ifname[IFNAMSIZ]; if (request->route.prefix.family != AF_INET && request->route.prefix.family != AF_INET6) prefix_ls2str (&request->route.prefix, prefix, sizeof (prefix)); else prefix2str (&request->route.prefix, prefix, sizeof (prefix)); inet_ntop (AF_INET, &request->path.area_id, area_id, sizeof (area_id)); ospf6_lsa_type_string (request->path.origin.type, type, sizeof (type)); inet_ntop (AF_INET, &request->path.origin.id, id, sizeof (id)); inet_ntop (AF_INET, &request->path.origin.adv_router, adv, sizeof (adv)); inet_ntop (AF_INET6, &request->nexthop.address, address, sizeof (address)); zlog_info ("ROUTE: %s %s %s %s %s", what, DTYPE_ABNAME (request->route.type), prefix, ((strcmp ("Add", what) == 0) ? "to" : "from"), where); zlog_info ("ROUTE: Area: %s type: %s cost: %lu (E2: %lu)", area_id, PTYPE_NAME (request->path.type), (u_long) request->path.cost, (u_long) request->path.cost_e2); zlog_info ("ROUTE: Origin: Type: %s", type); zlog_info ("ROUTE: Origin: Id: %s Adv: %s", id, adv); zlog_info ("ROUTE: Nexthop: %s", address); zlog_info ("ROUTE: Nexthop: Ifindex: %u (%s)", request->nexthop.ifindex, if_indextoname (request->nexthop.ifindex, ifname));}struct ospf6_path_node *ospf6_route_find_path_node (struct ospf6_route_req *request, struct ospf6_route_node *rn){ struct linklist_node node; for (linklist_head (rn->path_list, &node); ! linklist_end (&node); linklist_next (&node)) { struct ospf6_path_node *path_node = node.data; if (path_node->path.area_id == request->path.area_id && path_node->path.origin.type == request->path.origin.type && path_node->path.origin.id == request->path.origin.id && path_node->path.origin.adv_router == request->path.origin.adv_router) return path_node; }#if 0 zlog_info ("req path : area: %#x origin: type: %d, id: %d, adv_router: %#x", request->path.area_id, request->path.origin.type, request->path.origin.id, request->path.origin.adv_router); for (linklist_head (rn->path_list, &node); ! linklist_end (&node); linklist_next (&node)) { struct ospf6_path_node *path_node = node.data; zlog_info (" path : area: %#x origin: type: %d, id: %d, adv_router: %#x", path_node->path.area_id, path_node->path.origin.type, path_node->path.origin.id, path_node->path.origin.adv_router); }#endif return NULL;}struct ospf6_nexthop_node *ospf6_route_find_nexthop_node (struct ospf6_route_req *request, struct ospf6_path_node *pn){ struct linklist_node node; for (linklist_head (pn->nexthop_list, &node); ! linklist_end (&node); linklist_next (&node)) { struct ospf6_nexthop_node *nexthop_node = node.data; if (! memcmp (&nexthop_node->nexthop, &request->nexthop, sizeof (struct ospf6_nexthop))) return nexthop_node; } return NULL;}voidospf6_route_add (struct ospf6_route_req *request, struct ospf6_route_table *table){ struct ospf6_route_node *rn; struct ospf6_path_node *pn; struct ospf6_nexthop_node *nn; struct route_node *route_node; struct ospf6_route_req route; int route_change = 0; int path_change = 0; int nexthop_change = 0; /* find the requested route */ route_node = route_node_get (table->table, &request->route.prefix); rn = (struct ospf6_route_node *) route_node->info; if (rn) { if (memcmp (&rn->route, &request->route, sizeof (struct ospf6_route))) { memcpy (&rn->route, &request->route, sizeof (struct ospf6_route)); route_change++; } } else { rn = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_route_node)); rn->table = table; rn->route_node = route_node; rn->route_id = table->route_id++; rn->path_list = linklist_create (); rn->path_list->cmp = ospf6_path_cmp; memcpy (&rn->route, &request->route, sizeof (struct ospf6_route)); route_node->info = rn; } /* find the same path */ pn = ospf6_route_find_path_node (request, rn); if (pn) { if (memcmp (&pn->path, &request->path, sizeof (struct ospf6_path))) { memcpy (&pn->path, &request->path, sizeof (struct ospf6_path)); path_change++; } } else { pn = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_path_node)); pn->route_node = rn; pn->nexthop_list = linklist_create (); pn->nexthop_list->cmp = ospf6_nexthop_cmp; memcpy (&pn->path, &request->path, sizeof (struct ospf6_path)); linklist_add (pn, rn->path_list); } /* find the same nexthop */ nn = ospf6_route_find_nexthop_node (request, pn); if (nn) { if (memcmp (&nn->nexthop, &request->nexthop, sizeof (struct ospf6_nexthop))) { memcpy (&nn->nexthop, &request->nexthop, sizeof (struct ospf6_nexthop)); nexthop_change++; gettimeofday (&nn->installed, (struct timezone *) NULL); } } else { nn = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_nexthop_node)); nn->path_node = pn; memcpy (&nn->nexthop, &request->nexthop, sizeof (struct ospf6_nexthop)); linklist_add (nn, pn->nexthop_list); rn->count++; gettimeofday (&nn->installed, (struct timezone *) NULL); } SET_FLAG (nn->flag, OSPF6_ROUTE_FLAG_ADD); if (route_change) SET_FLAG (nn->flag, OSPF6_ROUTE_FLAG_ROUTE_CHANGE); if (path_change) SET_FLAG (nn->flag, OSPF6_ROUTE_FLAG_PATH_CHANGE); if (nexthop_change) SET_FLAG (nn->flag, OSPF6_ROUTE_FLAG_CHANGE); if (table->freeze) return; if (IS_OSPF6_DUMP_ROUTE) { ospf6_route_log_request ("Add", table->name, request); if (CHECK_FLAG (nn->flag, OSPF6_ROUTE_FLAG_ROUTE_CHANGE)) zlog_info ("ROUTE: route attribute change"); if (CHECK_FLAG (nn->flag, OSPF6_ROUTE_FLAG_PATH_CHANGE)) zlog_info ("ROUTE: path attribute change"); if (CHECK_FLAG (nn->flag, OSPF6_ROUTE_FLAG_CHANGE)) zlog_info ("ROUTE: nexthop attribute change"); } if (CHECK_FLAG (nn->flag, OSPF6_ROUTE_FLAG_ROUTE_CHANGE) || CHECK_FLAG (nn->flag, OSPF6_ROUTE_FLAG_PATH_CHANGE)) SET_FLAG (nn->flag, OSPF6_ROUTE_FLAG_CHANGE); /* Call hooks */ ospf6_route_request (&route, rn, pn, nn); if (CHECK_FLAG (nn->flag, OSPF6_ROUTE_FLAG_ADD)) ospf6_route_hook_call (ADD, &route, table); else if (CHECK_FLAG (nn->flag, OSPF6_ROUTE_FLAG_CHANGE)) ospf6_route_hook_call (CHANGE, &route, table); if (table->hook_add && CHECK_FLAG (nn->flag, OSPF6_ROUTE_FLAG_ADD)) (*table->hook_add) (&route); else if (table->hook_change && CHECK_FLAG (nn->flag, OSPF6_ROUTE_FLAG_CHANGE)) (*table->hook_change) (&route); /* clear flag */ nn->flag = 0;}voidospf6_route_remove (struct ospf6_route_req *request, struct ospf6_route_table *table){ struct ospf6_route_node *rn; struct ospf6_path_node *pn; struct ospf6_nexthop_node *nn; struct route_node *route_node; struct ospf6_route_req route; /* find the requested route */ route_node = route_node_get (table->table, &request->route.prefix); rn = (struct ospf6_route_node *) route_node->info; if (! rn) { if (IS_OSPF6_DUMP_ROUTE) { ospf6_route_log_request ("Remove", table->name, request); zlog_info ("ROUTE: Can't remove: No such route"); } return; } pn = ospf6_route_find_path_node (request, rn); if (! pn) { if (IS_OSPF6_DUMP_ROUTE) { ospf6_route_log_request ("Remove", table->name, request); zlog_info ("ROUTE: Can't remove: No such path"); } return; } if (pn->path.area_id != request->path.area_id || pn->path.origin.type != request->path.origin.type || pn->path.origin.id != request->path.origin.id || pn->path.origin.adv_router != request->path.origin.adv_router) { if (IS_OSPF6_DUMP_ROUTE) { ospf6_route_log_request ("Remove", table->name, request); zlog_info ("ROUTE: Can't remove: Path differ"); { char *s, *e, *c; char line[512], *p; p = line; s = (char *) &pn->path; e = s + sizeof (struct ospf6_path); for (c = s; c < e; c++) { if ((c - s) % 4 == 0) snprintf (p++, line + sizeof (line) - p, " "); snprintf (p, line + sizeof (line) - p, "%02x", *c); p += 2; } zlog_info ("ROUTE: path: %s", line); p = line; s = (char *) &request->path; e = s + sizeof (struct ospf6_path); for (c = s; c < e; c++) { if ((c - s) % 4 == 0) snprintf (p++, line + sizeof (line) - p, " "); snprintf (p, line + sizeof (line) - p, "%02x", *c); p += 2; } zlog_info ("ROUTE: req : %s", line); } } return; } nn = ospf6_route_find_nexthop_node (request, pn); if (! nn) { if (IS_OSPF6_DUMP_ROUTE) { ospf6_route_log_request ("Remove", table->name, request); zlog_info ("ROUTE: Can't remove: No such nexthop"); } return; } if (memcmp (&nn->nexthop, &request->nexthop, sizeof (struct ospf6_nexthop))) { if (IS_OSPF6_DUMP_ROUTE) { ospf6_route_log_request ("Remove", table->name, request); zlog_info ("ROUTE: Can't remove: Nexthop differ"); } return; } SET_FLAG (nn->flag, OSPF6_ROUTE_FLAG_REMOVE); if (table->freeze) return; if (IS_OSPF6_DUMP_ROUTE) ospf6_route_log_request ("Remove", table->name, request); ospf6_route_request (&route, rn, pn, nn); ospf6_route_hook_call (REMOVE, &route, table); if (table->hook_remove) (*table->hook_remove) (&route); /* clear flag */ nn->flag = 0; /* remove nexthop */ linklist_remove (nn, pn->nexthop_list); rn->count--; XFREE (MTYPE_OSPF6_ROUTE, nn); /* remove path if there's no nexthop for the path */ if (pn->nexthop_list->count != 0) return; linklist_remove (pn, rn->path_list); linklist_delete (pn->nexthop_list); XFREE (MTYPE_OSPF6_ROUTE, pn); /* remove route if there's no path for the route */ if (rn->path_list->count != 0) return; route_node->info = NULL; linklist_delete (rn->path_list); XFREE (MTYPE_OSPF6_ROUTE, rn);}voidospf6_route_remove_all (struct ospf6_route_table *table){ struct ospf6_route_req request; for (ospf6_route_head (&request, table); ! ospf6_route_end (&request);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -