From: Russ White Date: Thu, 16 Aug 2018 15:35:52 +0000 (-0400) Subject: Merge pull request #2848 from donaldsharp/more_init X-Git-Tag: frr-6.1-dev~56 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=12fa538096970b7a4f74b763b2f28dc72af89769;hp=29348bd7e753b69c495fb93b8cb207cb8f73974d;p=mirror_frr.git Merge pull request #2848 from donaldsharp/more_init sharpd, staticd: Add access_list_init --- diff --git a/babeld/babel_errors.c b/babeld/babel_errors.c new file mode 100644 index 000000000..e03cace37 --- /dev/null +++ b/babeld/babel_errors.c @@ -0,0 +1,61 @@ +/* + * Babel-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 + +#include "lib/ferr.h" +#include "babel_errors.h" + +/* clang-format off */ +static struct log_ref ferr_babel_err[] = { + { + .code = BABEL_ERR_MEMORY, + .title = "BABEL Memory Errors", + .description = "Babel has failed to allocate memory, the system is about to run out of memory", + .suggestion = "Find the process that is causing memory shortages, remediate that process and restart FRR" + }, + { + .code = BABEL_ERR_PACKET, + .title = "BABEL Packet Error", + .description = "Babel has detected a packet encode/decode problem", + .suggestion = "Collect relevant log files and file an Issue" + }, + { + .code = BABEL_ERR_CONFIG, + .title = "BABEL Configuration Error", + .description = "Babel has detected a configuration error of some sort", + .suggestion = "Ensure that the configuration is correct" + }, + { + .code = BABEL_ERR_ROUTE, + .title = "BABEL Route Error", + .description = "Babel has detected a routing error and has an inconsistent state", + .suggestion = "Gather data for filing an Issue and then restart FRR" + }, + { + .code = END_FERR, + } +}; +/* clang-format on */ + +void babel_error_init(void) +{ + log_ref_add(ferr_babel_err); +} diff --git a/babeld/babel_errors.h b/babeld/babel_errors.h new file mode 100644 index 000000000..19adc63f0 --- /dev/null +++ b/babeld/babel_errors.h @@ -0,0 +1,35 @@ +/* + * Babel-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 __BABEL_ERRORS_H__ +#define __BABEL_ERRORS_H__ + +#include "lib/ferr.h" + +enum babel_log_refs { + BABEL_ERR_MEMORY = BABEL_FERR_START, + BABEL_ERR_PACKET, + BABEL_ERR_CONFIG, + BABEL_ERR_ROUTE, +}; + +extern void babel_error_init(void); + +#endif diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 453fd8e04..b7c01e73d 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -27,6 +27,7 @@ THE SOFTWARE. #include "prefix.h" #include "vector.h" #include "distribute.h" +#include "lib_errors.h" #include "babel_main.h" #include "util.h" @@ -39,6 +40,7 @@ THE SOFTWARE. #include "route.h" #include "xroute.h" #include "babel_memory.h" +#include "babel_errors.h" #define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0) @@ -167,7 +169,7 @@ babel_interface_address_add (int cmd, struct zclient *client, if (babel_ifp->ipv4 == NULL) { babel_ifp->ipv4 = malloc(4); if (babel_ifp->ipv4 == NULL) { - zlog_err("not einough memory"); + flog_err(BABEL_ERR_MEMORY, "not enough memory"); } else { memcpy(babel_ifp->ipv4, &prefix->u.prefix4, 4); } @@ -707,7 +709,7 @@ interface_recalculate(struct interface *ifp) tmp = babel_ifp->sendbuf; babel_ifp->sendbuf = realloc(babel_ifp->sendbuf, babel_ifp->bufsize); if(babel_ifp->sendbuf == NULL) { - zlog_err("Couldn't reallocate sendbuf."); + flog_err(BABEL_ERR_MEMORY, "Couldn't reallocate sendbuf."); free(tmp); babel_ifp->bufsize = 0; return -1; @@ -727,8 +729,9 @@ interface_recalculate(struct interface *ifp) rc = setsockopt(protocol_socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*)&mreq, sizeof(mreq)); if(rc < 0) { - zlog_err("setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s", - ifp->name, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s", + ifp->name, safe_strerror(errno)); /* This is probably due to a missing link-local address, so down this interface, and wait until the main loop tries to up it again. */ @@ -790,8 +793,9 @@ interface_reset(struct interface *ifp) rc = setsockopt(protocol_socket, IPPROTO_IPV6, IPV6_LEAVE_GROUP, (char*)&mreq, sizeof(mreq)); if(rc < 0) - zlog_err("setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s", - ifp->name, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s", + ifp->name, safe_strerror(errno)); } update_interface_metric(ifp); @@ -1056,7 +1060,7 @@ DEFUN (show_babel_route, } route_stream_done(routes); } else { - zlog_err("Couldn't allocate route stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream."); } xroutes = xroute_stream(); if(xroutes) { @@ -1068,7 +1072,7 @@ DEFUN (show_babel_route, } xroute_stream_done(xroutes); } else { - zlog_err("Couldn't allocate route stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream."); } return CMD_SUCCESS; } @@ -1103,7 +1107,7 @@ DEFUN (show_babel_route_prefix, } route_stream_done(routes); } else { - zlog_err("Couldn't allocate route stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream."); } xroutes = xroute_stream(); if(xroutes) { @@ -1115,7 +1119,7 @@ DEFUN (show_babel_route_prefix, } xroute_stream_done(xroutes); } else { - zlog_err("Couldn't allocate route stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream."); } return CMD_SUCCESS; } @@ -1161,7 +1165,7 @@ DEFUN (show_babel_route_addr, } route_stream_done(routes); } else { - zlog_err("Couldn't allocate route stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream."); } xroutes = xroute_stream(); if(xroutes) { @@ -1173,7 +1177,7 @@ DEFUN (show_babel_route_addr, } xroute_stream_done(xroutes); } else { - zlog_err("Couldn't allocate route stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream."); } return CMD_SUCCESS; } @@ -1220,7 +1224,7 @@ DEFUN (show_babel_route_addr6, } route_stream_done(routes); } else { - zlog_err("Couldn't allocate route stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream."); } xroutes = xroute_stream(); if(xroutes) { @@ -1232,7 +1236,7 @@ DEFUN (show_babel_route_addr6, } xroute_stream_done(xroutes); } else { - zlog_err("Couldn't allocate route stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream."); } return CMD_SUCCESS; } diff --git a/babeld/babel_main.c b/babeld/babel_main.c index 2b87bed0f..31a3fb5b4 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -33,6 +33,7 @@ THE SOFTWARE. #include "vty.h" #include "memory.h" #include "libfrr.h" +#include "lib_errors.h" #include "babel_main.h" #include "babeld.h" @@ -45,6 +46,7 @@ THE SOFTWARE. #include "message.h" #include "resend.h" #include "babel_zebra.h" +#include "babel_errors.h" static void babel_fail(void); static void babel_init_random(void); @@ -151,7 +153,7 @@ main(int argc, char **argv) frr_preinit (&babeld_di, argc, argv); frr_opt_add ("", longopts, ""); - + babel_init_random(); /* set the Babel's default link-local multicast address and Babel's port */ @@ -181,9 +183,7 @@ main(int argc, char **argv) master = frr_init (); /* Library inits. */ - zprivs_init (&babeld_privs); - cmd_init (1); - vty_init (master); + babel_error_init(); resend_delay = BABEL_DEFAULT_RESEND_DELAY; change_smoothing_half_life(BABEL_DEFAULT_SMOOTHING_HALF_LIFE); @@ -225,7 +225,8 @@ babel_init_random(void) rc = read_random_bytes(&seed, sizeof(seed)); if(rc < 0) { - zlog_err("read(random): %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "read(random): %s", + safe_strerror(errno)); seed = 42; } @@ -245,13 +246,14 @@ babel_replace_by_null(int fd) fd_null = open("/dev/null", O_RDONLY); if(fd_null < 0) { - zlog_err("open(null): %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "open(null): %s", safe_strerror(errno)); exit(1); } rc = dup2(fd_null, fd); if(rc < 0) { - zlog_err("dup2(null, 0): %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "dup2(null, 0): %s", + safe_strerror(errno)); exit(1); } @@ -270,10 +272,12 @@ babel_load_state_file(void) fd = open(state_file, O_RDONLY); if(fd < 0 && errno != ENOENT) - zlog_err("open(babel-state: %s)", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "open(babel-state: %s)", + safe_strerror(errno)); rc = unlink(state_file); if(fd >= 0 && rc < 0) { - zlog_err("unlink(babel-state): %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "unlink(babel-state): %s", + safe_strerror(errno)); /* If we couldn't unlink it, it's probably stale. */ goto fini; } @@ -284,7 +288,8 @@ babel_load_state_file(void) long t; rc = read(fd, buf, 99); if(rc < 0) { - zlog_err("read(babel-state): %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "read(babel-state): %s", + safe_strerror(errno)); } else { buf[rc] = '\0'; rc = sscanf(buf, "%99s %d %ld\n", buf2, &s, &t); @@ -292,7 +297,7 @@ babel_load_state_file(void) unsigned char sid[8]; rc = parse_eui64(buf2, sid); if(rc < 0) { - zlog_err("Couldn't parse babel-state."); + flog_err(BABEL_ERR_CONFIG, "Couldn't parse babel-state."); } else { struct timeval realnow; debugf(BABEL_DEBUG_COMMON, @@ -302,12 +307,13 @@ babel_load_state_file(void) if(memcmp(sid, myid, 8) == 0) myseqno = seqno_plus(s, 1); else - zlog_err("ID mismatch in babel-state. id=%s; old=%s", + flog_err(BABEL_ERR_CONFIG, + "ID mismatch in babel-state. id=%s; old=%s", format_eui64(myid), format_eui64(sid)); } } else { - zlog_err("Couldn't parse babel-state."); + flog_err(BABEL_ERR_CONFIG, "Couldn't parse babel-state."); } } goto fini; @@ -347,7 +353,8 @@ babel_save_state_file(void) debugf(BABEL_DEBUG_COMMON, "Save state file."); fd = open(state_file, O_WRONLY | O_TRUNC | O_CREAT, 0644); if(fd < 0) { - zlog_err("creat(babel-state): %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "creat(babel-state): %s", + safe_strerror(errno)); unlink(state_file); } else { struct timeval realnow; @@ -357,12 +364,13 @@ babel_save_state_file(void) format_eui64(myid), (int)myseqno, (long)realnow.tv_sec); if(rc < 0 || rc >= 100) { - zlog_err("write(babel-state): overflow."); + flog_err(BABEL_ERR_CONFIG, "write(babel-state): overflow."); unlink(state_file); } else { rc = write(fd, buf, rc); if(rc < 0) { - zlog_err("write(babel-state): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_CONFIG, "write(babel-state): %s", + safe_strerror(errno)); unlink(state_file); } fsync(fd); diff --git a/babeld/babeld.c b/babeld/babeld.c index 20dd098f3..54692cdf2 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -29,6 +29,7 @@ THE SOFTWARE. #include "prefix.h" #include "filter.h" #include "plist.h" +#include "lib_errors.h" #include "babel_main.h" #include "babeld.h" @@ -43,6 +44,7 @@ THE SOFTWARE. #include "babel_filter.h" #include "babel_zebra.h" #include "babel_memory.h" +#include "babel_errors.h" static int babel_init_routing_process(struct thread *thread); static void babel_get_myid(void); @@ -143,7 +145,8 @@ babel_create_routing_process (void) /* Make socket for Babel protocol. */ protocol_socket = babel_socket(protocol_port); if (protocol_socket < 0) { - zlog_err("Couldn't create link local socket: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "Couldn't create link local socket: %s", + safe_strerror(errno)); goto fail; } @@ -176,7 +179,7 @@ babel_read_protocol (struct thread *thread) (struct sockaddr*)&sin6, sizeof(sin6)); if(rc < 0) { if(errno != EAGAIN && errno != EINTR) { - zlog_err("recv: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "recv: %s", safe_strerror(errno)); } } else { FOR_ALL_INTERFACES(vrf, ifp) { @@ -252,11 +255,13 @@ babel_get_myid(void) return; } - zlog_err("Warning: couldn't find router id -- using random value."); + flog_err(BABEL_ERR_CONFIG, + "Warning: couldn't find router id -- using random value."); rc = read_random_bytes(myid, 8); if(rc < 0) { - zlog_err("read(random): %s (cannot assign an ID)",safe_strerror(errno)); + flog_err(BABEL_ERR_CONFIG, "read(random): %s (cannot assign an ID)", + safe_strerror(errno)); exit(1); } /* Clear group and global bits */ @@ -514,7 +519,8 @@ resize_receive_buffer(int size) if(receive_buffer == NULL) { receive_buffer = malloc(size); if(receive_buffer == NULL) { - zlog_err("malloc(receive_buffer): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_MEMORY, "malloc(receive_buffer): %s", + safe_strerror(errno)); return -1; } receive_buffer_size = size; @@ -522,7 +528,8 @@ resize_receive_buffer(int size) unsigned char *new; new = realloc(receive_buffer, size); if(new == NULL) { - zlog_err("realloc(receive_buffer): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_MEMORY, "realloc(receive_buffer): %s", + safe_strerror(errno)); return -1; } receive_buffer = new; diff --git a/babeld/message.c b/babeld/message.c index 95b4e87cc..09eaca7a4 100644 --- a/babeld/message.c +++ b/babeld/message.c @@ -35,6 +35,7 @@ THE SOFTWARE. #include "message.h" #include "kernel.h" #include "babel_main.h" +#include "babel_errors.h" static unsigned char packet_header[4] = {42, 2}; @@ -140,12 +141,12 @@ parse_update_subtlv(const unsigned char *a, int alen, } if(i + 1 > alen) { - zlog_err("Received truncated attributes."); + flog_err(BABEL_ERR_PACKET, "Received truncated attributes."); return; } len = a[i + 1]; if(i + len > alen) { - zlog_err("Received truncated attributes."); + flog_err(BABEL_ERR_PACKET, "Received truncated attributes."); return; } @@ -153,13 +154,14 @@ parse_update_subtlv(const unsigned char *a, int alen, /* Nothing. */ } else if(type == SUBTLV_DIVERSITY) { if(len > DIVERSITY_HOPS) { - zlog_err("Received overlong channel information (%d > %d).n", - len, DIVERSITY_HOPS); + flog_err(BABEL_ERR_PACKET, + "Received overlong channel information (%d > %d).n", + len, DIVERSITY_HOPS); len = DIVERSITY_HOPS; } if(memchr(a + i + 2, 0, len) != NULL) { /* 0 is reserved. */ - zlog_err("Channel information contains 0!"); + flog_err(BABEL_ERR_PACKET, "Channel information contains 0!"); return; } memset(channels, 0, DIVERSITY_HOPS); @@ -187,12 +189,14 @@ parse_hello_subtlv(const unsigned char *a, int alen, } if(i + 1 > alen) { - zlog_err("Received truncated sub-TLV on Hello message."); + flog_err(BABEL_ERR_PACKET, + "Received truncated sub-TLV on Hello message."); return -1; } len = a[i + 1]; if(i + len > alen) { - zlog_err("Received truncated sub-TLV on Hello message."); + flog_err(BABEL_ERR_PACKET, + "Received truncated sub-TLV on Hello message."); return -1; } @@ -203,7 +207,8 @@ parse_hello_subtlv(const unsigned char *a, int alen, DO_NTOHL(*hello_send_us, a + i + 2); ret = 1; } else { - zlog_err("Received incorrect RTT sub-TLV on Hello message."); + flog_err(BABEL_ERR_PACKET, + "Received incorrect RTT sub-TLV on Hello message."); } } else { debugf(BABEL_DEBUG_COMMON, @@ -230,12 +235,14 @@ parse_ihu_subtlv(const unsigned char *a, int alen, } if(i + 1 > alen) { - zlog_err("Received truncated sub-TLV on IHU message."); + flog_err(BABEL_ERR_PACKET, + "Received truncated sub-TLV on IHU message."); return -1; } len = a[i + 1]; if(i + len > alen) { - zlog_err("Received truncated sub-TLV on IHU message."); + flog_err(BABEL_ERR_PACKET, + "Received truncated sub-TLV on IHU message."); return -1; } @@ -248,7 +255,8 @@ parse_ihu_subtlv(const unsigned char *a, int alen, ret = 1; } else { - zlog_err("Received incorrect RTT sub-TLV on IHU message."); + flog_err(BABEL_ERR_PACKET, + "Received incorrect RTT sub-TLV on IHU message."); } } else { debugf(BABEL_DEBUG_COMMON, @@ -337,27 +345,29 @@ parse_packet(const unsigned char *from, struct interface *ifp, } if(!linklocal(from)) { - zlog_err("Received packet from non-local address %s.", - format_address(from)); + flog_err(BABEL_ERR_PACKET, + "Received packet from non-local address %s.", + format_address(from)); return; } if (babel_packet_examin (packet, packetlen)) { - zlog_err("Received malformed packet on %s from %s.", - ifp->name, format_address(from)); + flog_err(BABEL_ERR_PACKET, + "Received malformed packet on %s from %s.", + ifp->name, format_address(from)); return; } neigh = find_neighbour(from, ifp); if(neigh == NULL) { - zlog_err("Couldn't allocate neighbour."); + flog_err(BABEL_ERR_PACKET, "Couldn't allocate neighbour."); return; } DO_NTOHS(bodylen, packet + 2); if(bodylen + 4 > packetlen) { - zlog_err("Received truncated packet (%d + 4 > %d).", + flog_err(BABEL_ERR_PACKET, "Received truncated packet (%d + 4 > %d).", bodylen, packetlen); bodylen = packetlen - 4; } @@ -506,7 +516,8 @@ parse_packet(const unsigned char *from, struct interface *ifp, have_router_id = 1; } if(!have_router_id && message[2] != 0) { - zlog_err("Received prefix with no router id."); + flog_err(BABEL_ERR_PACKET, + "Received prefix with no router id."); goto fail; } debugf(BABEL_DEBUG_COMMON,"Received update%s%s for %s from %s on %s.", @@ -517,7 +528,8 @@ parse_packet(const unsigned char *from, struct interface *ifp, if(message[2] == 0) { if(metric < 0xFFFF) { - zlog_err("Received wildcard update with finite metric."); + flog_err(BABEL_ERR_PACKET, + "Received wildcard update with finite metric."); goto done; } retract_neighbour_routes(neigh); @@ -609,8 +621,9 @@ parse_packet(const unsigned char *from, struct interface *ifp, continue; fail: - zlog_err("Couldn't parse packet (%d, %d) from %s on %s.", - message[0], message[1], format_address(from), ifp->name); + flog_err(BABEL_ERR_PACKET, + "Couldn't parse packet (%d, %d) from %s on %s.", + message[0], message[1], format_address(from), ifp->name); goto done; } @@ -697,7 +710,7 @@ fill_rtt_message(struct interface *ifp) DO_HTONL(babel_ifp->sendbuf + babel_ifp->buffered_hello + 10, time); return 1; } else { - zlog_err("No space left for timestamp sub-TLV " + flog_err(BABEL_ERR_PACKET, "No space left for timestamp sub-TLV " "(this shouldn't happen)"); return -1; } @@ -732,10 +745,11 @@ flushbuf(struct interface *ifp) babel_ifp->sendbuf, babel_ifp->buffered, (struct sockaddr*)&sin6, sizeof(sin6)); if(rc < 0) - zlog_err("send: %s", safe_strerror(errno)); + flog_err(BABEL_ERR_PACKET, "send: %s", safe_strerror(errno)); } else { - zlog_err("Warning: bucket full, dropping packet to %s.", - ifp->name); + flog_err(BABEL_ERR_PACKET, + "Warning: bucket full, dropping packet to %s.", + ifp->name); } } VALGRIND_MAKE_MEM_UNDEFINED(babel_ifp->sendbuf, babel_ifp->bufsize); @@ -856,7 +870,8 @@ start_unicast_message(struct neighbour *neigh, int type, int len) if(!unicast_buffer) unicast_buffer = malloc(UNICAST_BUFSIZE); if(!unicast_buffer) { - zlog_err("malloc(unicast_buffer): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_MEMORY, "malloc(unicast_buffer): %s", + safe_strerror(errno)); return -1; } @@ -992,11 +1007,13 @@ flush_unicast(int dofree) unicast_buffer, unicast_buffered, (struct sockaddr*)&sin6, sizeof(sin6)); if(rc < 0) - zlog_err("send(unicast): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_PACKET, "send(unicast): %s", + safe_strerror(errno)); } else { - zlog_err("Warning: bucket full, dropping unicast packet to %s if %s.", - format_address(unicast_neighbour->address), - unicast_neighbour->ifp->name); + flog_err(BABEL_ERR_PACKET, + "Warning: bucket full, dropping unicast packet to %s if %s.", + format_address(unicast_neighbour->address), + unicast_neighbour->ifp->name); } done: @@ -1301,7 +1318,8 @@ buffer_update(struct interface *ifp, again: babel_ifp->buffered_updates = malloc(n *sizeof(struct buffered_update)); if(babel_ifp->buffered_updates == NULL) { - zlog_err("malloc(buffered_updates): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_MEMORY, "malloc(buffered_updates): %s", + safe_strerror(errno)); if(n > 4) { /* Try again with a tiny buffer. */ n = 4; @@ -1364,7 +1382,7 @@ send_update(struct interface *ifp, int urgent, } route_stream_done(routes); } else { - zlog_err("Couldn't allocate route stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream."); } set_timeout(&babel_ifp->update_timeout, babel_ifp->update_interval); babel_ifp->last_update_time = babel_now.tv_sec; @@ -1442,7 +1460,7 @@ send_self_update(struct interface *ifp) } xroute_stream_done(xroutes); } else { - zlog_err("Couldn't allocate xroute stream."); + flog_err(BABEL_ERR_MEMORY, "Couldn't allocate xroute stream."); } } diff --git a/babeld/neighbour.c b/babeld/neighbour.c index 3db121fd2..c1592fb18 100644 --- a/babeld/neighbour.c +++ b/babeld/neighbour.c @@ -38,6 +38,7 @@ THE SOFTWARE. #include "route.h" #include "message.h" #include "resend.h" +#include "babel_errors.h" struct neighbour *neighs = NULL; @@ -89,7 +90,8 @@ find_neighbour(const unsigned char *address, struct interface *ifp) neigh = malloc(sizeof(struct neighbour)); if(neigh == NULL) { - zlog_err("malloc(neighbour): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_MEMORY, "malloc(neighbour): %s", + safe_strerror(errno)); return NULL; } diff --git a/babeld/route.c b/babeld/route.c index bc7590fb3..ceeaa1057 100644 --- a/babeld/route.c +++ b/babeld/route.c @@ -34,13 +34,14 @@ THE SOFTWARE. #include "xroute.h" #include "message.h" #include "resend.h" +#include "babel_errors.h" static void consider_route(struct babel_route *route); struct babel_route **routes = NULL; static int route_slots = 0, max_route_slots = 0; int kernel_metric = 0; -int diversity_kind = DIVERSITY_NONE; +enum babel_diversity diversity_kind = DIVERSITY_NONE; int diversity_factor = BABEL_DEFAULT_DIVERSITY_FACTOR; int keep_unfeasible = 0; @@ -398,15 +399,16 @@ install_route(struct babel_route *route) return; if(!route_feasible(route)) - zlog_err("WARNING: installing unfeasible route " - "(this shouldn't happen)."); + flog_err(BABEL_ERR_ROUTE, "WARNING: installing unfeasible route " + "(this shouldn't happen)."); i = find_route_slot(route->src->prefix, route->src->plen, NULL); assert(i >= 0 && i < route_slots); if(routes[i] != route && routes[i]->installed) { - zlog_err("WARNING: attempting to install duplicate route " - "(this shouldn't happen)."); + flog_err(BABEL_ERR_ROUTE, + "WARNING: attempting to install duplicate route " + "(this shouldn't happen)."); return; } @@ -416,7 +418,8 @@ install_route(struct babel_route *route) metric_to_kernel(route_metric(route)), NULL, 0, 0); if(rc < 0) { int save = errno; - zlog_err("kernel_route(ADD): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_ROUTE, "kernel_route(ADD): %s", + safe_strerror(errno)); if(save != EEXIST) return; } @@ -438,7 +441,8 @@ uninstall_route(struct babel_route *route) route->neigh->ifp->ifindex, metric_to_kernel(route_metric(route)), NULL, 0, 0); if(rc < 0) - zlog_err("kernel_route(FLUSH): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_ROUTE, "kernel_route(FLUSH): %s", + safe_strerror(errno)); route->installed = 0; } @@ -461,8 +465,8 @@ switch_routes(struct babel_route *old, struct babel_route *new) return; if(!route_feasible(new)) - zlog_err("WARNING: switching to unfeasible route " - "(this shouldn't happen)."); + flog_err(BABEL_ERR_ROUTE, "WARNING: switching to unfeasible route " + "(this shouldn't happen)."); rc = kernel_route(ROUTE_MODIFY, old->src->prefix, old->src->plen, old->nexthop, old->neigh->ifp->ifindex, @@ -470,7 +474,8 @@ switch_routes(struct babel_route *old, struct babel_route *new) new->nexthop, new->neigh->ifp->ifindex, metric_to_kernel(route_metric(new))); if(rc < 0) { - zlog_err("kernel_route(MODIFY): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_ROUTE, "kernel_route(MODIFY): %s", + safe_strerror(errno)); return; } @@ -498,7 +503,8 @@ change_route_metric(struct babel_route *route, route->nexthop, route->neigh->ifp->ifindex, new); if(rc < 0) { - zlog_err("kernel_route(MODIFY metric): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_ROUTE, "kernel_route(MODIFY metric): %s", + safe_strerror(errno)); return; } } @@ -581,10 +587,9 @@ route_interferes(struct babel_route *route, struct interface *ifp) } } return 0; - default: - zlog_err("Unknown kind of diversity."); - return 1; } + + return 1; } int @@ -793,7 +798,7 @@ update_route(const unsigned char *router_id, return NULL; if(martian_prefix(prefix, plen)) { - zlog_err("Rejecting martian route to %s through %s.", + flog_err(BABEL_ERR_ROUTE, "Rejecting martian route to %s through %s.", format_prefix(prefix, plen), format_address(nexthop)); return NULL; } @@ -901,7 +906,7 @@ update_route(const unsigned char *router_id, route->next = NULL; new_route = insert_route(route); if(new_route == NULL) { - zlog_err("Couldn't insert route."); + flog_err(BABEL_ERR_ROUTE, "Couldn't insert route."); free(route); return NULL; } diff --git a/babeld/route.h b/babeld/route.h index c2026d176..c994d22a9 100644 --- a/babeld/route.h +++ b/babeld/route.h @@ -27,10 +27,12 @@ THE SOFTWARE. #include "babel_interface.h" #include "source.h" -#define DIVERSITY_NONE 0 -#define DIVERSITY_INTERFACE_1 1 -#define DIVERSITY_CHANNEL_1 2 -#define DIVERSITY_CHANNEL 3 +enum babel_diversity { + DIVERSITY_NONE, + DIVERSITY_INTERFACE_1, + DIVERSITY_CHANNEL_1, + DIVERSITY_CHANNEL, +}; #define DIVERSITY_HOPS 8 @@ -55,7 +57,8 @@ struct route_stream; extern struct babel_route **routes; extern int kernel_metric; -extern int diversity_kind, diversity_factor; +extern enum babel_diversity diversity_kind; +extern int diversity_factor; extern int keep_unfeasible; extern int smoothing_half_life; diff --git a/babeld/source.c b/babeld/source.c index 72396102b..d6dd84895 100644 --- a/babeld/source.c +++ b/babeld/source.c @@ -31,6 +31,7 @@ THE SOFTWARE. #include "source.h" #include "babel_interface.h" #include "route.h" +#include "babel_errors.h" struct source *srcs = NULL; @@ -58,7 +59,7 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen, src = malloc(sizeof(struct source)); if(src == NULL) { - zlog_err("malloc(source): %s", safe_strerror(errno)); + flog_err(BABEL_ERR_MEMORY, "malloc(source): %s", safe_strerror(errno)); return NULL; } diff --git a/babeld/subdir.am b/babeld/subdir.am index c44cb275c..6f91f7393 100644 --- a/babeld/subdir.am +++ b/babeld/subdir.am @@ -9,6 +9,7 @@ dist_examples_DATA += babeld/babeld.conf.sample endif babeld_libbabel_a_SOURCES = \ + babeld/babel_errors.c \ babeld/babel_filter.c \ babeld/babel_interface.c \ babeld/babel_memory.c \ @@ -26,6 +27,7 @@ babeld_libbabel_a_SOURCES = \ # end noinst_HEADERS += \ + babeld/babel_errors.h \ babeld/babel_filter.h \ babeld/babel_interface.h \ babeld/babel_main.h \ diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am index 2f19bbbd7..b6b125f75 100644 --- a/bgpd/Makefile.am +++ b/bgpd/Makefile.am @@ -85,7 +85,7 @@ libbgp_a_SOURCES = \ bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC) bgp_attr_evpn.c \ bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c bgp_rd.c \ bgp_keepalives.c bgp_io.c bgp_flowspec.c bgp_flowspec_util.c \ - bgp_flowspec_vty.c bgp_labelpool.c bgp_pbr.c + bgp_flowspec_vty.c bgp_labelpool.c bgp_pbr.c bgp_errors.c noinst_HEADERS = \ bgp_memory.h \ @@ -99,7 +99,7 @@ noinst_HEADERS = \ $(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h \ bgp_vpn.h bgp_label.h bgp_rd.h bgp_evpn_private.h bgp_keepalives.h \ bgp_io.h bgp_flowspec.h bgp_flowspec_private.h bgp_flowspec_util.h \ - bgp_labelpool.h bgp_pbr.h + bgp_labelpool.h bgp_pbr.h bgp_errors.h bgpd_SOURCES = bgp_main.c bgpd_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@ diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index e5ad5e233..6acd4c8cf 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -39,6 +39,7 @@ #include "bgpd/bgp_aspath.h" #include "bgpd/bgp_community.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_label.h" #include "bgpd/bgp_packet.h" #include "bgpd/bgp_ecommunity.h" @@ -996,12 +997,14 @@ bgp_attr_flags_diagnose(struct bgp_attr_parser_args *args, for (i = 0; i <= 2; i++) /* O,T,P, but not E */ if (CHECK_FLAG(desired_flags, attr_flag_str[i].key) != CHECK_FLAG(real_flags, attr_flag_str[i].key)) { - zlog_err("%s attribute must%s be flagged as \"%s\"", - lookup_msg(attr_str, attr_code, NULL), - CHECK_FLAG(desired_flags, attr_flag_str[i].key) - ? "" - : " not", - attr_flag_str[i].str); + flog_err( + BGP_ERR_ATTR_FLAG, + "%s attribute must%s be flagged as \"%s\"", + lookup_msg(attr_str, attr_code, NULL), + CHECK_FLAG(desired_flags, attr_flag_str[i].key) + ? "" + : " not", + attr_flag_str[i].str); seen = 1; } if (!seen) { @@ -1059,7 +1062,8 @@ static int bgp_attr_flag_invalid(struct bgp_attr_parser_args *args) */ if (!CHECK_FLAG(BGP_ATTR_FLAG_OPTIONAL, flags) && !CHECK_FLAG(BGP_ATTR_FLAG_TRANS, flags)) { - zlog_err( + flog_err( + BGP_ERR_ATTR_FLAG, "%s well-known attributes must have transitive flag set (%x)", lookup_msg(attr_str, attr_code, NULL), flags); return 1; @@ -1071,18 +1075,18 @@ static int bgp_attr_flag_invalid(struct bgp_attr_parser_args *args) */ if (CHECK_FLAG(flags, BGP_ATTR_FLAG_PARTIAL)) { if (!CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)) { - zlog_err( - "%s well-known attribute " - "must NOT have the partial flag set (%x)", - lookup_msg(attr_str, attr_code, NULL), flags); + flog_err(BGP_ERR_ATTR_FLAG, + "%s well-known attribute " + "must NOT have the partial flag set (%x)", + lookup_msg(attr_str, attr_code, NULL), flags); return 1; } if (CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL) && !CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS)) { - zlog_err( - "%s optional + transitive attribute " - "must NOT have the partial flag set (%x)", - lookup_msg(attr_str, attr_code, NULL), flags); + flog_err(BGP_ERR_ATTR_FLAG, + "%s optional + transitive attribute " + "must NOT have the partial flag set (%x)", + lookup_msg(attr_str, attr_code, NULL), flags); return 1; } } @@ -1114,7 +1118,8 @@ static bgp_attr_parse_ret_t bgp_attr_origin(struct bgp_attr_parser_args *args) field contains the erroneous attribute (type, length and value). */ if (length != 1) { - zlog_err("Origin attribute length is not one %d", length); + flog_err(BGP_ERR_ATTR_LEN, + "Origin attribute length is not one %d", length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); } @@ -1127,7 +1132,8 @@ static bgp_attr_parse_ret_t bgp_attr_origin(struct bgp_attr_parser_args *args) contains the unrecognized attribute (type, length and value). */ if ((attr->origin != BGP_ORIGIN_IGP) && (attr->origin != BGP_ORIGIN_EGP) && (attr->origin != BGP_ORIGIN_INCOMPLETE)) { - zlog_err("Origin attribute value is invalid %d", attr->origin); + flog_err(BGP_ERR_ATTR_ORIGIN, + "Origin attribute value is invalid %d", attr->origin); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_INVAL_ORIGIN, args->total); } @@ -1155,8 +1161,9 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args) /* In case of IBGP, length will be zero. */ if (!attr->aspath) { - zlog_err("Malformed AS path from %s, length is %d", peer->host, - length); + flog_err(BGP_ERR_ATTR_MAL_AS_PATH, + "Malformed AS path from %s, length is %d", peer->host, + length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH, 0); } @@ -1184,7 +1191,8 @@ static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer, && !aspath_left_confed_check(attr->aspath)) || (peer->sort == BGP_PEER_EBGP && aspath_confed_check(attr->aspath))) { - zlog_err("Malformed AS path from %s", peer->host); + flog_err(BGP_ERR_ATTR_MAL_AS_PATH, "Malformed AS path from %s", + peer->host); bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_AS_PATH); return BGP_ATTR_PARSE_ERROR; @@ -1194,8 +1202,9 @@ static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer, if (CHECK_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) { if (peer->sort == BGP_PEER_EBGP && !aspath_firstas_check(attr->aspath, peer->as)) { - zlog_err("%s incorrect first AS (must be %u)", - peer->host, peer->as); + flog_err(BGP_ERR_ATTR_FIRST_AS, + "%s incorrect first AS (must be %u)", + peer->host, peer->as); bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_AS_PATH); return BGP_ATTR_PARSE_ERROR; @@ -1227,8 +1236,9 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args, /* In case of IBGP, length will be zero. */ if (!*as4_path) { - zlog_err("Malformed AS4 path from %s, length is %d", peer->host, - length); + flog_err(BGP_ERR_ATTR_MAL_AS_PATH, + "Malformed AS4 path from %s, length is %d", + peer->host, length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH, 0); } @@ -1250,7 +1260,8 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) /* Check nexthop attribute length. */ if (length != 4) { - zlog_err("Nexthop attribute length isn't four [%d]", length); + flog_err(BGP_ERR_ATTR_LEN, + "Nexthop attribute length isn't four [%d]", length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); @@ -1274,7 +1285,7 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) { char buf[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN); - zlog_err("Martian nexthop %s", buf); + flog_err(BGP_ERR_ATTR_MARTIAN_NH, "Martian nexthop %s", buf); return bgp_attr_malformed( args, BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP, args->total); } @@ -1294,7 +1305,8 @@ static bgp_attr_parse_ret_t bgp_attr_med(struct bgp_attr_parser_args *args) /* Length check. */ if (length != 4) { - zlog_err("MED attribute length isn't four [%d]", length); + flog_err(BGP_ERR_ATTR_LEN, + "MED attribute length isn't four [%d]", length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); @@ -1317,7 +1329,8 @@ bgp_attr_local_pref(struct bgp_attr_parser_args *args) /* Length check. */ if (length != 4) { - zlog_err("LOCAL_PREF attribute length isn't 4 [%u]", length); + flog_err(BGP_ERR_ATTR_LEN, + "LOCAL_PREF attribute length isn't 4 [%u]", length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); } @@ -1346,8 +1359,9 @@ static int bgp_attr_atomic(struct bgp_attr_parser_args *args) /* Length check. */ if (length != 0) { - zlog_err("ATOMIC_AGGREGATE attribute length isn't 0 [%u]", - length); + flog_err(BGP_ERR_ATTR_LEN, + "ATOMIC_AGGREGATE attribute length isn't 0 [%u]", + length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); } @@ -1372,8 +1386,9 @@ static int bgp_attr_aggregator(struct bgp_attr_parser_args *args) wantedlen = 8; if (length != wantedlen) { - zlog_err("AGGREGATOR attribute length isn't %u [%u]", wantedlen, - length); + flog_err(BGP_ERR_ATTR_LEN, + "AGGREGATOR attribute length isn't %u [%u]", + wantedlen, length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); } @@ -1401,7 +1416,8 @@ bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args, const bgp_size_t length = args->length; if (length != 8) { - zlog_err("New Aggregator length is not 8 [%d]", length); + flog_err(BGP_ERR_ATTR_LEN, + "New Aggregator length is not 8 [%d]", length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, 0); } @@ -1560,7 +1576,8 @@ bgp_attr_originator_id(struct bgp_attr_parser_args *args) /* Length check. */ if (length != 4) { - zlog_err("Bad originator ID length %d", length); + flog_err(BGP_ERR_ATTR_LEN, "Bad originator ID length %d", + length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); @@ -1583,7 +1600,8 @@ bgp_attr_cluster_list(struct bgp_attr_parser_args *args) /* Check length. */ if (length % 4) { - zlog_err("Bad cluster list length %d", length); + flog_err(BGP_ERR_ATTR_LEN, "Bad cluster list length %d", + length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); @@ -2052,10 +2070,10 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(int32_t type, if (type == BGP_PREFIX_SID_LABEL_INDEX) { if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) { - zlog_err( - "Prefix SID label index length is %d instead of %d", - length, - BGP_PREFIX_SID_LABEL_INDEX_LENGTH); + flog_err( + BGP_ERR_ATTR_LEN, + "Prefix SID label index length is %d instead of %d", + length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); @@ -2088,8 +2106,9 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(int32_t type, /* Placeholder code for the IPv6 SID type */ else if (type == BGP_PREFIX_SID_IPV6) { if (length != BGP_PREFIX_SID_IPV6_LENGTH) { - zlog_err("Prefix SID IPv6 length is %d instead of %d", - length, BGP_PREFIX_SID_IPV6_LENGTH); + flog_err(BGP_ERR_ATTR_LEN, + "Prefix SID IPv6 length is %d instead of %d", + length, BGP_PREFIX_SID_IPV6_LENGTH); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); @@ -2110,7 +2129,8 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(int32_t type, length -= 2; if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH) { - zlog_err( + flog_err( + BGP_ERR_ATTR_LEN, "Prefix SID Originator SRGB length is %d, it must be a multiple of %d ", length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH); return bgp_attr_malformed( @@ -2159,8 +2179,10 @@ bgp_attr_prefix_sid(int32_t tlength, struct bgp_attr_parser_args *args, tlength -= length + 3; if (tlength < 0) { - zlog_err("Prefix SID internal length %d causes us to read beyond the total Prefix SID length", - length); + flog_err( + BGP_ERR_ATTR_LEN, + "Prefix SID internal length %d causes us to read beyond the total Prefix SID length", + length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); @@ -2185,21 +2207,24 @@ bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args) * can only support that. */ if (length < 2) { - zlog_err("Bad PMSI tunnel attribute length %d", length); + flog_err(BGP_ERR_ATTR_LEN, + "Bad PMSI tunnel attribute length %d", length); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); } stream_getc(peer->curr); /* Flags */ tnl_type = stream_getc(peer->curr); if (tnl_type > PMSI_TNLTYPE_MAX) { - zlog_err("Invalid PMSI tunnel attribute type %d", tnl_type); + flog_err(BGP_ERR_ATTR_PMSI_TYPE, + "Invalid PMSI tunnel attribute type %d", tnl_type); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, args->total); } if (tnl_type == PMSI_TNLTYPE_INGR_REPL) { if (length != 9) { - zlog_err("Bad PMSI tunnel attribute length %d for IR", - length); + flog_err(BGP_ERR_ATTR_PMSI_LEN, + "Bad PMSI tunnel attribute length %d for IR", + length); return bgp_attr_malformed( args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, args->total); @@ -2799,9 +2824,10 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, break; default: if (safi != SAFI_FLOWSPEC) - zlog_err( - "Bad nexthop when sending to %s, AFI %u SAFI %u nhlen %d", - peer->host, afi, safi, attr->mp_nexthop_len); + flog_err( + BGP_ERR_ATTR_NH_SEND_LEN, + "Bad nexthop when sending to %s, AFI %u SAFI %u nhlen %d", + peer->host, afi, safi, attr->mp_nexthop_len); break; } diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 2c372124d..2e5b219ef 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -739,6 +739,13 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) else len = sprintf(str_buf + str_pnt, "MM:%u", seqnum); + } else if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_ND) { + uint8_t flags = *++pnt; + + if (flags + & ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG) + len = sprintf(str_buf + str_pnt, + "ND:Router Flag"); } else unk_ecom = 1; } else if (type == ECOMMUNITY_ENCODE_REDIRECT_IP_NH) { diff --git a/bgpd/bgp_errors.c b/bgpd/bgp_errors.c new file mode 100644 index 000000000..50dd001b8 --- /dev/null +++ b/bgpd/bgp_errors.c @@ -0,0 +1,306 @@ +/* + * BGP-specific error messages. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Don Slice + * + * 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 + +#include "lib/ferr.h" +#include "bgp_errors.h" + +/* clang-format off */ +static struct log_ref ferr_bgp_err[] = { + { + .code = BGP_ERR_ATTR_FLAG, + .title = "BGP attribute flag is incorrect", + .description = "BGP attribute flag is set to the wrong value (Optional/Transitive/Partial)", + .suggestion = "Determine the soure of the attribute and determine why the attribute flag has been set incorrectly" + }, + { + .code = BGP_ERR_ATTR_LEN, + .title = "BGP attribute length is incorrect", + .description = "BGP attribute length is incorrect", + .suggestion = "Determine the soure of the attribute and determine why the attribute length has been set incorrectly" + }, + { + .code = BGP_ERR_ATTR_ORIGIN, + .title = "BGP attribute origin value invalid", + .description = "BGP attribute origin value is invalid", + .suggestion = "Determine the soure of the attribute and determine why the origin attribute has been set incorrectly" + }, + { + .code = BGP_ERR_ATTR_MAL_AS_PATH, + .title = "BGP as path is invalid", + .description = "BGP as path has been malformed", + .suggestion = "Determine the soure of the update and determine why the as path has been set incorrectly" + }, + { + .code = BGP_ERR_ATTR_FIRST_AS, + .title = "BGP as path first as is invalid", + .description = "BGP update has invalid first as in as path", + .suggestion = "Determine the soure of the update and determine why the as path first as value has been set incorrectly" + }, + { + .code = BGP_ERR_ATTR_PMSI_TYPE, + .title = "BGP PMSI tunnel attribute type is invalid", + .description = "BGP update has invalid type for PMSI tunnel", + .suggestion = "Determine the soure of the update and determine why the PMSI tunnel attribute type has been set incorrectly" + }, + { + .code = BGP_ERR_ATTR_PMSI_LEN, + .title = "BGP PMSI tunnel attribute length is invalid", + .description = "BGP update has invalid length for PMSI tunnel", + .suggestion = "Determine the soure of the update and determine why the PMSI tunnel attribute length has been set incorrectly" + }, + { + .code = BGP_ERR_PEER_GROUP, + .title = "BGP peergroup operated on in error", + .description = "BGP operating on peer-group instead of peers included", + .suggestion = "Ensure the config doesn't contain peergroups contained within peergroups" + }, + { + .code = BGP_ERR_PEER_DELETE, + .title = "BGP failed to delete peer structure", + .description = "BGP was unable to delete peer structure when address-family removed", + .suggestion = "Determine if all expected peers are removed and restart FRR if not. Most likely a bug" + }, + { + .code = BGP_ERR_TABLE_CHUNK, + .title = "BGP failed to get table chunk memory", + .description = "BGP unable to get chunk memory for table manager", + .suggestion = "Ensure there is adequate memory on the device to support the table requirements" + }, + { + .code = BGP_ERR_MACIP_LEN, + .title = "BGP received MACIP with invalid IP addr len", + .description = "BGP received MACIP with invalid IP addr len from Zebra", + .suggestion = "Verify MACIP entries inserted in Zebra are correct. Most likely a bug" + }, + { + .code = BGP_ERR_LM_ERROR, + .title = "BGP received invalid label manager message", + .description = "BGP received invalid label manager message from label manager", + .suggestion = "Label manager sent invalid essage to BGP for wrong protocol, instance, etc. Most likely a bug" + }, + { + .code = BGP_ERR_JSON_MEM_ERROR, + .title = "BGP unable to allocate memory for JSON output", + .description = "BGP attempted to generate JSON output and was unable to allocate the memory required", + .suggestion = "Ensure that the device has adequate memory to suport the required functions" + }, + { + .code = BGP_ERR_UPDGRP_ATTR_LEN, + .title = "BGP update had attributes too long to send", + .description = "BGP attempted to send an update but the attributes were too long to fit", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_UPDGRP_CREATE, + .title = "BGP update group creation failed", + .description = "BGP attempted to create an update group but was unable to", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_UPDATE_SND, + .title = "BGP error creating update packet", + .description = "BGP attempted to create an update packet but was unable to", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_PKT_OPEN, + .title = "BGP error receiving open packet", + .description = "BGP received an open from a peer that was invalid", + .suggestion = "Determine the sending peer and correct his invalid open packet" + }, + { + .code = BGP_ERR_SND_FAIL, + .title = "BGP error sending to peer", + .description = "BGP attempted to respond to open from a peer and failed", + .suggestion = "BGP attempted to respond to an open and could not sene the packet. Check local IP address for source" + }, + { + .code = BGP_ERR_INVALID_STATUS, + .title = "BGP error receiving from peer", + .description = "BGP received an update from a peer but status was incorrect", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_UPDATE_RCV, + .title = "BGP error receiving update packet", + .description = "BGP received an invalid update packet", + .suggestion = "Determine the source of the update and resolve the invalid update being sent" + }, + { + .code = BGP_ERR_NO_CAP, + .title = "BGP error due to capability not enabled", + .description = "BGP attempted a function that did not have the capability enabled", + .suggestion = "Enable the capability if this functionality is desired" + }, + { + .code = BGP_ERR_NOTIFY_RCV, + .title = "BGP error receiving notify message", + .description = "BGP unable to process notification message", + .suggestion = "BGP notify received while in stopped state. If the problem persists, report for troubleshooting" + }, + { + .code = BGP_ERR_KEEP_RCV, + .title = "BGP error receiving keepalive packet", + .description = "BGP unable to process keepalive packet", + .suggestion = "BGP keepalive received while in stopped state. If the problem persists, report for troubleshooting" + }, + { + .code = BGP_ERR_RFSH_RCV, + .title = "BGP error receiving route refresh message", + .description = "BGP unable to process route refresh message", + .suggestion = "BGP route refresh received while in stopped state. If the problem persists, report for troubleshooting"}, + { + .code = BGP_ERR_CAP_RCV, + .title = "BGP error capability message", + .description = "BGP unable to process received capability", + .suggestion = "BGP capability message received while in stopped state. If the problem persists, report for troubleshooting" + }, + { + .code = BGP_ERR_NH_UPD, + .title = "BGP error with nexthopo update", + .description = "BGP unable to process nexthop update", + .suggestion = "BGP received nexthop update but nexthop is not reachable in this bgp instance. Report for troubleshooting" + }, + { + .code = BGP_ERR_LABEL, + .title = "Failure to apply label", + .description = "BGP attempted to attempted to apply a label but could not", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_MULTIPATH, + .title = "Multipath specified is invalid", + .description = "BGP was started with an invalid ecmp/multipath value", + .suggestion = "Correct the ecmp/multipath value supplied when starting the BGP daemon" + }, + { + .code = BGP_ERR_PKT_PROCESS, + .title = "Failure to process a packet", + .description = "BGP attempted to process a received packet but could not", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_CONNECT, + .title = "Failure to connect to peer", + .description = "BGP attempted to send open to peer but couldn't connect", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_FSM, + .title = "BGP FSM issue", + .description = "BGP neighbor transition problem", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_VNI, + .title = "BGP VNI creation issue", + .description = "BGP could not create a new VNI", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_NO_DFLT, + .title = "BGP default instance missing", + .description = "BGP could not find default instance", + .suggestion = "Define a default instance of BGP since some feature requires it's existence" + }, + { + .code = BGP_ERR_VTEP_INVALID, + .title = "BGP remote VTEP invalid", + .description = "BGP remote VTEP is invalid and cannot be used", + .suggestion = "Correct remote VTEP configuration or resolve the source of the problem" + }, + { + .code = BGP_ERR_ES_INVALID, + .title = "BGP ES route error", + .description = "BGP ES route incorrect, learned both local and remote", + .suggestion = "Correct configuration or addressing so that same not learned both local and remote" + }, + { + .code = BGP_ERR_EVPN_ROUTE_DELETE, + .title = "BGP EVPN route delete error", + .description = "BGP attempted to delete an EVPN route and failed", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_EVPN_FAIL, + .title = "BGP EVPN install/uninstall error", + .description = "BGP attempted to install or uninstall an EVPN prefix and failed", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_EVPN_ROUTE_INVALID, + .title = "BGP EVPN route received with invalid contents", + .description = "BGP received an EVPN route with invalid contents", + .suggestion = "Determine the source of the EVPN route and resolve whatever is causing invalid contents" + }, + { + .code = BGP_ERR_EVPN_ROUTE_CREATE, + .title = "BGP EVPN route create error", + .description = "BGP attempted to create an EVPN route and failed", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_ES_CREATE, + .title = "BGP EVPN ES entry create error", + .description = "BGP attempted to create an EVPN ES entry and failed", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = BGP_ERR_MULTI_INSTANCE, + .title = "BGP config multi-instance issue", + .description = "BGP configuration attempting multiple instances without enabling the feature", + .suggestion = "Correct the configuration so that bgp multiple-instance is enabled if desired" + }, + { + .code = BGP_ERR_EVPN_AS_MISMATCH, + .title = "BGP AS configuration issue", + .description = "BGP configuration attempted for a different AS than currently configured", + .suggestion = "Correct the configuration so that the correct BGP AS number is used" + }, + { + .code = BGP_ERR_EVPN_INSTANCE_MISMATCH, + .title = "BGP EVPN AS and process name mismatch", + .description = "BGP configuration has AS and process name mismatch", + .suggestion = "Correct the configuration so that the BGP AS number and instance name are consistent" + }, + { + .code = BGP_ERR_FLOWSPEC_PACKET, + .title = "BGP Flowspec packet processing error", + .description = "The BGP flowspec subsystem has detected a error in the send or receive of a packet", + .suggestion = "Gather log files from both sides of the peering relationship and open an issue" + }, + { + .code = BGP_ERR_FLOWSPEC_INSTALLATION, + .title = "BGP Flowspec Installation/removal Error", + .description = "The BGP flowspec subsystem has detected that there was a failure for installation/removal/modification of Flowspec from the dataplane", + .suggestion = "Gather log files from the router and open an issue, Restart FRR" + }, + { + .code = END_FERR, + } +}; +/* clang-format on */ + +void bgp_error_init(void) +{ + log_ref_add(ferr_bgp_err); +} diff --git a/bgpd/bgp_errors.h b/bgpd/bgp_errors.h new file mode 100644 index 000000000..be718d99e --- /dev/null +++ b/bgpd/bgp_errors.h @@ -0,0 +1,79 @@ +/* + * BGP-specific error messages. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Don Slice + * + * 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 __BGP_ERRORS_H__ +#define __BGP_ERRORS_H__ + +#include "lib/ferr.h" + +enum bgp_log_refs { + + BGP_ERR_ATTR_FLAG = BGP_FERR_START, + BGP_ERR_ATTR_LEN, + BGP_ERR_ATTR_ORIGIN, + BGP_ERR_ATTR_MAL_AS_PATH, + BGP_ERR_ATTR_FIRST_AS, + BGP_ERR_ATTR_MARTIAN_NH, + BGP_ERR_ATTR_PMSI_TYPE, + BGP_ERR_ATTR_PMSI_LEN, + BGP_ERR_ATTR_NH_SEND_LEN, + BGP_ERR_PEER_GROUP, + BGP_ERR_PEER_DELETE, + BGP_ERR_TABLE_CHUNK, + BGP_ERR_MACIP_LEN, + BGP_ERR_LM_ERROR, + BGP_ERR_JSON_MEM_ERROR, + BGP_ERR_UPDGRP_ATTR_LEN, + BGP_ERR_UPDGRP_CREATE, + BGP_ERR_UPDATE_SND, + BGP_ERR_PKT_OPEN, + BGP_ERR_SND_FAIL, + BGP_ERR_INVALID_STATUS, + BGP_ERR_UPDATE_RCV, + BGP_ERR_NO_CAP, + BGP_ERR_NOTIFY_RCV, + BGP_ERR_KEEP_RCV, + BGP_ERR_RFSH_RCV, + BGP_ERR_CAP_RCV, + BGP_ERR_NH_UPD, + BGP_ERR_LABEL, + BGP_ERR_MULTIPATH, + BGP_ERR_PKT_PROCESS, + BGP_ERR_CONNECT, + BGP_ERR_FSM, + BGP_ERR_VNI, + BGP_ERR_NO_DFLT, + BGP_ERR_VTEP_INVALID, + BGP_ERR_ES_INVALID, + BGP_ERR_EVPN_ROUTE_DELETE, + BGP_ERR_EVPN_FAIL, + BGP_ERR_EVPN_ROUTE_INVALID, + BGP_ERR_EVPN_ROUTE_CREATE, + BGP_ERR_ES_CREATE, + BGP_ERR_MULTI_INSTANCE, + BGP_ERR_EVPN_AS_MISMATCH, + BGP_ERR_EVPN_INSTANCE_MISMATCH, + BGP_ERR_FLOWSPEC_PACKET, + BGP_ERR_FLOWSPEC_INSTALLATION, +}; + +extern void bgp_error_init(void); + +#endif diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 73f225784..142b395a2 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -43,6 +43,7 @@ #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_encap_types.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_aspath.h" #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_nexthop.h" @@ -172,7 +173,8 @@ static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt) bgp_def = bgp_get_default(); if (!bgp_def) { - zlog_err("vrf import rt new - def instance not created yet"); + flog_err(BGP_ERR_NO_DFLT, + "vrf import rt new - def instance not created yet"); return NULL; } @@ -202,7 +204,8 @@ static void vrf_import_rt_free(struct vrf_irt_node *irt) bgp_def = bgp_get_default(); if (!bgp_def) { - zlog_err("vrf import rt free - def instance not created yet"); + flog_err(BGP_ERR_NO_DFLT, + "vrf import rt free - def instance not created yet"); return; } @@ -223,7 +226,9 @@ static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt) bgp_def = bgp_get_default(); if (!bgp_def) { - zlog_err("vrf import rt lookup - def instance not created yet"); + flog_err( + BGP_ERR_NO_DFLT, + "vrf import rt lookup - def instance not created yet"); return NULL; } @@ -619,7 +624,8 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, if (is_evpn_prefix_ipaddr_v4(p)) stream_put_in_addr(s, &p->prefix.imet_addr.ip.ipaddr_v4); else if (is_evpn_prefix_ipaddr_v6(p)) { - zlog_err( + flog_err( + BGP_ERR_VTEP_INVALID, "Bad remote IP when trying to %s remote VTEP for VNI %u", add ? "ADD" : "DEL", vpn->vni); return -1; @@ -1289,11 +1295,12 @@ static int update_evpn_type4_route_entry(struct bgp *bgp, * We shouldn't see the same route from any other vtep. */ if (remote_ri) { - zlog_err( - "%u ERROR: local es route for ESI: %s Vtep %s also learnt from remote", - bgp->vrf_id, - esi_to_str(&evp->prefix.es_addr.esi, buf, sizeof(buf)), - ipaddr2str(&es->originator_ip, buf1, sizeof(buf1))); + flog_err( + BGP_ERR_ES_INVALID, + "%u ERROR: local es route for ESI: %s Vtep %s also learnt from remote", + bgp->vrf_id, + esi_to_str(&evp->prefix.es_addr.esi, buf, sizeof(buf)), + ipaddr2str(&es->originator_ip, buf1, sizeof(buf1))); return -1; } @@ -1376,10 +1383,12 @@ static int update_evpn_type4_route(struct bgp *bgp, &attr, 1, &ri, &route_changed); if (ret != 0) { - zlog_err("%u ERROR: Failed to updated ES route ESI: %s VTEP %s", - bgp->vrf_id, - esi_to_str(&p->prefix.es_addr.esi, buf, sizeof(buf)), - ipaddr2str(&es->originator_ip, buf1, sizeof(buf1))); + flog_err( + BGP_ERR_ES_INVALID, + "%u ERROR: Failed to updated ES route ESI: %s VTEP %s", + bgp->vrf_id, + esi_to_str(&p->prefix.es_addr.esi, buf, sizeof(buf)), + ipaddr2str(&es->originator_ip, buf1, sizeof(buf1))); } assert(ri); @@ -2216,10 +2225,9 @@ static int delete_routes_for_es(struct bgp *bgp, struct evpnes *es) build_evpn_type4_prefix(&p, &es->esi, es->originator_ip.ipaddr_v4); ret = delete_evpn_type4_route(bgp, es, &p); if (ret) { - zlog_err( - "%u failed to delete type-4 route for ESI %s", - bgp->vrf_id, - esi_to_str(&es->esi, buf, sizeof(buf))); + flog_err(BGP_ERR_EVPN_ROUTE_DELETE, + "%u failed to delete type-4 route for ESI %s", + bgp->vrf_id, esi_to_str(&es->esi, buf, sizeof(buf))); } /* Delete all routes from per ES table */ @@ -2876,7 +2884,8 @@ static int install_uninstall_routes_for_es(struct bgp *bgp, bgp, es, evp, ri); if (ret) { - zlog_err( + flog_err( + BGP_ERR_EVPN_FAIL, "Failed to %s EVPN %s route in ESI %s", install ? "install" : "uninstall", @@ -2955,7 +2964,8 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) bgp_vrf, evp, ri); if (ret) { - zlog_err( + flog_err( + BGP_ERR_EVPN_FAIL, "Failed to %s EVPN %s route in VRF %s", install ? "install" : "uninstall", @@ -3028,7 +3038,8 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp, bgp, vpn, evp, ri); if (ret) { - zlog_err( + flog_err( + BGP_ERR_EVPN_FAIL, "%u: Failed to %s EVPN %s route in VNI %u", bgp->vrf_id, install ? "install" @@ -3130,11 +3141,11 @@ static int install_uninstall_route_in_es(struct bgp *bgp, struct evpnes *es, ret = uninstall_evpn_route_entry_in_es(bgp, es, evp, ri); if (ret) { - zlog_err("%u: Failed to %s EVPN %s route in ESI %s", - bgp->vrf_id, install ? "install" : "uninstall", - "ES", - esi_to_str(&evp->prefix.es_addr.esi, buf, - sizeof(buf))); + flog_err( + BGP_ERR_EVPN_FAIL, + "%u: Failed to %s EVPN %s route in ESI %s", bgp->vrf_id, + install ? "install" : "uninstall", "ES", + esi_to_str(&evp->prefix.es_addr.esi, buf, sizeof(buf))); return ret; } return 0; @@ -3173,11 +3184,12 @@ static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi, ri); if (ret) { - zlog_err("%u: Failed to %s prefix %s in VRF %s", - bgp_def->vrf_id, - install ? "install" : "uninstall", - prefix2str(evp, buf, sizeof(buf)), - vrf_id_to_name(bgp_vrf->vrf_id)); + flog_err(BGP_ERR_EVPN_FAIL, + "%u: Failed to %s prefix %s in VRF %s", + bgp_def->vrf_id, + install ? "install" : "uninstall", + prefix2str(evp, buf, sizeof(buf)), + vrf_id_to_name(bgp_vrf->vrf_id)); return ret; } } @@ -3208,12 +3220,14 @@ static int install_uninstall_route_in_vnis(struct bgp *bgp, afi_t afi, ret = uninstall_evpn_route_entry(bgp, vpn, evp, ri); if (ret) { - zlog_err("%u: Failed to %s EVPN %s route in VNI %u", - bgp->vrf_id, install ? "install" : "uninstall", - evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE - ? "MACIP" - : "IMET", - vpn->vni); + flog_err( + BGP_ERR_EVPN_FAIL, + "%u: Failed to %s EVPN %s route in VNI %u", + bgp->vrf_id, install ? "install" : "uninstall", + evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE + ? "MACIP" + : "IMET", + vpn->vni); return ret; } } @@ -3526,14 +3540,7 @@ static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) */ static void update_router_id_vni(struct hash_backet *backet, struct bgp *bgp) { - struct bgpevpn *vpn; - - vpn = (struct bgpevpn *)backet->data; - - if (!vpn) { - zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__); - return; - } + struct bgpevpn *vpn = (struct bgpevpn *)backet->data; /* Skip VNIs with configured RD. */ if (is_rd_configured(vpn)) @@ -3551,14 +3558,7 @@ static void update_router_id_vni(struct hash_backet *backet, struct bgp *bgp) */ static void withdraw_router_id_vni(struct hash_backet *backet, struct bgp *bgp) { - struct bgpevpn *vpn; - - vpn = (struct bgpevpn *)backet->data; - - if (!vpn) { - zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__); - return; - } + struct bgpevpn *vpn = (struct bgpevpn *)backet->data; /* Skip VNIs with configured RD. */ if (is_rd_configured(vpn)) @@ -3592,8 +3592,9 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, */ if (psize != 33 && psize != 37 && psize != 49 && psize != 36 && psize != 40 && psize != 52) { - zlog_err("%u:%s - Rx EVPN Type-2 NLRI with invalid length %d", - peer->bgp->vrf_id, peer->host, psize); + flog_err(BGP_ERR_EVPN_ROUTE_INVALID, + "%u:%s - Rx EVPN Type-2 NLRI with invalid length %d", + peer->bgp->vrf_id, peer->host, psize); return -1; } @@ -3628,7 +3629,8 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, memcpy(&p.prefix.macip_addr.mac.octet, pfx, ETH_ALEN); pfx += ETH_ALEN; } else { - zlog_err( + flog_err( + BGP_ERR_EVPN_ROUTE_INVALID, "%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d", peer->bgp->vrf_id, peer->host, macaddr_len); return -1; @@ -3639,7 +3641,8 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, ipaddr_len = *pfx++; if (ipaddr_len != 0 && ipaddr_len != IPV4_MAX_BITLEN && ipaddr_len != IPV6_MAX_BITLEN) { - zlog_err( + flog_err( + BGP_ERR_EVPN_ROUTE_INVALID, "%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d", peer->bgp->vrf_id, peer->host, ipaddr_len); return -1; @@ -3700,8 +3703,9 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, * IP len (1) and IP (4 or 16). */ if (psize != 17 && psize != 29) { - zlog_err("%u:%s - Rx EVPN Type-3 NLRI with invalid length %d", - peer->bgp->vrf_id, peer->host, psize); + flog_err(BGP_ERR_EVPN_ROUTE_INVALID, + "%u:%s - Rx EVPN Type-3 NLRI with invalid length %d", + peer->bgp->vrf_id, peer->host, psize); return -1; } @@ -3741,7 +3745,8 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, p.prefix.imet_addr.ip.ipa_type = IPADDR_V4; memcpy(&p.prefix.imet_addr.ip.ip.addr, pfx, IPV4_MAX_BYTELEN); } else { - zlog_err( + flog_err( + BGP_ERR_EVPN_ROUTE_INVALID, "%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d", peer->bgp->vrf_id, peer->host, ipaddr_len); return -1; @@ -3777,8 +3782,9 @@ static int process_type4_route(struct peer *peer, afi_t afi, safi_t safi, * RD (8), ESI (10), ip-len (1), ip (4 or 16) */ if (psize != 23 && psize != 35) { - zlog_err("%u:%s - Rx EVPN Type-4 NLRI with invalid length %d", - peer->bgp->vrf_id, peer->host, psize); + flog_err(BGP_ERR_EVPN_ROUTE_INVALID, + "%u:%s - Rx EVPN Type-4 NLRI with invalid length %d", + peer->bgp->vrf_id, peer->host, psize); return -1; } @@ -3798,7 +3804,8 @@ static int process_type4_route(struct peer *peer, afi_t afi, safi_t safi, if (ipaddr_len == IPV4_MAX_BITLEN) { memcpy(&vtep_ip, pfx, IPV4_MAX_BYTELEN); } else { - zlog_err( + flog_err( + BGP_ERR_EVPN_ROUTE_INVALID, "%u:%s - Rx EVPN Type-4 NLRI with unsupported IP address length %d", peer->bgp->vrf_id, peer->host, ipaddr_len); return -1; @@ -3840,8 +3847,9 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, * Note that the IP and GW should both be IPv4 or both IPv6. */ if (psize != 34 && psize != 58) { - zlog_err("%u:%s - Rx EVPN Type-5 NLRI with invalid length %d", - peer->bgp->vrf_id, peer->host, psize); + flog_err(BGP_ERR_EVPN_ROUTE_INVALID, + "%u:%s - Rx EVPN Type-5 NLRI with invalid length %d", + peer->bgp->vrf_id, peer->host, psize); return -1; } @@ -3872,7 +3880,8 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, /* Fetch IP prefix length. */ ippfx_len = *pfx++; if (ippfx_len > IPV6_MAX_BITLEN) { - zlog_err( + flog_err( + BGP_ERR_EVPN_ROUTE_INVALID, "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d", peer->bgp->vrf_id, peer->host, ippfx_len); return -1; @@ -3993,9 +4002,8 @@ static void cleanup_vni_on_disable(struct hash_backet *backet, struct bgp *bgp) */ static void free_vni_entry(struct hash_backet *backet, struct bgp *bgp) { - struct bgpevpn *vpn; + struct bgpevpn *vpn = (struct bgpevpn *)backet->data; - vpn = (struct bgpevpn *)backet->data; delete_all_vni_routes(bgp, vpn); bgp_evpn_free(bgp, vpn); } @@ -4067,11 +4075,6 @@ static void update_autort_vni(struct hash_backet *backet, struct bgp *bgp) { struct bgpevpn *vpn = backet->data; - if (!vpn) { - zlog_warn("%s: VNI hash entry for VNI not found", __PRETTY_FUNCTION__); - return; - } - if (!is_import_rt_configured(vpn)) { if (is_vni_live(vpn)) bgp_evpn_uninstall_routes(bgp, vpn); @@ -4104,7 +4107,8 @@ void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, struct prefix *p, build_type5_prefix_from_ip_prefix(&evp, p); ret = delete_evpn_type5_route(bgp_vrf, &evp); if (ret) { - zlog_err( + flog_err( + BGP_ERR_EVPN_ROUTE_DELETE, "%u failed to delete type-5 route for prefix %s in vrf %s", bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)), vrf_id_to_name(bgp_vrf->vrf_id)); @@ -4150,8 +4154,9 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p, build_type5_prefix_from_ip_prefix(&evp, p); ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr); if (ret) - zlog_err("%u: Failed to create type-5 route for prefix %s", - bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf))); + flog_err(BGP_ERR_EVPN_ROUTE_CREATE, + "%u: Failed to create type-5 route for prefix %s", + bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf))); } /* Inject all prefixes of a particular address-family (currently, IPv4 or @@ -4709,7 +4714,8 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, if (process_type2_route(peer, afi, safi, withdraw ? NULL : attr, pnt, psize, addpath_id)) { - zlog_err( + flog_err( + BGP_ERR_EVPN_FAIL, "%u:%s - Error in processing EVPN type-2 NLRI size %d", peer->bgp->vrf_id, peer->host, psize); return -1; @@ -4720,7 +4726,8 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, if (process_type3_route(peer, afi, safi, withdraw ? NULL : attr, pnt, psize, addpath_id)) { - zlog_err( + flog_err( + BGP_ERR_PKT_PROCESS, "%u:%s - Error in processing EVPN type-3 NLRI size %d", peer->bgp->vrf_id, peer->host, psize); return -1; @@ -4731,7 +4738,8 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, if (process_type4_route(peer, afi, safi, withdraw ? NULL : attr, pnt, psize, addpath_id)) { - zlog_err( + flog_err( + BGP_ERR_PKT_PROCESS, "%u:%s - Error in processing EVPN type-4 NLRI size %d", peer->bgp->vrf_id, peer->host, psize); return -1; @@ -4741,7 +4749,8 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, case BGP_EVPN_IP_PREFIX_ROUTE: if (process_type5_route(peer, afi, safi, attr, pnt, psize, addpath_id, withdraw)) { - zlog_err( + flog_err( + BGP_ERR_PKT_PROCESS, "%u:%s - Error in processing EVPN type-5 NLRI size %d", peer->bgp->vrf_id, peer->host, psize); return -1; @@ -5204,7 +5213,8 @@ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac, char buf[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; - zlog_err( + flog_err( + BGP_ERR_EVPN_ROUTE_CREATE, "%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s (flags: 0x%x)", bgp->vrf_id, vpn->vni, CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) @@ -5221,13 +5231,12 @@ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac, static void link_l2vni_hash_to_l3vni(struct hash_backet *backet, struct bgp *bgp_vrf) { - struct bgpevpn *vpn = NULL; + struct bgpevpn *vpn = (struct bgpevpn *)backet->data; struct bgp *bgp_def = NULL; bgp_def = bgp_get_default(); assert(bgp_def); - vpn = (struct bgpevpn *)backet->data; if (vpn->tenant_vrf_id == bgp_vrf->vrf_id) bgpevpn_link_to_l3vni(vpn); } @@ -5246,7 +5255,8 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, */ bgp_def = bgp_get_default(); if (!bgp_def) { - zlog_err( + flog_err( + BGP_ERR_NO_DFLT, "Cannot process L3VNI %u ADD - default BGP instance not yet created", l3vni); return -1; @@ -5263,13 +5273,16 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, BGP_INSTANCE_TYPE_VRF); switch (ret) { case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET: - zlog_err("'bgp multiple-instance' not present\n"); + flog_err(BGP_ERR_MULTI_INSTANCE, + "'bgp multiple-instance' not present\n"); return -1; case BGP_ERR_AS_MISMATCH: - zlog_err("BGP is already running; AS is %u\n", as); + flog_err(BGP_ERR_EVPN_AS_MISMATCH, + "BGP is already running; AS is %u\n", as); return -1; case BGP_ERR_INSTANCE_MISMATCH: - zlog_err("BGP instance name and AS number mismatch\n"); + flog_err(BGP_ERR_EVPN_INSTANCE_MISMATCH, + "BGP instance name and AS number mismatch\n"); return -1; } @@ -5330,7 +5343,8 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) bgp_vrf = bgp_lookup_by_vrf_id(vrf_id); if (!bgp_vrf) { - zlog_err( + flog_err( + BGP_ERR_NO_DFLT, "Cannot process L3VNI %u Del - Could not find BGP instance", l3vni); return -1; @@ -5338,7 +5352,8 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) bgp_def = bgp_get_default(); if (!bgp_def) { - zlog_err( + flog_err( + BGP_ERR_NO_DFLT, "Cannot process L3VNI %u Del - Could not find default BGP instance", l3vni); return -1; @@ -5468,7 +5483,8 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, if (!vpn) { vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id); if (!vpn) { - zlog_err( + flog_err( + BGP_ERR_VNI, "%u: Failed to allocate VNI entry for VNI %u - at Add", bgp->vrf_id, vni); return -1; @@ -5491,8 +5507,9 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, /* Create EVPN type-3 route and schedule for processing. */ build_evpn_type3_prefix(&p, vpn->originator_ip); if (update_evpn_route(bgp, vpn, &p, 0)) { - zlog_err("%u: Type3 route creation failure for VNI %u", - bgp->vrf_id, vni); + flog_err(BGP_ERR_EVPN_ROUTE_CREATE, + "%u: Type3 route creation failure for VNI %u", + bgp->vrf_id, vni); return -1; } @@ -5520,7 +5537,8 @@ int bgp_evpn_local_es_del(struct bgp *bgp, struct evpnes *es = NULL; if (!bgp->esihash) { - zlog_err("%u: ESI hash not yet created", bgp->vrf_id); + flog_err(BGP_ERR_ES_CREATE, "%u: ESI hash not yet created", + bgp->vrf_id); return -1; } @@ -5556,7 +5574,8 @@ int bgp_evpn_local_es_add(struct bgp *bgp, struct prefix_evpn p; if (!bgp->esihash) { - zlog_err("%u: ESI hash not yet created", bgp->vrf_id); + flog_err(BGP_ERR_ES_CREATE, "%u: ESI hash not yet created", + bgp->vrf_id); return -1; } @@ -5565,7 +5584,8 @@ int bgp_evpn_local_es_add(struct bgp *bgp, if (!es) { es = bgp_evpn_es_new(bgp, esi, originator_ip); if (!es) { - zlog_err( + flog_err( + BGP_ERR_ES_CREATE, "%u: Failed to allocate ES entry for ESI %s - at Local ES Add", bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf))); return -1; @@ -5576,8 +5596,9 @@ int bgp_evpn_local_es_add(struct bgp *bgp, build_evpn_type4_prefix(&p, esi, originator_ip->ipaddr_v4); if (update_evpn_type4_route(bgp, es, &p)) { - zlog_err("%u: Type4 route creation failure for ESI %s", - bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf))); + flog_err(BGP_ERR_EVPN_ROUTE_CREATE, + "%u: Type4 route creation failure for ESI %s", + bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf))); return -1; } diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index b45c1a99d..3828ce216 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -35,6 +35,7 @@ #include "bgpd/bgp_evpn_private.h" #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_vty.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_ecommunity.h" #define SHOW_DISPLAY_STANDARD 0 @@ -1892,7 +1893,8 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni) */ vpn = bgp_evpn_new(bgp, vni, bgp->router_id, 0); if (!vpn) { - zlog_err( + flog_err( + BGP_ERR_VNI, "%u: Failed to allocate VNI entry for VNI %u - at Config", bgp->vrf_id, vni); return NULL; diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c index 2d336fa6d..6695596c6 100644 --- a/bgpd/bgp_flowspec.c +++ b/bgpd/bgp_flowspec.c @@ -22,6 +22,7 @@ #include #include "prefix.h" +#include "lib_errors.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_route.h" @@ -30,6 +31,7 @@ #include "bgpd/bgp_flowspec_private.h" #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" static int bgp_fs_nlri_validate(uint8_t *nlri_content, uint32_t len) { @@ -102,13 +104,15 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, safi = packet->safi; if (afi == AFI_IP6) { - zlog_err("BGP flowspec IPv6 not supported"); + flog_err(LIB_ERR_DEVELOPMENT, + "BGP flowspec IPv6 not supported"); return -1; } if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT) { - zlog_err("BGP flowspec nlri length maximum reached (%u)", - packet->length); + flog_err(BGP_ERR_FLOWSPEC_PACKET, + "BGP flowspec nlri length maximum reached (%u)", + packet->length); return -1; } @@ -124,12 +128,14 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, /* When packet overflow occur return immediately. */ if (pnt + psize > lim) { - zlog_err("Flowspec NLRI length inconsistent ( size %u seen)", - psize); + flog_err(BGP_ERR_FLOWSPEC_PACKET, + "Flowspec NLRI length inconsistent ( size %u seen)", + psize); return -1; } if (bgp_fs_nlri_validate(pnt, psize) < 0) { - zlog_err("Bad flowspec format or NLRI options not supported"); + flog_err(BGP_ERR_FLOWSPEC_PACKET, + "Bad flowspec format or NLRI options not supported"); return -1; } p.family = AF_FLOWSPEC; @@ -182,8 +188,9 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0, NULL); if (ret) { - zlog_err("Flowspec NLRI failed to be %s.", - attr ? "added" : "withdrawn"); + flog_err(BGP_ERR_FLOWSPEC_INSTALLATION, + "Flowspec NLRI failed to be %s.", + attr ? "added" : "withdrawn"); return -1; } } diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c index 6408337a5..9f92a3c3a 100644 --- a/bgpd/bgp_flowspec_util.c +++ b/bgpd/bgp_flowspec_util.c @@ -21,11 +21,13 @@ #include "zebra.h" #include "prefix.h" +#include "lib_errors.h" #include "bgp_table.h" #include "bgp_flowspec_util.h" #include "bgp_flowspec_private.h" #include "bgp_pbr.h" +#include "bgp_errors.h" static void hex2bin(uint8_t *hex, int *bin) { @@ -66,8 +68,9 @@ static int bgp_flowspec_call_non_opaque_decode(uint8_t *nlri_content, int len, len, mval, error); if (*error < 0) - zlog_err("%s: flowspec_op_decode error %d", - __func__, *error); + flog_err(BGP_ERR_FLOWSPEC_PACKET, + "%s: flowspec_op_decode error %d", + __func__, *error); else *match_num = *error; return ret; @@ -444,8 +447,9 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len, len - offset, prefix, &error); if (error < 0) - zlog_err("%s: flowspec_ip_address error %d", - __func__, error); + flog_err(BGP_ERR_FLOWSPEC_PACKET, + "%s: flowspec_ip_address error %d", + __func__, error); else bpem->match_bitmask |= bitmask; offset += ret; @@ -538,8 +542,9 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len, len - offset, &bpem->tcpflags, &error); if (error < 0) - zlog_err("%s: flowspec_tcpflags_decode error %d", - __func__, error); + flog_err(BGP_ERR_FLOWSPEC_PACKET, + "%s: flowspec_tcpflags_decode error %d", + __func__, error); else bpem->match_tcpflags_num = error; /* contains the number of slots used */ @@ -552,14 +557,16 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len, len - offset, &bpem->fragment, &error); if (error < 0) - zlog_err("%s: flowspec_fragment_type_decode error %d", - __func__, error); + flog_err(BGP_ERR_FLOWSPEC_PACKET, + "%s: flowspec_fragment_type_decode error %d", + __func__, error); else bpem->match_fragment_num = error; offset += ret; break; default: - zlog_err("%s: unknown type %d\n", __func__, type); + flog_err(LIB_ERR_DEVELOPMENT, "%s: unknown type %d\n", + __func__, type); } } return error; diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 2fd63531d..14d692ebf 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -34,11 +34,13 @@ #include "queue.h" #include "filter.h" #include "command.h" +#include "lib_errors.h" #include "lib/json.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_packet.h" #include "bgpd/bgp_network.h" @@ -164,7 +166,8 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) * runs in our pthread. */ if (peer->curr) { - zlog_err( + flog_err( + BGP_ERR_PKT_PROCESS, "[%s] Dropping pending packet on connection transfer:", peer->host); uint16_t type = stream_getc_from(peer->curr, @@ -242,7 +245,8 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) } if (bgp_getsockname(peer) < 0) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)", (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER) ? "accept" @@ -254,8 +258,10 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) } if (from_peer->status > Active) { if (bgp_getsockname(from_peer) < 0) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)", + (CHECK_FLAG(from_peer->sflags, PEER_STATUS_ACCEPT_PEER) ? "accept" @@ -1280,15 +1286,17 @@ static int bgp_connect_check(struct thread *thread) static int bgp_connect_success(struct peer *peer) { if (peer->fd < 0) { - zlog_err("bgp_connect_success peer's fd is negative value %d", - peer->fd); + flog_err(BGP_ERR_CONNECT, + "bgp_connect_success peer's fd is negative value %d", + peer->fd); bgp_stop(peer); return -1; } if (bgp_getsockname(peer) < 0) { - zlog_err("%s: bgp_getsockname(): failed for peer %s, fd %d", - __FUNCTION__, peer->host, peer->fd); + flog_err_sys(LIB_ERR_SOCKET, + "%s: bgp_getsockname(): failed for peer %s, fd %d", + __FUNCTION__, peer->host, peer->fd); bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0); /* internal error */ bgp_writes_on(peer); @@ -1346,10 +1354,10 @@ int bgp_start(struct peer *peer) if (BGP_PEER_START_SUPPRESSED(peer)) { if (bgp_debug_neighbor_events(peer)) - zlog_err( - "%s [FSM] Trying to start suppressed peer" - " - this is never supposed to happen!", - peer->host); + flog_err(BGP_ERR_FSM, + "%s [FSM] Trying to start suppressed peer" + " - this is never supposed to happen!", + peer->host); return -1; } @@ -1381,7 +1389,8 @@ int bgp_start(struct peer *peer) if (peer->bgp->vrf_id == VRF_UNKNOWN) { if (bgp_debug_neighbor_events(peer)) - zlog_err( + flog_err( + BGP_ERR_FSM, "%s [FSM] In a VRF that is not initialised yet", peer->host); return -1; @@ -1435,8 +1444,9 @@ int bgp_start(struct peer *peer) "%s [FSM] Non blocking connect waiting result, fd %d", peer->host, peer->fd); if (peer->fd < 0) { - zlog_err("bgp_start peer's fd is negative value %d", - peer->fd); + flog_err(BGP_ERR_FSM, + "bgp_start peer's fd is negative value %d", + peer->fd); return -1; } /* @@ -1482,8 +1492,9 @@ static int bgp_fsm_open(struct peer *peer) peer and change to Idle status. */ static int bgp_fsm_event_error(struct peer *peer) { - zlog_err("%s [FSM] unexpected packet received in state %s", peer->host, - lookup_msg(bgp_status_msg, peer->status, NULL)); + flog_err(BGP_ERR_FSM, + "%s [FSM] unexpected packet received in state %s", peer->host, + lookup_msg(bgp_status_msg, peer->status, NULL)); return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR, 0); } @@ -1515,7 +1526,7 @@ static int bgp_establish(struct peer *peer) other = peer->doppelganger; peer = peer_xfer_conn(peer); if (!peer) { - zlog_err("%%Neighbor failed in xfer_conn"); + flog_err(BGP_ERR_CONNECT, "%%Neighbor failed in xfer_conn"); return -1; } @@ -1674,7 +1685,8 @@ static int bgp_fsm_update(struct peer *peer) /* This is empty event. */ static int bgp_ignore(struct peer *peer) { - zlog_err( + flog_err( + BGP_ERR_FSM, "%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d", peer->host, bgp_event_str[peer->cur_event], lookup_msg(bgp_status_msg, peer->status, NULL), @@ -1686,7 +1698,8 @@ static int bgp_ignore(struct peer *peer) /* This is to handle unexpected events.. */ static int bgp_fsm_exeption(struct peer *peer) { - zlog_err( + flog_err( + BGP_ERR_FSM, "%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d", peer->host, bgp_event_str[peer->cur_event], lookup_msg(bgp_status_msg, peer->status, NULL), @@ -1960,7 +1973,8 @@ int bgp_event_update(struct peer *peer, int event) * code. */ if (!dyn_nbr && !passive_conn && peer->bgp) { - zlog_err( + flog_err( + BGP_ERR_FSM, "%s [FSM] Failure handling event %s in state %s, " "prior events %s, %s, fd %d", peer->host, bgp_event_str[peer->cur_event], diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c index c8d5b1daa..311f98001 100644 --- a/bgpd/bgp_io.c +++ b/bgpd/bgp_io.c @@ -35,6 +35,7 @@ #include "bgpd/bgp_io.h" #include "bgpd/bgp_debug.h" // for bgp_debug_neighbor_events, bgp_type_str +#include "bgpd/bgp_errors.h" // for expanded error reference information #include "bgpd/bgp_fsm.h" // for BGP_EVENT_ADD, bgp_event #include "bgpd/bgp_packet.h" // for bgp_notify_send_with_data, bgp_notify... #include "bgpd/bgpd.h" // for peer, BGP_MARKER_SIZE, bgp_master, bm @@ -401,8 +402,9 @@ static uint16_t bgp_read(struct peer *peer) SET_FLAG(status, BGP_IO_TRANS_ERR); /* Fatal error; tear down session */ } else if (nbytes < 0) { - zlog_err("%s [Error] bgp_read_packet error: %s", peer->host, - safe_strerror(errno)); + flog_err(BGP_ERR_UPDATE_RCV, + "%s [Error] bgp_read_packet error: %s", peer->host, + safe_strerror(errno)); if (peer->status == Established) { if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)) { diff --git a/bgpd/bgp_keepalives.c b/bgpd/bgp_keepalives.c index 3216683a5..f81836cc8 100644 --- a/bgpd/bgp_keepalives.c +++ b/bgpd/bgp_keepalives.c @@ -239,10 +239,10 @@ void bgp_keepalives_on(struct peer *peer) /* placeholder bucket data to use for fast key lookups */ static struct pkat holder = {0}; - if (!peerhash_mtx) { - zlog_warn("%s: call bgp_keepalives_init() first", __func__); - return; - } + /* + * We need to ensure that bgp_keepalives_init was called first + */ + assert(peerhash_mtx); pthread_mutex_lock(peerhash_mtx); { @@ -269,10 +269,10 @@ void bgp_keepalives_off(struct peer *peer) /* placeholder bucket data to use for fast key lookups */ static struct pkat holder = {0}; - if (!peerhash_mtx) { - zlog_warn("%s: call bgp_keepalives_init() first", __func__); - return; - } + /* + * We need to ensure that bgp_keepalives_init was called first + */ + assert(peerhash_mtx); pthread_mutex_lock(peerhash_mtx); { diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index 8a051b7ff..633e58933 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -38,6 +38,7 @@ #include "bgpd/bgp_label.h" #include "bgpd/bgp_packet.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" extern struct zclient *zclient; @@ -244,7 +245,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, /* sanity check against packet data */ if ((pnt + psize) > lim) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)", peer->host, prefixlen, (uint)(lim - pnt)); return -1; @@ -256,10 +258,10 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, /* There needs to be at least one label */ if (prefixlen < 24) { - zlog_err( - "%s [Error] Update packet error" - " (wrong label length %d)", - peer->host, prefixlen); + flog_err(BGP_ERR_UPDATE_RCV, + "%s [Error] Update packet error" + " (wrong label length %d)", + peer->host, prefixlen); bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_INVAL_NETWORK); return -1; @@ -284,7 +286,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, * be logged locally, and the prefix SHOULD be * ignored. */ - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring", peer->host, inet_ntoa(p.u.prefix4)); continue; @@ -296,7 +299,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) { char buf[BUFSIZ]; - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring", peer->host, inet_ntop(AF_INET6, &p.u.prefix6, buf, @@ -308,7 +312,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) { char buf[BUFSIZ]; - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s: IPv6 unicast NLRI is multicast address %s, ignoring", peer->host, inet_ntop(AF_INET6, &p.u.prefix6, buf, @@ -331,7 +336,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, /* Packet length consistency check. */ if (pnt != lim) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error / L-U (%zu data remaining after parsing)", peer->host, lim - pnt); return -1; diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c index e052d6061..8d15649ea 100644 --- a/bgpd/bgp_labelpool.c +++ b/bgpd/bgp_labelpool.c @@ -34,6 +34,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_labelpool.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" /* * Definitions and external declarations. @@ -126,7 +127,8 @@ static wq_item_status lp_cbq_docallback(struct work_queue *wq, void *data) if (lcbq->label == MPLS_LABEL_NONE) { /* shouldn't happen */ - zlog_err("%s: error: label==MPLS_LABEL_NONE", __func__); + flog_err(BGP_ERR_LABEL, "%s: error: label==MPLS_LABEL_NONE", + __func__); return WQ_SUCCESS; } @@ -336,8 +338,9 @@ void bgp_lp_get( if (rc) { /* shouldn't happen */ - zlog_err("%s: can't insert new LCB into ledger list", - __func__); + flog_err(BGP_ERR_LABEL, + "%s: can't insert new LCB into ledger list", + __func__); XFREE(MTYPE_BGP_LABEL_CB, lcb); return; } @@ -424,8 +427,9 @@ void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last) struct lp_fifo *lf; if (last < first) { - zlog_err("%s: zebra label chunk invalid: first=%u, last=%u", - __func__, first, last); + flog_err(BGP_ERR_LABEL, + "%s: zebra label chunk invalid: first=%u, last=%u", + __func__, first, last); return; } diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 2327e262a..8eb1c9e25 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -54,11 +54,13 @@ #include "bgpd/bgp_regex.h" #include "bgpd/bgp_clist.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_filter.h" #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_packet.h" #include "bgpd/bgp_keepalives.h" #include "bgpd/bgp_network.h" +#include "bgpd/bgp_errors.h" #ifdef ENABLE_BGP_VNC #include "bgpd/rfapi/rfapi_backend.h" @@ -384,7 +386,8 @@ int main(int argc, char **argv) multipath_num = atoi(optarg); if (multipath_num > MULTIPATH_NUM || multipath_num <= 0) { - zlog_err( + flog_err( + BGP_ERR_MULTIPATH, "Multipath Number specified must be less than %d and greater than 0", MULTIPATH_NUM); return 1; @@ -417,6 +420,7 @@ int main(int argc, char **argv) if (no_fib_flag) bgp_option_set(BGP_OPT_NO_FIB); + bgp_error_init(); /* Initializations. */ bgp_vrf_init(); diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index f72104dd3..c2cb20b06 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -33,6 +33,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_table.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_attr.h" @@ -150,7 +151,8 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, psize = PSIZE(prefixlen); if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)", peer->host, prefixlen); return -1; @@ -158,7 +160,8 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, /* sanity check against packet data */ if ((pnt + psize) > lim) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)", peer->host, prefixlen, (uint)(lim - pnt)); return -1; @@ -166,7 +169,8 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, /* sanity check against storage for the IP address portion */ if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)", peer->host, prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8, @@ -176,7 +180,8 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, /* Sanity check against max bitlen of the address family */ if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)", peer->host, prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8, @@ -213,7 +218,8 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, #endif default: - zlog_err("Unknown RD type %d", type); + flog_err(BGP_ERR_UPDATE_RCV, "Unknown RD type %d", + type); break; /* just report */ } @@ -235,7 +241,8 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, } /* Packet length consistency check. */ if (pnt != lim) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error / VPN (%zu data remaining after parsing)", peer->host, lim - pnt); return -1; @@ -359,8 +366,10 @@ int vpn_leak_label_callback( return 0; } /* Shouldn't happen: different label allocation */ - zlog_err("%s: %s had label %u but got new assignment %u", - __func__, vp->bgp->name_pretty, vp->tovpn_label, label); + flog_err(BGP_ERR_LABEL, + "%s: %s had label %u but got new assignment %u", + __func__, vp->bgp->name_pretty, vp->tovpn_label, + label); /* use new one */ } diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 476b64e75..0664fdfd1 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -35,12 +35,14 @@ #include "hash.h" #include "filter.h" #include "ns.h" +#include "lib_errors.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_open.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_network.h" extern struct zebra_privs_t bgpd_privs; @@ -95,15 +97,9 @@ static int bgp_md5_set_connect(int socket, union sockunion *su, int ret = -1; #if HAVE_DECL_TCP_MD5SIG - if (bgpd_privs.change(ZPRIVS_RAISE)) { - zlog_err("%s: could not raise privs", __func__); - return ret; + frr_elevate_privs(&bgpd_privs) { + ret = bgp_md5_set_socket(socket, su, password); } - - ret = bgp_md5_set_socket(socket, su, password); - - if (bgpd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs", __func__); #endif /* HAVE_TCP_MD5SIG */ return ret; @@ -115,25 +111,18 @@ static int bgp_md5_set_password(struct peer *peer, const char *password) int ret = 0; struct bgp_listener *listener; - if (bgpd_privs.change(ZPRIVS_RAISE)) { - zlog_err("%s: could not raise privs", __func__); - return -1; - } - + frr_elevate_privs(&bgpd_privs) { /* Set or unset the password on the listen socket(s). Outbound - * connections - * are taken care of in bgp_connect() below. + * connections are taken care of in bgp_connect() below. */ - for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener)) - if (listener->su.sa.sa_family == peer->su.sa.sa_family) { - ret = bgp_md5_set_socket(listener->fd, &peer->su, - password); - break; - } - - if (bgpd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs", __func__); - + for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener)) + if (listener->su.sa.sa_family + == peer->su.sa.sa_family) { + ret = bgp_md5_set_socket(listener->fd, + &peer->su, password); + break; + } + } return ret; } @@ -158,10 +147,12 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock) if (!peer->gtsm_hops && (peer_sort(peer) == BGP_PEER_EBGP)) { ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, peer->ttl); if (ret) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d", - __func__, inet_ntop(AF_INET, &peer->remote_id, - buf, sizeof(buf)), + __func__, + inet_ntop(AF_INET, &peer->remote_id, buf, + sizeof(buf)), errno); return ret; } @@ -172,20 +163,24 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock) */ ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, MAXTTL); if (ret) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d", - __func__, inet_ntop(AF_INET, &peer->remote_id, - buf, sizeof(buf)), + __func__, + inet_ntop(AF_INET, &peer->remote_id, buf, + sizeof(buf)), errno); return ret; } ret = sockopt_minttl(peer->su.sa.sa_family, bgp_sock, MAXTTL + 1 - peer->gtsm_hops); if (ret) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d", - __func__, inet_ntop(AF_INET, &peer->remote_id, - buf, sizeof(buf)), + __func__, + inet_ntop(AF_INET, &peer->remote_id, buf, + sizeof(buf)), errno); return ret; } @@ -226,8 +221,10 @@ static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst) rc = getsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len); if (rc != 0) { #if defined(HAVE_CUMULUS) - zlog_err("[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d", - safe_strerror(errno), sock); + flog_err( + LIB_ERR_SOCKET, + "[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d", + safe_strerror(errno), sock); return -1; #endif } @@ -282,7 +279,8 @@ static int bgp_accept(struct thread *thread) /* Register accept thread. */ accept_sock = THREAD_FD(thread); if (accept_sock < 0) { - zlog_err("accept_sock is nevative value %d", accept_sock); + flog_err_sys(LIB_ERR_SOCKET, "accept_sock is nevative value %d", + accept_sock); return -1; } listener->thread = NULL; @@ -293,8 +291,9 @@ static int bgp_accept(struct thread *thread) /* Accept client connection. */ bgp_sock = sockunion_accept(accept_sock, &su); if (bgp_sock < 0) { - zlog_err("[Error] BGP socket accept failed (%s)", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "[Error] BGP socket accept failed (%s)", + safe_strerror(errno)); return -1; } set_nonblocking(bgp_sock); @@ -543,13 +542,11 @@ int bgp_connect(struct peer *peer) zlog_debug("Peer address not learnt: Returning from connect"); return 0; } - if (bgpd_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); + frr_elevate_privs(&bgpd_privs) { /* Make socket for the peer. */ - peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id, - bgp_get_bound_name(peer)); - if (bgpd_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id, + bgp_get_bound_name(peer)); + } if (peer->fd < 0) return -1; @@ -568,14 +565,14 @@ int bgp_connect(struct peer *peer) peer->host, safe_strerror(errno)); #ifdef IPTOS_PREC_INTERNETCONTROL - if (bgpd_privs.change(ZPRIVS_RAISE)) - zlog_err("%s: could not raise privs", __func__); - if (sockunion_family(&peer->su) == AF_INET) - setsockopt_ipv4_tos(peer->fd, IPTOS_PREC_INTERNETCONTROL); - else if (sockunion_family(&peer->su) == AF_INET6) - setsockopt_ipv6_tclass(peer->fd, IPTOS_PREC_INTERNETCONTROL); - if (bgpd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs", __func__); + frr_elevate_privs(&bgpd_privs) { + if (sockunion_family(&peer->su) == AF_INET) + setsockopt_ipv4_tos(peer->fd, + IPTOS_PREC_INTERNETCONTROL); + else if (sockunion_family(&peer->su) == AF_INET6) + setsockopt_ipv6_tclass(peer->fd, + IPTOS_PREC_INTERNETCONTROL); + } #endif if (peer->password) @@ -623,7 +620,8 @@ int bgp_getsockname(struct peer *peer) if (bgp_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop, peer)) { #if defined(HAVE_CUMULUS) - zlog_err( + flog_err( + BGP_ERR_NH_UPD, "%s: nexthop_set failed, resetting connection - intf %p", peer->host, peer->nexthop.ifp); return -1; @@ -642,31 +640,31 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, sockopt_reuseaddr(sock); sockopt_reuseport(sock); - if (bgpd_privs.change(ZPRIVS_RAISE)) - zlog_err("%s: could not raise privs", __func__); + frr_elevate_privs(&bgpd_privs) { #ifdef IPTOS_PREC_INTERNETCONTROL - if (sa->sa_family == AF_INET) - setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL); - else if (sa->sa_family == AF_INET6) - setsockopt_ipv6_tclass(sock, IPTOS_PREC_INTERNETCONTROL); + if (sa->sa_family == AF_INET) + setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL); + else if (sa->sa_family == AF_INET6) + setsockopt_ipv6_tclass(sock, + IPTOS_PREC_INTERNETCONTROL); #endif - sockopt_v6only(sa->sa_family, sock); + sockopt_v6only(sa->sa_family, sock); - ret = bind(sock, sa, salen); - en = errno; - if (bgpd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs", __func__); + ret = bind(sock, sa, salen); + en = errno; + } if (ret < 0) { - zlog_err("bind: %s", safe_strerror(en)); + flog_err_sys(LIB_ERR_SOCKET, "bind: %s", safe_strerror(en)); return ret; } ret = listen(sock, SOMAXCONN); if (ret < 0) { - zlog_err("listen: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "listen: %s", + safe_strerror(errno)); return ret; } @@ -702,14 +700,13 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address) snprintf(port_str, sizeof(port_str), "%d", port); port_str[sizeof(port_str) - 1] = '\0'; - if (bgpd_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - ret = vrf_getaddrinfo(address, port_str, &req, &ainfo_save, - bgp->vrf_id); - if (bgpd_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&bgpd_privs) { + ret = vrf_getaddrinfo(address, port_str, &req, &ainfo_save, + bgp->vrf_id); + } if (ret != 0) { - zlog_err("getaddrinfo: %s", gai_strerror(ret)); + flog_err_sys(LIB_ERR_SOCKET, "getaddrinfo: %s", + gai_strerror(ret)); return -1; } @@ -720,16 +717,17 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address) if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6) continue; - if (bgpd_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - sock = vrf_socket(ainfo->ai_family, ainfo->ai_socktype, - ainfo->ai_protocol, bgp->vrf_id, - (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ? - bgp->name : NULL)); - if (bgpd_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&bgpd_privs) { + sock = vrf_socket(ainfo->ai_family, + ainfo->ai_socktype, + ainfo->ai_protocol, bgp->vrf_id, + (bgp->inst_type + == BGP_INSTANCE_TYPE_VRF + ? bgp->name : NULL)); + } if (sock < 0) { - zlog_err("socket: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "socket: %s", + safe_strerror(errno)); continue; } @@ -746,10 +744,12 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address) } freeaddrinfo(ainfo_save); if (count == 0 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "%s: no usable addresses please check other programs usage of specified port %d", __func__, port); - zlog_err("%s: Program cannot continue", __func__); + flog_err_sys(LIB_ERR_SOCKET, "%s: Program cannot continue", + __func__); exit(-1); } diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 8b6ff3fa2..0c0c07995 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -38,6 +38,7 @@ #include "bgpd/bgp_attr.h" #include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_nht.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_zebra.h" @@ -343,7 +344,8 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) bgp = bgp_lookup_by_vrf_id(vrf_id); if (!bgp) { - zlog_err( + flog_err( + BGP_ERR_NH_UPD, "parse nexthop update: instance not found for vrf_id %u", vrf_id); return; diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index da90bbd67..7fbc03024 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -34,6 +34,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_packet.h" #include "bgpd/bgp_open.h" @@ -520,8 +521,9 @@ static as_t bgp_capability_as4(struct peer *peer, struct capability_header *hdr) SET_FLAG(peer->cap, PEER_CAP_AS4_RCV); if (hdr->length != CAPABILITY_CODE_AS4_LEN) { - zlog_err("%s AS4 capability has incorrect data length %d", - peer->host, hdr->length); + flog_err(BGP_ERR_PKT_OPEN, + "%s AS4 capability has incorrect data length %d", + peer->host, hdr->length); return 0; } @@ -1184,10 +1186,10 @@ int bgp_open_option_parse(struct peer *peer, uint8_t length, int *mp_capability) && !peer->afc_nego[AFI_IP6][SAFI_ENCAP] && !peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC] && !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) { - zlog_err( - "%s [Error] Configured AFI/SAFIs do not " - "overlap with received MP capabilities", - peer->host); + flog_err(BGP_ERR_PKT_OPEN, + "%s [Error] Configured AFI/SAFIs do not " + "overlap with received MP capabilities", + peer->host); if (error != error_data) bgp_notify_send_with_data( diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 446dc5ac1..bb474b9e2 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -36,12 +36,14 @@ #include "plist.h" #include "queue.h" #include "filter.h" +#include "lib_errors.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" #include "bgpd/bgp_dump.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_packet.h" @@ -1089,8 +1091,9 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) /* Just in case we have a silly peer who sends AS4 capability set to 0 */ if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) && !as4) { - zlog_err("%s bad OPEN, got AS4 capability, but AS4 set to 0", - peer->host); + flog_err(BGP_ERR_PKT_OPEN, + "%s bad OPEN, got AS4 capability, but AS4 set to 0", + peer->host); bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_PEER_AS, notify_data_remote_as4, 4); @@ -1103,7 +1106,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) * BGP_AS_TRANS, for some unknown reason. */ if (as4 == BGP_AS_TRANS) { - zlog_err( + flog_err( + BGP_ERR_PKT_OPEN, "%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed", peer->host); bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, @@ -1132,7 +1136,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) && as4 != remote_as) { /* raise error, log this, close session */ - zlog_err( + flog_err( + BGP_ERR_PKT_OPEN, "%s bad OPEN, got AS4 capability, but remote_as %u" " mismatch with 16bit 'myasn' %u in open", peer->host, as4, remote_as); @@ -1299,8 +1304,9 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) /* Get sockname. */ if ((ret = bgp_getsockname(peer)) < 0) { - zlog_err("%s: bgp_getsockname() failed for peer: %s", - __FUNCTION__, peer->host); + flog_err_sys(LIB_ERR_SOCKET, + "%s: bgp_getsockname() failed for peer: %s", + __FUNCTION__, peer->host); return BGP_Stop; } @@ -1313,7 +1319,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) || peer->afc_nego[AFI_IP][SAFI_ENCAP]) { if (!peer->nexthop.v4.s_addr) { #if defined(HAVE_CUMULUS) - zlog_err( + flog_err( + BGP_ERR_SND_FAIL, "%s: No local IPv4 addr resetting connection, fd %d", peer->host, peer->fd); bgp_notify_send(peer, BGP_NOTIFY_CEASE, @@ -1329,7 +1336,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) || peer->afc_nego[AFI_IP6][SAFI_ENCAP]) { if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global)) { #if defined(HAVE_CUMULUS) - zlog_err( + flog_err( + BGP_ERR_SND_FAIL, "%s: No local IPv6 addr resetting connection, fd %d", peer->host, peer->fd); bgp_notify_send(peer, BGP_NOTIFY_CEASE, @@ -1391,9 +1399,10 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) /* Status must be Established. */ if (peer->status != Established) { - zlog_err("%s [FSM] Update packet received under status %s", - peer->host, - lookup_msg(bgp_status_msg, peer->status, NULL)); + flog_err(BGP_ERR_INVALID_STATUS, + "%s [FSM] Update packet received under status %s", + peer->host, + lookup_msg(bgp_status_msg, peer->status, NULL)); bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0); return BGP_Stop; } @@ -1414,10 +1423,10 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) Attribute Length + 23 exceeds the message Length), then the Error Subcode is set to Malformed Attribute List. */ if (stream_pnt(s) + 2 > end) { - zlog_err( - "%s [Error] Update packet error" - " (packet length is short for unfeasible length)", - peer->host); + flog_err(BGP_ERR_UPDATE_RCV, + "%s [Error] Update packet error" + " (packet length is short for unfeasible length)", + peer->host); bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_ATTR); return BGP_Stop; @@ -1428,10 +1437,10 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) /* Unfeasible Route Length check. */ if (stream_pnt(s) + withdraw_len > end) { - zlog_err( - "%s [Error] Update packet error" - " (packet unfeasible length overflow %d)", - peer->host, withdraw_len); + flog_err(BGP_ERR_UPDATE_RCV, + "%s [Error] Update packet error" + " (packet unfeasible length overflow %d)", + peer->host, withdraw_len); bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_ATTR); return BGP_Stop; @@ -1502,7 +1511,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) ret = bgp_dump_attr(&attr, peer->rcvd_attr_str, BUFSIZ); if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW) - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.", peer->host); @@ -1562,7 +1572,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) } if (nlri_ret < 0) { - zlog_err("%s [Error] Error parsing NLRI", peer->host); + flog_err(BGP_ERR_UPDATE_RCV, + "%s [Error] Error parsing NLRI", peer->host); if (peer->status == Established) bgp_notify_send( peer, BGP_NOTIFY_UPDATE_ERR, @@ -1733,8 +1744,9 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) /* If peer does not have the capability, send notification. */ if (!CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_ADV)) { - zlog_err("%s [Error] BGP route refresh is not enabled", - peer->host); + flog_err(BGP_ERR_NO_CAP, + "%s [Error] BGP route refresh is not enabled", + peer->host); bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR, BGP_NOTIFY_HEADER_BAD_MESTYPE); return BGP_Stop; @@ -1742,7 +1754,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) /* Status must be Established. */ if (peer->status != Established) { - zlog_err( + flog_err( + BGP_ERR_INVALID_STATUS, "%s [Error] Route refresh packet received under status %s", peer->host, lookup_msg(bgp_status_msg, peer->status, NULL)); @@ -2122,8 +2135,9 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size) /* If peer does not have the capability, send notification. */ if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)) { - zlog_err("%s [Error] BGP dynamic capability is not enabled", - peer->host); + flog_err(BGP_ERR_NO_CAP, + "%s [Error] BGP dynamic capability is not enabled", + peer->host); bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR, BGP_NOTIFY_HEADER_BAD_MESTYPE); return BGP_Stop; @@ -2131,7 +2145,8 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size) /* Status must be Established. */ if (peer->status != Established) { - zlog_err( + flog_err( + BGP_ERR_NO_CAP, "%s [Error] Dynamic capability packet received under status %s", peer->host, lookup_msg(bgp_status_msg, peer->status, NULL)); @@ -2212,7 +2227,8 @@ int bgp_process_packet(struct thread *thread) memory_order_relaxed); mprc = bgp_open_receive(peer, size); if (mprc == BGP_Stop) - zlog_err( + flog_err( + BGP_ERR_PKT_OPEN, "%s: BGP OPEN receipt failed for peer: %s", __FUNCTION__, peer->host); break; @@ -2222,7 +2238,8 @@ int bgp_process_packet(struct thread *thread) peer->readtime = monotime(NULL); mprc = bgp_update_receive(peer, size); if (mprc == BGP_Stop) - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s: BGP UPDATE receipt failed for peer: %s", __FUNCTION__, peer->host); break; @@ -2231,7 +2248,8 @@ int bgp_process_packet(struct thread *thread) memory_order_relaxed); mprc = bgp_notify_receive(peer, size); if (mprc == BGP_Stop) - zlog_err( + flog_err( + BGP_ERR_NOTIFY_RCV, "%s: BGP NOTIFY receipt failed for peer: %s", __FUNCTION__, peer->host); break; @@ -2241,7 +2259,8 @@ int bgp_process_packet(struct thread *thread) memory_order_relaxed); mprc = bgp_keepalive_receive(peer, size); if (mprc == BGP_Stop) - zlog_err( + flog_err( + BGP_ERR_KEEP_RCV, "%s: BGP KEEPALIVE receipt failed for peer: %s", __FUNCTION__, peer->host); break; @@ -2251,7 +2270,8 @@ int bgp_process_packet(struct thread *thread) memory_order_relaxed); mprc = bgp_route_refresh_receive(peer, size); if (mprc == BGP_Stop) - zlog_err( + flog_err( + BGP_ERR_RFSH_RCV, "%s: BGP ROUTEREFRESH receipt failed for peer: %s", __FUNCTION__, peer->host); break; @@ -2260,7 +2280,8 @@ int bgp_process_packet(struct thread *thread) memory_order_relaxed); mprc = bgp_capability_receive(peer, size); if (mprc == BGP_Stop) - zlog_err( + flog_err( + BGP_ERR_CAP_RCV, "%s: BGP CAPABILITY receipt failed for peer: %s", __FUNCTION__, peer->host); break; diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index de475d2dc..129c143a6 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -33,6 +33,7 @@ #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_flowspec_private.h" +#include "bgpd/bgp_errors.h" DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH_ENTRY, "PBR match entry") DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH, "PBR match") @@ -652,8 +653,9 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p, action_count++; if (action_count > ACTIONS_MAX_NUM) { if (BGP_DEBUG(pbr, PBR_ERROR)) - zlog_err("%s: flowspec actions exceeds limit (max %u)", - __func__, action_count); + flog_err(BGP_ERR_FLOWSPEC_PACKET, + "%s: flowspec actions exceeds limit (max %u)", + __func__, action_count); break; } api_action = &api->actions[action_count - 1]; @@ -2250,15 +2252,17 @@ void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p, if (!bgp_zebra_tm_chunk_obtained()) { if (BGP_DEBUG(pbr, PBR_ERROR)) - zlog_err("%s: table chunk not obtained yet", - __func__); + flog_err(BGP_ERR_TABLE_CHUNK, + "%s: table chunk not obtained yet", + __func__); return; } if (bgp_pbr_build_and_validate_entry(p, info, &api) < 0) { if (BGP_DEBUG(pbr, PBR_ERROR)) - zlog_err("%s: cancel updating entry %p in bgp pbr", - __func__, info); + flog_err(BGP_ERR_FLOWSPEC_INSTALLATION, + "%s: cancel updating entry %p in bgp pbr", + __func__, info); return; } bgp_pbr_handle_entry(bgp, info, &api, nlri_update); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 1ded492a2..041049d05 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -44,6 +44,7 @@ #include "bgpd/bgp_route.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_aspath.h" #include "bgpd/bgp_regex.h" #include "bgpd/bgp_community.h" @@ -493,16 +494,18 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new, } if (newattr->sticky && !existattr->sticky) { - zlog_warn( - "%s: %s wins over %s due to sticky MAC flag", - pfx_buf, new_buf, exist_buf); + if (debug) + zlog_debug( + "%s: %s wins over %s due to sticky MAC flag", + pfx_buf, new_buf, exist_buf); return 1; } if (!newattr->sticky && existattr->sticky) { - zlog_warn( - "%s: %s loses to %s due to sticky MAC flag", - pfx_buf, new_buf, exist_buf); + if (debug) + zlog_debug( + "%s: %s loses to %s due to sticky MAC flag", + pfx_buf, new_buf, exist_buf); return 0; } } @@ -4202,8 +4205,9 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, /* Prefix length check. */ if (p.prefixlen > prefix_blen(&p) * 8) { - zlog_err( - "%s [Error] Update packet error (wrong perfix length %d for afi %u)", + flog_err( + BGP_ERR_UPDATE_RCV, + "%s [Error] Update packet error (wrong prefix length %d for afi %u)", peer->host, p.prefixlen, packet->afi); return -1; } @@ -4213,7 +4217,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, /* When packet overflow occur return immediately. */ if (pnt + psize > lim) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error (prefix length %d overflows packet)", peer->host, p.prefixlen); return -1; @@ -4222,7 +4227,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, /* Defensive coding, double-check the psize fits in a struct * prefix */ if (psize > (ssize_t)sizeof(p.u)) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)", peer->host, p.prefixlen, sizeof(p.u)); return -1; @@ -4243,7 +4249,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, * be logged locally, and the prefix SHOULD be * ignored. */ - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s: IPv4 unicast NLRI is multicast address %s, ignoring", peer->host, inet_ntoa(p.u.prefix4)); continue; @@ -4255,7 +4262,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) { char buf[BUFSIZ]; - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s: IPv6 unicast NLRI is link-local address %s, ignoring", peer->host, inet_ntop(AF_INET6, &p.u.prefix6, buf, @@ -4266,7 +4274,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) { char buf[BUFSIZ]; - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s: IPv6 unicast NLRI is multicast address %s, ignoring", peer->host, inet_ntop(AF_INET6, &p.u.prefix6, buf, @@ -4295,7 +4304,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, /* Packet length consistency check. */ if (pnt != lim) { - zlog_err( + flog_err( + BGP_ERR_UPDATE_RCV, "%s [Error] Update packet error (prefix length mismatch with total length)", peer->host); return -1; diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index 6a65f982e..37740671c 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -47,6 +47,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_advertise.h" #include "bgpd/bgp_packet.h" @@ -1630,8 +1631,9 @@ void update_group_adjust_peer(struct peer_af *paf) if (!updgrp) { updgrp = update_group_create(paf); if (!updgrp) { - zlog_err("couldn't create update group for peer %s", - paf->peer->host); + flog_err(BGP_ERR_UPDGRP_CREATE, + "couldn't create update group for peer %s", + paf->peer->host); return; } } diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 34ddbfcd1..c0761503f 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -46,6 +46,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_packet.h" @@ -786,7 +787,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp) * NLRI then * return */ if (space_remaining < space_needed) { - zlog_err( + flog_err( + BGP_ERR_UPDGRP_ATTR_LEN, "u%" PRIu64 ":s%" PRIu64 " attributes too long, cannot send UPDATE", subgrp->update_group->id, subgrp->id); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index e3efbbf25..fda458cb8 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -45,6 +45,7 @@ #include "bgpd/bgp_lcommunity.h" #include "bgpd/bgp_damp.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_open.h" @@ -802,7 +803,7 @@ DEFUN_HIDDEN (no_bgp_multiple_instance, vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); vty_out(vty, "if you are using this please let the developers know\n"); - zlog_warn("Deprecated option: `bgp multiple-instance` being used"); + zlog_info("Deprecated option: `bgp multiple-instance` being used"); ret = bgp_option_unset(BGP_OPT_MULTIPLE_INSTANCE); if (ret < 0) { vty_out(vty, "%% There are more than two BGP instances\n"); @@ -827,7 +828,7 @@ DEFUN_HIDDEN (bgp_config_type, if (argv_find(argv, argc, "cisco", &idx)) { vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n"); vty_out(vty, "if you are using this please let the developers know!\n"); - zlog_warn("Deprecated option: `bgp config-type cisco` being used"); + zlog_info("Deprecated option: `bgp config-type cisco` being used"); bgp_option_set(BGP_OPT_CONFIG_CISCO); } else bgp_option_unset(BGP_OPT_CONFIG_CISCO); @@ -10754,7 +10755,8 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty, for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { if (use_json) { if (!(json = json_object_new_object())) { - zlog_err( + flog_err( + BGP_ERR_JSON_MEM_ERROR, "Unable to allocate memory for JSON object"); vty_out(vty, "{\"error\": {\"message:\": \"Unable to allocate memory for JSON object\"}}}\n"); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 9591fe673..343471748 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -44,6 +44,7 @@ #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_mpath.h" #include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_nht.h" @@ -1016,7 +1017,7 @@ static int bgp_zebra_tm_connect(struct thread *t) ret = tm_table_manager_connect(zclient); } if (ret < 0) { - zlog_warn("Error connecting to table manager!"); + zlog_info("Error connecting to table manager!"); bgp_tm_status_connected = false; } else { if (!bgp_tm_status_connected) @@ -1077,7 +1078,8 @@ int bgp_zebra_get_table_range(uint32_t chunk_size, return -1; ret = tm_get_table_chunk(zclient, chunk_size, start, end); if (ret < 0) { - zlog_err("BGP: Error getting table chunk %u", chunk_size); + flog_err(BGP_ERR_TABLE_CHUNK, + "BGP: Error getting table chunk %u", chunk_size); return -1; } zlog_info("BGP: Table Manager returns range from chunk %u is [%u %u]", @@ -2381,9 +2383,10 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient, ipa_len = stream_getl(s); if (ipa_len != 0 && ipa_len != IPV4_MAX_BYTELEN && ipa_len != IPV6_MAX_BYTELEN) { - zlog_err("%u:Recv MACIP %s with invalid IP addr length %d", - vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del", - ipa_len); + flog_err(BGP_ERR_MACIP_LEN, + "%u:Recv MACIP %s with invalid IP addr length %d", + vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del", + ipa_len); return -1; } @@ -2473,11 +2476,13 @@ static void bgp_zebra_process_label_chunk( STREAM_GETL(s, last); if (zclient->redist_default != proto) { - zlog_err("Got LM msg with wrong proto %u", proto); + flog_err(BGP_ERR_LM_ERROR, "Got LM msg with wrong proto %u", + proto); return; } if (zclient->instance != instance) { - zlog_err("Got LM msg with wrong instance %u", proto); + flog_err(BGP_ERR_LM_ERROR, "Got LM msg with wrong instance %u", + proto); return; } @@ -2485,8 +2490,8 @@ static void bgp_zebra_process_label_chunk( first < MPLS_LABEL_UNRESERVED_MIN || last > MPLS_LABEL_UNRESERVED_MAX) { - zlog_err("%s: Invalid Label chunk: %u - %u", - __func__, first, last); + flog_err(BGP_ERR_LM_ERROR, "%s: Invalid Label chunk: %u - %u", + __func__, first, last); return; } if (BGP_DEBUG(zebra, ZEBRA)) { diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 82da0245b..c8b4e3acf 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -52,6 +52,7 @@ #include "bgpd/bgp_route.h" #include "bgpd/bgp_dump.h" #include "bgpd/bgp_debug.h" +#include "bgpd/bgp_errors.h" #include "bgpd/bgp_community.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_regex.h" @@ -683,12 +684,6 @@ struct peer_af *peer_af_create(struct peer *peer, afi_t afi, safi_t safi) /* Allocate new peer af */ af = XCALLOC(MTYPE_BGP_PEER_AF, sizeof(struct peer_af)); - if (af == NULL) { - zlog_err("Could not create af structure for peer %s", - peer->host); - return NULL; - } - peer->peer_af_array[afid] = af; af->afi = afi; af->safi = safi; @@ -1809,8 +1804,8 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) int active; if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - zlog_err("%s was called for peer-group %s", __func__, - peer->host); + flog_err(BGP_ERR_PEER_GROUP, "%s was called for peer-group %s", + __func__, peer->host); return 1; } @@ -1923,8 +1918,8 @@ static int non_peergroup_deactivate_af(struct peer *peer, afi_t afi, safi_t safi) { if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - zlog_err("%s was called for peer-group %s", __func__, - peer->host); + flog_err(BGP_ERR_PEER_GROUP, "%s was called for peer-group %s", + __func__, peer->host); return 1; } @@ -1936,8 +1931,9 @@ static int non_peergroup_deactivate_af(struct peer *peer, afi_t afi, peer->afc[afi][safi] = 0; if (peer_af_delete(peer, afi, safi) != 0) { - zlog_err("couldn't delete af structure for peer %s", - peer->host); + flog_err(BGP_ERR_PEER_DELETE, + "couldn't delete af structure for peer %s", + peer->host); return 1; } @@ -1986,8 +1982,9 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi) group = peer->group; if (peer_af_delete(peer, afi, safi) != 0) { - zlog_err("couldn't delete af structure for peer %s", - peer->host); + flog_err(BGP_ERR_PEER_DELETE, + "couldn't delete af structure for peer %s", + peer->host); } for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) { @@ -4094,7 +4091,7 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi, if (flag & PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS) { if (!bgp_flag_check( bgp, BGP_FLAG_DETERMINISTIC_MED)) { - zlog_warn( + zlog_info( "%s: enabling bgp deterministic-med, this is required" " for addpath-tx-bestpath-per-AS", peer->host); diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index a1f1169a7..355cf9205 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -32,6 +32,7 @@ #include "lib/command.h" #include "lib/stream.h" #include "lib/ringbuf.h" +#include "lib/lib_errors.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_ecommunity.h" @@ -3933,7 +3934,8 @@ void *rfapi_rfp_init_group_config_ptr_vty(void *rfp_start_val, size); break; default: - zlog_err("%s: Unknown group type=%d", __func__, type); + flog_err(LIB_ERR_DEVELOPMENT, "%s: Unknown group type=%d", + __func__, type); /* should never happen */ assert("Unknown type" == NULL); break; @@ -4047,7 +4049,8 @@ void *rfapi_rfp_get_group_config_ptr_name( criteria, search_cb); break; default: - zlog_err("%s: Unknown group type=%d", __func__, type); + flog_err(LIB_ERR_DEVELOPMENT, "%s: Unknown group type=%d", + __func__, type); /* should never happen */ assert("Unknown type" == NULL); break; diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index c1af269d3..ac3b6da23 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -34,6 +34,7 @@ #include "lib/skiplist.h" #include "lib/thread.h" #include "lib/stream.h" +#include "lib/lib_errors.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_ecommunity.h" @@ -3028,7 +3029,7 @@ static void rfapiBgpInfoFilteredImportEncap( break; default: - zlog_err("%s: bad afi %d", __func__, afi); + flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", __func__, afi); return; } @@ -3485,7 +3486,7 @@ void rfapiBgpInfoFilteredImportVPN( break; default: - zlog_err("%s: bad afi %d", __func__, afi); + flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", __func__, afi); return; } @@ -3890,7 +3891,8 @@ rfapiBgpInfoFilteredImportFunction(safi_t safi) default: /* not expected */ - zlog_err("%s: bad safi %d", __func__, safi); + flog_err(LIB_ERR_DEVELOPMENT, "%s: bad safi %d", __func__, + safi); return rfapiBgpInfoFilteredImportBadSafi; } } diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index d4dd34d1d..69426670a 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -33,6 +33,7 @@ #include "lib/linklist.h" #include "lib/plist.h" #include "lib/routemap.h" +#include "lib/lib_errors.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_ecommunity.h" @@ -187,7 +188,8 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn, if (!afi) { - zlog_err("%s: can't get afi of route node", __func__); + flog_err(LIB_ERR_DEVELOPMENT, + "%s: can't get afi of route node", __func__); return; } @@ -333,7 +335,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn, struct prefix ce_nexthop; if (!afi) { - zlog_err("%s: bad afi", __func__); + flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi", __func__); return; } @@ -698,7 +700,8 @@ void vnc_direct_bgp_add_prefix(struct bgp *bgp, afi_t afi = family2afi(rn->p.family); if (!afi) { - zlog_err("%s: can't get afi of route node", __func__); + flog_err(LIB_ERR_DEVELOPMENT, + "%s: can't get afi of route node", __func__); return; } @@ -807,7 +810,8 @@ void vnc_direct_bgp_del_prefix(struct bgp *bgp, afi_t afi = family2afi(rn->p.family); if (!afi) { - zlog_err("%s: can't get afi route node", __func__); + flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi route node", + __func__); return; } @@ -922,7 +926,8 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) afi_t afi = family2afi(rfd->vn_addr.addr_family); if (!afi) { - zlog_err("%s: can't get afi of nve vn addr", __func__); + flog_err(LIB_ERR_DEVELOPMENT, + "%s: can't get afi of nve vn addr", __func__); return; } @@ -974,7 +979,8 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) if (afi == AFI_IP || afi == AFI_IP6) { rt = import_table->imported_vpn[afi]; } else { - zlog_err("%s: bad afi %d", __func__, afi); + flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", + __func__, afi); return; } @@ -1066,7 +1072,8 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) afi_t afi = family2afi(rfd->vn_addr.addr_family); if (!afi) { - zlog_err("%s: can't get afi of nve vn addr", __func__); + flog_err(LIB_ERR_DEVELOPMENT, + "%s: can't get afi of nve vn addr", __func__); return; } @@ -1113,7 +1120,8 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) if (afi == AFI_IP || afi == AFI_IP6) { rt = import_table->imported_vpn[afi]; } else { - zlog_err("%s: bad afi %d", __func__, afi); + flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", + __func__, afi); return; } @@ -1288,7 +1296,7 @@ static void vnc_direct_bgp_add_group_afi(struct bgp *bgp, if (afi == AFI_IP || afi == AFI_IP6) { rt = import_table->imported_vpn[afi]; } else { - zlog_err("%s: bad afi %d", __func__, afi); + flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", __func__, afi); return; } @@ -1632,7 +1640,8 @@ void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi, struct attr *iattr; if (!afi) { - zlog_err("%s: can't get afi of route node", __func__); + flog_err(LIB_ERR_DEVELOPMENT, + "%s: can't get afi of route node", __func__); return; } @@ -1751,7 +1760,8 @@ void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi, struct vnc_export_info *eti; if (!afi) { - zlog_err("%s: can't get afi route node", __func__); + flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi route node", + __func__); return; } diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 156572b57..72363f7cf 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -32,6 +32,7 @@ #include "lib/linklist.h" #include "lib/plist.h" #include "lib/routemap.h" +#include "lib/lib_errors.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_ecommunity.h" @@ -602,7 +603,8 @@ static void vnc_import_bgp_add_route_mode_resolve_nve( */ if (!afi) { - zlog_err("%s: can't get afi of prefix", __func__); + flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi of prefix", + __func__); return; } @@ -718,7 +720,8 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp, } if (!afi) { - zlog_err("%s: can't get afi of prefix", __func__); + flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi of prefix", + __func__); return; } @@ -905,7 +908,8 @@ vnc_import_bgp_add_route_mode_nvegroup(struct bgp *bgp, struct prefix *prefix, assert(rfg); if (!afi) { - zlog_err("%s: can't get afi of prefix", __func__); + flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi of prefix", + __func__); return; } @@ -2628,7 +2632,8 @@ void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix, VNC_RHNCK(enter); if (!afi) { - zlog_err("%s: can't get afi of prefix", __func__); + flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi of prefix", + __func__); return; } diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 7d564ef11..a2871188e 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -32,6 +32,7 @@ #include "lib/stream.h" #include "lib/ringbuf.h" #include "lib/memory.h" +#include "lib/lib_errors.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_ecommunity.h" @@ -570,7 +571,8 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp, return; if (rn->p.family != AF_INET && rn->p.family != AF_INET6) { - zlog_err("%s: invalid route node addr family", __func__); + flog_err(LIB_ERR_DEVELOPMENT, + "%s: invalid route node addr family", __func__); return; } @@ -642,7 +644,8 @@ static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd, return; if (afi != AFI_IP && afi != AFI_IP6) { - zlog_err("%s: invalid vn addr family", __func__); + flog_err(LIB_ERR_DEVELOPMENT, "%s: invalid vn addr family", + __func__); return; } @@ -739,12 +742,13 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp, if (afi == AFI_IP || afi == AFI_IP6) { rt = import_table->imported_vpn[afi]; } else { - zlog_err("%s: bad afi %d", __func__, afi); + flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", __func__, afi); return; } if (!family) { - zlog_err("%s: computed bad family: %d", __func__, family); + flog_err(LIB_ERR_DEVELOPMENT, "%s: computed bad family: %d", + __func__, family); return; } diff --git a/doc/Makefile.am b/doc/Makefile.am index 1f6a0d87f..6f7258548 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -241,7 +241,7 @@ EXTRA_DIST = frr-sphinx.mk \ user/vtysh.rst \ user/zebra.rst \ user/bfd.rst \ - user/flowspec.rst \ + user/flowspec.rst \ mpls/ChangeLog.opaque.txt \ mpls/ospfd.conf \ mpls/cli_summary.txt \ diff --git a/eigrpd/eigrp_errors.c b/eigrpd/eigrp_errors.c new file mode 100644 index 000000000..3db0ec854 --- /dev/null +++ b/eigrpd/eigrp_errors.c @@ -0,0 +1,49 @@ +/* + * EIGRP-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 + +#include "lib/ferr.h" +#include "eigrp_errors.h" + +/* clang-format off */ +static struct log_ref ferr_eigrp_err[] = { + { + .code = EIGRP_ERR_PACKET, + .title = "EIGRP Packet Error", + .description = "EIGRP has a packet that does not correctly decode or encode", + .suggestion = "Gather log files from both sides of the neighbor relationship and open an issue" + }, + { + .code = EIGRP_ERR_CONFIG, + .title = "EIGRP Configuration Error", + .description = "EIGRP has detected a configuration error", + .suggestion = "Correct the configuration issue, if it still persists open an Issue" + }, + { + .code = END_FERR, + } +}; +/* clang-format on */ + +void eigrp_error_init(void) +{ + log_ref_add(ferr_eigrp_err); +} diff --git a/eigrpd/eigrp_errors.h b/eigrpd/eigrp_errors.h new file mode 100644 index 000000000..e1ace8ab4 --- /dev/null +++ b/eigrpd/eigrp_errors.h @@ -0,0 +1,33 @@ +/* + * EIGRP-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 __EIGRP_ERRORS_H__ +#define __EIGRP_ERRORS_H__ + +#include "lib/ferr.h" + +enum eigrp_log_refs { + EIGRP_ERR_PACKET = EIGRP_FERR_START, + EIGRP_ERR_CONFIG, +}; + +extern void eigrp_error_init(void); + +#endif diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c index 2e55d57c3..d438db28d 100644 --- a/eigrpd/eigrp_hello.c +++ b/eigrpd/eigrp_hello.c @@ -54,6 +54,7 @@ #include "eigrpd/eigrp_vty.h" #include "eigrpd/eigrp_dump.h" #include "eigrpd/eigrp_macros.h" +#include "eigrpd/eigrp_errors.h" /* Packet Type String. */ static const struct message eigrp_general_tlv_type_str[] = { @@ -420,8 +421,9 @@ void eigrp_sw_version_initialize(void) ret = sscanf(ver_string, "%" SCNu32 ".%" SCNu32, &FRR_MAJOR, &FRR_MINOR); if (ret != 2) - zlog_err("Did not Properly parse %s, please fix VERSION string", - VERSION); + flog_err(EIGRP_ERR_PACKET, + "Did not Properly parse %s, please fix VERSION string", + VERSION); } /** diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c index c4ca07178..31101a52d 100644 --- a/eigrpd/eigrp_main.c +++ b/eigrpd/eigrp_main.c @@ -64,6 +64,7 @@ #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_snmp.h" #include "eigrpd/eigrp_filter.h" +#include "eigrpd/eigrp_errors.h" //#include "eigrpd/eigrp_routemap.h" /* eigprd privileges */ @@ -168,6 +169,7 @@ int main(int argc, char **argv, char **envp) eigrp_om->master = frr_init(); master = eigrp_om->master; + eigrp_error_init(); vrf_init(NULL, NULL, NULL, NULL); /*EIGRPd init*/ diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c index 3bf75072a..b10673d9e 100644 --- a/eigrpd/eigrp_neighbor.c +++ b/eigrpd/eigrp_neighbor.c @@ -53,6 +53,7 @@ #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_memory.h" +#include "eigrpd/eigrp_errors.h" struct eigrp_neighbor *eigrp_nbr_new(struct eigrp_interface *ei) { @@ -335,7 +336,8 @@ int eigrp_nbr_count_get(void) void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty) { if (nbr == NULL) { - zlog_err("Nbr Hard restart: Neighbor not specified."); + flog_err(EIGRP_ERR_CONFIG, + "Nbr Hard restart: Neighbor not specified."); return; } diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index 629beddec..8eaf1e82a 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -37,6 +37,7 @@ #include "privs.h" #include "table.h" #include "vty.h" +#include "lib_errors.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" @@ -60,60 +61,42 @@ int eigrp_sock_init(void) int hincl = 1; #endif - if (eigrpd_privs.change(ZPRIVS_RAISE)) - zlog_err("eigrp_sock_init: could not raise privs, %s", - safe_strerror(errno)); - - eigrp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP); - if (eigrp_sock < 0) { - int save_errno = errno; - if (eigrpd_privs.change(ZPRIVS_LOWER)) - zlog_err("eigrp_sock_init: could not lower privs, %s", + frr_elevate_privs(&eigrpd_privs) { + eigrp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP); + if (eigrp_sock < 0) { + zlog_err("eigrp_read_sock_init: socket: %s", safe_strerror(errno)); - zlog_err("eigrp_read_sock_init: socket: %s", - safe_strerror(save_errno)); - exit(1); - } + exit(1); + } #ifdef IP_HDRINCL - /* we will include IP header with packet */ - ret = setsockopt(eigrp_sock, IPPROTO_IP, IP_HDRINCL, &hincl, - sizeof(hincl)); - if (ret < 0) { - int save_errno = errno; - if (eigrpd_privs.change(ZPRIVS_LOWER)) - zlog_err("eigrp_sock_init: could not lower privs, %s", - safe_strerror(errno)); - zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", - eigrp_sock, safe_strerror(save_errno)); - } + /* we will include IP header with packet */ + ret = setsockopt(eigrp_sock, IPPROTO_IP, IP_HDRINCL, &hincl, + sizeof(hincl)); + if (ret < 0) { + zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", + eigrp_sock, safe_strerror(errno)); + } #elif defined(IPTOS_PREC_INTERNETCONTROL) #warning "IP_HDRINCL not available on this system" #warning "using IPTOS_PREC_INTERNETCONTROL" - ret = setsockopt_ipv4_tos(eigrp_sock, IPTOS_PREC_INTERNETCONTROL); - if (ret < 0) { - int save_errno = errno; - if (eigrpd_privs.change(ZPRIVS_LOWER)) - zlog_err("eigrpd_sock_init: could not lower privs, %s", - safe_strerror(errno)); - zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos, - eigrp_sock, safe_strerror(save_errno)); - close(eigrp_sock); /* Prevent sd leak. */ - return ret; - } + ret = setsockopt_ipv4_tos(eigrp_sock, + IPTOS_PREC_INTERNETCONTROL); + if (ret < 0) { + zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", + tos, eigrp_sock, safe_strerror(errno)); + close(eigrp_sock); /* Prevent sd leak. */ + return ret; + } #else /* !IPTOS_PREC_INTERNETCONTROL */ #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL" - zlog_warn("IP_HDRINCL option not available"); + zlog_warn("IP_HDRINCL option not available"); #endif /* IP_HDRINCL */ - ret = setsockopt_ifindex(AF_INET, eigrp_sock, 1); - - if (ret < 0) - zlog_warn("Can't set pktinfo option for fd %d", eigrp_sock); - - if (eigrpd_privs.change(ZPRIVS_LOWER)) { - zlog_err("eigrp_sock_init: could not lower privs, %s", - safe_strerror(errno)); + ret = setsockopt_ifindex(AF_INET, eigrp_sock, 1); + if (ret < 0) + zlog_warn("Can't set pktinfo option for fd %d", + eigrp_sock); } return eigrp_sock; @@ -125,9 +108,7 @@ void eigrp_adjust_sndbuflen(struct eigrp *eigrp, unsigned int buflen) /* Check if any work has to be done at all. */ if (eigrp->maxsndbuflen >= buflen) return; - if (eigrpd_privs.change(ZPRIVS_RAISE)) - zlog_err("%s: could not raise privs, %s", __func__, - safe_strerror(errno)); + frr_elevate_privs(&eigrpd_privs) { /* Now we try to set SO_SNDBUF to what our caller has requested * (the MTU of a newly added interface). However, if the OS has @@ -136,18 +117,16 @@ void eigrp_adjust_sndbuflen(struct eigrp *eigrp, unsigned int buflen) * may allocate more buffer space, than requested, this isn't * a error. */ - setsockopt_so_sendbuf(eigrp->fd, buflen); - newbuflen = getsockopt_so_sendbuf(eigrp->fd); - if (newbuflen < 0 || newbuflen < (int)buflen) - zlog_warn("%s: tried to set SO_SNDBUF to %u, but got %d", - __func__, buflen, newbuflen); - if (newbuflen >= 0) - eigrp->maxsndbuflen = (unsigned int)newbuflen; - else - zlog_warn("%s: failed to get SO_SNDBUF", __func__); - if (eigrpd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs, %s", __func__, - safe_strerror(errno)); + setsockopt_so_sendbuf(eigrp->fd, buflen); + newbuflen = getsockopt_so_sendbuf(eigrp->fd); + if (newbuflen < 0 || newbuflen < (int)buflen) + zlog_warn("%s: tried to set SO_SNDBUF to %u, but got %d", + __func__, buflen, newbuflen); + if (newbuflen >= 0) + eigrp->maxsndbuflen = (unsigned int)newbuflen; + else + zlog_warn("%s: failed to get SO_SNDBUF", __func__); + } } int eigrp_if_ipmulticast(struct eigrp *top, struct prefix *p, diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index 027f30563..6338e5cf7 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -42,6 +42,7 @@ #include "checksum.h" #include "md5.h" #include "sha256.h" +#include "lib_errors.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" @@ -56,6 +57,7 @@ #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_memory.h" +#include "eigrpd/eigrp_errors.h" /* Packet Type String. */ const struct message eigrp_packet_type_str[] = { @@ -346,12 +348,14 @@ int eigrp_write(struct thread *thread) /* Get one packet from queue. */ ep = eigrp_fifo_next(ei->obuf); if (!ep) { - zlog_err("%s: Interface %s no packet on queue?", - __PRETTY_FUNCTION__, ei->ifp->name); + flog_err(LIB_ERR_DEVELOPMENT, + "%s: Interface %s no packet on queue?", + __PRETTY_FUNCTION__, ei->ifp->name); goto out; } if (ep->length < EIGRP_HEADER_LEN) { - zlog_err("%s: Packet just has a header?", __PRETTY_FUNCTION__); + flog_err(EIGRP_ERR_PACKET, + "%s: Packet just has a header?", __PRETTY_FUNCTION__); eigrp_header_dump((struct eigrp_header *)ep->s->data); eigrp_packet_delete(ei); goto out; @@ -1210,8 +1214,9 @@ uint16_t eigrp_add_internalTLV_to_stream(struct stream *s, stream_putw(s, length); break; default: - zlog_err("%s: Unexpected prefix length: %d", - __PRETTY_FUNCTION__, pe->destination->prefixlen); + flog_err(LIB_ERR_DEVELOPMENT, + "%s: Unexpected prefix length: %d", + __PRETTY_FUNCTION__, pe->destination->prefixlen); return 0; } stream_putl(s, 0x00000000); diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index b7490cd49..b6e6352de 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -59,6 +59,7 @@ #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_memory.h" +#include "eigrpd/eigrp_errors.h" void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe) { @@ -169,10 +170,10 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, if (!dest) { char buf[PREFIX_STRLEN]; - zlog_err( - "%s: Received prefix %s which we do not know about", - __PRETTY_FUNCTION__, - prefix2str(&dest_addr, buf, sizeof(buf))); + flog_err(EIGRP_ERR_PACKET, + "%s: Received prefix %s which we do not know about", + __PRETTY_FUNCTION__, + prefix2str(&dest_addr, buf, sizeof(buf))); eigrp_IPv4_InternalTLV_free(tlv); continue; } diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 8ca0e282a..61eee99f6 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -37,6 +37,7 @@ #include "log.h" #include "linklist.h" #include "vty.h" +#include "lib_errors.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" @@ -411,7 +412,8 @@ eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg) } break; default: - zlog_err("%s: Please implement handler", __PRETTY_FUNCTION__); + flog_err(LIB_ERR_DEVELOPMENT, "%s: Please implement handler", + __PRETTY_FUNCTION__); break; } distance_done: diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 24d1253cb..91c0046bb 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -43,6 +43,7 @@ #include "sockopt.h" #include "keychain.h" #include "libfrr.h" +#include "lib_errors.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" @@ -161,21 +162,16 @@ static struct eigrp *eigrp_new(const char *AS) eigrp->networks = eigrp_topology_new(); if ((eigrp_socket = eigrp_sock_init()) < 0) { - zlog_err( - "eigrp_new: fatal error: eigrp_sock_init was unable to open " - "a socket"); + flog_err_sys( + LIB_ERR_SOCKET, + "eigrp_new: fatal error: eigrp_sock_init was unable to open a socket"); exit(1); } eigrp->fd = eigrp_socket; eigrp->maxsndbuflen = getsockopt_so_sendbuf(eigrp->fd); - if ((eigrp->ibuf = stream_new(EIGRP_PACKET_MAX_LEN + 1)) == NULL) { - zlog_err( - "eigrp_new: fatal error: stream_new (%u) failed allocating ibuf", - EIGRP_PACKET_MAX_LEN + 1); - exit(1); - } + eigrp->ibuf = stream_new(EIGRP_PACKET_MAX_LEN + 1); eigrp->t_read = NULL; thread_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read); diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 2c6b1e321..2635d555d 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -10,6 +10,7 @@ endif eigrpd_libeigrp_a_SOURCES = \ eigrpd/eigrp_dump.c \ + eigrpd/eigrp_errors.c \ eigrpd/eigrp_filter.c \ eigrpd/eigrp_fsm.c \ eigrpd/eigrp_hello.c \ @@ -39,6 +40,7 @@ eigrpdheader_HEADERS = \ noinst_HEADERS += \ eigrpd/eigrp_const.h \ + eigrpd/eigrp_errors.h \ eigrpd/eigrp_filter.h \ eigrpd/eigrp_fsm.h \ eigrpd/eigrp_interface.h \ diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c index 2cc2fefd9..d05dba33e 100644 --- a/isisd/isis_bpf.c +++ b/isisd/isis_bpf.c @@ -32,6 +32,7 @@ #include "network.h" #include "stream.h" #include "if.h" +#include "lib_errors.h" #include "isisd/dict.h" #include "isisd/isis_constants.h" @@ -186,31 +187,26 @@ int isis_sock_init(struct isis_circuit *circuit) { int retval = ISIS_OK; - if (isisd_privs.change(ZPRIVS_RAISE)) - zlog_err("%s: could not raise privs, %s", __func__, - safe_strerror(errno)); + frr_elevate_privs(&isisd_privs) { - retval = open_bpf_dev(circuit); + retval = open_bpf_dev(circuit); - if (retval != ISIS_OK) { - zlog_warn("%s: could not initialize the socket", __func__); - goto end; - } + if (retval != ISIS_OK) { + zlog_warn("%s: could not initialize the socket", + __func__); + break; + } - if (if_is_broadcast(circuit->interface)) { - circuit->tx = isis_send_pdu_bcast; - circuit->rx = isis_recv_pdu_bcast; - } else { - zlog_warn("isis_sock_init(): unknown circuit type"); - retval = ISIS_WARNING; - goto end; + if (if_is_broadcast(circuit->interface)) { + circuit->tx = isis_send_pdu_bcast; + circuit->rx = isis_recv_pdu_bcast; + } else { + zlog_warn("isis_sock_init(): unknown circuit type"); + retval = ISIS_WARNING; + break; + } } -end: - if (isisd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs, %s", __func__, - safe_strerror(errno)); - return retval; } diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 42041a7c4..7cf83f20f 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -57,6 +57,7 @@ #include "isisd/isis_events.h" #include "isisd/isis_te.h" #include "isisd/isis_mt.h" +#include "isisd/isis_errors.h" DEFINE_QOBJ_TYPE(isis_circuit) @@ -566,7 +567,8 @@ int isis_circuit_up(struct isis_circuit *circuit) return ISIS_OK; if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit)) { - zlog_err( + flog_err( + ISIS_ERR_CONFIG, "Interface MTU %zu on %s is too low to support area lsp mtu %u!", isis_circuit_pdu_size(circuit), circuit->interface->name, circuit->area->lsp_mtu); @@ -577,7 +579,9 @@ int isis_circuit_up(struct isis_circuit *circuit) if (circuit->circ_type == CIRCUIT_T_BROADCAST) { circuit->circuit_id = isis_circuit_id_gen(isis, circuit->interface); if (!circuit->circuit_id) { - zlog_err("There are already 255 broadcast circuits active!"); + flog_err( + ISIS_ERR_CONFIG, + "There are already 255 broadcast circuits active!"); return ISIS_ERROR; } diff --git a/isisd/isis_csm.c b/isisd/isis_csm.c index 10870d5c5..aae90b008 100644 --- a/isisd/isis_csm.c +++ b/isisd/isis_csm.c @@ -47,6 +47,7 @@ #include "isisd/isisd.h" #include "isisd/isis_csm.h" #include "isisd/isis_events.h" +#include "isisd/isis_errors.h" extern struct isis *isis; @@ -137,10 +138,12 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg) case IF_UP_FROM_Z: isis_circuit_if_add(circuit, (struct interface *)arg); if (isis_circuit_up(circuit) != ISIS_OK) { - zlog_err( + flog_err( + ISIS_ERR_CONFIG, "Could not bring up %s because of invalid config.", circuit->interface->name); - zlog_err( + flog_err( + ISIS_ERR_CONFIG, "Clearing config for %s. Please re-examine it.", circuit->interface->name); if (circuit->ip_router) { diff --git a/isisd/isis_dlpi.c b/isisd/isis_dlpi.c index 718f3a898..54a19ad23 100644 --- a/isisd/isis_dlpi.c +++ b/isisd/isis_dlpi.c @@ -36,6 +36,7 @@ #include "network.h" #include "stream.h" #include "if.h" +#include "lib_errors.h" #include "isisd/dict.h" #include "isisd/isis_constants.h" @@ -467,31 +468,26 @@ int isis_sock_init(struct isis_circuit *circuit) { int retval = ISIS_OK; - if (isisd_privs.change(ZPRIVS_RAISE)) - zlog_err("%s: could not raise privs, %s", __func__, - safe_strerror(errno)); + frr_elevate_privs(&isisd_privs) { - retval = open_dlpi_dev(circuit); + retval = open_dlpi_dev(circuit); - if (retval != ISIS_OK) { - zlog_warn("%s: could not initialize the socket", __func__); - goto end; - } + if (retval != ISIS_OK) { + zlog_warn("%s: could not initialize the socket", + __func__); + break; + } - if (circuit->circ_type == CIRCUIT_T_BROADCAST) { - circuit->tx = isis_send_pdu_bcast; - circuit->rx = isis_recv_pdu_bcast; - } else { - zlog_warn("isis_sock_init(): unknown circuit type"); - retval = ISIS_WARNING; - goto end; + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + circuit->tx = isis_send_pdu_bcast; + circuit->rx = isis_recv_pdu_bcast; + } else { + zlog_warn("isis_sock_init(): unknown circuit type"); + retval = ISIS_WARNING; + break; + } } -end: - if (isisd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs, %s", __func__, - safe_strerror(errno)); - return retval; } diff --git a/isisd/isis_errors.c b/isisd/isis_errors.c new file mode 100644 index 000000000..ecff65da1 --- /dev/null +++ b/isisd/isis_errors.c @@ -0,0 +1,49 @@ +/* + * ISIS-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 + +#include "lib/ferr.h" +#include "isis_errors.h" + +/* clang-format off */ +static struct log_ref ferr_isis_err[] = { + { + .code = ISIS_ERR_PACKET, + .title = "ISIS Packet Error", + .description = "Isis has detected an error with a packet from a peer", + .suggestion = "Gather log information and open an issue then restart FRR" + }, + { + .code = ISIS_ERR_CONFIG, + .title = "ISIS Configuration Error", + .description = "Isis has detected an error within configuration for the router", + .suggestion = "Ensure configuration is correct" + }, + { + .code = END_FERR, + } +}; +/* clang-format on */ + +void isis_error_init(void) +{ + log_ref_add(ferr_isis_err); +} diff --git a/isisd/isis_errors.h b/isisd/isis_errors.h new file mode 100644 index 000000000..f738254a3 --- /dev/null +++ b/isisd/isis_errors.h @@ -0,0 +1,33 @@ +/* + * ISIS-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 __ISIS_ERRORS_H__ +#define __ISIS_ERRORS_H__ + +#include "lib/ferr.h" + +enum isis_log_refs { + ISIS_ERR_PACKET = ISIS_FERR_START, + ISIS_ERR_CONFIG, +}; + +extern void isis_error_init(void); + +#endif diff --git a/isisd/isis_events.c b/isisd/isis_events.c index 349ec262c..52a0b9fac 100644 --- a/isisd/isis_events.c +++ b/isisd/isis_events.c @@ -48,6 +48,7 @@ #include "isisd/isis_csm.h" #include "isisd/isis_events.h" #include "isisd/isis_spf.h" +#include "isisd/isis_errors.h" /* debug isis-spf spf-events 4w4d: ISIS-Spf (tlt): L2 SPF needed, new adjacency, from 0x609229F4 @@ -156,9 +157,9 @@ void isis_circuit_is_type_set(struct isis_circuit *circuit, int newtype) return; /* No change */ if (!(newtype & circuit->area->is_type)) { - zlog_err( - "ISIS-Evt (%s) circuit type change - invalid level %s because" - " area is %s", + flog_err( + ISIS_ERR_CONFIG, + "ISIS-Evt (%s) circuit type change - invalid level %s because area is %s", circuit->area->area_tag, circuit_t2string(newtype), circuit_t2string(circuit->area->is_type)); return; diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 37651163f..66c97ae89 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -38,6 +38,7 @@ #include "md5.h" #include "table.h" #include "srcdest_table.h" +#include "lib_errors.h" #include "isisd/dict.h" #include "isisd/isis_constants.h" @@ -453,7 +454,8 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, struct isis_area *area, int level, bool confusion) { if (lsp->own_lsp) { - zlog_err( + flog_err( + LIB_ERR_DEVELOPMENT, "ISIS-Upd (%s): BUG updating LSP %s still marked as own LSP", area->area_tag, rawlspid_print(lsp->hdr.lsp_id)); lsp_clear_data(lsp); @@ -1242,8 +1244,9 @@ static int lsp_regenerate(struct isis_area *area, int level) lsp = lsp_search(lspid, lspdb); if (!lsp) { - zlog_err("ISIS-Upd (%s): lsp_regenerate: no L%d LSP found!", - area->area_tag, level); + flog_err(LIB_ERR_DEVELOPMENT, + "ISIS-Upd (%s): lsp_regenerate: no L%d LSP found!", + area->area_tag, level); return ISIS_ERROR; } @@ -1610,8 +1613,9 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level) lsp = lsp_search(lsp_id, lspdb); if (!lsp) { - zlog_err("lsp_regenerate_pseudo: no l%d LSP %s found!", level, - rawlspid_print(lsp_id)); + flog_err(LIB_ERR_DEVELOPMENT, + "lsp_regenerate_pseudo: no l%d LSP %s found!", level, + rawlspid_print(lsp_id)); return ISIS_ERROR; } diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 40ceb99fb..5b18ab0a2 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -53,6 +53,7 @@ #include "isisd/isis_routemap.h" #include "isisd/isis_zebra.h" #include "isisd/isis_te.h" +#include "isisd/isis_errors.h" /* Default configuration file name */ #define ISISD_DEFAULT_CONFIG "isisd.conf" @@ -103,7 +104,7 @@ static __attribute__((__noreturn__)) void terminate(int i) void sighup(void) { - zlog_err("SIGHUP/reload is not implemented for isisd"); + zlog_notice("SIGHUP/reload is not implemented for isisd"); return; } @@ -189,6 +190,7 @@ int main(int argc, char **argv, char **envp) /* * initializations */ + isis_error_init(); access_list_init(); vrf_init(NULL, NULL, NULL, NULL); prefix_list_init(); diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 8e2a7f13a..5c4e3a35b 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -34,6 +34,7 @@ #include "if.h" #include "checksum.h" #include "md5.h" +#include "lib_errors.h" #include "isisd/dict.h" #include "isisd/isis_constants.h" @@ -54,6 +55,7 @@ #include "isisd/isis_te.h" #include "isisd/isis_mt.h" #include "isisd/isis_tlvs.h" +#include "isisd/isis_errors.h" static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit, int level) @@ -86,9 +88,10 @@ static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit, retval = circuit->tx(circuit, level); if (retval != ISIS_OK) - zlog_err("ISIS-Upd (%s): Send L%d LSP PSNP on %s failed", - circuit->area->area_tag, level, - circuit->interface->name); + flog_err(ISIS_ERR_PACKET, + "ISIS-Upd (%s): Send L%d LSP PSNP on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); return retval; } @@ -614,8 +617,9 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, } if (!p2p_hello && !(level & iih.circ_type)) { - zlog_err("Level %d LAN Hello with Circuit Type %d", level, - iih.circ_type); + flog_err(ISIS_ERR_PACKET, + "Level %d LAN Hello with Circuit Type %d", level, + iih.circ_type); return ISIS_ERROR; } @@ -1350,7 +1354,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) /* Verify that at least the 8 bytes fixed header have been received */ if (stream_get_endp(circuit->rcv_stream) < ISIS_FIXED_HDR_LEN) { - zlog_err("PDU is too short to be IS-IS."); + flog_err(ISIS_ERR_PACKET, "PDU is too short to be IS-IS."); return ISIS_ERROR; } @@ -1365,12 +1369,14 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) uint8_t max_area_addrs = stream_getc(circuit->rcv_stream); if (idrp == ISO9542_ESIS) { - zlog_err("No support for ES-IS packet IDRP=%" PRIx8, idrp); + flog_err(LIB_ERR_DEVELOPMENT, + "No support for ES-IS packet IDRP=%" PRIx8, idrp); return ISIS_ERROR; } if (idrp != ISO10589_ISIS) { - zlog_err("Not an IS-IS packet IDRP=%" PRIx8, idrp); + flog_err(ISIS_ERR_PACKET, "Not an IS-IS packet IDRP=%" PRIx8, + idrp); return ISIS_ERROR; } @@ -1380,7 +1386,8 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) } if (id_len != 0 && id_len != ISIS_SYS_ID_LEN) { - zlog_err( + flog_err( + ISIS_ERR_PACKET, "IDFieldLengthMismatch: ID Length field in a received PDU %" PRIu8 ", while the parameter for this IS is %u", id_len, ISIS_SYS_ID_LEN); @@ -1394,14 +1401,16 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) } if (length != expected_length) { - zlog_err("Exepected fixed header length = %" PRIu8 - " but got %" PRIu8, - expected_length, length); + flog_err(ISIS_ERR_PACKET, + "Exepected fixed header length = %" PRIu8 + " but got %" PRIu8, + expected_length, length); return ISIS_ERROR; } if (stream_get_endp(circuit->rcv_stream) < length) { - zlog_err( + flog_err( + ISIS_ERR_PACKET, "PDU is too short to contain fixed header of given PDU type."); return ISIS_ERROR; } @@ -1419,7 +1428,8 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) /* either 3 or 0 */ if (max_area_addrs != 0 && max_area_addrs != isis->max_area_addrs) { - zlog_err( + flog_err( + ISIS_ERR_PACKET, "maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8 " while the parameter for this IS is %u", max_area_addrs, isis->max_area_addrs); @@ -1643,9 +1653,10 @@ int send_hello(struct isis_circuit *circuit, int level) retval = circuit->tx(circuit, level); if (retval != ISIS_OK) - zlog_err("ISIS-Adj (%s): Send L%d IIH on %s failed", - circuit->area->area_tag, level, - circuit->interface->name); + flog_err(ISIS_ERR_PACKET, + "ISIS-Adj (%s): Send L%d IIH on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); return retval; } @@ -1840,9 +1851,10 @@ int send_csnp(struct isis_circuit *circuit, int level) int retval = circuit->tx(circuit, level); if (retval != ISIS_OK) { - zlog_err("ISIS-Snp (%s): Send L%d CSNP on %s failed", - circuit->area->area_tag, level, - circuit->interface->name); + flog_err(ISIS_ERR_PACKET, + "ISIS-Snp (%s): Send L%d CSNP on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); isis_free_tlvs(tlvs); return retval; } @@ -2004,9 +2016,10 @@ static int send_psnp(int level, struct isis_circuit *circuit) int retval = circuit->tx(circuit, level); if (retval != ISIS_OK) { - zlog_err("ISIS-Snp (%s): Send L%d PSNP on %s failed", - circuit->area->area_tag, level, - circuit->interface->name); + flog_err(ISIS_ERR_PACKET, + "ISIS-Snp (%s): Send L%d PSNP on %s failed", + circuit->area->area_tag, level, + circuit->interface->name); isis_free_tlvs(tlvs); return retval; } @@ -2111,7 +2124,8 @@ int send_lsp(struct thread *thread) * than * the circuit's MTU. So handle and log this case here. */ if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream)) { - zlog_err( + flog_err( + ISIS_ERR_PACKET, "ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08" PRIx32 ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16 "s on %s. LSP Size is %zu while interface stream size is %zu.", @@ -2146,11 +2160,12 @@ int send_lsp(struct thread *thread) clear_srm = 0; retval = circuit->tx(circuit, lsp->level); if (retval != ISIS_OK) { - zlog_err("ISIS-Upd (%s): Send L%d LSP on %s failed %s", - circuit->area->area_tag, lsp->level, - circuit->interface->name, - (retval == ISIS_WARNING) ? "temporarily" - : "permanently"); + flog_err(ISIS_ERR_PACKET, + "ISIS-Upd (%s): Send L%d LSP on %s failed %s", + circuit->area->area_tag, lsp->level, + circuit->interface->name, + (retval == ISIS_WARNING) ? "temporarily" + : "permanently"); } out: diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c index fd82b85f5..2f6526bc5 100644 --- a/isisd/isis_pfpacket.c +++ b/isisd/isis_pfpacket.c @@ -31,6 +31,7 @@ #include "network.h" #include "stream.h" #include "if.h" +#include "lib_errors.h" #include "isisd/dict.h" #include "isisd/isis_constants.h" @@ -184,35 +185,30 @@ int isis_sock_init(struct isis_circuit *circuit) { int retval = ISIS_OK; - if (isisd_privs.change(ZPRIVS_RAISE)) - zlog_err("%s: could not raise privs, %s", __func__, - safe_strerror(errno)); + frr_elevate_privs(&isisd_privs) { - retval = open_packet_socket(circuit); + retval = open_packet_socket(circuit); - if (retval != ISIS_OK) { - zlog_warn("%s: could not initialize the socket", __func__); - goto end; - } + if (retval != ISIS_OK) { + zlog_warn("%s: could not initialize the socket", + __func__); + break; + } /* Assign Rx and Tx callbacks are based on real if type */ - if (if_is_broadcast(circuit->interface)) { - circuit->tx = isis_send_pdu_bcast; - circuit->rx = isis_recv_pdu_bcast; - } else if (if_is_pointopoint(circuit->interface)) { - circuit->tx = isis_send_pdu_p2p; - circuit->rx = isis_recv_pdu_p2p; - } else { - zlog_warn("isis_sock_init(): unknown circuit type"); - retval = ISIS_WARNING; - goto end; + if (if_is_broadcast(circuit->interface)) { + circuit->tx = isis_send_pdu_bcast; + circuit->rx = isis_recv_pdu_bcast; + } else if (if_is_pointopoint(circuit->interface)) { + circuit->tx = isis_send_pdu_p2p; + circuit->rx = isis_recv_pdu_p2p; + } else { + zlog_warn("isis_sock_init(): unknown circuit type"); + retval = ISIS_WARNING; + break; + } } -end: - if (isisd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs, %s", __func__, - safe_strerror(errno)); - return retval; } diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 63f8b34be..341921146 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -38,6 +38,7 @@ #include "jhash.h" #include "skiplist.h" #include "srcdest_table.h" +#include "lib_errors.h" #include "isis_constants.h" #include "isis_common.h" @@ -437,7 +438,7 @@ static void isis_vertex_id_init(struct isis_vertex *vertex, union isis_N *n, } else if (VTYPE_IP(vtype)) { memcpy(&vertex->N.ip, &n->ip, sizeof(n->ip)); } else { - zlog_err("WTF!"); + flog_err(LIB_ERR_DEVELOPMENT, "Unknown Vertex Type"); } } diff --git a/isisd/subdir.am b/isisd/subdir.am index 7b56715fa..7b8be4616 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -15,6 +15,7 @@ isisd_libisis_a_SOURCES = \ isisd/isis_csm.c \ isisd/isis_dr.c \ isisd/isis_dynhn.c \ + isisd/isis_errors.c \ isisd/isis_events.c \ isisd/isis_flags.c \ isisd/isis_lsp.c \ @@ -44,6 +45,7 @@ noinst_HEADERS += \ isisd/isis_csm.h \ isisd/isis_dr.h \ isisd/isis_dynhn.h \ + isisd/isis_errors.h \ isisd/isis_events.h \ isisd/isis_flags.h \ isisd/isis_lsp.h \ diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index b51ff82ce..e830263de 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -42,6 +42,7 @@ #include "filter.h" #include "qobj.h" #include "libfrr.h" +#include "lib_errors.h" static void ldpd_shutdown(void); static pid_t start_child(enum ldpd_process, char *, int, int); @@ -483,8 +484,9 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync) nullfd = open("/dev/null", O_RDONLY | O_NOCTTY); if (nullfd == -1) { - zlog_err("%s: failed to open /dev/null: %s", __func__, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "%s: failed to open /dev/null: %s", __func__, + safe_strerror(errno)); } else { dup2(nullfd, 0); dup2(nullfd, 1); diff --git a/ldpd/socket.c b/ldpd/socket.c index aefa3461a..bebd7a7d6 100644 --- a/ldpd/socket.c +++ b/ldpd/socket.c @@ -41,7 +41,6 @@ ldp_create_socket(int af, enum socket_type type) #ifdef __OpenBSD__ int opt; #endif - int save_errno; /* create socket */ switch (type) { @@ -80,25 +79,18 @@ ldp_create_socket(int af, enum socket_type type) sock_set_bindany(fd, 1); break; } - if (ldpd_privs.change(ZPRIVS_RAISE)) - log_warn("%s: could not raise privs", __func__); - if (sock_set_reuse(fd, 1) == -1) { - if (ldpd_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); - close(fd); - return (-1); - } - if (bind(fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) { - save_errno = errno; - if (ldpd_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); - log_warnx("%s: error binding socket: %s", __func__, - safe_strerror(save_errno)); - close(fd); - return (-1); + frr_elevate_privs(&ldpd_privs) { + if (sock_set_reuse(fd, 1) == -1) { + close(fd); + return (-1); + } + if (bind(fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) { + log_warnx("%s: error binding socket: %s", __func__, + safe_strerror(errno)); + close(fd); + return (-1); + } } - if (ldpd_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); /* set options */ switch (af) { @@ -262,17 +254,13 @@ int sock_set_bindany(int fd, int enable) { #ifdef HAVE_SO_BINDANY - if (ldpd_privs.change(ZPRIVS_RAISE)) - log_warn("%s: could not raise privs", __func__); - if (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &enable, - sizeof(int)) < 0) { - if (ldpd_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); - log_warn("%s: error setting SO_BINDANY", __func__); - return (-1); + frr_elevate_privs(&ldpd_privs) { + if (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &enable, + sizeof(int)) < 0) { + log_warn("%s: error setting SO_BINDANY", __func__); + return (-1); + } } - if (ldpd_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); return (0); #elif defined(HAVE_IP_FREEBIND) if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &enable, sizeof(int)) < 0) { @@ -306,14 +294,10 @@ sock_set_md5sig(int fd, int af, union ldpd_addr *addr, const char *password) #if HAVE_DECL_TCP_MD5SIG addr2sa(af, addr, 0, &su); - if (ldpe_privs.change(ZPRIVS_RAISE)) { - log_warn("%s: could not raise privs", __func__); - return (-1); + frr_elevate_privs(&ldpe_privs) { + ret = sockopt_tcp_signature(fd, &su, password); + save_errno = errno; } - ret = sockopt_tcp_signature(fd, &su, password); - save_errno = errno; - if (ldpe_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); #endif /* HAVE_TCP_MD5SIG */ if (ret < 0) log_warnx("%s: can't set TCP_MD5SIG option on fd %d: %s", diff --git a/lib/agentx.c b/lib/agentx.c index 302bbf0a4..8e6493d4d 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -31,6 +31,7 @@ #include "memory.h" #include "linklist.h" #include "version.h" +#include "lib_errors.h" static int agentx_enabled = 0; @@ -141,16 +142,20 @@ static int agentx_log_callback(int major, int minor, void *serverarg, msg[strlen(msg) - 1] = '\0'; switch (slm->priority) { case LOG_EMERG: - zlog_err("snmp[emerg]: %s", msg ? msg : slm->msg); + flog_err(LIB_ERR_SNMP, + "snmp[emerg]: %s", msg ? msg : slm->msg); break; case LOG_ALERT: - zlog_err("snmp[alert]: %s", msg ? msg : slm->msg); + flog_err(LIB_ERR_SNMP, + "snmp[alert]: %s", msg ? msg : slm->msg); break; case LOG_CRIT: - zlog_err("snmp[crit]: %s", msg ? msg : slm->msg); + flog_err(LIB_ERR_SNMP, + "snmp[crit]: %s", msg ? msg : slm->msg); break; case LOG_ERR: - zlog_err("snmp[err]: %s", msg ? msg : slm->msg); + flog_err(LIB_ERR_SNMP, + "snmp[err]: %s", msg ? msg : slm->msg); break; case LOG_WARNING: zlog_warn("snmp[warning]: %s", msg ? msg : slm->msg); diff --git a/lib/bfd.h b/lib/bfd.h index 94430051a..f824b0fd9 100644 --- a/lib/bfd.h +++ b/lib/bfd.h @@ -24,6 +24,7 @@ #define _ZEBRA_BFD_H #include "lib/json.h" +#include "lib/zclient.h" #define BFD_DEF_MIN_RX 300 #define BFD_MIN_MIN_RX 50 diff --git a/lib/buffer.c b/lib/buffer.c index b573981c1..0292c85da 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -25,6 +25,8 @@ #include "buffer.h" #include "log.h" #include "network.h" +#include "lib_errors.h" + #include DEFINE_MTYPE_STATIC(LIB, BUFFER, "Buffer") @@ -341,7 +343,8 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width, iov_alloc * sizeof(*iov)); } else { /* This should absolutely never occur. */ - zlog_err( + flog_err_sys( + LIB_ERR_SYSTEM_CALL, "%s: corruption detected: iov_small overflowed; " "head %p, tail %p, head->next %p", __func__, (void *)b->head, @@ -456,9 +459,9 @@ in one shot. */ while (written > 0) { struct buffer_data *d; if (!(d = b->head)) { - zlog_err( - "%s: corruption detected: buffer queue empty, " - "but written is %lu", + flog_err( + LIB_ERR_DEVELOPMENT, + "%s: corruption detected: buffer queue empty, but written is %lu", __func__, (unsigned long)written); break; } diff --git a/lib/command.c b/lib/command.c index 7eda239ee..1df644210 100644 --- a/lib/command.c +++ b/lib/command.c @@ -45,6 +45,7 @@ #include "libfrr.h" #include "jhash.h" #include "hook.h" +#include "lib_errors.h" DEFINE_MTYPE(LIB, HOST, "Host config") DEFINE_MTYPE(LIB, COMPLETION, "Completion item") @@ -2416,7 +2417,8 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel) cwd[MAXPATHLEN] = '\0'; if (getcwd(cwd, MAXPATHLEN) == NULL) { - zlog_err("config_log_file: Unable to alloc mem!"); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "config_log_file: Unable to alloc mem!"); return CMD_WARNING_CONFIG_FAILED; } diff --git a/lib/command_parse.y b/lib/command_parse.y index 0f3e42219..1b304a98b 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -404,8 +404,8 @@ yyerror (CMD_YYLTYPE *loc, struct parser_ctx *ctx, char const *msg) char spacing[256]; int lineno = 0; - zlog_err ("%s: FATAL parse error: %s", __func__, msg); - zlog_err ("%s: %d:%d-%d of this command definition:", __func__, loc->first_line, loc->first_column, loc->last_column); + zlog_notice ("%s: FATAL parse error: %s", __func__, msg); + zlog_notice ("%s: %d:%d-%d of this command definition:", __func__, loc->first_line, loc->first_column, loc->last_column); line = tmpstr; do { @@ -414,7 +414,7 @@ yyerror (CMD_YYLTYPE *loc, struct parser_ctx *ctx, char const *msg) if (eol) *eol++ = '\0'; - zlog_err ("%s: | %s", __func__, line); + zlog_notice ("%s: | %s", __func__, line); if (lineno == loc->first_line && lineno == loc->last_line && loc->first_column < (int)sizeof(spacing) - 1 && loc->last_column < (int)sizeof(spacing) - 1) { @@ -426,7 +426,7 @@ yyerror (CMD_YYLTYPE *loc, struct parser_ctx *ctx, char const *msg) memset(spacing, ' ', loc->first_column - 1); memset(spacing + loc->first_column - 1, '^', len); spacing[loc->first_column - 1 + len] = '\0'; - zlog_err ("%s: | %s", __func__, spacing); + zlog_notice ("%s: | %s", __func__, spacing); } } while ((line = eol)); free(tmpstr); diff --git a/lib/ferr.c b/lib/ferr.c index 45574520a..2fa5db6f3 100644 --- a/lib/ferr.c +++ b/lib/ferr.c @@ -19,14 +19,22 @@ #include #include #include +#include #include "ferr.h" #include "vty.h" #include "jhash.h" #include "memory.h" +#include "hash.h" +#include "command.h" +#include "json.h" +#include "linklist.h" DEFINE_MTYPE_STATIC(LIB, ERRINFO, "error information") +/* + * Thread-specific key for temporary storage of allocated ferr. + */ static pthread_key_t errkey; static void ferr_free(void *arg) @@ -46,6 +54,160 @@ static void err_key_fini(void) pthread_key_delete(errkey); } +/* + * Global shared hash table holding reference text for all defined errors. + */ +pthread_mutex_t refs_mtx = PTHREAD_MUTEX_INITIALIZER; +struct hash *refs; + +static int ferr_hash_cmp(const void *a, const void *b) +{ + const struct log_ref *f_a = a; + const struct log_ref *f_b = b; + + return f_a->code == f_b->code; +} + +static inline unsigned int ferr_hash_key(void *a) +{ + struct log_ref *f = a; + + return f->code; +} + +void log_ref_add(struct log_ref *ref) +{ + uint32_t i = 0; + + pthread_mutex_lock(&refs_mtx); + { + while (ref[i].code != END_FERR) { + hash_get(refs, &ref[i], hash_alloc_intern); + i++; + } + } + pthread_mutex_unlock(&refs_mtx); +} + +struct log_ref *log_ref_get(uint32_t code) +{ + struct log_ref holder; + struct log_ref *ref; + + holder.code = code; + pthread_mutex_lock(&refs_mtx); + { + ref = hash_lookup(refs, &holder); + } + pthread_mutex_unlock(&refs_mtx); + + return ref; +} + +void log_ref_display(struct vty *vty, uint32_t code, bool json) +{ + struct log_ref *ref; + struct json_object *top, *obj; + struct list *errlist; + struct listnode *ln; + + if (json) + top = json_object_new_object(); + + pthread_mutex_lock(&refs_mtx); + { + errlist = code ? list_new() : hash_to_list(refs); + } + pthread_mutex_unlock(&refs_mtx); + + if (code) { + ref = log_ref_get(code); + if (!ref) { + vty_out(vty, "Code %"PRIu32" - Unknown\n", code); + return; + } + listnode_add(errlist, ref); + } + + for (ALL_LIST_ELEMENTS_RO(errlist, ln, ref)) { + if (json) { + char key[11]; + + snprintf(key, sizeof(key), "%"PRIu32, ref->code); + obj = json_object_new_object(); + json_object_string_add(obj, "title", ref->title); + json_object_string_add(obj, "description", + ref->description); + json_object_string_add(obj, "suggestion", + ref->suggestion); + json_object_object_add(top, key, obj); + } else { + char pbuf[256]; + char ubuf[256]; + + snprintf(pbuf, sizeof(pbuf), "\nError %"PRIu32" - %s", + code, ref->title); + memset(ubuf, '=', strlen(pbuf)); + ubuf[sizeof(ubuf) - 1] = '\0'; + + vty_out(vty, "%s\n%s\n", pbuf, ubuf); + vty_out(vty, "Description:\n%s\n\n", ref->description); + vty_out(vty, "Recommendation:\n%s\n", ref->suggestion); + } + } + + if (json) { + const char *str = json_object_to_json_string_ext( + top, JSON_C_TO_STRING_PRETTY); + vty_out(vty, "%s\n", str); + json_object_free(top); + } + + list_delete_and_null(&errlist); +} + +DEFUN_NOSH(show_error_code, + show_error_code_cmd, + "show error <(1-4294967296)|all> [json]", + SHOW_STR + "Information on errors\n" + "Error code to get info about\n" + "Information on all errors\n" + JSON_STR) +{ + bool json = strmatch(argv[argc-1]->text, "json"); + uint32_t arg = 0; + + if (!strmatch(argv[2]->text, "all")) + arg = strtoul(argv[2]->arg, NULL, 10); + + log_ref_display(vty, arg, json); + return CMD_SUCCESS; +} + +void log_ref_init(void) +{ + pthread_mutex_lock(&refs_mtx); + { + refs = hash_create(ferr_hash_key, ferr_hash_cmp, + "Error Reference Texts"); + } + pthread_mutex_unlock(&refs_mtx); + + install_element(VIEW_NODE, &show_error_code_cmd); +} + +void log_ref_fini(void) +{ + pthread_mutex_lock(&refs_mtx); + { + hash_clean(refs, NULL); + hash_free(refs); + refs = NULL; + } + pthread_mutex_unlock(&refs_mtx); +} + const struct ferr *ferr_get_last(ferr_r errval) { struct ferr *last_error = pthread_getspecific(errkey); diff --git a/lib/ferr.h b/lib/ferr.h index 2f100c1b0..335875c16 100644 --- a/lib/ferr.h +++ b/lib/ferr.h @@ -25,6 +25,8 @@ #include #include +#include "vty.h" + /* return type when this error indication stuff is used. * * guaranteed to have boolean evaluation to "false" when OK, "true" when error @@ -93,6 +95,66 @@ struct ferr { char pathname[PATH_MAX]; }; +/* Numeric ranges assigned to daemons for use as error codes. */ +#define BABEL_FERR_START 0x01000001 +#define BABEL_FRRR_END 0x01FFFFFF +#define BGP_FERR_START 0x02000001 +#define BGP_FERR_END 0x02FFFFFF +#define EIGRP_FERR_START 0x03000001 +#define EIGRP_FERR_END 0x03FFFFFF +#define ISIS_FERR_START 0x04000001 +#define ISIS_FERR_END 0x04FFFFFF +#define LDP_FERR_START 0x05000001 +#define LDP_FERR_END 0x05FFFFFF +#define LIB_FERR_START 0x06000001 +#define LIB_FERR_END 0x06FFFFFF +#define NHRP_FERR_START 0x07000001 +#define NHRP_FERR_END 0x07FFFFFF +#define OSPF_FERR_START 0x08000001 +#define OSPF_FERR_END 0x08FFFFFF +#define OSPFV3_FERR_START 0x09000001 +#define OSPFV3_FERR_END 0x09FFFFFF +#define PBR_FERR_START 0x0A000001 +#define PBR_FERR_END 0x0AFFFFFF +#define PIM_FERR_START 0x0B000001 +#define PIM_FERR_STOP 0x0BFFFFFF +#define RIP_FERR_START 0x0C000001 +#define RIP_FERR_STOP 0x0CFFFFFF +#define RIPNG_FERR_START 0x0D000001 +#define RIPNG_FERR_STOP 0x0DFFFFFF +#define SHARP_FERR_START 0x0E000001 +#define SHARP_FERR_END 0x0EFFFFFF +#define VTYSH_FERR_START 0x0F000001 +#define VTYSH_FRR_END 0x0FFFFFFF +#define WATCHFRR_FERR_START 0x10000001 +#define WATCHFRR_FERR_END 0x10FFFFFF +#define ZEBRA_FERR_START 0xF1000001 +#define ZEBRA_FERR_END 0xF1FFFFFF +#define END_FERR 0xFFFFFFFF + +struct log_ref { + /* Unique error code displayed to end user as a reference. -1 means + * this is an uncoded error that does not have reference material. */ + uint32_t code; + /* Ultra brief title */ + const char *title; + /* Brief description of error */ + const char *description; + /* Remedial suggestion */ + const char *suggestion; +}; + +void log_ref_add(struct log_ref *ref); +struct log_ref *log_ref_get(uint32_t code); +void log_ref_display(struct vty *vty, uint32_t code, bool json); + +/* + * This function should be called by the + * code in libfrr.c + */ +void log_ref_init(void); +void log_ref_fini(void); + /* get error details. * * NB: errval/ferr_r does NOT carry the full error information. It's only @@ -101,8 +163,10 @@ struct ferr { */ const struct ferr *ferr_get_last(ferr_r errval); -/* can optionally be called at strategic locations. - * always returns 0. */ +/* + * Can optionally be called at strategic locations. + * Always returns 0. + */ ferr_r ferr_clear(void); /* do NOT call these functions directly. only for macro use! */ diff --git a/lib/frr_zmq.c b/lib/frr_zmq.c index 3153e697f..02d9b68bc 100644 --- a/lib/frr_zmq.c +++ b/lib/frr_zmq.c @@ -24,6 +24,7 @@ #include "memory.h" #include "frr_zmq.h" #include "log.h" +#include "lib_errors.h" DEFINE_MTYPE_STATIC(LIB, ZEROMQ_CB, "ZeroMQ callback") @@ -140,7 +141,8 @@ static int frrzmq_read_msg(struct thread *t) return 0; out_err: - zlog_err("ZeroMQ read error: %s(%d)", strerror(errno), errno); + flog_err(LIB_ERR_ZMQ, "ZeroMQ read error: %s(%d)", strerror(errno), + errno); if (cb->read.cb_error) cb->read.cb_error(cb->read.arg, cb->zmqsock); return 1; @@ -253,7 +255,8 @@ static int frrzmq_write_msg(struct thread *t) return 0; out_err: - zlog_err("ZeroMQ write error: %s(%d)", strerror(errno), errno); + flog_err(LIB_ERR_ZMQ, "ZeroMQ write error: %s(%d)", strerror(errno), + errno); if (cb->write.cb_error) cb->write.cb_error(cb->write.arg, cb->zmqsock); return 1; diff --git a/lib/hash.h b/lib/hash.h index 12c214e46..2b4ea48f3 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -167,7 +167,9 @@ hash_create_size(unsigned int size, unsigned int (*hash_key)(void *), * hash table to operate on * * data - * data to insert or retrieve + * data to insert or retrieve - A hash backet will not be created if + * the alloc_func returns a NULL pointer and nothing will be added to + * the hash. As such backet->data will always be non-NULL. * * alloc_func * function to call if the item is not found in the hash table. This @@ -236,6 +238,8 @@ extern void *hash_release(struct hash *hash, void *data); * during the walk will cause undefined behavior in that some new entries * will be walked and some will not. So do not do this. * + * The backet passed to func will have a non-NULL data pointer. + * * hash * hash table to operate on * @@ -256,6 +260,8 @@ extern void hash_iterate(struct hash *hash, * during the walk will cause undefined behavior in that some new entries * will be walked and some will not. So do not do this. * + * The backet passed to func will have a non-NULL data pointer. + * * hash * hash table to operate on * diff --git a/lib/if.c b/lib/if.c index dd7d21038..6023624dc 100644 --- a/lib/if.c +++ b/lib/if.c @@ -23,6 +23,7 @@ #include "linklist.h" #include "vector.h" +#include "lib_errors.h" #include "vty.h" #include "command.h" #include "vrf.h" diff --git a/lib/if.h b/lib/if.h index 7b65bbd2e..3a9c4af84 100644 --- a/lib/if.h +++ b/lib/if.h @@ -297,28 +297,32 @@ DECLARE_QOBJ_TYPE(interface) #define IFNAME_RB_INSERT(vrf, ifp) \ if (RB_INSERT(if_name_head, &vrf->ifaces_by_name, (ifp))) \ - zlog_err( \ + flog_err( \ + LIB_ERR_INTERFACE, \ "%s(%s): corruption detected -- interface with this " \ "name exists already in VRF %u!", \ __func__, (ifp)->name, (ifp)->vrf_id); #define IFNAME_RB_REMOVE(vrf, ifp) \ if (RB_REMOVE(if_name_head, &vrf->ifaces_by_name, (ifp)) == NULL) \ - zlog_err( \ + flog_err( \ + LIB_ERR_INTERFACE, \ "%s(%s): corruption detected -- interface with this " \ "name doesn't exist in VRF %u!", \ __func__, (ifp)->name, (ifp)->vrf_id); #define IFINDEX_RB_INSERT(vrf, ifp) \ if (RB_INSERT(if_index_head, &vrf->ifaces_by_index, (ifp))) \ - zlog_err( \ + flog_err( \ + LIB_ERR_INTERFACE, \ "%s(%u): corruption detected -- interface with this " \ "ifindex exists already in VRF %u!", \ __func__, (ifp)->ifindex, (ifp)->vrf_id); #define IFINDEX_RB_REMOVE(vrf, ifp) \ if (RB_REMOVE(if_index_head, &vrf->ifaces_by_index, (ifp)) == NULL) \ - zlog_err( \ + flog_err( \ + LIB_ERR_INTERFACE, \ "%s(%u): corruption detected -- interface with this " \ "ifindex doesn't exist in VRF %u!", \ __func__, (ifp)->ifindex, (ifp)->vrf_id); diff --git a/lib/lib_errors.c b/lib/lib_errors.c new file mode 100644 index 000000000..332a5b1d4 --- /dev/null +++ b/lib/lib_errors.c @@ -0,0 +1,118 @@ +/* + * 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 "lib_errors.h" + +/* clang-format off */ +static struct log_ref ferr_lib_err[] = { + { + .code = LIB_ERR_PRIVILEGES, + .title = "Failure to raise or lower privileges", + .description = "FRR attempted to raise or lower its privileges and was unable to do so", + .suggestion = "Ensure that you are running FRR as the frr user and that the user has sufficient 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_SOCKET, + .title = "Socket Error", + .description = "When attempting to access a socket a system error has occured and we were unable to properly complete the request", + .suggestion = "Ensure that there are sufficient system resources available and ensure that the frr user has sufficient permisions to work", + }, + { + .code = LIB_ERR_ZAPI_MISSMATCH, + .title = "ZAPI Error", + .description = "A version miss-match has been detected between zebra and client protocol", + .suggestion = "Two different versions of FRR have been installed and the install is not properly setup. Completely stop FRR, remove it from the system and reinstall. Typically only developers should see this issue." + }, + { + .code = LIB_ERR_ZAPI_ENCODE, + .title = "ZAPI Error", + .description = "The ZAPI subsystem has detected an encoding issue, between zebra and a client protocol", + .suggestion = "Restart FRR" + }, + { + .code = LIB_ERR_ZAPI_SOCKET, + .title = "ZAPI Error", + .description = "The ZAPI subsystem has detected a socket error between zebra and a client", + .suggestion = "Restart FRR" + }, + { + .code = LIB_ERR_SYSTEM_CALL, + .title = "System Call Error", + .description = "FRR has detected a error from using a vital system call and has probably already exited", + .suggestion = "Ensure permissions are correct for FRR files, users and groups are correct. Additionally check that sufficient system resources are available." + }, + { + .code = LIB_ERR_VTY, + .title = "VTY Subsystem Error", + .description = "FRR has detected a problem with the specified configuration file", + .suggestion = "Ensure configuration file exists and has correct permissions for operations Additionally ensure that all config lines are correct as well", + }, + { + .code = LIB_ERR_SNMP, + .title = "SNMP Subsystem Error", + .description = "FRR has detected a problem with the snmp library it uses A callback from this subsystem has indicated some error", + .suggestion = "Examine callback message and ensure snmp is properly setup and working" + }, + { + .code = LIB_ERR_INTERFACE, + .title = "Interface Subsystem Error", + .description = "FRR has detected a problem with interface data from the kernel as it deviates from what we would expect to happen via normal netlink messaging", + .suggestion = "Open an Issue with all relevant log files and restart FRR" + }, + { + .code = LIB_ERR_NS, + .title = "NameSpace Subsystem Error", + .description = "FRR has detected a problem with NameSpace data from the kernel as it deviates from what we would expect to happen via normal kernel messaging", + .suggestion = "Open an Issue with all relevant log files and restart FRR" + }, + { + .code = LIB_ERR_DEVELOPMENT, + .title = "Developmental Escape Error", + .description = "FRR has detected an issue where new development has not properly updated all code paths.", + .suggestion = "Open an Issue with all relevant log files" + }, + { + .code = LIB_ERR_ZMQ, + .title = "ZMQ Subsystem Error", + .description = "FRR has detected an issue with the Zero MQ subsystem and ZeroMQ is not working properly now", + .suggestion = "Open an Issue with all relevant log files and restart FRR" + }, + { + .code = LIB_ERR_UNAVAILABLE, + .title = "Feature or system unavailable", + .description = "FRR was not compiled with support for a particular feature, or it is not available on the current platform", + .suggestion = "Recompile FRR with the feature enabled, or find out what platforms support the feature" + }, + { + .code = END_FERR, + } +}; +/* clang-format on */ + +void lib_error_init(void) +{ + log_ref_add(ferr_lib_err); +} diff --git a/lib/lib_errors.h b/lib/lib_errors.h new file mode 100644 index 000000000..84f5b8dc1 --- /dev/null +++ b/lib/lib_errors.h @@ -0,0 +1,45 @@ +/* + * 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 "lib/ferr.h" + +enum lib_log_refs { + LIB_ERR_PRIVILEGES = LIB_FERR_START, + LIB_ERR_VRF_START, + LIB_ERR_SOCKET, + LIB_ERR_ZAPI_MISSMATCH, + LIB_ERR_ZAPI_ENCODE, + LIB_ERR_ZAPI_SOCKET, + LIB_ERR_SYSTEM_CALL, + LIB_ERR_VTY, + LIB_ERR_SNMP, + LIB_ERR_INTERFACE, + LIB_ERR_NS, + LIB_ERR_DEVELOPMENT, + LIB_ERR_ZMQ, + LIB_ERR_UNAVAILABLE, +}; + +extern void lib_error_init(void); + +#endif diff --git a/lib/libfrr.c b/lib/libfrr.c index 86a5bd29f..821c57f37 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,9 @@ struct thread_master *frr_init(void) vty_init(master); memory_init(); + log_ref_init(); + lib_error_init(); + return master; } @@ -825,8 +829,9 @@ static void frr_terminal_close(int isexit) nullfd = open("/dev/null", O_RDONLY | O_NOCTTY); if (nullfd == -1) { - zlog_err("%s: failed to open /dev/null: %s", __func__, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "%s: failed to open /dev/null: %s", __func__, + safe_strerror(errno)); } else { dup2(nullfd, 0); dup2(nullfd, 1); @@ -897,8 +902,9 @@ void frr_run(struct thread_master *master) } else if (di->daemon_mode) { int nullfd = open("/dev/null", O_RDONLY | O_NOCTTY); if (nullfd == -1) { - zlog_err("%s: failed to open /dev/null: %s", __func__, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "%s: failed to open /dev/null: %s", + __func__, safe_strerror(errno)); } else { dup2(nullfd, 0); dup2(nullfd, 1); @@ -935,6 +941,7 @@ void frr_fini(void) /* memory_init -> nothing needed */ vty_terminate(); cmd_terminate(); + log_ref_fini(); zprivs_terminate(di->privs); /* signal_init -> nothing needed */ thread_master_free(master); diff --git a/lib/log.c b/lib/log.c index 1345ff2fd..e011a78f1 100644 --- a/lib/log.c +++ b/lib/log.c @@ -28,6 +28,8 @@ #include "log_int.h" #include "memory.h" #include "command.h" +#include "lib_errors.h" + #ifndef SUNOS_5 #include #endif @@ -631,7 +633,8 @@ void zlog_backtrace(int priority) size = backtrace(array, array_size(array)); if (size <= 0 || (size_t)size > array_size(array)) { - zlog_err( + flog_err_sys( + LIB_ERR_SYSTEM_CALL, "Cannot get backtrace, returned invalid # of frames %d " "(valid range is between 1 and %lu)", size, (unsigned long)(array_size(array))); @@ -639,7 +642,8 @@ void zlog_backtrace(int priority) } zlog(priority, "Backtrace for %d stack frames:", size); if (!(strings = backtrace_symbols(array, size))) { - zlog_err("Cannot get backtrace symbols (out of memory?)"); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Cannot get backtrace symbols (out of memory?)"); for (i = 0; i < size; i++) zlog(priority, "[bt %d] %p", i, array[i]); } else { @@ -712,10 +716,10 @@ void _zlog_assert_failed(const char *assertion, const char *file, void memory_oom(size_t size, const char *name) { - zlog_err( - "out of memory: failed to allocate %zu bytes for %s" - "object", - size, name); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "out of memory: failed to allocate %zu bytes for %s" + "object", + size, name); zlog_backtrace(LOG_ERR); abort(); } @@ -864,7 +868,8 @@ int zlog_rotate(void) save_errno = errno; umask(oldumask); if (zl->fp == NULL) { - zlog_err( + flog_err_sys( + LIB_ERR_SYSTEM_CALL, "Log rotate failed: cannot open file %s for append: %s", zl->filename, safe_strerror(save_errno)); ret = -1; @@ -984,7 +989,8 @@ static const struct zebra_desc_table *zroute_lookup(unsigned int zroute) unsigned int i; if (zroute >= array_size(route_types)) { - zlog_err("unknown zebra route type: %u", zroute); + flog_err(LIB_ERR_DEVELOPMENT, "unknown zebra route type: %u", + zroute); return &unknown; } if (zroute == route_types[zroute].type) @@ -998,7 +1004,9 @@ static const struct zebra_desc_table *zroute_lookup(unsigned int zroute) return &route_types[i]; } } - zlog_err("internal error: cannot find route type %u in table!", zroute); + flog_err(LIB_ERR_DEVELOPMENT, + "internal error: cannot find route type %u in table!", + zroute); return &unknown; } @@ -1015,7 +1023,8 @@ char zebra_route_char(unsigned int zroute) const char *zserv_command_string(unsigned int command) { if (command >= array_size(command_types)) { - zlog_err("unknown zserv command type: %u", command); + flog_err(LIB_ERR_DEVELOPMENT, "unknown zserv command type: %u", + command); return unknown.string; } return command_types[command].string; diff --git a/lib/log.h b/lib/log.h index 07eb6d5bd..980f3ddf4 100644 --- a/lib/log.h +++ b/lib/log.h @@ -85,6 +85,13 @@ extern void zlog_info(const char *format, ...) PRINTF_ATTRIBUTE(1, 2); extern void zlog_notice(const char *format, ...) PRINTF_ATTRIBUTE(1, 2); extern void zlog_debug(const char *format, ...) PRINTF_ATTRIBUTE(1, 2); +/* For logs which have error codes associated with them */ +#define flog_err(ferr_id, format, ...) \ + zlog_err("[EC %d] " format, ferr_id, ##__VA_ARGS__) +#define flog_err_sys(ferr_id, format, ...) \ + flog_err(ferr_id, format, ##__VA_ARGS__) + + extern void zlog_thread_info(int log_level); /* Set logging level for the given destination. If the log_level diff --git a/lib/mpls.h b/lib/mpls.h index ff6f1d6c9..c9dd60dce 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -22,6 +22,7 @@ #ifndef _QUAGGA_MPLS_H #define _QUAGGA_MPLS_H +#include #include #ifdef MPLS_LABEL_MAX diff --git a/lib/netns_linux.c b/lib/netns_linux.c index a80b51fa0..b8eaa72c2 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -35,10 +35,10 @@ #include "ns.h" #include "log.h" #include "memory.h" - #include "command.h" #include "vty.h" #include "vrf.h" +#include "lib_errors.h" DEFINE_MTYPE_STATIC(LIB, NS, "NetNS Context") DEFINE_MTYPE_STATIC(LIB, NS_NAME, "NetNS Name") @@ -219,15 +219,17 @@ static int ns_enable_internal(struct ns *ns, void (*func)(ns_id_t, void *)) } if (!ns_is_enabled(ns)) { - zlog_err("Can not enable NS %u: %s!", ns->ns_id, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Can not enable NS %u: %s!", ns->ns_id, + safe_strerror(errno)); return 0; } /* Non default NS. leave */ if (ns->ns_id == NS_UNKNOWN) { - zlog_err("Can not enable NS %s %u: Invalid NSID", - ns->name, ns->ns_id); + flog_err(LIB_ERR_NS, + "Can not enable NS %s %u: Invalid NSID", + ns->name, ns->ns_id); return 0; } if (func) @@ -470,8 +472,9 @@ void ns_init(void) if (have_netns_enabled < 0) { ns_default_ns_fd = open(NS_DEFAULT_NAME, O_RDONLY); if (ns_default_ns_fd == -1) - zlog_err("NS initialization failure %d(%s)", - errno, safe_strerror(errno)); + flog_err(LIB_ERR_NS, + "NS initialization failure %d(%s)", errno, + safe_strerror(errno)); } else { ns_default_ns_fd = -1; default_ns = NULL; @@ -492,7 +495,8 @@ void ns_init_management(ns_id_t default_ns_id, ns_id_t internal_ns) ns_init(); default_ns = ns_get_created_internal(NULL, NULL, default_ns_id); if (!default_ns) { - zlog_err("%s: failed to create the default NS!", __func__); + flog_err(LIB_ERR_NS, "%s: failed to create the default NS!", + __func__); exit(1); } if (have_netns()) { @@ -509,7 +513,8 @@ void ns_init_management(ns_id_t default_ns_id, ns_id_t internal_ns) /* Enable the default NS. */ if (!ns_enable(default_ns, NULL)) { - zlog_err("%s: failed to enable the default NS!", __func__); + flog_err(LIB_ERR_NS, "%s: failed to enable the default NS!", + __func__); exit(1); } } diff --git a/lib/pid_output.c b/lib/pid_output.c index 023a166f2..c6120de86 100644 --- a/lib/pid_output.c +++ b/lib/pid_output.c @@ -24,6 +24,7 @@ #include #include "version.h" #include "network.h" +#include "lib_errors.h" #define PIDFILE_MASK 0644 @@ -41,8 +42,9 @@ pid_t pid_output(const char *path) oldumask = umask(0777 & ~PIDFILE_MASK); fd = open(path, O_RDWR | O_CREAT, PIDFILE_MASK); if (fd < 0) { - zlog_err("Can't create pid lock file %s (%s), exiting", path, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Can't create pid lock file %s (%s), exiting", + path, safe_strerror(errno)); umask(oldumask); exit(1); } else { @@ -57,19 +59,22 @@ pid_t pid_output(const char *path) lock.l_whence = SEEK_SET; if (fcntl(fd, F_SETLK, &lock) < 0) { - zlog_err("Could not lock pid_file %s (%s), exiting", - path, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Could not lock pid_file %s (%s), exiting", + path, safe_strerror(errno)); exit(1); } sprintf(buf, "%d\n", (int)pid); pidsize = strlen(buf); if ((tmp = write(fd, buf, pidsize)) != (int)pidsize) - zlog_err( + flog_err_sys( + LIB_ERR_SYSTEM_CALL, "Could not write pid %d to pid_file %s, rc was %d: %s", (int)pid, path, tmp, safe_strerror(errno)); else if (ftruncate(fd, pidsize) < 0) - zlog_err( + flog_err_sys( + LIB_ERR_SYSTEM_CALL, "Could not truncate pid_file %s to %u bytes: %s", path, (unsigned int)pidsize, safe_strerror(errno)); diff --git a/lib/prefix.c b/lib/prefix.c index 751f20cb8..a7f4fda1b 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -27,6 +27,7 @@ #include "memory.h" #include "log.h" #include "jhash.h" +#include "lib_errors.h" DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix") @@ -656,8 +657,9 @@ void prefix_copy(struct prefix *dest, const struct prefix *src) memcpy((void *)dest->u.prefix_flowspec.ptr, (void *)src->u.prefix_flowspec.ptr, len); } else { - zlog_err("prefix_copy(): Unknown address family %d", - src->family); + flog_err(LIB_ERR_DEVELOPMENT, + "prefix_copy(): Unknown address family %d", + src->family); assert(0); } } diff --git a/lib/privs.c b/lib/privs.c index 7c99742d3..34905ca48 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -696,6 +696,41 @@ static int getgrouplist(const char *user, gid_t group, gid_t *groups, } #endif /* HAVE_GETGROUPLIST */ +struct zebra_privs_t *_zprivs_raise(struct zebra_privs_t *privs, + const char *funcname) +{ + int save_errno = errno; + + if (!privs) + return NULL; + + errno = 0; + if (privs->change(ZPRIVS_RAISE)) { + zlog_err("%s: Failed to raise privileges (%s)", + funcname, safe_strerror(errno)); + } + errno = save_errno; + privs->raised_in_funcname = funcname; + return privs; +} + +void _zprivs_lower(struct zebra_privs_t **privs) +{ + int save_errno = errno; + + if (!*privs) + return; + + errno = 0; + if ((*privs)->change(ZPRIVS_LOWER)) { + zlog_err("%s: Failed to lower privileges (%s)", + (*privs)->raised_in_funcname, safe_strerror(errno)); + } + errno = save_errno; + (*privs)->raised_in_funcname = NULL; + *privs = NULL; +} + void zprivs_preinit(struct zebra_privs_t *zprivs) { struct passwd *pwentry = NULL; diff --git a/lib/privs.h b/lib/privs.h index 7fe59328b..b061370b7 100644 --- a/lib/privs.h +++ b/lib/privs.h @@ -62,6 +62,7 @@ struct zebra_privs_t { int (*change)(zebra_privs_ops_t); /* change privileges, 0 on success */ zebra_privs_current_t (*current_state)( void); /* current privilege state */ + const char *raised_in_funcname; }; struct zprivs_ids_t { @@ -81,4 +82,42 @@ extern void zprivs_terminate(struct zebra_privs_t *); /* query for runtime uid's and gid's, eg vty needs this */ extern void zprivs_get_ids(struct zprivs_ids_t *); +/* + * Wrapper around zprivs, to be used as: + * frr_elevate_privs(&privs) { + * ... code ... + * if (error) + * break; -- break can be used to get out of the block + * ... code ... + * } + * + * The argument to frr_elevate_privs() can be NULL to leave privileges as-is + * (mostly useful for conditional privilege-raising, i.e.:) + * frr_elevate_privs(cond ? &privs : NULL) {} + * + * NB: The code block is always executed, regardless of whether privileges + * could be raised or not, or whether NULL was given or not. This is fully + * intentional; the user may have configured some RBAC or similar that we + * are not aware of, but that allows our code to proceed without privileges. + * + * The point of this wrapper is to prevent accidental bugs where privileges + * are elevated but then not dropped. This can happen when, for example, a + * "return", "goto" or "break" in the middle of the elevated-privilege code + * skips past the privilege dropping call. + * + * The macro below uses variable cleanup to drop privileges as soon as the + * code block is left in any way (and thus the _privs variable goes out of + * scope.) _once is just a trick to run the loop exactly once. + */ +extern struct zebra_privs_t *_zprivs_raise(struct zebra_privs_t *privs, + const char *funcname); +extern void _zprivs_lower(struct zebra_privs_t **privs); + +#define frr_elevate_privs(privs) \ + for (struct zebra_privs_t *_once = NULL, \ + *_privs __attribute__( \ + (unused, cleanup(_zprivs_lower))) = \ + _zprivs_raise(privs, __func__); \ + _once == NULL; _once = (void *)1) + #endif /* _ZEBRA_PRIVS_H */ diff --git a/lib/routemap.c b/lib/routemap.c index 4e8682f31..4125bb53a 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -1545,7 +1545,7 @@ static void route_map_clear_reference(struct hash_backet *backet, void *arg) struct route_map_dep *dep = (struct route_map_dep *)backet->data; char *rmap_name; - if (dep && arg) { + if (arg) { rmap_name = (char *)hash_release(dep->dep_rmap_hash, (void *)arg); if (rmap_name) { @@ -1601,9 +1601,8 @@ static void route_map_print_dependency(struct hash_backet *backet, void *data) char *rmap_name = (char *)backet->data; char *dep_name = (char *)data; - if (rmap_name) - zlog_debug("%s: Dependency for %s: %s", __FUNCTION__, dep_name, - rmap_name); + zlog_debug("%s: Dependency for %s: %s", __FUNCTION__, dep_name, + rmap_name); } static int route_map_dep_update(struct hash *dephash, const char *dep_name, @@ -1725,18 +1724,14 @@ static struct hash *route_map_get_dep_hash(route_map_event_t event) static void route_map_process_dependency(struct hash_backet *backet, void *data) { - char *rmap_name; + char *rmap_name = (char *)backet->data; route_map_event_t type = (route_map_event_t)(ptrdiff_t)data; - rmap_name = (char *)backet->data; - - if (rmap_name) { - if (rmap_debug) - zlog_debug("%s: Notifying %s of dependency", - __FUNCTION__, rmap_name); - if (route_map_master.event_hook) - (*route_map_master.event_hook)(type, rmap_name); - } + if (rmap_debug) + zlog_debug("%s: Notifying %s of dependency", + __FUNCTION__, rmap_name); + if (route_map_master.event_hook) + (*route_map_master.event_hook)(type, rmap_name); } void route_map_upd8_dependency(route_map_event_t type, const char *arg, diff --git a/lib/sigevent.c b/lib/sigevent.c index 59eaa8037..034602793 100644 --- a/lib/sigevent.c +++ b/lib/sigevent.c @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef SA_SIGINFO #ifdef HAVE_UCONTEXT_H @@ -83,7 +84,8 @@ int quagga_sigevent_process(void) sigdelset(&newmask, SIGKILL); if ((sigprocmask(SIG_BLOCK, &newmask, &oldmask)) < 0) { - zlog_err("quagga_signal_timer: couldnt block signals!"); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "quagga_signal_timer: couldnt block signals!"); return -1; } #endif /* SIGEVENT_BLOCK_SIGNALS */ diff --git a/lib/skiplist.c b/lib/skiplist.c index a546bb44c..a36bf4713 100644 --- a/lib/skiplist.c +++ b/lib/skiplist.c @@ -60,6 +60,7 @@ #include "log.h" #include "vty.h" #include "skiplist.h" +#include "lib_errors.h" DEFINE_MTYPE_STATIC(LIB, SKIP_LIST, "Skip List") DEFINE_MTYPE_STATIC(LIB, SKIP_LIST_NODE, "Skip Node") @@ -182,7 +183,8 @@ int skiplist_insert(register struct skiplist *l, register void *key, /* DEBUG */ if (!key) { - zlog_err("%s: key is 0, value is %p", __func__, value); + flog_err(LIB_ERR_DEVELOPMENT, "%s: key is 0, value is %p", + __func__, value); } p = l->header; diff --git a/lib/sockopt.c b/lib/sockopt.c index 4ebc43815..878b5ae09 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -27,6 +27,7 @@ #include "log.h" #include "sockopt.h" #include "sockunion.h" +#include "lib_errors.h" void setsockopt_so_recvbuf(int sock, int size) { @@ -61,8 +62,9 @@ int getsockopt_so_sendbuf(const int sock) int ret = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&optval, &optlen); if (ret < 0) { - zlog_err("fd %d: can't getsockopt SO_SNDBUF: %d (%s)", sock, - errno, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "fd %d: can't getsockopt SO_SNDBUF: %d (%s)", sock, + errno, safe_strerror(errno)); return ret; } return optval; @@ -670,8 +672,10 @@ int sockopt_tcp_signature(int sock, union sockunion *su, const char *password) if (ENOENT == errno) ret = 0; else - zlog_err("sockopt_tcp_signature: setsockopt(%d): %s", - sock, safe_strerror(errno)); + flog_err_sys( + LIB_ERR_SYSTEM_CALL, + "sockopt_tcp_signature: setsockopt(%d): %s", + sock, safe_strerror(errno)); } return ret; #else /* HAVE_TCP_MD5SIG */ diff --git a/lib/sockunion.c b/lib/sockunion.c index 44378b536..bbbfbfc42 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -26,6 +26,7 @@ #include "memory.h" #include "log.h" #include "jhash.h" +#include "lib_errors.h" DEFINE_MTYPE_STATIC(LIB, SOCKUNION, "Socket union") @@ -365,14 +366,10 @@ int sockopt_mark_default(int sock, int mark, struct zebra_privs_t *cap) #ifdef SO_MARK int ret; - if (cap->change(ZPRIVS_RAISE)) - zlog_err("routing_socket: Can't raise privileges"); - - ret = setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)); - - if (cap->change(ZPRIVS_LOWER)) - zlog_err("routing_socket: Can't lower privileges"); - + frr_elevate_privs(cap) { + ret = setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, + sizeof(mark)); + } return ret; #else return 0; 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..36111dfea 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!"); + flog_err(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!"); + flog_err(LIB_ERR_VRF_START, + "vrf_init: failed to enable the default VRF!"); exit(1); } @@ -542,20 +545,23 @@ 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)); + flog_err_sys(LIB_ERR_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)); + flog_err_sys(LIB_ERR_SOCKET, + "%s: Can't switchback from VRF %u (%s)", __func__, + vrf_id, safe_strerror(errno)); errno = save_errno; if (ret <= 0) return ret; @@ -758,16 +764,10 @@ DEFUN_NOSH (vrf_netns, if (!pathname) return CMD_WARNING_CONFIG_FAILED; - if (vrf_daemon_privs && - vrf_daemon_privs->change(ZPRIVS_RAISE)) - zlog_err("%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__); + frr_elevate_privs(vrf_daemon_privs) { + ret = vrf_netns_handler_create(vty, vrf, pathname, + NS_UNKNOWN, NS_UNKNOWN); + } return ret; } @@ -905,14 +905,15 @@ 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)); + flog_err_sys(LIB_ERR_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)); + flog_err_sys(LIB_ERR_SOCKET, + "%s: Can't switchback from VRF %u (%s)", __func__, + vrf_id, safe_strerror(errno)); errno = save_errno; return ret; } @@ -923,16 +924,17 @@ 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)); + flog_err_sys(LIB_ERR_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)); + flog_err_sys(LIB_ERR_SOCKET, + "%s: Can't switchback from VRF %u (%s)", __func__, + vrf_id, safe_strerror(errno)); errno = saved_errno; return rc; } @@ -944,14 +946,15 @@ 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)); + flog_err_sys(LIB_ERR_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)); + flog_err_sys(LIB_ERR_SOCKET, + "%s: Can't switchback from VRF %u (%s)", __func__, + vrf_id, safe_strerror(errno)); errno = save_errno; if (ret <= 0) diff --git a/lib/vty.c b/lib/vty.c index 15e934b70..748c14f67 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -40,6 +40,7 @@ #include "network.h" #include "libfrr.h" #include "frrstr.h" +#include "lib_errors.h" #include #include @@ -511,7 +512,7 @@ static int vty_command(struct vty *vty, char *buf) vty_str); /* now log the command */ - zlog_err("%s%s", prompt_str, buf); + zlog_notice("%s%s", prompt_str, buf); } #ifdef CONSUMED_TIME_CHECK @@ -1329,9 +1330,9 @@ static int vty_telnet_option(struct vty *vty, unsigned char *buf, int nbytes) TELNET_NAWS_SB_LEN, (unsigned long)vty->sb_len); else if (sizeof(vty->sb_buf) < TELNET_NAWS_SB_LEN) - zlog_err( - "Bug detected: sizeof(vty->sb_buf) %lu < %d, " - "too small to handle the telnet NAWS option", + flog_err( + LIB_ERR_DEVELOPMENT, + "Bug detected: sizeof(vty->sb_buf) %lu < %d, too small to handle the telnet NAWS option", (unsigned long)sizeof(vty->sb_buf), TELNET_NAWS_SB_LEN); else { @@ -1972,7 +1973,8 @@ static void vty_serv_sock_addrinfo(const char *hostname, unsigned short port) ret = getaddrinfo(hostname, port_str, &req, &ainfo); if (ret != 0) { - zlog_err("getaddrinfo failed: %s", gai_strerror(ret)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "getaddrinfo failed: %s", + gai_strerror(ret)); exit(1); } @@ -2032,8 +2034,9 @@ static void vty_serv_un(const char *path) /* Make UNIX domain socket. */ sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) { - zlog_err("Cannot create unix stream socket: %s", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "Cannot create unix stream socket: %s", + safe_strerror(errno)); return; } @@ -2051,15 +2054,16 @@ static void vty_serv_un(const char *path) ret = bind(sock, (struct sockaddr *)&serv, len); if (ret < 0) { - zlog_err("Cannot bind path %s: %s", path, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "Cannot bind path %s: %s", path, + safe_strerror(errno)); close(sock); /* Avoid sd leak. */ return; } ret = listen(sock, 5); if (ret < 0) { - zlog_err("listen(fd %d) failed: %s", sock, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "listen(fd %d) failed: %s", sock, + safe_strerror(errno)); close(sock); /* Avoid sd leak. */ return; } @@ -2074,8 +2078,9 @@ static void vty_serv_un(const char *path) if ((int)ids.gid_vty > 0) { /* set group of socket */ if (chown(path, -1, ids.gid_vty)) { - zlog_err("vty_serv_un: could chown socket, %s", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "vty_serv_un: could chown socket, %s", + safe_strerror(errno)); } } @@ -2406,8 +2411,9 @@ static void vty_read_file(FILE *confp) nl = strchr(vty->error_buf, '\n'); if (nl) *nl = '\0'; - zlog_err("ERROR: %s on config line %u: %s", message, line_num, - vty->error_buf); + flog_err(LIB_ERR_VTY, + "ERROR: %s on config line %u: %s", message, line_num, + vty->error_buf); } vty_close(vty); @@ -2480,7 +2486,8 @@ bool vty_read_config(const char *config_file, char *config_default_dir) if (config_file != NULL) { if (!IS_DIRECTORY_SEP(config_file[0])) { if (getcwd(cwd, MAXPATHLEN) == NULL) { - zlog_err( + flog_err_sys( + LIB_ERR_SYSTEM_CALL, "Failure to determine Current Working Directory %d!", errno); exit(1); @@ -2495,7 +2502,7 @@ bool vty_read_config(const char *config_file, char *config_default_dir) confp = fopen(fullpath, "r"); if (confp == NULL) { - zlog_err("%s: failed to open configuration file %s: %s", + zlog_warn("%s: failed to open configuration file %s: %s, checking backup", __func__, fullpath, safe_strerror(errno)); confp = vty_use_backup_config(fullpath); @@ -2503,8 +2510,9 @@ bool vty_read_config(const char *config_file, char *config_default_dir) zlog_warn( "WARNING: using backup configuration file!"); else { - zlog_err("can't open configuration file [%s]", - config_file); + flog_err(LIB_ERR_VTY, + "can't open configuration file [%s]", + config_file); exit(1); } } @@ -2540,9 +2548,9 @@ bool vty_read_config(const char *config_file, char *config_default_dir) #endif /* VTYSH */ confp = fopen(config_default_dir, "r"); if (confp == NULL) { - zlog_err("%s: failed to open configuration file %s: %s", - __func__, config_default_dir, - safe_strerror(errno)); + zlog_warn("%s: failed to open configuration file %s: %s, checking backup", + __func__, config_default_dir, + safe_strerror(errno)); confp = vty_use_backup_config(config_default_dir); if (confp) { @@ -2550,8 +2558,9 @@ bool vty_read_config(const char *config_file, char *config_default_dir) "WARNING: using backup configuration file!"); fullpath = config_default_dir; } else { - zlog_err("can't open configuration file [%s]", - config_default_dir); + flog_err(LIB_ERR_VTY, + "can't open configuration file [%s]", + config_default_dir); goto tmp_free_and_out; } } else @@ -3064,12 +3073,14 @@ static void vty_save_cwd(void) * Hence not worrying about it too much. */ if (!chdir(SYSCONFDIR)) { - zlog_err("Failure to chdir to %s, errno: %d", - SYSCONFDIR, errno); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Failure to chdir to %s, errno: %d", + SYSCONFDIR, errno); exit(-1); } if (getcwd(cwd, MAXPATHLEN) == NULL) { - zlog_err("Failure to getcwd, errno: %d", errno); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Failure to getcwd, errno: %d", errno); exit(-1); } } diff --git a/lib/zclient.c b/lib/zclient.c index 38a9e6c78..cc91705ee 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -38,6 +38,7 @@ #include "sockopt.h" #include "pbr.h" #include "nexthop_group.h" +#include "lib_errors.h" DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient") DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs") @@ -212,9 +213,9 @@ int zclient_socket_connect(struct zclient *zclient) set_cloexec(sock); - zclient->privs->change(ZPRIVS_RAISE); - setsockopt_so_sendbuf(sock, 1048576); - zclient->privs->change(ZPRIVS_LOWER); + frr_elevate_privs(zclient->privs) { + setsockopt_so_sendbuf(sock, 1048576); + } /* Connect to zebra. */ ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len); @@ -312,9 +313,9 @@ int zclient_read_header(struct stream *s, int sock, uint16_t *size, STREAM_GETW(s, *cmd); if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) { - zlog_err( - "%s: socket %d version mismatch, marker %d, version %d", - __func__, sock, *marker, *version); + flog_err(LIB_ERR_ZAPI_MISSMATCH, + "%s: socket %d version mismatch, marker %d, version %d", + __func__, sock, *marker, *version); return -1; } @@ -1045,12 +1046,12 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) char buf[PREFIX2STR_BUFFER]; prefix2str(&api->prefix, buf, sizeof(buf)); - zlog_err( - "%s: prefix %s: can't encode " - "%u labels (maximum is %u)", - __func__, buf, - api_nh->label_num, - MPLS_MAX_LABELS); + flog_err(LIB_ERR_ZAPI_ENCODE, + "%s: prefix %s: can't encode " + "%u labels (maximum is %u)", + __func__, buf, + api_nh->label_num, + MPLS_MAX_LABELS); return -1; } @@ -1671,10 +1672,10 @@ static void link_params_set_value(struct stream *s, struct if_link_params *iflp) for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++) iflp->unrsv_bw[i] = stream_getf(s); if (i < bwclassnum) - zlog_err( - "%s: received %d > %d (MAX_CLASS_TYPE) bw entries" - " - outdated library?", - __func__, bwclassnum, MAX_CLASS_TYPE); + flog_err(LIB_ERR_ZAPI_MISSMATCH, + "%s: received %d > %d (MAX_CLASS_TYPE) bw entries" + " - outdated library?", + __func__, bwclassnum, MAX_CLASS_TYPE); } iflp->admin_grp = stream_getl(s); iflp->rmt_as = stream_getl(s); @@ -1703,8 +1704,9 @@ struct interface *zebra_interface_link_params_read(struct stream *s) struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); if (ifp == NULL) { - zlog_err("%s: unknown ifindex %u, shouldn't happen", __func__, - ifindex); + flog_err(LIB_ERR_ZAPI_ENCODE, + "%s: unknown ifindex %u, shouldn't happen", __func__, + ifindex); return NULL; } @@ -2039,7 +2041,8 @@ static int zclient_read_sync_response(struct zclient *zclient, size); } if (ret != 0) { - zlog_err("%s: Invalid Sync Message Reply", __func__); + flog_err(LIB_ERR_ZAPI_ENCODE, + "%s: Invalid Sync Message Reply", __func__); return -1; } @@ -2081,13 +2084,13 @@ int lm_label_manager_connect(struct zclient *zclient) ret = writen(zclient->sock, s->data, stream_get_endp(s)); if (ret < 0) { - zlog_err("Can't write to zclient sock"); + flog_err(LIB_ERR_ZAPI_SOCKET, "Can't write to zclient sock"); close(zclient->sock); zclient->sock = -1; return -1; } if (ret == 0) { - zlog_err("Zclient sock closed"); + flog_err(LIB_ERR_ZAPI_SOCKET, "Zclient sock closed"); close(zclient->sock); zclient->sock = -1; return -1; @@ -2108,13 +2111,13 @@ int lm_label_manager_connect(struct zclient *zclient) /* sanity */ if (proto != zclient->redist_default) - zlog_err( - "Wrong proto (%u) in LM connect response. Should be %u", - proto, zclient->redist_default); + flog_err(LIB_ERR_ZAPI_ENCODE, + "Wrong proto (%u) in LM connect response. Should be %u", + proto, zclient->redist_default); if (instance != zclient->instance) - zlog_err( - "Wrong instId (%u) in LM connect response. Should be %u", - instance, zclient->instance); + flog_err(LIB_ERR_ZAPI_ENCODE, + "Wrong instId (%u) in LM connect response. Should be %u", + instance, zclient->instance); /* result code */ result = stream_getc(s); @@ -2203,13 +2206,15 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, ret = writen(zclient->sock, s->data, stream_get_endp(s)); if (ret < 0) { - zlog_err("Can't write to zclient sock"); + flog_err(LIB_ERR_ZAPI_SOCKET, + "Can't write to zclient sock"); close(zclient->sock); zclient->sock = -1; return -1; } if (ret == 0) { - zlog_err("Zclient sock closed"); + flog_err(LIB_ERR_ZAPI_SOCKET, + "Zclient sock closed"); close(zclient->sock); zclient->sock = -1; return -1; @@ -2230,11 +2235,13 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, /* sanities */ if (proto != zclient->redist_default) - zlog_err("Wrong proto (%u) in get chunk response. Should be %u", - proto, zclient->redist_default); + flog_err(LIB_ERR_ZAPI_ENCODE, + "Wrong proto (%u) in get chunk response. Should be %u", + proto, zclient->redist_default); if (instance != zclient->instance) - zlog_err("Wrong instId (%u) in get chunk response Should be %u", - instance, zclient->instance); + flog_err(LIB_ERR_ZAPI_ENCODE, + "Wrong instId (%u) in get chunk response Should be %u", + instance, zclient->instance); /* keep */ response_keep = stream_getc(s); @@ -2244,14 +2251,15 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, /* not owning this response */ if (keep != response_keep) { - zlog_err( - "Invalid Label chunk: %u - %u, keeps mismatch %u != %u", - *start, *end, keep, response_keep); + flog_err(LIB_ERR_ZAPI_ENCODE, + "Invalid Label chunk: %u - %u, keeps mismatch %u != %u", + *start, *end, keep, response_keep); } /* sanity */ if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN || *end > MPLS_LABEL_UNRESERVED_MAX) { - zlog_err("Invalid Label chunk: %u - %u", *start, *end); + flog_err(LIB_ERR_ZAPI_ENCODE, + "Invalid Label chunk: %u - %u", *start, *end); return -1; } @@ -2301,13 +2309,14 @@ int lm_release_label_chunk(struct zclient *zclient, uint32_t start, ret = writen(zclient->sock, s->data, stream_get_endp(s)); if (ret < 0) { - zlog_err("Can't write to zclient sock"); + flog_err(LIB_ERR_ZAPI_SOCKET, "Can't write to zclient sock"); close(zclient->sock); zclient->sock = -1; return -1; } if (ret == 0) { - zlog_err("Zclient sock connection closed"); + flog_err(LIB_ERR_ZAPI_SOCKET, + "Zclient sock connection closed"); close(zclient->sock); zclient->sock = -1; return -1; @@ -2410,13 +2419,15 @@ int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size, ret = writen(zclient->sock, s->data, stream_get_endp(s)); if (ret < 0) { - zlog_err("%s: can't write to zclient->sock", __func__); + flog_err(LIB_ERR_ZAPI_SOCKET, + "%s: can't write to zclient->sock", __func__); close(zclient->sock); zclient->sock = -1; return -1; } if (ret == 0) { - zlog_err("%s: zclient->sock connection closed", __func__); + flog_err(LIB_ERR_ZAPI_SOCKET, + "%s: zclient->sock connection closed", __func__); close(zclient->sock); zclient->sock = -1; return -1; @@ -2502,7 +2513,8 @@ int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw) stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16); break; default: - zlog_err("%s: unknown af", __func__); + flog_err(LIB_ERR_ZAPI_ENCODE, + "%s: unknown af", __func__); return -1; } @@ -2604,15 +2616,16 @@ static int zclient_read(struct thread *thread) command = stream_getw(zclient->ibuf); if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { - zlog_err( - "%s: socket %d version mismatch, marker %d, version %d", - __func__, zclient->sock, marker, version); + flog_err(LIB_ERR_ZAPI_MISSMATCH, + "%s: socket %d version mismatch, marker %d, version %d", + __func__, zclient->sock, marker, version); return zclient_failed(zclient); } if (length < ZEBRA_HEADER_SIZE) { - zlog_err("%s: socket %d message length %u is less than %d ", - __func__, zclient->sock, length, ZEBRA_HEADER_SIZE); + flog_err(LIB_ERR_ZAPI_MISSMATCH, + "%s: socket %d message length %u is less than %d ", + __func__, zclient->sock, length, ZEBRA_HEADER_SIZE); return zclient_failed(zclient); } diff --git a/nhrpd/nhrp_errors.c b/nhrpd/nhrp_errors.c new file mode 100644 index 000000000..c557ba8a6 --- /dev/null +++ b/nhrpd/nhrp_errors.c @@ -0,0 +1,49 @@ +/* + * NHRP-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 + +#include "lib/ferr.h" +#include "nhrp_errors.h" + +/* clang-format off */ +static struct log_ref ferr_nhrp_err[] = { + { + .code = NHRP_ERR_SWAN, + .title = "NHRP Strong Swan Error", + .description = "NHRP has detected a error with the Strongswan code", + .suggestion = "Ensure that StrongSwan is configured correctly. Restart StrongSwan and FRR" + }, + { + .code = NHRP_ERR_RESOLVER, + .title = "NHRP DNS Resolution", + .description = "NHRP has detected an error in an attempt to resolve a hostname", + .suggestion = "Ensure that DNS is working properly and the hostname is configured in dns. If you are still seeing this error, open an issue" + }, + { + .code = END_FERR, + } +}; +/* clang-format on */ + +void nhrp_error_init(void) +{ + log_ref_add(ferr_nhrp_err); +} diff --git a/nhrpd/nhrp_errors.h b/nhrpd/nhrp_errors.h new file mode 100644 index 000000000..c9e947eb2 --- /dev/null +++ b/nhrpd/nhrp_errors.h @@ -0,0 +1,33 @@ +/* + * NHRP-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 __NHRP_ERRORS_H__ +#define __NHRP_ERRORS_H__ + +#include "lib/ferr.h" + +enum nhrp_log_refs { + NHRP_ERR_SWAN = NHRP_FERR_START, + NHRP_ERR_RESOLVER, +}; + +extern void nhrp_error_init(void); + +#endif diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c index ba1e00ded..e9f44e855 100644 --- a/nhrpd/nhrp_main.c +++ b/nhrpd/nhrp_main.c @@ -23,6 +23,7 @@ #include "nhrpd.h" #include "netlink.h" +#include "nhrp_errors.h" DEFINE_MGROUP(NHRPD, "NHRP") @@ -128,6 +129,7 @@ int main(int argc, char **argv) /* Library inits. */ master = frr_init(); + nhrp_error_init(); vrf_init(NULL, NULL, NULL, NULL); nhrp_interface_init(); resolver_init(); diff --git a/nhrpd/resolver.c b/nhrpd/resolver.c index 415e7523d..dfa5dc3df 100644 --- a/nhrpd/resolver.c +++ b/nhrpd/resolver.c @@ -12,7 +12,10 @@ #include "vector.h" #include "thread.h" +#include "lib_errors.h" + #include "nhrpd.h" +#include "nhrp_errors.h" struct resolver_state { ares_channel channel; @@ -191,9 +194,9 @@ void resolver_resolve(struct resolver_query *query, int af, union sockunion *)) { if (query->callback != NULL) { - zlog_err( - "Trying to resolve '%s', but previous query was not finished yet", - hostname); + flog_err(NHRP_ERR_RESOLVER, + "Trying to resolve '%s', but previous query was not finished yet", + hostname); return; } diff --git a/nhrpd/subdir.am b/nhrpd/subdir.am index 5b06946c8..d66e96822 100644 --- a/nhrpd/subdir.am +++ b/nhrpd/subdir.am @@ -13,6 +13,7 @@ nhrpd_nhrpd_SOURCES = \ nhrpd/netlink_arp.c \ nhrpd/netlink_gre.c \ nhrpd/nhrp_cache.c \ + nhrpd/nhrp_errors.c \ nhrpd/nhrp_event.c \ nhrpd/nhrp_interface.c \ nhrpd/nhrp_main.c \ @@ -34,6 +35,7 @@ noinst_HEADERS += \ nhrpd/debug.h \ nhrpd/list.h \ nhrpd/netlink.h \ + nhrpd/nhrp_errors.h \ nhrpd/nhrp_protocol.h \ nhrpd/nhrpd.h \ nhrpd/os.h \ diff --git a/nhrpd/vici.c b/nhrpd/vici.c index eb3827a12..7cd703414 100644 --- a/nhrpd/vici.c +++ b/nhrpd/vici.c @@ -14,9 +14,11 @@ #include "thread.h" #include "zbuf.h" #include "log.h" -#include "nhrpd.h" +#include "lib_errors.h" +#include "nhrpd.h" #include "vici.h" +#include "nhrp_errors.h" #define ERRNO_IO_RETRY(EN) (((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR)) @@ -212,9 +214,9 @@ static void parse_sa_message(struct vici_message_ctx *ctx, if (str2sockunion(buf, &sactx->local.host) < 0) - zlog_err( - "VICI: bad strongSwan local-host: %s", - buf); + flog_err(NHRP_ERR_SWAN, + "VICI: bad strongSwan local-host: %s", + buf); } else if (blob_equal(key, "local-id") && ctx->nsections == 1) { sactx->local.id = *val; @@ -230,9 +232,9 @@ static void parse_sa_message(struct vici_message_ctx *ctx, if (str2sockunion(buf, &sactx->remote.host) < 0) - zlog_err( - "VICI: bad strongSwan remote-host: %s", - buf); + flog_err(NHRP_ERR_SWAN, + "VICI: bad strongSwan remote-host: %s", + buf); } else if (blob_equal(key, "remote-id") && ctx->nsections == 1) { sactx->remote.id = *val; @@ -275,7 +277,7 @@ static void parse_cmd_response(struct vici_message_ctx *ctx, case VICI_KEY_VALUE: if (blob_equal(key, "errmsg") && blob2buf(val, buf, sizeof(buf))) - zlog_err("VICI: strongSwan: %s", buf); + flog_err(NHRP_ERR_SWAN, "VICI: strongSwan: %s", buf); break; default: break; @@ -334,7 +336,7 @@ static void vici_recv_message(struct vici_conn *vici, struct zbuf *msg) break; case VICI_EVENT_UNKNOWN: case VICI_CMD_UNKNOWN: - zlog_err( + flog_err(NHRP_ERR_SWAN, "VICI: StrongSwan does not support mandatory events (unpatched?)"); break; case VICI_EVENT_CONFIRM: diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index c7cd94bd3..228a525e7 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -26,6 +26,7 @@ #include "command.h" #include "thread.h" #include "linklist.h" +#include "lib_errors.h" #include "ospf6_proto.h" #include "ospf6_lsa.h" @@ -1558,7 +1559,8 @@ int ospf6_receive(struct thread *thread) /* receive message */ len = ospf6_recvmsg(&src, &dst, &ifindex, iovector); if (len > iobuflen) { - zlog_err("Excess message read"); + flog_err(LIB_ERR_DEVELOPMENT, + "Excess message read"); return 0; } @@ -1706,7 +1708,7 @@ static void ospf6_send(struct in6_addr *src, struct in6_addr *dst, /* send message */ len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector); if (len != ntohs(oh->length)) - zlog_err("Could not send entire message"); + flog_err(LIB_ERR_DEVELOPMENT, "Could not send entire message"); } static uint32_t ospf6_packet_max(struct ospf6_interface *oi) diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c index 4790d8f01..8988a53e5 100644 --- a/ospf6d/ospf6_network.c +++ b/ospf6d/ospf6_network.c @@ -25,6 +25,7 @@ #include "sockunion.h" #include "sockopt.h" #include "privs.h" +#include "lib_errors.h" #include "libospf.h" #include "ospf6_proto.h" @@ -75,18 +76,14 @@ static void ospf6_set_checksum(void) /* Make ospf6d's server socket. */ int ospf6_serv_sock(void) { - if (ospf6d_privs.change(ZPRIVS_RAISE)) - zlog_err("ospf6_serv_sock: could not raise privs"); - - ospf6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP); - if (ospf6_sock < 0) { - zlog_warn("Network: can't create OSPF6 socket."); - if (ospf6d_privs.change(ZPRIVS_LOWER)) - zlog_err("ospf_sock_init: could not lower privs"); - return -1; + frr_elevate_privs(&ospf6d_privs) { + + ospf6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP); + if (ospf6_sock < 0) { + zlog_warn("Network: can't create OSPF6 socket."); + return -1; + } } - if (ospf6d_privs.change(ZPRIVS_LOWER)) - zlog_err("ospf_sock_init: could not lower privs"); /* set socket options */ #if 1 @@ -120,8 +117,10 @@ int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option) ret = setsockopt(ospf6_sock, IPPROTO_IPV6, option, &mreq6, sizeof(mreq6)); if (ret < 0) { - zlog_err("Network: setsockopt (%d) on ifindex %d failed: %s", - option, ifindex, safe_strerror(errno)); + flog_err_sys( + LIB_ERR_SOCKET, + "Network: setsockopt (%d) on ifindex %d failed: %s", + option, ifindex, safe_strerror(errno)); return ret; } diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 15d8eb6cf..a099eead4 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -574,8 +574,8 @@ static void route_table_assert(struct ospf6_route_table *table) if (link_error == 0 && num == table->count) return; - zlog_err("PANIC !!"); - zlog_err("Something has gone wrong with ospf6_route_table[%p]", table); + flog_err(LIB_ERR_DEVELOPMENT, "PANIC !!"); + flog_err(LIB_ERR_DEVELOPMENT, "Something has gone wrong with ospf6_route_table[%p]", table); zlog_debug("table count = %d, real number = %d", table->count, num); zlog_debug("DUMP START"); for (r = ospf6_route_head(table); r; r = ospf6_route_next(r)) { diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 69c18ab75..9c13c51b1 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -30,6 +30,7 @@ #include "pqueue.h" #include "linklist.h" #include "thread.h" +#include "lib_errors.h" #include "ospf6_lsa.h" #include "ospf6_lsdb.h" @@ -272,7 +273,8 @@ static void ospf6_nexthop_calc(struct ospf6_vertex *w, struct ospf6_vertex *v, ifindex = (VERTEX_IS_TYPE(NETWORK, v) ? ospf6_spf_get_ifindex_from_nh(v) : ROUTER_LSDESC_GET_IFID(lsdesc)); if (ifindex == 0) { - zlog_err("No nexthop ifindex at vertex %s", v->name); + flog_err(LIB_ERR_DEVELOPMENT, + "No nexthop ifindex at vertex %s", v->name); return; } diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 8458d1995..06a84dcb9 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -28,6 +28,7 @@ #include "zclient.h" #include "memory.h" #include "lib/bfd.h" +#include "lib_errors.h" #include "ospf6_proto.h" #include "ospf6_top.h" @@ -362,9 +363,10 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request) ret = zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); if (ret < 0) - zlog_err("zclient_route_send() %s failed: %s", - (type == REM ? "delete" : "add"), - safe_strerror(errno)); + flog_err(LIB_ERR_ZAPI_SOCKET, + "zclient_route_send() %s failed: %s", + (type == REM ? "delete" : "add"), + safe_strerror(errno)); return; } diff --git a/ospfd/ospf_errors.c b/ospfd/ospf_errors.c new file mode 100644 index 000000000..2927f7cb1 --- /dev/null +++ b/ospfd/ospf_errors.c @@ -0,0 +1,84 @@ +/* + * OSPF-specific error messages. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Chirag Shah + * + * 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 + +#include "lib/ferr.h" +#include "ospf_errors.h" + +static struct log_ref ferr_ospf_err[] = { + { + .code = OSPF_ERR_PKT_PROCESS, + .title = "Failure to process a packet", + .description = "OSPF attempted to process a received packet but could not", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = OSPF_ERR_ROUTER_LSA_MISMATCH, + .title = "Failure to process Router LSA", + .description = "OSPF attempted to process a Router LSA but Advertising ID mismatch with link id", + .suggestion = "Check OSPF network config for any config issue, If the problem persists, report the problem for troubleshooting" + }, + { + .code = OSPF_ERR_DOMAIN_CORRUPT, + .title = "OSPF Domain Corruption", + .description = "OSPF attempted to process a Router LSA but Advertising ID mismatch with link id", + .suggestion = "Check OSPF network Database for corrupted LSA, If the problem persists, shutdown OSPF domain and report the problem for troubleshooting" + }, + { + .code = OSPF_ERR_INIT_FAIL, + .title = "OSPF Initialization failure", + .description = "OSPF failed to initialized OSPF default insance", + .suggestion = "Ensure there is adequate memory on the device. If the problem persists, report the problem for troubleshooting" + }, + { + .code = OSPF_ERR_SR_INVALID_DB, + .title = "OSPF SR Invalid DB", + .description = "OSPF Segment Routing Database is invalid", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = OSPF_ERR_SR_NODE_CREATE, + .title = "OSPF SR hash node creation failed", + .description = "OSPF Segment Routing node creation failed", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + { + .code = OSPF_ERR_SR_INVALID_LSA_ID, + .title = "OSPF SR Invalid LSA ID", + .description = "OSPF Segment Routing invalid lsa id", + .suggestion = "Restart OSPF instance, If the problem persists, report the problem for troubleshooting" + }, + { + .code = OSPF_ERR_SR_INVALID_ALGORITHM, + .title = "OSPF SR Invalid Algorithm", + .description = "OSPF Segment Routing invalid Algorithm", + .suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting" + }, + + { + .code = END_FERR, + } +}; + +void ospf_error_init(void) +{ + log_ref_add(ferr_ospf_err); +} diff --git a/ospfd/ospf_errors.h b/ospfd/ospf_errors.h new file mode 100644 index 000000000..c3f101855 --- /dev/null +++ b/ospfd/ospf_errors.h @@ -0,0 +1,39 @@ +/* + * OSPF-specific error messages. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Chirag Shah + * + * 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 __OSPF_ERRORS_H__ +#define __OSPF_ERRORS_H__ + +#include "lib/ferr.h" + +enum ospf_log_refs { + OSPF_ERR_PKT_PROCESS = OSPF_FERR_START, + OSPF_ERR_ROUTER_LSA_MISMATCH, + OSPF_ERR_DOMAIN_CORRUPT, + OSPF_ERR_INIT_FAIL, + OSPF_ERR_SR_INVALID_DB, + OSPF_ERR_SR_NODE_CREATE, + OSPF_ERR_SR_INVALID_LSA_ID, + OSPF_ERR_SR_INVALID_ALGORITHM, +}; + +extern void ospf_error_init(void); + +#endif diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 5bf7ec146..6dadc05bb 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -52,6 +52,7 @@ #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_vty.h" #include "ospfd/ospf_bfd.h" +#include "ospfd/ospf_errors.h" /* ospfd privileges */ zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN, @@ -206,12 +207,16 @@ int main(int argc, char **argv) ospf_route_map_init(); ospf_opaque_init(); + /* OSPF errors init */ + ospf_error_init(); + /* Need to initialize the default ospf structure, so the interface mode commands can be duly processed if they are received before 'router ospf', when quagga(ospfd) is restarted */ if (!ospf_get_instance(instance)) { - zlog_err("OSPF instance init failed: %s", strerror(errno)); + flog_err(OSPF_ERR_INIT_FAIL, "OSPF instance init failed: %s", + strerror(errno)); exit(1); } diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index d7cca0f13..1fb930659 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -29,6 +29,7 @@ #include "log.h" #include "sockopt.h" #include "privs.h" +#include "lib_errors.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_network.h" @@ -185,66 +186,51 @@ int ospf_sock_init(struct ospf *ospf) /* silently return since VRF is not ready */ return -1; } - if (ospfd_privs.change(ZPRIVS_RAISE)) { - zlog_err("ospf_sock_init: could not raise privs, %s", - safe_strerror(errno)); - } - - ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP, ospf->vrf_id, - ospf->name); - if (ospf_sock < 0) { - int save_errno = errno; - - if (ospfd_privs.change(ZPRIVS_LOWER)) - zlog_err("ospf_sock_init: could not lower privs, %s", + frr_elevate_privs(&ospfd_privs) { + ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP, + ospf->vrf_id, ospf->name); + if (ospf_sock < 0) { + zlog_err("ospf_read_sock_init: socket: %s", safe_strerror(errno)); - zlog_err("ospf_read_sock_init: socket: %s", - safe_strerror(save_errno)); - exit(1); - } + exit(1); + } #ifdef IP_HDRINCL - /* we will include IP header with packet */ - ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, - sizeof(hincl)); - if (ret < 0) { - int save_errno = errno; - - zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", - ospf_sock, safe_strerror(save_errno)); - close(ospf_sock); - goto out; - } + /* we will include IP header with packet */ + ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, + sizeof(hincl)); + if (ret < 0) { + zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", + ospf_sock, safe_strerror(errno)); + close(ospf_sock); + break; + } #elif defined(IPTOS_PREC_INTERNETCONTROL) #warning "IP_HDRINCL not available on this system" #warning "using IPTOS_PREC_INTERNETCONTROL" - ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL); - if (ret < 0) { - int save_errno = errno; - - zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos, - ospf_sock, safe_strerror(save_errno)); - close(ospf_sock); /* Prevent sd leak. */ - goto out; - } + ret = setsockopt_ipv4_tos(ospf_sock, + IPTOS_PREC_INTERNETCONTROL); + if (ret < 0) { + zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", + tos, ospf_sock, safe_strerror(errno)); + close(ospf_sock); /* Prevent sd leak. */ + break; + } #else /* !IPTOS_PREC_INTERNETCONTROL */ #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL" - zlog_warn("IP_HDRINCL option not available"); + zlog_warn("IP_HDRINCL option not available"); #endif /* IP_HDRINCL */ - ret = setsockopt_ifindex(AF_INET, ospf_sock, 1); + ret = setsockopt_ifindex(AF_INET, ospf_sock, 1); - if (ret < 0) - zlog_warn("Can't set pktinfo option for fd %d", ospf_sock); + if (ret < 0) + zlog_warn("Can't set pktinfo option for fd %d", + ospf_sock); - setsockopt_so_sendbuf(ospf_sock, bufsize); - setsockopt_so_recvbuf(ospf_sock, bufsize); + setsockopt_so_sendbuf(ospf_sock, bufsize); + setsockopt_so_recvbuf(ospf_sock, bufsize); + } ospf->fd = ospf_sock; -out: - if (ospfd_privs.change(ZPRIVS_LOWER)) { - zlog_err("ospf_sock_init: could not lower privs, %s", - safe_strerror(errno)); - } return ret; } diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 486ef3335..f1d4a39db 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -35,6 +35,7 @@ #include "checksum.h" #include "md5.h" #include "vrf.h" +#include "ospf_errors.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_network.h" @@ -230,7 +231,8 @@ void ospf_fifo_free(struct ospf_fifo *fifo) void ospf_packet_add(struct ospf_interface *oi, struct ospf_packet *op) { if (!oi->obuf) { - zlog_err( + flog_err( + OSPF_ERR_PKT_PROCESS, "ospf_packet_add(interface %s in state %d [%s], packet type %s, " "destination %s) called with NULL obuf, ignoring " "(please report this bug)!\n", @@ -253,7 +255,8 @@ static void ospf_packet_add_top(struct ospf_interface *oi, struct ospf_packet *op) { if (!oi->obuf) { - zlog_err( + flog_err( + OSPF_ERR_PKT_PROCESS, "ospf_packet_add(interface %s in state %d [%s], packet type %s, " "destination %s) called with NULL obuf, ignoring " "(please report this bug)!\n", @@ -1915,17 +1918,18 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, char buf2[INET_ADDRSTRLEN]; char buf3[INET_ADDRSTRLEN]; - zlog_err( - "Incoming Router-LSA from %s with " - "Adv-ID[%s] != LS-ID[%s]", - inet_ntop(AF_INET, &ospfh->router_id, - buf1, INET_ADDRSTRLEN), - inet_ntop(AF_INET, &lsa->data->id, buf2, - INET_ADDRSTRLEN), - inet_ntop(AF_INET, - &lsa->data->adv_router, buf3, - INET_ADDRSTRLEN)); - zlog_err( + flog_err(OSPF_ERR_ROUTER_LSA_MISMATCH, + "Incoming Router-LSA from %s with " + "Adv-ID[%s] != LS-ID[%s]", + inet_ntop(AF_INET, &ospfh->router_id, + buf1, INET_ADDRSTRLEN), + inet_ntop(AF_INET, &lsa->data->id, + buf2, INET_ADDRSTRLEN), + inet_ntop(AF_INET, + &lsa->data->adv_router, + buf3, INET_ADDRSTRLEN)); + flog_err( + OSPF_ERR_DOMAIN_CORRUPT, "OSPF domain compromised by attack or corruption. " "Verify correct operation of -ALL- OSPF routers."); DISCARD_LSA(lsa, 0); diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 25983ddc5..23dae6b08 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -48,6 +48,7 @@ #include "vty.h" #include "zclient.h" #include +#include "ospf_errors.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -820,8 +821,9 @@ static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh) case EXT_SUBTLV_PREFIX_SID: psid = (struct ext_subtlv_prefix_sid *)sub_tlvh; if (psid->algorithm != SR_ALGORITHM_SPF) { - zlog_err("SR (%s): Unsupported Algorithm", - __func__); + flog_err(OSPF_ERR_SR_INVALID_ALGORITHM, + "SR (%s): Unsupported Algorithm", + __func__); XFREE(MTYPE_OSPF_SR_PARAMS, srp); return NULL; } @@ -1100,7 +1102,8 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa) return; if (OspfSR.neighbors == NULL) { - zlog_err("SR (%s): Abort! no valid SR DataBase", __func__); + flog_err(OSPF_ERR_SR_INVALID_DB, + "SR (%s): Abort! no valid SR DataBase", __func__); return; } @@ -1110,17 +1113,18 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa) /* Sanity check */ if (srn == NULL) { - zlog_err("SR (%s): Abort! can't create SR node in hash table", - __func__); + flog_err(OSPF_ERR_SR_NODE_CREATE, + "SR (%s): Abort! can't create SR node in hash table", + __func__); return; } if ((srn->instance != 0) && (srn->instance != ntohl(lsah->id.s_addr))) { - zlog_err( - "SR (%s): Abort! Wrong " - "LSA ID 4.0.0.%u for SR node %s/%u", - __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)), - inet_ntoa(lsah->adv_router), srn->instance); + flog_err(OSPF_ERR_SR_INVALID_LSA_ID, + "SR (%s): Abort! Wrong " + "LSA ID 4.0.0.%u for SR node %s/%u", + __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)), + inet_ntoa(lsah->adv_router), srn->instance); return; } @@ -1209,7 +1213,8 @@ void ospf_sr_ri_lsa_delete(struct ospf_lsa *lsa) /* Sanity check */ if (OspfSR.neighbors == NULL) { - zlog_err("SR (%s): Abort! no valid SR Data Base", __func__); + flog_err(OSPF_ERR_SR_INVALID_DB, + "SR (%s): Abort! no valid SR Data Base", __func__); return; } @@ -1218,15 +1223,18 @@ void ospf_sr_ri_lsa_delete(struct ospf_lsa *lsa) /* Sanity check */ if (srn == NULL) { - zlog_err("SR (%s): Abort! no entry in SRDB for SR Node %s", - __func__, inet_ntoa(lsah->adv_router)); + flog_err(OSPF_ERR_SR_NODE_CREATE, + "SR (%s): Abort! no entry in SRDB for SR Node %s", + __func__, inet_ntoa(lsah->adv_router)); return; } if ((srn->instance != 0) && (srn->instance != ntohl(lsah->id.s_addr))) { - zlog_err("SR (%s): Abort! Wrong LSA ID 4.0.0.%u for SR node %s", - __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)), - inet_ntoa(lsah->adv_router)); + flog_err( + OSPF_ERR_SR_INVALID_LSA_ID, + "SR (%s): Abort! Wrong LSA ID 4.0.0.%u for SR node %s", + __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)), + inet_ntoa(lsah->adv_router)); return; } @@ -1252,7 +1260,8 @@ void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa) /* Sanity check */ if (OspfSR.neighbors == NULL) { - zlog_err("SR (%s): Abort! no valid SR DataBase", __func__); + flog_err(OSPF_ERR_SR_INVALID_DB, + "SR (%s): Abort! no valid SR DataBase", __func__); return; } @@ -1263,8 +1272,9 @@ void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa) /* Sanity check */ if (srn == NULL) { - zlog_err("SR (%s): Abort! can't create SR node in hash table", - __func__); + flog_err(OSPF_ERR_SR_NODE_CREATE, + "SR (%s): Abort! can't create SR node in hash table", + __func__); return; } @@ -1302,7 +1312,8 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa) /* Sanity check */ if (OspfSR.neighbors == NULL) { - zlog_err("SR (%s): Abort! no valid SR DataBase", __func__); + flog_err(OSPF_ERR_SR_INVALID_DB, + "SR (%s): Abort! no valid SR DataBase", __func__); return; } @@ -1359,7 +1370,8 @@ void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa) /* Sanity check */ if (OspfSR.neighbors == NULL) { - zlog_err("SR (%s): Abort! no valid SR DataBase", __func__); + flog_err(OSPF_ERR_SR_INVALID_DB, + "SR (%s): Abort! no valid SR DataBase", __func__); return; } @@ -1370,8 +1382,9 @@ void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa) /* Sanity check */ if (srn == NULL) { - zlog_err("SR (%s): Abort! can't create SR node in hash table", - __func__); + flog_err(OSPF_ERR_SR_NODE_CREATE, + "SR (%s): Abort! can't create SR node in hash table", + __func__); return; } @@ -1410,7 +1423,8 @@ void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa) /* Sanity check */ if (OspfSR.neighbors == NULL) { - zlog_err("SR (%s): Abort! no valid SR DataBase", __func__); + flog_err(OSPF_ERR_SR_INVALID_DB, + "SR (%s): Abort! no valid SR DataBase", __func__); return; } @@ -1524,10 +1538,6 @@ static void ospf_sr_nhlfe_update(struct hash_backet *backet, void *args) struct sr_nhlfe old; int rc; - /* Sanity Check */ - if (srn == NULL) - return; - if (IS_DEBUG_OSPF_SR) zlog_debug(" |- Update Prefix for SR Node %s", inet_ntoa(srn->adv_router)); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 2298c2261..ac8f0d92c 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -38,6 +38,7 @@ #include "bfd.h" #include "libfrr.h" #include "defaults.h" +#include "lib_errors.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_network.h" @@ -2087,25 +2088,17 @@ static int ospf_vrf_enable(struct vrf *vrf) old_vrf_id); if (old_vrf_id != ospf->vrf_id) { - if (ospfd_privs.change(ZPRIVS_RAISE)) { - zlog_err( - "ospf_sock_init: could not raise privs, %s", - safe_strerror(errno)); - } - - /* stop zebra redist to us for old vrf */ - zclient_send_dereg_requests(zclient, old_vrf_id); + frr_elevate_privs(&ospfd_privs) { + /* stop zebra redist to us for old vrf */ + zclient_send_dereg_requests(zclient, + old_vrf_id); - ospf_set_redist_vrf_bitmaps(ospf); + ospf_set_redist_vrf_bitmaps(ospf); - /* start zebra redist to us for new vrf */ - ospf_zebra_vrf_register(ospf); + /* start zebra redist to us for new vrf */ + ospf_zebra_vrf_register(ospf); - ret = ospf_sock_init(ospf); - if (ospfd_privs.change(ZPRIVS_LOWER)) { - zlog_err( - "ospf_sock_init: could not lower privs, %s", - safe_strerror(errno)); + ret = ospf_sock_init(ospf); } if (ret < 0 || ospf->fd <= 0) return 0; diff --git a/ospfd/subdir.am b/ospfd/subdir.am index f2e292e18..cd659a9bc 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -20,6 +20,7 @@ ospfd_libfrrospf_a_SOURCES = \ ospfd/ospf_bfd.c \ ospfd/ospf_dump.c \ ospfd/ospf_dump_api.c \ + ospfd/ospf_errors.c \ ospfd/ospf_ext.c \ ospfd/ospf_flood.c \ ospfd/ospf_ia.c \ @@ -68,6 +69,7 @@ noinst_HEADERS += \ ospfd/ospf_apiserver.h \ ospfd/ospf_ase.h \ ospfd/ospf_bfd.h \ + ospfd/ospf_errors.h \ ospfd/ospf_ext.h \ ospfd/ospf_flood.h \ ospfd/ospf_ia.h \ diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 6eb4303fb..7c45ce261 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2795,9 +2795,6 @@ static int pim_print_pnc_cache_walkcb(struct hash_backet *backet, void *arg) ifindex_t first_ifindex; struct interface *ifp = NULL; - if (!pnc) - return CMD_SUCCESS; - for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) { first_ifindex = nh_node->ifindex; ifp = if_lookup_by_index(first_ifindex, pim->vrf_id); diff --git a/pimd/pim_errors.c b/pimd/pim_errors.c new file mode 100644 index 000000000..d154752bd --- /dev/null +++ b/pimd/pim_errors.c @@ -0,0 +1,49 @@ +/* + * PIM-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 + +#include "lib/ferr.h" +#include "pim_errors.h" + +/* clang-format off */ +static struct log_ref ferr_pim_err[] = { + { + .code = PIM_ERR_MSDP_PACKET, + .title = "PIM MSDP Packet Error", + .description = "PIM has received a packet from a peer that does not correctly decode", + .suggestion = "Check MSDP peer and ensure it is correctly working" + }, + { + .code = PIM_ERR_CONFIG, + .title = "PIM Configuration Error", + .description = "PIM has detected a configuration error", + .suggestion = "Ensure the configuration is correct and apply correct configuration" + }, + { + .code = END_FERR, + } +}; +/* clang-format on */ + +void pim_error_init(void) +{ + log_ref_add(ferr_pim_err); +} diff --git a/pimd/pim_errors.h b/pimd/pim_errors.h new file mode 100644 index 000000000..ad9c95a93 --- /dev/null +++ b/pimd/pim_errors.h @@ -0,0 +1,33 @@ +/* + * PIM-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 __PIM_ERRORS_H__ +#define __PIM_ERRORS_H__ + +#include "lib/ferr.h" + +enum pim_log_refs { + PIM_ERR_MSDP_PACKET = PIM_FERR_START, + PIM_ERR_CONFIG, +}; + +extern void pim_error_init(void); + +#endif diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index eb3307589..92a78c4bb 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -549,26 +549,6 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, up = pim_upstream_add(pim_ifp->pim, sg, NULL, up_flags, __PRETTY_FUNCTION__, ch); - if (!up) { - zlog_err( - "%s: could not attach upstream (S,G)=%s on interface %s", - __PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name); - - if (ch->parent) - listnode_delete(ch->parent->sources, ch); - - pim_ifchannel_remove_children(ch); - if (ch->sources) - list_delete_and_null(&ch->sources); - - THREAD_OFF(ch->t_ifjoin_expiry_timer); - THREAD_OFF(ch->t_ifjoin_prune_pending_timer); - THREAD_OFF(ch->t_ifassert_timer); - - RB_REMOVE(pim_ifchannel_rb, &pim_ifp->ifchannel_rb, ch); - XFREE(MTYPE_PIM_IFCHANNEL, ch); - return NULL; - } ch->upstream = up; listnode_add_sort(up->ifchannels, ch); diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index b46f1b5e9..270f1e3f2 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -24,6 +24,7 @@ #include "if.h" #include "hash.h" #include "jhash.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_igmp.h" @@ -96,7 +97,8 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp, } if (!join) { - zlog_err( + flog_err_sys( + LIB_ERR_SOCKET, "IGMP socket fd=%d could not join any group on interface address %s", fd, inet_ntoa(ifaddr)); close(fd); @@ -697,7 +699,8 @@ static void sock_close(struct igmp_sock *igmp) THREAD_OFF(igmp->t_igmp_read); if (close(igmp->fd)) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "Failure closing IGMP socket %s fd=%d on interface %s: errno=%d: %s", inet_ntoa(igmp->ifaddr), igmp->fd, igmp->interface->name, errno, safe_strerror(errno)); @@ -960,12 +963,6 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list, } igmp = igmp_sock_new(fd, ifaddr, ifp, mtrace_only); - if (!igmp) { - zlog_err("%s %s: igmp_sock_new() failure", __FILE__, - __PRETTY_FUNCTION__); - close(fd); - return 0; - } igmp_read_on(igmp); diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 132fe4d56..7b21376c9 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -21,6 +21,7 @@ #include "log.h" #include "memory.h" #include "if.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_iface.h" @@ -1583,7 +1584,8 @@ void igmp_v3_send_query(struct igmp_group *group, int fd, const char *ifname, msg_size = IGMP_V3_SOURCES_OFFSET + (num_sources << 2); if (msg_size > query_buf_size) { - zlog_err( + flog_err( + LIB_ERR_DEVELOPMENT, "%s %s: unable to send: msg_size=%zd larger than query_buf_size=%d", __FILE__, __PRETTY_FUNCTION__, msg_size, query_buf_size); diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index e664bf306..8dc48cc00 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -22,6 +22,7 @@ #include "hash.h" #include "vrf.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_ssm.h" @@ -94,10 +95,6 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf) zlog_debug("%s: NHT rpf hash init ", __PRETTY_FUNCTION__); pim->ssm_info = pim_ssm_init(); - if (!pim->ssm_info) { - pim_instance_terminate(pim); - return NULL; - } pim->static_routes = list_new(); pim->static_routes->del = (void (*)(void *))pim_static_route_free; @@ -132,14 +129,6 @@ static int pim_vrf_new(struct vrf *vrf) struct pim_instance *pim = pim_instance_init(vrf); zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id); - if (pim == NULL) { - zlog_err("%s %s: pim class init failure ", __FILE__, - __PRETTY_FUNCTION__); - /* - * We will crash and burn otherwise - */ - exit(1); - } vrf->info = (void *)pim; diff --git a/pimd/pim_main.c b/pimd/pim_main.c index c4cab25ae..578794086 100644 --- a/pimd/pim_main.c +++ b/pimd/pim_main.c @@ -47,6 +47,7 @@ #include "pim_msdp.h" #include "pim_iface.h" #include "pim_bfd.h" +#include "pim_errors.h" extern struct host host; @@ -108,6 +109,7 @@ int main(int argc, char **argv, char **envp) /* * Initializations */ + pim_error_init(); pim_vrf_init(); access_list_init(); prefix_list_init(); diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index dd3067840..c69e2939e 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -25,6 +25,7 @@ #include "vty.h" #include "plist.h" #include "sockopt.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_rpf.h" @@ -55,27 +56,22 @@ static int pim_mroute_set(struct pim_instance *pim, int enable) * We need to create the VRF table for the pim mroute_socket */ if (pim->vrf_id != VRF_DEFAULT) { - if (pimd_privs.change(ZPRIVS_RAISE)) - zlog_err( - "pim_mroute_socket_enable: could not raise privs, %s", - safe_strerror(errno)); + frr_elevate_privs(&pimd_privs) { - opt = pim->vrf->data.l.table_id; - err = setsockopt(pim->mroute_socket, IPPROTO_IP, MRT_TABLE, - &opt, opt_len); - if (err) { - zlog_warn( - "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP, MRT_TABLE=%d): errno=%d: %s", - __FILE__, __PRETTY_FUNCTION__, - pim->mroute_socket, opt, errno, - safe_strerror(errno)); - return -1; - } + opt = pim->vrf->data.l.table_id; + err = setsockopt(pim->mroute_socket, IPPROTO_IP, + MRT_TABLE, + &opt, opt_len); + if (err) { + zlog_warn( + "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP, MRT_TABLE=%d): errno=%d: %s", + __FILE__, __PRETTY_FUNCTION__, + pim->mroute_socket, opt, errno, + safe_strerror(errno)); + return -1; + } - if (pimd_privs.change(ZPRIVS_LOWER)) - zlog_err( - "pim_mroute_socket_enable: could not lower privs, %s", - safe_strerror(errno)); + } } opt = enable ? MRT_INIT : MRT_DONE; @@ -708,32 +704,29 @@ int pim_mroute_socket_enable(struct pim_instance *pim) { int fd; - if (pimd_privs.change(ZPRIVS_RAISE)) - zlog_err("pim_mroute_socket_enable: could not raise privs, %s", - safe_strerror(errno)); + frr_elevate_privs(&pimd_privs) { - fd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP); + fd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP); - if (fd < 0) { - zlog_warn("Could not create mroute socket: errno=%d: %s", errno, - safe_strerror(errno)); - return -2; - } + if (fd < 0) { + zlog_warn("Could not create mroute socket: errno=%d: %s", + errno, + safe_strerror(errno)); + return -2; + } #ifdef SO_BINDTODEVICE - if (pim->vrf->vrf_id != VRF_DEFAULT - && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, pim->vrf->name, - strlen(pim->vrf->name))) { - zlog_warn("Could not setsockopt SO_BINDTODEVICE: %s", - safe_strerror(errno)); - close(fd); - return -3; - } + if (pim->vrf->vrf_id != VRF_DEFAULT + && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, + pim->vrf->name, strlen(pim->vrf->name))) { + zlog_warn("Could not setsockopt SO_BINDTODEVICE: %s", + safe_strerror(errno)); + close(fd); + return -3; + } #endif - if (pimd_privs.change(ZPRIVS_LOWER)) - zlog_err("pim_mroute_socket_enable: could not lower privs, %s", - safe_strerror(errno)); + } pim->mroute_socket = fd; if (pim_mroute_set(pim, 1)) { diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 4910cb8b3..7fcf42e8c 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "pimd.h" #include "pim_cmd.h" @@ -517,7 +518,8 @@ static void pim_msdp_sa_local_del_on_up_del(struct pim_instance *pim, * the flow. Accounting for such cases requires lot of * changes; perhaps * address this in the next release? - XXX */ - zlog_err( + flog_err( + LIB_ERR_DEVELOPMENT, "MSDP sa %s SPT teardown is causing the local entry to be removed", sa->sg_str); return; diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c index 978d97924..65232aafa 100644 --- a/pimd/pim_msdp_packet.c +++ b/pimd/pim_msdp_packet.c @@ -23,9 +23,11 @@ #include #include #include +#include #include "pimd.h" #include "pim_str.h" +#include "pim_errors.h" #include "pim_msdp.h" #include "pim_msdp_packet.h" @@ -145,7 +147,8 @@ static void pim_msdp_connect_check(struct pim_msdp_peer *mp) /* If getsockopt is fail, this is fatal error. */ if (ret < 0) { - zlog_err("can't get sockopt for nonblocking connect"); + flog_err_sys(LIB_ERR_SOCKET, + "can't get sockopt for nonblocking connect"); pim_msdp_peer_reset_tcp_conn(mp, "connect-failed"); return; } @@ -481,8 +484,9 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp) if (prefix_len != 32) { /* ignore SA update if the prefix length is not 32 */ - zlog_err("rxed sa update with invalid prefix length %d", - prefix_len); + flog_err(PIM_ERR_MSDP_PACKET, + "rxed sa update with invalid prefix length %d", + prefix_len); return; } if (PIM_DEBUG_MSDP_PACKETS) { diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c index f245a0435..feac42cf5 100644 --- a/pimd/pim_msdp_socket.c +++ b/pimd/pim_msdp_socket.c @@ -26,9 +26,11 @@ #include #include #include +#include #include "pimd.h" #include "pim_sock.h" +#include "pim_errors.h" #include "pim_msdp.h" #include "pim_msdp_socket.h" @@ -41,16 +43,18 @@ static void pim_msdp_update_sock_send_buffer_size(int fd) socklen_t optlen = sizeof(optval); if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) < 0) { - zlog_err("getsockopt of SO_SNDBUF failed %s\n", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "getsockopt of SO_SNDBUF failed %s\n", + safe_strerror(errno)); return; } if (optval < size) { if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0) { - zlog_err("Couldn't increase send buffer: %s\n", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "Couldn't increase send buffer: %s\n", + safe_strerror(errno)); } } } @@ -70,7 +74,8 @@ static int pim_msdp_sock_accept(struct thread *thread) /* re-register accept thread */ accept_sock = THREAD_FD(thread); if (accept_sock < 0) { - zlog_err("accept_sock is negative value %d", accept_sock); + flog_err(LIB_ERR_DEVELOPMENT, + "accept_sock is negative value %d", accept_sock); return -1; } pim->msdp.listener.thread = NULL; @@ -80,8 +85,8 @@ static int pim_msdp_sock_accept(struct thread *thread) /* accept client connection. */ msdp_sock = sockunion_accept(accept_sock, &su); if (msdp_sock < 0) { - zlog_err("pim_msdp_sock_accept failed (%s)", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "pim_msdp_sock_accept failed (%s)", + safe_strerror(errno)); return -1; } @@ -90,8 +95,9 @@ static int pim_msdp_sock_accept(struct thread *thread) if (!mp || !PIM_MSDP_PEER_IS_LISTENER(mp)) { ++pim->msdp.rejected_accepts; if (PIM_DEBUG_MSDP_EVENTS) { - zlog_err("msdp peer connection refused from %s", - sockunion2str(&su, buf, SU_ADDRSTRLEN)); + flog_err(PIM_ERR_MSDP_PACKET, + "msdp peer connection refused from %s", + sockunion2str(&su, buf, SU_ADDRSTRLEN)); } close(msdp_sock); return -1; @@ -106,7 +112,7 @@ static int pim_msdp_sock_accept(struct thread *thread) * with this one */ if (mp->fd >= 0) { if (PIM_DEBUG_MSDP_EVENTS) { - zlog_err( + zlog_notice( "msdp peer new connection from %s stop old connection", sockunion2str(&su, buf, SU_ADDRSTRLEN)); } @@ -135,7 +141,8 @@ int pim_msdp_sock_listen(struct pim_instance *pim) sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { - zlog_err("socket: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "socket: %s", + safe_strerror(errno)); return sock; } @@ -154,42 +161,38 @@ int pim_msdp_sock_listen(struct pim_instance *pim) struct interface *ifp = if_lookup_by_name(pim->vrf->name, pim->vrf_id); if (!ifp) { - zlog_err("%s: Unable to lookup vrf interface: %s", - __PRETTY_FUNCTION__, pim->vrf->name); + flog_err(LIB_ERR_INTERFACE, + "%s: Unable to lookup vrf interface: %s", + __PRETTY_FUNCTION__, pim->vrf->name); close(sock); return -1; } if (pim_socket_bind(sock, ifp)) { - zlog_err("%s: Unable to bind to socket: %s", - __PRETTY_FUNCTION__, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "%s: Unable to bind to socket: %s", + __PRETTY_FUNCTION__, safe_strerror(errno)); close(sock); return -1; } } - if (pimd_privs.change(ZPRIVS_RAISE)) { - zlog_err("pim_msdp_socket: could not raise privs, %s", - safe_strerror(errno)); - } - - /* bind to well known TCP port */ - rc = bind(sock, (struct sockaddr *)&sin, socklen); - - if (pimd_privs.change(ZPRIVS_LOWER)) { - zlog_err("pim_msdp_socket: could not lower privs, %s", - safe_strerror(errno)); + frr_elevate_privs(&pimd_privs) { + /* bind to well known TCP port */ + rc = bind(sock, (struct sockaddr *)&sin, socklen); } if (rc < 0) { - zlog_err("pim_msdp_socket bind to port %d: %s", - ntohs(sin.sin_port), safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "pim_msdp_socket bind to port %d: %s", + ntohs(sin.sin_port), safe_strerror(errno)); close(sock); return rc; } rc = listen(sock, 3 /* backlog */); if (rc < 0) { - zlog_err("pim_msdp_socket listen: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "pim_msdp_socket listen: %s", + safe_strerror(errno)); close(sock); return rc; } @@ -219,7 +222,7 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) * with this one */ if (mp->fd >= 0) { if (PIM_DEBUG_MSDP_EVENTS) { - zlog_err( + zlog_notice( "msdp duplicate connect to %s nuke old connection", mp->key_str); } @@ -229,8 +232,9 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) /* Make socket for the peer. */ mp->fd = sockunion_socket(&mp->su_peer); if (mp->fd < 0) { - zlog_err("pim_msdp_socket socket failure: %s", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "pim_msdp_socket socket failure: %s", + safe_strerror(errno)); return -1; } @@ -238,13 +242,15 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) struct interface *ifp = if_lookup_by_name(mp->pim->vrf->name, mp->pim->vrf_id); if (!ifp) { - zlog_err("%s: Unable to lookup vrf interface: %s", - __PRETTY_FUNCTION__, mp->pim->vrf->name); + flog_err(LIB_ERR_INTERFACE, + "%s: Unable to lookup vrf interface: %s", + __PRETTY_FUNCTION__, mp->pim->vrf->name); return -1; } if (pim_socket_bind(mp->fd, ifp)) { - zlog_err("%s: Unable to bind to socket: %s", - __PRETTY_FUNCTION__, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "%s: Unable to bind to socket: %s", + __PRETTY_FUNCTION__, safe_strerror(errno)); close(mp->fd); mp->fd = -1; return -1; @@ -261,8 +267,9 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) /* source bind */ rc = sockunion_bind(mp->fd, &mp->su_local, 0, &mp->su_local); if (rc < 0) { - zlog_err("pim_msdp_socket connect bind failure: %s", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "pim_msdp_socket connect bind failure: %s", + safe_strerror(errno)); close(mp->fd); mp->fd = -1; return rc; diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index e73422331..11d847636 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -25,6 +25,7 @@ #include "if.h" #include "vty.h" #include "plist.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_neighbor.h" @@ -799,7 +800,8 @@ void pim_neighbor_update(struct pim_neighbor *neigh, if (neigh->prefix_list == addr_list) { if (addr_list) { - zlog_err( + flog_err( + LIB_ERR_DEVELOPMENT, "%s: internal error: trying to replace same prefix list=%p", __PRETTY_FUNCTION__, (void *)addr_list); } diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index f50687528..b103da2e1 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -38,6 +38,7 @@ #include "pim_assert.h" #include "pim_msg.h" #include "pim_register.h" +#include "pim_errors.h" static int on_pim_hello_send(struct thread *t); static int pim_hello_send(struct interface *ifp, uint16_t holdtime); @@ -115,8 +116,9 @@ void pim_sock_delete(struct interface *ifp, const char *delete_message) delete_message); if (!ifp->info) { - zlog_err("%s: %s: but PIM not enabled on interface %s (!)", - __PRETTY_FUNCTION__, delete_message, ifp->name); + flog_err(PIM_ERR_CONFIG, + "%s: %s: but PIM not enabled on interface %s (!)", + __PRETTY_FUNCTION__, delete_message, ifp->name); return; } diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 3b3e5eb69..3db5015e7 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -31,6 +31,7 @@ #include "plist.h" #include "nexthop.h" #include "table.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_vty.h" @@ -56,6 +57,8 @@ void pim_rp_list_hash_clean(void *data) hash_clean(pnc->upstream_hash, NULL); hash_free(pnc->upstream_hash); pnc->upstream_hash = NULL; + if (pnc->nexthop) + nexthops_free(pnc->nexthop); XFREE(MTYPE_PIM_NEXTHOP_CACHE, pnc); } @@ -110,7 +113,8 @@ void pim_rp_init(struct pim_instance *pim) rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info)); if (!str2prefix("224.0.0.0/4", &rp_info->group)) { - zlog_err("Unable to convert 224.0.0.0/4 to prefix"); + flog_err(LIB_ERR_DEVELOPMENT, + "Unable to convert 224.0.0.0/4 to prefix"); list_delete_and_null(&pim->rp_list); route_table_finish(pim->rp_table); XFREE(MTYPE_PIM_RP, rp_info); @@ -231,7 +235,8 @@ static struct rp_info *pim_rp_find_match_group(struct pim_instance *pim, rn = route_node_match(pim->rp_table, group); if (!rn) { - zlog_err( + flog_err( + LIB_ERR_DEVELOPMENT, "%s: BUG We should have found default group information\n", __PRETTY_FUNCTION__); return best; @@ -619,7 +624,9 @@ int pim_rp_del(struct pim_instance *pim, const char *rp, rn = route_node_get(pim->rp_table, &rp_info->group); if (rn) { if (rn->info != rp_info) - zlog_err("WTF matey"); + flog_err( + LIB_ERR_DEVELOPMENT, + "Expected rn->info to be equal to rp_info"); if (PIM_DEBUG_TRACE) { char buf[PREFIX_STRLEN]; diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c index fb0d6b506..1f584a2f9 100644 --- a/pimd/pim_sock.c +++ b/pimd/pim_sock.c @@ -33,6 +33,7 @@ #include "if.h" #include "vrf.h" #include "sockopt.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_mroute.h" @@ -45,15 +46,11 @@ int pim_socket_raw(int protocol) { int fd; - if (pimd_privs.change(ZPRIVS_RAISE)) - zlog_err("pim_sockek_raw: could not raise privs, %s", - safe_strerror(errno)); + frr_elevate_privs(&pimd_privs) { - fd = socket(AF_INET, SOCK_RAW, protocol); + fd = socket(AF_INET, SOCK_RAW, protocol); - if (pimd_privs.change(ZPRIVS_LOWER)) - zlog_err("pim_socket_raw: could not lower privs, %s", - safe_strerror(errno)); + } if (fd < 0) { zlog_warn("Could not create raw socket: errno=%d: %s", errno, @@ -68,17 +65,13 @@ void pim_socket_ip_hdr(int fd) { const int on = 1; - if (pimd_privs.change(ZPRIVS_RAISE)) - zlog_err("%s: could not raise privs, %s", __PRETTY_FUNCTION__, - safe_strerror(errno)); + frr_elevate_privs(&pimd_privs) { - if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on))) - zlog_err("%s: Could not turn on IP_HDRINCL option: %s", - __PRETTY_FUNCTION__, safe_strerror(errno)); + if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on))) + zlog_err("%s: Could not turn on IP_HDRINCL option: %s", + __PRETTY_FUNCTION__, safe_strerror(errno)); - if (pimd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs, %s", __PRETTY_FUNCTION__, - safe_strerror(errno)); + } } /* @@ -90,16 +83,12 @@ int pim_socket_bind(int fd, struct interface *ifp) int ret = 0; #ifdef SO_BINDTODEVICE - if (pimd_privs.change(ZPRIVS_RAISE)) - zlog_err("%s: could not raise privs, %s", __PRETTY_FUNCTION__, - safe_strerror(errno)); + frr_elevate_privs(&pimd_privs) { - ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifp->name, - strlen(ifp->name)); + ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifp->name, + strlen(ifp->name)); - if (pimd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs, %s", __PRETTY_FUNCTION__, - safe_strerror(errno)); + } #endif return ret; @@ -161,7 +150,8 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp, fd, errno, safe_strerror(errno)); } #else - zlog_err( + flog_err( + LIB_ERR_DEVELOPMENT, "%s %s: Missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()", __FILE__, __PRETTY_FUNCTION__); close(fd); @@ -298,7 +288,8 @@ int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr, sizeof(ifaddr_str))) sprintf(ifaddr_str, ""); - zlog_err( + flog_err( + LIB_ERR_SOCKET, "Failure socket joining fd=%d group %s on interface address %s: errno=%d: %s", fd, group_str, ifaddr_str, errno, safe_strerror(errno)); return ret; diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c index 1f7cfcaa9..8347878d3 100644 --- a/pimd/pim_ssm.c +++ b/pimd/pim_ssm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "pimd.h" #include "pim_ssm.h" @@ -72,8 +73,9 @@ static int pim_is_grp_standard_ssm(struct prefix *group) if (first) { if (!str2prefix(PIM_SSM_STANDARD_RANGE, &group_ssm)) - zlog_err("%s: Failure to Read Group Address: %s", - __PRETTY_FUNCTION__, PIM_SSM_STANDARD_RANGE); + flog_err(LIB_ERR_DEVELOPMENT, + "%s: Failure to Read Group Address: %s", + __PRETTY_FUNCTION__, PIM_SSM_STANDARD_RANGE); first = 0; } diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index bdf303d5c..be30d9c73 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -24,6 +24,7 @@ #include "memory.h" #include "sockopt.h" #include "vrf.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_ssmpingd.h" @@ -82,8 +83,9 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl) fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { - zlog_err("%s: could not create socket: errno=%d: %s", - __PRETTY_FUNCTION__, errno, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "%s: could not create socket: errno=%d: %s", + __PRETTY_FUNCTION__, errno, safe_strerror(errno)); return -1; } @@ -124,7 +126,8 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl) safe_strerror(errno)); } #else - zlog_err( + flog_err( + LIB_ERR_DEVELOPMENT, "%s %s: missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()", __FILE__, __PRETTY_FUNCTION__); close(fd); diff --git a/pimd/pim_time.c b/pimd/pim_time.c index 6f011da43..029e55116 100644 --- a/pimd/pim_time.c +++ b/pimd/pim_time.c @@ -25,6 +25,7 @@ #include "log.h" #include "thread.h" +#include "lib_errors.h" #include "pim_time.h" @@ -34,8 +35,9 @@ static int gettime_monotonic(struct timeval *tv) result = gettimeofday(tv, 0); if (result) { - zlog_err("%s: gettimeofday() failure: errno=%d: %s", - __PRETTY_FUNCTION__, errno, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "%s: gettimeofday() failure: errno=%d: %s", + __PRETTY_FUNCTION__, errno, safe_strerror(errno)); } return result; @@ -50,8 +52,9 @@ int64_t pim_time_monotonic_sec() struct timeval now_tv; if (gettime_monotonic(&now_tv)) { - zlog_err("%s: gettime_monotonic() failure: errno=%d: %s", - __PRETTY_FUNCTION__, errno, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "%s: gettime_monotonic() failure: errno=%d: %s", + __PRETTY_FUNCTION__, errno, safe_strerror(errno)); return -1; } @@ -68,8 +71,9 @@ int64_t pim_time_monotonic_dsec() int64_t now_dsec; if (gettime_monotonic(&now_tv)) { - zlog_err("%s: gettime_monotonic() failure: errno=%d: %s", - __PRETTY_FUNCTION__, errno, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "%s: gettime_monotonic() failure: errno=%d: %s", + __PRETTY_FUNCTION__, errno, safe_strerror(errno)); return -1; } @@ -85,8 +89,9 @@ int64_t pim_time_monotonic_usec(void) int64_t now_dsec; if (gettime_monotonic(&now_tv)) { - zlog_err("%s: gettime_monotonic() failure: errno=%d: %s", - __PRETTY_FUNCTION__, errno, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "%s: gettime_monotonic() failure: errno=%d: %s", + __PRETTY_FUNCTION__, errno, safe_strerror(errno)); return -1; } diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c index 80bda336d..70700dd50 100644 --- a/pimd/pim_tlv.c +++ b/pimd/pim_tlv.c @@ -767,12 +767,6 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr, { struct prefix *p; p = prefix_new(); - if (!p) { - zlog_err("%s %s: failure: prefix_new()", - __FILE__, __PRETTY_FUNCTION__); - FREE_ADDR_LIST(*hello_option_addr_list); - return -3; - } prefix_copy(p, &tmp); listnode_add(*hello_option_addr_list, p); } diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index fb616e1b0..baa07a8ec 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -28,6 +28,7 @@ #include "thread.h" #include "prefix.h" #include "vty.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_iface.h" @@ -122,7 +123,8 @@ void zclient_lookup_new(void) { zlookup = zclient_new_notify(master, &zclient_options_default); if (!zlookup) { - zlog_err("%s: zclient_new() failure", __PRETTY_FUNCTION__); + flog_err(LIB_ERR_ZAPI_SOCKET, "%s: zclient_new() failure", + __PRETTY_FUNCTION__); return; } @@ -168,8 +170,9 @@ static int zclient_read_nexthop(struct pim_instance *pim, err = zclient_read_header(s, zlookup->sock, &length, &marker, &version, &vrf_id, &command); if (err < 0) { - zlog_err("%s: zclient_read_header() failed", - __PRETTY_FUNCTION__); + flog_err(LIB_ERR_ZAPI_MISSMATCH, + "%s: zclient_read_header() failed", + __PRETTY_FUNCTION__); zclient_lookup_failed(zlookup); return -1; } @@ -312,14 +315,15 @@ static int zclient_lookup_nexthop_once(struct pim_instance *pim, /* Check socket. */ if (zlookup->sock < 0) { - zlog_err("%s: zclient lookup socket is not connected", - __PRETTY_FUNCTION__); + flog_err(LIB_ERR_ZAPI_SOCKET, + "%s: zclient lookup socket is not connected", + __PRETTY_FUNCTION__); zclient_lookup_failed(zlookup); return -1; } if (pim->vrf->vrf_id == VRF_UNKNOWN) { - zlog_err( + zlog_notice( "%s: VRF: %s does not fully exist yet, delaying lookup", __PRETTY_FUNCTION__, pim->vrf->name); return -1; @@ -333,15 +337,17 @@ static int zclient_lookup_nexthop_once(struct pim_instance *pim, ret = writen(zlookup->sock, s->data, stream_get_endp(s)); if (ret < 0) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "%s: writen() failure: %d writing to zclient lookup socket", __PRETTY_FUNCTION__, errno); zclient_lookup_failed(zlookup); return -2; } if (ret == 0) { - zlog_err("%s: connection closed on zclient lookup socket", - __PRETTY_FUNCTION__); + flog_err_sys(LIB_ERR_SOCKET, + "%s: connection closed on zclient lookup socket", + __PRETTY_FUNCTION__); zclient_lookup_failed(zlookup); return -3; } @@ -509,7 +515,8 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) count = stream_get_endp(s); ret = writen(zlookup->sock, s->data, count); if (ret <= 0) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "%s: writen() failure: %d writing to zclient lookup socket", __PRETTY_FUNCTION__, errno); return -1; @@ -528,8 +535,9 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) err = zclient_read_header(s, zlookup->sock, &length, &marker, &version, &vrf_id, &command); if (err < 0) { - zlog_err("%s: zclient_read_header() failed", - __PRETTY_FUNCTION__); + flog_err(LIB_ERR_ZAPI_MISSMATCH, + "%s: zclient_read_header() failed", + __PRETTY_FUNCTION__); zclient_lookup_failed(zlookup); return -1; } @@ -544,7 +552,8 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) more.src = c_oil->oil.mfcc_origin; more.grp = c_oil->oil.mfcc_mcastgrp; - zlog_err( + flog_err( + LIB_ERR_ZAPI_MISSMATCH, "%s: Received wrong %s(%s) information requested", __PRETTY_FUNCTION__, pim_str_sg_dump(&more), c_oil->pim->vrf->name); diff --git a/pimd/pimd.c b/pimd/pimd.c index cb7b8b589..dd0c7e3c2 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -28,6 +28,7 @@ #include "hash.h" #include "jhash.h" #include "vrf.h" +#include "lib_errors.h" #include "pimd.h" #include "pim_cmd.h" @@ -84,7 +85,8 @@ static void pim_free() void pim_init() { if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "%s %s: could not solve %s to group address: errno=%d: %s", __FILE__, __PRETTY_FUNCTION__, PIM_ALL_PIM_ROUTERS, errno, safe_strerror(errno)); diff --git a/pimd/subdir.am b/pimd/subdir.am index 0696d9b1e..55d56ece9 100644 --- a/pimd/subdir.am +++ b/pimd/subdir.am @@ -15,6 +15,7 @@ pimd_libpim_a_SOURCES = \ pimd/pim_bfd.c \ pimd/pim_br.c \ pimd/pim_cmd.c \ + pimd/pim_errors.c \ pimd/pim_hello.c \ pimd/pim_iface.c \ pimd/pim_ifchannel.c \ @@ -64,6 +65,7 @@ noinst_HEADERS += \ pimd/pim_bfd.h \ pimd/pim_br.h \ pimd/pim_cmd.h \ + pimd/pim_errors.h \ pimd/pim_hello.h \ pimd/pim_iface.h \ pimd/pim_ifchannel.h \ diff --git a/ripd/rip_errors.c b/ripd/rip_errors.c new file mode 100644 index 000000000..363b1b7fb --- /dev/null +++ b/ripd/rip_errors.c @@ -0,0 +1,41 @@ +/* + * RIP-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 + +#include "lib/ferr.h" +#include "rip_errors.h" + +static struct log_ref ferr_rip_err[] = { + { + .code = RIP_ERR_PACKET, + .title = "RIP Packet Error", + .description = "RIP has detected a packet encode/decode issue", + .suggestion = "Gather log files from both sides and open a Issue" + }, + { + .code = END_FERR, + } +}; + +void rip_error_init(void) +{ + log_ref_add(ferr_rip_err); +} diff --git a/ripd/rip_errors.h b/ripd/rip_errors.h new file mode 100644 index 000000000..6b5f5c016 --- /dev/null +++ b/ripd/rip_errors.h @@ -0,0 +1,33 @@ +/* + * RIP-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 __RIP_ERRORS_H__ +#define __RIP_ERRORS_H__ + +#include "lib/ferr.h" + +enum rip_log_refs { + RIP_ERR_PACKET = RIP_FERR_START, + RIP_ERR_CONFIG, +}; + +extern void rip_error_init(void); + +#endif diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 58247f162..364e23c5e 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -34,6 +34,7 @@ #include "filter.h" #include "sockopt.h" #include "privs.h" +#include "lib_errors.h" #include "zebra/connected.h" @@ -864,8 +865,9 @@ static int rip_interface_wakeup(struct thread *t) /* Join to multicast group. */ if (rip_multicast_join(ifp, rip->sock) < 0) { - zlog_err("multicast join failed, interface %s not running", - ifp->name); + flog_err_sys(LIB_ERR_SOCKET, + "multicast join failed, interface %s not running", + ifp->name); return 0; } diff --git a/ripd/rip_main.c b/ripd/rip_main.c index 0194e5312..e5a5c3e22 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -37,6 +37,7 @@ #include "libfrr.h" #include "ripd/ripd.h" +#include "ripd/rip_errors.h" /* ripd options. */ #if CONFDATE > 20190521 @@ -167,6 +168,7 @@ int main(int argc, char **argv) master = frr_init(); /* Library initialization. */ + rip_error_init(); keychain_init(); vrf_init(NULL, NULL, NULL, NULL); diff --git a/ripd/ripd.c b/ripd/ripd.c index a034fb4f2..02ead6fde 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -40,9 +40,11 @@ #include "md5.h" #include "keychain.h" #include "privs.h" +#include "lib_errors.h" #include "ripd/ripd.h" #include "ripd/rip_debug.h" +#include "ripd/rip_errors.h" DEFINE_QOBJ_TYPE(rip) @@ -1056,9 +1058,9 @@ static void rip_auth_md5_set(struct stream *s, struct rip_interface *ri, /* Check packet length. */ if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE)) { - zlog_err( - "rip_auth_md5_set(): packet length %ld is less than minimum length.", - len); + flog_err(RIP_ERR_PACKET, + "rip_auth_md5_set(): packet length %ld is less than minimum length.", + len); return; } @@ -1339,7 +1341,8 @@ static int rip_create_socket(void) /* Make datagram socket. */ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { - zlog_err("Cannot create UDP socket: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "Cannot create UDP socket: %s", + safe_strerror(errno)); exit(1); } @@ -1354,27 +1357,20 @@ static int rip_create_socket(void) setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL); #endif - if (ripd_privs.change(ZPRIVS_RAISE)) - zlog_err("rip_create_socket: could not raise privs"); - setsockopt_so_recvbuf(sock, RIP_UDP_RCV_BUF); - if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr))) < 0) - - { - int save_errno = errno; - if (ripd_privs.change(ZPRIVS_LOWER)) - zlog_err("rip_create_socket: could not lower privs"); - - zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__, - sock, inet_ntoa(addr.sin_addr), - (int)ntohs(addr.sin_port), safe_strerror(save_errno)); - - close(sock); - return ret; + frr_elevate_privs(&ripd_privs) { + setsockopt_so_recvbuf(sock, RIP_UDP_RCV_BUF); + if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr))) + < 0) { + zlog_err("%s: Can't bind socket %d to %s port %d: %s", + __func__, sock, inet_ntoa(addr.sin_addr), + (int)ntohs(addr.sin_port), + safe_strerror(errno)); + + close(sock); + return ret; + } } - if (ripd_privs.change(ZPRIVS_LOWER)) - zlog_err("rip_create_socket: could not lower privs"); - return sock; } diff --git a/ripd/subdir.am b/ripd/subdir.am index 1c5167ef4..612db1a7a 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -13,6 +13,7 @@ endif ripd_librip_a_SOURCES = \ ripd/rip_debug.c \ + ripd/rip_errors.c \ ripd/rip_interface.c \ ripd/rip_memory.c \ ripd/rip_offset.c \ @@ -24,6 +25,7 @@ ripd_librip_a_SOURCES = \ noinst_HEADERS += \ ripd/rip_debug.h \ + ripd/rip_errors.h \ ripd/rip_interface.h \ ripd/rip_memory.h \ ripd/ripd.h \ diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index c463630b1..ef324b001 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -35,6 +35,7 @@ #include "thread.h" #include "privs.h" #include "vrf.h" +#include "lib_errors.h" #include "ripngd/ripngd.h" #include "ripngd/ripng_debug.h" @@ -71,15 +72,14 @@ static int ripng_multicast_join(struct interface *ifp) * While this is bogus, privs are available and easy to use * for this call as a workaround. */ - if (ripngd_privs.change(ZPRIVS_RAISE)) - zlog_err("ripng_multicast_join: could not raise privs"); + frr_elevate_privs(&ripngd_privs) { - ret = setsockopt(ripng->sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, - (char *)&mreq, sizeof(mreq)); - save_errno = errno; + ret = setsockopt(ripng->sock, IPPROTO_IPV6, + IPV6_JOIN_GROUP, + (char *)&mreq, sizeof(mreq)); + save_errno = errno; - if (ripngd_privs.change(ZPRIVS_LOWER)) - zlog_err("ripng_multicast_join: could not lower privs"); + } if (ret < 0 && save_errno == EADDRINUSE) { /* @@ -642,8 +642,9 @@ static int ripng_interface_wakeup(struct thread *t) /* Join to multicast group. */ if (ripng_multicast_join(ifp) < 0) { - zlog_err("multicast join failed, interface %s not running", - ifp->name); + flog_err_sys(LIB_ERR_SOCKET, + "multicast join failed, interface %s not running", + ifp->name); return 0; } diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index f18b6d791..934a87b07 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -35,6 +35,7 @@ #include "routemap.h" #include "if_rmap.h" #include "privs.h" +#include "lib_errors.h" #include "ripngd/ripngd.h" #include "ripngd/ripng_route.h" @@ -94,7 +95,7 @@ static int ripng_make_socket(void) sock = socket(AF_INET6, SOCK_DGRAM, 0); if (sock < 0) { - zlog_err("Can't make ripng socket"); + flog_err_sys(LIB_ERR_SOCKET, "Can't make ripng socket"); return sock; } @@ -124,18 +125,14 @@ static int ripng_make_socket(void) #endif /* SIN6_LEN */ ripaddr.sin6_port = htons(RIPNG_PORT_DEFAULT); - if (ripngd_privs.change(ZPRIVS_RAISE)) - zlog_err("ripng_make_socket: could not raise privs"); - - ret = bind(sock, (struct sockaddr *)&ripaddr, sizeof(ripaddr)); - if (ret < 0) { - zlog_err("Can't bind ripng socket: %s.", safe_strerror(errno)); - if (ripngd_privs.change(ZPRIVS_LOWER)) - zlog_err("ripng_make_socket: could not lower privs"); - goto error; + frr_elevate_privs(&ripngd_privs) { + ret = bind(sock, (struct sockaddr *)&ripaddr, sizeof(ripaddr)); + if (ret < 0) { + zlog_err("Can't bind ripng socket: %s.", + safe_strerror(errno)); + goto error; + } } - if (ripngd_privs.change(ZPRIVS_LOWER)) - zlog_err("ripng_make_socket: could not lower privs"); return sock; error: @@ -202,12 +199,14 @@ int ripng_send_packet(caddr_t buf, int bufsize, struct sockaddr_in6 *to, if (ret < 0) { if (to) - zlog_err("RIPng send fail on %s to %s: %s", ifp->name, - inet6_ntoa(to->sin6_addr), - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "RIPng send fail on %s to %s: %s", + ifp->name, inet6_ntoa(to->sin6_addr), + safe_strerror(errno)); else - zlog_err("RIPng send fail on %s: %s", ifp->name, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "RIPng send fail on %s: %s", ifp->name, + safe_strerror(errno)); } return ret; diff --git a/tests/lib/test_privs.c b/tests/lib/test_privs.c index 421c34543..e203da8f6 100644 --- a/tests/lib/test_privs.c +++ b/tests/lib/test_privs.c @@ -113,10 +113,9 @@ int main(int argc, char **argv) ((test_privs.current_state() == ZPRIVS_RAISED) ? "Raised" : "Lowered") printf("%s\n", PRIV_STATE()); - test_privs.change(ZPRIVS_RAISE); - - printf("%s\n", PRIV_STATE()); - test_privs.change(ZPRIVS_LOWER); + frr_elevate_privs(&test_privs) { + printf("%s\n", PRIV_STATE()); + } printf("%s\n", PRIV_STATE()); zprivs_get_ids(&ids); @@ -126,10 +125,9 @@ int main(int argc, char **argv) /* but these should continue to work... */ printf("%s\n", PRIV_STATE()); - test_privs.change(ZPRIVS_RAISE); - - printf("%s\n", PRIV_STATE()); - test_privs.change(ZPRIVS_LOWER); + frr_elevate_privs(&test_privs) { + printf("%s\n", PRIV_STATE()); + } printf("%s\n", PRIV_STATE()); zprivs_get_ids(&ids); diff --git a/tools/zprivs.cocci b/tools/zprivs.cocci new file mode 100644 index 000000000..76d13c3f0 --- /dev/null +++ b/tools/zprivs.cocci @@ -0,0 +1,76 @@ +@@ +identifier change; +identifier end; +expression E, f, g; +iterator name frr_elevate_privs; +@@ + +- if (E.change(ZPRIVS_RAISE)) +- f; ++ frr_elevate_privs(&E) { + <+... +- goto end; ++ break; + ...+> +- end: +- if (E.change(ZPRIVS_LOWER)) +- g; ++ } + +@@ +identifier change, errno, safe_strerror, exit; +expression E, f1, f2, f3, ret, fn; +iterator name frr_elevate_privs; +@@ + + if (E.change(ZPRIVS_RAISE)) + f1; + ... + if (...) { +- int save_errno = errno; + ... +- if (E.change(ZPRIVS_LOWER)) +- f2; + ... +- safe_strerror(save_errno) ++ safe_strerror(errno) + ... + \( return ret; \| exit(ret); \) + } + ... + if (E.change(ZPRIVS_LOWER)) + f3; + +@@ +identifier change; +expression E, f1, f2, f3, ret; +iterator name frr_elevate_privs; +@@ + + if (E.change(ZPRIVS_RAISE)) + f1; + ... + if (...) { + ... +- if (E.change(ZPRIVS_LOWER)) +- f2; + ... + return ret; + } + ... + if (E.change(ZPRIVS_LOWER)) + f3; + +@@ +identifier change; +expression E, f, g; +iterator name frr_elevate_privs; +@@ + +- if (E.change(ZPRIVS_RAISE)) +- f; ++ frr_elevate_privs(&E) { + ... +- if (E.change(ZPRIVS_LOWER)) +- g; ++ } diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 48a90a695..ef4d1a083 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -45,6 +45,7 @@ #include "libfrr.h" #include "command_graph.h" #include "frrstr.h" +#include "json.h" DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CMD, "Vtysh cmd copy") @@ -2344,6 +2345,28 @@ DEFUN (vtysh_show_debugging_hashtable, "Hashtable statistics for %s:\n"); } +DEFUN (vtysh_show_error_code, + vtysh_show_error_code_cmd, + "show error <(1-4294967296)|all> [json]", + SHOW_STR + "Information on errors\n" + "Error code to get info about\n" + "Information on all errors\n" + JSON_STR) +{ + char *fcmd = argv_concat(argv, argc, 0); + char cmd[256]; + int rv; + + snprintf(cmd, sizeof(cmd), "do %s", fcmd); + + /* FIXME: Needs to determine which daemon to send to via code ranges */ + rv = show_per_daemon(cmd, ""); + + XFREE(MTYPE_TMP, fcmd); + return rv; +} + /* Memory */ DEFUN (vtysh_show_memory, vtysh_show_memory_cmd, @@ -3780,6 +3803,7 @@ void vtysh_init_vty(void) /* debugging */ install_element(VIEW_NODE, &vtysh_show_debugging_cmd); + install_element(VIEW_NODE, &vtysh_show_error_code_cmd); install_element(VIEW_NODE, &vtysh_show_debugging_hashtable_cmd); install_element(ENABLE_NODE, &vtysh_debug_all_cmd); install_element(CONFIG_NODE, &vtysh_debug_all_cmd); diff --git a/watchfrr/subdir.am b/watchfrr/subdir.am index aa1a4403b..931f11ef6 100644 --- a/watchfrr/subdir.am +++ b/watchfrr/subdir.am @@ -8,10 +8,12 @@ endif noinst_HEADERS += \ watchfrr/watchfrr.h \ + watchfrr/watchfrr_errors.h \ # end watchfrr_watchfrr_LDADD = lib/libfrr.la @LIBCAP@ watchfrr_watchfrr_SOURCES = \ watchfrr/watchfrr.c \ + watchfrr/watchfrr_errors.c \ watchfrr/watchfrr_vty.c \ # end diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index ca388d807..c6e750597 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -27,6 +27,7 @@ #include "command.h" #include "memory_vty.h" #include "libfrr.h" +#include "lib_errors.h" #include #include @@ -35,6 +36,7 @@ #include #include "watchfrr.h" +#include "watchfrr_errors.h" #ifndef MIN #define MIN(X,Y) (((X) <= (Y)) ? (X) : (Y)) @@ -247,8 +249,9 @@ static pid_t run_background(char *shell_cmd) switch (child = fork()) { case -1: - zlog_err("fork failed, cannot run command [%s]: %s", shell_cmd, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "fork failed, cannot run command [%s]: %s", + shell_cmd, safe_strerror(errno)); return -1; case 0: /* Child process. */ @@ -262,14 +265,16 @@ static pid_t run_background(char *shell_cmd) char dashc[] = "-c"; char *const argv[4] = {shell, dashc, shell_cmd, NULL}; execv("/bin/sh", argv); - zlog_err("execv(/bin/sh -c '%s') failed: %s", shell_cmd, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "execv(/bin/sh -c '%s') failed: %s", + shell_cmd, safe_strerror(errno)); _exit(127); } default: /* Parent process: we will reap the child later. */ - zlog_err("Forked background command [pid %d]: %s", (int)child, - shell_cmd); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Forked background command [pid %d]: %s", + (int)child, shell_cmd); return child; } } @@ -326,7 +331,8 @@ static void sigchild(void) switch (child = waitpid(-1, &status, WNOHANG)) { case -1: - zlog_err("waitpid failed: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "waitpid failed: %s", + safe_strerror(errno)); return; case 0: zlog_warn("SIGCHLD received, but waitpid did not reap a child"); @@ -349,7 +355,8 @@ static void sigchild(void) * completed. */ gettimeofday(&restart->time, NULL); } else { - zlog_err( + flog_err_sys( + LIB_ERR_SYSTEM_CALL, "waitpid returned status for an unknown child process %d", (int)child); name = "(unknown)"; @@ -370,8 +377,10 @@ static void sigchild(void) zlog_debug("%s %s process %d exited normally", what, name, (int)child); } else - zlog_err("cannot interpret %s %s process %d wait status 0x%x", - what, name, (int)child, status); + flog_err_sys( + LIB_ERR_SYSTEM_CALL, + "cannot interpret %s %s process %d wait status 0x%x", + what, name, (int)child, status); phase_check(); } @@ -481,8 +490,9 @@ static int wakeup_init(struct thread *t_wakeup) dmn->t_wakeup = NULL; if (try_connect(dmn) < 0) { SET_WAKEUP_DOWN(dmn); - zlog_err("%s state -> down : initial connection attempt failed", - dmn->name); + flog_err(WATCHFRR_ERR_CONNECTION, + "%s state -> down : initial connection attempt failed", + dmn->name); dmn->state = DAEMON_DOWN; } return 0; @@ -491,7 +501,8 @@ static int wakeup_init(struct thread *t_wakeup) static void daemon_down(struct daemon *dmn, const char *why) { if (IS_UP(dmn) || (dmn->state == DAEMON_INIT)) - zlog_err("%s state -> down : %s", dmn->name, why); + flog_err(WATCHFRR_ERR_CONNECTION, + "%s state -> down : %s", dmn->name, why); else if (gs.loglevel > LOG_DEBUG) zlog_debug("%s still down : %s", dmn->name, why); if (IS_UP(dmn)) @@ -684,21 +695,23 @@ static int try_connect(struct daemon *dmn) of creating a socket. */ if (access(addr.sun_path, W_OK) < 0) { if (errno != ENOENT) - zlog_err("%s: access to socket %s denied: %s", - dmn->name, addr.sun_path, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "%s: access to socket %s denied: %s", + dmn->name, addr.sun_path, + safe_strerror(errno)); return -1; } if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - zlog_err("%s(%s): cannot make socket: %s", __func__, - addr.sun_path, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "%s(%s): cannot make socket: %s", + __func__, addr.sun_path, safe_strerror(errno)); return -1; } if (set_nonblocking(sock) < 0 || set_cloexec(sock) < 0) { - zlog_err("%s(%s): set_nonblocking/cloexec(%d) failed", __func__, - addr.sun_path, sock); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "%s(%s): set_nonblocking/cloexec(%d) failed", + __func__, addr.sun_path, sock); close(sock); return -1; } @@ -735,8 +748,9 @@ static int try_connect(struct daemon *dmn) static int phase_hanging(struct thread *t_hanging) { gs.t_phase_hanging = NULL; - zlog_err("Phase [%s] hanging for %ld seconds, aborting phased restart", - phase_str[gs.phase], PHASE_TIMEOUT); + flog_err(WATCHFRR_ERR_CONNECTION, + "Phase [%s] hanging for %ld seconds, aborting phased restart", + phase_str[gs.phase], PHASE_TIMEOUT); gs.phase = PHASE_NONE; return 0; } @@ -850,10 +864,10 @@ static int wakeup_unresponsive(struct thread *t_wakeup) dmn->t_wakeup = NULL; if (dmn->state != DAEMON_UNRESPONSIVE) - zlog_err( - "%s: no longer unresponsive (now %s), " - "wakeup should have been cancelled!", - dmn->name, state_str[dmn->state]); + flog_err(WATCHFRR_ERR_CONNECTION, + "%s: no longer unresponsive (now %s), " + "wakeup should have been cancelled!", + dmn->name, state_str[dmn->state]); else { SET_WAKEUP_UNRESPONSIVE(dmn); try_restart(dmn); @@ -867,10 +881,10 @@ static int wakeup_no_answer(struct thread *t_wakeup) dmn->t_wakeup = NULL; dmn->state = DAEMON_UNRESPONSIVE; - zlog_err( - "%s state -> unresponsive : no response yet to ping " - "sent %ld seconds ago", - dmn->name, gs.timeout); + flog_err(WATCHFRR_ERR_CONNECTION, + "%s state -> unresponsive : no response yet to ping " + "sent %ld seconds ago", + dmn->name, gs.timeout); SET_WAKEUP_UNRESPONSIVE(dmn); try_restart(dmn); return 0; @@ -1149,6 +1163,7 @@ int main(int argc, char **argv) gs.restart.interval = gs.min_restart_interval; master = frr_init(); + watchfrr_error_init(); zlog_set_level(ZLOG_DEST_MONITOR, ZLOG_DISABLED); if (watchfrr_di.daemon_mode) { diff --git a/watchfrr/watchfrr_errors.c b/watchfrr/watchfrr_errors.c new file mode 100644 index 000000000..662e7f654 --- /dev/null +++ b/watchfrr/watchfrr_errors.c @@ -0,0 +1,43 @@ +/* + * Watchfrr-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 + +#include "lib/ferr.h" +#include "watchfrr_errors.h" + +/* clang-format off */ +static struct log_ref ferr_watchfrr_err[] = { + { + .code = WATCHFRR_ERR_CONNECTION, + .title = "WATCHFRR Connection Error", + .description = "WATCHFRR has detected a connectivity issue with one of the FRR daemons", + .suggestion = "Ensure that FRR is still running and if not please open an Issue" + }, + { + .code = END_FERR, + } +}; +/* clang-format on */ + +void watchfrr_error_init(void) +{ + log_ref_add(ferr_watchfrr_err); +} diff --git a/watchfrr/watchfrr_errors.h b/watchfrr/watchfrr_errors.h new file mode 100644 index 000000000..4652f950f --- /dev/null +++ b/watchfrr/watchfrr_errors.h @@ -0,0 +1,32 @@ +/* + * Watchfrr-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 __WATCHFRR_ERRORS_H__ +#define __WATCHFRR_ERRORS_H__ + +#include "lib/ferr.h" + +enum watchfrr_log_refs { + WATCHFRR_ERR_CONNECTION = WATCHFRR_FERR_START, +}; + +extern void watchfrr_error_init(void); + +#endif diff --git a/zebra/connected.h b/zebra/connected.h index 2a2b09339..75b6e05bd 100644 --- a/zebra/connected.h +++ b/zebra/connected.h @@ -22,6 +22,12 @@ #ifndef _ZEBRA_CONNECTED_H #define _ZEBRA_CONNECTED_H +#include +#include + +#include "lib/if.h" +#include "lib/prefix.h" + extern struct connected *connected_check(struct interface *ifp, union prefixconstptr p); extern struct connected *connected_check_ptp(struct interface *ifp, diff --git a/zebra/debug.h b/zebra/debug.h index 1c08459e2..e74afe476 100644 --- a/zebra/debug.h +++ b/zebra/debug.h @@ -22,6 +22,8 @@ #ifndef _ZEBRA_DEBUG_H #define _ZEBRA_DEBUG_H +#include "lib/vty.h" + /* Debug flags. */ #define ZEBRA_DEBUG_EVENT 0x01 diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c index f5ed94552..d17a9cf49 100644 --- a/zebra/if_ioctl.c +++ b/zebra/if_ioctl.c @@ -33,6 +33,7 @@ #include "log.h" #include "vrf.h" #include "vty.h" +#include "lib_errors.h" #include "zebra/interface.h" #include "zebra/rib.h" @@ -175,13 +176,15 @@ static int if_getaddrs(void) ret = getifaddrs(&ifap); if (ret != 0) { - zlog_err("getifaddrs(): %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "getifaddrs(): %s", + safe_strerror(errno)); return -1; } for (ifapfree = ifap; ifap; ifap = ifap->ifa_next) { if (ifap->ifa_addr == NULL) { - zlog_err( + flog_err( + LIB_ERR_INTERFACE, "%s: nonsensical ifaddr with NULL ifa_addr, ifname %s", __func__, (ifap->ifa_name ? ifap->ifa_name : "(null)")); @@ -190,8 +193,9 @@ static int if_getaddrs(void) ifp = if_lookup_by_name(ifap->ifa_name, VRF_DEFAULT); if (ifp == NULL) { - zlog_err("if_getaddrs(): Can't lookup interface %s\n", - ifap->ifa_name); + flog_err(LIB_ERR_INTERFACE, + "if_getaddrs(): Can't lookup interface %s\n", + ifap->ifa_name); continue; } diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c index 6627787fd..5a58fe175 100644 --- a/zebra/if_ioctl_solaris.c +++ b/zebra/if_ioctl_solaris.c @@ -34,6 +34,7 @@ #include "privs.h" #include "vrf.h" #include "vty.h" +#include "lib_errors.h" #include "zebra/interface.h" #include "zebra/ioctl_solaris.h" @@ -58,29 +59,26 @@ static int interface_list_ioctl(int af) size_t needed, lastneeded = 0; char *buf = NULL; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); + frr_elevate_privs(&zserv_privs) { + sock = socket(af, SOCK_DGRAM, 0); + } - sock = socket(af, SOCK_DGRAM, 0); if (sock < 0) { zlog_warn("Can't make %s socket stream: %s", (af == AF_INET ? "AF_INET" : "AF_INET6"), safe_strerror(errno)); - - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - return -1; } -calculate_lifc_len: /* must hold privileges to enter here */ - lifn.lifn_family = af; - lifn.lifn_flags = LIFC_NOXMIT; /* we want NOXMIT interfaces too */ - ret = ioctl(sock, SIOCGLIFNUM, &lifn); - save_errno = errno; +calculate_lifc_len: + frr_elevate_privs(&zserv_privs) { + lifn.lifn_family = af; + lifn.lifn_flags = LIFC_NOXMIT; + /* we want NOXMIT interfaces too */ + ret = ioctl(sock, SIOCGLIFNUM, &lifn); + save_errno = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + } if (ret < 0) { zlog_warn("interface_list_ioctl: SIOCGLIFNUM failed %s", @@ -109,27 +107,18 @@ calculate_lifc_len: /* must hold privileges to enter here */ lifconf.lifc_len = needed; lifconf.lifc_buf = buf; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - - ret = ioctl(sock, SIOCGLIFCONF, &lifconf); + frr_elevate_privs(&zserv_privs) { + ret = ioctl(sock, SIOCGLIFCONF, &lifconf); + } if (ret < 0) { if (errno == EINVAL) - goto calculate_lifc_len; /* deliberately hold privileges - */ + goto calculate_lifc_len; zlog_warn("SIOCGLIFCONF: %s", safe_strerror(errno)); - - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - goto end; } - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - /* Allocate interface. */ lifreq = lifconf.lifc_req; diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 56e27e6dc..a15d91424 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -52,6 +52,7 @@ #include "vrf.h" #include "vrf_int.h" #include "mpls.h" +#include "lib_errors.h" #include "vty.h" #include "zebra/zserv.h" @@ -79,9 +80,9 @@ static void set_ifindex(struct interface *ifp, ifindex_t ifi_index, if (((oifp = if_lookup_by_index_per_ns(zns, ifi_index)) != NULL) && (oifp != ifp)) { if (ifi_index == IFINDEX_INTERNAL) - zlog_err( - "Netlink is setting interface %s ifindex to reserved " - "internal value %u", + flog_err( + LIB_ERR_INTERFACE, + "Netlink is setting interface %s ifindex to reserved internal value %u", ifp->name, ifi_index); else { if (IS_ZEBRA_DEBUG_KERNEL) @@ -89,9 +90,9 @@ static void set_ifindex(struct interface *ifp, ifindex_t ifi_index, "interface index %d was renamed from %s to %s", ifi_index, oifp->name, ifp->name); if (if_is_up(oifp)) - zlog_err( - "interface rename detected on up interface: index %d " - "was renamed from %s to %s, results are uncertain!", + flog_err( + LIB_ERR_INTERFACE, + "interface rename detected on up interface: index %d was renamed from %s to %s, results are uncertain!", ifi_index, oifp->name, ifp->name); if_delete_update(oifp); } @@ -309,8 +310,8 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, vrf = vrf_get((vrf_id_t)ifi->ifi_index, name); // It would create vrf if (!vrf) { - zlog_err("VRF %s id %u not created", name, - ifi->ifi_index); + flog_err(LIB_ERR_INTERFACE, "VRF %s id %u not created", + name, ifi->ifi_index); return; } @@ -331,8 +332,9 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, /* Enable the created VRF. */ if (!vrf_enable(vrf)) { - zlog_err("Failed to enable VRF %s id %u", name, - ifi->ifi_index); + flog_err(LIB_ERR_INTERFACE, + "Failed to enable VRF %s id %u", name, + ifi->ifi_index); return; } @@ -373,20 +375,20 @@ static int get_iflink_speed(struct interface *interface) ifdata.ifr_data = (caddr_t)&ecmd; /* use ioctl to get IP address of an interface */ - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - sd = vrf_socket(PF_INET, SOCK_DGRAM, IPPROTO_IP, interface->vrf_id, - NULL); - if (sd < 0) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("Failure to read interface %s speed: %d %s", - ifname, errno, safe_strerror(errno)); - return 0; - } + frr_elevate_privs(&zserv_privs) { + sd = vrf_socket(PF_INET, SOCK_DGRAM, IPPROTO_IP, + interface->vrf_id, + NULL); + if (sd < 0) { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("Failure to read interface %s speed: %d %s", + ifname, errno, safe_strerror(errno)); + return 0; + } /* Get the current link state for the interface */ - rc = vrf_ioctl(interface->vrf_id, sd, SIOCETHTOOL, (char *)&ifdata); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + rc = vrf_ioctl(interface->vrf_id, sd, SIOCETHTOOL, + (char *)&ifdata); + } if (rc < 0) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( @@ -915,7 +917,8 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) ifp = if_lookup_by_index_per_ns(zns, ifa->ifa_index); if (ifp == NULL) { - zlog_err( + flog_err( + LIB_ERR_INTERFACE, "netlink_interface_addr can't find interface by index %d", ifa->ifa_index); return -1; diff --git a/zebra/interface.c b/zebra/interface.c index 4211155c2..763931d35 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -22,6 +22,7 @@ #include #include "if.h" +#include "lib_errors.h" #include "vty.h" #include "sockunion.h" #include "prefix.h" @@ -718,7 +719,8 @@ void if_delete_update(struct interface *ifp) struct zebra_if *zif; if (if_is_up(ifp)) { - zlog_err( + flog_err( + LIB_ERR_INTERFACE, "interface %s vrf %u index %d is still up while being deleted.", ifp->name, ifp->vrf_id, ifp->ifindex); return; diff --git a/zebra/ioctl.c b/zebra/ioctl.c index a577b008d..0469bc38c 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -27,6 +27,7 @@ #include "ioctl.h" #include "log.h" #include "privs.h" +#include "lib_errors.h" #include "vty.h" #include "zebra/rib.h" @@ -54,22 +55,16 @@ int if_ioctl(unsigned long request, caddr_t buffer) int ret; int err = 0; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - int save_errno = errno; - - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_err("Cannot create UDP socket: %s", - safe_strerror(save_errno)); - exit(1); + frr_elevate_privs(&zserv_privs) { + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + zlog_err("Cannot create UDP socket: %s", + safe_strerror(errno)); + exit(1); + } + if ((ret = ioctl(sock, request, buffer)) < 0) + err = errno; } - if ((ret = ioctl(sock, request, buffer)) < 0) - err = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); close(sock); if (ret < 0) { @@ -86,23 +81,17 @@ int vrf_if_ioctl(unsigned long request, caddr_t buffer, vrf_id_t vrf_id) int ret; int err = 0; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - sock = vrf_socket(AF_INET, SOCK_DGRAM, 0, vrf_id, NULL); - if (sock < 0) { - int save_errno = errno; - - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_err("Cannot create UDP socket: %s", - safe_strerror(save_errno)); - exit(1); + frr_elevate_privs(&zserv_privs) { + sock = vrf_socket(AF_INET, SOCK_DGRAM, 0, vrf_id, NULL); + if (sock < 0) { + zlog_err("Cannot create UDP socket: %s", + safe_strerror(errno)); + exit(1); + } + ret = vrf_ioctl(vrf_id, sock, request, buffer); + if (ret < 0) + err = errno; } - ret = vrf_ioctl(vrf_id, sock, request, buffer); - if (ret < 0) - err = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); close(sock); if (ret < 0) { @@ -119,23 +108,17 @@ static int if_ioctl_ipv6(unsigned long request, caddr_t buffer) int ret; int err = 0; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - sock = socket(AF_INET6, SOCK_DGRAM, 0); - if (sock < 0) { - int save_errno = errno; - - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_err("Cannot create IPv6 datagram socket: %s", - safe_strerror(save_errno)); - exit(1); - } + frr_elevate_privs(&zserv_privs) { + sock = socket(AF_INET6, SOCK_DGRAM, 0); + if (sock < 0) { + zlog_err("Cannot create IPv6 datagram socket: %s", + safe_strerror(errno)); + exit(1); + } - if ((ret = ioctl(sock, request, buffer)) < 0) - err = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + if ((ret = ioctl(sock, request, buffer)) < 0) + err = errno; + } close(sock); if (ret < 0) { @@ -413,8 +396,9 @@ void if_get_flags(struct interface *ifp) ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id); if (ret < 0) { - zlog_err("vrf_if_ioctl(SIOCGIFFLAGS) failed: %s", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "vrf_if_ioctl(SIOCGIFFLAGS) failed: %s", + safe_strerror(errno)); return; } #ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */ @@ -431,8 +415,9 @@ void if_get_flags(struct interface *ifp) /* Seems not all interfaces implement this ioctl */ if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) - zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "if_ioctl(SIOCGIFMEDIA) failed: %s", + safe_strerror(errno)); else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ { if (ifmr.ifm_status & IFM_ACTIVE) diff --git a/zebra/ioctl_solaris.c b/zebra/ioctl_solaris.c index eb68451f7..260911ce6 100644 --- a/zebra/ioctl_solaris.c +++ b/zebra/ioctl_solaris.c @@ -31,6 +31,7 @@ #include "privs.h" #include "vty.h" #include "vrf.h" +#include "lib_errors.h" #include "zebra/rib.h" #include "zebra/rt.h" @@ -57,24 +58,19 @@ int if_ioctl(unsigned long request, caddr_t buffer) int ret; int err; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - int save_errno = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_err("Cannot create UDP socket: %s", - safe_strerror(save_errno)); - exit(1); - } + frr_elevate_privs(&zserv_privs) { + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + zlog_err("Cannot create UDP socket: %s", + safe_strerror(errno)); + exit(1); + } - if ((ret = ioctl(sock, request, buffer)) < 0) - err = errno; + if ((ret = ioctl(sock, request, buffer)) < 0) + err = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + } close(sock); @@ -92,24 +88,19 @@ int if_ioctl_ipv6(unsigned long request, caddr_t buffer) int ret; int err; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - - sock = socket(AF_INET6, SOCK_DGRAM, 0); - if (sock < 0) { - int save_errno = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_err("Cannot create IPv6 datagram socket: %s", - safe_strerror(save_errno)); - exit(1); - } + frr_elevate_privs(&zserv_privs) { + + sock = socket(AF_INET6, SOCK_DGRAM, 0); + if (sock < 0) { + zlog_err("Cannot create IPv6 datagram socket: %s", + safe_strerror(errno)); + exit(1); + } - if ((ret = ioctl(sock, request, buffer)) < 0) - err = errno; + if ((ret = ioctl(sock, request, buffer)) < 0) + err = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + } close(sock); diff --git a/zebra/ipforward_proc.c b/zebra/ipforward_proc.c index f823ec438..3a766b1ea 100644 --- a/zebra/ipforward_proc.c +++ b/zebra/ipforward_proc.c @@ -25,6 +25,7 @@ #include "log.h" #include "privs.h" +#include "lib_errors.h" #include "zebra/ipforward.h" @@ -76,24 +77,19 @@ int ipforward_on(void) { FILE *fp; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges, %s", safe_strerror(errno)); + frr_elevate_privs(&zserv_privs) { - fp = fopen(proc_ipv4_forwarding, "w"); + fp = fopen(proc_ipv4_forwarding, "w"); - if (fp == NULL) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges, %s", - safe_strerror(errno)); - return -1; - } + if (fp == NULL) { + return -1; + } - fprintf(fp, "1\n"); + fprintf(fp, "1\n"); - fclose(fp); + fclose(fp); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges, %s", safe_strerror(errno)); + } return ipforward(); } @@ -102,24 +98,19 @@ int ipforward_off(void) { FILE *fp; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges, %s", safe_strerror(errno)); + frr_elevate_privs(&zserv_privs) { - fp = fopen(proc_ipv4_forwarding, "w"); + fp = fopen(proc_ipv4_forwarding, "w"); - if (fp == NULL) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges, %s", - safe_strerror(errno)); - return -1; - } + if (fp == NULL) { + return -1; + } - fprintf(fp, "0\n"); + fprintf(fp, "0\n"); - fclose(fp); + fclose(fp); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges, %s", safe_strerror(errno)); + } return ipforward(); } @@ -153,24 +144,19 @@ int ipforward_ipv6_on(void) { FILE *fp; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges, %s", safe_strerror(errno)); + frr_elevate_privs(&zserv_privs) { - fp = fopen(proc_ipv6_forwarding, "w"); + fp = fopen(proc_ipv6_forwarding, "w"); - if (fp == NULL) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges, %s", - safe_strerror(errno)); - return -1; - } + if (fp == NULL) { + return -1; + } - fprintf(fp, "1\n"); + fprintf(fp, "1\n"); - fclose(fp); + fclose(fp); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges, %s", safe_strerror(errno)); + } return ipforward_ipv6(); } @@ -180,24 +166,19 @@ int ipforward_ipv6_off(void) { FILE *fp; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges, %s", safe_strerror(errno)); + frr_elevate_privs(&zserv_privs) { - fp = fopen(proc_ipv6_forwarding, "w"); + fp = fopen(proc_ipv6_forwarding, "w"); - if (fp == NULL) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges, %s", - safe_strerror(errno)); - return -1; - } + if (fp == NULL) { + return -1; + } - fprintf(fp, "0\n"); + fprintf(fp, "0\n"); - fclose(fp); + fclose(fp); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges, %s", safe_strerror(errno)); + } return ipforward_ipv6(); } diff --git a/zebra/ipforward_solaris.c b/zebra/ipforward_solaris.c index 123cf1bd0..b06baa04a 100644 --- a/zebra/ipforward_solaris.c +++ b/zebra/ipforward_solaris.c @@ -25,6 +25,7 @@ #include "log.h" #include "prefix.h" +#include "lib_errors.h" #include "privs.h" #include "zebra/ipforward.h" @@ -69,10 +70,10 @@ static int solaris_nd(const int cmd, const char *parameter, const int value) else if (cmd == ND_GET) snprintf(nd_buf, ND_BUFFER_SIZE, "%s", parameter); else { - zlog_err( - "internal error - inappropriate command given to " - "solaris_nd()%s:%d", - __FILE__, __LINE__); + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "internal error - inappropriate command given to " + "solaris_nd()%s:%d", + __FILE__, __LINE__); return -1; } @@ -81,27 +82,21 @@ static int solaris_nd(const int cmd, const char *parameter, const int value) strioctl.ic_len = ND_BUFFER_SIZE; strioctl.ic_dp = nd_buf; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("solaris_nd: Can't raise privileges"); - if ((fd = open(device, O_RDWR)) < 0) { - zlog_warn("failed to open device %s - %s", device, - safe_strerror(errno)); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("solaris_nd: Can't lower privileges"); - return -1; - } - if (ioctl(fd, I_STR, &strioctl) < 0) { - int save_errno = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("solaris_nd: Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + if ((fd = open(device, O_RDWR)) < 0) { + zlog_warn("failed to open device %s - %s", device, + safe_strerror(errno)); + return -1; + } + if (ioctl(fd, I_STR, &strioctl) < 0) { + close(fd); + zlog_warn("ioctl I_STR failed on device %s - %s", + device, + safe_strerror(errno)); + return -1; + } close(fd); - zlog_warn("ioctl I_STR failed on device %s - %s", device, - safe_strerror(save_errno)); - return -1; } - close(fd); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("solaris_nd: Can't lower privileges"); if (cmd == ND_GET) { errno = 0; diff --git a/zebra/ipforward_sysctl.c b/zebra/ipforward_sysctl.c index cdf426b9b..74a178e59 100644 --- a/zebra/ipforward_sysctl.c +++ b/zebra/ipforward_sysctl.c @@ -26,6 +26,7 @@ #include "zebra/ipforward.h" #include "log.h" +#include "lib_errors.h" #define MIB_SIZ 4 @@ -53,16 +54,12 @@ int ipforward_on(void) int ipforwarding = 1; len = sizeof ipforwarding; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - if (sysctl(mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_warn("Can't set ipforwarding on"); - return -1; + frr_elevate_privs(&zserv_privs) { + if (sysctl(mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) { + zlog_warn("Can't set ipforwarding on"); + return -1; + } } - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); return ipforwarding; } @@ -72,16 +69,12 @@ int ipforward_off(void) int ipforwarding = 0; len = sizeof ipforwarding; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - if (sysctl(mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_warn("Can't set ipforwarding on"); - return -1; + frr_elevate_privs(&zserv_privs) { + if (sysctl(mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) { + zlog_warn("Can't set ipforwarding on"); + return -1; + } } - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); return ipforwarding; } @@ -100,16 +93,12 @@ int ipforward_ipv6(void) int ip6forwarding = 0; len = sizeof ip6forwarding; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - if (sysctl(mib_ipv6, MIB_SIZ, &ip6forwarding, &len, 0, 0) < 0) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_warn("can't get ip6forwarding value"); - return -1; + frr_elevate_privs(&zserv_privs) { + if (sysctl(mib_ipv6, MIB_SIZ, &ip6forwarding, &len, 0, 0) < 0) { + zlog_warn("can't get ip6forwarding value"); + return -1; + } } - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); return ip6forwarding; } @@ -119,16 +108,13 @@ int ipforward_ipv6_on(void) int ip6forwarding = 1; len = sizeof ip6forwarding; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - if (sysctl(mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_warn("can't get ip6forwarding value"); - return -1; + frr_elevate_privs(&zserv_privs) { + if (sysctl(mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) + < 0) { + zlog_warn("can't get ip6forwarding value"); + return -1; + } } - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); return ip6forwarding; } @@ -138,16 +124,13 @@ int ipforward_ipv6_off(void) int ip6forwarding = 0; len = sizeof ip6forwarding; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - if (sysctl(mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - zlog_warn("can't get ip6forwarding value"); - return -1; + frr_elevate_privs(&zserv_privs) { + if (sysctl(mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) + < 0) { + zlog_warn("can't get ip6forwarding value"); + return -1; + } } - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); return ip6forwarding; } diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index ca7840479..f02ba1fa2 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -1,7 +1,13 @@ /* * - * Copyright (C) 2000 Robert Olsson. - * Swedish University of Agricultural Sciences + * Copyright (C) 1997, 2000 + * Portions: + * Swedish University of Agricultural Sciences + * Robert Olsson + * Kunihiro Ishiguro + * + * Thanks to Jens Laas at Swedish University of Agricultural Sciences + * for reviewing and tests. * * This file is part of GNU Zebra. * @@ -20,19 +26,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* - * This work includes work with the following copywrite: - * - * Copyright (C) 1997, 2000 Kunihiro Ishiguro - * - */ - -/* - * Thanks to Jens Låås at Swedish University of Agricultural Sciences - * for reviewing and tests. - */ - - #include #include "if.h" diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index c2411d083..771ae796e 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -28,7 +28,7 @@ */ /* - * Thanks to Jens Låås at Swedish University of Agricultural Sciences + * Thanks to Jens Laas at Swedish University of Agricultural Sciences * for reviewing and tests. */ @@ -51,6 +51,7 @@ #include "thread.h" #include "privs.h" #include "libfrr.h" +#include "lib_errors.h" #include "version.h" #include "zebra/interface.h" #include "zebra/rtadv.h" @@ -80,16 +81,12 @@ int irdp_sock_init(void) int save_errno; int sock; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("irdp_sock_init: could not raise privs, %s", - safe_strerror(errno)); + frr_elevate_privs(&zserv_privs) { - sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - save_errno = errno; + sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + save_errno = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("irdp_sock_init: could not lower privs, %s", - safe_strerror(errno)); + } if (sock < 0) { zlog_warn("IRDP: can't create irdp socket %s", diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index b0dde96cc..c36c95897 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -28,39 +28,39 @@ */ /* - * Thanks to Jens Låås at Swedish University of Agricultural Sciences + * Thanks to Jens Laas at Swedish University of Agricultural Sciences * for reviewing and tests. */ #include +#include - -#include "if.h" -#include "vty.h" -#include "sockunion.h" -#include "prefix.h" +#include "checksum.h" #include "command.h" -#include "memory.h" -#include "zebra_memory.h" -#include "stream.h" -#include "ioctl.h" #include "connected.h" +#include "if.h" +#include "ioctl.h" #include "log.h" -#include "zclient.h" +#include "log.h" +#include "memory.h" +#include "prefix.h" +#include "sockopt.h" +#include "sockunion.h" +#include "sockunion.h" +#include "stream.h" #include "thread.h" +#include "vty.h" +#include "zclient.h" + +#include "zebra_memory.h" #include "zebra/interface.h" #include "zebra/rtadv.h" #include "zebra/rib.h" #include "zebra/zserv.h" #include "zebra/redistribute.h" #include "zebra/irdp.h" -#include -#include "if.h" -#include "checksum.h" -#include "sockunion.h" -#include "log.h" -#include "sockopt.h" +#include "zebra/zebra_errors.h" /* GLOBAL VARS */ @@ -95,13 +95,15 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) src = ip->ip_src; if (len != iplen) { - zlog_err("IRDP: RX length doesnt match IP length"); + flog_err(ZEBRA_ERR_IRDP_LEN_MISMATCH, + "IRDP: RX length doesnt match IP length"); return; } if (iplen < ICMP_MINLEN) { - zlog_err("IRDP: RX ICMP packet too short from %s\n", - inet_ntoa(src)); + flog_err(ZEBRA_ERR_IRDP_LEN_MISMATCH, + "IRDP: RX ICMP packet too short from %s\n", + inet_ntoa(src)); return; } @@ -110,8 +112,9 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) + len of IP-header) 14+20 */ if (iplen > IRDP_RX_BUF - 34) { - zlog_err("IRDP: RX ICMP packet too long from %s\n", - inet_ntoa(src)); + flog_err(ZEBRA_ERR_IRDP_LEN_MISMATCH, + "IRDP: RX ICMP packet too long from %s\n", + inet_ntoa(src)); return; } diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index a5c2cd69f..ef7c26c9d 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -41,6 +41,7 @@ #include "nexthop.h" #include "vrf.h" #include "mpls.h" +#include "lib_errors.h" #include "zebra/zserv.h" #include "zebra/zebra_ns.h" @@ -51,6 +52,7 @@ #include "zebra/rt_netlink.h" #include "zebra/if_netlink.h" #include "zebra/rule_netlink.h" +#include "zebra/zebra_errors.h" #ifndef SO_RCVBUFFORCE #define SO_RCVBUFFORCE (33) @@ -147,9 +149,8 @@ int netlink_talk_filter(struct nlmsghdr *h, ns_id_t ns_id, int startup) * received some other message in an unexpected * way. */ - zlog_err("%s: ignoring message type 0x%04x(%s) NS %u", - __PRETTY_FUNCTION__, h->nlmsg_type, - nl_msg_type_to_str(h->nlmsg_type), ns_id); + zlog_debug("%s: ignoring message type 0x%04x(%s) NS %u", __func__, + h->nlmsg_type, nl_msg_type_to_str(h->nlmsg_type), ns_id); return 0; } @@ -162,31 +163,33 @@ static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize) ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen); if (ret < 0) { - zlog_err("Can't get %s receive buffer size: %s", nl->name, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "Can't get %s receive buffer size: %s", nl->name, + safe_strerror(errno)); return -1; } /* Try force option (linux >= 2.6.14) and fall back to normal set */ - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("routing_socket: Can't raise privileges"); - ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize, - sizeof(nl_rcvbufsize)); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("routing_socket: Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, + &nl_rcvbufsize, + sizeof(nl_rcvbufsize)); + } if (ret < 0) ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize, sizeof(nl_rcvbufsize)); if (ret < 0) { - zlog_err("Can't set %s receive buffer size: %s", nl->name, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "Can't set %s receive buffer size: %s", nl->name, + safe_strerror(errno)); return -1; } ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen); if (ret < 0) { - zlog_err("Can't get %s receive buffer size: %s", nl->name, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "Can't get %s receive buffer size: %s", nl->name, + safe_strerror(errno)); return -1; } @@ -203,33 +206,26 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups, struct sockaddr_nl snl; int sock; int namelen; - int save_errno; - if (zserv_privs.change(ZPRIVS_RAISE)) { - zlog_err("Can't raise privileges"); - return -1; - } - - sock = ns_socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, ns_id); - if (sock < 0) { - zlog_err("Can't open %s socket: %s", nl->name, - safe_strerror(errno)); - return -1; - } + frr_elevate_privs(&zserv_privs) { + sock = ns_socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, ns_id); + if (sock < 0) { + zlog_err("Can't open %s socket: %s", nl->name, + safe_strerror(errno)); + return -1; + } - memset(&snl, 0, sizeof snl); - snl.nl_family = AF_NETLINK; - snl.nl_groups = groups; + memset(&snl, 0, sizeof snl); + snl.nl_family = AF_NETLINK; + snl.nl_groups = groups; - /* Bind the socket to the netlink structure for anything. */ - ret = bind(sock, (struct sockaddr *)&snl, sizeof snl); - save_errno = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + /* Bind the socket to the netlink structure for anything. */ + ret = bind(sock, (struct sockaddr *)&snl, sizeof snl); + } if (ret < 0) { zlog_err("Can't bind %s socket to group 0x%x: %s", nl->name, - snl.nl_groups, safe_strerror(save_errno)); + snl.nl_groups, safe_strerror(errno)); close(sock); return -1; } @@ -238,8 +234,8 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups, namelen = sizeof snl; ret = getsockname(sock, (struct sockaddr *)&snl, (socklen_t *)&namelen); if (ret < 0 || namelen != sizeof snl) { - zlog_err("Can't get %s socket name: %s", nl->name, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "Can't get %s socket name: %s", + nl->name, safe_strerror(errno)); close(sock); return -1; } @@ -290,9 +286,10 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, * this message type or not ask for * it to be sent up to us */ - zlog_err("Unknown netlink nlmsg_type %s(%d) vrf %u\n", - nl_msg_type_to_str(h->nlmsg_type), h->nlmsg_type, - ns_id); + flog_err(ZEBRA_ERR_UNKNOWN_NLMSG, + "Unknown netlink nlmsg_type %s(%d) vrf %u\n", + nl_msg_type_to_str(h->nlmsg_type), h->nlmsg_type, + ns_id); break; } return 0; @@ -335,15 +332,15 @@ static void netlink_write_incoming(const char *buf, const unsigned int size, char fname[MAXPATHLEN]; FILE *f; - zserv_privs.change(ZPRIVS_RAISE); snprintf(fname, MAXPATHLEN, "%s/%s_%u", DAEMON_VTY_DIR, "netlink", counter); - f = fopen(fname, "w"); + frr_elevate_privs(&zserv_privs) { + f = fopen(fname, "w"); + } if (f) { fwrite(buf, 1, size, f); fclose(f); } - zserv_privs.change(ZPRIVS_LOWER); } /** @@ -358,8 +355,9 @@ static long netlink_read_file(char *buf, const char *fname) FILE *f; long file_bytes = -1; - zserv_privs.change(ZPRIVS_RAISE); - f = fopen(fname, "r"); + frr_elevate_privs(&zserv_privs) { + f = fopen(fname, "r"); + } if (f) { fseek(f, 0, SEEK_END); file_bytes = ftell(f); @@ -367,7 +365,6 @@ static long netlink_read_file(char *buf, const char *fname) fread(buf, NL_RCV_PKT_BUF_SIZE, 1, f); fclose(f); } - zserv_privs.change(ZPRIVS_LOWER); return file_bytes; } @@ -699,8 +696,9 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), continue; if (errno == EWOULDBLOCK || errno == EAGAIN) break; - zlog_err("%s recvmsg overrun: %s", nl->name, - safe_strerror(errno)); + flog_err(ZEBRA_ERR_RECVMSG_OVERRUN, + "%s recvmsg overrun: %s", nl->name, + safe_strerror(errno)); /* * In this case we are screwed. * There is no good way to @@ -711,13 +709,14 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), } if (status == 0) { - zlog_err("%s EOF", nl->name); + flog_err_sys(LIB_ERR_SOCKET, "%s EOF", nl->name); return -1; } if (msg.msg_namelen != sizeof snl) { - zlog_err("%s sender address length error: length %d", - nl->name, msg.msg_namelen); + flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR, + "%s sender address length error: length %d", + nl->name, msg.msg_namelen); return -1; } @@ -788,6 +787,15 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), continue; } + if (h->nlmsg_len + < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { + flog_err( + ZEBRA_ERR_NETLINK_LENGTH_ERROR, + "%s error: message truncated", + nl->name); + return -1; + } + /* Deal with errors that occur because of races * in link handling */ if (nl == &zns->netlink_cmd @@ -836,7 +844,8 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), err->msg.nlmsg_seq, err->msg.nlmsg_pid); } else - zlog_err( + flog_err( + ZEBRA_ERR_UNEXPECTED_MESSAGE, "%s error: %s, type=%s(%u), seq=%u, pid=%u", nl->name, safe_strerror(-errnum), @@ -862,27 +871,28 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), * other actors besides the kernel */ if (snl.nl_pid != 0) { - zlog_err("Ignoring message from pid %u", - snl.nl_pid); + zlog_debug("Ignoring message from pid %u", + snl.nl_pid); continue; } error = (*filter)(h, zns->ns_id, startup); if (error < 0) { - zlog_err("%s filter function error", nl->name); - zlog_backtrace(LOG_ERR); + zlog_warn("%s filter function error", nl->name); ret = error; } } /* After error care. */ if (msg.msg_flags & MSG_TRUNC) { - zlog_err("%s error: message truncated", nl->name); + flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR, + "%s error: message truncated", nl->name); continue; } if (status) { - zlog_err("%s error: data remnant size %d", nl->name, - status); + flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR, + "%s error: data remnant size %d", nl->name, + status); return -1; } } @@ -906,11 +916,11 @@ int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup), struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns, int startup) { - int status; + int status = 0; struct sockaddr_nl snl; struct iovec iov; struct msghdr msg; - int save_errno; + int save_errno = 0; memset(&snl, 0, sizeof snl); memset(&iov, 0, sizeof iov); @@ -936,12 +946,10 @@ int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup), n->nlmsg_flags); /* Send message to netlink interface. */ - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - status = sendmsg(nl->sock, &msg, 0); - save_errno = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + status = sendmsg(nl->sock, &msg, 0); + save_errno = errno; + } if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) { zlog_debug("%s: >> netlink message dump [sent]", __func__); @@ -949,8 +957,8 @@ int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup), } if (status < 0) { - zlog_err("netlink_talk sendmsg() error: %s", - safe_strerror(save_errno)); + flog_err_sys(LIB_ERR_SOCKET, "netlink_talk sendmsg() error: %s", + safe_strerror(save_errno)); return -1; } @@ -969,11 +977,11 @@ int netlink_request(struct nlsock *nl, struct nlmsghdr *n) { int ret; struct sockaddr_nl snl; - int save_errno; /* Check netlink socket. */ if (nl->sock < 0) { - zlog_err("%s socket isn't active.", nl->name); + flog_err_sys(LIB_ERR_SOCKET, "%s socket isn't active.", + nl->name); return -1; } @@ -986,21 +994,14 @@ int netlink_request(struct nlsock *nl, struct nlmsghdr *n) snl.nl_family = AF_NETLINK; /* Raise capabilities and send message, then lower capabilities. */ - if (zserv_privs.change(ZPRIVS_RAISE)) { - zlog_err("Can't raise privileges"); - return -1; + frr_elevate_privs(&zserv_privs) { + ret = sendto(nl->sock, (void *)n, n->nlmsg_len, 0, + (struct sockaddr *)&snl, sizeof snl); } - ret = sendto(nl->sock, (void *)n, n->nlmsg_len, 0, - (struct sockaddr *)&snl, sizeof snl); - save_errno = errno; - - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); - if (ret < 0) { zlog_err("%s sendto failed: %s", nl->name, - safe_strerror(save_errno)); + safe_strerror(errno)); return -1; } @@ -1074,8 +1075,8 @@ void kernel_init(struct zebra_ns *zns) /* Register kernel socket. */ if (fcntl(zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0) - zlog_err("Can't set %s socket error: %s(%d)", - zns->netlink.name, safe_strerror(errno), errno); + flog_err_sys(LIB_ERR_SOCKET, "Can't set %s socket flags: %s", + zns->netlink.name, safe_strerror(errno)); if (fcntl(zns->netlink_cmd.sock, F_SETFL, O_NONBLOCK) < 0) zlog_err("Can't set %s socket error: %s(%d)", diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 71d709e72..78e25e762 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -39,6 +39,7 @@ #include "rib.h" #include "privs.h" #include "vrf.h" +#include "lib_errors.h" #include "zebra/rt.h" #include "zebra/interface.h" @@ -46,6 +47,7 @@ #include "zebra/debug.h" #include "zebra/kernel_socket.h" #include "zebra/rib.h" +#include "zebra/zebra_errors.h" extern struct zebra_privs_t zserv_privs; @@ -407,8 +409,9 @@ int ifm_read(struct if_msghdr *ifm) /* paranoia: sanity check structure */ if (ifm->ifm_msglen < sizeof(struct if_msghdr)) { - zlog_err("ifm_read: ifm->ifm_msglen %d too short\n", - ifm->ifm_msglen); + flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR, + "ifm_read: ifm->ifm_msglen %d too short\n", + ifm->ifm_msglen); return -1; } @@ -1382,15 +1385,11 @@ static int kernel_read(struct thread *thread) /* Make routing socket. */ static void routing_socket(struct zebra_ns *zns) { - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("routing_socket: Can't raise privileges"); - - routing_sock = - ns_socket(AF_ROUTE, SOCK_RAW, 0, zns->ns_id); + frr_elevate_privs(&zserv_privs) { + routing_sock = ns_socket(AF_ROUTE, SOCK_RAW, 0, zns->ns_id); + } if (routing_sock < 0) { - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("routing_socket: Can't lower privileges"); zlog_warn("Can't init kernel routing socket"); return; } @@ -1402,9 +1401,6 @@ static void routing_socket(struct zebra_ns *zns) /*if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0) zlog_warn ("Can't set O_NONBLOCK to routing socket");*/ - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("routing_socket: Can't lower privileges"); - /* kernel_read needs rewrite. */ thread_add_read(zebrad.master, kernel_read, NULL, routing_sock, NULL); } diff --git a/zebra/label_manager.c b/zebra/label_manager.c index f2f89fdeb..e53764c77 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -21,12 +21,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include #include -#include "zebra.h" -#include "zserv.h" #include "lib/log.h" #include "lib/memory.h" #include "lib/mpls.h" @@ -35,7 +34,9 @@ #include "lib/zclient.h" #include "lib/libfrr.h" -#include "label_manager.h" +#include "zebra/zserv.h" +#include "zebra/label_manager.h" +#include "zebra/zebra_errors.h" #define CONNECTION_DELAY 5 @@ -82,8 +83,9 @@ static int relay_response_back(void) ret = zclient_read_header(src, zclient->sock, &size, &marker, &version, &vrf_id, &resp_cmd); if (ret < 0 && errno != EAGAIN) { - zlog_err("Error reading Label Manager response: %s", - strerror(errno)); + flog_err(ZEBRA_ERR_LM_RESPONSE, + "Error reading Label Manager response: %s", + strerror(errno)); return -1; } zlog_debug("Label Manager response received, %d bytes", size); @@ -101,7 +103,8 @@ static int relay_response_back(void) /* lookup the client to relay the msg to */ zserv = zserv_find_client(proto, instance); if (!zserv) { - zlog_err( + flog_err( + ZEBRA_ERR_LM_NO_SUCH_CLIENT, "Error relaying LM response: can't find client %s, instance %u", proto_str, instance); return -1; @@ -116,8 +119,9 @@ static int relay_response_back(void) /* send response back */ ret = writen(zserv->sock, dst->data, stream_get_endp(dst)); if (ret <= 0) { - zlog_err("Error relaying LM response to %s instance %u: %s", - proto_str, instance, strerror(errno)); + flog_err(ZEBRA_ERR_LM_RELAY_FAILED, + "Error relaying LM response to %s instance %u: %s", + proto_str, instance, strerror(errno)); return -1; } zlog_debug("Relayed LM response (%d bytes) to %s instance %u", ret, @@ -183,7 +187,8 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, unsigned short instance; if (zclient->sock < 0) { - zlog_err("Unable to relay LM request: no socket"); + flog_err(ZEBRA_ERR_LM_NO_SOCKET, + "Unable to relay LM request: no socket"); reply_error(cmd, zserv, vrf_id); return -1; } @@ -211,8 +216,9 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, /* check & set client instance if unset */ if (zserv->instance && zserv->instance != instance) { - zlog_err("Client instance(%u) != msg instance(%u)", - zserv->instance, instance); + flog_err(ZEBRA_ERR_LM_BAD_INSTANCE, + "Client instance(%u) != msg instance(%u)", + zserv->instance, instance); return -1; } @@ -233,8 +239,9 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, /* Send request to external label manager */ ret = writen(zclient->sock, dst->data, stream_get_endp(dst)); if (ret <= 0) { - zlog_err("Error relaying LM request from %s instance %u: %s", - proto_str, instance, strerror(errno)); + flog_err(ZEBRA_ERR_LM_RELAY_FAILED, + "Error relaying LM request from %s instance %u: %s", + proto_str, instance, strerror(errno)); reply_error(cmd, zserv, vrf_id); return -1; } @@ -262,7 +269,8 @@ static int lm_zclient_connect(struct thread *t) return 0; if (zclient_socket_connect(zclient) < 0) { - zlog_err("Error connecting synchronous zclient!"); + flog_err(ZEBRA_ERR_LM_CLIENT_CONNECTION_FAILED, + "Error connecting synchronous zclient!"); thread_add_timer(zebrad.master, lm_zclient_connect, zclient, CONNECTION_DELAY, &zclient->t_connect); return -1; @@ -393,8 +401,9 @@ struct label_manager_chunk *assign_label_chunk(uint8_t proto, ->end + 1; if (lmc->start > MPLS_LABEL_UNRESERVED_MAX - size + 1) { - zlog_err("Reached max labels. Start: %u, size: %u", lmc->start, - size); + flog_err(ZEBRA_ERR_LM_EXHAUSTED_LABELS, + "Reached max labels. Start: %u, size: %u", lmc->start, + size); XFREE(MTYPE_LM_CHUNK, lmc); return NULL; } @@ -432,7 +441,8 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, if (lmc->end != end) continue; if (lmc->proto != proto || lmc->instance != instance) { - zlog_err("%s: Daemon mismatch!!", __func__); + flog_err(ZEBRA_ERR_LM_DAEMON_MISMATCH, + "%s: Daemon mismatch!!", __func__); continue; } lmc->proto = NO_PROTO; @@ -442,7 +452,8 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, break; } if (ret != 0) - zlog_err("%s: Label chunk not released!!", __func__); + flog_err(ZEBRA_ERR_LM_UNRELEASED_CHUNK, + "%s: Label chunk not released!!", __func__); return ret; } diff --git a/zebra/main.c b/zebra/main.c index 4eeba8549..5e7c69382 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -39,6 +39,7 @@ #include "routemap.h" #include "frr_pthread.h" +#include "zebra/zebra_errors.h" #include "zebra/rib.h" #include "zebra/zserv.h" #include "zebra/debug.h" @@ -288,7 +289,8 @@ int main(int argc, char **argv) multipath_num = atoi(optarg); if (multipath_num > MULTIPATH_NUM || multipath_num <= 0) { - zlog_err( + flog_err( + ZEBRA_ERR_BAD_MULTIPATH_NUM, "Multipath Number specified must be less than %d and greater than 0", MULTIPATH_NUM); return 1; @@ -411,6 +413,9 @@ int main(int argc, char **argv) /* RNH init */ zebra_rnh_init(); + + /* Error init */ + zebra_error_init(); #if defined(HANDLE_ZAPI_FUZZING) if (zapi_fuzzing) { diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index 346699198..c0ad87ce3 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -33,6 +33,7 @@ #include "log.h" #include "privs.h" #include "vxlan.h" +#include "lib_errors.h" #include "zebra/debug.h" #include "zebra/rib.h" @@ -211,7 +212,8 @@ static int kernel_rtm_ipv4(int cmd, const struct prefix *p, */ case ZEBRA_ERR_RTEXIST: if (cmd != RTM_ADD) - zlog_err( + flog_err( + LIB_ERR_SYSTEM_CALL, "%s: rtm_write() returned %d for command %d", __func__, error, cmd); continue; @@ -224,7 +226,8 @@ static int kernel_rtm_ipv4(int cmd, const struct prefix *p, case ZEBRA_ERR_RTNOEXIST: case ZEBRA_ERR_RTUNREACH: default: - zlog_err( + flog_err( + LIB_ERR_SYSTEM_CALL, "%s: %s: rtm_write() unexpectedly returned %d for command %s", __func__, prefix2str(p, prefix_buf, @@ -396,21 +399,19 @@ enum dp_req_result kernel_route_rib(struct route_node *rn, int route = 0; if (src_p && src_p->prefixlen) { - zlog_err("route add: IPv6 sourcedest routes unsupported!"); + zlog_warn("%s: IPv6 sourcedest routes unsupported!", __func__); return DP_REQUEST_FAILURE; } - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); + frr_elevate_privs(&zserv_privs) { - if (old) - route |= kernel_rtm(RTM_DELETE, p, old); + if (old) + route |= kernel_rtm(RTM_DELETE, p, old); - if (new) - route |= kernel_rtm(RTM_ADD, p, new); + if (new) + route |= kernel_rtm(RTM_ADD, p, new); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + } if (new) { kernel_route_rib_pass_fail( diff --git a/zebra/rtadv.c b/zebra/rtadv.c index edc16c549..43dfca10e 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -35,6 +35,7 @@ #include "privs.h" #include "vrf.h" #include "ns.h" +#include "lib_errors.h" #include "zebra/interface.h" #include "zebra/rtadv.h" @@ -180,7 +181,7 @@ static void rtadv_send_packet(int sock, struct interface *ifp) adata = calloc(1, CMSG_SPACE(sizeof(struct in6_pktinfo))); if (adata == NULL) { - zlog_err( + zlog_warn( "rtadv_send_packet: can't malloc control data"); exit(-1); } @@ -373,9 +374,10 @@ static void rtadv_send_packet(int sock, struct interface *ifp) ret = sendmsg(sock, &msg, 0); if (ret < 0) { - zlog_err("%s(%u): Tx RA failed, socket %u error %d (%s)", - ifp->name, ifp->ifindex, sock, errno, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "%s(%u): Tx RA failed, socket %u error %d (%s)", + ifp->name, ifp->ifindex, sock, errno, + safe_strerror(errno)); } else zif->ra_sent++; } @@ -624,19 +626,15 @@ static int rtadv_read(struct thread *thread) static int rtadv_make_socket(ns_id_t ns_id) { - int sock; + int sock = -1; int ret = 0; struct icmp6_filter filter; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("rtadv_make_socket: could not raise privs, %s", - safe_strerror(errno)); + frr_elevate_privs(&zserv_privs) { - sock = ns_socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, ns_id); + sock = ns_socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, ns_id); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("rtadv_make_socket: could not lower privs, %s", - safe_strerror(errno)); + } if (sock < 0) { return -1; diff --git a/zebra/rule_socket.c b/zebra/rule_socket.c index ecd642d80..620410de0 100644 --- a/zebra/rule_socket.c +++ b/zebra/rule_socket.c @@ -29,6 +29,7 @@ #include "if.h" #include "prefix.h" #include "vrf.h" +#include "lib_errors.h" #include "zebra/zserv.h" #include "zebra/zebra_ns.h" @@ -43,13 +44,15 @@ enum dp_req_result kernel_add_pbr_rule(struct zebra_pbr_rule *rule) { - zlog_err("%s not Implemented for this platform", __PRETTY_FUNCTION__); + flog_err(LIB_ERR_UNAVAILABLE, "%s not Implemented for this platform", + __PRETTY_FUNCTION__); return DP_REQUEST_FAILURE; } enum dp_req_result kernel_del_pbr_rule(struct zebra_pbr_rule *rule) { - zlog_err("%s not Implemented for this platform", __PRETTY_FUNCTION__); + flog_err(LIB_ERR_UNAVAILABLE, "%s not Implemented for this platform", + __PRETTY_FUNCTION__); return DP_REQUEST_FAILURE; } diff --git a/zebra/subdir.am b/zebra/subdir.am index 73354ec38..f44574b23 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -71,6 +71,7 @@ zebra_zebra_SOURCES = \ zebra/zebra_netns_notify.c \ zebra/table_manager.c \ zebra/zapi_msg.c \ + zebra/zebra_errors.c \ # end zebra/zebra_vty_clippy.c: $(CLIPPY_DEPS) @@ -115,6 +116,7 @@ noinst_HEADERS += \ zebra/zebra_netns_notify.h \ zebra/table_manager.h \ zebra/zapi_msg.h \ + zebra/zebra_errors.h \ # end zebra_zebra_irdp_la_SOURCES = \ diff --git a/zebra/table_manager.c b/zebra/table_manager.c index 5bcc2c40d..43b5c7d59 100644 --- a/zebra/table_manager.c +++ b/zebra/table_manager.c @@ -35,6 +35,7 @@ #include "zebra/zebra_vrf.h" #include "zebra/label_manager.h" /* for NO_PROTO */ #include "zebra/table_manager.h" +#include "zebra/zebra_errors.h" /* routing table identifiers * @@ -146,8 +147,9 @@ struct table_manager_chunk *assign_table_chunk(uint8_t proto, uint16_t instance, #endif /* SUNOS_5 */ tmc->start = start; if (RT_TABLE_ID_UNRESERVED_MAX - size + 1 < start) { - zlog_err("Reached max table id. Start/Size %u/%u", - start, size); + flog_err(ZEBRA_ERR_TM_EXHAUSTED_IDS, + "Reached max table id. Start/Size %u/%u", start, + size); XFREE(MTYPE_TM_CHUNK, tmc); return NULL; } @@ -184,7 +186,8 @@ int release_table_chunk(uint8_t proto, uint16_t instance, uint32_t start, if (tmc->end != end) continue; if (tmc->proto != proto || tmc->instance != instance) { - zlog_err("%s: Daemon mismatch!!", __func__); + flog_err(ZEBRA_ERR_TM_DAEMON_MISMATCH, + "%s: Daemon mismatch!!", __func__); continue; } tmc->proto = NO_PROTO; @@ -193,7 +196,8 @@ int release_table_chunk(uint8_t proto, uint16_t instance, uint32_t start, break; } if (ret != 0) - zlog_err("%s: Table chunk not released!!", __func__); + flog_err(ZEBRA_ERR_TM_UNRELEASED_CHUNK, + "%s: Table chunk not released!!", __func__); return ret; } diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 22c0dd623..008fc8f06 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1058,7 +1058,8 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS) STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN); l += IPV6_MAX_BYTELEN; } else { - zlog_err( + flog_err( + ZEBRA_ERR_UNKNOWN_FAMILY, "rnh_register: Received unknown family type %d\n", p.family); return; @@ -1136,7 +1137,8 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS) STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN); l += IPV6_MAX_BYTELEN; } else { - zlog_err( + flog_err( + ZEBRA_ERR_UNKNOWN_FAMILY, "rnh_register: Received unknown family type %d\n", p.family); return; @@ -1172,7 +1174,8 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS) * registration */ if (hdr->length < ZEBRA_MIN_FEC_LENGTH) { - zlog_err( + flog_err( + ZEBRA_ERR_IRDP_LEN_MISMATCH, "fec_register: Received a fec register of hdr->length %d, it is of insufficient size to properly decode", hdr->length); return; @@ -1183,7 +1186,8 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS) memset(&p, 0, sizeof(p)); STREAM_GETW(s, p.family); if (p.family != AF_INET && p.family != AF_INET6) { - zlog_err( + flog_err( + ZEBRA_ERR_UNKNOWN_FAMILY, "fec_register: Received unknown family type %d\n", p.family); return; @@ -1230,7 +1234,8 @@ static void zread_fec_unregister(ZAPI_HANDLER_ARGS) * fec unregistration */ if (hdr->length < ZEBRA_MIN_FEC_LENGTH) { - zlog_err( + flog_err( + ZEBRA_ERR_IRDP_LEN_MISMATCH, "fec_unregister: Received a fec unregister of hdr->length %d, it is of insufficient size to properly decode", hdr->length); return; @@ -1244,7 +1249,8 @@ static void zread_fec_unregister(ZAPI_HANDLER_ARGS) memset(&p, 0, sizeof(p)); STREAM_GETW(s, p.family); if (p.family != AF_INET && p.family != AF_INET6) { - zlog_err( + flog_err( + ZEBRA_ERR_UNKNOWN_FAMILY, "fec_unregister: Received unknown family type %d\n", p.family); return; @@ -2376,8 +2382,9 @@ static void zread_table_manager_connect(struct zserv *client, /* accept only dynamic routing protocols */ if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) { - zlog_err("client %d has wrong protocol %s", client->sock, - zebra_route_string(proto)); + flog_err(ZEBRA_ERR_TM_WRONG_PROTO, + "client %d has wrong protocol %s", client->sock, + zebra_route_string(proto)); zsend_table_manager_connect_response(client, vrf_id, 1); return; } @@ -2415,8 +2422,9 @@ static void zread_label_manager_connect(struct zserv *client, /* accept only dynamic routing protocols */ if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) { - zlog_err("client %d has wrong protocol %s", client->sock, - zebra_route_string(proto)); + flog_err(ZEBRA_ERR_TM_WRONG_PROTO, + "client %d has wrong protocol %s", client->sock, + zebra_route_string(proto)); zsend_label_manager_connect_response(client, vrf_id, 1); return; } @@ -2444,14 +2452,16 @@ static int msg_client_id_mismatch(const char *op, struct zserv *client, uint8_t proto, unsigned int instance) { if (proto != client->proto) { - zlog_err("%s: msg vs client proto mismatch, client=%u msg=%u", - op, client->proto, proto); + flog_err(ZEBRA_ERR_PROTO_OR_INSTANCE_MISMATCH, + "%s: msg vs client proto mismatch, client=%u msg=%u", + op, client->proto, proto); /* TODO: fail when BGP sets proto and instance */ /* return 1; */ } if (instance != client->instance) { - zlog_err( + flog_err( + ZEBRA_ERR_PROTO_OR_INSTANCE_MISMATCH, "%s: msg vs client instance mismatch, client=%u msg=%u", op, client->instance, instance); /* TODO: fail when BGP sets proto and instance */ @@ -2486,7 +2496,8 @@ static void zread_get_label_chunk(struct zserv *client, struct stream *msg, lmc = assign_label_chunk(client->proto, client->instance, keep, size); if (!lmc) - zlog_err( + flog_err( + ZEBRA_ERR_LM_CANNOT_ASSIGN_CHUNK, "Unable to assign Label Chunk of size %u to %s instance %u", size, zebra_route_string(client->proto), client->instance); @@ -2544,7 +2555,8 @@ static void zread_label_manager_request(ZAPI_HANDLER_ARGS) else { /* Sanity: don't allow 'unidentified' requests */ if (!client->proto) { - zlog_err( + flog_err( + ZEBRA_ERR_LM_ALIENS, "Got label request from an unidentified client"); return; } @@ -2572,8 +2584,9 @@ static void zread_get_table_chunk(struct zserv *client, struct stream *msg, tmc = assign_table_chunk(client->proto, client->instance, size); if (!tmc) - zlog_err("%s: Unable to assign Table Chunk of size %u", - __func__, size); + flog_err(ZEBRA_ERR_TM_CANNOT_ASSIGN_CHUNK, + "%s: Unable to assign Table Chunk of size %u", + __func__, size); else zlog_debug("Assigned Table Chunk %u - %u", tmc->start, tmc->end); @@ -2610,7 +2623,8 @@ static void zread_table_manager_request(ZAPI_HANDLER_ARGS) else { /* Sanity: don't allow 'unidentified' requests */ if (!client->proto) { - zlog_err( + flog_err( + ZEBRA_ERR_TM_ALIENS, "Got table request from an unidentified client"); return; } @@ -3073,12 +3087,13 @@ static void zserv_write_incoming(struct stream *orig, uint16_t command) copy = stream_dup(orig); stream_set_getp(copy, 0); - zserv_privs.change(ZPRIVS_RAISE); snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command); - fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644); + + frr_elevate_privs(&zserv_privs) { + fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644); + } stream_flush(copy, fd); close(fd); - zserv_privs.change(ZPRIVS_LOWER); stream_free(copy); } #endif diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 8289e33c6..29fe59bab 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -28,6 +28,7 @@ #include "zebra/rib.h" #include "zebra/zserv.h" #include "zebra/zebra_pbr.h" +#include "zebra/zebra_errors.h" /* * This is called to process inbound ZAPI messages. diff --git a/zebra/zebra_errors.c b/zebra/zebra_errors.c new file mode 100644 index 000000000..198e1cce2 --- /dev/null +++ b/zebra/zebra_errors.c @@ -0,0 +1,278 @@ +/* + * Zebra-specific error messages. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Quentin Young + * + * 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 + +#include "lib/ferr.h" +#include "zebra_errors.h" + +/* clang-format off */ +static struct log_ref ferr_zebra_err[] = { + { + .code = ZEBRA_ERR_LM_RESPONSE, + .title = "Error reading response from label manager", + .description = "Zebra could not read the ZAPI header from the label manager", + .suggestion = "Wait for the error to resolve on its own. If it does not resolve, restart Zebra.", + }, + { + .code = ZEBRA_ERR_LM_NO_SUCH_CLIENT, + .title = "Label manager could not find ZAPI client", + .description = "Zebra was unable to find a ZAPI client matching the given protocol and instance number.", + .suggestion = "Ensure clients which use the label manager are properly configured and running.", + }, + { + .code = ZEBRA_ERR_LM_RELAY_FAILED, + .title = "Zebra could not relay label manager response", + .description = "Zebra found the client and instance to relay the label manager response or request to, but was not able to do so, possibly because the connection was closed.", + .suggestion = "Ensure clients which use the label manager are properly configured and running.", + }, + { + .code = ZEBRA_ERR_LM_BAD_INSTANCE, + .title = "Mismatch between ZAPI instance and encoded message instance", + .description = "While relaying a request to the external label manager, Zebra noticed that the instance number encoded in the message did not match the client instance number.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_LM_EXHAUSTED_LABELS, + .title = "Zebra label manager used all available labels", + .description = "Zebra is unable to assign additional label chunks because it has exhausted its assigned label range.", + .suggestion = "Make the label range bigger and restart Zebra.", + }, + { + .code = ZEBRA_ERR_LM_DAEMON_MISMATCH, + .title = "Daemon mismatch when releasing label chunks", + .description = "Zebra noticed a mismatch between a label chunk and a protocol daemon number or instance when releasing unused label chunks.", + .suggestion = "Ignore this error.", + }, + { + .code = ZEBRA_ERR_LM_UNRELEASED_CHUNK, + .title = "Zebra did not free any label chunks", + .description = "Zebra's chunk cleanup procedure ran, but no label chunks were released.", + .suggestion = "Ignore this error.", + }, + { + .code = ZEBRA_ERR_DP_INVALID_RC, + .title = "Dataplane returned invalid status code", + .description = "The underlying dataplane responded to a Zebra message or other interaction with an unrecognized, unknown or invalid status code.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_WQ_NONEXISTENT, + .title = "A necessary work queue does not exist.", + .description = "A necessary work queue does not exist.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_FEC_ADD_FAILED, + .title = "Failed to add FEC for MPLS client", + .description = "A client requested a label binding for a new FEC, but Zebra was unable to add the FEC to its internal table.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_FEC_RM_FAILED, + .title = "Failed to remove FEC for MPLS client", + .description = "Zebra was unable to find and remove a FEC in its internal table.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_IRDP_LEN_MISMATCH, + .title = "IRDP message length mismatch", + .description = "The length encoded in the IP TLV does not match the length of the packet received.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_RNH_UNKNOWN_FAMILY, + .title = "Attempted to perform nexthop update for unknown address family", + .description = "Zebra attempted to perform a nexthop update for unknown address family", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_DP_INSTALL_FAIL, + .title = "Dataplane installation failure", + .description = "Installation of routes to underlying dataplane failed.", + .suggestion = "Check all configuration parameters for correctness.", + }, + { + .code = ZEBRA_ERR_TABLE_LOOKUP_FAILED, + .title = "Zebra table lookup failed", + .description = "Zebra attempted to look up a table for a particular address family and subsequent address family, but didn't find anything.", + .suggestion = "If you entered a command to trigger this error, make sure you entered the arguments correctly. Check your config file for any potential errors. If these look correct, seek help.", + }, + { + .code = ZEBRA_ERR_NETLINK_NOT_AVAILABLE, + .title = "Netlink backend not available", + .description = "FRR was not compiled with support for Netlink. Any operations that require Netlink will fail.", + .suggestion = "Recompile FRR with Netlink, or install a package that supports this feature.", + }, + { + .code = ZEBRA_ERR_PROTOBUF_NOT_AVAILABLE, + .title = "Protocol Buffers backend not available", + .description = "FRR was not compiled with support for Protocol Buffers. Any operations that require Protobuf will fail.", + .suggestion = "Recompile FRR with Protobuf support, or install a package that supports this feature.", + }, + { + .code = ZEBRA_ERR_TM_EXHAUSTED_IDS, + .title = "Table manager used all available IDs", + .description = "Zebra's table manager used up all IDs available to it and can't assign any more.", + .suggestion = "Reconfigure Zebra with a larger range of table IDs.", + }, + { + .code = ZEBRA_ERR_TM_DAEMON_MISMATCH, + .title = "Daemon mismatch when releasing table chunks", + .description = "Zebra noticed a mismatch between a table ID chunk and a protocol daemon number instance when releasing unused table chunks.", + .suggestion = "Ignore this error.", + }, + { + .code = ZEBRA_ERR_TM_UNRELEASED_CHUNK, + .title = "Zebra did not free any table chunks", + .description = "Zebra's table chunk cleanup procedure ran, but no table chunks were released.", + .suggestion = "Ignore this error.", + }, + { + .code = ZEBRA_ERR_UNKNOWN_FAMILY, + .title = "Address family specifier unrecognized", + .description = "Zebra attempted to process information from somewhere that included an address family specifier, but did not recognize the provided specifier.", + .suggestion = "Ensure that your configuration is correct. If it is, notify a developer.", + }, + { + .code = ZEBRA_ERR_TM_WRONG_PROTO, + .title = "Incorrect protocol for table manager client", + .description = "Zebra's table manager only accepts connections from daemons managing dynamic routing protocols, but received a connection attempt from a daemon that does not meet this criterion.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_PROTO_OR_INSTANCE_MISMATCH, + .title = "Mismatch between message and client protocol and/or instance", + .description = "Zebra detected a mismatch between a client's protocol and/or instance numbers versus those stored in a message transiting its socket.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_LM_CANNOT_ASSIGN_CHUNK, + .title = "Label manager unable to assign label chunk", + .description = "Zebra's label manager was unable to assign a label chunk to client.", + .suggestion = "Ensure that Zebra has a sufficient label range available and that there is not a range collision.", + }, + { + .code = ZEBRA_ERR_LM_ALIENS, + .title = "Label request from unidentified client", + .description = "Zebra's label manager received a label request from an unidentified client.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_TM_CANNOT_ASSIGN_CHUNK, + .title = "Table manager unable to assign table chunk", + .description = "Zebra's table manager was unable to assign a table chunk to a client.", + .suggestion = "Ensure that Zebra has sufficient table ID range available and that there is not a range collision.", + }, + { + .code = ZEBRA_ERR_TM_ALIENS, + .title = "Table request from unidentified client", + .description = "Zebra's table manager received a table request from an unidentified client.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_RECVBUF, + .title = "Cannot set receive buffer size", + .description = "Socket receive buffer size could not be set in the kernel", + .suggestion = "Ignore this error.", + }, + { + .code = ZEBRA_ERR_UNKNOWN_NLMSG, + .title = "Unknown Netlink message type", + .description = "Zebra received a Netlink message with an unrecognized type field.", + .suggestion = "Verify that you are running the latest version of FRR to ensure kernel compatibility. If the problem persists, notify a developer.", + }, + { + .code = ZEBRA_ERR_RECVMSG_OVERRUN, + .title = "Receive buffer overrun", + .description = "The kernel's buffer for a socket has been overrun, rendering the socket invalid.", + .suggestion = "Zebra will restart itself. Notify a developer if this issue shows up frequently.", + }, + { + .code = ZEBRA_ERR_NETLINK_LENGTH_ERROR, + .title = "Netlink message length mismatch", + .description = "Zebra received a Netlink message with incorrect length fields.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_NETLINK_LENGTH_ERROR, + .title = "Netlink message length mismatch", + .description = "Zebra received a Netlink message with incorrect length fields.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_UNEXPECTED_MESSAGE, + .title = "Received unexpected response from kernel", + .description = "Received unexpected response from the kernel via Netlink.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_NETLINK_BAD_SEQUENCE, + .title = "Bad sequence number in Netlink message", + .description = "Zebra received a Netlink message with a bad sequence number.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_BAD_MULTIPATH_NUM, + .title = "Multipath number was out of valid range", + .description = "Multipath number specified to Zebra must be in the appropriate range", + .suggestion = "Provide a multipath number that is within its accepted range", + }, + { + .code = ZEBRA_ERR_PREFIX_PARSE_ERROR, + .title = "String could not be parsed as IP prefix", + .description = "There was an attempt to parse a string as an IPv4 or IPv6 prefix, but the string could not be parsed and this operation failed.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_MAC_ADD_FAILED, + .title = "Failed to add MAC address to interface", + .description = "Zebra attempted to assign a MAC address to a vxlan interface but failed", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_VNI_DEL_FAILED, + .title = "Failed to delete VNI", + .description = "Zebra attempted to delete a VNI entry and failed", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_VTEP_ADD_FAILED, + .title = "Adding remote VTEP failed", + .description = "Zebra attempted to add a remote VTEP and failed.", + .suggestion = "Notify a developer.", + }, + { + .code = ZEBRA_ERR_VNI_ADD_FAILED, + .title = "Adding VNI failed", + .description = "Zebra attempted to add a VNI hash to an interface and failed", + .suggestion = "Notify a developer.", + }, + { + .code = END_FERR, + } +}; +/* clang-format on */ + + +void zebra_error_init(void) +{ + log_ref_add(ferr_zebra_err); +} diff --git a/zebra/zebra_errors.h b/zebra/zebra_errors.h new file mode 100644 index 000000000..f8a00bce0 --- /dev/null +++ b/zebra/zebra_errors.h @@ -0,0 +1,73 @@ +/* + * Zebra-specific error messages. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Quentin Young + * + * 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 __ZEBRA_ERRORS_H__ +#define __ZEBRA_ERRORS_H__ + +#include "lib/ferr.h" + +enum zebra_log_refs { + ZEBRA_ERR_LM_RESPONSE = ZEBRA_FERR_START, + ZEBRA_ERR_LM_NO_SUCH_CLIENT, + ZEBRA_ERR_LM_RELAY_FAILED, + ZEBRA_ERR_LM_NO_SOCKET, + ZEBRA_ERR_LM_BAD_INSTANCE, + ZEBRA_ERR_LM_RELAY_REQUEST_FAILED, + ZEBRA_ERR_LM_CLIENT_CONNECTION_FAILED, + ZEBRA_ERR_LM_EXHAUSTED_LABELS, + ZEBRA_ERR_LM_DAEMON_MISMATCH, + ZEBRA_ERR_LM_UNRELEASED_CHUNK, + ZEBRA_ERR_DP_INVALID_RC, + ZEBRA_ERR_WQ_NONEXISTENT, + ZEBRA_ERR_FEC_ADD_FAILED, + ZEBRA_ERR_FEC_RM_FAILED, + ZEBRA_ERR_IRDP_LEN_MISMATCH, + ZEBRA_ERR_RNH_UNKNOWN_FAMILY, + ZEBRA_ERR_DP_INSTALL_FAIL, + ZEBRA_ERR_TABLE_LOOKUP_FAILED, + ZEBRA_ERR_NETLINK_NOT_AVAILABLE, + ZEBRA_ERR_PROTOBUF_NOT_AVAILABLE, + ZEBRA_ERR_TM_EXHAUSTED_IDS, + ZEBRA_ERR_TM_DAEMON_MISMATCH, + ZEBRA_ERR_TM_UNRELEASED_CHUNK, + ZEBRA_ERR_UNKNOWN_FAMILY, + ZEBRA_ERR_TM_WRONG_PROTO, + ZEBRA_ERR_PROTO_OR_INSTANCE_MISMATCH, + ZEBRA_ERR_LM_CANNOT_ASSIGN_CHUNK, + ZEBRA_ERR_LM_ALIENS, + ZEBRA_ERR_TM_CANNOT_ASSIGN_CHUNK, + ZEBRA_ERR_TM_ALIENS, + ZEBRA_ERR_RECVBUF, + ZEBRA_ERR_UNKNOWN_NLMSG, + ZEBRA_ERR_RECVMSG_OVERRUN, + ZEBRA_ERR_NETLINK_LENGTH_ERROR, + ZEBRA_ERR_UNEXPECTED_MESSAGE, + ZEBRA_ERR_NETLINK_BAD_SEQUENCE, + ZEBRA_ERR_BAD_MULTIPATH_NUM, + ZEBRA_ERR_PREFIX_PARSE_ERROR, + ZEBRA_ERR_MAC_ADD_FAILED, + ZEBRA_ERR_VNI_DEL_FAILED, + ZEBRA_ERR_VTEP_ADD_FAILED, + ZEBRA_ERR_VNI_ADD_FAILED, +}; + +void zebra_error_init(void); + +#endif /* __ZEBRA_ERRORS_H__ */ diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 9d3133f55..1cb14abbf 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -35,6 +35,7 @@ #include "zebra/zserv.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" +#include "zebra/zebra_errors.h" #include "fpm/fpm.h" #include "zebra_fpm_private.h" @@ -1517,7 +1518,9 @@ static inline void zfpm_init_message_format(const char *format) if (!strcmp("netlink", format)) { if (!have_netlink) { - zlog_err("FPM netlink message format is not available"); + flog_err( + ZEBRA_ERR_NETLINK_NOT_AVAILABLE, + "FPM netlink message format is not available"); return; } zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK; @@ -1526,7 +1529,8 @@ static inline void zfpm_init_message_format(const char *format) if (!strcmp("protobuf", format)) { if (!have_protobuf) { - zlog_err( + flog_err( + ZEBRA_ERR_PROTOBUF_NOT_AVAILABLE, "FPM protobuf message format is not available"); return; } diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 424a11546..f7283aed3 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -45,6 +45,7 @@ #include "zebra/zebra_memory.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_mpls.h" +#include "zebra/zebra_errors.h" DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object") DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object") @@ -917,7 +918,9 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); switch (kernel_add_lsp(lsp)) { case DP_REQUEST_QUEUED: - zlog_err("No current DataPlane interfaces can return this, please fix"); + flog_err( + ZEBRA_ERR_DP_INVALID_RC, + "No current DataPlane interfaces can return this, please fix"); break; case DP_REQUEST_FAILURE: break; @@ -932,7 +935,9 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) switch (kernel_del_lsp(lsp)) { case DP_REQUEST_QUEUED: - zlog_err("No current DataPlane interfaces can return this, please fix"); + flog_err( + ZEBRA_ERR_DP_INVALID_RC, + "No current DataPlane interfaces can return this, please fix"); break; case DP_REQUEST_FAILURE: break; @@ -970,7 +975,9 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) switch (kernel_upd_lsp(lsp)) { case DP_REQUEST_QUEUED: - zlog_err("No current DataPlane interfaces can return this, please fix"); + flog_err( + ZEBRA_ERR_DP_INVALID_RC, + "No current DataPlane interfaces can return this, please fix"); break; case DP_REQUEST_FAILURE: break; @@ -1048,7 +1055,8 @@ static int lsp_processq_add(zebra_lsp_t *lsp) return 0; if (zebrad.lsp_process_q == NULL) { - zlog_err("%s: work_queue does not exist!", __func__); + flog_err(ZEBRA_ERR_WQ_NONEXISTENT, + "%s: work_queue does not exist!", __func__); return -1; } @@ -1690,7 +1698,8 @@ static int mpls_processq_init(struct zebra_t *zebra) { zebra->lsp_process_q = work_queue_new(zebra->master, "LSP processing"); if (!zebra->lsp_process_q) { - zlog_err("%s: could not initialise work queue!", __func__); + flog_err(ZEBRA_ERR_WQ_NONEXISTENT, + "%s: could not initialise work queue!", __func__); return -1; } @@ -1825,7 +1834,8 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, fec = fec_add(table, p, MPLS_INVALID_LABEL, 0, label_index); if (!fec) { prefix2str(p, buf, BUFSIZ); - zlog_err( + flog_err( + ZEBRA_ERR_FEC_ADD_FAILED, "Failed to add FEC %s upon register, client %s", buf, zebra_route_string(client->proto)); return -1; @@ -1905,8 +1915,9 @@ int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p, fec = fec_find(table, p); if (!fec) { prefix2str(p, buf, BUFSIZ); - zlog_err("Failed to find FEC %s upon unregister, client %s", - buf, zebra_route_string(client->proto)); + flog_err(ZEBRA_ERR_FEC_RM_FAILED, + "Failed to find FEC %s upon unregister, client %s", + buf, zebra_route_string(client->proto)); return -1; } @@ -2036,7 +2047,8 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p, MPLS_INVALID_LABEL_INDEX); if (!fec) { prefix2str(p, buf, BUFSIZ); - zlog_err("Failed to add FEC %s upon config", buf); + flog_err(ZEBRA_ERR_FEC_ADD_FAILED, + "Failed to add FEC %s upon config", buf); return -1; } @@ -2083,7 +2095,8 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p) fec = fec_find(table, p); if (!fec) { prefix2str(p, buf, BUFSIZ); - zlog_err("Failed to find FEC %s upon delete", buf); + flog_err(ZEBRA_ERR_FEC_RM_FAILED, + "Failed to find FEC %s upon delete", buf); return -1; } @@ -2433,7 +2446,7 @@ void mpls_ldp_lsp_uninstall_all(struct hash_backet *backet, void *ctxt) struct hash *lsp_table; lsp = (zebra_lsp_t *)backet->data; - if (!lsp || !lsp->nhlfe_list) + if (!lsp->nhlfe_list) return; lsp_table = ctxt; diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c index 412fe7d3d..542de27e8 100644 --- a/zebra/zebra_mpls_openbsd.c +++ b/zebra/zebra_mpls_openbsd.c @@ -31,6 +31,7 @@ #include "prefix.h" #include "interface.h" #include "log.h" +#include "lib_errors.h" extern struct zebra_privs_t zserv_privs; @@ -116,14 +117,13 @@ static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label, hdr.rtm_mpls = MPLS_OP_SWAP; } - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - ret = writev(kr_state.fd, iov, iovcnt); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + ret = writev(kr_state.fd, iov, iovcnt); + } if (ret == -1) - zlog_err("%s: %s", __func__, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "%s: %s", __func__, + safe_strerror(errno)); return ret; } @@ -224,14 +224,13 @@ static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label, hdr.rtm_mpls = MPLS_OP_SWAP; } - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - ret = writev(kr_state.fd, iov, iovcnt); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + ret = writev(kr_state.fd, iov, iovcnt); + } if (ret == -1) - zlog_err("%s: %s", __func__, safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "%s: %s", __func__, + safe_strerror(errno)); return ret; } @@ -360,8 +359,8 @@ static int kmpw_install(struct zebra_pw *pw) imr.imr_type = IMR_TYPE_ETHERNET_TAGGED; break; default: - zlog_err("%s: unhandled pseudowire type (%#X)", __func__, - pw->type); + zlog_warn("%s: unhandled pseudowire type (%#X)", __func__, + pw->type); return -1; } @@ -382,8 +381,8 @@ static int kmpw_install(struct zebra_pw *pw) sa_in6->sin6_addr = pw->nexthop.ipv6; break; default: - zlog_err("%s: unhandled pseudowire address-family (%u)", - __func__, pw->af); + zlog_warn("%s: unhandled pseudowire address-family (%u)", + __func__, pw->af); return -1; } memcpy(&imr.imr_nexthop, (struct sockaddr *)&ss, @@ -398,7 +397,8 @@ static int kmpw_install(struct zebra_pw *pw) strlcpy(ifr.ifr_name, pw->ifname, sizeof(ifr.ifr_name)); ifr.ifr_data = (caddr_t)&imr; if (ioctl(kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) { - zlog_err("ioctl SIOCSETMPWCFG: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "ioctl SIOCSETMPWCFG: %s", + safe_strerror(errno)); return -1; } @@ -415,7 +415,8 @@ static int kmpw_uninstall(struct zebra_pw *pw) strlcpy(ifr.ifr_name, pw->ifname, sizeof(ifr.ifr_name)); ifr.ifr_data = (caddr_t)&imr; if (ioctl(kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) { - zlog_err("ioctl SIOCSETMPWCFG: %s", safe_strerror(errno)); + flog_err_sys(LIB_ERR_SYSTEM_CALL, "ioctl SIOCSETMPWCFG: %s", + safe_strerror(errno)); return -1; } diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c index 96e6df34d..a3278c478 100644 --- a/zebra/zebra_netns_id.c +++ b/zebra/zebra_netns_id.c @@ -22,6 +22,7 @@ #include "ns.h" #include "vrf.h" #include "log.h" +#include "lib_errors.h" #if defined(HAVE_NETLINK) @@ -34,7 +35,8 @@ #include "kernel_netlink.h" #endif /* defined(HAVE_NETLINK) */ -#include "zebra_netns_id.h" +#include "zebra/zebra_netns_id.h" +#include "zebra/zebra_errors.h" /* default NS ID value used when VRF backend is not NETNS */ #define NS_DEFAULT_INTERNAL 0 @@ -86,8 +88,8 @@ static int send_receive(int sock, struct nlmsghdr *nlh, unsigned int seq, ret = sendto(sock, (const void *)nlh, (size_t)nlh->nlmsg_len, 0, (struct sockaddr *)&snl, (socklen_t)sizeof(snl)); if (ret < 0) { - zlog_err("netlink( %u) sendmsg() error: %s", sock, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "netlink( %u) sendmsg() error: %s", + sock, safe_strerror(errno)); return -1; } @@ -107,16 +109,20 @@ static int send_receive(int sock, struct nlmsghdr *nlh, unsigned int seq, }; ret = recvmsg(sock, &msg, 0); if (ret < 0) { - zlog_err("netlink recvmsg: error %d (errno %u)", ret, errno); + flog_err_sys(LIB_ERR_SOCKET, + "netlink recvmsg: error %d (errno %u)", ret, + errno); return -1; } if (msg.msg_flags & MSG_TRUNC) { - zlog_err("netlink recvmsg : error message truncated"); + flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR, + "netlink recvmsg : error message truncated"); return -1; } /* nlh already points to buf */ if (nlh->nlmsg_seq != seq) { - zlog_err( + flog_err( + ZEBRA_ERR_NETLINK_BAD_SEQUENCE, "netlink recvmsg: bad sequence number %x (expected %x)", seq, nlh->nlmsg_seq); return -1; @@ -170,8 +176,8 @@ ns_id_t zebra_ns_id_get(const char *netnspath) /* netlink socket */ sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sock < 0) { - zlog_err("netlink( %u) socket() error: %s", sock, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, "netlink( %u) socket() error: %s", + sock, safe_strerror(errno)); close(fd); return NS_UNKNOWN; } @@ -181,8 +187,9 @@ ns_id_t zebra_ns_id_get(const char *netnspath) snl.nl_pid = 0; /* AUTO PID */ ret = bind(sock, (struct sockaddr *)&snl, sizeof(snl)); if (ret < 0) { - zlog_err("netlink( %u) socket() bind error: %s", sock, - safe_strerror(errno)); + flog_err_sys(LIB_ERR_SOCKET, + "netlink( %u) socket() bind error: %s", sock, + safe_strerror(errno)); close(sock); close(fd); return NS_UNKNOWN; @@ -255,7 +262,8 @@ ns_id_t zebra_ns_id_get(const char *netnspath) if (ret <= 0) { if (errno != EEXIST && ret != 0) { - zlog_err( + flog_err( + LIB_ERR_SOCKET, "netlink( %u) recvfrom() error 2 when reading: %s", fd, safe_strerror(errno)); close(sock); diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index 2dd686fd0..2b7bf04ec 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -34,6 +34,7 @@ #include "ns.h" #include "command.h" #include "memory.h" +#include "lib_errors.h" #include "zserv.h" #include "zebra_memory.h" @@ -75,11 +76,9 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name) if (netnspath == NULL) return; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - ns_id = zebra_ns_id_get(netnspath); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + ns_id = zebra_ns_id_get(netnspath); + } if (ns_id == NS_UNKNOWN) return; ns_id_external = ns_map_nsid_with_external(ns_id, true); @@ -96,12 +95,10 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name) ns_map_nsid_with_external(ns_id, false); return; } - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - ret = vrf_netns_handler_create(NULL, vrf, netnspath, - ns_id_external, ns_id); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + ret = vrf_netns_handler_create(NULL, vrf, netnspath, + ns_id_external, ns_id); + } if (ret != CMD_SUCCESS) { zlog_warn("NS notify : failed to create NS %s", netnspath); ns_map_nsid_with_external(ns_id, false); @@ -168,20 +165,16 @@ static int zebra_ns_ready_read(struct thread *t) netnspath = zns_info->netnspath; if (--zns_info->retries == 0) stop_retry = 1; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - err = ns_switch_to_netns(netnspath); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + err = ns_switch_to_netns(netnspath); + } if (err < 0) return zebra_ns_continue_read(zns_info, stop_retry); /* go back to default ns */ - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - err = ns_switchback_to_initial(); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + err = ns_switchback_to_initial(); + } if (err < 0) return zebra_ns_continue_read(zns_info, stop_retry); diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 25e68cc08..456253cc3 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -26,6 +26,7 @@ #include "lib/logicalrouter.h" #include "lib/prefix.h" #include "lib/memory.h" +#include "lib/lib_errors.h" #include "rtadv.h" #include "zebra_ns.h" @@ -314,11 +315,9 @@ int zebra_ns_init(void) dzns = zebra_ns_alloc(); - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); - ns_id = zebra_ns_id_get_default(); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); + frr_elevate_privs(&zserv_privs) { + ns_id = zebra_ns_id_get_default(); + } ns_id_external = ns_map_nsid_with_external(ns_id, true); ns_init_management(ns_id_external, ns_id); diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index cc2d5d411..b71234be0 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -19,25 +19,29 @@ */ #include + #include /* for sockaddr_un */ #include + +#include "bfd.h" +#include "buffer.h" +#include "command.h" +#include "if.h" +#include "network.h" +#include "ptm_lib.h" +#include "rib.h" +#include "stream.h" +#include "version.h" +#include "vrf.h" #include "vty.h" -#include "zebra/zserv.h" -#include "zebra/interface.h" + #include "zebra/debug.h" +#include "zebra/interface.h" +#include "zebra/zebra_errors.h" #include "zebra/zebra_ptm.h" -#include "if.h" -#include "command.h" -#include "stream.h" -#include "ptm_lib.h" -#include "network.h" -#include "buffer.h" #include "zebra/zebra_ptm_redistribute.h" -#include "bfd.h" -#include "vrf.h" -#include "rib.h" +#include "zebra/zserv.h" #include "zebra_vrf.h" -#include "version.h" /* * Choose the BFD implementation that we'll use. @@ -500,15 +504,17 @@ static int zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, dest_str, src_str); if (str2prefix(dest_str, &dest_prefix) == 0) { - zlog_err("%s: Peer addr %s not found", __func__, dest_str); + flog_err(ZEBRA_ERR_PREFIX_PARSE_ERROR, + "%s: Peer addr %s not found", __func__, dest_str); return -1; } memset(&src_prefix, 0, sizeof(struct prefix)); if (strcmp(ZEBRA_PTM_INVALID_SRC_IP, src_str)) { if (str2prefix(src_str, &src_prefix) == 0) { - zlog_err("%s: Local addr %s not found", __func__, - src_str); + flog_err(ZEBRA_ERR_PREFIX_PARSE_ERROR, + "%s: Local addr %s not found", __func__, + src_str); return -1; } } @@ -602,8 +608,8 @@ static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt) ifp = if_lookup_by_name_all_vrf(port_str); if (!ifp) { - zlog_err("%s: %s not found in interface list", __func__, - port_str); + zlog_warn("%s: %s not found in interface list", + __func__, port_str); return -1; } } @@ -1026,8 +1032,8 @@ int zebra_ptm_bfd_client_deregister(struct zserv *client) return 0; if (IS_ZEBRA_DEBUG_EVENT) - zlog_err("bfd_client_deregister msg for client %s", - zebra_route_string(proto)); + zlog_warn("bfd_client_deregister msg for client %s", + zebra_route_string(proto)); if (ptm_cb.ptm_sock == -1) { ptm_cb.t_timer = NULL; diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 69f6ff9de..b477cd470 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -20,37 +20,38 @@ #include -#include "if.h" -#include "prefix.h" -#include "table.h" -#include "memory.h" -#include "zebra_memory.h" #include "command.h" +#include "if.h" +#include "linklist.h" #include "log.h" #include "log_int.h" -#include "sockunion.h" -#include "linklist.h" -#include "thread.h" -#include "workqueue.h" +#include "memory.h" +#include "mpls.h" +#include "nexthop.h" +#include "prefix.h" #include "prefix.h" #include "routemap.h" -#include "nexthop.h" -#include "vrf.h" -#include "mpls.h" +#include "sockunion.h" #include "srcdest_table.h" +#include "table.h" +#include "thread.h" +#include "vrf.h" +#include "workqueue.h" +#include "zebra/connected.h" +#include "zebra/debug.h" +#include "zebra/interface.h" +#include "zebra/redistribute.h" #include "zebra/rib.h" #include "zebra/rt.h" +#include "zebra/zapi_msg.h" +#include "zebra/zebra_errors.h" +#include "zebra/zebra_memory.h" #include "zebra/zebra_ns.h" -#include "zebra/zebra_vrf.h" -#include "zebra/redistribute.h" -#include "zebra/zebra_routemap.h" -#include "zebra/debug.h" #include "zebra/zebra_rnh.h" -#include "zebra/interface.h" -#include "zebra/connected.h" +#include "zebra/zebra_routemap.h" +#include "zebra/zebra_vrf.h" #include "zebra/zebra_vxlan.h" -#include "zebra/zapi_msg.h" DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason), (rn, reason)) @@ -1125,10 +1126,14 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re, hook_call(rib_update, rn, "installing in kernel"); switch (kernel_route_rib(rn, p, src_p, old, re)) { case DP_REQUEST_QUEUED: - zlog_err("No current known DataPlane interfaces can return this, please fix"); + flog_err( + ZEBRA_ERR_DP_INVALID_RC, + "No current known DataPlane interfaces can return this, please fix"); break; case DP_REQUEST_FAILURE: - zlog_err("No current known Rib Install Failure cases, please fix"); + flog_err( + ZEBRA_ERR_DP_INSTALL_FAIL, + "No current known Rib Install Failure cases, please fix"); break; case DP_REQUEST_SUCCESS: zvrf->installs++; @@ -1161,10 +1166,14 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re) hook_call(rib_update, rn, "uninstalling from kernel"); switch (kernel_route_rib(rn, p, src_p, re, NULL)) { case DP_REQUEST_QUEUED: - zlog_err("No current known DataPlane interfaces can return this, please fix"); + flog_err( + ZEBRA_ERR_DP_INVALID_RC, + "No current known DataPlane interfaces can return this, please fix"); break; case DP_REQUEST_FAILURE: - zlog_err("No current known RIB Install Failure cases, please fix"); + flog_err( + ZEBRA_ERR_DP_INSTALL_FAIL, + "No current known RIB Install Failure cases, please fix"); break; case DP_REQUEST_SUCCESS: if (zvrf) @@ -1936,7 +1945,8 @@ void rib_queue_add(struct route_node *rn) } if (zebrad.ribq == NULL) { - zlog_err("%s: work_queue does not exist!", __func__); + flog_err(ZEBRA_ERR_WQ_NONEXISTENT, + "%s: work_queue does not exist!", __func__); return; } @@ -1991,7 +2001,8 @@ static void rib_queue_init(struct zebra_t *zebra) if (!(zebra->ribq = work_queue_new(zebra->master, "route_node processing"))) { - zlog_err("%s: could not initialise work queue!", __func__); + flog_err(ZEBRA_ERR_WQ_NONEXISTENT, + "%s: could not initialise work queue!", __func__); return; } @@ -2004,7 +2015,8 @@ static void rib_queue_init(struct zebra_t *zebra) zebra->ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; if (!(zebra->mq = meta_queue_new())) { - zlog_err("%s: could not initialise meta queue!", __func__); + flog_err(ZEBRA_ERR_WQ_NONEXISTENT, + "%s: could not initialise meta queue!", __func__); return; } return; @@ -2231,8 +2243,9 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id) /* Lookup table. */ table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); if (!table) { - zlog_err("%s:%u zebra_vrf_table() returned NULL", - __func__, vrf_id); + flog_err(ZEBRA_ERR_TABLE_LOOKUP_FAILED, + "%s:%u zebra_vrf_table() returned NULL", __func__, + vrf_id); return; } @@ -2278,8 +2291,9 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id) rib_dest_t *dest; if (NULL == (table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id))) { - zlog_err("%s:%u zebra_vrf_table() returned NULL", - __func__, vrf_id); + flog_err(ZEBRA_ERR_TABLE_LOOKUP_FAILED, + "%s:%u zebra_vrf_table() returned NULL", __func__, + vrf_id); return; } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 453f08a18..156600c10 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -47,6 +47,7 @@ #include "zebra/zebra_routemap.h" #include "zebra/interface.h" #include "zebra/zebra_memory.h" +#include "zebra/zebra_errors.h" static void free_state(vrf_id_t vrf_id, struct route_entry *re, struct route_node *rn); @@ -857,8 +858,9 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, stream_put(s, &rn->p.u.prefix6, IPV6_MAX_BYTELEN); break; default: - zlog_err("%s: Unknown family (%d) notification attempted\n", - __FUNCTION__, rn->p.family); + flog_err(ZEBRA_ERR_RNH_UNKNOWN_FAMILY, + "%s: Unknown family (%d) notification attempted\n", + __FUNCTION__, rn->p.family); break; } if (re) { diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 17a25b700..04f9be8ad 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -22,33 +22,34 @@ #include +#include "hash.h" #include "if.h" -#include "prefix.h" -#include "table.h" -#include "memory.h" -#include "log.h" +#include "jhash.h" #include "linklist.h" +#include "log.h" +#include "memory.h" +#include "prefix.h" #include "stream.h" -#include "hash.h" -#include "jhash.h" +#include "table.h" #include "vlan.h" #include "vxlan.h" #ifdef GNU_LINUX #include #endif +#include "zebra/debug.h" +#include "zebra/interface.h" #include "zebra/rib.h" #include "zebra/rt.h" +#include "zebra/rt_netlink.h" +#include "zebra/zebra_errors.h" +#include "zebra/zebra_l2.h" +#include "zebra/zebra_memory.h" #include "zebra/zebra_ns.h" -#include "zebra/zserv.h" -#include "zebra/debug.h" -#include "zebra/interface.h" #include "zebra/zebra_vrf.h" -#include "zebra/rt_netlink.h" -#include "zebra/zebra_vxlan_private.h" #include "zebra/zebra_vxlan.h" -#include "zebra/zebra_memory.h" -#include "zebra/zebra_l2.h" +#include "zebra/zebra_vxlan_private.h" +#include "zebra/zserv.h" DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix"); DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash"); @@ -280,8 +281,6 @@ static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt) int width; n = (zebra_neigh_t *)backet->data; - if (!n) - return; ipaddr2str(&n->ip, buf, sizeof(buf)), width = strlen(buf); if (width > wctx->addr_width) @@ -355,8 +354,6 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt) vty = wctx->vty; json_vni = wctx->json; n = (zebra_neigh_t *)backet->data; - if (!n) - return; if (json_vni) json_row = json_object_new_object(); @@ -435,11 +432,7 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet, json = (json_object *)args[1]; zvni = (zebra_vni_t *)backet->data; - if (!zvni) { - if (json) - vty_out(vty, "{}\n"); - return; - } + num_neigh = hashcount(zvni->neigh_table); if (json == NULL) { vty_out(vty, @@ -628,8 +621,6 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt) vty = wctx->vty; json_mac_hdr = wctx->json; mac = (zebra_mac_t *)backet->data; - if (!mac) - return; prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)); @@ -735,11 +726,6 @@ static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt) json = (struct json_object *)wctx->json; zvni = (zebra_vni_t *)backet->data; - if (!zvni) { - if (json) - vty_out(vty, "{}\n"); - return; - } wctx->zvni = zvni; /*We are iterating over a new VNI, set the count to 0*/ @@ -794,8 +780,6 @@ static void zl3vni_print_nh_hash(struct hash_backet *backet, void *ctx) if (json_vni) json_nh = json_object_new_object(); n = (zebra_neigh_t *)backet->data; - if (!n) - return; if (!json_vni) { vty_out(vty, "%-15s %-17s\n", @@ -828,11 +812,6 @@ static void zl3vni_print_nh_hash_all_vni(struct hash_backet *backet, json = (struct json_object *)args[1]; zl3vni = (zebra_l3vni_t *)backet->data; - if (!zl3vni) { - if (json) - vty_out(vty, "{}\n"); - return; - } num_nh = hashcount(zl3vni->nh_table); if (!num_nh) @@ -872,11 +851,6 @@ static void zl3vni_print_rmac_hash_all_vni(struct hash_backet *backet, json = (struct json_object *)args[1]; zl3vni = (zebra_l3vni_t *)backet->data; - if (!zl3vni) { - if (json) - vty_out(vty, "{}\n"); - return; - } num_rmacs = hashcount(zl3vni->rmac_table); if (!num_rmacs) @@ -920,8 +894,6 @@ static void zl3vni_print_rmac_hash(struct hash_backet *backet, void *ctx) if (json) json_rmac = json_object_new_object(); zrmac = (zebra_mac_t *)backet->data; - if (!zrmac) - return; if (!json) { vty_out(vty, "%-17s %-21s\n", @@ -1098,8 +1070,6 @@ static void zl3vni_print_hash(struct hash_backet *backet, void *ctx[]) json = (json_object *)ctx[1]; zl3vni = (zebra_l3vni_t *)backet->data; - if (!zl3vni) - return; if (!json) { vty_out(vty, "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n", @@ -1147,8 +1117,6 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]) json = ctxt[1]; zvni = (zebra_vni_t *)backet->data; - if (!zvni) - return; zvtep = zvni->vteps; while (zvtep) { @@ -1492,14 +1460,13 @@ static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni, zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0); } - } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_err( - "local MAC %s getting deleted on VNI %u has remote neigh %s", - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni, - ipaddr2str(&n->ip, buf2, sizeof(buf2))); + } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) + && IS_ZEBRA_DEBUG_VXLAN) { + zlog_debug( + "local MAC %s getting deleted on VNI %u has remote neigh %s", + prefix_mac2str(&n->emac, buf, sizeof(buf)), + zvni->vni, + ipaddr2str(&n->ip, buf2, sizeof(buf2))); } } } @@ -1543,14 +1510,13 @@ static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni, char buf2[INET6_ADDRSTRLEN]; for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) { - if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_err( - "remote MAC %s getting deleted on VNI %u has local neigh %s", - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni, - ipaddr2str(&n->ip, buf2, sizeof(buf2))); + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) + && IS_ZEBRA_DEBUG_VXLAN) { + zlog_debug( + "remote MAC %s getting deleted on VNI %u has local neigh %s", + prefix_mac2str(&n->emac, buf, sizeof(buf)), + zvni->vni, + ipaddr2str(&n->ip, buf2, sizeof(buf2))); } } } @@ -1628,8 +1594,8 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n) return 0; if (!zvni->vxlan_if) { - zlog_err("VNI %u hash %p couldn't be uninstalled - no intf", - zvni->vni, zvni); + zlog_warn("VNI %u hash %p couldn't be uninstalled - no intf", + zvni->vni, zvni); return -1; } @@ -1653,8 +1619,6 @@ static void zvni_install_neigh_hash(struct hash_backet *backet, void *ctxt) struct neigh_walk_ctx *wctx = ctxt; n = (zebra_neigh_t *)backet->data; - if (!n) - return; if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) zvni_neigh_install(wctx->zvni, n); @@ -1803,9 +1767,10 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, if (!mac) { mac = zvni_mac_add(zvni, macaddr); if (!mac) { - zlog_err("Failed to add MAC %s intf %s(%u) VID %u", - prefix_mac2str(macaddr, buf, sizeof(buf)), - ifp->name, ifp->ifindex, vxl->access_vlan); + flog_err(ZEBRA_ERR_MAC_ADD_FAILED, + "Failed to add MAC %s intf %s(%u) VID %u", + prefix_mac2str(macaddr, buf, sizeof(buf)), + ifp->name, ifp->ifindex, vxl->access_vlan); return -1; } } @@ -1822,7 +1787,8 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, if (!n) { n = zvni_neigh_add(zvni, ip, macaddr); if (!n) { - zlog_err( + flog_err( + ZEBRA_ERR_MAC_ADD_FAILED, "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u", ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), @@ -1875,9 +1841,9 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni, /* mac entry should be present */ mac = zvni_mac_lookup(zvni, &n->emac); if (!mac) { - zlog_err("MAC %s doesnt exists for neigh %s on VNI %u", - prefix_mac2str(&n->emac, buf1, sizeof(buf1)), - ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni); + zlog_warn("MAC %s doesnt exists for neigh %s on VNI %u", + prefix_mac2str(&n->emac, buf1, sizeof(buf1)), + ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni); return -1; } @@ -1919,8 +1885,6 @@ static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet, /* Add primary SVI MAC*/ zvni = (zebra_vni_t *)backet->data; - if (!zvni) - return; ifp = zvni->vxlan_if; if (!ifp) @@ -1960,8 +1924,6 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet, struct interface *ifp = NULL; zvni = (zebra_vni_t *)backet->data; - if (!zvni) - return; ifp = zvni->vxlan_if; if (!ifp) @@ -2085,7 +2047,8 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, /* New neighbor - create */ n = zvni_neigh_add(zvni, ip, macaddr); if (!n) { - zlog_err( + flog_err( + ZEBRA_ERR_MAC_ADD_FAILED, "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u", ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), @@ -2156,10 +2119,11 @@ static int zvni_remote_neigh_update(zebra_vni_t *zvni, */ zmac = zvni_mac_lookup(zvni, macaddr); if (!zmac || !CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) { - zlog_err("Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local", - ipaddr2str(&n->ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - zvni->vni); + zlog_warn( + "Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local", + ipaddr2str(&n->ip, buf2, sizeof(buf2)), + prefix_mac2str(macaddr, buf, sizeof(buf)), + zvni->vni); return -1; } @@ -2588,8 +2552,8 @@ static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local) return 0; if (!zvni->vxlan_if) { - zlog_err("VNI %u hash %p couldn't be uninstalled - no intf", - zvni->vni, zvni); + zlog_warn("VNI %u hash %p couldn't be uninstalled - no intf", + zvni->vni, zvni); return -1; } @@ -2622,8 +2586,6 @@ static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt) struct mac_walk_ctx *wctx = ctxt; mac = (zebra_mac_t *)backet->data; - if (!mac) - return; if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) zvni_mac_install(wctx->zvni, mac); @@ -2918,7 +2880,7 @@ static void zvni_build_hash_table() /* VNI hash entry is not expected to exist. */ zvni = zvni_lookup(vni); if (zvni) { - zlog_err( + zlog_warn( "VNI hash already present for IF %s(%u) L2-VNI %u", ifp->name, ifp->ifindex, vni); continue; @@ -2926,7 +2888,7 @@ static void zvni_build_hash_table() zvni = zvni_add(vni); if (!zvni) { - zlog_err( + zlog_warn( "Failed to add VNI hash, IF %s(%u) L2-VNI %u", ifp->name, ifp->ifindex, vni); return; @@ -3049,8 +3011,8 @@ static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip) static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip) { if (!zvni->vxlan_if) { - zlog_err("VNI %u hash %p couldn't be uninstalled - no intf", - zvni->vni, zvni); + zlog_warn("VNI %u hash %p couldn't be uninstalled - no intf", + zvni->vni, zvni); return -1; } @@ -3067,8 +3029,6 @@ static void zvni_cleanup_all(struct hash_backet *backet, void *arg) struct zebra_vrf *zvrf = (struct zebra_vrf *)arg; zvni = (zebra_vni_t *)backet->data; - if (!zvni) - return; /* remove from l3-vni list */ if (zvrf->l3vni) @@ -3093,8 +3053,6 @@ static void zl3vni_cleanup_all(struct hash_backet *backet, void *args) zebra_l3vni_t *zl3vni = NULL; zl3vni = (zebra_l3vni_t *)backet->data; - if (!zl3vni) - return; zebra_vxlan_process_l3vni_oper_down(zl3vni); } @@ -3244,7 +3202,7 @@ static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac) return 0; if (!zl3vni->vxlan_if) { - zlog_err( + zlog_warn( "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if", prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)), zl3vni->vni, zl3vni); @@ -3900,8 +3858,9 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, /* Delete the hash entry. */ if (zvni_del(zvni)) { - zlog_err("Failed to del VNI hash %p, VNI %u", zvni, - zvni->vni); + flog_err(ZEBRA_ERR_VNI_DEL_FAILED, + "Failed to del VNI hash %p, VNI %u", zvni, + zvni->vni); return -1; } } else { @@ -4920,7 +4879,7 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp, return 0; if (!zvni->vxlan_if) { - zlog_err( + zlog_warn( "VNI %u hash %p doesn't have intf upon local neighbor DEL", zvni->vni, zvni); return -1; @@ -4939,7 +4898,7 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp, zmac = zvni_mac_lookup(zvni, &n->emac); if (!zmac) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_err( + zlog_warn( "Trying to del a neigh %s without a mac %s on VNI %u", ipaddr2str(ip, buf, sizeof(buf)), prefix_mac2str(&n->emac, buf2, sizeof(buf2)), @@ -5086,7 +5045,7 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) } ifp = zvni->vxlan_if; if (!ifp) { - zlog_err( + zlog_warn( "VNI %u hash %p doesn't have intf upon remote MACIP DEL", vni, zvni); continue; @@ -5113,9 +5072,9 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) n = zvni_neigh_lookup(zvni, &ip); if (n && !mac) { - zlog_err("Failed to locate MAC %s for neigh %s VNI %u", - prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni); + zlog_warn("Failed to locate MAC %s for neigh %s VNI %u", + prefix_mac2str(&macaddr, buf, sizeof(buf)), + ipaddr2str(&ip, buf1, sizeof(buf1)), vni); continue; } @@ -5129,7 +5088,7 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) /* Ignore the delete if this mac is a gateway mac-ip */ if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) { - zlog_err( + zlog_warn( "%u: Ignore Del for MAC %s neigh %s on VNI %u as it is configured as a default gateway", zvrf_id(zvrf), prefix_mac2str(&macaddr, buf, sizeof(buf)), @@ -5248,14 +5207,14 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) /* Locate VNI hash entry - expected to exist. */ zvni = zvni_lookup(vni); if (!zvni) { - zlog_err( + zlog_warn( "Failed to locate VNI hash upon remote MACIP ADD, VNI %u", vni); continue; } ifp = zvni->vxlan_if; if (!ifp) { - zlog_err( + zlog_warn( "VNI %u hash %p doesn't have intf upon remote MACIP add", vni, zvni); continue; @@ -5275,7 +5234,8 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) zvtep = zvni_vtep_find(zvni, &vtep_ip); if (!zvtep) { if (zvni_vtep_add(zvni, &vtep_ip) == NULL) { - zlog_err( + flog_err( + ZEBRA_ERR_VTEP_ADD_FAILED, "Failed to add remote VTEP, VNI %u zvni %p", vni, zvni); continue; @@ -5548,8 +5508,8 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, if (!zvni) return 0; if (!zvni->vxlan_if) { - zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL", - zvni->vni, zvni); + zlog_warn("VNI %u hash %p doesn't have intf upon local MAC DEL", + zvni->vni, zvni); return -1; } @@ -5616,8 +5576,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, } if (!zvni->vxlan_if) { - zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD", - zvni->vni, zvni); + zlog_warn("VNI %u hash %p doesn't have intf upon local MAC ADD", + zvni->vni, zvni); return -1; } @@ -5682,9 +5642,10 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, if (!mac) { mac = zvni_mac_add(zvni, macaddr); if (!mac) { - zlog_err("Failed to add MAC %s intf %s(%u) VID %u", - prefix_mac2str(macaddr, buf, sizeof(buf)), - ifp->name, ifp->ifindex, vid); + flog_err(ZEBRA_ERR_MAC_ADD_FAILED, + "Failed to add MAC %s intf %s(%u) VID %u", + prefix_mac2str(macaddr, buf, sizeof(buf)), + ifp->name, ifp->ifindex, vid); return -1; } } @@ -5734,8 +5695,8 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) } if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_err("Recv MACIP DEL for non-default VRF %u", - zvrf_id(zvrf)); + zlog_warn("Recv MACIP DEL for non-default VRF %u", + zvrf_id(zvrf)); return; } @@ -5766,7 +5727,7 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) ifp = zvni->vxlan_if; if (!ifp) { - zlog_err( + zlog_warn( "VNI %u hash %p doesn't have intf upon remote VTEP DEL", zvni->vni, zvni); continue; @@ -5818,8 +5779,8 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) } if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_err("Recv MACIP ADD for non-default VRF %u", - zvrf_id(zvrf)); + zlog_warn("Recv MACIP ADD for non-default VRF %u", + zvrf_id(zvrf)); return; } @@ -5840,7 +5801,8 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) /* Locate VNI hash entry - expected to exist. */ zvni = zvni_lookup(vni); if (!zvni) { - zlog_err( + flog_err( + ZEBRA_ERR_VTEP_ADD_FAILED, "Failed to locate VNI hash upon remote VTEP ADD, VNI %u", vni); continue; @@ -5848,7 +5810,8 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) ifp = zvni->vxlan_if; if (!ifp) { - zlog_err( + flog_err( + ZEBRA_ERR_VTEP_ADD_FAILED, "VNI %u hash %p doesn't have intf upon remote VTEP ADD", zvni->vni, zvni); continue; @@ -5866,8 +5829,9 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) continue; if (zvni_vtep_add(zvni, &vtep_ip) == NULL) { - zlog_err("Failed to add remote VTEP, VNI %u zvni %p", - vni, zvni); + flog_err(ZEBRA_ERR_VTEP_ADD_FAILED, + "Failed to add remote VTEP, VNI %u zvni %p", + vni, zvni); continue; } @@ -5918,8 +5882,8 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ifp_zif->link_ifindex); if (!svi_if) { - zlog_err("MACVLAN %s(%u) without link information", - ifp->name, ifp->ifindex); + zlog_warn("MACVLAN %s(%u) without link information", + ifp->name, ifp->ifindex); return -1; } @@ -5966,8 +5930,8 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, return 0; if (!zvni->vxlan_if) { - zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up", - zvni->vni, zvni); + zlog_warn("VNI %u hash %p doesn't have intf upon MACVLAN up", + zvni->vni, zvni); return -1; } @@ -6063,8 +6027,9 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) return 0; if (!zvni->vxlan_if) { - zlog_err("VNI %u hash %p doesn't have intf upon SVI up", - zvni->vni, zvni); + zlog_warn( + "VNI %u hash %p doesn't have intf upon SVI up", + zvni->vni, zvni); return -1; } @@ -6125,7 +6090,7 @@ int zebra_vxlan_if_down(struct interface *ifp) /* Locate hash entry; it is expected to exist. */ zvni = zvni_lookup(vni); if (!zvni) { - zlog_err( + zlog_warn( "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u", ifp->name, ifp->ifindex, vni); return -1; @@ -6191,7 +6156,7 @@ int zebra_vxlan_if_up(struct interface *ifp) /* Locate hash entry; it is expected to exist. */ zvni = zvni_lookup(vni); if (!zvni) { - zlog_err( + zlog_warn( "Failed to locate VNI hash at UP, IF %s(%u) VNI %u", ifp->name, ifp->ifindex, vni); return -1; @@ -6262,7 +6227,7 @@ int zebra_vxlan_if_del(struct interface *ifp) /* Locate hash entry; it is expected to exist. */ zvni = zvni_lookup(vni); if (!zvni) { - zlog_err( + zlog_warn( "Failed to locate VNI hash at del, IF %s(%u) VNI %u", ifp->name, ifp->ifindex, vni); return 0; @@ -6285,8 +6250,9 @@ int zebra_vxlan_if_del(struct interface *ifp) /* Delete the hash entry. */ if (zvni_del(zvni)) { - zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u", - zvni, ifp->name, ifp->ifindex, zvni->vni); + flog_err(ZEBRA_ERR_VNI_DEL_FAILED, + "Failed to del VNI hash %p, IF %s(%u) VNI %u", + zvni, ifp->name, ifp->ifindex, zvni->vni); return -1; } } @@ -6372,7 +6338,7 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) /* Update VNI hash. */ zvni = zvni_lookup(vni); if (!zvni) { - zlog_err( + zlog_warn( "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u", ifp->name, ifp->ifindex, vni); return -1; @@ -6500,7 +6466,8 @@ int zebra_vxlan_if_add(struct interface *ifp) if (!zvni) { zvni = zvni_add(vni); if (!zvni) { - zlog_err( + flog_err( + ZEBRA_ERR_VNI_ADD_FAILED, "Failed to add VNI hash, IF %s(%u) VNI %u", ifp->name, ifp->ifindex, vni); return -1; @@ -6703,8 +6670,8 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS) struct interface *vlan_if = NULL; if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_err("EVPN GW-MACIP Adv for non-default VRF %u", - zvrf_id(zvrf)); + zlog_warn("EVPN GW-MACIP Adv for non-default VRF %u", + zvrf_id(zvrf)); return; } @@ -6766,8 +6733,8 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS) struct interface *ifp = NULL; if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_err("EVPN GW-MACIP Adv for non-default VRF %u", - zvrf_id(zvrf)); + zlog_warn("EVPN GW-MACIP Adv for non-default VRF %u", + zvrf_id(zvrf)); return; } @@ -6871,7 +6838,7 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) struct zebra_ns *zns = NULL; if (zvrf_id(zvrf) != VRF_DEFAULT) { - zlog_err("EVPN VNI Adv for non-default VRF %u", zvrf_id(zvrf)); + zlog_warn("EVPN VNI Adv for non-default VRF %u", zvrf_id(zvrf)); return; } diff --git a/zebra/zserv.c b/zebra/zserv.c index f76c2fabd..174e01074 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -54,6 +54,7 @@ #include "lib/zclient.h" /* for zmsghdr, ZEBRA_HEADER_SIZE, ZEBRA... */ #include "lib/frr_pthread.h" /* for frr_pthread_new, frr_pthread_stop... */ #include "lib/frratomic.h" /* for atomic_load_explicit, atomic_stor... */ +#include "lib/lib_errors.h" /* for generic ferr ids */ #include "zebra/debug.h" /* for various debugging macros */ #include "zebra/rib.h" /* for rib_score_proto */ @@ -786,15 +787,14 @@ void zserv_start(char *path) unlink(suna->sun_path); } - zserv_privs.change(ZPRIVS_RAISE); - setsockopt_so_recvbuf(zebrad.sock, 1048576); - setsockopt_so_sendbuf(zebrad.sock, 1048576); - zserv_privs.change(ZPRIVS_LOWER); - - if (sa.ss_family != AF_UNIX && zserv_privs.change(ZPRIVS_RAISE)) - zlog_err("Can't raise privileges"); + frr_elevate_privs(&zserv_privs) { + setsockopt_so_recvbuf(zebrad.sock, 1048576); + setsockopt_so_sendbuf(zebrad.sock, 1048576); + } - ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len); + frr_elevate_privs((sa.ss_family != AF_UNIX) ? &zserv_privs : NULL) { + ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len); + } if (ret < 0) { zlog_warn("Can't bind zserv socket on %s: %s", path, safe_strerror(errno)); @@ -804,8 +804,6 @@ void zserv_start(char *path) zebrad.sock = -1; return; } - if (sa.ss_family != AF_UNIX && zserv_privs.change(ZPRIVS_LOWER)) - zlog_err("Can't lower privileges"); ret = listen(zebrad.sock, 5); if (ret < 0) {