Merge branch 'snmp' of https://github.com/clicon/clixon into snmp

This commit is contained in:
Kristofer Hallin 2022-06-11 16:58:56 +02:00
commit 5711bfec3b
5 changed files with 230 additions and 163 deletions

View file

@ -103,75 +103,18 @@ snmp_common_handler(netsnmp_mib_handler *handler,
clicon_debug(1, "%s \"%s\" %s inclusive:%d %s", __FUNCTION__, clicon_debug(1, "%s \"%s\" %s inclusive:%d %s", __FUNCTION__,
oidstr2, oidstr2,
snmp_msg_int2str(reqinfo->mode), snmp_msg_int2str(reqinfo->mode),
requests->inclusive, tablehandler?"table":""); requests->inclusive, tablehandler?"table":"scalar");
else else
clicon_debug(1, "%s \"%s\"/\"%s\" %s inclusive:%d %s", __FUNCTION__, clicon_debug(1, "%s \"%s\"/\"%s\" %s inclusive:%d %s", __FUNCTION__,
oidstr2, oidstr0, oidstr2, oidstr0,
snmp_msg_int2str(reqinfo->mode), snmp_msg_int2str(reqinfo->mode),
requests->inclusive, tablehandler?"table":""); requests->inclusive, tablehandler?"table":"scalar");
retval = 0; retval = 0;
done: done:
return retval; return retval;
} }
/*! SNMP table operation handler
* Callorder: 161,160,.... 0, 1,2,3, 160,161,...
* see https://net-snmp.sourceforge.io/dev/agent/data_set_8c-example.html#_a0
*
* see table_array.[ch] simplify the task of
* writing a table handler for the net-snmp agent when the data being
* accessed is in an oid sorted form and must be accessed externally.
*
* netsnmp_table_build_oid_from_index()
*
* table_container.[ch]
*
* build_new_oid
*/
int
clixon_snmp_table_handler(netsnmp_mib_handler *handler,
netsnmp_handler_registration *nhreg,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
int retval = -1;
clixon_snmp_handle *sh = NULL;
cvec *nsc = NULL;
cxobj *xt = NULL;
cbuf *cb = NULL;
int ret;
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 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;
#endif
break;
case MODE_GET: // 160
case MODE_SET_RESERVE1:
case MODE_SET_RESERVE2:
case MODE_SET_ACTION:
case MODE_SET_COMMIT:
break;
}
// ok:
retval = SNMP_ERR_NOERROR;
done:
if (xt)
xml_free(xt);
if (cb)
cbuf_free(cb);
if (nsc)
xml_nsctx_free(nsc);
return retval;
}
/*! Scalar handler, set a value to clixon /*! Scalar handler, set a value to clixon
* get xpath: see yang2api_path_fmt / api_path2xpath * get xpath: see yang2api_path_fmt / api_path2xpath
@ -356,18 +299,16 @@ clixon_snmp_scalar_handler(netsnmp_mib_handler *handler,
{ {
int retval = -1; int retval = -1;
clixon_snmp_handle *sh = NULL; clixon_snmp_handle *sh = NULL;
yang_stmt *ys;
int asn1_type; int asn1_type;
netsnmp_variable_list *requestvb = requests->requestvb; netsnmp_variable_list *requestvb = requests->requestvb;
clicon_debug(2, "%s", __FUNCTION__); clicon_debug(2, "%s", __FUNCTION__);
if (snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 0) < 0) if (snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 0) < 0)
goto done; goto done;
ys = sh->sh_ys;
/* see net-snmp/agent/snmp_agent.h / net-snmp/library/snmp.h */ /* see net-snmp/agent/snmp_agent.h / net-snmp/library/snmp.h */
switch (reqinfo->mode) { switch (reqinfo->mode) {
case MODE_GET: /* 160 */ case MODE_GET: /* 160 */
if (snmp_scalar_get(sh->sh_h, ys, sh->sh_cvk_orig, if (snmp_scalar_get(sh->sh_h, sh->sh_ys, sh->sh_cvk_orig,
requestvb, sh->sh_default, reqinfo, requests) < 0) requestvb, sh->sh_default, reqinfo, requests) < 0)
goto done; goto done;
break; break;
@ -376,7 +317,7 @@ clixon_snmp_scalar_handler(netsnmp_mib_handler *handler,
break; break;
case MODE_SET_RESERVE1: /* 0 */ case MODE_SET_RESERVE1: /* 0 */
/* Translate from YANG ys leaf type to SNMP asn1.1 type ids (not value), also cvtype */ /* Translate from YANG ys leaf type to SNMP asn1.1 type ids (not value), also cvtype */
if (type_yang2asn1(ys, &asn1_type, 0) < 0) if (type_yang2asn1(sh->sh_ys, &asn1_type, 0) < 0)
goto done; goto done;
if (requestvb->type != asn1_type){ if (requestvb->type != asn1_type){
clicon_debug(1, "%s Expected type:%d, got: %d", __FUNCTION__, requestvb->type, asn1_type); clicon_debug(1, "%s Expected type:%d, got: %d", __FUNCTION__, requestvb->type, asn1_type);
@ -387,7 +328,7 @@ clixon_snmp_scalar_handler(netsnmp_mib_handler *handler,
case MODE_SET_RESERVE2: /* 1 */ case MODE_SET_RESERVE2: /* 1 */
break; break;
case MODE_SET_ACTION: /* 2 */ case MODE_SET_ACTION: /* 2 */
if (snmp_scalar_set(sh->sh_h, ys, requestvb, reqinfo, requests) < 0) if (snmp_scalar_set(sh->sh_h, sh->sh_ys, requestvb, reqinfo, requests) < 0)
goto done; goto done;
break; break;
case MODE_SET_UNDO: /* 5 */ case MODE_SET_UNDO: /* 5 */
@ -406,3 +347,83 @@ clixon_snmp_scalar_handler(netsnmp_mib_handler *handler,
done: done:
return retval; return retval;
} }
/*! SNMP table operation handler
* Callorder: 161,160,.... 0, 1,2,3, 160,161,...
* see https://net-snmp.sourceforge.io/dev/agent/data_set_8c-example.html#_a0
*
* see table_array.[ch] simplify the task of
* writing a table handler for the net-snmp agent when the data being
* accessed is in an oid sorted form and must be accessed externally.
*
* netsnmp_table_build_oid_from_index()
*
* table_container.[ch]
*
* build_new_oid
*/
int
clixon_snmp_table_handler(netsnmp_mib_handler *handler,
netsnmp_handler_registration *nhreg,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
int retval = -1;
clixon_snmp_handle *sh = NULL;
cvec *nsc = NULL;
cxobj *xt = NULL;
cbuf *cb = NULL;
int ret;
clicon_debug(2, "%s", __FUNCTION__);
if ((ret = snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 1)) < 0)
goto done;
if (sh->sh_ys == NULL){
clicon_debug(1, "%s Error table not registered", __FUNCTION__);
goto ok;
}
switch(reqinfo->mode){
case MODE_GET: // 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 1
{
if ((ret = netsnmp_call_next_handler(handler, nhreg, reqinfo, requests)) < 0){
clicon_err(OE_SNMP, ret, "netsnmp_call_next_handler");
goto done;
}
}
#endif
// Wrong sh, need to make another call
// if (snmp_scalar_get(sh->sh_h, sh->sh_ys, sh->sh_cvk_orig,
// requestvb, sh->sh_default, reqinfo, requests) < 0)
#endif
// Then try and get actual scalar
break;
case MODE_GETNEXT: // 161
#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;
#endif
break;
case MODE_SET_RESERVE1:
case MODE_SET_RESERVE2:
case MODE_SET_ACTION:
case MODE_SET_COMMIT:
break;
}
ok:
retval = SNMP_ERR_NOERROR;
done:
if (xt)
xml_free(xt);
if (cb)
cbuf_free(cb);
if (nsc)
xml_nsctx_free(nsc);
return retval;
}

View file

@ -94,8 +94,6 @@ static const map_str2int snmp_access_map[] = {
/* Map between clixon and ASN.1 types. /* Map between clixon and ASN.1 types.
* @see net-snmp/library/asn1.h * @see net-snmp/library/asn1.h
* @see union netsnmp_vardata in net-snmp/types.h * @see union netsnmp_vardata in net-snmp/types.h
* XXX not complete
* XXX TimeTicks
*/ */
static const map_str2int snmp_type_map[] = { static const map_str2int snmp_type_map[] = {
{"int32", ASN_INTEGER}, // 2 {"int32", ASN_INTEGER}, // 2
@ -109,8 +107,27 @@ static const map_str2int snmp_type_map[] = {
{NULL, -1} {NULL, -1}
}; };
#define CLIXON_ASN_PHYS_ADDR 0x4242 /* Special case phy-address */ //#define CLIXON_ASN_PHYS_ADDR 0x4242 /* Special case phy-address */
#define CLIXON_ASN_ADMIN_STRING 0x4243 /* Special case SnmpAdminString */ //#define CLIXON_ASN_ADMIN_STRING 0x4243 /* Special case SnmpAdminString */
#define CLIXON_ASN_PHYS_ADDR 253 /* Special case phy-address */
#define CLIXON_ASN_ADMIN_STRING 254 /* Special case SnmpAdminString */
/* Map between clixon "orig" resolved type and ASN.1 types.
*/
static const map_str2int snmp_orig_map[] = {
{"counter32", ASN_COUNTER}, // 0x41 / 65
{"object-identifier-128", ASN_OBJECT_ID}, // 6
{"AutonomousType", ASN_OBJECT_ID}, // 6
{"DateAndTime", ASN_OCTET_STR}, // 4
{"UUIDorZero", ASN_OCTET_STR}, // 4
{"binary", ASN_OCTET_STR}, // 4
{"timeticks", ASN_TIMETICKS}, // 0x43 / 67
{"timestamp", ASN_TIMETICKS}, // 0x43 / 67
{"InetAddress", ASN_IPADDRESS}, // 0x40 / 64
{"phys-address", CLIXON_ASN_PHYS_ADDR}, /* Clixon extended string type */
{"SnmpAdminString", CLIXON_ASN_ADMIN_STRING}, /* cf extension display-type 255T? */
{NULL, -1}
};
/* Map between SNMP message / mode str and int form /* Map between SNMP message / mode str and int form
*/ */
@ -139,6 +156,18 @@ snmp_msg_int2str(int msg)
{ {
return clicon_int2str(snmp_msg_map, msg); return clicon_int2str(snmp_msg_map, msg);
} }
/*! Should be netsnmp lib function, cant find it
*/
int
oid_eq(const oid *objid0,
size_t objid0len,
const oid *objid1,
size_t objid1len)
{
if (objid0len != objid1len)
return 0;
return memcmp(objid0, objid1, objid0len*sizeof(*objid0));
}
/*! Duplicate clixon snmp handler struct /*! Duplicate clixon snmp handler struct
* Use signature of libnetsnmp data_clone field of netsnmp_mib_handler in agent_handler.h * Use signature of libnetsnmp data_clone field of netsnmp_mib_handler in agent_handler.h
@ -238,40 +267,14 @@ type_yang2asn1(yang_stmt *ys,
goto done; goto done;
restype = yrestype?yang_argument_get(yrestype):NULL; restype = yrestype?yang_argument_get(yrestype):NULL;
} }
/* Special case: counter32, maps to same resolved type as gauge32 */ /* Translate to asn.1
if (strcmp(origtype, "counter32")==0){ * First try original type, first type
at = ASN_COUNTER; */
if ((at = clicon_str2int(snmp_orig_map, origtype)) >= 0 &&
(extended || (at != CLIXON_ASN_PHYS_ADDR && at != CLIXON_ASN_ADMIN_STRING))){
;
} }
else if (strcmp(origtype, "object-identifier-128") == 0 || /* Then try fully resolved type */
strcmp(origtype, "AutonomousType") == 0){
at = ASN_OBJECT_ID;
}
else if (strcmp(origtype, "binary")==0){
at = ASN_OCTET_STR;
}
else if (strcmp(origtype, "timeticks")==0){
at = ASN_TIMETICKS;
}
else if (strcmp(origtype, "DateAndTime")==0) {
at = ASN_OCTET_STR;
}
else if (strcmp(origtype, "UUIDorZero")==0) {
at = ASN_OCTET_STR;
}
else if (strcmp(origtype, "timestamp")==0){
at = ASN_TIMETICKS;
}
else if (strcmp(origtype, "InetAddress")==0){
at = ASN_IPADDRESS;
}
else if (extended && strcmp(origtype, "phys-address")==0){
at = CLIXON_ASN_PHYS_ADDR; /* Clixon extended string type */
}
else if (extended && strcmp(origtype, "SnmpAdminString")==0){
at = CLIXON_ASN_ADMIN_STRING; /* cf extension display-type 255T? */
}
/* translate to asn.1 */
else if ((at = clicon_str2int(snmp_type_map, restype)) < 0){ else if ((at = clicon_str2int(snmp_type_map, restype)) < 0){
clicon_err(OE_YANG, 0, "No snmp translation for YANG %s type:%s", clicon_err(OE_YANG, 0, "No snmp translation for YANG %s type:%s",
yang_argument_get(ys), restype); yang_argument_get(ys), restype);
@ -364,6 +367,10 @@ type_snmp2xml(yang_stmt *ys,
case ASN_GAUGE: // 0x42 case ASN_GAUGE: // 0x42
cv_uint32_set(cv, *requestvb->val.integer); cv_uint32_set(cv, *requestvb->val.integer);
break; break;
case CLIXON_ASN_ADMIN_STRING: // XXX
case CLIXON_ASN_PHYS_ADDR: // XXX
assert(0);
break;
case ASN_OCTET_STR: // 4 case ASN_OCTET_STR: // 4
cv_string_set(cv, (char*)requestvb->val.string); cv_string_set(cv, (char*)requestvb->val.string);
break; break;
@ -758,45 +765,17 @@ snmp_body2oid(cxobj *xi,
return retval; return retval;
} }
/*========== libnetsnmp-specific code =============== /*! Specialized SNMP error category log/err callback
* Peeks into internal lib global variables, may be sensitive to library change
*/
/*! Check if netsnmp is connected
* @retval 1 yes, running
* @retval 0 No, not running
* XXX: this peeks into the "main_session" global variable in agent/snmp_agent.c
* Tried to find API function but failed
*/
int
snmp_agent_check(void)
{
extern netsnmp_session *main_session;
return (main_session != NULL) ? 1 : 0;
}
/*! Cleanup remaining libnetsnmb memory
* XXX: this peeks into the "tclist" global variable in snmplib/parse.c
* Tried to find API function but failed
*/
int
snmp_agent_cleanup(void)
{
extern void *tclist;
if (tclist)
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) * This function displays all negative SNMP errors on the form SNMPERR_* that are not
* There are also positive SNMP errors on the form SNMP_ERR_* which are not properly handled below * 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] handle Application-specific handle
* @param[in] suberr Application-specific handle, points to SNMP_ERR_* unless < -0x1000 in which * @param[in] suberr Application-specific handle, points to SNMP_ERR_* unless
case they are MIB_* errors defined in agent_registry.h < CLIXON_ERR_SNMP_MIB in which case they are MIB_* errors defined
* @param[out] cb Read log/error string into this buffer 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 * @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. * this category, then OE_SNMP should NOT be used.
*/ */
@ -832,3 +811,60 @@ clixon_snmp_err_cb(void *handle,
} }
return 0; return 0;
} }
/*========== libnetsnmp-specific code ===============
* Peeks into internal lib global variables, may be sensitive to library change
*/
/*! Check if netsnmp is connected
* @retval 1 yes, running
* @retval 0 No, not running
* XXX: this peeks into the "main_session" global variable in agent/snmp_agent.c
* Tried to find API function but failed
*/
int
clixon_snmp_api_agent_check(void)
{
extern netsnmp_session *main_session;
return (main_session != NULL) ? 1 : 0;
}
/*! Cleanup remaining libnetsnmb memory
* XXX: this peeks into the "tclist" global variable in snmplib/parse.c
* Tried to find API function but failed
*/
int
clixon_snmp_api_agent_cleanup(void)
{
extern void *tclist;
if (tclist)
free(tclist);
return 0;
}
/*! See if oid is registered
* This is good enough for add,
* But for delete a more advanced function is needed
* @see netsnmp_subtree_load
* @retval -1 Error
* @retval 0 Not found
* @retval 1 Found
*/
int
clixon_snmp_api_oid_find(oid *oid0,
size_t oid0len)
{
int retval = -1;
netsnmp_subtree *tree1 = NULL;
if ((tree1 = netsnmp_subtree_find(oid0, oid0len, NULL, "")) != NULL &&
oid_eq(oid0, oid0len, tree1->name_a, tree1->namelen)){
fprintf(stderr, "%s EQUAL==================\n", __FUNCTION__);
retval = 1;
}
else
retval = 0;
// done:
return retval;
}

View file

@ -67,23 +67,28 @@ typedef struct clixon_snmp_handle clixon_snmp_handle;
/* /*
* Prototypes * Prototypes
*/ */
int snmp_access_str2int(char *modes_str);
int oid_eq(const oid * objid0, size_t objid0len, const oid * objid1, size_t objid1len);
int snmp_access_str2int(char *modes_str);
const char *snmp_msg_int2str(int msg); const char *snmp_msg_int2str(int msg);
void *snmp_handle_clone(void *arg); void *snmp_handle_clone(void *arg);
void snmp_handle_free(void *arg); void snmp_handle_free(void *arg);
int type_yang2asn1(yang_stmt *ys, int *asn1_type, int extended); int type_yang2asn1(yang_stmt *ys, int *asn1_type, int extended);
int type_snmp2xml(yang_stmt *ys, int type_snmp2xml(yang_stmt *ys,
netsnmp_variable_list *requestvb, netsnmp_variable_list *requestvb,
netsnmp_agent_request_info *reqinfo, netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests, netsnmp_request_info *requests,
char **valstr); char **valstr);
int type_xml2snmp_pre(char *xmlstr, yang_stmt *ys, char **snmpstr); int type_xml2snmp_pre(char *xmlstr, yang_stmt *ys, char **snmpstr);
int type_xml2snmp(char *snmpstr, int *asn1type, u_char **snmpval, size_t *snmplen, char **reason); int type_xml2snmp(char *snmpstr, int *asn1type, u_char **snmpval, size_t *snmplen, char **reason);
int yang2xpath(yang_stmt *ys, cvec *keyvec, char **xpath); 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 clixon_snmp_err_cb(void *handle, int suberr, cbuf *cb);
int snmp_agent_cleanup(void);
int clixon_snmp_err_cb(void *handle, int suberr, cbuf *cb); /*========== libnetsnmp-specific code =============== */
int clixon_snmp_api_agent_check(void);
int clixon_snmp_api_agent_cleanup(void);
int clixon_snmp_api_oid_find(oid *oid1, size_t oidlen);
#endif /* _SNMP_LIB_H_ */ #endif /* _SNMP_LIB_H_ */

View file

@ -110,7 +110,7 @@ snmp_terminate(clicon_handle h)
snmp_shutdown(__FUNCTION__); snmp_shutdown(__FUNCTION__);
shutdown_agent(); shutdown_agent();
snmp_agent_cleanup(); clixon_snmp_api_agent_cleanup();
clicon_rpc_close_session(h); clicon_rpc_close_session(h);
if ((yspec = clicon_dbspec_yang(h)) != NULL) if ((yspec = clicon_dbspec_yang(h)) != NULL)
ys_free(yspec); ys_free(yspec);
@ -267,7 +267,7 @@ clixon_snmp_init_subagent(clicon_handle h,
/* example-demon will be used to read example-demon.conf files. */ /* example-demon will be used to read example-demon.conf files. */
init_snmp(__PROGRAM__); init_snmp(__PROGRAM__);
if (!snmp_agent_check()){ if (!clixon_snmp_api_agent_check()){
clicon_err(OE_DAEMON, 0, "Connection to SNMP agent failed"); clicon_err(OE_DAEMON, 0, "Connection to SNMP agent failed");
goto done; goto done;
} }

View file

@ -95,6 +95,7 @@
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
* netsnmp_subtree_find(oid1,sz1, 0, 0)
*/ */
static int static int
mibyang_leaf_register(clicon_handle h, mibyang_leaf_register(clicon_handle h,
@ -110,7 +111,7 @@ mibyang_leaf_register(clicon_handle h,
char *default_str = NULL; char *default_str = NULL;
char *oidstr = NULL; char *oidstr = NULL;
oid oid1[MAX_OID_LEN] = {0,}; oid oid1[MAX_OID_LEN] = {0,};
size_t sz1 = MAX_OID_LEN; size_t oid1len = MAX_OID_LEN;
int modes; int modes;
char *name; char *name;
clixon_snmp_handle *sh; clixon_snmp_handle *sh;
@ -132,11 +133,14 @@ mibyang_leaf_register(clicon_handle h,
cvi = NULL; cvi = NULL;
while ((cvi = cvec_each(cvk_oid, cvi)) != NULL) while ((cvi = cvec_each(cvk_oid, cvi)) != NULL)
cprintf(cboid, ".%s", cv_string_get(cvi)); cprintf(cboid, ".%s", cv_string_get(cvi));
if (snmp_parse_oid(cbuf_get(cboid), oid1, &sz1) == NULL){ if (snmp_parse_oid(cbuf_get(cboid), oid1, &oid1len) == NULL){
clicon_err(OE_XML, 0, "snmp_parse_oid(%s)", cbuf_get(cboid)); clicon_err(OE_XML, 0, "snmp_parse_oid(%s)", cbuf_get(cboid));
// goto done; // goto done;
goto ok; // XXX skip goto ok; // XXX skip
} }
/* Check if already registered */
if (clixon_snmp_api_oid_find(oid1, oid1len) == 1)
goto ok;
if (yang_extension_value(ys, "max-access", IETF_YANG_SMIV2_NS, NULL, &modes_str) < 0) if (yang_extension_value(ys, "max-access", IETF_YANG_SMIV2_NS, NULL, &modes_str) < 0)
goto done; goto done;
/* Only for sanity check of types initially to fail early */ /* Only for sanity check of types initially to fail early */
@ -155,7 +159,7 @@ mibyang_leaf_register(clicon_handle h,
goto done; goto done;
name = yang_argument_get(ys); name = yang_argument_get(ys);
/* Stateless function, just returns ptr */
if ((handler = netsnmp_create_handler(name, clixon_snmp_scalar_handler)) == NULL){ if ((handler = netsnmp_create_handler(name, clixon_snmp_scalar_handler)) == NULL){
clicon_err(OE_XML, errno, "netsnmp_create_handler"); clicon_err(OE_XML, errno, "netsnmp_create_handler");
goto done; goto done;
@ -172,7 +176,7 @@ mibyang_leaf_register(clicon_handle h,
sh->sh_h = h; sh->sh_h = h;
sh->sh_ys = ys; sh->sh_ys = ys;
memcpy(sh->sh_oid, oid1, sizeof(oid1)); memcpy(sh->sh_oid, oid1, sizeof(oid1));
sh->sh_oidlen = sz1; sh->sh_oidlen = oid1len;
sh->sh_default = default_str; sh->sh_default = default_str;
if (cvk_orig && if (cvk_orig &&
(sh->sh_cvk_orig = cvec_dup(cvk_orig)) == NULL){ (sh->sh_cvk_orig = cvec_dup(cvk_orig)) == NULL){
@ -184,8 +188,9 @@ mibyang_leaf_register(clicon_handle h,
clicon_err(OE_UNIX, errno, "cvec_dup"); clicon_err(OE_UNIX, errno, "cvec_dup");
goto done; goto done;
} }
/* Stateless function, just returns ptr */
if ((nhreg = netsnmp_handler_registration_create(name, handler, if ((nhreg = netsnmp_handler_registration_create(name, handler,
oid1, sz1, oid1, oid1len,
modes)) == NULL){ modes)) == NULL){
clicon_err(OE_XML, errno, "netsnmp_handler_registration_create"); clicon_err(OE_XML, errno, "netsnmp_handler_registration_create");
netsnmp_handler_free(handler); netsnmp_handler_free(handler);
@ -238,7 +243,7 @@ mibyang_table_register(clicon_handle h,
netsnmp_handler_registration *nhreg; netsnmp_handler_registration *nhreg;
char *oidstr = NULL; char *oidstr = NULL;
oid oid1[MAX_OID_LEN] = {0,}; oid oid1[MAX_OID_LEN] = {0,};
size_t sz1 = MAX_OID_LEN; size_t oid1len = MAX_OID_LEN;
char *name; char *name;
clixon_snmp_handle *sh; clixon_snmp_handle *sh;
int ret; int ret;
@ -261,7 +266,7 @@ mibyang_table_register(clicon_handle h,
goto done; goto done;
if (oidstr == NULL) if (oidstr == NULL)
goto ok; goto ok;
if (snmp_parse_oid(oidstr, oid1, &sz1) == NULL){ if (snmp_parse_oid(oidstr, oid1, &oid1len) == NULL){
clicon_err(OE_XML, errno, "snmp_parse_oid"); clicon_err(OE_XML, errno, "snmp_parse_oid");
goto done; goto done;
} }
@ -279,14 +284,14 @@ mibyang_table_register(clicon_handle h,
sh->sh_ys = ylist; 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 = oid1len;
if ((handler = netsnmp_create_handler(name, clixon_snmp_table_handler)) == NULL){ if ((handler = netsnmp_create_handler(name, clixon_snmp_table_handler)) == NULL){
clicon_err(OE_XML, errno, "netsnmp_create_handler"); clicon_err(OE_XML, errno, "netsnmp_create_handler");
goto done; goto done;
} }
if ((nhreg = netsnmp_handler_registration_create(name, handler, if ((nhreg = netsnmp_handler_registration_create(name, handler,
oid1, sz1, oid1, oid1len,
HANDLER_CAN_RWRITE)) == NULL){ HANDLER_CAN_RWRITE)) == NULL){
clicon_err(OE_XML, errno, "netsnmp_handler_registration_create"); clicon_err(OE_XML, errno, "netsnmp_handler_registration_create");
netsnmp_handler_free(handler); netsnmp_handler_free(handler);