summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure.ac6
-rw-r--r--doc/Building_FRR_on_CentOS6.md1
-rw-r--r--doc/Building_FRR_on_CentOS7.md1
-rw-r--r--doc/Building_FRR_on_Debian8.md1
-rw-r--r--doc/Building_FRR_on_Fedora24.md1
-rw-r--r--doc/Building_FRR_on_FreeBSD10.md1
-rw-r--r--doc/Building_FRR_on_FreeBSD11.md1
-rw-r--r--doc/Building_FRR_on_FreeBSD9.md1
-rw-r--r--doc/Building_FRR_on_NetBSD6.md1
-rw-r--r--doc/Building_FRR_on_NetBSD7.md1
-rw-r--r--doc/Building_FRR_on_OmniOS.md1
-rw-r--r--doc/Building_FRR_on_OpenBSD6.md1
-rw-r--r--doc/Building_FRR_on_Ubuntu1204.md1
-rw-r--r--doc/Building_FRR_on_Ubuntu1404.md1
-rw-r--r--doc/Building_FRR_on_Ubuntu1604.md1
-rw-r--r--doc/pimd.8.in4
-rw-r--r--doc/zebra.8.in16
-rw-r--r--ldpd/lde.c4
-rw-r--r--ldpd/ldpd.c2
-rw-r--r--lib/libfrr.c107
-rw-r--r--lib/libfrr.h4
-rw-r--r--lib/zclient.c114
-rw-r--r--lib/zclient.h10
-rw-r--r--redhat/README.rpm_build.md1
-rw-r--r--redhat/frr.spec.in10
-rw-r--r--tests/test_lblmgr.c3
-rw-r--r--zebra/client_main.c6
-rw-r--r--zebra/label_manager.c4
-rw-r--r--zebra/main.c8
-rw-r--r--zebra/zserv.c124
30 files changed, 198 insertions, 239 deletions
diff --git a/configure.ac b/configure.ac
index 6b5cd19a5..1343d3133 100755
--- a/configure.ac
+++ b/configure.ac
@@ -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
diff --git a/doc/Building_FRR_on_CentOS6.md b/doc/Building_FRR_on_CentOS6.md
index b25845c38..10830e501 100644
--- a/doc/Building_FRR_on_CentOS6.md
+++ b/doc/Building_FRR_on_CentOS6.md
@@ -109,7 +109,6 @@ an example.)
--enable-rtadv \
--disable-exampledir \
--enable-watchfrr \
- --enable-tcp-zebra \
--disable-ldpd \
--enable-fpm \
--enable-nhrpd \
diff --git a/doc/Building_FRR_on_CentOS7.md b/doc/Building_FRR_on_CentOS7.md
index 932459167..787b80fbf 100644
--- a/doc/Building_FRR_on_CentOS7.md
+++ b/doc/Building_FRR_on_CentOS7.md
@@ -61,7 +61,6 @@ an example.)
--enable-rtadv \
--disable-exampledir \
--enable-watchfrr \
- --enable-tcp-zebra \
--disable-ldpd \
--enable-fpm \
--enable-nhrpd \
diff --git a/doc/Building_FRR_on_Debian8.md b/doc/Building_FRR_on_Debian8.md
index 1a961f752..a2dbbdb30 100644
--- a/doc/Building_FRR_on_Debian8.md
+++ b/doc/Building_FRR_on_Debian8.md
@@ -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 \
diff --git a/doc/Building_FRR_on_Fedora24.md b/doc/Building_FRR_on_Fedora24.md
index c161b9b12..0070fd153 100644
--- a/doc/Building_FRR_on_Fedora24.md
+++ b/doc/Building_FRR_on_Fedora24.md
@@ -54,7 +54,6 @@ an example.)
--enable-rtadv \
--disable-exampledir \
--enable-watchfrr \
- --enable-tcp-zebra \
--enable-ldpd \
--enable-fpm \
--enable-nhrpd \
diff --git a/doc/Building_FRR_on_FreeBSD10.md b/doc/Building_FRR_on_FreeBSD10.md
index 36ef573bb..ccae83a66 100644
--- a/doc/Building_FRR_on_FreeBSD10.md
+++ b/doc/Building_FRR_on_FreeBSD10.md
@@ -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
diff --git a/doc/Building_FRR_on_FreeBSD11.md b/doc/Building_FRR_on_FreeBSD11.md
index d6affd688..71ccd149f 100644
--- a/doc/Building_FRR_on_FreeBSD11.md
+++ b/doc/Building_FRR_on_FreeBSD11.md
@@ -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
diff --git a/doc/Building_FRR_on_FreeBSD9.md b/doc/Building_FRR_on_FreeBSD9.md
index 41d3148ad..8a09d8a4c 100644
--- a/doc/Building_FRR_on_FreeBSD9.md
+++ b/doc/Building_FRR_on_FreeBSD9.md
@@ -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
diff --git a/doc/Building_FRR_on_NetBSD6.md b/doc/Building_FRR_on_NetBSD6.md
index 2e453da66..4fe7109bc 100644
--- a/doc/Building_FRR_on_NetBSD6.md
+++ b/doc/Building_FRR_on_NetBSD6.md
@@ -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
diff --git a/doc/Building_FRR_on_NetBSD7.md b/doc/Building_FRR_on_NetBSD7.md
index f5f99d9ba..7fe9ad20c 100644
--- a/doc/Building_FRR_on_NetBSD7.md
+++ b/doc/Building_FRR_on_NetBSD7.md
@@ -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
diff --git a/doc/Building_FRR_on_OmniOS.md b/doc/Building_FRR_on_OmniOS.md
index 7e75bda9e..6e4575f07 100644
--- a/doc/Building_FRR_on_OmniOS.md
+++ b/doc/Building_FRR_on_OmniOS.md
@@ -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
diff --git a/doc/Building_FRR_on_OpenBSD6.md b/doc/Building_FRR_on_OpenBSD6.md
index e9e103051..c1bfa5005 100644
--- a/doc/Building_FRR_on_OpenBSD6.md
+++ b/doc/Building_FRR_on_OpenBSD6.md
@@ -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
diff --git a/doc/Building_FRR_on_Ubuntu1204.md b/doc/Building_FRR_on_Ubuntu1204.md
index e8567867c..58aa167d5 100644
--- a/doc/Building_FRR_on_Ubuntu1204.md
+++ b/doc/Building_FRR_on_Ubuntu1204.md
@@ -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
diff --git a/doc/Building_FRR_on_Ubuntu1404.md b/doc/Building_FRR_on_Ubuntu1404.md
index a0f3a121f..8e6b38cc2 100644
--- a/doc/Building_FRR_on_Ubuntu1404.md
+++ b/doc/Building_FRR_on_Ubuntu1404.md
@@ -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 \
diff --git a/doc/Building_FRR_on_Ubuntu1604.md b/doc/Building_FRR_on_Ubuntu1604.md
index 9144d4610..a178f9a16 100644
--- a/doc/Building_FRR_on_Ubuntu1604.md
+++ b/doc/Building_FRR_on_Ubuntu1604.md
@@ -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 \
diff --git a/doc/pimd.8.in b/doc/pimd.8.in
index 3fb060e56..6db3418f8 100644
--- a/doc/pimd.8.in
+++ b/doc/pimd.8.in
@@ -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
diff --git a/doc/zebra.8.in b/doc/zebra.8.in
index f5b8bd4d8..333e66fcf 100644
--- a/doc/zebra.8.in
+++ b/doc/zebra.8.in
@@ -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
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 77643ff48..11fcbfa46 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -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();
}
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index abcad79d6..abf584484 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -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;
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 022296b3f..e92456cf7 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -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;
diff --git a/lib/libfrr.h b/lib/libfrr.h
index 0f6ed0cb0..23516150e 100644
--- a/lib/libfrr.h
+++ b/lib/libfrr.h
@@ -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[];
diff --git a/lib/zclient.c b/lib/zclient.c
index a6252af40..233d0359d 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -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)
diff --git a/lib/zclient.h b/lib/zclient.h
index 435d26e2f..2752acc28 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -36,6 +36,14 @@
/* 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);
diff --git a/redhat/README.rpm_build.md b/redhat/README.rpm_build.md
index dd01babf5..c05331256 100644
--- a/redhat/README.rpm_build.md
+++ b/redhat/README.rpm_build.md
@@ -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 }
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index b23249e04..12cdcf04f 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -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 }
@@ -75,12 +74,6 @@
%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 }
@@ -234,9 +227,6 @@ developing OSPF-API and frr applications.
%if %{with_multipath}
--enable-multipath=%{with_multipath} \
%endif
-%if %{with_tcp_zebra}
- --enable-tcp-zebra \
-%endif
--enable-vtysh \
%if %{with_ospfclient}
--enable-ospfclient \
diff --git a/tests/test_lblmgr.c b/tests/test_lblmgr.c
index afc5ba663..5e604db61 100644
--- a/tests/test_lblmgr.c
+++ b/tests/test_lblmgr.c
@@ -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); */
diff --git a/zebra/client_main.c b/zebra/client_main.c
index 17130c602..95b9d00dc 100644
--- a/zebra/client_main.c
+++ b/zebra/client_main.c
@@ -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");
diff --git a/zebra/label_manager.c b/zebra/label_manager.c
index b50f75158..1ed5eacd8 100644
--- a/zebra/label_manager.c
+++ b/zebra/label_manager.c
@@ -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);
diff --git a/zebra/main.c b/zebra/main.c
index 27a6f3e02..ddd6db525 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -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;
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 97f712277..8700cc510 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -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 */
-}