From 0878c8d423a7e53ac08a73bb47819dc4c9268a31 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 26 Sep 2016 18:36:49 +0200 Subject: [PATCH] lib: vty: add infrastructure for qobj ID "index" As mentioned in previous commits, this prepares to replace the vty's "void *index" context position with a safe qobj pointer. This will allow concurrent configuration editing by multiple users, as soon as no more code (library included) in the daemon uses vty->index anymore. Signed-off-by: David Lamparter --- lib/vty.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/lib/vty.h b/lib/vty.h index 4f1dbe653..ba68ecb7e 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -24,10 +24,18 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "thread.h" #include "log.h" #include "sockunion.h" +#include "qobj.h" #define VTY_BUFSIZ 512 #define VTY_MAXHIST 20 +#if defined(VTY_DEPRECATE_INDEX) && defined(__GNUC__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define INDEX_WARNING __attribute__((deprecated)) +#else +#define INDEX_WARNING +#endif + /* VTY struct. */ struct vty { @@ -75,7 +83,10 @@ struct vty /* For current referencing point of interface, route-map, access-list etc... */ - void *index; + void *index INDEX_WARNING; + + /* qobj object ID (replacement for "index") */ + uint64_t qobj_index; /* For multiple level index treatment such as key chain and key. */ void *index_sub; @@ -127,6 +138,46 @@ struct vty char address[SU_ADDRSTRLEN]; }; +#undef INDEX_WARNING + +static inline void vty_push_context(struct vty *vty, + int node, uint64_t id, void *idx) +{ + vty->node = node; + vty->qobj_index = id; +#if defined(VTY_DEPRECATE_INDEX) && defined(__GNUC__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + vty->index = idx; +#pragma GCC diagnostic pop +#else + vty->index = idx; +#endif +} + +#define VTY_PUSH_CONTEXT(nodeval, ptr) \ + vty_push_context(vty, nodeval, QOBJ_ID(ptr), NULL) +#define VTY_PUSH_CONTEXT_COMPAT(nodeval, ptr) \ + vty_push_context(vty, nodeval, QOBJ_ID(ptr), ptr) + +/* can return NULL if context is invalid! */ +#define VTY_GET_CONTEXT(structname) \ + QOBJ_GET_TYPESAFE(vty->qobj_index, structname) + +/* will return if ptr is NULL. */ +#define VTY_CHECK_CONTEXT(ptr) \ + if (!ptr) { \ + vty_out (vty, "Current configuration object was deleted " \ + "by another process.%s", VTY_NEWLINE); \ + return CMD_WARNING; \ + } + +/* struct structname *ptr = ; ptr will never be NULL. */ +#define VTY_DECLVAR_CONTEXT(structname, ptr) \ + struct structname *ptr = VTY_GET_CONTEXT(structname); \ + VTY_CHECK_CONTEXT(ptr); + struct vty_arg { const char *name; -- 2.39.5