summaryrefslogtreecommitdiffstats
path: root/nhrpd/nhrp_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'nhrpd/nhrp_config.c')
-rw-r--r--nhrpd/nhrp_config.c342
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);
+}