From 4e0d9dd987781fe2e7b1bfc91f848b01873330d0 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 5 May 2022 23:03:18 +0200 Subject: [PATCH] SNMP frontend Fixed table/scalar collision issue Made the CS variable change said to be in previous commit --- apps/snmp/snmp_main.c | 5 --- apps/snmp/snmp_mib_yang.c | 71 ++++++++++++++++++++++++++++++--------- test/test_snmp.sh | 40 +++++++++++++--------- test/test_snmp_table.sh | 53 +++++++++++++++++------------ 4 files changed, 111 insertions(+), 58 deletions(-) diff --git a/apps/snmp/snmp_main.c b/apps/snmp/snmp_main.c index ee921319..c2e25e5e 100644 --- a/apps/snmp/snmp_main.c +++ b/apps/snmp/snmp_main.c @@ -394,11 +394,6 @@ main(int argc, if (clicon_nsctx_global_set(h, nsctx_global) < 0) goto done; -#if 0 - /* Call start function is all plugins before we go interactive */ - if (clixon_plugin_start_all(h) < 0) - goto done; -#endif /* Get session id from backend hello */ clicon_session_id_set(h, getpid()); diff --git a/apps/snmp/snmp_mib_yang.c b/apps/snmp/snmp_mib_yang.c index 30056e4a..37177b05 100644 --- a/apps/snmp/snmp_mib_yang.c +++ b/apps/snmp/snmp_mib_yang.c @@ -292,6 +292,7 @@ my_test_instance_handler(netsnmp_mib_handler *handler, return SNMP_ERR_NOERROR; } + #endif /*! Parse smiv2 extensions for YANG leaf @@ -318,8 +319,6 @@ mib_yang_leaf(clicon_handle h, char *origtype=NULL; /* original type */ char *name; - - clicon_debug(1, "%s %s", __FUNCTION__, oidstr); if (yang_extension_value(ys, "oid", IETF_YANG_SMIV2_NS, NULL, &oidstr) < 0) goto done; if (oidstr == NULL) @@ -347,10 +346,12 @@ mib_yang_leaf(clicon_handle h, goto done; // restype = yrestype?yang_argument_get(yrestype):NULL; name = yang_argument_get(ys); + if ((handler = netsnmp_create_handler(name, my_test_instance_handler)) == NULL){ clicon_err(OE_SNMP, errno, "netsnmp_create_handler"); goto done; } + // handler->myvoid = h; handler->myvoid =(void*)99; if ((nh = netsnmp_handler_registration_create(name, @@ -362,12 +363,13 @@ mib_yang_leaf(clicon_handle h, netsnmp_handler_free(handler); goto done; } - clicon_debug(1, "%s %p", __FUNCTION__, nh); if ((ret = netsnmp_register_instance(nh)) < 0){ /* XXX Failures are MIB_REGISTRATION_FAILED and MIB_DUPLICATE_REGISTRATION. */ clicon_err(OE_SNMP, ret, "netsnmp_register_instance"); goto done; } + clicon_debug(1, "%s %s registered", __FUNCTION__, oidstr); + ok: retval = 0; done: @@ -386,29 +388,67 @@ mib_yang_leaf(clicon_handle h, * @see yang_extension_value * @see ys_populate_unknown */ -static int -mib_yang_extension(yang_stmt *ys, - void *arg) -{ - int retval = -1; - clicon_handle h = (clicon_handle)arg; - switch(yang_keyword_get(ys)){ +/*! Traverse mib-yang tree, identify scalars and tables, register OID and callbacks + * + * The tree is traversed depth-first, which at least guarantees that a parent is + * traversed before a child. + * Extensions are grouped in some categories, the one I have seen are, example: + * 1. leaf + * smiv2:max-access "read-write"; + * smiv2:oid "1.3.6.1.4.1.8072.2.1.1"; + * smiv2:defval "42"; (not always) + * 2. container, list + * smiv2:oid "1.3.6.1.4.1.8072.2.1"; + * 3. module level + * smiv2:alias "netSnmpExamples" { + * smiv2:oid "1.3.6.1.4.1.8072.2"; + + * @param[in] h Clixon handle + * @param[in] yn yang node + * @retval -1 Error, aborted at first error encounter + * @retval 0 OK, all nodes traversed + */ +static int +mib_traverse(clicon_handle h, + yang_stmt *yn) +{ + int retval = -1; + yang_stmt *ys = NULL; + yang_stmt *yp; + int ret; + + switch(yang_keyword_get(yn)){ case Y_LEAF: - if (mib_yang_leaf(h, ys) < 0) + if (mib_yang_leaf(h, yn) < 0) goto done; break; case Y_CONTAINER: // XXX break; case Y_LIST: // XXX + yp = yang_parent_get(yn); + if (yang_keyword_get(yp) == Y_CONTAINER){ + /* XXX ad-hoc method to find table? now skip */ + goto ok; + } break; default: break; } + ys = NULL; + while ((ys = yn_each(yn, ys)) != NULL) { + if ((ret = mib_traverse(h, ys)) < 0) + goto done; + if (ret > 0){ + retval = ret; + goto done; + } + } + ok: retval = 0; -done: + done: return retval; -} +} int clixon_snmp_mib_yangs(clicon_handle h) @@ -420,8 +460,6 @@ clixon_snmp_mib_yangs(clicon_handle h) yang_stmt *ymod; /* XXX Hardcoded, replace this with generic MIB */ - init_testtable(); // XXX - if ((yspec = clicon_dbspec_yang(h)) == NULL){ clicon_err(OE_FATAL, 0, "No DB_SPEC"); goto done; @@ -444,9 +482,10 @@ clixon_snmp_mib_yangs(clicon_handle h) goto done; } /* Recursively traverse the mib-yang to find extensions */ - if (yang_apply(ymod, -1, mib_yang_extension, 1, h) < 0) + if (mib_traverse(h, ymod) < 0) goto done; } + init_testtable(); // XXX NOTE Must be AFTER loop ^ for unknown reason retval = 0; done: return retval; diff --git a/test/test_snmp.sh b/test/test_snmp.sh index 2c14e98f..858023fa 100755 --- a/test/test_snmp.sh +++ b/test/test_snmp.sh @@ -48,27 +48,35 @@ EOF function testinit(){ new "test params: -f $cfg" - # Kill old backend and start a new one - new "kill old backend" - sudo clixon_backend -zf $cfg - if [ $? -ne 0 ]; then + + if [ $BE -ne 0 ]; then + # Kill old backend and start a new one + new "kill old backend" + sudo clixon_backend -zf $cfg + if [ $? -ne 0 ]; then err "Failed to start backend" + fi + + sudo pkill -f clixon_backend + + new "Starting backend" + start_backend -s init -f $cfg fi - sudo pkill -f clixon_backend + new "wait backend" + wait_backend + + if [ $CS -ne 0 ]; then + # Kill old clixon_snmp, if any + new "Terminating any old clixon_snmp processes" + sudo killall -q clixon_snmp - new "Starting backend" - start_backend -s init -f $cfg + new "Starting clixon_snmp" + start_snmp $cfg & + fi - # Kill old clixon_snmp, if any - new "Terminating any old clixon_snmp processes" - sudo killall -q clixon_snmp - - new "Starting clixon_snmp" - start_snmp $cfg & - - # Wait for things to settle - sleep 3 + new "wait snmp" + wait_snmp } function testexit(){ diff --git a/test/test_snmp_table.sh b/test/test_snmp_table.sh index 4e0a1172..b7e7e472 100755 --- a/test/test_snmp_table.sh +++ b/test/test_snmp_table.sh @@ -41,6 +41,7 @@ cat < $cfg /var/tmp/$APPNAME.pidfile $dir unix:$SOCK + NET-SNMP-EXAMPLES-MIB EOF @@ -57,31 +58,41 @@ EOF function testinit(){ new "test params: -f $cfg" - # Kill old backend and start a new one - new "kill old backend" - sudo clixon_backend -zf $cfg - if [ $? -ne 0 ]; then - err "Failed to start backend" + if [ $BE -ne 0 ]; then + # Kill old backend and start a new one + new "kill old backend" + sudo clixon_backend -zf $cfg + if [ $? -ne 0 ]; then + err "Failed to start backend" + fi + + sudo pkill -f clixon_backend + + new "Starting backend" + start_backend -s init -f $cfg + fi + + new "wait backend" + wait_backend + + if [ $CS -ne 0 ]; then + # Kill old clixon_snmp, if any + new "Terminating any old clixon_snmp processes" + sudo killall -q clixon_snmp + + new "Starting clixon_snmp" + start_snmp $cfg & fi - sudo pkill -f clixon_backend - - new "Starting backend" - start_backend -s init -f $cfg - - # Kill old clixon_snmp, if any - new "Terminating any old clixon_snmp processes" - sudo killall -q clixon_snmp - - new "Starting clixon_snmp" - start_snmp $cfg & - - # Wait for things to settle - sleep 3 + new "wait snmp" + wait_snmp } -function testexit(){ - stop_snmp +function testexit() +{ + if [ $CS -ne 0 ]; then + stop_snmp + fi } new "SNMP table tests"