diff options
author | Timo Teräs <timo.teras@iki.fi> | 2014-09-30 08:20:31 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2014-09-30 08:20:45 +0300 |
commit | ae9537903c496dc50693c59b7b0751aee38ed012 (patch) | |
tree | b1eddd7d5178eac802cb4018a0d75bd899133457 | |
parent | 55bccfd7198195aef8f968691b53ec867cbe3989 (diff) | |
download | quagga-old-nhrp.tar.bz2 quagga-old-nhrp.tar.xz |
add nhrpd skeletonold-nhrp
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | SERVICES | 2 | ||||
-rwxr-xr-x | configure.ac | 18 | ||||
-rw-r--r-- | lib/log.c | 5 | ||||
-rw-r--r-- | lib/log.h | 3 | ||||
-rw-r--r-- | nhrpd/Makefile.am | 18 | ||||
-rw-r--r-- | nhrpd/nhrp_config.c | 342 | ||||
-rw-r--r-- | nhrpd/nhrp_main.c | 230 | ||||
-rw-r--r-- | nhrpd/nhrpd.h | 43 | ||||
-rw-r--r-- | vtysh/Makefile.am | 2 | ||||
-rw-r--r-- | vtysh/vtysh.c | 1 | ||||
-rw-r--r-- | vtysh/vtysh.h | 5 | ||||
-rw-r--r-- | zebra/client_main.c | 1 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 2 |
14 files changed, 668 insertions, 10 deletions
diff --git a/Makefile.am b/Makefile.am index 6916470b..ff32ae1f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,10 @@ ## Process this file with automake to produce Makefile.in. SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @BABELD@ \ - @ISISD@ @WATCHQUAGGA@ @VTYSH@ @OSPFCLIENT@ @DOC@ m4 @pkgsrcdir@ \ - redhat @SOLARIS@ tests + @NHRPD@ @ISISD@ @WATCHQUAGGA@ @VTYSH@ @OSPFCLIENT@ @DOC@ \ + m4 @pkgsrcdir@ redhat @SOLARIS@ tests -DIST_SUBDIRS = lib zebra bgpd ripd ripngd ospfd ospf6d babeld \ +DIST_SUBDIRS = lib zebra bgpd ripd ripngd ospfd ospf6d babeld nhrpd \ isisd watchquagga vtysh ospfclient doc m4 pkgsrc redhat tests \ solaris @@ -17,3 +17,5 @@ bgpd 2605/tcp ospf6d 2606/tcp ospfapi 2607/tcp isisd 2608/tcp +babeld 2609/tcp +nhrpd 2610/tcp diff --git a/configure.ac b/configure.ac index f1df482b..b4c572e7 100755 --- a/configure.ac +++ b/configure.ac @@ -216,6 +216,8 @@ AC_ARG_ENABLE(ospf6d, [ --disable-ospf6d do not build ospf6d]) AC_ARG_ENABLE(babeld, [ --disable-babeld do not build babeld]) +AC_ARG_ENABLE(nhrpd, +[ --disable-nhrpd do not build nhrpd]) AC_ARG_ENABLE(watchquagga, [ --disable-watchquagga do not build watchquagga]) AC_ARG_ENABLE(isisd, @@ -1309,6 +1311,13 @@ else fi AM_CONDITIONAL(BABELD, test "x$BABELD" = "xbabeld") +if test "${enable_nhrpd}" = "no";then + NHRPD="" +else + NHRPD="nhrpd" +fi +AM_CONDITIONAL(NHRPD, test "x$NHRPD" = "xnhrpd") + if test "${enable_watchquagga}" = "no";then WATCHQUAGGA="" else @@ -1371,6 +1380,7 @@ AC_SUBST(RIPNGD) AC_SUBST(OSPFD) AC_SUBST(OSPF6D) AC_SUBST(BABELD) +AC_SUBST(NHRPD) AC_SUBST(WATCHQUAGGA) AC_SUBST(ISISD) AC_SUBST(SOLARIS) @@ -1672,6 +1682,7 @@ AC_DEFINE_UNQUOTED(PATH_BGPD_PID, "$quagga_statedir/bgpd.pid",bgpd PID) AC_DEFINE_UNQUOTED(PATH_OSPFD_PID, "$quagga_statedir/ospfd.pid",ospfd PID) AC_DEFINE_UNQUOTED(PATH_OSPF6D_PID, "$quagga_statedir/ospf6d.pid",ospf6d PID) AC_DEFINE_UNQUOTED(PATH_BABELD_PID, "$quagga_statedir/babeld.pid",babeld PID) +AC_DEFINE_UNQUOTED(PATH_NHRPD_PID, "$quagga_statedir/nhrpd.pid",nhrpd PID) AC_DEFINE_UNQUOTED(PATH_ISISD_PID, "$quagga_statedir/isisd.pid",isisd PID) AC_DEFINE_UNQUOTED(PATH_WATCHQUAGGA_PID, "$quagga_statedir/watchquagga.pid",watchquagga PID) AC_DEFINE_UNQUOTED(ZEBRA_SERV_PATH, "$quagga_statedir/zserv.api",zebra api socket) @@ -1682,6 +1693,7 @@ AC_DEFINE_UNQUOTED(BGP_VTYSH_PATH, "$quagga_statedir/bgpd.vty",bgpd vty socket) AC_DEFINE_UNQUOTED(OSPF_VTYSH_PATH, "$quagga_statedir/ospfd.vty",ospfd vty socket) AC_DEFINE_UNQUOTED(OSPF6_VTYSH_PATH, "$quagga_statedir/ospf6d.vty",ospf6d vty socket) AC_DEFINE_UNQUOTED(BABEL_VTYSH_PATH, "$quagga_statedir/babeld.vty",babeld vty socket) +AC_DEFINE_UNQUOTED(NHRP_VTYSH_PATH, "$quagga_statedir/nhrpd.vty",nhrpd vty socket) AC_DEFINE_UNQUOTED(ISIS_VTYSH_PATH, "$quagga_statedir/isisd.vty",isisd vty socket) AC_DEFINE_UNQUOTED(DAEMON_VTY_DIR, "$quagga_statedir",daemon vty directory) @@ -1706,9 +1718,9 @@ AC_MSG_RESULT($ac_cv_htonl_works) AC_CONFIG_FILES([Makefile lib/Makefile zebra/Makefile ripd/Makefile ripngd/Makefile bgpd/Makefile ospfd/Makefile watchquagga/Makefile - ospf6d/Makefile isisd/Makefile babeld/Makefile vtysh/Makefile - doc/Makefile ospfclient/Makefile tests/Makefile m4/Makefile - tests/bgpd.tests/Makefile + ospf6d/Makefile isisd/Makefile babeld/Makefile nhrpd/Makefile + vtysh/Makefile doc/Makefile ospfclient/Makefile m4/Makefile + tests/Makefile tests/bgpd.tests/Makefile tests/libzebra.tests/Makefile redhat/Makefile pkgsrc/Makefile @@ -52,6 +52,7 @@ const char *zlog_proto_names[] = "OSPF6", "ISIS", "MASC", + "NHRP", NULL, }; @@ -978,6 +979,8 @@ proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BGP; else if (strncmp (s, "ba", 2) == 0) return ZEBRA_ROUTE_BABEL; + else if (strncmp (s, "n", 1) == 0) + return ZEBRA_ROUTE_NHRP; } if (afi == AFI_IP6) { @@ -997,6 +1000,8 @@ proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BGP; else if (strncmp (s, "ba", 2) == 0) return ZEBRA_ROUTE_BABEL; + else if (strncmp (s, "n", 1) == 0) + return ZEBRA_ROUTE_NHRP; } return -1; } @@ -53,7 +53,8 @@ typedef enum ZLOG_BABEL, ZLOG_OSPF6, ZLOG_ISIS, - ZLOG_MASC + ZLOG_MASC, + ZLOG_NHRP } zlog_proto_t; /* If maxlvl is set to ZLOG_DISABLED, then no messages will be sent diff --git a/nhrpd/Makefile.am b/nhrpd/Makefile.am new file mode 100644 index 00000000..d5e663e7 --- /dev/null +++ b/nhrpd/Makefile.am @@ -0,0 +1,18 @@ +## Process this file with automake to produce Makefile.in. + +INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib +DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" +INSTALL_SDATA=@INSTALL@ -m 600 + +AM_CFLAGS = $(PICFLAGS) +AM_LDFLAGS = $(PILDFLAGS) + +sbin_PROGRAMS = nhrpd + +nhrpd_SOURCES = \ + nhrp_config.c \ + nhrp_main.c + +nhrpd_LDADD = ../lib/libzebra.la @LIBCAP@ + +#dist_examples_DATA = nhrpd.conf.sample 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); +} diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c new file mode 100644 index 00000000..6552bb69 --- /dev/null +++ b/nhrpd/nhrp_main.c @@ -0,0 +1,230 @@ +/* + * NHRP daemon main functions. + * 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/>. + */ + +#include <unistd.h> + +#include "zebra.h" +#include "privs.h" +#include "getopt.h" +#include "thread.h" +#include "sigevent.h" +#include "version.h" +#include "log.h" +#include "memory.h" + +#include "nhrpd.h" + +unsigned int debug_flags = 0; + +struct thread_master *master; +struct timeval current_time; +static const char *pid_file = PATH_NHRPD_PID; +static char config_default[] = SYSCONFDIR NHRP_DEFAULT_CONFIG; +static char *config_file = NULL; +static char *vty_addr = NULL; +static int vty_port = NHRP_VTY_PORT; +static int do_daemonise = 0; + +/* nhrpd options. */ +struct option longopts[] = { + { "daemon", no_argument, NULL, 'd'}, + { "config_file", required_argument, NULL, 'f'}, + { "pid_file", required_argument, NULL, 'i'}, + { "socket", required_argument, NULL, 'z'}, + { "help", no_argument, NULL, 'h'}, + { "vty_addr", required_argument, NULL, 'A'}, + { "vty_port", required_argument, NULL, 'P'}, + { "user", required_argument, NULL, 'u'}, + { "group", required_argument, NULL, 'g'}, + { "version", no_argument, NULL, 'v'}, + { 0 } +}; + +/* nhrpd privileges */ +static zebra_capabilities_t _caps_p [] = { + ZCAP_NET_RAW, ZCAP_BIND +}; + +static struct zebra_privs_t nhrpd_privs = { +#ifdef QUAGGA_USER + .user = QUAGGA_USER, +#endif +#ifdef QUAGGA_GROUP + .group = QUAGGA_GROUP, +#endif +#ifdef VTY_GROUP + .vty_group = VTY_GROUP, +#endif + .caps_p = _caps_p, + .cap_num_p = 2, + .cap_num_i = 0 +}; + +static void usage(const char *progname, int status) +{ + if (status != 0) + fprintf(stderr, "Try `%s --help' for more information.\n", progname); + else + printf( +"Usage : %s [OPTION...]\n\ +Daemon which manages NHRP protocol.\n\n\ +-d, --daemon Runs in daemon mode\n\ +-f, --config_file Set configuration file name\n\ +-i, --pid_file Set process identifier file name\n\ +-z, --socket Set path of zebra socket\n\ +-A, --vty_addr Set vty's bind address\n\ +-P, --vty_port Set vty's port number\n\ +-u, --user User to run as\n\ +-g, --group Group to run as\n\ +-v, --version Print program version\n\ +-h, --help Display this help and exit\n\ +\n\ +Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS); + + exit(status); +} + +static void parse_arguments(const char *progname, int argc, char **argv) +{ + int rc, opt; + + while (1) { + opt = getopt_long(argc, argv, "df:i:z:hA:P:u:g:v", longopts, 0); + if(opt < 0) break; + + switch (opt) { + case 0: + break; + case 'd': + do_daemonise = -1; + break; + case 'f': + config_file = optarg; + break; + case 'i': + pid_file = optarg; + break; + case 'z': + zclient_serv_path_set(optarg); + break; + case 'A': + vty_addr = optarg; + break; + case 'P': + vty_port = atoi (optarg); + if (vty_port <= 0 || vty_port > 0xffff) + vty_port = NHRP_VTY_PORT; + break; + case 'u': + nhrpd_privs.user = optarg; + break; + case 'g': + nhrpd_privs.group = optarg; + break; + case 'v': + print_version(progname); + exit(0); + break; + case 'h': + usage(progname, 0); + break; + default: + usage(progname, 1); + break; + } + } +} + +static void nhrp_sigusr1(void) +{ + zlog_rotate(NULL); +} + +static void nhrp_request_stop(void) +{ + debugf(NHRP_DEBUG_COMMON, "Exiting..."); + + nhrp_zebra_terminate(); + /* memory_terminate(); */ + vty_terminate(); + cmd_terminate(); + /* signal_terminate(); */ + zprivs_terminate(&nhrpd_privs); + + debugf(NHRP_DEBUG_COMMON, "Remove pid file."); + if (pid_file) unlink(pid_file); + debugf(NHRP_DEBUG_COMMON, "Done."); + + closezlog(zlog_default); + + exit(0); +} + +static struct quagga_signal_t sighandlers[] = { + { .signal = SIGUSR1, .handler = &nhrp_sigusr1, }, + { .signal = SIGINT, .handler = &nhrp_request_stop, }, + { .signal = SIGTERM, .handler = &nhrp_request_stop, }, +}; + +int main(int argc, char **argv) +{ + struct thread thread; + const char *progname; + + /* Set umask before anything for security */ + umask(0027); + progname = basename(argv[0]); + zlog_default = openzlog(progname, ZLOG_NHRP, LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); + zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING); + + parse_arguments(progname, argc, argv); + + /* Library inits. */ + master = thread_master_create(); + zprivs_init(&nhrpd_privs); + signal_init(master, array_size(sighandlers), sighandlers); + cmd_init(1); + vty_init(master); + memory_init(); + nhrp_zebra_init(); + + if (do_daemonise && daemon(0, 0) < 0) { + zlog_err("daemonise: %s", safe_strerror(errno)); + exit (1); + } + + /* write pid file */ + if (pid_output(pid_file) < 0) { + zlog_err("error while writing pidfile"); + exit (1); + } + + /* Get zebra configuration file. */ + zlog_set_level(NULL, ZLOG_DEST_STDOUT, do_daemonise ? ZLOG_DISABLED : LOG_DEBUG); + vty_read_config(config_file, config_default); + + /* Create VTY socket */ + vty_serv_sock(vty_addr, vty_port, NHRP_VTYSH_PATH); + zlog_notice("nhrpd starting: vty@%d", vty_port); + + /* Main loop */ + while (thread_fetch(master, &thread)) + thread_call(&thread); + + return 0; +} diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h new file mode 100644 index 00000000..016ab34e --- /dev/null +++ b/nhrpd/nhrpd.h @@ -0,0 +1,43 @@ + +#define NHRP_DEBUG_COMMON (1 << 0) +#define NHRP_DEBUG_KERNEL (1 << 1) +#define NHRP_DEBUG_ROUTE (1 << 2) +#define NHRP_DEBUG_ALL (0xFFFF) + +#define NHRP_VTY_PORT 2610 +#define NHRP_DEFAULT_CONFIG "nhrpd.conf" + +#if defined(__GNUC__) && (__GNUC__ >= 3) +#define likely(_x) __builtin_expect(!!(_x), 1) +#define unlikely(_x) __builtin_expect(!!(_x), 0) +#else +#define likely(_x) !!(_x) +#define unlikely(_x) !!(_x) +#endif + +extern unsigned int debug_flags; + +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L + +#define debugf(level, ...) \ + do { \ + if (unlikely(debug_flags & level)) \ + zlog_debug(__VA_ARGS__); \ + } while(0) + +#elif defined __GNUC__ + +#define debugf(level, _args...) \ + do { \ + if (unlikely(debug_flags & level)) \ + zlog_debug(_args); \ + } while(0) + +#else + +static inline void debugf(int level, const char *format, ...) { } + +void nhrp_zebra_init(void); +void nhrp_zebra_terminate(void); + +#endif diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am index 5c325ec2..92feb27e 100644 --- a/vtysh/Makefile.am +++ b/vtysh/Makefile.am @@ -24,7 +24,7 @@ EXTRA_DIST = extract.pl vtysh_cmd_FILES = $(top_srcdir)/bgpd/*.c $(top_srcdir)/isisd/*.c \ $(top_srcdir)/ospfd/*.c $(top_srcdir)/ospf6d/*.c \ $(top_srcdir)/ripd/*.c $(top_srcdir)/ripngd/*.c \ - $(top_srcdir)/babeld/*.c \ + $(top_srcdir)/babeld/*.c $(top_srcdir)/nhrpd/*.c \ $(top_srcdir)/lib/keychain.c $(top_srcdir)/lib/routemap.c \ $(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \ $(top_srcdir)/lib/distribute.c $(top_srcdir)/lib/if_rmap.c \ diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 89b9b257..6c98a611 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -59,6 +59,7 @@ struct vtysh_client { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH}, { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH}, { .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_VTYSH_PATH}, + { .fd = -1, .name = "nhrpd", .flag = VTYSH_NHRPD, .path = NHRP_VTYSH_PATH}, }; diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 3cc7bafe..bf120c51 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -29,8 +29,9 @@ #define VTYSH_OSPF6D 0x10 #define VTYSH_BGPD 0x20 #define VTYSH_ISISD 0x40 -#define VTYSH_BABELD 0x80 -#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_BABELD +#define VTYSH_BABELD 0x80 +#define VTYSH_NHRPD 0x100 +#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_BABELD|VTYSH_NHRPD #define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_BABELD #define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_BABELD diff --git a/zebra/client_main.c b/zebra/client_main.c index 8b95907b..6fe86c76 100644 --- a/zebra/client_main.c +++ b/zebra/client_main.c @@ -119,6 +119,7 @@ struct zebra_info { "ospf", ZEBRA_ROUTE_OSPF }, { "ospf6", ZEBRA_ROUTE_OSPF6 }, { "bgp", ZEBRA_ROUTE_BGP }, + { "nhrp", ZEBRA_ROUTE_NHRP }, { NULL, 0 } }; diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index dc7e1ca1..4f7ff234 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -69,6 +69,7 @@ static const struct [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115}, [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}, [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95}, + [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10}, /* no entry/default: 150 */ }; @@ -1510,6 +1511,7 @@ static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = { [ZEBRA_ROUTE_BGP] = 3, [ZEBRA_ROUTE_HSLS] = 4, [ZEBRA_ROUTE_BABEL] = 2, + [ZEBRA_ROUTE_NHRP] = 2, }; /* Look into the RN and queue it into one or more priority queues, |