summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2018-06-14 14:23:49 +0200
committerQuentin Young <qlyoung@cumulusnetworks.com>2018-08-14 22:02:05 +0200
commitb66d022e8d843bbc5daec9d1cb59f66d338f7433 (patch)
treeb52046d8fb40b7d70b837f7fbeb8b7b01ac54859 /lib
parentlib: Allow adding arrays of ferr's (diff)
downloadfrr-b66d022e8d843bbc5daec9d1cb59f66d338f7433.tar.xz
frr-b66d022e8d843bbc5daec9d1cb59f66d338f7433.zip
lib, bgpd: Add code to make lib auto create the ferr infrastructure
Add code to auto-create the ferr infrastructure as well as add some initial error handling for vrf.c Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/ferr.h5
-rw-r--r--lib/lib_errors.c52
-rw-r--r--lib/lib_errors.h34
-rw-r--r--lib/libfrr.c3
-rw-r--r--lib/subdir.am2
-rw-r--r--lib/vrf.c55
6 files changed, 131 insertions, 20 deletions
diff --git a/lib/ferr.h b/lib/ferr.h
index 7e38fa455..011925b85 100644
--- a/lib/ferr.h
+++ b/lib/ferr.h
@@ -121,6 +121,11 @@ struct ferr_ref {
void ferr_ref_add(struct ferr_ref *ref);
struct ferr_ref *ferr_ref_get(uint32_t code);
void ferr_ref_display(struct vty *, uint32_t code);
+
+/*
+ * This function should be called by the
+ * code in libfrr.c
+ */
void ferr_ref_init(void);
void ferr_ref_fini(void);
diff --git a/lib/lib_errors.c b/lib/lib_errors.c
new file mode 100644
index 000000000..73b90a9c5
--- /dev/null
+++ b/lib/lib_errors.c
@@ -0,0 +1,52 @@
+/*
+ * Library-specific error messages.
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This program is free software; you can redistribute it 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 program 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+#include <lib_errors.h>
+
+static struct ferr_ref ferr_lib_err[] = {
+ {
+ .code = LIB_ERR_PRIVILEGES,
+ .title = "Failure to raise or lower privileges",
+ .description = "FRR attempted to raise or lower it's privileges and was unable to do so",
+ .suggestion = "Ensure that you are running FRR as the frr user and that the user has\nSufficient privileges to properly access root privileges"
+ },
+ {
+ .code = LIB_ERR_VRF_START,
+ .title = "VRF Failure on Start",
+ .description = "Upon startup FRR failed to properly initialize and startup the VRF subsystem",
+ .suggestion = "Ensure that there is sufficient memory to start processes and restart FRR",
+ },
+ {
+ .code = LIB_ERR_VRF_SOCKET,
+ .title = "VRF Socket Error",
+ .description = "When attempting to access a socket for the VRF specified, we\nwere unable to properly complete the request",
+ .suggestion = "Ensure that there is sufficient system resources available and\nensure that the frr user has sufficient permisions to work",
+ },
+ {
+ .code = END_FERR
+ }
+};
+
+void lib_error_init(void)
+{
+ ferr_ref_init();
+ ferr_ref_add(ferr_lib_err);
+}
diff --git a/lib/lib_errors.h b/lib/lib_errors.h
new file mode 100644
index 000000000..67a6f8fae
--- /dev/null
+++ b/lib/lib_errors.h
@@ -0,0 +1,34 @@
+/*
+ * Library-specific error messages.
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This program is free software; you can redistribute it 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 program 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __LIB_ERRORS_H__
+#define __LIB_ERRORS_H__
+
+#include "ferr.h"
+#include "lib_errors.h"
+
+enum lib_ferr_refs {
+ LIB_ERR_PRIVILEGES = LIB_FERR_START,
+ LIB_ERR_VRF_START,
+ LIB_ERR_VRF_SOCKET,
+};
+
+extern void lib_error_init(void);
+
+#endif
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 86a5bd29f..b7e4da393 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -35,6 +35,7 @@
#include "log_int.h"
#include "module.h"
#include "network.h"
+#include "lib_errors.h"
DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm))
DEFINE_KOOH(frr_early_fini, (), ())
@@ -598,6 +599,8 @@ struct thread_master *frr_init(void)
vty_init(master);
memory_init();
+ lib_error_init();
+
return master;
}
diff --git a/lib/subdir.am b/lib/subdir.am
index 9eaae59df..b938dbcea 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -35,6 +35,7 @@ lib_libfrr_la_SOURCES = \
lib/jhash.c \
lib/json.c \
lib/keychain.c \
+ lib/lib_errors.c \
lib/libfrr.c \
lib/linklist.c \
lib/log.c \
@@ -118,6 +119,7 @@ pkginclude_HEADERS += \
lib/jhash.h \
lib/json.h \
lib/keychain.h \
+ lib/lib_errors.h \
lib/libfrr.h \
lib/libospf.h \
lib/linklist.h \
diff --git a/lib/vrf.c b/lib/vrf.c
index 4f29bad5f..ca0bbe1db 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -35,6 +35,7 @@
#include "ns.h"
#include "privs.h"
#include "nexthop_group.h"
+#include "lib_errors.h"
/* default VRF ID value used when VRF backend is not NETNS */
#define VRF_DEFAULT_INTERNAL 0
@@ -466,13 +467,15 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
/* The default VRF always exists. */
default_vrf = vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME);
if (!default_vrf) {
- zlog_err("vrf_init: failed to create the default VRF!");
+ zlog_ferr(LIB_ERR_VRF_START,
+ "vrf_init: failed to create the default VRF!");
exit(1);
}
/* Enable the default VRF. */
if (!vrf_enable(default_vrf)) {
- zlog_err("vrf_init: failed to enable the default VRF!");
+ zlog_ferr(LIB_ERR_VRF_START,
+ "vrf_init: failed to enable the default VRF!");
exit(1);
}
@@ -542,20 +545,24 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
ret = vrf_switch_to_netns(vrf_id);
if (ret < 0)
- zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
- safe_strerror(errno));
+ zlog_ferr(LIB_ERR_VRF_SOCKET,
+ "%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
+ safe_strerror(errno));
+
if (ret > 0 && interfacename && vrf_default_accepts_vrf(type)) {
zlog_err("VRF socket not used since net.ipv4.%s_l3mdev_accept != 0",
(type == SOCK_STREAM ? "tcp" : "udp"));
errno = EEXIST; /* not sure if this is the best error... */
return -2;
}
+
ret = socket(domain, type, protocol);
save_errno = errno;
ret2 = vrf_switchback_to_initial();
if (ret2 < 0)
- zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
- vrf_id, safe_strerror(errno));
+ zlog_ferr(LIB_ERR_VRF_SOCKET,
+ "%s: Can't switchback from VRF %u (%s)", __func__,
+ vrf_id, safe_strerror(errno));
errno = save_errno;
if (ret <= 0)
return ret;
@@ -760,14 +767,16 @@ DEFUN_NOSH (vrf_netns,
if (vrf_daemon_privs &&
vrf_daemon_privs->change(ZPRIVS_RAISE))
- zlog_err("%s: Can't raise privileges", __func__);
+ zlog_ferr(LIB_ERR_PRIVILEGES,
+ "%s: Can't raise privileges", __func__);
ret = vrf_netns_handler_create(vty, vrf, pathname,
NS_UNKNOWN, NS_UNKNOWN);
if (vrf_daemon_privs &&
vrf_daemon_privs->change(ZPRIVS_LOWER))
- zlog_err("%s: Can't lower privileges", __func__);
+ zlog_ferr(LIB_ERR_PRIVILEGES,
+ "%s: Can't lower privileges", __func__);
return ret;
}
@@ -905,14 +914,16 @@ int vrf_getaddrinfo(const char *node, const char *service,
ret = vrf_switch_to_netns(vrf_id);
if (ret < 0)
- zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
- safe_strerror(errno));
+ zlog_ferr(LIB_ERR_VRF_SOCKET,
+ "%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
+ safe_strerror(errno));
ret = getaddrinfo(node, service, hints, res);
save_errno = errno;
ret2 = vrf_switchback_to_initial();
if (ret2 < 0)
- zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
- vrf_id, safe_strerror(errno));
+ zlog_ferr(LIB_ERR_VRF_SOCKET,
+ "%s: Can't switchback from VRF %u (%s)", __func__,
+ vrf_id, safe_strerror(errno));
errno = save_errno;
return ret;
}
@@ -923,16 +934,18 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
ret = vrf_switch_to_netns(vrf_id);
if (ret < 0) {
- zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
- safe_strerror(errno));
+ zlog_ferr(LIB_ERR_VRF_SOCKET,
+ "%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
+ safe_strerror(errno));
return 0;
}
rc = ioctl(d, request, params);
saved_errno = errno;
ret = vrf_switchback_to_initial();
if (ret < 0)
- zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
- vrf_id, safe_strerror(errno));
+ zlog_ferr(LIB_ERR_VRF_SOCKET,
+ "%s: Can't switchback from VRF %u (%s)", __func__,
+ vrf_id, safe_strerror(errno));
errno = saved_errno;
return rc;
}
@@ -944,14 +957,16 @@ int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
ret = vrf_switch_to_netns(vrf_id);
if (ret < 0)
- zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
- safe_strerror(errno));
+ zlog_ferr(LIB_ERR_VRF_SOCKET,
+ "%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
+ safe_strerror(errno));
ret = sockunion_socket(su);
save_errno = errno;
ret2 = vrf_switchback_to_initial();
if (ret2 < 0)
- zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
- vrf_id, safe_strerror(errno));
+ zlog_ferr(LIB_ERR_VRF_SOCKET,
+ "%s: Can't switchback from VRF %u (%s)", __func__,
+ vrf_id, safe_strerror(errno));
errno = save_errno;
if (ret <= 0)