lib: keep hash of node's commands to detect duplicate installs
* command.h: (struct cmd_node) Add a hash, so duplicate installs of
a cmd_element to a command node can be detected. To help catch
strays from the VIEW/ENABLE node consolidation particularly
(installs to VIEW automatically install to ENABLE too now).
* command.c: (cmd_hash_{key,cmp}) helpers for the hash - just directly
on the pointer value is sufficient to catch the main problem.
(install_node) setup the hash for the command node.
(install_element) check for duplicate installs.
The assert on the cmd_parse_format seems misplaced.
(install_default_basic) separate the basic, VIEW, node default commands
to here.
(cmd_init) get rid of dupes, given consolidation.
(cmd_terminate) clean up the node command hash.
Not done: The (struct cmd_node)'s vector could be replaced with the
cmd hash, however much of the command parser depends heavily on the
vector and it's a lot of work to change. A vector_lookup_value could
also work, particularly if vector could be backed by a hash.
The duplicate check could be disabled in releases - but useful in
development. It's a little extra overhead at startup. The command
initialisation overhead is already something that bites in
micro-benchmarks - makes it easy for other implementations to show
how much faster they are with benchmarks where other load is low
enough that startup time is a factor.
diff --git a/lib/command.h b/lib/command.h
index 09bc516..214b1d5 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -26,6 +26,7 @@
#include "vector.h"
#include "vty.h"
#include "lib/route_types.h"
+#include "hash.h"
/* Host configuration variable */
struct host
@@ -127,7 +128,10 @@
int (*func) (struct vty *);
/* Vector of this node's command list. */
- vector cmd_vector;
+ vector cmd_vector;
+
+ /* Hashed index of command node list, for de-dupping primarily */
+ struct hash *cmd_hash;
};
enum