summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/agentx.c7
-rw-r--r--lib/agg_table.h5
-rw-r--r--lib/command.h8
-rw-r--r--lib/filter.c33
-rw-r--r--lib/frr_pthread.c5
-rw-r--r--lib/frr_zmq.c22
-rw-r--r--lib/hash.c14
-rw-r--r--lib/if.c22
-rw-r--r--lib/ldp_sync.c2
-rw-r--r--lib/libfrr_trace.c4
-rw-r--r--lib/libfrr_trace.h240
-rw-r--r--lib/linklist.c9
-rw-r--r--lib/memory.c5
-rw-r--r--lib/nexthop.c8
-rw-r--r--lib/nexthop_group.c20
-rw-r--r--lib/northbound_cli.c8
-rw-r--r--lib/plist.c32
-rw-r--r--lib/routemap.c56
-rw-r--r--lib/sockunion.c12
-rw-r--r--lib/spf_backoff.c9
-rw-r--r--lib/subdir.am8
-rw-r--r--lib/table.c10
-rw-r--r--lib/table.h5
-rw-r--r--lib/thread.c49
-rw-r--r--lib/thread.h19
-rw-r--r--lib/trace.h80
-rw-r--r--lib/workqueue.c4
-rw-r--r--lib/zassert.h2
-rw-r--r--lib/zclient.c50
-rw-r--r--lib/zlog.c29
30 files changed, 575 insertions, 202 deletions
diff --git a/lib/agentx.c b/lib/agentx.c
index 7c4bdcbe27..603d8d6172 100644
--- a/lib/agentx.c
+++ b/lib/agentx.c
@@ -107,7 +107,7 @@ static void agentx_events_update(void)
struct thread *thr;
int fd, thr_fd;
- THREAD_OFF(timeout_thr);
+ thread_cancel(&timeout_thr);
FD_ZERO(&fds);
snmp_select_info(&maxfd, &fds, &timeout, &block);
@@ -130,7 +130,7 @@ static void agentx_events_update(void)
if (thr_fd == fd) {
struct listnode *nextln = listnextnode(ln);
if (!FD_ISSET(fd, &fds)) {
- thread_cancel(thr);
+ thread_cancel(&thr);
list_delete_node(events, ln);
}
ln = nextln;
@@ -151,7 +151,8 @@ static void agentx_events_update(void)
*/
while (ln) {
struct listnode *nextln = listnextnode(ln);
- thread_cancel(listgetdata(ln));
+ thr = listgetdata(ln);
+ thread_cancel(&thr);
list_delete_node(events, ln);
ln = nextln;
}
diff --git a/lib/agg_table.h b/lib/agg_table.h
index e98476f1b7..e0c06449ee 100644
--- a/lib/agg_table.h
+++ b/lib/agg_table.h
@@ -161,6 +161,11 @@ agg_node_get_prefix(const struct agg_node *node)
return &node->p;
}
+static inline unsigned int agg_node_get_lock_count(const struct agg_node *node)
+{
+ return node->lock;
+}
+
#ifdef _FRR_ATTRIBUTE_PRINTFRR
#pragma FRR printfrr_ext "%pRN" (struct agg_node *)
#endif
diff --git a/lib/command.h b/lib/command.h
index 677d4b2dad..bb007b0868 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -462,6 +462,14 @@ struct cmd_node {
#define EVPN_TYPE_3_HELP_STR "Multicast (Type-3) route\n"
#define EVPN_TYPE_4_HELP_STR "Ethernet Segment (Type-4) route\n"
#define EVPN_TYPE_5_HELP_STR "Prefix (Type-5) route\n"
+#define EVPN_TYPE_ALL_LIST "<ead|1|macip|2|multicast|3|es|4|prefix|5>"
+#define EVPN_TYPE_ALL_LIST_HELP_STR \
+ EVPN_TYPE_1_HELP_STR EVPN_TYPE_1_HELP_STR \
+ EVPN_TYPE_2_HELP_STR EVPN_TYPE_2_HELP_STR \
+ EVPN_TYPE_3_HELP_STR EVPN_TYPE_3_HELP_STR \
+ EVPN_TYPE_4_HELP_STR EVPN_TYPE_4_HELP_STR \
+ EVPN_TYPE_5_HELP_STR EVPN_TYPE_5_HELP_STR
+
/* Prototypes. */
extern void install_node(struct cmd_node *node);
diff --git a/lib/filter.c b/lib/filter.c
index e6add0462b..f5ae9ee2b7 100644
--- a/lib/filter.c
+++ b/lib/filter.c
@@ -576,14 +576,12 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
if (filter->addr_mask.s_addr == 0xffffffff)
vty_out(vty, " any\n");
else {
- vty_out(vty, " %s",
- inet_ntoa(filter->addr));
+ vty_out(vty, " %pI4", &filter->addr);
if (filter->addr_mask.s_addr
!= INADDR_ANY)
vty_out(vty,
- ", wildcard bits %s",
- inet_ntoa(
- filter->addr_mask));
+ ", wildcard bits %pI4",
+ &filter->addr_mask);
vty_out(vty, "\n");
}
}
@@ -625,14 +623,12 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
if (filter->addr_mask.s_addr == 0xffffffff)
vty_out(vty, " any\n");
else {
- vty_out(vty, " %s",
- inet_ntoa(filter->addr));
+ vty_out(vty, " %pI4", &filter->addr);
if (filter->addr_mask.s_addr
!= INADDR_ANY)
vty_out(vty,
- ", wildcard bits %s",
- inet_ntoa(
- filter->addr_mask));
+ ", wildcard bits %pI4",
+ &filter->addr_mask);
vty_out(vty, "\n");
}
}
@@ -722,29 +718,28 @@ static void config_write_access_cisco(struct vty *vty, struct filter *mfilter)
if (filter->addr_mask.s_addr == 0xffffffff)
vty_out(vty, " any");
else if (filter->addr_mask.s_addr == INADDR_ANY)
- vty_out(vty, " host %s", inet_ntoa(filter->addr));
+ vty_out(vty, " host %pI4", &filter->addr);
else {
- vty_out(vty, " %s", inet_ntoa(filter->addr));
- vty_out(vty, " %s", inet_ntoa(filter->addr_mask));
+ vty_out(vty, " %pI4", &filter->addr);
+ vty_out(vty, " %pI4", &filter->addr_mask);
}
if (filter->mask_mask.s_addr == 0xffffffff)
vty_out(vty, " any");
else if (filter->mask_mask.s_addr == INADDR_ANY)
- vty_out(vty, " host %s", inet_ntoa(filter->mask));
+ vty_out(vty, " host %pI4", &filter->mask);
else {
- vty_out(vty, " %s", inet_ntoa(filter->mask));
- vty_out(vty, " %s", inet_ntoa(filter->mask_mask));
+ vty_out(vty, " %pI4", &filter->mask);
+ vty_out(vty, " %pI4", &filter->mask_mask);
}
vty_out(vty, "\n");
} else {
if (filter->addr_mask.s_addr == 0xffffffff)
vty_out(vty, " any\n");
else {
- vty_out(vty, " %s", inet_ntoa(filter->addr));
+ vty_out(vty, " %pI4", &filter->addr);
if (filter->addr_mask.s_addr != INADDR_ANY)
- vty_out(vty, " %s",
- inet_ntoa(filter->addr_mask));
+ vty_out(vty, " %pI4", &filter->addr_mask);
vty_out(vty, "\n");
}
}
diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c
index da9594ed80..3f0179fbc1 100644
--- a/lib/frr_pthread.c
+++ b/lib/frr_pthread.c
@@ -28,6 +28,7 @@
#include "memory.h"
#include "linklist.h"
#include "zlog.h"
+#include "libfrr_trace.h"
DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread")
DEFINE_MTYPE_STATIC(LIB, PTHREAD_PRIM, "POSIX sync primitives")
@@ -167,6 +168,8 @@ int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr)
sigfillset(&blocksigs);
pthread_sigmask(SIG_BLOCK, &blocksigs, &oldsigs);
+ frrtrace(1, frr_libfrr, frr_pthread_run, fpt->name);
+
fpt->rcu_thread = rcu_thread_prepare();
ret = pthread_create(&fpt->thread, attr, frr_pthread_inner, fpt);
@@ -204,6 +207,8 @@ void frr_pthread_notify_running(struct frr_pthread *fpt)
int frr_pthread_stop(struct frr_pthread *fpt, void **result)
{
+ frrtrace(1, frr_libfrr, frr_pthread_stop, fpt->name);
+
int ret = (*fpt->attr.stop)(fpt, result);
memset(&fpt->thread, 0x00, sizeof(fpt->thread));
return ret;
diff --git a/lib/frr_zmq.c b/lib/frr_zmq.c
index 565936a410..cc11d76700 100644
--- a/lib/frr_zmq.c
+++ b/lib/frr_zmq.c
@@ -190,10 +190,8 @@ int funcname_frrzmq_thread_add_read(struct thread_master *master,
cb->read.cancelled = false;
if (events & ZMQ_POLLIN) {
- if (cb->read.thread) {
- thread_cancel(cb->read.thread);
- cb->read.thread = NULL;
- }
+ thread_cancel(&cb->read.thread);
+
funcname_thread_add_event(master, frrzmq_read_msg, cbp, fd,
&cb->read.thread, funcname, schedfrom,
fromln);
@@ -298,10 +296,8 @@ int funcname_frrzmq_thread_add_write(struct thread_master *master,
cb->write.cancelled = false;
if (events & ZMQ_POLLOUT) {
- if (cb->write.thread) {
- thread_cancel(cb->write.thread);
- cb->write.thread = NULL;
- }
+ thread_cancel(&cb->write.thread);
+
funcname_thread_add_event(master, frrzmq_write_msg, cbp, fd,
&cb->write.thread, funcname,
schedfrom, fromln);
@@ -317,10 +313,8 @@ void frrzmq_thread_cancel(struct frrzmq_cb **cb, struct cb_core *core)
if (!cb || !*cb)
return;
core->cancelled = true;
- if (core->thread) {
- thread_cancel(core->thread);
- core->thread = NULL;
- }
+ thread_cancel(&core->thread);
+
if ((*cb)->read.cancelled && !(*cb)->read.thread
&& (*cb)->write.cancelled && (*cb)->write.thread)
XFREE(MTYPE_ZEROMQ_CB, *cb);
@@ -344,8 +338,8 @@ void frrzmq_check_events(struct frrzmq_cb **cbp, struct cb_core *core,
return;
if (events & event && core->thread && !core->cancelled) {
struct thread_master *tm = core->thread->master;
- thread_cancel(core->thread);
- core->thread = NULL;
+ thread_cancel(&core->thread);
+
thread_add_event(tm, (event == ZMQ_POLLIN ? frrzmq_read_msg
: frrzmq_write_msg),
cbp, cb->fd, &core->thread);
diff --git a/lib/hash.c b/lib/hash.c
index 85982774ac..ed429b77d0 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -29,6 +29,7 @@
#include "command.h"
#include "libfrr.h"
#include "frr_pthread.h"
+#include "libfrr_trace.h"
DEFINE_MTYPE_STATIC(LIB, HASH, "Hash")
DEFINE_MTYPE_STATIC(LIB, HASH_BACKET, "Hash Bucket")
@@ -138,6 +139,8 @@ static void hash_expand(struct hash *hash)
void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *))
{
+ frrtrace(2, frr_libfrr, hash_get, hash, data);
+
unsigned int key;
unsigned int index;
void *newdata;
@@ -172,6 +175,8 @@ void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *))
hash->index[index] = bucket;
hash->count++;
+ frrtrace(3, frr_libfrr, hash_insert, hash, data, key);
+
int oldlen = bucket->next ? bucket->next->len : 0;
int newlen = oldlen + 1;
@@ -206,7 +211,7 @@ unsigned int string_hash_make(const char *str)
void *hash_release(struct hash *hash, void *data)
{
- void *ret;
+ void *ret = NULL;
unsigned int key;
unsigned int index;
struct hash_bucket *bucket;
@@ -236,11 +241,14 @@ void *hash_release(struct hash *hash, void *data)
ret = bucket->data;
XFREE(MTYPE_HASH_BACKET, bucket);
hash->count--;
- return ret;
+ break;
}
pp = bucket;
}
- return NULL;
+
+ frrtrace(3, frr_libfrr, hash_release, hash, data, ret);
+
+ return ret;
}
void hash_iterate(struct hash *hash, void (*func)(struct hash_bucket *, void *),
diff --git a/lib/if.c b/lib/if.c
index 304840e5b9..c707c4c6d9 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -826,7 +826,7 @@ DEFUN (show_address,
p = ifc->address;
if (p->family == AF_INET)
- vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen);
+ vty_out (vty, "%pFX\n", p);
}
}
return CMD_SUCCESS;
@@ -858,7 +858,7 @@ DEFUN (show_address_vrf_all,
p = ifc->address;
if (p->family == AF_INET)
- vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen);
+ vty_out (vty, "%pFX\n", p);
}
}
}
@@ -929,10 +929,9 @@ connected_log(struct connected *connected, char *str)
p = connected->address;
vrf = vrf_lookup_by_id(ifp->vrf_id);
- snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %s/%d ",
+ snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %pFX ",
str, ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id,
- prefix_family_str(p),
- inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
+ prefix_family_str(p), p);
p = connected->destination;
if (p) {
@@ -949,14 +948,12 @@ nbr_connected_log(struct nbr_connected *connected, char *str)
struct prefix *p;
struct interface *ifp;
char logbuf[BUFSIZ];
- char buf[BUFSIZ];
ifp = connected->ifp;
p = connected->address;
- snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %s/%d ", str,
- ifp->name, prefix_family_str(p),
- inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
+ snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %pFX ", str,
+ ifp->name, prefix_family_str(p), p);
zlog_info("%s", logbuf);
}
@@ -1109,8 +1106,8 @@ ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp)
if (rn)
{
route_unlock_node (rn);
- zlog_info ("ifaddr_ipv4_add(): address %s is already added",
- inet_ntoa (*ifaddr));
+ zlog_info("ifaddr_ipv4_add(): address %pI4 is already added",
+ ifaddr);
return;
}
rn->info = ifp;
@@ -1129,8 +1126,7 @@ ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
if (! rn)
{
- zlog_info ("ifaddr_ipv4_delete(): can't find address %s",
- inet_ntoa (*ifaddr));
+ zlog_info("%s: can't find address %pI4", __func__, ifaddr);
return;
}
rn->info = NULL;
diff --git a/lib/ldp_sync.c b/lib/ldp_sync.c
index 9657f0b1df..c9d7eb37cf 100644
--- a/lib/ldp_sync.c
+++ b/lib/ldp_sync.c
@@ -79,7 +79,7 @@ bool ldp_sync_if_down(struct ldp_sync_info *ldp_sync_info)
* update state
*/
if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) {
- THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
+ THREAD_OFF(ldp_sync_info->t_holddown);
if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_UP)
ldp_sync_info->state =
diff --git a/lib/libfrr_trace.c b/lib/libfrr_trace.c
new file mode 100644
index 0000000000..2f300e6ee1
--- /dev/null
+++ b/lib/libfrr_trace.c
@@ -0,0 +1,4 @@
+#define TRACEPOINT_CREATE_PROBES
+#define TRACEPOINT_DEFINE
+
+#include "libfrr_trace.h"
diff --git a/lib/libfrr_trace.h b/lib/libfrr_trace.h
new file mode 100644
index 0000000000..7215007ffb
--- /dev/null
+++ b/lib/libfrr_trace.h
@@ -0,0 +1,240 @@
+/* Tracing
+ *
+ * Copyright (C) 2020 NVIDIA Corporation
+ * 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
+ */
+
+#if !defined(_LIBFRR_TRACE_H_) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define _LIBFRR_TRACE_H_
+
+#include "trace.h"
+
+#ifdef HAVE_LTTNG
+
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER frr_libfrr
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./libfrr_trace.h"
+
+#include <lttng/tracepoint.h>
+
+#include "hash.h"
+#include "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "table.h"
+
+/* clang-format off */
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ hash_get,
+ TP_ARGS(struct hash *, hash, void *, data),
+ TP_FIELDS(
+ ctf_string(name, hash->name ? hash->name : "(unnamed)")
+ ctf_integer(unsigned int, index_size, hash->size)
+ ctf_integer(unsigned long, item_count, hash->count)
+ ctf_integer_hex(intptr_t, data_ptr, data)
+ )
+)
+
+TRACEPOINT_LOGLEVEL(frr_libfrr, hash_get, TRACE_INFO)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ hash_insert,
+ TP_ARGS(struct hash *, hash, void *, data, unsigned int, key),
+ TP_FIELDS(
+ ctf_string(name, hash->name ? hash->name : "(unnamed)")
+ ctf_integer(unsigned int, key, hash->size)
+ ctf_integer(unsigned int, index_size, hash->size)
+ ctf_integer(unsigned long, item_count, hash->count)
+ ctf_integer_hex(intptr_t, data_ptr, data)
+ )
+)
+
+TRACEPOINT_LOGLEVEL(frr_libfrr, hash_insert, TRACE_INFO)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ hash_release,
+ TP_ARGS(struct hash *, hash, void *, data, void *, released_item),
+ TP_FIELDS(
+ ctf_string(name, hash->name ? hash->name : "(unnamed)")
+ ctf_integer(unsigned int, index_size, hash->size)
+ ctf_integer(unsigned long, item_count, hash->count)
+ ctf_integer_hex(intptr_t, data_ptr, data)
+ ctf_integer_hex(intptr_t, released_item, data)
+ )
+)
+
+TRACEPOINT_LOGLEVEL(frr_libfrr, hash_release, TRACE_INFO)
+
+#define THREAD_SCHEDULE_ARGS \
+ TP_ARGS(struct thread_master *, master, const char *, funcname, \
+ const char *, schedfrom, int, fromln, struct thread **, \
+ thread_ptr, int, fd, int, val, void *, arg, long, time)
+
+TRACEPOINT_EVENT_CLASS(
+ frr_libfrr,
+ thread_operation,
+ THREAD_SCHEDULE_ARGS,
+ TP_FIELDS(
+ ctf_string(threadmaster_name, master->name)
+ ctf_string(function_name, funcname ? funcname : "(unknown function)")
+ ctf_string(scheduled_from, schedfrom ? schedfrom : "(unknown file)")
+ ctf_integer(int, scheduled_on_line, fromln)
+ ctf_integer_hex(intptr_t, thread_addr, thread_ptr ? *thread_ptr : NULL)
+ ctf_integer(int, file_descriptor, fd)
+ ctf_integer(int, event_value, val)
+ ctf_integer_hex(intptr_t, argument_ptr, arg)
+ ctf_integer(long, timer, time)
+ )
+)
+
+#define THREAD_OPERATION_TRACEPOINT_INSTANCE(name) \
+ TRACEPOINT_EVENT_INSTANCE(frr_libfrr, thread_operation, name, \
+ THREAD_SCHEDULE_ARGS) \
+ TRACEPOINT_LOGLEVEL(frr_libfrr, name, TRACE_INFO)
+
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_timer)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_event)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_read)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_write)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel_async)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_call)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ frr_pthread_run,
+ TP_ARGS(
+ char *, name
+ ),
+ TP_FIELDS(
+ ctf_string(frr_pthread_name, name)
+ )
+)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ frr_pthread_stop,
+ TP_ARGS(
+ char *, name
+ ),
+ TP_FIELDS(
+ ctf_string(frr_pthread_name, name)
+ )
+)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ memalloc,
+ TP_ARGS(
+ struct memtype *, mt, void *, ptr, size_t, size
+ ),
+ TP_FIELDS(
+ ctf_string(memtype, mt->name)
+ ctf_integer(size_t, size, size)
+ ctf_integer_hex(intptr_t, ptr, ptr)
+ )
+)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ memfree,
+ TP_ARGS(
+ struct memtype *, mt, void *, ptr
+ ),
+ TP_FIELDS(
+ ctf_string(memtype, mt->name)
+ ctf_integer_hex(intptr_t, ptr, ptr)
+ )
+)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ list_add,
+ TP_ARGS(
+ struct list *, list, const void *, ptr
+ ),
+ TP_FIELDS(
+ ctf_integer_hex(intptr_t, list, list)
+ ctf_integer(unsigned int, count, list->count)
+ ctf_integer_hex(intptr_t, ptr, ptr)
+ )
+)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ list_remove,
+ TP_ARGS(
+ struct list *, list, const void *, ptr
+ ),
+ TP_FIELDS(
+ ctf_integer_hex(intptr_t, list, list)
+ ctf_integer(unsigned int, count, list->count)
+ ctf_integer_hex(intptr_t, ptr, ptr)
+ )
+)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ list_delete_node,
+ TP_ARGS(
+ struct list *, list, const void *, node
+ ),
+ TP_FIELDS(
+ ctf_integer_hex(intptr_t, list, list)
+ ctf_integer(unsigned int, count, list->count)
+ ctf_integer_hex(intptr_t, node, node)
+ )
+)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ list_sort,
+ TP_ARGS(
+ struct list *, list
+ ),
+ TP_FIELDS(
+ ctf_integer_hex(intptr_t, list, list)
+ ctf_integer(unsigned int, count, list->count)
+ )
+)
+
+TRACEPOINT_EVENT(
+ frr_libfrr,
+ route_node_get,
+ TP_ARGS(
+ struct route_table *, table, char *, prefix
+ ),
+ TP_FIELDS(
+ ctf_integer_hex(intptr_t, table, table)
+ ctf_string(prefix, prefix)
+ )
+)
+
+/* clang-format on */
+
+#include <lttng/tracepoint-event.h>
+#include <lttng/tracelog.h>
+
+#endif /* HAVE_LTTNG */
+
+#endif /* _LIBFRR_TRACE_H_ */
diff --git a/lib/linklist.c b/lib/linklist.c
index 84dc6e1419..43c2002231 100644
--- a/lib/linklist.c
+++ b/lib/linklist.c
@@ -23,6 +23,7 @@
#include "linklist.h"
#include "memory.h"
+#include "libfrr_trace.h"
DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List")
DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node")
@@ -66,6 +67,8 @@ static void listnode_free(struct list *list, struct listnode *node)
struct listnode *listnode_add(struct list *list, void *val)
{
+ frrtrace(2, frr_libfrr, list_add, list, val);
+
struct listnode *node;
assert(val != NULL);
@@ -281,6 +284,8 @@ void listnode_move_to_tail(struct list *l, struct listnode *n)
void listnode_delete(struct list *list, const void *val)
{
+ frrtrace(2, frr_libfrr, list_remove, list, val);
+
struct listnode *node = listnode_lookup(list, val);
if (node)
@@ -360,6 +365,8 @@ struct listnode *listnode_lookup_nocheck(struct list *list, void *data)
void list_delete_node(struct list *list, struct listnode *node)
{
+ frrtrace(2, frr_libfrr, list_delete_node, list, node);
+
if (node->prev)
node->prev->next = node->next;
else
@@ -374,6 +381,8 @@ void list_delete_node(struct list *list, struct listnode *node)
void list_sort(struct list *list, int (*cmp)(const void **, const void **))
{
+ frrtrace(1, frr_libfrr, list_sort, list);
+
struct listnode *ln, *nn;
int i = -1;
void *data;
diff --git a/lib/memory.c b/lib/memory.c
index 2c902d123b..f715044ea3 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -29,6 +29,7 @@
#include "memory.h"
#include "log.h"
+#include "libfrr_trace.h"
static struct memgroup *mg_first = NULL;
struct memgroup **mg_insert = &mg_first;
@@ -77,6 +78,8 @@ static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr)
static inline void mt_count_free(struct memtype *mt, void *ptr)
{
+ frrtrace(2, frr_libfrr, memfree, mt, ptr);
+
assert(mt->n_alloc);
atomic_fetch_sub_explicit(&mt->n_alloc, 1, memory_order_relaxed);
@@ -89,6 +92,8 @@ static inline void mt_count_free(struct memtype *mt, void *ptr)
static inline void *mt_checkalloc(struct memtype *mt, void *ptr, size_t size)
{
+ frrtrace(3, frr_libfrr, memalloc, mt, ptr, size);
+
if (__builtin_expect(ptr == NULL, 0)) {
if (size) {
/* malloc(0) is allowed to return NULL */
diff --git a/lib/nexthop.c b/lib/nexthop.c
index f1575649b1..b2fa945690 100644
--- a/lib/nexthop.c
+++ b/lib/nexthop.c
@@ -431,13 +431,13 @@ const char *nexthop2str(const struct nexthop *nexthop, char *str, int size)
break;
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
- snprintf(str, size, "%s if %u", inet_ntoa(nexthop->gate.ipv4),
- nexthop->ifindex);
+ snprintfrr(str, size, "%pI4 if %u", &nexthop->gate.ipv4,
+ nexthop->ifindex);
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
- snprintf(str, size, "%s if %u", inet6_ntoa(nexthop->gate.ipv6),
- nexthop->ifindex);
+ snprintfrr(str, size, "%pI6 if %u", &nexthop->gate.ipv6,
+ nexthop->ifindex);
break;
case NEXTHOP_TYPE_BLACKHOLE:
snprintf(str, size, "blackhole");
diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c
index 4afb1d642a..dee98ad8d7 100644
--- a/lib/nexthop_group.c
+++ b/lib/nexthop_group.c
@@ -975,7 +975,6 @@ void nexthop_group_write_nexthop_simple(struct vty *vty,
const struct nexthop *nh,
char *altifname)
{
- char buf[100];
char *ifname;
vty_out(vty, "nexthop ");
@@ -990,19 +989,16 @@ void nexthop_group_write_nexthop_simple(struct vty *vty,
vty_out(vty, "%s", ifname);
break;
case NEXTHOP_TYPE_IPV4:
- vty_out(vty, "%s", inet_ntoa(nh->gate.ipv4));
+ vty_out(vty, "%pI4", &nh->gate.ipv4);
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
- vty_out(vty, "%s %s", inet_ntoa(nh->gate.ipv4), ifname);
+ vty_out(vty, "%pI4 %s", &nh->gate.ipv4, ifname);
break;
case NEXTHOP_TYPE_IPV6:
- vty_out(vty, "%s",
- inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf)));
+ vty_out(vty, "%pI6", &nh->gate.ipv6);
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
- vty_out(vty, "%s %s",
- inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf)),
- ifname);
+ vty_out(vty, "%pI6 %s", &nh->gate.ipv6, ifname);
break;
case NEXTHOP_TYPE_BLACKHOLE:
break;
@@ -1056,10 +1052,14 @@ void nexthop_group_json_nexthop(json_object *j, const struct nexthop *nh)
ifindex2ifname(nh->ifindex, nh->vrf_id));
break;
case NEXTHOP_TYPE_IPV4:
- json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4));
+ json_object_string_add(
+ j, "nexthop",
+ inet_ntop(AF_INET, &nh->gate.ipv4, buf, sizeof(buf)));
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
- json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4));
+ json_object_string_add(
+ j, "nexthop",
+ inet_ntop(AF_INET, &nh->gate.ipv4, buf, sizeof(buf)));
json_object_string_add(j, "vrfId",
ifindex2ifname(nh->ifindex, nh->vrf_id));
break;
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c
index a7f3a1b305..7048df99fb 100644
--- a/lib/northbound_cli.c
+++ b/lib/northbound_cli.c
@@ -89,7 +89,7 @@ static int nb_cli_classic_commit(struct vty *vty)
static void nb_cli_pending_commit_clear(struct vty *vty)
{
- THREAD_TIMER_OFF(vty->t_pending_commit);
+ THREAD_OFF(vty->t_pending_commit);
vty->backoff_cmd_count = 0;
XFREE(MTYPE_TMP, vty->pending_cmds_buf);
vty->pending_cmds_buflen = 0;
@@ -154,7 +154,7 @@ static int nb_cli_schedule_command(struct vty *vty)
vty->pending_cmds_buflen);
/* Schedule the commit operation. */
- THREAD_TIMER_OFF(vty->t_pending_commit);
+ THREAD_OFF(vty->t_pending_commit);
thread_add_timer_msec(master, nb_cli_pending_commit_cb, vty, 100,
&vty->t_pending_commit);
@@ -312,7 +312,7 @@ int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input,
void nb_cli_confirmed_commit_clean(struct vty *vty)
{
- THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout);
+ thread_cancel(&vty->t_confirmed_commit_timeout);
nb_config_free(vty->confirmed_commit_rollback);
vty->confirmed_commit_rollback = NULL;
}
@@ -377,7 +377,7 @@ static int nb_cli_commit(struct vty *vty, bool force,
"%% Resetting confirmed-commit timeout to %u minute(s)\n\n",
confirmed_timeout);
- THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout);
+ thread_cancel(&vty->t_confirmed_commit_timeout);
thread_add_timer(master,
nb_cli_confirmed_commit_timeout, vty,
confirmed_timeout * 60,
diff --git a/lib/plist.c b/lib/plist.c
index 981e86e2ac..4588dfe1d3 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -901,14 +901,11 @@ static void __attribute__((unused)) prefix_list_print(struct prefix_list *plist)
printf("any %s\n", prefix_list_type_str(pentry));
else {
struct prefix *p;
- char buf[BUFSIZ];
p = &pentry->prefix;
- printf(" seq %lld %s %s/%d", (long long)pentry->seq,
- prefix_list_type_str(pentry),
- inet_ntop(p->family, p->u.val, buf, BUFSIZ),
- p->prefixlen);
+ printf(" seq %lld %s %pFX", (long long)pentry->seq,
+ prefix_list_type_str(pentry), p);
if (pentry->ge)
printf(" ge %d", pentry->ge);
if (pentry->le)
@@ -1014,12 +1011,8 @@ static void vty_show_prefix_entry(struct vty *vty, afi_t afi,
vty_out(vty, "any");
else {
struct prefix *p = &pentry->prefix;
- char buf[BUFSIZ];
- vty_out(vty, "%s/%d",
- inet_ntop(p->family, p->u.val, buf,
- BUFSIZ),
- p->prefixlen);
+ vty_out(vty, "%pFX", p);
if (pentry->ge)
vty_out(vty, " ge %d", pentry->ge);
@@ -1121,12 +1114,8 @@ static int vty_show_prefix_list_prefix(struct vty *vty, afi_t afi,
vty_out(vty, "any");
else {
struct prefix *pf = &pentry->prefix;
- char buf[BUFSIZ];
- vty_out(vty, "%s/%d",
- inet_ntop(pf->family, pf->u.val, buf,
- BUFSIZ),
- pf->prefixlen);
+ vty_out(vty, "%pFX", pf);
if (pentry->ge)
vty_out(vty, " ge %d", pentry->ge);
@@ -1491,11 +1480,8 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
for (pentry = plist->head; pentry; pentry = pentry->next) {
struct prefix *p = &pentry->prefix;
char buf_a[BUFSIZ];
- char buf_b[BUFSIZ];
- snprintf(buf_a, sizeof(buf_a), "%s/%d",
- inet_ntop(p->family, p->u.val, buf_b, BUFSIZ),
- p->prefixlen);
+ snprintf(buf_a, sizeof(buf_a), "%pFX", p);
json_object_int_add(json_list, "seq", pentry->seq);
json_object_string_add(json_list, "seqPrefixListType",
@@ -1526,13 +1512,9 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
for (pentry = plist->head; pentry; pentry = pentry->next) {
struct prefix *p = &pentry->prefix;
- char buf[BUFSIZ];
- vty_out(vty, " seq %" PRId64 " %s %s/%d",
- pentry->seq,
- prefix_list_type_str(pentry),
- inet_ntop(p->family, p->u.val, buf, BUFSIZ),
- p->prefixlen);
+ vty_out(vty, " seq %" PRId64 " %s %pFX", pentry->seq,
+ prefix_list_type_str(pentry), p);
if (pentry->ge)
vty_out(vty, " ge %d", pentry->ge);
diff --git a/lib/routemap.c b/lib/routemap.c
index fb70860024..0eb54a4794 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -2377,7 +2377,6 @@ route_map_result_t route_map_apply(struct route_map *map,
route_map_result_t ret = RMAP_PERMITMATCH;
struct route_map_index *index = NULL;
struct route_map_rule *set = NULL;
- char buf[PREFIX_STRLEN];
bool skip_match_clause = false;
if (recursion > RMAP_RECURSION_LIMIT) {
@@ -2403,16 +2402,14 @@ route_map_result_t route_map_apply(struct route_map *map,
if (index) {
if (rmap_debug)
zlog_debug(
- "Best match route-map: %s, sequence: %d for pfx: %s, result: %s",
- map->name, index->pref,
- prefix2str(prefix, buf, sizeof(buf)),
+ "Best match route-map: %s, sequence: %d for pfx: %pFX, result: %s",
+ map->name, index->pref, prefix,
route_map_cmd_result_str(match_ret));
} else {
if (rmap_debug)
zlog_debug(
- "No best match sequence for pfx: %s in route-map: %s, result: %s",
- prefix2str(prefix, buf, sizeof(buf)),
- map->name,
+ "No best match sequence for pfx: %pFX in route-map: %s, result: %s",
+ prefix, map->name,
route_map_cmd_result_str(match_ret));
/*
* No index matches this prefix. Return deny unless,
@@ -2437,9 +2434,8 @@ route_map_result_t route_map_apply(struct route_map *map,
prefix, type, object);
if (rmap_debug) {
zlog_debug(
- "Route-map: %s, sequence: %d, prefix: %s, result: %s",
- map->name, index->pref,
- prefix2str(prefix, buf, sizeof(buf)),
+ "Route-map: %s, sequence: %d, prefix: %pFX, result: %s",
+ map->name, index->pref, prefix,
route_map_cmd_result_str(match_ret));
}
} else
@@ -2549,12 +2545,10 @@ route_map_result_t route_map_apply(struct route_map *map,
}
route_map_apply_end:
- if (rmap_debug) {
- zlog_debug("Route-map: %s, prefix: %s, result: %s",
- (map ? map->name : "null"),
- prefix2str(prefix, buf, sizeof(buf)),
+ if (rmap_debug)
+ zlog_debug("Route-map: %s, prefix: %pFX, result: %s",
+ (map ? map->name : "null"), prefix,
route_map_result_str(ret));
- }
return (ret);
}
@@ -3156,8 +3150,6 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd,
struct list *rmap_index_list = NULL;
struct listnode *ln = NULL, *nln = NULL;
struct route_map_index *index = NULL;
- struct prefix *p = NULL, *pp = NULL;
- char buf[SU_ADDRSTRLEN], pbuf[SU_ADDRSTRLEN];
uint8_t len = 54;
vty_out(vty, "%s:\n", frr_protonameinst);
@@ -3171,22 +3163,13 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd,
"____________________");
for (rn = route_top(rm_pfx_tbl4); rn;
rn = route_next(rn)) {
- p = &rn->p;
-
- vty_out(vty, " %s/%d (%d)\n",
- inet_ntop(p->family, &p->u.prefix, buf,
- SU_ADDRSTRLEN),
- p->prefixlen, rn->lock);
+ vty_out(vty, " %pRN (%d)\n", rn,
+ route_node_get_lock_count(rn));
vty_out(vty, "(P) ");
prn = rn->parent;
if (prn) {
- pp = &prn->p;
- vty_out(vty, "%s/%d\n",
- inet_ntop(pp->family,
- &pp->u.prefix, pbuf,
- SU_ADDRSTRLEN),
- pp->prefixlen);
+ vty_out(vty, "%pRN\n", prn);
}
vty_out(vty, "\n");
@@ -3215,22 +3198,13 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd,
"____________________");
for (rn = route_top(rm_pfx_tbl6); rn;
rn = route_next(rn)) {
- p = &rn->p;
-
- vty_out(vty, " %s/%d (%d)\n",
- inet_ntop(p->family, &p->u.prefix, buf,
- SU_ADDRSTRLEN),
- p->prefixlen, rn->lock);
+ vty_out(vty, " %pRN (%d)\n", rn,
+ route_node_get_lock_count(rn));
vty_out(vty, "(P) ");
prn = rn->parent;
if (prn) {
- pp = &prn->p;
- vty_out(vty, "%s/%d\n",
- inet_ntop(pp->family,
- &pp->u.prefix, pbuf,
- SU_ADDRSTRLEN),
- pp->prefixlen);
+ vty_out(vty, "%pRN\n", prn);
}
vty_out(vty, "\n");
diff --git a/lib/sockunion.c b/lib/sockunion.c
index d77229797c..c999845659 100644
--- a/lib/sockunion.c
+++ b/lib/sockunion.c
@@ -587,15 +587,11 @@ static void __attribute__((unused)) sockunion_print(const union sockunion *su)
switch (su->sa.sa_family) {
case AF_INET:
- printf("%s\n", inet_ntoa(su->sin.sin_addr));
+ printf("%pI4\n", &su->sin.sin_addr);
+ break;
+ case AF_INET6:
+ printf("%pI6\n", &su->sin6.sin6_addr);
break;
- case AF_INET6: {
- char buf[SU_ADDRSTRLEN];
-
- printf("%s\n", inet_ntop(AF_INET6, &(su->sin6.sin6_addr), buf,
- sizeof(buf)));
- } break;
-
#ifdef AF_LINK
case AF_LINK: {
struct sockaddr_dl *sdl;
diff --git a/lib/spf_backoff.c b/lib/spf_backoff.c
index acb208e5e7..ac6dd29f06 100644
--- a/lib/spf_backoff.c
+++ b/lib/spf_backoff.c
@@ -110,8 +110,8 @@ void spf_backoff_free(struct spf_backoff *backoff)
if (!backoff)
return;
- THREAD_TIMER_OFF(backoff->t_holddown);
- THREAD_TIMER_OFF(backoff->t_timetolearn);
+ thread_cancel(&backoff->t_holddown);
+ thread_cancel(&backoff->t_timetolearn);
XFREE(MTYPE_SPF_BACKOFF_NAME, backoff->name);
XFREE(MTYPE_SPF_BACKOFF, backoff);
@@ -121,7 +121,6 @@ static int spf_backoff_timetolearn_elapsed(struct thread *thread)
{
struct spf_backoff *backoff = THREAD_ARG(thread);
- backoff->t_timetolearn = NULL;
backoff->state = SPF_BACKOFF_LONG_WAIT;
backoff_debug("SPF Back-off(%s) TIMETOLEARN elapsed, move to state %s",
backoff->name, spf_backoff_state2str(backoff->state));
@@ -132,7 +131,7 @@ static int spf_backoff_holddown_elapsed(struct thread *thread)
{
struct spf_backoff *backoff = THREAD_ARG(thread);
- THREAD_TIMER_OFF(backoff->t_timetolearn);
+ THREAD_OFF(backoff->t_timetolearn);
timerclear(&backoff->first_event_time);
backoff->state = SPF_BACKOFF_QUIET;
backoff_debug("SPF Back-off(%s) HOLDDOWN elapsed, move to state %s",
@@ -166,7 +165,7 @@ long spf_backoff_schedule(struct spf_backoff *backoff)
break;
case SPF_BACKOFF_SHORT_WAIT:
case SPF_BACKOFF_LONG_WAIT:
- THREAD_TIMER_OFF(backoff->t_holddown);
+ thread_cancel(&backoff->t_holddown);
thread_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed,
backoff, backoff->holddown,
&backoff->t_holddown);
diff --git a/lib/subdir.am b/lib/subdir.am
index 55f127b019..ed3c30799d 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -3,7 +3,7 @@
#
lib_LTLIBRARIES += lib/libfrr.la
lib_libfrr_la_LDFLAGS = -version-info 0:0:0 -Xlinker -e_libfrr_version
-lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(LIBM)
+lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(UST_LIBS) $(LIBM)
lib_libfrr_la_SOURCES = \
lib/agg_table.c \
@@ -46,6 +46,7 @@ lib_libfrr_la_SOURCES = \
lib/lib_errors.c \
lib/lib_vty.c \
lib/libfrr.c \
+ lib/libfrr_trace.c \
lib/linklist.c \
lib/log.c \
lib/log_filter.c \
@@ -204,6 +205,7 @@ pkginclude_HEADERS += \
lib/lib_errors.h \
lib/lib_vty.h \
lib/libfrr.h \
+ lib/libfrr_trace.h \
lib/libospf.h \
lib/linklist.h \
lib/log.h \
@@ -251,6 +253,7 @@ pkginclude_HEADERS += \
lib/table.h \
lib/termtable.h \
lib/thread.h \
+ lib/trace.h \
lib/typerb.h \
lib/typesafe.h \
lib/vector.h \
@@ -401,7 +404,7 @@ lib_grammar_sandbox_LDADD = \
lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY
lib_clippy_CFLAGS = $(PYTHON_CFLAGS)
-lib_clippy_LDADD = $(PYTHON_LIBS)
+lib_clippy_LDADD = $(PYTHON_LIBS) $(UST_LIBS)
lib_clippy_LDFLAGS = -export-dynamic
lib_clippy_SOURCES = \
lib/clippy.c \
@@ -411,6 +414,7 @@ lib_clippy_SOURCES = \
lib/command_py.c \
lib/defun_lex.l \
lib/graph.c \
+ lib/libfrr_trace.c \
lib/memory.c \
lib/vector.c \
# end
diff --git a/lib/table.c b/lib/table.c
index 86347cbacd..89e32182b5 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -27,6 +27,7 @@
#include "table.h"
#include "memory.h"
#include "sockunion.h"
+#include "libfrr_trace.h"
DEFINE_MTYPE_STATIC(LIB, ROUTE_TABLE, "Route table")
DEFINE_MTYPE(LIB, ROUTE_NODE, "Route node")
@@ -119,7 +120,8 @@ static void route_table_free(struct route_table *rt)
node = node->parent;
tmp_node->table->count--;
- tmp_node->lock = 0; /* to cause assert if unlocked after this */
+ tmp_node->lock =
+ 0; /* to cause assert if unlocked after this */
rn_hash_node_del(&rt->hash, tmp_node);
route_node_free(rt, tmp_node);
@@ -275,6 +277,12 @@ struct route_node *route_node_lookup_maynull(struct route_table *table,
struct route_node *route_node_get(struct route_table *table,
union prefixconstptr pu)
{
+ if (frrtrace_enabled(frr_libfrr, route_node_get)) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(pu, buf, sizeof(buf));
+ frrtrace(2, frr_libfrr, route_node_get, table, buf);
+ }
+
struct route_node search;
struct prefix *p = &search.p;
diff --git a/lib/table.h b/lib/table.h
index 9cd9503376..5d620d332b 100644
--- a/lib/table.h
+++ b/lib/table.h
@@ -262,6 +262,11 @@ static inline void route_unlock_node(struct route_node *node)
route_node_delete(node);
}
+static inline unsigned int route_node_get_lock_count(struct route_node *node)
+{
+ return node->lock;
+}
+
/*
* route_table_iter_next
*
diff --git a/lib/thread.c b/lib/thread.c
index db35a3f031..1765de9573 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -35,6 +35,7 @@
#include "frratomic.h"
#include "frr_pthread.h"
#include "lib_errors.h"
+#include "libfrr_trace.h"
DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread")
DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master")
@@ -787,6 +788,13 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m,
struct thread *thread = NULL;
struct thread **thread_array;
+ if (dir == THREAD_READ)
+ frrtrace(9, frr_libfrr, schedule_read, m, funcname, schedfrom,
+ fromln, t_ptr, fd, 0, arg, 0);
+ else
+ frrtrace(9, frr_libfrr, schedule_write, m, funcname, schedfrom,
+ fromln, t_ptr, fd, 0, arg, 0);
+
assert(fd >= 0 && fd < m->fd_limit);
frr_with_mutex(&m->mtx) {
if (t_ptr && *t_ptr)
@@ -861,6 +869,9 @@ funcname_thread_add_timer_timeval(struct thread_master *m,
assert(type == THREAD_TIMER);
assert(time_relative);
+ frrtrace(9, frr_libfrr, schedule_timer, m, funcname, schedfrom, fromln,
+ t_ptr, 0, 0, arg, (long)time_relative->tv_sec);
+
frr_with_mutex(&m->mtx) {
if (t_ptr && *t_ptr)
/* thread is already scheduled; don't reschedule */
@@ -939,6 +950,9 @@ struct thread *funcname_thread_add_event(struct thread_master *m,
{
struct thread *thread = NULL;
+ frrtrace(9, frr_libfrr, schedule_event, m, funcname, schedfrom, fromln,
+ t_ptr, 0, val, arg, 0);
+
assert(m != NULL);
frr_with_mutex(&m->mtx) {
@@ -1163,19 +1177,30 @@ void thread_cancel_event(struct thread_master *master, void *arg)
*
* @param thread task to cancel
*/
-void thread_cancel(struct thread *thread)
+void thread_cancel(struct thread **thread)
{
- struct thread_master *master = thread->master;
+ struct thread_master *master;
+
+ if (thread == NULL || *thread == NULL)
+ return;
+
+ master = (*thread)->master;
+
+ frrtrace(9, frr_libfrr, thread_cancel, master, thread->funcname,
+ thread->schedfrom, thread->schedfrom_line, NULL, thread->u.fd,
+ thread->u.val, thread->arg, thread->u.sands.tv_sec);
assert(master->owner == pthread_self());
frr_with_mutex(&master->mtx) {
struct cancel_req *cr =
XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
- cr->thread = thread;
+ cr->thread = *thread;
listnode_add(master->cancel_req, cr);
do_thread_cancel(master);
}
+
+ *thread = NULL;
}
/**
@@ -1206,6 +1231,17 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread,
void *eventobj)
{
assert(!(thread && eventobj) && (thread || eventobj));
+
+ if (thread && *thread)
+ frrtrace(9, frr_libfrr, thread_cancel_async, master,
+ (*thread)->funcname, (*thread)->schedfrom,
+ (*thread)->schedfrom_line, NULL, (*thread)->u.fd,
+ (*thread)->u.val, (*thread)->arg,
+ (*thread)->u.sands.tv_sec);
+ else
+ frrtrace(9, frr_libfrr, thread_cancel_async, master, NULL, NULL,
+ 0, NULL, 0, 0, eventobj, 0);
+
assert(master->owner != pthread_self());
frr_with_mutex(&master->mtx) {
@@ -1227,6 +1263,9 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread,
while (!master->canceled)
pthread_cond_wait(&master->cancel_cond, &master->mtx);
}
+
+ if (thread)
+ *thread = NULL;
}
/* ------------------------------------------------------------------------- */
@@ -1581,6 +1620,10 @@ void thread_call(struct thread *thread)
GETRUSAGE(&before);
thread->real = before.real;
+ frrtrace(9, frr_libfrr, thread_call, thread->master, thread->funcname,
+ thread->schedfrom, thread->schedfrom_line, NULL, thread->u.fd,
+ thread->u.val, thread->arg, thread->u.sands.tv_sec);
+
pthread_setspecific(thread_current, thread);
(*thread->func)(thread);
pthread_setspecific(thread_current, NULL);
diff --git a/lib/thread.h b/lib/thread.h
index c22b2105cd..e2b7763c51 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -147,18 +147,15 @@ struct cpu_thread_history {
#define THREAD_FD(X) ((X)->u.fd)
#define THREAD_VAL(X) ((X)->u.val)
-#define THREAD_OFF(thread) \
- do { \
- if (thread) { \
- thread_cancel(thread); \
- thread = NULL; \
- } \
+/*
+ * Please consider this macro deprecated, and do not use it in new code.
+ */
+#define THREAD_OFF(thread) \
+ do { \
+ if ((thread)) \
+ thread_cancel(&(thread)); \
} while (0)
-#define THREAD_READ_OFF(thread) THREAD_OFF(thread)
-#define THREAD_WRITE_OFF(thread) THREAD_OFF(thread)
-#define THREAD_TIMER_OFF(thread) THREAD_OFF(thread)
-
#define debugargdef const char *funcname, const char *schedfrom, int fromln
#define thread_add_read(m,f,a,v,t) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,t,#f,__FILE__,__LINE__)
@@ -207,7 +204,7 @@ extern void funcname_thread_execute(struct thread_master *,
debugargdef);
#undef debugargdef
-extern void thread_cancel(struct thread *);
+extern void thread_cancel(struct thread **event);
extern void thread_cancel_async(struct thread_master *, struct thread **,
void *);
extern void thread_cancel_event(struct thread_master *, void *);
diff --git a/lib/trace.h b/lib/trace.h
new file mode 100644
index 0000000000..73fc10a556
--- /dev/null
+++ b/lib/trace.h
@@ -0,0 +1,80 @@
+/* Tracing macros
+ *
+ * Wraps tracepoint macros for different tracing systems to allow switching
+ * between them at compile time.
+ *
+ * This should not be included directly by source files wishing to provide
+ * tracepoints. Instead, write a header that defines LTTng tracepoints and
+ * which includes this header, and include your new header in your source. USDT
+ * probes do not need tracepoint definitions, but are less capable than LTTng
+ * tracepoints.
+ *
+ * Copyright (C) 2020 NVIDIA Corporation
+ * 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 _TRACE_H_
+#define _TRACE_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+/*
+ * Provided here:
+ * - frrtrace(n, provider, name, ...args...)
+ * - frrtrace_enabled(provider, name)
+ * - frrtracelog(level, msg, ...)
+ *
+ * Use frrtrace() to define tracepoints. n is the number of arguments; this is
+ * needed because USDT probe definitions use DTRACE_PROBEn macros, so the
+ * number of args must be passed in order to expand the correct macro.
+ *
+ * frrtrace_enabled() maps to tracepoint_enabled() under LTTng and is always
+ * true when using USDT. In the future it could be mapped to USDT semaphores
+ * but this is not implemented at present.
+ *
+ * frrtracelog() maps to tracelog() under LTTng and should only be used in zlog
+ * core code, to propagate zlog messages to LTTng. It expands to nothing
+ * otherwise.
+ */
+
+#if defined(HAVE_LTTNG)
+
+#define frrtrace(nargs, provider, name, ...) \
+ tracepoint(provider, name, ## __VA_ARGS__)
+#define frrtrace_enabled(...) tracepoint_enabled(__VA_ARGS__)
+#define frrtracelog(...) tracelog(__VA_ARGS__)
+
+#elif defined(HAVE_USDT)
+
+#include "sys/sdt.h"
+
+#define frrtrace(nargs, provider, name, ...) \
+ DTRACE_PROBE##nargs(provider, name, ## __VA_ARGS__)
+#define frrtrace_enabled(...) true
+#define frrtracelog(...)
+
+#else
+
+#define frrtrace(nargs, provider, name, ...) (void)0
+#define frrtrace_enabled(...) false
+#define frrtracelog(...) (void)0
+
+#endif
+
+#endif /* _TRACE_H_ */
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 54090d0d0f..f8e4677220 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -104,7 +104,7 @@ void work_queue_free_and_null(struct work_queue **wqp)
struct work_queue *wq = *wqp;
if (wq->thread != NULL)
- thread_cancel(wq->thread);
+ thread_cancel(&(wq->thread));
while (!work_queue_empty(wq)) {
struct work_queue_item *item = work_queue_last_item(wq);
@@ -215,7 +215,7 @@ void workqueue_cmd_init(void)
void work_queue_plug(struct work_queue *wq)
{
if (wq->thread)
- thread_cancel(wq->thread);
+ thread_cancel(&(wq->thread));
wq->thread = NULL;
diff --git a/lib/zassert.h b/lib/zassert.h
index e50a88f407..e6b254ee8d 100644
--- a/lib/zassert.h
+++ b/lib/zassert.h
@@ -27,6 +27,8 @@ extern void _zlog_assert_failed(const char *assertion, const char *file,
unsigned int line, const char *function)
__attribute__((noreturn));
+#undef __ASSERT_FUNCTION
+
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define __ASSERT_FUNCTION __func__
#elif defined(__GNUC__)
diff --git a/lib/zclient.c b/lib/zclient.c
index 914b02749e..d0144279e5 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1116,13 +1116,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
/* limit the number of nexthops if necessary */
if (api->nexthop_num > MULTIPATH_NUM) {
- char buf[PREFIX2STR_BUFFER];
-
- prefix2str(&api->prefix, buf, sizeof(buf));
flog_err(
EC_LIB_ZAPI_ENCODE,
- "%s: prefix %s: can't encode %u nexthops (maximum is %u)",
- __func__, buf, api->nexthop_num, MULTIPATH_NUM);
+ "%s: prefix %pFX: can't encode %u nexthops (maximum is %u)",
+ __func__, &api->prefix, api->nexthop_num,
+ MULTIPATH_NUM);
return -1;
}
@@ -1139,15 +1137,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
/* MPLS labels for BGP-LU or Segment Routing */
if (api_nh->label_num > MPLS_MAX_LABELS) {
- char buf[PREFIX2STR_BUFFER];
-
- prefix2str(&api->prefix, buf, sizeof(buf));
-
- flog_err(EC_LIB_ZAPI_ENCODE,
- "%s: prefix %s: can't encode %u labels (maximum is %u)",
- __func__, buf,
- api_nh->label_num,
- MPLS_MAX_LABELS);
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
+ "%s: prefix %pFX: can't encode %u labels (maximum is %u)",
+ __func__, &api->prefix,
+ api_nh->label_num, MPLS_MAX_LABELS);
return -1;
}
@@ -1162,13 +1156,10 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
/* limit the number of nexthops if necessary */
if (api->backup_nexthop_num > MULTIPATH_NUM) {
- char buf[PREFIX2STR_BUFFER];
-
- prefix2str(&api->prefix, buf, sizeof(buf));
flog_err(
EC_LIB_ZAPI_ENCODE,
- "%s: prefix %s: can't encode %u backup nexthops (maximum is %u)",
- __func__, buf, api->backup_nexthop_num,
+ "%s: prefix %pFX: can't encode %u backup nexthops (maximum is %u)",
+ __func__, &api->prefix, api->backup_nexthop_num,
MULTIPATH_NUM);
return -1;
}
@@ -1185,15 +1176,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
/* MPLS labels for BGP-LU or Segment Routing */
if (api_nh->label_num > MPLS_MAX_LABELS) {
- char buf[PREFIX2STR_BUFFER];
-
- prefix2str(&api->prefix, buf, sizeof(buf));
-
- flog_err(EC_LIB_ZAPI_ENCODE,
- "%s: prefix %s: backup: can't encode %u labels (maximum is %u)",
- __func__, buf,
- api_nh->label_num,
- MPLS_MAX_LABELS);
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
+ "%s: prefix %pFX: backup: can't encode %u labels (maximum is %u)",
+ __func__, &api->prefix,
+ api_nh->label_num, MPLS_MAX_LABELS);
return -1;
}
@@ -2319,13 +2306,10 @@ struct connected *zebra_interface_address_read(int type, struct stream *s,
else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
/* carp interfaces on OpenBSD with 0.0.0.0/0 as
* "peer" */
- char buf[PREFIX_STRLEN];
flog_err(
EC_LIB_ZAPI_ENCODE,
- "warning: interface %s address %s with peer flag set, but no peer address!",
- ifp->name,
- prefix2str(ifc->address, buf,
- sizeof(buf)));
+ "warning: interface %s address %pFX with peer flag set, but no peer address!",
+ ifp->name, ifc->address);
UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
}
}
diff --git a/lib/zlog.c b/lib/zlog.c
index 8dfd20371b..e77feec5f2 100644
--- a/lib/zlog.c
+++ b/lib/zlog.c
@@ -52,6 +52,7 @@
#include "printfrr.h"
#include "frrcu.h"
#include "zlog.h"
+#include "libfrr_trace.h"
DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE, "log message")
DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF, "log thread-local buffer")
@@ -450,6 +451,34 @@ void vzlog(int prio, const char *fmt, va_list ap)
{
struct zlog_tls *zlog_tls = zlog_tls_get();
+#ifdef HAVE_LTTNG
+ va_list copy;
+ va_copy(copy, ap);
+ char *msg = vasprintfrr(MTYPE_LOG_MESSAGE, fmt, copy);
+
+ switch (prio) {
+ case LOG_ERR:
+ frrtracelog(TRACE_ERR, msg);
+ break;
+ case LOG_WARNING:
+ frrtracelog(TRACE_WARNING, msg);
+ break;
+ case LOG_DEBUG:
+ frrtracelog(TRACE_DEBUG, msg);
+ break;
+ case LOG_NOTICE:
+ frrtracelog(TRACE_DEBUG, msg);
+ break;
+ case LOG_INFO:
+ default:
+ frrtracelog(TRACE_INFO, msg);
+ break;
+ }
+
+ va_end(copy);
+ XFREE(MTYPE_LOG_MESSAGE, msg);
+#endif
+
if (zlog_tls)
vzlog_tls(zlog_tls, prio, fmt, ap);
else