summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/agg_table.c59
-rw-r--r--lib/agg_table.h153
-rw-r--r--lib/bfd.c6
-rw-r--r--lib/bfd.h4
-rw-r--r--lib/ferr.c2
-rw-r--r--lib/frr_pthread.c42
-rw-r--r--lib/frr_pthread.h14
-rw-r--r--lib/frratomic.h42
-rw-r--r--lib/json.c8
-rw-r--r--lib/json.h2
-rw-r--r--lib/log.c1
-rw-r--r--lib/memory.c22
-rw-r--r--lib/memory.h2
-rw-r--r--lib/memory_vty.c30
-rw-r--r--lib/netns_linux.c13
-rw-r--r--lib/plist.c4
-rw-r--r--lib/plist.h3
-rw-r--r--lib/routemap.c22
-rw-r--r--lib/subdir.am7
-rw-r--r--lib/table.h3
-rw-r--r--lib/vrf.c59
-rw-r--r--lib/vrf.h12
-rw-r--r--lib/zclient.c3
-rw-r--r--lib/zclient.h1
24 files changed, 448 insertions, 66 deletions
diff --git a/lib/agg_table.c b/lib/agg_table.c
new file mode 100644
index 0000000000..6033fc3f05
--- /dev/null
+++ b/lib/agg_table.c
@@ -0,0 +1,59 @@
+/*
+ * Aggregate Route
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * FRR 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, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "zebra.h"
+
+#include "agg_table.h"
+
+
+static struct route_node *agg_node_create(route_table_delegate_t *delegate,
+ struct route_table *table)
+{
+ struct agg_node *node;
+
+ node = XCALLOC(MTYPE_TMP, sizeof(struct agg_node));
+
+ return agg_node_to_rnode(node);
+}
+
+static void agg_node_destroy(route_table_delegate_t *delegate,
+ struct route_table *table, struct route_node *node)
+
+{
+ struct agg_node *anode = agg_node_from_rnode(node);
+
+ XFREE(MTYPE_TMP, anode);
+}
+
+route_table_delegate_t agg_table_delegate = {
+ .create_node = agg_node_create,
+ .destroy_node = agg_node_destroy,
+};
+
+struct agg_table *agg_table_init(void)
+{
+ struct agg_table *at;
+
+ at = XCALLOC(MTYPE_TMP, sizeof(struct agg_table));
+
+ at->route_table = route_table_init_with_delegate(&agg_table_delegate);
+ at->route_table->info = at;
+
+ return at;
+}
diff --git a/lib/agg_table.h b/lib/agg_table.h
new file mode 100644
index 0000000000..235f0d37a3
--- /dev/null
+++ b/lib/agg_table.h
@@ -0,0 +1,153 @@
+/*
+ * agg_table - Aggregate Table Header
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * FRR 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, or (at your option) any
+ * later version.
+ *
+ * FRR 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 __AGG_TABLE_H__
+#define __AGG_TABLE_H__
+
+#include "prefix.h"
+#include "table.h"
+
+struct agg_table {
+ struct route_table *route_table;
+
+ void *info;
+};
+
+struct agg_node {
+ /*
+ * Caution these must be the very first fields
+ * @see agg_node_to_rnode
+ * @see agg_node_from_rnode
+ */
+ ROUTE_NODE_FIELDS
+
+ /* Aggregation. */
+ void *aggregate;
+};
+
+static inline struct route_node *agg_node_to_rnode(struct agg_node *node)
+{
+ return (struct route_node *)node;
+}
+
+static inline struct agg_node *agg_node_from_rnode(struct route_node *node)
+{
+ return (struct agg_node *)node;
+}
+
+static inline struct agg_node *agg_lock_node(struct agg_node *node)
+{
+ return (struct agg_node *)route_lock_node(agg_node_to_rnode(node));
+}
+
+static inline void agg_unlock_node(struct agg_node *node)
+{
+ return route_unlock_node(agg_node_to_rnode(node));
+}
+
+static inline void agg_set_table_info(struct agg_table *atable, void *data)
+{
+ atable->info = data;
+}
+
+static inline void *agg_get_table_info(struct agg_table *atable)
+{
+ return atable->info;
+}
+
+static inline struct agg_node *agg_route_top(struct agg_table *table)
+{
+ return agg_node_from_rnode(route_top(table->route_table));
+}
+
+static inline struct agg_node *agg_route_next(struct agg_node *node)
+{
+ return agg_node_from_rnode(route_next(agg_node_to_rnode(node)));
+}
+
+static inline struct agg_node *agg_node_get(struct agg_table *table,
+ struct prefix *p)
+{
+ return agg_node_from_rnode(route_node_get(table->route_table, p));
+}
+
+static inline struct agg_node *
+agg_node_lookup(const struct agg_table *const table, struct prefix *p)
+{
+ return agg_node_from_rnode(route_node_lookup(table->route_table, p));
+}
+
+static inline struct agg_node *agg_route_next_until(struct agg_node *node,
+ struct agg_node *limit)
+{
+ struct route_node *rnode;
+
+ rnode = route_next_until(agg_node_to_rnode(node),
+ agg_node_to_rnode(limit));
+
+ return agg_node_from_rnode(rnode);
+}
+
+static inline struct agg_node *agg_node_match(struct agg_table *table,
+ struct prefix *p)
+{
+ return agg_node_from_rnode(route_node_match(table->route_table, p));
+}
+
+static inline struct agg_node *agg_node_parent(struct agg_node *node)
+{
+ struct route_node *rn = agg_node_to_rnode(node);
+
+ return agg_node_from_rnode(rn->parent);
+}
+
+static inline struct agg_node *agg_node_left(struct agg_node *node)
+{
+ struct route_node *rn = agg_node_to_rnode(node);
+
+ return agg_node_from_rnode(rn->l_left);
+}
+
+static inline struct agg_node *agg_node_right(struct agg_node *node)
+{
+ struct route_node *rn = agg_node_to_rnode(node);
+
+ return agg_node_from_rnode(rn->l_right);
+}
+
+extern struct agg_table *agg_table_init(void);
+
+static inline void agg_table_finish(struct agg_table *atable)
+{
+ route_table_finish(atable->route_table);
+ atable->route_table = NULL;
+
+ XFREE(MTYPE_TMP, atable);
+}
+
+static inline struct agg_node *agg_route_table_top(struct agg_node *node)
+{
+ return (struct agg_node *)route_top(node->table);
+}
+
+static inline struct agg_table *agg_get_table(struct agg_node *node)
+{
+ return (struct agg_table *)node->table->info;
+}
+#endif
diff --git a/lib/bfd.c b/lib/bfd.c
index 0eddb47514..1dfe583caf 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -342,7 +342,7 @@ static void bfd_last_update(time_t last_update, char *buf, size_t len)
* bfd_show_param - Show the BFD parameter information.
*/
void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag,
- int extra_space, uint8_t use_json, json_object *json_obj)
+ int extra_space, bool use_json, json_object *json_obj)
{
json_object *json_bfd = NULL;
@@ -378,7 +378,7 @@ void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag,
* bfd_show_status - Show the BFD status information.
*/
static void bfd_show_status(struct vty *vty, struct bfd_info *bfd_info,
- int bfd_tag, int extra_space, uint8_t use_json,
+ int bfd_tag, int extra_space, bool use_json,
json_object *json_bfd)
{
char time_buf[32];
@@ -402,7 +402,7 @@ static void bfd_show_status(struct vty *vty, struct bfd_info *bfd_info,
* bfd_show_info - Show the BFD information.
*/
void bfd_show_info(struct vty *vty, struct bfd_info *bfd_info, int multihop,
- int extra_space, uint8_t use_json, json_object *json_obj)
+ int extra_space, bool use_json, json_object *json_obj)
{
json_object *json_bfd = NULL;
diff --git a/lib/bfd.h b/lib/bfd.h
index f824b0fd9b..b1e490a622 100644
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -91,11 +91,11 @@ extern struct interface *bfd_get_peer_info(struct stream *s, struct prefix *dp,
const char *bfd_get_status_str(int status);
extern void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info,
- int bfd_tag, int extra_space, uint8_t use_json,
+ int bfd_tag, int extra_space, bool use_json,
json_object *json_obj);
extern void bfd_show_info(struct vty *vty, struct bfd_info *bfd_info,
- int multihop, int extra_space, uint8_t use_json,
+ int multihop, int extra_space, bool use_json,
json_object *json_obj);
extern void bfd_client_sendmsg(struct zclient *zclient, int command);
diff --git a/lib/ferr.c b/lib/ferr.c
index 17ec51c4bf..35d0fe4ff4 100644
--- a/lib/ferr.c
+++ b/lib/ferr.c
@@ -148,7 +148,7 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json)
snprintf(pbuf, sizeof(pbuf), "\nError %"PRIu32" - %s",
ref->code, ref->title);
memset(ubuf, '=', strlen(pbuf));
- ubuf[sizeof(ubuf) - 1] = '\0';
+ ubuf[strlen(pbuf) - 1] = '\0';
vty_out(vty, "%s\n%s\n", pbuf, ubuf);
vty_out(vty, "Description:\n%s\n\n", ref->description);
diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c
index f5a6383f48..c0aae5e52e 100644
--- a/lib/frr_pthread.c
+++ b/lib/frr_pthread.c
@@ -85,7 +85,7 @@ void frr_pthread_finish()
}
struct frr_pthread *frr_pthread_new(struct frr_pthread_attr *attr,
- const char *name)
+ const char *name, const char *os_name)
{
static struct frr_pthread holder = {};
struct frr_pthread *fpt = NULL;
@@ -107,6 +107,9 @@ struct frr_pthread *frr_pthread_new(struct frr_pthread_attr *attr,
fpt->attr = *attr;
name = (name ? name : "Anonymous thread");
fpt->name = XSTRDUP(MTYPE_FRR_PTHREAD, name);
+ if (os_name)
+ snprintf(fpt->os_name, OS_THREAD_NAMELEN,
+ "%s", os_name);
if (attr == &frr_pthread_attr_default)
fpt->attr.id = frr_pthread_get_id();
/* initialize startup synchronization primitives */
@@ -140,16 +143,34 @@ void frr_pthread_destroy(struct frr_pthread *fpt)
XFREE(MTYPE_FRR_PTHREAD, fpt);
}
-void frr_pthread_set_name(struct frr_pthread *fpt, const char *name)
+int frr_pthread_set_name(struct frr_pthread *fpt, const char *name,
+ const char *os_name)
{
- pthread_mutex_lock(&fpt->mtx);
- {
- if (fpt->name)
- XFREE(MTYPE_FRR_PTHREAD, fpt->name);
- fpt->name = XSTRDUP(MTYPE_FRR_PTHREAD, name);
+ int ret = 0;
+
+ if (name) {
+ pthread_mutex_lock(&fpt->mtx);
+ {
+ if (fpt->name)
+ XFREE(MTYPE_FRR_PTHREAD, fpt->name);
+ fpt->name = XSTRDUP(MTYPE_FRR_PTHREAD, name);
+ }
+ pthread_mutex_unlock(&fpt->mtx);
+ thread_master_set_name(fpt->master, name);
}
- pthread_mutex_unlock(&fpt->mtx);
- thread_master_set_name(fpt->master, name);
+
+ if (os_name) {
+ pthread_mutex_lock(&fpt->mtx);
+ snprintf(fpt->os_name, OS_THREAD_NAMELEN, "%s", os_name);
+ pthread_mutex_unlock(&fpt->mtx);
+#ifdef GNU_LINUX
+ ret = pthread_setname_np(fpt->thread, fpt->os_name);
+#elif defined(OPEN_BSD)
+ ret = pthread_set_name_np(fpt->thread, fpt->os_name);
+#endif
+ }
+
+ return ret;
}
struct frr_pthread *frr_pthread_get(uint32_t id)
@@ -311,6 +332,9 @@ static void *fpt_run(void *arg)
fpt->master->handle_signals = false;
+ if (fpt->os_name[0])
+ frr_pthread_set_name(fpt, NULL, fpt->os_name);
+
frr_pthread_notify_running(fpt);
struct thread task;
diff --git a/lib/frr_pthread.h b/lib/frr_pthread.h
index 91002dd8ef..cc4fc74337 100644
--- a/lib/frr_pthread.h
+++ b/lib/frr_pthread.h
@@ -28,6 +28,8 @@
DECLARE_MTYPE(FRR_PTHREAD);
DECLARE_MTYPE(PTHREAD_PRIM);
+#define OS_THREAD_NAMELEN 16
+
struct frr_pthread;
struct frr_pthread_attr;
@@ -89,6 +91,9 @@ struct frr_pthread {
* Requires: mtx
*/
char *name;
+
+ /* Used in pthread_set_name max 16 characters */
+ char os_name[OS_THREAD_NAMELEN];
};
extern struct frr_pthread_attr frr_pthread_attr_default;
@@ -122,18 +127,23 @@ void frr_pthread_finish(void);
*
* @param attr - the thread attributes
* @param name - Human-readable name
+ * @param os_name - 16 characters (including '\0') thread name to set in os,
* @return the created frr_pthread upon success, or NULL upon failure
*/
struct frr_pthread *frr_pthread_new(struct frr_pthread_attr *attr,
- const char *name);
+ const char *name, const char *os_name);
/*
* Changes the name of the frr_pthread.
*
* @param fpt - the frr_pthread to operate on
* @param name - Human-readable name
+ * @param os_name - 16 characters thread name , including the null
+ * terminator ('\0') to set in os.
+ * @return - on success returns 0 otherwise nonzero error number.
*/
-void frr_pthread_set_name(struct frr_pthread *fpt, const char *name);
+int frr_pthread_set_name(struct frr_pthread *fpt, const char *name,
+ const char *os_name);
/*
* Destroys an frr_pthread.
diff --git a/lib/frratomic.h b/lib/frratomic.h
index 689b25255d..1f1d1b569a 100644
--- a/lib/frratomic.h
+++ b/lib/frratomic.h
@@ -29,6 +29,12 @@
#ifdef HAVE_STDATOMIC_H
#include <stdatomic.h>
+/* These are available in gcc, but not in stdatomic */
+#define atomic_add_fetch_explicit __atomic_add_fetch
+#define atomic_sub_fetch_explicit __atomic_sub_fetch
+#define atomic_and_fetch_explicit __atomic_and_fetch
+#define atomic_or_fetch_explicit __atomic_or_fetch
+
/* gcc 4.7 and newer */
#elif defined(HAVE___ATOMIC)
@@ -49,6 +55,11 @@
#define atomic_fetch_and_explicit __atomic_fetch_and
#define atomic_fetch_or_explicit __atomic_fetch_or
+#define atomic_add_fetch_explicit __atomic_add_fetch
+#define atomic_sub_fetch_explicit __atomic_sub_fetch
+#define atomic_and_fetch_explicit __atomic_and_fetch
+#define atomic_or_fetch_explicit __atomic_or_fetch
+
#define atomic_compare_exchange_weak_explicit(atom, expect, desire, mem1, \
mem2) \
__atomic_compare_exchange_n(atom, expect, desire, 1, mem1, mem2)
@@ -137,6 +148,7 @@
*_expect = rval; \
ret; \
})
+
#define atomic_fetch_and_explicit(ptr, val, mem) \
({ \
__sync_synchronize(); \
@@ -152,6 +164,36 @@
rval; \
})
+#define atomic_add_fetch_explicit(ptr, val, mem) \
+ ({ \
+ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_add_and_fetch((ptr), (val)); \
+ __sync_synchronize(); \
+ rval; \
+ })
+#define atomic_sub_fetch_explicit(ptr, val, mem) \
+ ({ \
+ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_sub_and_fetch((ptr), (val)); \
+ __sync_synchronize(); \
+ rval; \
+ })
+
+#define atomic_and_fetch_explicit(ptr, val, mem) \
+ ({ \
+ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_and_and_fetch(ptr, val); \
+ __sync_synchronize(); \
+ rval; \
+ })
+#define atomic_or_fetch_explicit(ptr, val, mem) \
+ ({ \
+ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_or_and_fetch(ptr, val); \
+ __sync_synchronize(); \
+ rval; \
+ })
+
#else /* !HAVE___ATOMIC && !HAVE_STDATOMIC_H */
#error no atomic functions...
#endif
diff --git a/lib/json.c b/lib/json.c
index 40b6aadaa3..4ea20ba178 100644
--- a/lib/json.c
+++ b/lib/json.c
@@ -28,15 +28,15 @@
* is the *last* keyword on the line no matter
* what.
*/
-int use_json(const int argc, struct cmd_token *argv[])
+bool use_json(const int argc, struct cmd_token *argv[])
{
if (argc == 0)
- return 0;
+ return false;
if (argv[argc - 1]->arg && strmatch(argv[argc - 1]->text, "json"))
- return 1;
+ return true;
- return 0;
+ return false;
}
void json_object_string_add(struct json_object *obj, const char *key,
diff --git a/lib/json.h b/lib/json.h
index 788d1d6efa..d349162304 100644
--- a/lib/json.h
+++ b/lib/json.h
@@ -52,7 +52,7 @@ extern int json_object_object_get_ex(struct json_object *obj, const char *key,
#include "command.h"
-extern int use_json(const int argc, struct cmd_token *argv[]);
+extern bool use_json(const int argc, struct cmd_token *argv[]);
extern void json_object_string_add(struct json_object *obj, const char *key,
const char *s);
extern void json_object_int_add(struct json_object *obj, const char *key,
diff --git a/lib/log.c b/lib/log.c
index b067018e08..010b984786 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -925,7 +925,6 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_IMPORT_ROUTE_REGISTER),
DESC_ENTRY(ZEBRA_IMPORT_ROUTE_UNREGISTER),
DESC_ENTRY(ZEBRA_IMPORT_CHECK_UPDATE),
- DESC_ENTRY(ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD),
DESC_ENTRY(ZEBRA_BFD_DEST_REGISTER),
DESC_ENTRY(ZEBRA_BFD_DEST_DEREGISTER),
DESC_ENTRY(ZEBRA_BFD_DEST_UPDATE),
diff --git a/lib/memory.c b/lib/memory.c
index 87cba69fc5..695bbfe115 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -36,9 +36,19 @@ DEFINE_MTYPE(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec")
static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr)
{
+ size_t current;
size_t oldsize;
- atomic_fetch_add_explicit(&mt->n_alloc, 1, memory_order_relaxed);
+ current = 1 + atomic_fetch_add_explicit(&mt->n_alloc, 1,
+ memory_order_relaxed);
+
+ oldsize = atomic_load_explicit(&mt->n_max, memory_order_relaxed);
+ if (current > oldsize)
+ /* note that this may fail, but approximation is sufficient */
+ atomic_compare_exchange_weak_explicit(&mt->n_max, &oldsize,
+ current,
+ memory_order_relaxed,
+ memory_order_relaxed);
oldsize = atomic_load_explicit(&mt->size, memory_order_relaxed);
if (oldsize == 0)
@@ -51,7 +61,15 @@ static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr)
#ifdef HAVE_MALLOC_USABLE_SIZE
size_t mallocsz = malloc_usable_size(ptr);
- atomic_fetch_add_explicit(&mt->total, mallocsz, memory_order_relaxed);
+ current = mallocsz + atomic_fetch_add_explicit(&mt->total, mallocsz,
+ memory_order_relaxed);
+ oldsize = atomic_load_explicit(&mt->max_size, memory_order_relaxed);
+ if (current > oldsize)
+ /* note that this may fail, but approximation is sufficient */
+ atomic_compare_exchange_weak_explicit(&mt->max_size, &oldsize,
+ current,
+ memory_order_relaxed,
+ memory_order_relaxed);
#endif
}
diff --git a/lib/memory.h b/lib/memory.h
index c39f34e3a7..2d6c144778 100644
--- a/lib/memory.h
+++ b/lib/memory.h
@@ -34,9 +34,11 @@ struct memtype {
struct memtype *next, **ref;
const char *name;
_Atomic size_t n_alloc;
+ _Atomic size_t n_max;
_Atomic size_t size;
#ifdef HAVE_MALLOC_USABLE_SIZE
_Atomic size_t total;
+ _Atomic size_t max_size;
#endif
};
diff --git a/lib/memory_vty.c b/lib/memory_vty.c
index 9ee2e52ec7..73a18529a2 100644
--- a/lib/memory_vty.c
+++ b/lib/memory_vty.c
@@ -73,27 +73,45 @@ static int show_memory_mallinfo(struct vty *vty)
static int qmem_walker(void *arg, struct memgroup *mg, struct memtype *mt)
{
struct vty *vty = arg;
- if (!mt)
+ if (!mt) {
vty_out(vty, "--- qmem %s ---\n", mg->name);
- else {
+ vty_out(vty, "%-30s: %8s %-8s%s %8s %9s\n",
+ "Type", "Current#", " Size",
+#ifdef HAVE_MALLOC_USABLE_SIZE
+ " Total",
+#else
+ "",
+#endif
+ "Max#",
+#ifdef HAVE_MALLOC_USABLE_SIZE
+ "MaxBytes"
+#else
+ ""
+#endif
+ );
+ } else {
if (mt->n_alloc != 0) {
char size[32];
snprintf(size, sizeof(size), "%6zu", mt->size);
-
#ifdef HAVE_MALLOC_USABLE_SIZE
#define TSTR " %9zu"
#define TARG , mt->total
+#define TARG2 , mt->max_size
#else
#define TSTR ""
#define TARG
+#define TARG2
#endif
- vty_out(vty, "%-30s: %10zu %-16s"TSTR"\n", mt->name,
+ vty_out(vty, "%-30s: %8zu %-8s"TSTR" %8zu"TSTR"\n",
+ mt->name,
mt->n_alloc,
mt->size == 0 ? ""
: mt->size == SIZE_VAR
- ? "(variably sized)"
+ ? "variable"
: size
- TARG);
+ TARG,
+ mt->n_max
+ TARG2);
}
}
return 0;
diff --git a/lib/netns_linux.c b/lib/netns_linux.c
index b8eaa72c22..33338ac89c 100644
--- a/lib/netns_linux.c
+++ b/lib/netns_linux.c
@@ -468,21 +468,12 @@ void ns_init(void)
if (ns_initialised == 1)
return;
errno = 0;
-#ifdef HAVE_NETNS
- if (have_netns_enabled < 0) {
+ if (have_netns())
ns_default_ns_fd = open(NS_DEFAULT_NAME, O_RDONLY);
- if (ns_default_ns_fd == -1)
- flog_err(LIB_ERR_NS,
- "NS initialization failure %d(%s)", errno,
- safe_strerror(errno));
- } else {
+ else {
ns_default_ns_fd = -1;
default_ns = NULL;
}
-#else
- ns_default_ns_fd = -1;
- default_ns = NULL;
-#endif /* HAVE_NETNS */
ns_current_ns_fd = -1;
ns_initialised = 1;
}
diff --git a/lib/plist.c b/lib/plist.c
index 2b666f256f..5746080127 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -396,7 +396,7 @@ static int64_t prefix_new_seq_get(struct prefix_list *plist)
newseq = ((maxseq / 5) * 5) + 5;
- return newseq;
+ return (newseq > UINT_MAX) ? UINT_MAX : newseq;
}
/* Return prefix list entry which has same seq number. */
@@ -1900,7 +1900,7 @@ void prefix_bgp_orf_remove_all(afi_t afi, char *name)
/* return prefix count */
int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
- uint8_t use_json)
+ bool use_json)
{
struct prefix_list *plist;
struct prefix_list_entry *pentry;
diff --git a/lib/plist.h b/lib/plist.h
index fecbe0e2ce..8a4fa8d3ce 100644
--- a/lib/plist.h
+++ b/lib/plist.h
@@ -72,6 +72,7 @@ extern struct stream *prefix_bgp_orf_entry(struct stream *,
uint8_t, uint8_t);
extern int prefix_bgp_orf_set(char *, afi_t, struct orf_prefix *, int, int);
extern void prefix_bgp_orf_remove_all(afi_t, char *);
-extern int prefix_bgp_show_prefix_list(struct vty *, afi_t, char *, uint8_t);
+extern int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
+ bool use_json);
#endif /* _QUAGGA_PLIST_H */
diff --git a/lib/routemap.c b/lib/routemap.c
index 4125bb53ae..e5613c2081 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -891,6 +891,14 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map)
}
}
+static int sort_route_map(const void **map1, const void **map2)
+{
+ const struct route_map *m1 = *map1;
+ const struct route_map *m2 = *map2;
+
+ return strcmp(m1->name, m2->name);
+}
+
static int vty_show_route_map(struct vty *vty, const char *name)
{
struct route_map *map;
@@ -907,9 +915,19 @@ static int vty_show_route_map(struct vty *vty, const char *name)
return CMD_SUCCESS;
}
} else {
+
+ struct list *maplist = list_new();
+ struct listnode *ln;
+
for (map = route_map_master.head; map; map = map->next)
- if (!map->deleted)
- vty_show_route_map_entry(vty, map);
+ listnode_add(maplist, map);
+
+ list_sort(maplist, sort_route_map);
+
+ for (ALL_LIST_ELEMENTS_RO(maplist, ln, map))
+ vty_show_route_map_entry(vty, map);
+
+ list_delete_and_null(&maplist);
}
return CMD_SUCCESS;
}
diff --git a/lib/subdir.am b/lib/subdir.am
index 50cfd70a57..ef6c8f8e55 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -6,6 +6,7 @@ lib_libfrr_la_LDFLAGS = -version-info 0:0:0
lib_libfrr_la_LIBADD = @LIBCAP@
lib_libfrr_la_SOURCES = \
+ lib/agg_table.c \
lib/bfd.c \
lib/buffer.c \
lib/checksum.c \
@@ -89,6 +90,7 @@ lib/nexthop_group_clippy.c: $(CLIPPY_DEPS)
lib/nexthop_group.lo: lib/nexthop_group_clippy.c
pkginclude_HEADERS += \
+ lib/agg_table.h \
lib/bfd.h \
lib/bitfield.h \
lib/buffer.h \
@@ -291,7 +293,7 @@ if GIT_VERSION
# (even if gitversion.h's file timestamp doesn't change, make will think it
# did, because of .PHONY...)
-.PHONY: lib/gitversion.h.tmp
+PHONY_GITVERSION=lib/gitversion.h.tmp
.SILENT: lib/gitversion.h lib/gitversion.h.tmp
GITH=lib/gitversion.h
lib/gitversion.h.tmp: $(top_srcdir)/.git
@@ -300,7 +302,8 @@ lib/gitversion.h: lib/gitversion.h.tmp
{ test -f ${GITH} && diff -s -q ${GITH}.tmp ${GITH}; } || cp ${GITH}.tmp ${GITH}
else
-.PHONY: lib/gitversion.h
+PHONY_GITVERSION=lib/gitversion.h
lib/gitversion.h:
true
endif
+.PHONY: $(PHONY_GITVERSION)
diff --git a/lib/table.h b/lib/table.h
index 8304abe59b..711ace111e 100644
--- a/lib/table.h
+++ b/lib/table.h
@@ -126,9 +126,6 @@ struct route_table {
\
/* Each node of route. */ \
void *info; \
- \
- /* Aggregation. */ \
- void *aggregate;
/* Each routing entry. */
diff --git a/lib/vrf.c b/lib/vrf.c
index ecd09a6b91..1fb1b786c7 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -39,6 +39,7 @@
/* default VRF ID value used when VRF backend is not NETNS */
#define VRF_DEFAULT_INTERNAL 0
+#define VRF_DEFAULT_NAME_INTERNAL "default"
DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
@@ -56,6 +57,7 @@ struct vrf_name_head vrfs_by_name = RB_INITIALIZER(&vrfs_by_name);
static int vrf_backend;
static struct zebra_privs_t *vrf_daemon_privs;
+static char vrf_default_name[VRF_NAMSIZ] = VRF_DEFAULT_NAME_INTERNAL;
/*
* Turn on/off debug code
@@ -69,6 +71,7 @@ struct vrf_master {
int (*vrf_delete_hook)(struct vrf *);
int (*vrf_enable_hook)(struct vrf *);
int (*vrf_disable_hook)(struct vrf *);
+ int (*vrf_update_name_hook)(struct vrf *vrf);
} vrf_master = {
0,
};
@@ -165,6 +168,13 @@ struct vrf *vrf_get(vrf_id_t vrf_id, const char *name)
*/
if (name)
vrf = vrf_lookup_by_name(name);
+ if (vrf && vrf_id != VRF_UNKNOWN
+ && vrf->vrf_id != VRF_UNKNOWN
+ && vrf->vrf_id != vrf_id) {
+ zlog_debug("VRF_GET: avoid %s creation(%u), same name exists (%u)",
+ name, vrf_id, vrf->vrf_id);
+ return NULL;
+ }
/* Try to find VRF both by ID and name */
if (!vrf && vrf_id != VRF_UNKNOWN)
vrf = vrf_lookup_by_id(vrf_id);
@@ -445,10 +455,8 @@ static void vrf_autocomplete(vector comps, struct cmd_token *token)
{
struct vrf *vrf = NULL;
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (vrf->vrf_id != VRF_DEFAULT)
- vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
- }
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
}
static const struct cmd_variable_handler vrf_var_handlers[] = {
@@ -461,7 +469,8 @@ static const struct cmd_variable_handler vrf_var_handlers[] = {
/* Initialize VRF module. */
void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
- int (*disable)(struct vrf *), int (*delete)(struct vrf *))
+ int (*disable)(struct vrf *), int (*delete)(struct vrf *),
+ int ((*update)(struct vrf *)))
{
struct vrf *default_vrf;
@@ -475,6 +484,7 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
vrf_master.vrf_enable_hook = enable;
vrf_master.vrf_disable_hook = disable;
vrf_master.vrf_delete_hook = delete;
+ vrf_master.vrf_update_name_hook = update;
/* The default VRF always exists. */
default_vrf = vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME);
@@ -483,6 +493,9 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
"vrf_init: failed to create the default VRF!");
exit(1);
}
+ if (vrf_is_backend_netns())
+ strlcpy(default_vrf->data.l.netns_name,
+ VRF_DEFAULT_NAME, NS_NAMSIZ);
/* Enable the default VRF. */
if (!vrf_enable(default_vrf)) {
@@ -876,12 +889,40 @@ void vrf_cmd_init(int (*writefunc)(struct vty *vty),
}
}
-vrf_id_t vrf_get_default_id(void)
+void vrf_set_default_name(const char *default_name)
{
- struct vrf *vrf = vrf_lookup_by_name(VRF_DEFAULT_NAME);
+ struct vrf *def_vrf;
+ struct vrf *vrf_with_default_name = NULL;
- if (vrf)
- return vrf->vrf_id;
+ def_vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ assert(default_name);
+ vrf_with_default_name = vrf_lookup_by_name(default_name);
+ if (vrf_with_default_name && vrf_with_default_name != def_vrf) {
+ /* vrf name already used by an other VRF */
+ zlog_debug("VRF: %s, avoid changing name to %s, same name exists (%u)",
+ vrf_with_default_name->name, default_name,
+ vrf_with_default_name->vrf_id);
+ return;
+ }
+ snprintf(vrf_default_name, VRF_NAMSIZ, "%s", default_name);
+ if (def_vrf) {
+ RB_REMOVE(vrf_name_head, &vrfs_by_name, def_vrf);
+ strlcpy(def_vrf->data.l.netns_name,
+ vrf_default_name, NS_NAMSIZ);
+ strlcpy(def_vrf->name, vrf_default_name, sizeof(def_vrf->name));
+ RB_INSERT(vrf_name_head, &vrfs_by_name, def_vrf);
+ if (vrf_master.vrf_update_name_hook)
+ (*vrf_master.vrf_update_name_hook)(def_vrf);
+ }
+}
+
+const char *vrf_get_default_name(void)
+{
+ return vrf_default_name;
+}
+
+vrf_id_t vrf_get_default_id(void)
+{
/* backend netns is only known by zebra
* for other daemons, we return VRF_DEFAULT_INTERNAL
*/
diff --git a/lib/vrf.h b/lib/vrf.h
index 56ba101ff0..c962ac4c69 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -41,8 +41,6 @@ enum { IFLA_VRF_UNSPEC, IFLA_VRF_TABLE, __IFLA_VRF_MAX };
#define VRF_NAMSIZ 36
#define NS_NAMSIZ 16
-#define VRF_DEFAULT_NAME "Default-IP-Routing-Table"
-
/*
* The command strings
*/
@@ -201,8 +199,10 @@ extern int vrf_bitmap_check(vrf_bitmap_t, vrf_id_t);
* delete -> Called back when a vrf is being deleted from
* the system ( 2 and 3 ) above.
*/
-extern void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
- int (*disable)(struct vrf *), int (*delete)(struct vrf *));
+extern void vrf_init(int (*create)(struct vrf *vrf), int (*enable)(struct vrf *vrf),
+ int (*disable)(struct vrf *vrf), int (*delete)(struct vrf *vrf),
+ int ((*update)(struct vrf *vrf)));
+
/*
* Call vrf_terminate when the protocol is being shutdown
*/
@@ -236,6 +236,10 @@ extern vrf_id_t vrf_get_default_id(void);
/* The default VRF ID */
#define VRF_DEFAULT vrf_get_default_id()
+extern void vrf_set_default_name(const char *default_name);
+extern const char *vrf_get_default_name(void);
+#define VRF_DEFAULT_NAME vrf_get_default_name()
+
/* VRF is mapped on netns or not ? */
int vrf_is_mapped_on_netns(struct vrf *vrf);
diff --git a/lib/zclient.c b/lib/zclient.c
index b2bafcb7d8..c5a48c178a 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1366,6 +1366,9 @@ static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
vrf = vrf_get(vrf_id, vrfname_tmp);
vrf->data.l.table_id = data.l.table_id;
memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
+ /* overwrite default vrf */
+ if (vrf_id == VRF_DEFAULT)
+ vrf_set_default_name(vrfname_tmp);
vrf_enable(vrf);
}
diff --git a/lib/zclient.h b/lib/zclient.h
index b8ff85e80f..cab734ae5e 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -91,7 +91,6 @@ typedef enum {
ZEBRA_IMPORT_ROUTE_REGISTER,
ZEBRA_IMPORT_ROUTE_UNREGISTER,
ZEBRA_IMPORT_CHECK_UPDATE,
- ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD,
ZEBRA_BFD_DEST_REGISTER,
ZEBRA_BFD_DEST_DEREGISTER,
ZEBRA_BFD_DEST_UPDATE,