diff options
Diffstat (limited to 'nhrpd/nhrp_config.c')
-rw-r--r-- | nhrpd/nhrp_config.c | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/nhrpd/nhrp_config.c b/nhrpd/nhrp_config.c new file mode 100644 index 00000000..c7f931f2 --- /dev/null +++ b/nhrpd/nhrp_config.c @@ -0,0 +1,342 @@ +/* + * NHRP configuration. + * Copyright (c) 2014 Timo Teräs + * + * This file is free software: you may copy, redistribute and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 2 of the License, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* quagga's includes */ +#include "zebra.h" +#include "command.h" +#include "zclient.h" +#include "stream.h" + +#include "nhrpd.h" + +static struct zclient *zclient; + +static struct cmd_node zebra_node = { + ZEBRA_NODE, + "%s(config-router)# ", + 1 /* vtysh? yes */ +}; + +static struct cmd_node debug_node = { + DEBUG_NODE, + "", + 1 +}; + +static const struct message debug_type[] = { + { NHRP_DEBUG_ALL, "all" }, + { NHRP_DEBUG_COMMON, "common" }, + { NHRP_DEBUG_KERNEL, "kernel" }, + { NHRP_DEBUG_ROUTE, "route" }, + { 0, NULL }, +}; + +#if 0 +/* Zebra route add and delete treatment (ipv6). */ +static int +babel_zebra_read_ipv6 (int command, struct zclient *zclient, + zebra_size_t length) +{ + struct stream *s; + struct zapi_ipv6 api; + unsigned long ifindex = -1; + struct in6_addr nexthop; + struct prefix_ipv6 prefix; + + s = zclient->ibuf; + ifindex = 0; + memset (&nexthop, 0, sizeof (struct in6_addr)); + memset (&api, 0, sizeof(struct zapi_ipv6)); + memset (&prefix, 0, sizeof (struct prefix_ipv6)); + + /* Type, flags, message. */ + api.type = stream_getc (s); + api.flags = stream_getc (s); + api.message = stream_getc (s); + + /* IPv6 prefix. */ + prefix.family = AF_INET6; + prefix.prefixlen = stream_getc (s); + stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen)); + + /* Nexthop, ifindex, distance, metric. */ + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { + api.nexthop_num = stream_getc (s); + stream_get (&nexthop, s, sizeof(nexthop)); + } + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { + api.ifindex_num = stream_getc (s); + ifindex = stream_getl (s); + } + 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 (command == ZEBRA_IPV6_ROUTE_ADD) + babel_ipv6_route_add(&api, &prefix, ifindex, &nexthop); + else + babel_ipv6_route_delete(&api, &prefix, ifindex); + + return 0; +} + +static int +babel_zebra_read_ipv4 (int command, struct zclient *zclient, + zebra_size_t length) +{ + struct stream *s; + struct zapi_ipv4 api; + unsigned long ifindex = -1; + struct in_addr nexthop; + struct prefix_ipv4 prefix; + + s = zclient->ibuf; + ifindex = 0; + memset (&nexthop, 0, sizeof (struct in_addr)); + memset (&api, 0, sizeof(struct zapi_ipv4)); + memset (&prefix, 0, sizeof (struct prefix_ipv4)); + + /* Type, flags, message. */ + api.type = stream_getc (s); + api.flags = stream_getc (s); + api.message = stream_getc (s); + + /* IPv6 prefix. */ + prefix.family = AF_INET; + prefix.prefixlen = stream_getc (s); + stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen)); + + /* Nexthop, ifindex, distance, metric. */ + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { + api.nexthop_num = stream_getc (s); + stream_get (&nexthop, s, sizeof(nexthop)); + } + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { + api.ifindex_num = stream_getc (s); + ifindex = stream_getl (s); + } + 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 (command == ZEBRA_IPV6_ROUTE_ADD) { + babel_ipv4_route_add(&api, &prefix, ifindex, &nexthop); + } else { + babel_ipv4_route_delete(&api, &prefix, ifindex); + } + + return 0; +} + +/* [NHRP Command] */ +DEFUN(nhrp_redistribute_type, nhrp_redistribute_type_cmd, + "redistribute " QUAGGA_REDIST_STR_BABELD, + "Redistribute\n" + QUAGGA_REDIST_HELP_STR_BABELD) +{ + int type; + + type = proto_redistnum(AFI_IP6, argv[0]); + if (type < 0) + type = proto_redistnum(AFI_IP, argv[0]); + if (type < 0) { + vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, type); + return CMD_SUCCESS; +} + +/* [Babel Command] */ +DEFUN (no_babel_redistribute_type, + no_babel_redistribute_type_cmd, + "no redistribute " QUAGGA_REDIST_STR_BABELD, + NO_STR + "Redistribute\n" + QUAGGA_REDIST_HELP_STR_BABELD) +{ + int type; + + type = proto_redistnum(AFI_IP6, argv[0]); + + if (type < 0) + type = proto_redistnum(AFI_IP, argv[0]); + + if (type < 0) { + vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type); + /* perhaps should we remove xroutes having the same type... */ + return CMD_SUCCESS; +} +#endif + +#ifndef NO_DEBUG + +DEFUN(show_debugging_nhrp, show_debugging_nhrp_cmd, + "show debugging nhrp", + SHOW_STR + "Debugging information\n" + "NHRP configuration\n") +{ + int i; + + vty_out(vty, "NHRP debugging status:%s", VTY_NEWLINE); + + for (i = 0; debug_type[i].str != NULL; i++) { + if (debug_type[i].key == NHRP_DEBUG_ALL) + continue; + if (!(debug_type[i].key & debug_flags)) + continue; + + vty_out(vty, " NHRP %s debugging is on%s", + debug_type[i].str, VTY_NEWLINE); + } + + return CMD_SUCCESS; +} + +static int toggle_debug(struct vty *vty, const char *type, int on_off) +{ + int i; + + for (i = 0; debug_type[i].str != NULL; i++) { + if (strcmp(debug_type[i].str, type) != 0) + continue; + if (on_off) + debug_flags |= debug_type[i].key; + else + debug_flags &= ~debug_type[i].key; + return CMD_SUCCESS; + } + vty_out(vty, "Invalid type %s%s", type, VTY_NEWLINE); + return CMD_WARNING; +} + +DEFUN (debug_nhrp, debug_nhrp_cmd, + "debug nhrp (common|kernel|route|all)", + "Enable debug messages for specific or all parts.\n" + "NHRP information\n" + "Common messages (default)\n" + "Kernel messages\n" + "Route messages\n" + "All messages\n") +{ + return toggle_debug(vty, argv[0], 1); +} + +DEFUN (no_debug_nhrp, no_debug_nhrp_cmd, + "no debug nhrp (common|kernel|route|all)", + NO_STR + "Disable debug messages for specific or all parts.\n" + "NHRP information\n" + "Common messages (default)\n" + "Kernel messages\n" + "Route messages\n" + "All messages\n") +{ + return toggle_debug(vty, argv[0], 0); +} + +#endif /* NO_DEBUG */ + +static int nhrp_config_write(struct vty *vty) +{ + int lines = 0; + +#ifndef NO_DEBUG + if (debug_flags == NHRP_DEBUG_ALL) { + vty_out (vty, "debug nhrp all%s", VTY_NEWLINE); + lines++; + } else { + int i; + + for (i = 0; debug_type[i].str != NULL; i++) { + if (debug_type[i].key == NHRP_DEBUG_ALL) + continue; + if (!(debug_flags & debug_type[i].key)) + continue; + vty_out (vty, "debug nhrp %s%s", debug_type[i].str, VTY_NEWLINE); + lines++; + } + } +#endif /* NO_DEBUG */ + + if (lines) { + vty_out (vty, "!%s", VTY_NEWLINE); + lines++; + } + + if (!zclient->enable) { + vty_out (vty, "no router zebra%s", VTY_NEWLINE); + lines++; + } else if (!zclient->redist[ZEBRA_ROUTE_NHRP]) { + vty_out(vty, "router zebra%s", VTY_NEWLINE); + vty_out(vty, " no redistribute nhrp%s", VTY_NEWLINE); + lines += 2; + } + + return lines; +} + +void nhrp_zebra_init(void) +{ + zclient = zclient_new(); +#if 0 + zclient->interface_add = babel_interface_add; + zclient->interface_delete = babel_interface_delete; + zclient->interface_up = babel_interface_up; + zclient->interface_down = babel_interface_down; + zclient->interface_address_add = babel_interface_address_add; + zclient->interface_address_delete = babel_interface_address_delete; + zclient->ipv4_route_add = babel_zebra_read_ipv4; + zclient->ipv4_route_delete = babel_zebra_read_ipv4; + zclient->ipv6_route_add = babel_zebra_read_ipv6; + zclient->ipv6_route_delete = babel_zebra_read_ipv6; +#endif + zclient_init(zclient, ZEBRA_ROUTE_NHRP); + + install_node(&zebra_node, nhrp_config_write); + install_default(ZEBRA_NODE); + + install_element(VIEW_NODE, &show_debugging_nhrp_cmd); + + install_element(ENABLE_NODE, &show_debugging_nhrp_cmd); + install_element(ENABLE_NODE, &debug_nhrp_cmd); + install_element(ENABLE_NODE, &no_debug_nhrp_cmd); + + install_element(CONFIG_NODE, &debug_nhrp_cmd); + install_element(CONFIG_NODE, &no_debug_nhrp_cmd); +} + +void nhrp_zebra_terminate(void) +{ + zclient_stop(zclient); +} |