]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/log.c
zebra: Allow ns delete to happen after under/over flow checks
[mirror_frr.git] / lib / log.c
index 521783e4b09887d5434d33b98e36a2314dd0f9e2..12a1d7fbe04062a1c8ae24863c568a8ea00b2878 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
 #include <ucontext.h>
 #endif
 
+#ifdef HAVE_LIBUNWIND
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#include <dlfcn.h>
+#endif
+
 DEFINE_MTYPE_STATIC(LIB, ZLOG, "Logging")
 
 static int logfile_fd = -1; /* Used in signal handler. */
@@ -313,7 +319,9 @@ static char *num_append(char *s, int len, unsigned long x)
        return str_append(s, len, t);
 }
 
-#if defined(SA_SIGINFO) || defined(HAVE_STACK_TRACE)
+#if defined(SA_SIGINFO) \
+       || defined(HAVE_PRINTSTACK) \
+       || defined(HAVE_GLIBC_BACKTRACE)
 static char *hex_append(char *s, int len, unsigned long x)
 {
        char buf[30];
@@ -533,7 +541,37 @@ void zlog_signal(int signo, const char *action
    Needs to be enhanced to support syslog logging. */
 void zlog_backtrace_sigsafe(int priority, void *program_counter)
 {
-#ifdef HAVE_STACK_TRACE
+#ifdef HAVE_LIBUNWIND
+       char buf[100];
+       unw_cursor_t cursor;
+       unw_context_t uc;
+       unw_word_t ip, off, sp;
+       Dl_info dlinfo;
+
+       unw_getcontext(&uc);
+       unw_init_local(&cursor, &uc);
+       while (unw_step(&cursor) > 0) {
+               char name[128] = "?";
+
+               unw_get_reg(&cursor, UNW_REG_IP, &ip);
+               unw_get_reg(&cursor, UNW_REG_SP, &sp);
+
+               if (unw_is_signal_frame(&cursor))
+                       dprintf(2, "    ---- signal ----\n");
+
+               if (!unw_get_proc_name(&cursor, buf, sizeof(buf), &off)) {
+                       snprintf(name, sizeof(name), "%s+%#lx",
+                               buf, (long)off);
+               }
+               dprintf(2, "%-30s %16lx %16lx", name, (long)ip, (long)sp);
+               if (dladdr((void *)ip, &dlinfo)) {
+                       dprintf(2, " %s (mapped at %p)",
+                               dlinfo.dli_fname, dlinfo.dli_fbase);
+               }
+               dprintf(2, "\n");
+
+       }
+#elif defined(HAVE_GLIBC_BACKTRACE) || defined(HAVE_PRINTSTACK)
        static const char pclabel[] = "Program counter: ";
        void *array[64];
        int size;
@@ -624,9 +662,38 @@ void zlog_backtrace_sigsafe(int priority, void *program_counter)
 
 void zlog_backtrace(int priority)
 {
-#ifndef HAVE_GLIBC_BACKTRACE
-       zlog(priority, "No backtrace available on this platform.");
-#else
+#ifdef HAVE_LIBUNWIND
+       char buf[100];
+       unw_cursor_t cursor;
+       unw_context_t uc;
+       unw_word_t ip, off, sp;
+       Dl_info dlinfo;
+
+       unw_getcontext(&uc);
+       unw_init_local(&cursor, &uc);
+       zlog(priority, "Backtrace:");
+       while (unw_step(&cursor) > 0) {
+               char name[128] = "?";
+
+               unw_get_reg(&cursor, UNW_REG_IP, &ip);
+               unw_get_reg(&cursor, UNW_REG_SP, &sp);
+
+               if (unw_is_signal_frame(&cursor))
+                       zlog(priority, "    ---- signal ----");
+
+               if (!unw_get_proc_name(&cursor, buf, sizeof(buf), &off))
+                       snprintf(name, sizeof(name), "%s+%#lx",
+                               buf, (long)off);
+
+               if (dladdr((void *)ip, &dlinfo))
+                       zlog(priority, "%-30s %16lx %16lx %s (mapped at %p)",
+                               name, (long)ip, (long)sp,
+                               dlinfo.dli_fname, dlinfo.dli_fbase);
+               else
+                       zlog(priority, "%-30s %16lx %16lx",
+                               name, (long)ip, (long)sp);
+       }
+#elif defined(HAVE_GLIBC_BACKTRACE)
        void *array[20];
        int size, i;
        char **strings;
@@ -634,7 +701,7 @@ void zlog_backtrace(int priority)
        size = backtrace(array, array_size(array));
        if (size <= 0 || (size_t)size > array_size(array)) {
                flog_err_sys(
-                       LIB_ERR_SYSTEM_CALL,
+                       EC_LIB_SYSTEM_CALL,
                        "Cannot get backtrace, returned invalid # of frames %d "
                        "(valid range is between 1 and %lu)",
                        size, (unsigned long)(array_size(array)));
@@ -642,7 +709,7 @@ void zlog_backtrace(int priority)
        }
        zlog(priority, "Backtrace for %d stack frames:", size);
        if (!(strings = backtrace_symbols(array, size))) {
-               flog_err_sys(LIB_ERR_SYSTEM_CALL,
+               flog_err_sys(EC_LIB_SYSTEM_CALL,
                             "Cannot get backtrace symbols (out of memory?)");
                for (i = 0; i < size; i++)
                        zlog(priority, "[bt %d] %p", i, array[i]);
@@ -651,7 +718,9 @@ void zlog_backtrace(int priority)
                        zlog(priority, "[bt %d] %s", i, strings[i]);
                free(strings);
        }
-#endif /* HAVE_GLIBC_BACKTRACE */
+#else /* !HAVE_GLIBC_BACKTRACE && !HAVE_LIBUNWIND */
+       zlog(priority, "No backtrace available on this platform.");
+#endif
 }
 
 void zlog(int priority, const char *format, ...)
@@ -716,7 +785,7 @@ void _zlog_assert_failed(const char *assertion, const char *file,
 
 void memory_oom(size_t size, const char *name)
 {
-       flog_err_sys(LIB_ERR_SYSTEM_CALL,
+       flog_err_sys(EC_LIB_SYSTEM_CALL,
                     "out of memory: failed to allocate %zu bytes for %s"
                     "object",
                     size, name);
@@ -872,7 +941,7 @@ int zlog_rotate(void)
                        pthread_mutex_unlock(&loglock);
 
                        flog_err_sys(
-                               LIB_ERR_SYSTEM_CALL,
+                               EC_LIB_SYSTEM_CALL,
                                "Log rotate failed: cannot open file %s for append: %s",
                                zl->filename, safe_strerror(save_errno));
                        ret = -1;
@@ -945,6 +1014,7 @@ static const struct zebra_desc_table command_types[] = {
        DESC_ENTRY(ZEBRA_MPLS_LABELS_DELETE),
        DESC_ENTRY(ZEBRA_IPMR_ROUTE_STATS),
        DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT),
+       DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT_ASYNC),
        DESC_ENTRY(ZEBRA_GET_LABEL_CHUNK),
        DESC_ENTRY(ZEBRA_RELEASE_LABEL_CHUNK),
        DESC_ENTRY(ZEBRA_ADVERTISE_ALL_VNI),
@@ -964,6 +1034,7 @@ static const struct zebra_desc_table command_types[] = {
        DESC_ENTRY(ZEBRA_IP_PREFIX_ROUTE_DEL),
        DESC_ENTRY(ZEBRA_REMOTE_MACIP_ADD),
        DESC_ENTRY(ZEBRA_REMOTE_MACIP_DEL),
+       DESC_ENTRY(ZEBRA_DUPLICATE_ADDR_DETECTION),
        DESC_ENTRY(ZEBRA_PW_ADD),
        DESC_ENTRY(ZEBRA_PW_DELETE),
        DESC_ENTRY(ZEBRA_PW_SET),
@@ -979,6 +1050,7 @@ static const struct zebra_desc_table command_types[] = {
        DESC_ENTRY(ZEBRA_IPSET_DESTROY),
        DESC_ENTRY(ZEBRA_IPSET_ENTRY_ADD),
        DESC_ENTRY(ZEBRA_IPSET_ENTRY_DELETE),
+       DESC_ENTRY(ZEBRA_VXLAN_FLOOD_CONTROL),
 };
 #undef DESC_ENTRY
 
@@ -989,8 +1061,8 @@ static const struct zebra_desc_table *zroute_lookup(unsigned int zroute)
        unsigned int i;
 
        if (zroute >= array_size(route_types)) {
-               flog_err(LIB_ERR_DEVELOPMENT, "unknown zebra route type: %u",
-                         zroute);
+               flog_err(EC_LIB_DEVELOPMENT, "unknown zebra route type: %u",
+                        zroute);
                return &unknown;
        }
        if (zroute == route_types[zroute].type)
@@ -1004,9 +1076,8 @@ static const struct zebra_desc_table *zroute_lookup(unsigned int zroute)
                        return &route_types[i];
                }
        }
-       flog_err(LIB_ERR_DEVELOPMENT,
-                 "internal error: cannot find route type %u in table!",
-                 zroute);
+       flog_err(EC_LIB_DEVELOPMENT,
+                "internal error: cannot find route type %u in table!", zroute);
        return &unknown;
 }
 
@@ -1023,8 +1094,8 @@ char zebra_route_char(unsigned int zroute)
 const char *zserv_command_string(unsigned int command)
 {
        if (command >= array_size(command_types)) {
-               flog_err(LIB_ERR_DEVELOPMENT, "unknown zserv command type: %u",
-                         command);
+               flog_err(EC_LIB_DEVELOPMENT, "unknown zserv command type: %u",
+                        command);
                return unknown.string;
        }
        return command_types[command].string;