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 <clixon/clixon.h>
|
||||||
|
|
||||||
#include "snmp_lib.h"
|
#include "snmp_lib.h"
|
||||||
|
#include "snmp_register.h"
|
||||||
#include "snmp_handler.h"
|
#include "snmp_handler.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -127,7 +128,6 @@ snmp_common_handler(netsnmp_mib_handler *handler,
|
||||||
* table_container.[ch]
|
* table_container.[ch]
|
||||||
*
|
*
|
||||||
* build_new_oid
|
* build_new_oid
|
||||||
* XXX Check expected return values for these netsnmp handler functions
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clixon_snmp_table_handler(netsnmp_mib_handler *handler,
|
clixon_snmp_table_handler(netsnmp_mib_handler *handler,
|
||||||
|
|
@ -142,27 +142,16 @@ clixon_snmp_table_handler(netsnmp_mib_handler *handler,
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
clicon_debug(2, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
if ((ret = snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 1)) < 0)
|
if ((ret = snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 1)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
switch(reqinfo->mode){
|
switch(reqinfo->mode){
|
||||||
case MODE_GETNEXT:{ // 160
|
case MODE_GETNEXT: // 160
|
||||||
#ifdef NOTYET
|
#ifdef SNMP_TABLE_DYNAMIC
|
||||||
char *oidstr = NULL;
|
/* Register table sub-oid:s of existing entries in clixon */
|
||||||
oid oid1[MAX_OID_LEN] = {0,};
|
if (mibyang_table_poll(sh->sh_h, sh->sh_ys) < 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");
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
if (snmp_set_var_objid(requests->requestvb, oid1, sz1) != 0){
|
|
||||||
clicon_err(OE_XML, 0, "snmp_set_var_objid");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MODE_GET: // 160
|
case MODE_GET: // 160
|
||||||
case MODE_SET_RESERVE1:
|
case MODE_SET_RESERVE1:
|
||||||
|
|
@ -216,6 +205,7 @@ snmp_scalar_get(clicon_handle h,
|
||||||
int asn1type;
|
int asn1type;
|
||||||
char *reason = NULL;
|
char *reason = NULL;
|
||||||
|
|
||||||
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
/* Prepare backend call by constructing namespace context */
|
/* Prepare backend call by constructing namespace context */
|
||||||
if (xml_nsctx_yang(ys, &nsc) < 0)
|
if (xml_nsctx_yang(ys, &nsc) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -781,3 +781,47 @@ snmp_agent_cleanup(void)
|
||||||
free(tclist);
|
free(tclist);
|
||||||
return 0;
|
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_
|
#ifndef _SNMP_LIB_H_
|
||||||
#define _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
|
* Types
|
||||||
*/
|
*/
|
||||||
|
|
@ -48,7 +54,7 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
struct clixon_snmp_handle {
|
struct clixon_snmp_handle {
|
||||||
clicon_handle sh_h;
|
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? */
|
oid sh_oid[MAX_OID_LEN]; /* OID for debug, may be removed? */
|
||||||
size_t sh_oidlen;
|
size_t sh_oidlen;
|
||||||
char *sh_default; /* MIB default value leaf only */
|
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_body2oid(cxobj *xi, cg_var *cv);
|
||||||
int snmp_agent_check(void);
|
int snmp_agent_check(void);
|
||||||
int snmp_agent_cleanup(void);
|
int snmp_agent_cleanup(void);
|
||||||
|
int clixon_snmp_err_cb(void *handle, int suberr, cbuf *cb);
|
||||||
|
|
||||||
#endif /* _SNMP_LIB_H_ */
|
#endif /* _SNMP_LIB_H_ */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,6 @@ clixon_snmp_input_cb(int s,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Init netsnmp agent connection
|
/*! Init netsnmp agent connection
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] logdst Log destination, see clixon_log.h
|
* @param[in] logdst Log destination, see clixon_log.h
|
||||||
|
|
@ -293,37 +292,6 @@ clixon_snmp_init_subagent(clicon_handle h,
|
||||||
return retval;
|
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
|
/*! Usage help routine
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] argv0 command line
|
* @param[in] argv0 command line
|
||||||
|
|
|
||||||
|
|
@ -200,8 +200,8 @@ mibyang_leaf_register(clicon_handle h,
|
||||||
* XXX: nhreg->agent_data
|
* XXX: nhreg->agent_data
|
||||||
*/
|
*/
|
||||||
if ((ret = netsnmp_register_instance(nhreg)) != SNMPERR_SUCCESS){
|
if ((ret = netsnmp_register_instance(nhreg)) != SNMPERR_SUCCESS){
|
||||||
/* XXX Failures are MIB_REGISTRATION_FAILED and MIB_DUPLICATE_REGISTRATION. */
|
/* Note MIB_ errors, not regular SNMPERR_ */
|
||||||
clicon_err(OE_SNMP, ret, "netsnmp_register_instance");
|
clicon_err(OE_SNMP, ret-CLIXON_ERR_SNMP_MIB, "netsnmp_register_instance");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
clicon_debug(1, "%s %s registered", __FUNCTION__, cbuf_get(cboid));
|
clicon_debug(1, "%s %s registered", __FUNCTION__, cbuf_get(cboid));
|
||||||
|
|
@ -232,7 +232,6 @@ mibyang_leaf_register(clicon_handle h,
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mibyang_table_register(clicon_handle h,
|
mibyang_table_register(clicon_handle h,
|
||||||
yang_stmt *ys,
|
|
||||||
yang_stmt *ylist)
|
yang_stmt *ylist)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -250,7 +249,13 @@ mibyang_table_register(clicon_handle h,
|
||||||
char *keyname;
|
char *keyname;
|
||||||
yang_stmt *yleaf;
|
yang_stmt *yleaf;
|
||||||
int asn1type;
|
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 */
|
/* Get OID from parent container */
|
||||||
if (yang_extension_value(ys, "oid", IETF_YANG_SMIV2_NS, NULL, &oidstr) < 0)
|
if (yang_extension_value(ys, "oid", IETF_YANG_SMIV2_NS, NULL, &oidstr) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -271,7 +276,7 @@ mibyang_table_register(clicon_handle h,
|
||||||
}
|
}
|
||||||
memset(sh, 0, sizeof(*sh));
|
memset(sh, 0, sizeof(*sh));
|
||||||
sh->sh_h = h;
|
sh->sh_h = h;
|
||||||
sh->sh_ys = ys;
|
sh->sh_ys = ylist;
|
||||||
|
|
||||||
memcpy(sh->sh_oid, oid1, sizeof(oid1));
|
memcpy(sh->sh_oid, oid1, sizeof(oid1));
|
||||||
sh->sh_oidlen = sz1;
|
sh->sh_oidlen = sz1;
|
||||||
|
|
@ -357,9 +362,8 @@ mibyang_table_register(clicon_handle h,
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
mibyang_table_traverse_static(clicon_handle h,
|
mibyang_table_poll(clicon_handle h,
|
||||||
yang_stmt *ys,
|
|
||||||
yang_stmt *ylist)
|
yang_stmt *ylist)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -378,8 +382,14 @@ mibyang_table_traverse_static(clicon_handle h,
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
int i;
|
int i;
|
||||||
cxobj *xi;
|
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)
|
if (xml_nsctx_yang(ys, &nsc) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (yang2xpath(ys, NULL, &xpath) < 0)
|
if (yang2xpath(ys, NULL, &xpath) < 0)
|
||||||
|
|
@ -496,11 +506,13 @@ mibyang_traverse(clicon_handle h,
|
||||||
yp = yang_parent_get(yn);
|
yp = yang_parent_get(yn);
|
||||||
if (yang_keyword_get(yp) == Y_CONTAINER){
|
if (yang_keyword_get(yp) == Y_CONTAINER){
|
||||||
/* Register table entry handler itself (not column/row leafs) */
|
/* 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;
|
goto done;
|
||||||
|
#ifndef SNMP_TABLE_DYNAMIC
|
||||||
/* Register table sub-oid:s of existing entries in clixon */
|
/* 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;
|
goto done;
|
||||||
|
#endif
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ extern "C" {
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
|
int mibyang_table_poll(clicon_handle h, yang_stmt *ylist);
|
||||||
int clixon_snmp_traverse_mibyangs(clicon_handle h);
|
int clixon_snmp_traverse_mibyangs(clicon_handle h);
|
||||||
|
|
||||||
#endif /* _SNMP_REGISTER_H_ */
|
#endif /* _SNMP_REGISTER_H_ */
|
||||||
|
|
|
||||||
|
|
@ -163,5 +163,3 @@
|
||||||
* If not set, client will exit
|
* If not set, client will exit
|
||||||
*/
|
*/
|
||||||
#define PROTO_RESTART_RECONNECT
|
#define PROTO_RESTART_RECONNECT
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue