diff --git a/apps/snmp/snmp_handler.c b/apps/snmp/snmp_handler.c index dfa90cde..f2550577 100644 --- a/apps/snmp/snmp_handler.c +++ b/apps/snmp/snmp_handler.c @@ -58,6 +58,7 @@ #include #include "snmp_lib.h" +#include "snmp_register.h" #include "snmp_handler.h" static int @@ -127,7 +128,6 @@ snmp_common_handler(netsnmp_mib_handler *handler, * table_container.[ch] * * build_new_oid - * XXX Check expected return values for these netsnmp handler functions */ int clixon_snmp_table_handler(netsnmp_mib_handler *handler, @@ -142,27 +142,16 @@ clixon_snmp_table_handler(netsnmp_mib_handler *handler, cbuf *cb = NULL; int ret; - clicon_debug(2, "%s", __FUNCTION__); + clicon_debug(1, "%s", __FUNCTION__); if ((ret = snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 1)) < 0) goto done; switch(reqinfo->mode){ - case MODE_GETNEXT:{ // 160 -#ifdef NOTYET - char *oidstr = NULL; - oid oid1[MAX_OID_LEN] = {0,}; - size_t sz1 = MAX_OID_LEN; - - oidstr = ".1.3.6.1.2.1.2.2.1.1.1"; - if (snmp_parse_oid(oidstr, oid1, &sz1) == NULL){ - clicon_err(OE_XML, errno, "snmp_parse_oid"); + case MODE_GETNEXT: // 160 +#ifdef SNMP_TABLE_DYNAMIC + /* Register table sub-oid:s of existing entries in clixon */ + if (mibyang_table_poll(sh->sh_h, sh->sh_ys) < 0) goto done; - } - if (snmp_set_var_objid(requests->requestvb, oid1, sz1) != 0){ - clicon_err(OE_XML, 0, "snmp_set_var_objid"); - goto done; - } #endif - } break; case MODE_GET: // 160 case MODE_SET_RESERVE1: @@ -216,6 +205,7 @@ snmp_scalar_get(clicon_handle h, int asn1type; char *reason = NULL; + clicon_debug(1, "%s", __FUNCTION__); /* Prepare backend call by constructing namespace context */ if (xml_nsctx_yang(ys, &nsc) < 0) goto done; diff --git a/apps/snmp/snmp_lib.c b/apps/snmp/snmp_lib.c index 1ccdec99..f4fda344 100644 --- a/apps/snmp/snmp_lib.c +++ b/apps/snmp/snmp_lib.c @@ -781,3 +781,47 @@ snmp_agent_cleanup(void) free(tclist); return 0; } + +/* Specialized SNMP error category log/err callback + * + * This function displays all negative SNMP errors on the form SNMPERR_* that are not SNMPERR_SUCCESS(=0) + * There are also positive SNMP errors on the form SNMP_ERR_* which are not properly handled below + * @param[in] handle Application-specific handle + * @param[in] suberr Application-specific handle, points to SNMP_ERR_* unless < -0x1000 in which + case they are MIB_* errors defined in agent_registry.h + * @param[out] cb Read log/error string into this buffer + * @note Some SNMP API functions sometimes returns NULL/ptr or other return values that do not fall into + * this category, then OE_SNMP should NOT be used. + */ +int +clixon_snmp_err_cb(void *handle, + int suberr, + cbuf *cb) +{ + const char *errstr; + + clicon_debug(1, "%s", __FUNCTION__); + if (suberr < 0){ + if (suberr < -CLIXON_ERR_SNMP_MIB){ + switch (suberr+CLIXON_ERR_SNMP_MIB){ + case MIB_DUPLICATE_REGISTRATION: + cprintf(cb, "Duplicate MIB registration"); + break; + case MIB_REGISTRATION_FAILED: + cprintf(cb, "MIB registration failed"); + break; + default: + cprintf(cb, "unknown MIB error %d", suberr+CLIXON_ERR_SNMP_MIB); + break; + } + } + else if ((errstr = snmp_api_errstring(suberr)) == NULL) + cprintf(cb, "unknown SNMP error %d", suberr); + else + cprintf(cb, "%s", errstr); + } + else{ /* See eg SNMP_ERR_* in snmp.h for positive error numbers, are they applicable here? */ + cprintf(cb, "unknown error %d", suberr); + } + return 0; +} diff --git a/apps/snmp/snmp_lib.h b/apps/snmp/snmp_lib.h index 1150957b..1e4bfe2f 100644 --- a/apps/snmp/snmp_lib.h +++ b/apps/snmp/snmp_lib.h @@ -41,6 +41,12 @@ extern "C" { #ifndef _SNMP_LIB_H_ #define _SNMP_LIB_H_ +/* + * Constants + */ +/* Need some way to multiplex SNMP_ and MIB errors on OE_SNMP error handler */ +#define CLIXON_ERR_SNMP_MIB 0x1000 + /* * Types */ @@ -48,7 +54,7 @@ extern "C" { */ struct clixon_snmp_handle { clicon_handle sh_h; - yang_stmt *sh_ys; + yang_stmt *sh_ys; /* Leaf for scalar, list for table */ oid sh_oid[MAX_OID_LEN]; /* OID for debug, may be removed? */ size_t sh_oidlen; char *sh_default; /* MIB default value leaf only */ @@ -77,6 +83,7 @@ int yang2xpath(yang_stmt *ys, cvec *keyvec, char **xpath); int snmp_body2oid(cxobj *xi, cg_var *cv); int snmp_agent_check(void); int snmp_agent_cleanup(void); +int clixon_snmp_err_cb(void *handle, int suberr, cbuf *cb); #endif /* _SNMP_LIB_H_ */ diff --git a/apps/snmp/snmp_main.c b/apps/snmp/snmp_main.c index 20853082..1db56424 100644 --- a/apps/snmp/snmp_main.c +++ b/apps/snmp/snmp_main.c @@ -225,7 +225,6 @@ clixon_snmp_input_cb(int s, return retval; } - /*! Init netsnmp agent connection * @param[in] h Clixon handle * @param[in] logdst Log destination, see clixon_log.h @@ -293,37 +292,6 @@ clixon_snmp_init_subagent(clicon_handle h, return retval; } -/* Specialized SNMP error category log/err callback - * - * This function displays all negative SNMP errors on the form SNMPERR_* that are not SNMPERR_SUCCESS(=0) - * There are also positive SNMP errors on the form SNMP_ERR_* which are not properly handled below - * @param[in] handle Application-specific handle - * @param[in] suberr Application-specific handle - * @param[out] cb Read log/error string into this buffer - * @note Some SNMP API functions sometimes returns NULL/ptr or other return values that do not fall into - * this category, then OE_SNMP should NOT be used. - */ -static int -clixon_snmp_err_cb(void *handle, - int suberr, - cbuf *cb) -{ - const char *errstr; - - clicon_debug(1, "%s", __FUNCTION__); - if (suberr < 0){ - if ((errstr = snmp_api_errstring(suberr)) == NULL) - cprintf(cb, "unknown error %d", suberr); - else - cprintf(cb, "%s", errstr); - } - else{ /* See eg SNMP_ERR_* in snmp.h for positive error numbers, are they applicable here? */ - cprintf(cb, "unknown error %d", suberr); - } - return 0; -} - - /*! Usage help routine * @param[in] h Clixon handle * @param[in] argv0 command line diff --git a/apps/snmp/snmp_register.c b/apps/snmp/snmp_register.c index f2a4aca1..88760f18 100644 --- a/apps/snmp/snmp_register.c +++ b/apps/snmp/snmp_register.c @@ -200,8 +200,8 @@ mibyang_leaf_register(clicon_handle h, * XXX: nhreg->agent_data */ if ((ret = netsnmp_register_instance(nhreg)) != SNMPERR_SUCCESS){ - /* XXX Failures are MIB_REGISTRATION_FAILED and MIB_DUPLICATE_REGISTRATION. */ - clicon_err(OE_SNMP, ret, "netsnmp_register_instance"); + /* Note MIB_ errors, not regular SNMPERR_ */ + clicon_err(OE_SNMP, ret-CLIXON_ERR_SNMP_MIB, "netsnmp_register_instance"); goto done; } clicon_debug(1, "%s %s registered", __FUNCTION__, cbuf_get(cboid)); @@ -232,7 +232,6 @@ mibyang_leaf_register(clicon_handle h, */ static int mibyang_table_register(clicon_handle h, - yang_stmt *ys, yang_stmt *ylist) { int retval = -1; @@ -250,7 +249,13 @@ mibyang_table_register(clicon_handle h, char *keyname; yang_stmt *yleaf; int asn1type; - + yang_stmt *ys; + + if ((ys = yang_parent_get(ylist)) == NULL || + yang_keyword_get(ys) != Y_CONTAINER){ + clicon_err(OE_YANG, EINVAL, "ylist parent is not list"); + goto done; + } /* Get OID from parent container */ if (yang_extension_value(ys, "oid", IETF_YANG_SMIV2_NS, NULL, &oidstr) < 0) goto done; @@ -271,7 +276,7 @@ mibyang_table_register(clicon_handle h, } memset(sh, 0, sizeof(*sh)); sh->sh_h = h; - sh->sh_ys = ys; + sh->sh_ys = ylist; memcpy(sh->sh_oid, oid1, sizeof(oid1)); sh->sh_oidlen = sz1; @@ -357,10 +362,9 @@ mibyang_table_register(clicon_handle h, * @retval 0 OK * @retval -1 Error */ -static int -mibyang_table_traverse_static(clicon_handle h, - yang_stmt *ys, - yang_stmt *ylist) +int +mibyang_table_poll(clicon_handle h, + yang_stmt *ylist) { int retval = -1; cvec *nsc = NULL; @@ -378,8 +382,14 @@ mibyang_table_traverse_static(clicon_handle h, cg_var *cv; int i; cxobj *xi; + yang_stmt *ys; - clicon_debug(1, "%s %s", __FUNCTION__, yang_argument_get(ys)); + clicon_debug(1, "%s", __FUNCTION__); + if ((ys = yang_parent_get(ylist)) == NULL || + yang_keyword_get(ys) != Y_CONTAINER){ + clicon_err(OE_YANG, EINVAL, "ylist parent is not list"); + goto done; + } if (xml_nsctx_yang(ys, &nsc) < 0) goto done; if (yang2xpath(ys, NULL, &xpath) < 0) @@ -496,11 +506,13 @@ mibyang_traverse(clicon_handle h, yp = yang_parent_get(yn); if (yang_keyword_get(yp) == Y_CONTAINER){ /* Register table entry handler itself (not column/row leafs) */ - if (mibyang_table_register(h, yp, yn) < 0) + if (mibyang_table_register(h, yn) < 0) goto done; +#ifndef SNMP_TABLE_DYNAMIC /* Register table sub-oid:s of existing entries in clixon */ - if (mibyang_table_traverse_static(h, yp, yn) < 0) + if (mibyang_table_poll(h, yn) < 0) goto done; +#endif goto ok; } break; diff --git a/apps/snmp/snmp_register.h b/apps/snmp/snmp_register.h index 3252d6a7..38f155bf 100644 --- a/apps/snmp/snmp_register.h +++ b/apps/snmp/snmp_register.h @@ -44,6 +44,7 @@ extern "C" { /* * Prototypes */ +int mibyang_table_poll(clicon_handle h, yang_stmt *ylist); int clixon_snmp_traverse_mibyangs(clicon_handle h); #endif /* _SNMP_REGISTER_H_ */ diff --git a/include/clixon_custom.h b/include/clixon_custom.h index 1f08ea06..064d8973 100644 --- a/include/clixon_custom.h +++ b/include/clixon_custom.h @@ -163,5 +163,3 @@ * If not set, client will exit */ #define PROTO_RESTART_RECONNECT - -