diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/agg_table.c | 59 | ||||
| -rw-r--r-- | lib/agg_table.h | 153 | ||||
| -rw-r--r-- | lib/bfd.c | 6 | ||||
| -rw-r--r-- | lib/bfd.h | 4 | ||||
| -rw-r--r-- | lib/ferr.c | 2 | ||||
| -rw-r--r-- | lib/frr_pthread.c | 42 | ||||
| -rw-r--r-- | lib/frr_pthread.h | 14 | ||||
| -rw-r--r-- | lib/frratomic.h | 42 | ||||
| -rw-r--r-- | lib/json.c | 8 | ||||
| -rw-r--r-- | lib/json.h | 2 | ||||
| -rw-r--r-- | lib/log.c | 1 | ||||
| -rw-r--r-- | lib/memory.c | 22 | ||||
| -rw-r--r-- | lib/memory.h | 2 | ||||
| -rw-r--r-- | lib/memory_vty.c | 30 | ||||
| -rw-r--r-- | lib/netns_linux.c | 13 | ||||
| -rw-r--r-- | lib/plist.c | 4 | ||||
| -rw-r--r-- | lib/plist.h | 3 | ||||
| -rw-r--r-- | lib/routemap.c | 22 | ||||
| -rw-r--r-- | lib/subdir.am | 7 | ||||
| -rw-r--r-- | lib/table.h | 3 | ||||
| -rw-r--r-- | lib/vrf.c | 59 | ||||
| -rw-r--r-- | lib/vrf.h | 12 | ||||
| -rw-r--r-- | lib/zclient.c | 3 | ||||
| -rw-r--r-- | lib/zclient.h | 1 |
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 @@ -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; @@ -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, @@ -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. */ @@ -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 */ @@ -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, |
