📄 zserv.c
字号:
{ case ZEBRA_NEXTHOP_IPV6: stream_get (&nexthop, s, 16); break; case ZEBRA_NEXTHOP_IFINDEX: ifindex = stream_getl (s); break; } } } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (s); else api.distance = 0; if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (s); else api.metric = 0; if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0); else rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);}voidzebra_read_ipv6 (int command, struct zserv *client, u_short length){ u_char type; u_char flags; struct in6_addr nexthop, *gate; u_char *lim; u_char *pnt; unsigned int ifindex; pnt = stream_pnt (client->ibuf); lim = pnt + length; type = stream_getc (client->ibuf); flags = stream_getc (client->ibuf); stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr)); while (stream_pnt (client->ibuf) < lim) { int size; struct prefix_ipv6 p; ifindex = stream_getl (client->ibuf); memset (&p, 0, sizeof (struct prefix_ipv6)); p.family = AF_INET6; p.prefixlen = stream_getc (client->ibuf); size = PSIZE(p.prefixlen); stream_get (&p.prefix, client->ibuf, size); if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) gate = NULL; else gate = &nexthop; if (command == ZEBRA_IPV6_ROUTE_ADD) rib_add_ipv6 (type, flags, &p, gate, ifindex, 0); else rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0); }}voidzread_ipv6_nexthop_lookup (struct zserv *client, u_short length){ struct in6_addr addr; char buf[BUFSIZ]; stream_get (&addr, client->ibuf, 16); printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ)); zsend_ipv6_nexthop_lookup (client, &addr);}#endif /* HAVE_IPV6 *//* Close zebra client. */voidzebra_client_close (struct zserv *client){ /* Close file descriptor. */ if (client->sock) { close (client->sock); client->sock = -1; } /* Free stream buffers. */ if (client->ibuf) stream_free (client->ibuf); if (client->obuf) stream_free (client->obuf); /* Release threads. */ if (client->t_read) thread_cancel (client->t_read); if (client->t_write) thread_cancel (client->t_write); /* Free client structure. */ listnode_delete (client_list, client); XFREE (0, client);}/* Make new client. */voidzebra_client_create (int sock){ struct zserv *client; client = XCALLOC (0, sizeof (struct zserv)); /* Make client input/output buffer. */ client->sock = sock; client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ); client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ); /* Set table number. */ client->rtm_table = rtm_table_default; /* Add this client to linked list. */ listnode_add (client_list, client); /* Make new read thread. */ zebra_event (ZEBRA_READ, sock, client);}/* Handler of zebra service request. */intzebra_client_read (struct thread *thread){ int sock; struct zserv *client; int nbyte; u_short length; u_char command; /* Get thread data. Reset reading thread because I'm running. */ sock = THREAD_FD (thread); client = THREAD_ARG (thread); client->t_read = NULL; /* Read length and command. */ nbyte = stream_read (client->ibuf, sock, 3); if (nbyte <= 0) { if (IS_ZEBRA_DEBUG_EVENT) zlog_info ("connection closed socket [%d]", sock); zebra_client_close (client); return -1; } length = stream_getw (client->ibuf); command = stream_getc (client->ibuf); if (length < 3) { if (IS_ZEBRA_DEBUG_EVENT) zlog_info ("length %d is less than 3 ", length); zebra_client_close (client); return -1; } length -= 3; /* Read rest of data. */ if (length) { nbyte = stream_read (client->ibuf, sock, length); if (nbyte <= 0) { if (IS_ZEBRA_DEBUG_EVENT) zlog_info ("connection closed [%d] when reading zebra data", sock); zebra_client_close (client); return -1; } } /* Debug packet information. */ if (IS_ZEBRA_DEBUG_EVENT) zlog_info ("zebra message comes from socket [%d]", sock); if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) zlog_info ("zebra message received [%s] %d", zebra_command_str[command], length); switch (command) { case ZEBRA_INTERFACE_ADD: zread_interface_add (client, length); break; case ZEBRA_INTERFACE_DELETE: zread_interface_delete (client, length); break; case ZEBRA_IPV4_ROUTE_ADD: zread_ipv4_add (client, length); break; case ZEBRA_IPV4_ROUTE_DELETE: zread_ipv4_delete (client, length); break;#ifdef HAVE_IPV6 case ZEBRA_IPV6_ROUTE_ADD: zread_ipv6_add (client, length); break; case ZEBRA_IPV6_ROUTE_DELETE: zread_ipv6_delete (client, length); break;#endif /* HAVE_IPV6 */ case ZEBRA_REDISTRIBUTE_ADD: zebra_redistribute_add (command, client, length); break; case ZEBRA_REDISTRIBUTE_DELETE: zebra_redistribute_delete (command, client, length); break; case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: zebra_redistribute_default_add (command, client, length); break; case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: zebra_redistribute_default_delete (command, client, length); break; case ZEBRA_IPV4_NEXTHOP_LOOKUP: zread_ipv4_nexthop_lookup (client, length); break;#ifdef HAVE_IPV6 case ZEBRA_IPV6_NEXTHOP_LOOKUP: zread_ipv6_nexthop_lookup (client, length); break;#endif /* HAVE_IPV6 */ case ZEBRA_IPV4_IMPORT_LOOKUP: zread_ipv4_import_lookup (client, length); break; default: zlog_info ("Zebra received unknown command %d", command); break; } stream_reset (client->ibuf); zebra_event (ZEBRA_READ, sock, client); return 0;}/* Write output buffer to the socket. */voidzebra_write (struct thread *thread){ int sock; struct zserv *client; /* Thread treatment. */ sock = THREAD_FD (thread); client = THREAD_ARG (thread); client->t_write = NULL; stream_flush (client->obuf, sock);}/* Accept code of zebra server socket. */intzebra_accept (struct thread *thread){ int val; int accept_sock; int client_sock; struct sockaddr_in client; socklen_t len; accept_sock = THREAD_FD (thread); len = sizeof (struct sockaddr_in); client_sock = accept (accept_sock, (struct sockaddr *) &client, &len); if (client_sock < 0) { zlog_warn ("Can't accept zebra socket: %s", strerror (errno)); return -1; } /* Make client socket non-blocking. */ val = fcntl (client_sock, F_GETFL, 0); fcntl (client_sock, F_SETFL, (val | O_NONBLOCK)); /* Create new zebra client. */ zebra_client_create (client_sock); /* Register myself. */ zebra_event (ZEBRA_SERV, accept_sock, NULL); return 0;}/* Make zebra's server socket. */voidzebra_serv (){ int ret; int accept_sock; struct sockaddr_in addr; accept_sock = socket (AF_INET, SOCK_STREAM, 0); if (accept_sock < 0) { zlog_warn ("Can't bind to socket: %s", strerror (errno)); zlog_warn ("zebra can't provice full functionality due to above error"); return; } memset (&addr, 0, sizeof (struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons (ZEBRA_PORT);#ifdef HAVE_SIN_LEN addr.sin_len = sizeof (struct sockaddr_in);#endif /* HAVE_SIN_LEN */ addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); sockopt_reuseaddr (accept_sock); sockopt_reuseport (accept_sock); ret = bind (accept_sock, (struct sockaddr *)&addr, sizeof (struct sockaddr_in)); if (ret < 0) { zlog_warn ("Can't bind to socket: %s", strerror (errno)); zlog_warn ("zebra can't provice full functionality due to above error"); close (accept_sock); /* Avoid sd leak. */ return; } ret = listen (accept_sock, 1); if (ret < 0) { zlog_warn ("Can't listen to socket: %s", strerror (errno)); zlog_warn ("zebra can't provice full functionality due to above error"); close (accept_sock); /* Avoid sd leak. */ return; } zebra_event (ZEBRA_SERV, accept_sock, NULL);}/* For sockaddr_un. */#include <sys/un.h>/* zebra server UNIX domain socket. */voidzebra_serv_un (char *path){ int ret; int sock, len; struct sockaddr_un serv; mode_t old_mask; /* First of all, unlink existing socket */ unlink (path); /* Set umask */ old_mask = umask (0077); /* Make UNIX domain socket. */ sock = socket (AF_UNIX, SOCK_STREAM, 0); if (sock < 0) { perror ("sock"); return; } /* Make server socket. */ memset (&serv, 0, sizeof (struct sockaddr_un)); serv.sun_family = AF_UNIX; strncpy (serv.sun_path, path, strlen (path));#ifdef HAVE_SUN_LEN len = serv.sun_len = SUN_LEN(&serv);#else len = sizeof (serv.sun_family) + strlen (serv.sun_path);#endif /* HAVE_SUN_LEN */ ret = bind (sock, (struct sockaddr *) &serv, len); if (ret < 0) { perror ("bind"); close (sock); return; } ret = listen (sock, 5); if (ret < 0) { perror ("listen"); close (sock); return; } umask (old_mask); zebra_event (ZEBRA_SERV, sock, NULL);}/* Zebra's event management function. */extern struct thread_master *master;voidzebra_event (enum event event, int sock, struct zserv *client){ switch (event) { case ZEBRA_SERV: thread_add_read (master, zebra_accept, client, sock); break; case ZEBRA_READ: client->t_read = thread_add_read (master, zebra_client_read, client, sock); break; case ZEBRA_WRITE: /**/ break; }}/* Display default rtm_table for all clients. */DEFUN (show_table, show_table_cmd, "show table", SHOW_STR "default routing table to use for all clients\n"){ vty_out (vty, "table %d%s", rtm_table_default, VTY_NEWLINE); return CMD_SUCCESS;}DEFUN (config_table, config_table_cmd, "table TABLENO", "Configure target kernel routing table\n" "TABLE integer\n"){ rtm_table_default = strtol (argv[0], (char**)0, 10); return CMD_SUCCESS;}DEFUN (no_ip_forwarding, no_ip_forwarding_cmd, "no ip forwarding", NO_STR IP_STR "Turn off IP forwarding"){ int ret; ret = ipforward (); if (ret == 0) { vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE); return CMD_ERR_NOTHING_TODO; } ret = ipforward_off (); if (ret != 0) { vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS;}/* This command is for debugging purpose. */DEFUN (show_zebra_client, show_zebra_client_cmd, "show zebra client", SHOW_STR "Zebra information" "Client information"){ listnode node; struct zserv *client; for (node = listhead (client_list); node; nextnode (node)) { client = getdata (node); vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE); } return CMD_SUCCESS;}/* Table configuration write function. */intconfig_write_table (struct vty *vty){ if (rtm_table_default) vty_out (vty, "table %d%s", rtm_table_default, VTY_NEWLINE); return 0;}/* table node for routing tables. */struct cmd_node table_node ={ TABLE_NODE, "", /* This node has no interface. */ 1};/* Only display ip forwarding is enabled or not. */DEFUN (show_ip_forwarding, show_ip_forwarding_cmd, "show ip forwarding", SHOW_STR IP_STR "IP forwarding status\n"){ int ret; ret = ipforward (); if (ret == 0) vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE); else vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE); return CMD_SUCCESS;}#ifdef HAVE_IPV6/* Only display ipv6 forwarding is enabled or not. */DEFUN (show_ipv6_forwarding, show_ipv6_forwarding_cmd, "show ipv6 forwarding", SHOW_STR "IPv6 information\n" "Forwarding status\n"){ int ret; ret = ipforward_ipv6 (); switch (ret) { case -1: vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE); break; case 0: vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE); break; case 1: vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE); break; default: vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE); break; } return CMD_SUCCESS;}DEFUN (no_ipv6_forwarding, no_ipv6_forwarding_cmd, "no ipv6 forwarding", NO_STR IP_STR "Doesn't forward IPv6 protocol packet"){ int ret; ret = ipforward_ipv6_off (); if (ret != 0) { vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS;}#endif /* HAVE_IPV6 *//* IPForwarding configuration write function. */intconfig_write_forwarding (struct vty *vty){ if (! ipforward ()) vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);#ifdef HAVE_IPV6 if (! ipforward_ipv6 ()) vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);#endif /* HAVE_IPV6 */ vty_out (vty, "!%s", VTY_NEWLINE); return 0;}/* table node for routing tables. */struct cmd_node forwarding_node ={ FORWARDING_NODE, "", /* This node has no interface. */ 1};/* Initialisation of zebra and installation of commands. */voidzebra_init (){ /* Client list init. */ client_list = list_new (); /* Forwarding is on by default. */ ipforward_on ();#ifdef HAVE_IPV6 ipforward_ipv6_on ();#endif /* HAVE_IPV6 */ /* Make zebra server socket. */#ifdef HAVE_TCP_ZEBRA zebra_serv ();#else zebra_serv_un (ZEBRA_SERV_PATH);#endif /* HAVE_TCP_ZEBRA */ /* Install configuration write function. */ install_node (&table_node, config_write_table); install_node (&forwarding_node, config_write_forwarding); install_element (VIEW_NODE, &show_ip_forwarding_cmd); install_element (ENABLE_NODE, &show_ip_forwarding_cmd); install_element (CONFIG_NODE, &no_ip_forwarding_cmd); install_element (ENABLE_NODE, &show_zebra_client_cmd);#ifdef HAVE_NETLINK install_element (VIEW_NODE, &show_table_cmd); install_element (ENABLE_NODE, &show_table_cmd); install_element (CONFIG_NODE, &config_table_cmd);#endif /* HAVE_NETLINK */#ifdef HAVE_IPV6 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd); install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd); install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);#endif /* HAVE_IPV6 */ FIFO_INIT(&message_queue); t_write = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -