SNMP: Started register table entries dynamically
Compile-time constant: SNMP_TABLE_DYNAMIC Added MIB SNMP erroir handling
This commit is contained in:
parent
cb3aef450d
commit
b5d17d643a
7 changed files with 84 additions and 64 deletions
|
|
@ -58,6 +58,7 @@
|
|||
#include <clixon/clixon.h>
|
||||
|
||||
#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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue