diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-06-14 14:23:49 +0200 |
---|---|---|
committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2018-08-14 22:02:05 +0200 |
commit | b66d022e8d843bbc5daec9d1cb59f66d338f7433 (patch) | |
tree | b52046d8fb40b7d70b837f7fbeb8b7b01ac54859 /lib | |
parent | lib: Allow adding arrays of ferr's (diff) | |
download | frr-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.h | 5 | ||||
-rw-r--r-- | lib/lib_errors.c | 52 | ||||
-rw-r--r-- | lib/lib_errors.h | 34 | ||||
-rw-r--r-- | lib/libfrr.c | 3 | ||||
-rw-r--r-- | lib/subdir.am | 2 | ||||
-rw-r--r-- | lib/vrf.c | 55 |
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 \ @@ -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) |