📄 ospf6_zebra.c
字号:
struct linklist_node node; struct ospf6_nexthop *nexthop = NULL; struct in6_addr **nexthops; unsigned int *ifindexes; struct prefix_ipv6 *p; int i, ret = 0; if (IS_OSPF6_DUMP_ZEBRA) { prefix2str (&request->route.prefix, buf, sizeof (buf)); if (type == REMOVE) zlog_info ("ZEBRA: Send remove route: %s", buf); else zlog_info ("ZEBRA: Send add route: %s", buf); } if (zclient->sock < 0) { if (IS_OSPF6_DUMP_ZEBRA) zlog_info ("ZEBRA: failed: not connected to zebra"); return; } if (request->path.origin.adv_router == ospf6->router_id && (request->path.type == OSPF6_PATH_TYPE_EXTERNAL1 || request->path.type == OSPF6_PATH_TYPE_EXTERNAL2)) { if (IS_OSPF6_DUMP_ZEBRA) zlog_info ("ZEBRA: self originated external route, ignore"); return; } /* Only the best path (i.e. the first path of the path-list in 'struct ospf6_route') will be sent to zebra. */ ospf6_route_lookup (&route, &request->route.prefix, request->table); if (memcmp (&route.path, &request->path, sizeof (route.path))) { /* this is not preferred best route, ignore */ if (IS_OSPF6_DUMP_ZEBRA) zlog_info ("ZEBRA: not best path, ignore"); return; } nexthop_list = linklist_create (); /* for each nexthop */ for (ospf6_route_lookup (&route, &request->route.prefix, request->table); ! ospf6_route_end (&route); ospf6_route_next (&route)) { if (memcmp (&route.path, &request->path, sizeof (route.path))) break;#define IN6_IS_ILLEGAL_NEXTHOP(a)\ ((*(u_int32_t *)(void *)(&(a)->s6_addr[0]) == 0xffffffff) &&\ (*(u_int32_t *)(void *)(&(a)->s6_addr[4]) == 0xffffffff) &&\ (*(u_int32_t *)(void *)(&(a)->s6_addr[8]) == 0xffffffff) &&\ (*(u_int32_t *)(void *)(&(a)->s6_addr[12]) == 0xffffffff)) if (IN6_IS_ILLEGAL_NEXTHOP (&route.nexthop.address)) { zlog_warn ("ZEBRA: Illegal nexthop"); continue; } if (type == REMOVE && ! memcmp (&route.nexthop, &request->nexthop, sizeof (struct ospf6_nexthop))) continue; nexthop = XCALLOC (MTYPE_OSPF6_OTHER, sizeof (struct ospf6_nexthop)); if (! nexthop) { zlog_warn ("ZEBRA: Can't update nexthop: malloc failed"); continue; } memcpy (nexthop, &route.nexthop, sizeof (struct ospf6_nexthop)); linklist_add (nexthop, nexthop_list); } if (type == REMOVE && nexthop_list->count != 0) type = ADD; else if (type == REMOVE && nexthop_list->count == 0) { if (IS_OSPF6_DUMP_ZEBRA) zlog_info ("ZEBRA: all nexthop with the selected path has gone"); if (! memcmp (&request->route, &route.route, sizeof (struct ospf6_route))) { /* send 'add' of alternative route */ struct ospf6_path seconde_path; if (IS_OSPF6_DUMP_ZEBRA) zlog_info ("ZEBRA: found alternative path to add"); memcpy (&seconde_path, &route.path, sizeof (struct ospf6_path)); type = ADD; while (! memcmp (&seconde_path, &route.path, sizeof (struct ospf6_path))) { nexthop = XCALLOC (MTYPE_OSPF6_OTHER, sizeof (struct ospf6_nexthop)); if (! nexthop) zlog_warn ("ZEBRA: Can't update nexthop: malloc failed"); else { memcpy (nexthop, &route.nexthop, sizeof (struct ospf6_nexthop)); linklist_add (nexthop, nexthop_list); } ospf6_route_next (&route); } } else { /* there is no alternative route. send 'remove' to zebra for requested route */ if (IS_OSPF6_DUMP_ZEBRA) zlog_info ("ZEBRA: can't find alternative path, remove"); if (IS_OSPF6_DUMP_ZEBRA) { zlog_info ("ZEBRA: Debug: walk over the route ?"); ospf6_route_log_request ("Debug route", "***", &route); ospf6_route_log_request ("Debug request", "***", request); } nexthop = XCALLOC (MTYPE_OSPF6_OTHER, sizeof (struct ospf6_nexthop)); if (! nexthop) zlog_warn ("ZEBRA: Can't update nexthop: malloc failed"); else { memcpy (nexthop, &request->nexthop, sizeof (struct ospf6_nexthop)); linklist_add (nexthop, nexthop_list); } } } if (nexthop_list->count == 0) { if (IS_OSPF6_DUMP_ZEBRA) zlog_info ("ZEBRA: no nexthop, ignore"); linklist_delete (nexthop_list); return; } /* allocate memory for nexthop_list */ nexthops = XCALLOC (MTYPE_OSPF6_OTHER, nexthop_list->count * sizeof (struct in6_addr *)); if (! nexthops) { zlog_warn ("ZEBRA: Can't update zebra route: malloc failed"); for (linklist_head (nexthop_list, &node); !linklist_end (&node); linklist_next (&node)) XFREE (MTYPE_OSPF6_OTHER, node.data); linklist_delete (nexthop_list); return; } /* allocate memory for ifindex_list */ ifindexes = XCALLOC (MTYPE_OSPF6_OTHER, nexthop_list->count * sizeof (unsigned int)); if (! ifindexes) { zlog_warn ("ZEBRA: Can't update zebra route: malloc failed"); for (linklist_head (nexthop_list, &node); !linklist_end (&node); linklist_next (&node)) XFREE (MTYPE_OSPF6_OTHER, node.data); linklist_delete (nexthop_list); XFREE (MTYPE_OSPF6_OTHER, nexthops); return; } i = 0; for (linklist_head (nexthop_list, &node); ! linklist_end (&node); linklist_next (&node)) { nexthop = node.data; if (IS_OSPF6_DUMP_ZEBRA) { inet_ntop (AF_INET6, &nexthop->address, buf, sizeof (buf)); if_indextoname (nexthop->ifindex, ifname); zlog_info ("ZEBRA: nexthop: %s%%%s(%d)", buf, ifname, nexthop->ifindex); } nexthops[i] = &nexthop->address; ifindexes[i] = nexthop->ifindex; i++; } api.type = ZEBRA_ROUTE_OSPF6; api.flags = 0; api.message = 0; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); api.nexthop_num = nexthop_list->count; api.nexthop = nexthops; api.ifindex_num = nexthop_list->count; api.ifindex = ifindexes; p = (struct prefix_ipv6 *) &request->route.prefix; if (type == REMOVE && nexthop_list->count == 1) ret = zapi_ipv6_delete (zclient, p, &api); else ret = zapi_ipv6_add (zclient, p, &api); if (ret < 0) zlog_err ("ZEBRA: zapi_ipv6_add () failed: %s", strerror (errno)); for (linklist_head (nexthop_list, &node); !linklist_end (&node); linklist_next (&node)) XFREE (MTYPE_OSPF6_OTHER, node.data); linklist_delete (nexthop_list); XFREE (MTYPE_OSPF6_OTHER, nexthops); XFREE (MTYPE_OSPF6_OTHER, ifindexes); return;}voidospf6_zebra_route_update_add (struct ospf6_route_req *request){ ospf6_zebra_route_update (ADD, request);}voidospf6_zebra_route_update_remove (struct ospf6_route_req *request){ ospf6_zebra_route_update (REMOVE, request);}static voidospf6_zebra_redistribute_ospf6 (){ struct route_node *node; for (node = route_top (ospf6->route_table->table); node; node = route_next (node)) { if (! node || ! node->info) continue; ospf6_zebra_route_update_add (node->info); }}static voidospf6_zebra_no_redistribute_ospf6 (){ struct route_node *node; if (! ospf6) return; for (node = route_top (ospf6->route_table->table); node; node = route_next (node)) { if (! node || ! node->info) continue; ospf6_zebra_route_update_remove (node->info); }}DEFUN (redistribute_ospf6, redistribute_ospf6_cmd, "redistribute ospf6", "Redistribute control\n" "OSPF6 route\n"){ /* log */ if (IS_OSPF6_DUMP_CONFIG) zlog_info ("Config: redistribute ospf6"); zclient->redist[ZEBRA_ROUTE_OSPF6] = 1; /* set zebra route table */ ospf6_zebra_redistribute_ospf6 (); return CMD_SUCCESS;}DEFUN (no_redistribute_ospf6, no_redistribute_ospf6_cmd, "no redistribute ospf6", NO_STR "Redistribute control\n" "OSPF6 route\n"){ /* log */ if (IS_OSPF6_DUMP_CONFIG) zlog_info ("Config: no redistribute ospf6"); zclient->redist[ZEBRA_ROUTE_OSPF6] = 0; if (! ospf6) return CMD_SUCCESS; /* clean up zebra route table */ ospf6_zebra_no_redistribute_ospf6 (); ospf6_route_hook_unregister (ospf6_zebra_route_update_add, ospf6_zebra_route_update_add, ospf6_zebra_route_update_remove, ospf6->route_table); return CMD_SUCCESS;}voidospf6_zebra_init (){ /* Allocate zebra structure. */ zclient = zclient_new (); zclient_init (zclient, ZEBRA_ROUTE_OSPF6); zclient->interface_add = ospf6_zebra_if_add; zclient->interface_delete = ospf6_zebra_if_del; zclient->interface_up = ospf6_zebra_if_state_update; zclient->interface_down = ospf6_zebra_if_state_update; zclient->interface_address_add = ospf6_zebra_if_address_update_add; zclient->interface_address_delete = ospf6_zebra_if_address_update_delete; zclient->ipv4_route_add = NULL; zclient->ipv4_route_delete = NULL; zclient->ipv6_route_add = ospf6_zebra_read_ipv6; zclient->ipv6_route_delete = ospf6_zebra_read_ipv6; /* redistribute connected route by default */ /* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */ /* Install zebra node. */ install_node (&zebra_node, ospf6_zebra_config_write); /* Install command element for zebra node. */ install_element (VIEW_NODE, &show_zebra_cmd); install_element (ENABLE_NODE, &show_zebra_cmd); install_element (CONFIG_NODE, &router_zebra_cmd); install_element (CONFIG_NODE, &no_router_zebra_cmd); install_default (ZEBRA_NODE); install_element (ZEBRA_NODE, &redistribute_ospf6_cmd); install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd);#if 0 hook.name = "ZebraRouteUpdate"; hook.hook_add = ospf6_zebra_route_update_add; hook.hook_change = ospf6_zebra_route_update_add; hook.hook_remove = ospf6_zebra_route_update_remove; ospf6_hook_register (&hook, &route_hook);#endif return;}voidospf6_zebra_finish (){ zclient_stop (zclient); zclient_free (zclient); zclient = (struct zclient *) NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -