]> git.puffer.fish Git - matthieu/frr.git/commitdiff
*: remove --enable-tcp-zebra, rework ZAPI path
authorDavid Lamparter <equinox@opensourcerouting.org>
Sun, 6 Aug 2017 05:35:50 +0000 (07:35 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Tue, 8 Aug 2017 09:14:05 +0000 (11:14 +0200)
This adds "@tcp" as new choice on the -z option present in zebra and the
protocol daemons.  The --enable-tcp-zebra option on configure is no
longer needed, both UNIX and TCP socket support is always available.

Note that @tcp should not be used by default (e.g. in an init script),
and --enable-tcp-zebra should never have been in any distro package
builds, because

**** TCP-ZEBRA IS A SECURITY PROBLEM ****

It allows arbitrary local users to mess with the routing table and
inject bogus data -- and also ZAPI is not designed to be robust against
attacks.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
30 files changed:
configure.ac
doc/Building_FRR_on_CentOS6.md
doc/Building_FRR_on_CentOS7.md
doc/Building_FRR_on_Debian8.md
doc/Building_FRR_on_Fedora24.md
doc/Building_FRR_on_FreeBSD10.md
doc/Building_FRR_on_FreeBSD11.md
doc/Building_FRR_on_FreeBSD9.md
doc/Building_FRR_on_NetBSD6.md
doc/Building_FRR_on_NetBSD7.md
doc/Building_FRR_on_OmniOS.md
doc/Building_FRR_on_OpenBSD6.md
doc/Building_FRR_on_Ubuntu1204.md
doc/Building_FRR_on_Ubuntu1404.md
doc/Building_FRR_on_Ubuntu1604.md
doc/pimd.8.in
doc/zebra.8.in
ldpd/lde.c
ldpd/ldpd.c
lib/libfrr.c
lib/libfrr.h
lib/zclient.c
lib/zclient.h
redhat/README.rpm_build.md
redhat/frr.spec.in
tests/test_lblmgr.c
zebra/client_main.c
zebra/label_manager.c
zebra/main.c
zebra/zserv.c

index 6b5cd19a5f5bcad7b0c585cfda03aa377e1aeeb8..1343d31336ce46e990584d8509077cd9eb6e0149 100755 (executable)
@@ -321,8 +321,6 @@ AC_ARG_ENABLE(snmp,
   AS_HELP_STRING([--enable-snmp=ARG], [enable SNMP support (smux or agentx)]))
 AC_ARG_WITH(libpam,
   AS_HELP_STRING([--with-libpam], [use libpam for PAM support in vtysh]))
-AC_ARG_ENABLE(tcp-zebra,
-  AS_HELP_STRING([--enable-tcp-zebra], [enable TCP/IP socket connection between zebra and protocol daemon]))
 AC_ARG_ENABLE(ospfapi,
   AS_HELP_STRING([--disable-ospfapi], [do not build OSPFAPI to access the OSPF LSA Database]))
 AC_ARG_ENABLE(ospfclient,
@@ -559,10 +557,6 @@ AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$have_protobuf" = "xyes"])
 # End of logic for protobuf support.
 #
 
-if test "${enable_tcp_zebra}" = "yes"; then
-  AC_DEFINE(HAVE_TCP_ZEBRA,,Use TCP for zebra communication)
-fi
-
 if test "${enable_linux24_tcp_md5}" = "yes"; then
   AC_DEFINE(HAVE_TCP_MD5_LINUX24,,Old Linux 2.4 TCP MD5 Signature Patch)
 fi
index b25845c38a2af2588b0e4776318cd589eb8cc9d8..10830e50166b2402925966e5ee5037c0ee1c3464 100644 (file)
@@ -109,7 +109,6 @@ an example.)
         --enable-rtadv \
         --disable-exampledir \
         --enable-watchfrr \
-        --enable-tcp-zebra \
         --disable-ldpd \
         --enable-fpm \
         --enable-nhrpd \
index 932459167f1d4922543befc229422577e8ca8358..787b80fbf7dd019e29341a14be50c29aa2a7d493 100644 (file)
@@ -61,7 +61,6 @@ an example.)
         --enable-rtadv \
         --disable-exampledir \
         --enable-watchfrr \
-        --enable-tcp-zebra \
         --disable-ldpd \
         --enable-fpm \
         --enable-nhrpd \
index 1a961f752a410d822466c7ef79dd34442108e03d..a2dbbdb30fa6238f7909cd8aa47dfe8a192c51ed 100644 (file)
@@ -60,7 +60,6 @@ an example.)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --enable-ldpd \
         --with-pkg-git-version \
index c161b9b128c23d78599a90ef4a451b7cdaabd585..0070fd1534945405300c39f6779ce00ffd908433 100644 (file)
@@ -54,7 +54,6 @@ an example.)
         --enable-rtadv \
         --disable-exampledir \
         --enable-watchfrr \
-        --enable-tcp-zebra \
         --enable-ldpd \
         --enable-fpm \
         --enable-nhrpd \
index 36ef573bb0ce4f983ccfbe8b5c429233d1fb058f..ccae83a66734c1b372bf9fd8f05ba94a05978116 100644 (file)
@@ -61,7 +61,6 @@ an example)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --with-pkg-git-version \
         --with-pkg-extra-version=-MyOwnFRRVersion   
index d6affd688bcefed339429b260296ba940aa13b13..71ccd149ffcfac4f1fd75fb48c7527938490d0e8 100644 (file)
@@ -61,7 +61,6 @@ an example)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --with-pkg-git-version \
         --with-pkg-extra-version=-MyOwnFRRVersion   
index 41d3148ad72887284c8130a2824a825ae8f8d790..8a09d8a4cc64ceca17d8d1f1523524814d9ec03f 100644 (file)
@@ -69,7 +69,6 @@ an example)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --with-pkg-git-version \
         --with-pkg-extra-version=-MyOwnFRRVersion   
index 2e453da66c4e7b3b3746c5b426bb9a2c945bc13a..4fe7109bcdb29ad076e4c60164fc5d95912659ef 100644 (file)
@@ -65,7 +65,6 @@ an example)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --with-pkg-git-version \
         --with-pkg-extra-version=-MyOwnFRRVersion   
index f5f99d9ba08fa9aa137e894e1132f3decb4cc4e9..7fe9ad20c939bcb16690d4a9906197375e1ac9eb 100644 (file)
@@ -59,7 +59,6 @@ an example)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --with-pkg-git-version \
         --with-pkg-extra-version=-MyOwnFRRVersion   
index 7e75bda9e9d23ade2cd61041822ddae93bdc307d..6e4575f07b2ad67597a58ffac5ef1d22b721a1bb 100644 (file)
@@ -104,7 +104,6 @@ an example)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --with-pkg-git-version \
         --with-pkg-extra-version=-MyOwnFRRVersion   
index e9e103051566482249f5e7dda4dd405d95d7572b..c1bfa5005e4521fae3b41bddddbeb8f87d779961 100644 (file)
@@ -54,7 +54,6 @@ an example)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --with-pkg-git-version \
         --with-pkg-extra-version=-MyOwnFRRVersion   
index e8567867ccd922c40b30f9090476ee0400ae8c0b..58aa167d57290a695d6edfb142270b9caf77a9e3 100644 (file)
@@ -93,7 +93,6 @@ an example.)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --with-pkg-git-version \
         --with-pkg-extra-version=-MyOwnFRRVersion   
index a0f3a121ff7efb02ca993c4c4c58ce7208e8d4c2..8e6b38cc2d35cb456a084979274b775bef86e997 100644 (file)
@@ -53,7 +53,6 @@ an example.)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
         --enable-ldpd \
         --with-pkg-git-version \
index 9144d4610b7bac2330f6b58beb0369f842528d66..a178f9a1603d5cbc01a5f5cd9877f6e7b0b7ab68 100644 (file)
@@ -54,7 +54,6 @@ an example.)
         --enable-configfile-mask=0640 \
         --enable-logfile-mask=0640 \
         --enable-rtadv \
-        --enable-tcp-zebra \
         --enable-fpm \
        --enable-systemd=yes \
         --with-pkg-git-version \
index 3fb060e5647531e5007b8b52396ea9abe59c543a..6db3418f8fea82218b89389749f34ee27d7ff10c 100644 (file)
@@ -60,7 +60,9 @@ restart pimd.  The default is \fB\fI@CFG_STATE@/pimd.pid\fR.
 .TP
 \fB\-z\fR, \fB\-\-socket \fR\fIpath\fR
 Specify the socket path for contacting the zebra daemon.
-The default is \fB\fI@CFG_STATE@/zserv.api\fR.
+The default is \fB\fI@CFG_STATE@/zserv.api\fR.  The value of this option
+must be the same as the one given when starting zebra.  Refer to the \fBzebra
+(8)\fR man page for more information.
 .TP
 \fB\-P\fR, \fB\-\-vty_port \fR\fIport-number\fR 
 Specify the port that the pimd VTY will listen on. This defaults to
index f5b8bd4d80893e60ec2840926302ab00c0c36da2..333e66fcf684f882bdfe98ba99fd6045f845431e 100644 (file)
@@ -26,6 +26,9 @@ zebra \- a routing manager for use with associated @PACKAGE_FULLNAME@ components
 ] [
 .B \-M
 .I module:options
+] [
+.B \-z
+.I socketpath
 ]
 .SH DESCRIPTION
 .B zebra 
@@ -97,6 +100,19 @@ respectively.  The \fBfpm\fR module takes an additional colon-separated
 argument specifying the encapsulation, either \fBnetlink\fR or \fBprotobuf\fR.
 It should thus be loaded with \fB-M fpm:netlink\fR or \fB-M fpm:protobuf\fR.
 .TP
+\fB\-z\fR, \fB\-\-socket \fR\fIsocketpath\fR
+Use the specified path to open the zebra API socket on.
+The default is \fB\fI@CFG_STATE@/zserv.api\fR.  This option must be given with
+the same value to all FRR protocol daemons.
+
+For debugging purposes (using tcpdump or wireshark to trace cross-daemon
+communication), a TCP socket can be used by specifying \fI@tcp[46][:port]\fR.
+It is intentionally not possible to bind this to anything other than localhost
+since zebra and the other daemons need to be running on the same host.  Using
+this feature \fBCREATES A SECURITY ISSUE\fR since nothing prevents other users
+on the local system from connecting to zebra and injecting bogus routing
+information.
+.TP
 \fB\-v\fR, \fB\-\-version\fR
 Print the version and exit.
 .SH FILES
index 77643ff48bbad3ca037925dcd020cfe35faa7309..11fcbfa46dba8af6d8fbd0f9893cd579c5214baa 100644 (file)
@@ -37,6 +37,7 @@
 #include "zclient.h"
 #include "stream.h"
 #include "network.h"
+#include "libfrr.h"
 
 static void             lde_shutdown(void);
 static int              lde_dispatch_imsg(struct thread *);
@@ -170,7 +171,8 @@ lde_init(struct ldpd_init *init)
        lde_gc_start_timer();
 
        /* Init synchronous zclient and label list */
-       zclient_serv_path_set(init->zclient_serv_path);
+       frr_zclient_addr(&zclient_addr, &zclient_addr_len,
+                        init->zclient_serv_path);
        zclient_sync_init(init->instance);
        lde_label_list_init();
 }
index abcad79d67cad6a6ca4cf5106e8e5bcb3cde3eb5..abf584484e98f55552741ffab7e8e2fd7397c265 100644 (file)
@@ -256,7 +256,7 @@ main(int argc, char *argv[])
        strlcpy(init.user, ldpd_privs.user, sizeof(init.user));
        strlcpy(init.group, ldpd_privs.group, sizeof(init.group));
        strlcpy(init.ctl_sock_path, ctl_sock_path, sizeof(init.ctl_sock_path));
-       strlcpy(init.zclient_serv_path, zclient_serv_path_get(),
+       strlcpy(init.zclient_serv_path, frr_zclientpath,
            sizeof(init.zclient_serv_path));
 
        argc -= optind;
index 022296b3fbc886ba38f702ff2c06e4ee07b72adc..e92456cf775a0eaf611a3a648ada32c117a781f0 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <zebra.h>
+#include <sys/un.h>
 
 #include "libfrr.h"
 #include "getopt.h"
@@ -40,6 +41,7 @@ char frr_protoname[256] = "NONE";
 char frr_protonameinst[256] = "NONE";
 
 char config_default[256];
+char frr_zclientpath[256];
 static char pidfile_default[256];
 static char vtypath_default[256];
 
@@ -127,6 +129,100 @@ static const struct optspec os_user = {"u:g:",
                                       lo_user};
 
 
+bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len,
+                     const char *path)
+{
+       memset(sa, 0, sizeof(*sa));
+
+       if (!path)
+               path = ZEBRA_SERV_PATH;
+
+       if (!strncmp(path, ZAPI_TCP_PATHNAME, strlen(ZAPI_TCP_PATHNAME))) {
+               int af;
+               int port = ZEBRA_PORT;
+               char *err = NULL;
+               struct sockaddr_in *sin = NULL;
+               struct sockaddr_in6 *sin6 = NULL;
+
+               path += strlen(ZAPI_TCP_PATHNAME);
+
+               switch (path[0]) {
+               case '4':
+                       path++;
+                       af = AF_INET;
+                       break;
+               case '6':
+                       path++;
+                       /* fallthrough */
+               default:
+                       af = AF_INET6;
+                       break;
+               }
+
+               switch (path[0]) {
+               case '\0':
+                       break;
+               case ':':
+                       path++;
+                       port = strtoul(path, &err, 10);
+                       if (*err || !*path)
+                               return false;
+                       break;
+               default:
+                       return false;
+               }
+
+               sa->ss_family = af;
+               switch (af) {
+               case AF_INET:
+                       sin = (struct sockaddr_in *)sa;
+                       sin->sin_port = htons(port);
+                       sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+                       *sa_len = sizeof(struct sockaddr_in);
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+                       sin->sin_len = *sa_len;
+#endif
+                       break;
+               case AF_INET6:
+                       sin6 = (struct sockaddr_in6 *)sa;
+                       sin6->sin6_port = htons(port);
+                       inet_pton(AF_INET6, "::1", &sin6->sin6_addr);
+                       *sa_len = sizeof(struct sockaddr_in6);
+#ifdef SIN6_LEN
+                       sin6->sin6_len = *sa_len;
+#endif
+                       break;
+               }
+       } else {
+               /* "sun" is a #define on solaris */
+               struct sockaddr_un *suna = (struct sockaddr_un *)sa;
+
+               suna->sun_family = AF_UNIX;
+               strlcpy(suna->sun_path, path, sizeof(suna->sun_path));
+#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
+               *sa_len = suna->sun_len = SUN_LEN(suna);
+#else
+               *sa_len = sizeof(suna->sun_family) + strlen(suna->sun_path);
+#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
+#if 0
+               /* this is left here for future reference;  Linux abstract
+                * socket namespace support can be enabled by replacing
+                * above #if 0 with #ifdef GNU_LINUX.
+                *
+                * THIS IS A SECURITY ISSUE, the abstract socket namespace
+                * does not have user/group permission control on sockets.
+                * we'd need to implement SCM_CREDENTIALS support first to
+                * check that only proper users can connect to abstract
+                * sockets. (same problem as tcp-zebra, except there is a
+                * fix with SCM_CREDENTIALS.  tcp-zebra has no such fix.)
+                */
+               if (suna->sun_path[0] == '@')
+                       suna->sun_path[0] = '\0';
+#endif
+       }
+       return true;
+}
+
 static struct frr_daemon_info *di = NULL;
 
 void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
@@ -156,6 +252,8 @@ void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
 
        strlcpy(frr_protoname, di->logname, sizeof(frr_protoname));
        strlcpy(frr_protonameinst, di->logname, sizeof(frr_protonameinst));
+
+       strlcpy(frr_zclientpath, ZEBRA_SERV_PATH, sizeof(frr_zclientpath));
 }
 
 void frr_opt_add(const char *optstr, const struct option *longopts,
@@ -233,7 +331,7 @@ static int frr_opt(int opt)
        case 'z':
                if (di->flags & FRR_NO_ZCLIENT)
                        return 1;
-               zclient_serv_path_set(optarg);
+               strlcpy(frr_zclientpath, optarg, sizeof(frr_zclientpath));
                break;
        case 'A':
                if (di->flags & FRR_NO_TCPVTY)
@@ -341,6 +439,13 @@ struct thread_master *frr_init(void)
        zlog_set_level(ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
 #endif
 
+       if (!frr_zclient_addr(&zclient_addr, &zclient_addr_len,
+                             frr_zclientpath)) {
+               fprintf(stderr, "Invalid zserv socket path: %s\n",
+                       frr_zclientpath);
+               exit(1);
+       }
+
        frrmod_init(di->module);
        while (modules) {
                modules = (oc = modules)->next;
index 0f6ed0cb00fa8d7f7d9bc6cee00b4c3366cc476c..23516150eed1e51c532ed46befdd07c8882190db 100644 (file)
@@ -100,7 +100,11 @@ extern void frr_vty_serv(void);
 /* note: contains call to frr_vty_serv() */
 extern void frr_run(struct thread_master *master);
 
+extern bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len,
+                            const char *path);
+
 extern char config_default[256];
+extern char frr_zclientpath[256];
 extern const char frr_sysconfdir[];
 extern const char frr_vtydir[];
 extern const char frr_moduledir[];
index a6252af403949d63c7db80e961a2959bae80f47d..233d0359d5e6621843b62c57d248458af56416d0 100644 (file)
@@ -45,7 +45,8 @@ enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
 /* Prototype for event manager. */
 static void zclient_event(enum event, struct zclient *);
 
-const char *zclient_serv_path = NULL;
+struct sockaddr_storage zclient_addr;
+socklen_t zclient_addr_len;
 
 /* This file local debug flag. */
 int zclient_debug = 0;
@@ -183,31 +184,28 @@ void zclient_reset(struct zclient *zclient)
        zclient_init(zclient, zclient->redist_default, zclient->instance);
 }
 
-#ifdef HAVE_TCP_ZEBRA
-
-/* Make socket to zebra daemon. Return zebra socket. */
-static int zclient_socket(void)
+/**
+ * Connect to zebra daemon.
+ * @param zclient a pointer to zclient structure
+ * @return socket fd just to make sure that connection established
+ * @see zclient_init
+ * @see zclient_new
+ */
+int zclient_socket_connect(struct zclient *zclient)
 {
        int sock;
        int ret;
-       struct sockaddr_in serv;
 
        /* We should think about IPv6 connection. */
-       sock = socket(AF_INET, SOCK_STREAM, 0);
+       sock = socket(zclient_addr.ss_family, SOCK_STREAM, 0);
        if (sock < 0)
                return -1;
 
-       /* Make server socket. */
-       memset(&serv, 0, sizeof(struct sockaddr_in));
-       serv.sin_family = AF_INET;
-       serv.sin_port = htons(ZEBRA_PORT);
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-       serv.sin_len = sizeof(struct sockaddr_in);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
-       serv.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+       set_cloexec(sock);
 
        /* Connect to zebra. */
-       ret = connect(sock, (struct sockaddr *)&serv, sizeof(serv));
+       ret = connect(sock, (struct sockaddr *)&zclient_addr,
+                       zclient_addr_len);
        if (ret < 0) {
                if (zclient_debug)
                        zlog_warn("%s connect failure: %d(%s)",
@@ -216,65 +214,11 @@ static int zclient_socket(void)
                close(sock);
                return -1;
        }
-       return sock;
-}
 
-#else
-
-/* For sockaddr_un. */
-#include <sys/un.h>
-
-static int zclient_socket_un(const char *path)
-{
-       int ret;
-       int sock, len;
-       struct sockaddr_un addr;
-
-       sock = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (sock < 0)
-               return -1;
-
-       /* Make server socket. */
-       memset(&addr, 0, sizeof(struct sockaddr_un));
-       addr.sun_family = AF_UNIX;
-       strncpy(addr.sun_path, path, strlen(path));
-#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
-       len = addr.sun_len = SUN_LEN(&addr);
-#else
-       len = sizeof(addr.sun_family) + strlen(addr.sun_path);
-#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
-
-       ret = connect(sock, (struct sockaddr *)&addr, len);
-       if (ret < 0) {
-               if (zclient_debug)
-                       zlog_warn("%s connect failure: %d(%s)",
-                                 __PRETTY_FUNCTION__, errno,
-                                 safe_strerror(errno));
-               close(sock);
-               return -1;
-       }
+       zclient->sock = sock;
        return sock;
 }
 
-#endif /* HAVE_TCP_ZEBRA */
-
-/**
- * Connect to zebra daemon.
- * @param zclient a pointer to zclient structure
- * @return socket fd just to make sure that connection established
- * @see zclient_init
- * @see zclient_new
- */
-int zclient_socket_connect(struct zclient *zclient)
-{
-#ifdef HAVE_TCP_ZEBRA
-       zclient->sock = zclient_socket();
-#else
-       zclient->sock = zclient_socket_un(zclient_serv_path_get());
-#endif
-       return zclient->sock;
-}
-
 static int zclient_failed(struct zclient *zclient)
 {
        zclient->fail++;
@@ -2157,34 +2101,6 @@ static void zclient_event(enum event event, struct zclient *zclient)
        }
 }
 
-const char *zclient_serv_path_get()
-{
-       return zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH;
-}
-
-void zclient_serv_path_set(char *path)
-{
-       struct stat sb;
-
-       /* reset */
-       zclient_serv_path = NULL;
-
-       /* test if `path' is socket. don't set it otherwise. */
-       if (stat(path, &sb) == -1) {
-               zlog_warn("%s: zebra socket `%s' does not exist", __func__,
-                         path);
-               return;
-       }
-
-       if ((sb.st_mode & S_IFMT) != S_IFSOCK) {
-               zlog_warn("%s: `%s' is not unix socket, sir", __func__, path);
-               return;
-       }
-
-       /* it seems that path is unix socket */
-       zclient_serv_path = path;
-}
-
 void zclient_interface_set_master(struct zclient *client,
                                  struct interface *master,
                                  struct interface *slave)
index 435d26e2f9c28523c3142c2c81fe2fd5a1db7be9..2752acc28152ac5a4901049c3a77ff52cc622d28 100644 (file)
 /* Zebra header size. */
 #define ZEBRA_HEADER_SIZE             8
 
+/* special socket path name to use TCP
+ * @ is used as first character because that's abstract socket names on Linux
+ */
+#define ZAPI_TCP_PATHNAME             "@tcp"
+
+extern struct sockaddr_storage zclient_addr;
+extern socklen_t zclient_addr_len;
+
 /* Zebra message types. */
 typedef enum {
        ZEBRA_INTERFACE_ADD,
@@ -275,8 +283,6 @@ extern void zclient_reset(struct zclient *);
 extern void zclient_free(struct zclient *);
 
 extern int zclient_socket_connect(struct zclient *);
-extern void zclient_serv_path_set(char *path);
-extern const char *zclient_serv_path_get(void);
 
 extern u_short *redist_check_instance(struct redist_proto *, u_short);
 extern void redist_add_instance(struct redist_proto *, u_short);
index dd01babf50785ae90345ed65fffe34e4da732e6d..c05331256aa781890478c4d5cea4b4dc867ac952 100644 (file)
@@ -52,7 +52,6 @@ Building your own FRRouting RPM
     
         ############### FRRouting (FRR) configure options #################
         # with-feature options
-        %{!?with_tcp_zebra:     %global  with_tcp_zebra     0 }
         %{!?with_pam:           %global  with_pam           0 }
         %{!?with_ospfclient:    %global  with_ospfclient    1 }
         %{!?with_ospfapi:       %global  with_ospfapi       1 }
index b23249e04ec4256b8a73fc6de7d3932bacb78272..12cdcf04fe699df78a59df5df05baabeebe9d529 100644 (file)
@@ -10,7 +10,6 @@
 
 #################### FRRouting (FRR) configure options #####################
 # with-feature options
-%{!?with_tcp_zebra:     %global  with_tcp_zebra     0 }
 %{!?with_pam:           %global  with_pam           0 }
 %{!?with_ospfclient:    %global  with_ospfclient    1 }
 %{!?with_ospfapi:       %global  with_ospfapi       1 }
     %global  with_pimd  0
 %endif
 
-# if FPM is enabled, then enable tcp_zebra as well 
-#
-%if %{with_fpm}
-    %global with_tcp_zebra  1
-%endif
-
 # misc internal defines
 %{!?frr_uid:            %global  frr_uid            92 }
 %{!?frr_gid:            %global  frr_gid            92 }
@@ -233,9 +226,6 @@ developing OSPF-API and frr applications.
 %endif
 %if %{with_multipath}
     --enable-multipath=%{with_multipath} \
-%endif
-%if %{with_tcp_zebra}
-    --enable-tcp-zebra \
 %endif
     --enable-vtysh \
 %if %{with_ospfclient}
index afc5ba66307c9896d881455d7b1f55d3a80ce5ca..5e604db61a2a3c89a980fd975cdcb6ff71017473 100644 (file)
@@ -113,8 +113,7 @@ static int zebra_send_release_label_chunk(uint32_t start, uint32_t end)
 
 void init_zclient(struct thread_master *master, char *lm_zserv_path)
 {
-       if (lm_zserv_path)
-               zclient_serv_path_set(lm_zserv_path);
+       frr_zclient_addr(&zclient_addr, &zclient_addr_len, lm_zserv_path);
 
        zclient = zclient_new(master);
        /* zclient_init(zclient, ZEBRA_LABEL_MANAGER, 0); */
index 17130c602e9bdbbf1ab80f98dde4bf1562390a5a..95b9d00dc0c0587a8687fd911e4e493650ae56aa 100644 (file)
@@ -186,11 +186,7 @@ int main(int argc, char **argv)
        /* Establish connection to zebra. */
        zclient = zclient_new(master);
        zclient->enable = 1;
-#ifdef HAVE_TCP_ZEBRA
-       zclient->sock = zclient_socket();
-#else
-       zclient->sock = zclient_socket_un(ZEBRA_SERV_PATH);
-#endif /* HAVE_TCP_ZEBRA */
+       zclient_socket_connect(zclient);
 
        /* Open simulation file. */
        fp = fopen(argv[1], "r");
index b50f751587885c01d21dfe7282369bd3cf4e28a7..1ed5eacd80b036bf8683bddc3968d02ae3b11369 100644 (file)
@@ -33,6 +33,7 @@
 #include "lib/network.h"
 #include "lib/stream.h"
 #include "lib/zclient.h"
+#include "lib/libfrr.h"
 
 #include "label_manager.h"
 
@@ -216,7 +217,8 @@ static int lm_zclient_connect(struct thread *t)
 static void lm_zclient_init(char *lm_zserv_path)
 {
        if (lm_zserv_path)
-               zclient_serv_path_set(lm_zserv_path);
+               frr_zclient_addr(&zclient_addr, &zclient_addr_len,
+                                lm_zserv_path);
 
        /* Set default values. */
        zclient = zclient_new(zebrad.master);
index 27a6f3e02762974deb37867aa9fb11ef6e400cd7..ddd6db5254abc41b19c6afe59d6f113a5f59e95a 100644 (file)
@@ -204,6 +204,8 @@ int main(int argc, char **argv)
        char *zserv_path = NULL;
        /* Socket to external label manager */
        char *lblmgr_path = NULL;
+       struct sockaddr_storage dummy;
+       socklen_t dummylen;
 
        frr_preinit(&zebra_di, argc, argv);
 
@@ -256,6 +258,12 @@ int main(int argc, char **argv)
                        break;
                case 'z':
                        zserv_path = optarg;
+                       if (!frr_zclient_addr(&dummy, &dummylen, optarg)) {
+                               fprintf(stderr,
+                                       "Invalid zserv socket path: %s\n",
+                                       optarg);
+                               exit(1);
+                       }
                        break;
                case 'l':
                        lblmgr_path = optarg;
index 97f7122774887df5bae9d29b18049a1740aa3752..8700cc51022c5de8fe34d3ba7180157628b99d1b 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <zebra.h>
+#include <sys/un.h>
 
 #include "prefix.h"
 #include "command.h"
@@ -38,6 +39,7 @@
 #include "buffer.h"
 #include "nexthop.h"
 #include "vrf.h"
+#include "libfrr.h"
 
 #include "zebra/zserv.h"
 #include "zebra/zebra_ns.h"
@@ -2486,116 +2488,59 @@ static int zebra_accept(struct thread *thread)
        return 0;
 }
 
-#ifdef HAVE_TCP_ZEBRA
-/* Make zebra's server socket. */
-static void zebra_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 create zserv stream socket: %s",
-                         safe_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_STRUCT_SOCKADDR_IN_SIN_LEN
-       addr.sin_len = sizeof(struct sockaddr_in);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
-       addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-       sockopt_reuseaddr(accept_sock);
-       sockopt_reuseport(accept_sock);
-
-       if (zserv_privs.change(ZPRIVS_RAISE))
-               zlog_err("Can't raise privileges");
-
-       ret = bind(accept_sock, (struct sockaddr *)&addr,
-                  sizeof(struct sockaddr_in));
-       if (ret < 0) {
-               zlog_warn("Can't bind to stream socket: %s",
-                         safe_strerror(errno));
-               zlog_warn(
-                       "zebra can't provice full functionality due to above error");
-               close(accept_sock); /* Avoid sd leak. */
-               return;
-       }
-
-       if (zserv_privs.change(ZPRIVS_LOWER))
-               zlog_err("Can't lower privileges");
-
-       ret = listen(accept_sock, 1);
-       if (ret < 0) {
-               zlog_warn("Can't listen to stream socket: %s",
-                         safe_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);
-}
-#else /* HAVE_TCP_ZEBRA */
-
-/* For sockaddr_un. */
-#include <sys/un.h>
-
-/* zebra server UNIX domain socket. */
-static void zebra_serv_un(const char *path)
+/* Make zebra server socket, wiping any existing one (see bug #403). */
+void zebra_zserv_socket_init(char *path)
 {
        int ret;
-       int sock, len;
-       struct sockaddr_un serv;
+       int sock;
        mode_t old_mask;
+       struct sockaddr_storage sa;
+       socklen_t sa_len;
 
-       /* First of all, unlink existing socket */
-       unlink(path);
+       if (!frr_zclient_addr(&sa, &sa_len, path))
+               /* should be caught in zebra main() */
+               return;
 
        /* Set umask */
        old_mask = umask(0077);
 
        /* Make UNIX domain socket. */
-       sock = socket(AF_UNIX, SOCK_STREAM, 0);
+       sock = socket(sa.ss_family, SOCK_STREAM, 0);
        if (sock < 0) {
-               zlog_warn("Can't create zserv unix socket: %s",
+               zlog_warn("Can't create zserv socket: %s",
                          safe_strerror(errno));
                zlog_warn(
                        "zebra can't provide full functionality due to above error");
                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_STRUCT_SOCKADDR_UN_SUN_LEN
-       len = serv.sun_len = SUN_LEN(&serv);
-#else
-       len = sizeof(serv.sun_family) + strlen(serv.sun_path);
-#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
-
-       ret = bind(sock, (struct sockaddr *)&serv, len);
+       if (sa.ss_family != AF_UNIX) {
+               sockopt_reuseaddr(sock);
+               sockopt_reuseport(sock);
+       } else {
+               struct sockaddr_un *suna = (struct sockaddr_un *)&sa;
+               if (suna->sun_path[0])
+                       unlink(suna->sun_path);
+       }
+
+       if (zserv_privs.change(ZPRIVS_RAISE))
+               zlog_err("Can't raise privileges");
+
+       ret = bind(sock, (struct sockaddr *)&sa, sa_len);
        if (ret < 0) {
-               zlog_warn("Can't bind to unix socket %s: %s", path,
+               zlog_warn("Can't bind zserv socket on %s: %s", path,
                          safe_strerror(errno));
                zlog_warn(
                        "zebra can't provide full functionality due to above error");
                close(sock);
                return;
        }
+       if (zserv_privs.change(ZPRIVS_LOWER))
+               zlog_err("Can't lower privileges");
 
        ret = listen(sock, 5);
        if (ret < 0) {
-               zlog_warn("Can't listen to unix socket %s: %s", path,
+               zlog_warn("Can't listen to zserv socket %s: %s", path,
                          safe_strerror(errno));
                zlog_warn(
                        "zebra can't provide full functionality due to above error");
@@ -2607,7 +2552,6 @@ static void zebra_serv_un(const char *path)
 
        zebra_event(ZEBRA_SERV, sock, NULL);
 }
-#endif /* HAVE_TCP_ZEBRA */
 
 
 static void zebra_event(enum event event, int sock, struct zserv *client)
@@ -3050,13 +2994,3 @@ void zebra_init(void)
        /* Route-map */
        zebra_route_map_init();
 }
-
-/* Make zebra server socket, wiping any existing one (see bug #403). */
-void zebra_zserv_socket_init(char *path)
-{
-#ifdef HAVE_TCP_ZEBRA
-       zebra_serv();
-#else
-       zebra_serv_un(path ? path : ZEBRA_SERV_PATH);
-#endif /* HAVE_TCP_ZEBRA */
-}