SNMP frontend: String table index

This commit is contained in:
Olof hagsand 2022-06-06 18:14:21 +02:00
parent a0e6536bab
commit 78c070b65b
4 changed files with 66 additions and 31 deletions

View file

@ -377,7 +377,7 @@ clixon_snmp_scalar_handler(netsnmp_mib_handler *handler,
/* 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, if (snmp_scalar_get(sh->sh_h, 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;

View file

@ -157,8 +157,13 @@ snmp_handle_clone(void *arg)
return NULL; return NULL;
} }
memset(sh1, 0, sizeof(*sh1)); memset(sh1, 0, sizeof(*sh1));
if (sh0->sh_cvk && if (sh0->sh_cvk_orig &&
(sh1->sh_cvk = cvec_dup(sh0->sh_cvk)) == NULL){ (sh1->sh_cvk_orig = cvec_dup(sh0->sh_cvk_orig)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_dup");
return NULL;
}
if (sh0->sh_cvk_oid &&
(sh1->sh_cvk_oid = cvec_dup(sh0->sh_cvk_oid)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_dup"); clicon_err(OE_UNIX, errno, "cvec_dup");
return NULL; return NULL;
} }
@ -175,8 +180,10 @@ snmp_handle_free(void *arg)
clixon_snmp_handle *sh = (clixon_snmp_handle *)arg; clixon_snmp_handle *sh = (clixon_snmp_handle *)arg;
if (sh != NULL){ if (sh != NULL){
if (sh->sh_cvk) if (sh->sh_cvk_orig)
cvec_free(sh->sh_cvk); cvec_free(sh->sh_cvk_orig);
if (sh->sh_cvk_oid)
cvec_free(sh->sh_cvk_oid);
if (sh->sh_table_info){ if (sh->sh_table_info){
if (sh->sh_table_info->indexes){ if (sh->sh_table_info->indexes){
snmp_free_varbind(sh->sh_table_info->indexes); snmp_free_varbind(sh->sh_table_info->indexes);
@ -685,7 +692,9 @@ yang2xpath(yang_stmt *ys,
return retval; return retval;
} }
/*! /*! Translate from xml body to OID
* For ints this is one to one, eg 42 -> 42
* But for eg strings this is more comples, eg foo -> 3.6.22.22 (or something,...)
*/ */
int int
snmp_body2oid(cxobj *xi, snmp_body2oid(cxobj *xi,

View file

@ -52,7 +52,8 @@ struct clixon_snmp_handle {
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 */
cvec *sh_cvk; /* Index/Key variables */ cvec *sh_cvk_orig; /* Index/Key variables (original) */
cvec *sh_cvk_oid; /* Index/Key variables (OID translated) */
netsnmp_table_registration_info *sh_table_info; /* To mimic table-handler in libnetsnmp code*/ netsnmp_table_registration_info *sh_table_info; /* To mimic table-handler in libnetsnmp code*/
}; };
typedef struct clixon_snmp_handle clixon_snmp_handle; typedef struct clixon_snmp_handle clixon_snmp_handle;

View file

@ -90,14 +90,17 @@
* smiv2:defval "42"; (optional) * smiv2:defval "42"; (optional)
* @param[in] h Clixon handle * @param[in] h Clixon handle
* @param[in] ys Mib-Yang node * @param[in] ys Mib-Yang node
* @param[in] cvk Vector of key/index values. NB: not for scalars, only tables * @param[in] cvk_orig Vector of untranslated key/index values (eg "foo")
* @param[in] cvk_oid Vector of translated to OID key/index values. (eg "3.6.22.22")
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
*/ */
static int static int
mibyang_leaf_register(clicon_handle h, mibyang_leaf_register(clicon_handle h,
yang_stmt *ys, yang_stmt *ys,
cvec *cvk) cvec *cvk_orig,
cvec *cvk_oid)
{ {
int retval = -1; int retval = -1;
netsnmp_handler_registration *nhreg = NULL; netsnmp_handler_registration *nhreg = NULL;
@ -127,7 +130,7 @@ mibyang_leaf_register(clicon_handle h,
} }
cprintf(cboid, "%s", oidstr); cprintf(cboid, "%s", oidstr);
cvi = NULL; cvi = NULL;
while ((cvi = cvec_each(cvk, 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, &sz1) == 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));
@ -171,8 +174,13 @@ mibyang_leaf_register(clicon_handle h,
memcpy(sh->sh_oid, oid1, sizeof(oid1)); memcpy(sh->sh_oid, oid1, sizeof(oid1));
sh->sh_oidlen = sz1; sh->sh_oidlen = sz1;
sh->sh_default = default_str; sh->sh_default = default_str;
if (cvk && if (cvk_orig &&
(sh->sh_cvk = cvec_dup(cvk)) == NULL){ (sh->sh_cvk_orig = cvec_dup(cvk_orig)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_dup");
goto done;
}
if (cvk_oid &&
(sh->sh_cvk_oid = cvec_dup(cvk_oid)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_dup"); clicon_err(OE_UNIX, errno, "cvec_dup");
goto done; goto done;
} }
@ -363,9 +371,10 @@ mibyang_table_traverse_static(clicon_handle h,
cxobj *xrow; cxobj *xrow;
cxobj *xcol; cxobj *xcol;
yang_stmt *y; yang_stmt *y;
cvec *cvk0; cvec *cvk_name;
cg_var *cv0; cg_var *cv0;
cvec *cvk = NULL; /* vector of index keys */ cvec *cvk_orig = NULL; /* vector of index keys: original index */
cvec *cvk_oid = NULL; /* vector of index keys: translated to OID */
cg_var *cv; cg_var *cv;
int i; int i;
cxobj *xi; cxobj *xi;
@ -383,35 +392,48 @@ mibyang_table_traverse_static(clicon_handle h,
} }
if ((xtable = xpath_first(xt, nsc, "%s", xpath)) != NULL) { if ((xtable = xpath_first(xt, nsc, "%s", xpath)) != NULL) {
/* Make a clone of key-list, but replace names with values */ /* Make a clone of key-list, but replace names with values */
if ((cvk0 = yang_cvec_get(ylist)) == NULL){ if ((cvk_name = yang_cvec_get(ylist)) == NULL){
clicon_err(OE_YANG, 0, "No keys"); clicon_err(OE_YANG, 0, "No keys");
goto done; goto done;
} }
xrow = NULL; xrow = NULL;
while ((xrow = xml_child_each(xtable, xrow, CX_ELMNT)) != NULL) { while ((xrow = xml_child_each(xtable, xrow, CX_ELMNT)) != NULL) {
if (cvk){ if (cvk_orig){
cvec_free(cvk); cvec_free(cvk_orig);
cvk = NULL; cvk_orig = NULL;
} }
if ((cvk = cvec_dup(cvk0)) == NULL){ if ((cvk_orig = cvec_dup(cvk_name)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_dup"); clicon_err(OE_UNIX, errno, "cvec_dup");
goto done; goto done;
} }
for (i=0; i<cvec_len(cvk0); i++){ if (cvk_oid){
cv0 = cvec_i(cvk0, i); cvec_free(cvk_oid);
cv = cvec_i(cvk, i); cvk_oid = NULL;
}
if ((cvk_oid = cvec_dup(cvk_name)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_dup");
goto done;
}
for (i=0; i<cvec_len(cvk_name); i++){
cv0 = cvec_i(cvk_name, i);
if ((xi = xml_find_type(xrow, NULL, cv_string_get(cv0), CX_ELMNT)) == NULL) if ((xi = xml_find_type(xrow, NULL, cv_string_get(cv0), CX_ELMNT)) == NULL)
break; break;
cv = cvec_i(cvk_orig, i);
if (cv_string_set(cv, xml_body(xi)) < 0){
clicon_err(OE_UNIX, errno, "cv_string_set");
goto done;
}
cv = cvec_i(cvk_oid, i);
if (snmp_body2oid(xi, cv) < 0) if (snmp_body2oid(xi, cv) < 0)
goto done; goto done;
} }
if (i<cvec_len(cvk0)) if (i<cvec_len(cvk_name))
continue; /* skip row, not all indexes */ continue; /* skip row, not all indexes */
xcol = NULL; xcol = NULL;
while ((xcol = xml_child_each(xrow, xcol, CX_ELMNT)) != NULL) { while ((xcol = xml_child_each(xrow, xcol, CX_ELMNT)) != NULL) {
if ((y = xml_spec(xcol)) == NULL) if ((y = xml_spec(xcol)) == NULL)
continue; continue;
if (mibyang_leaf_register(h, y, cvk) < 0) if (mibyang_leaf_register(h, y, cvk_orig, cvk_oid) < 0)
goto done; goto done;
} }
} }
@ -420,8 +442,11 @@ mibyang_table_traverse_static(clicon_handle h,
done: done:
if (xpath) if (xpath)
free(xpath); free(xpath);
if (cvk) if (cvk_orig)
cvec_free(cvk); cvec_free(cvk_orig);
if (cvk_oid)
cvec_free(cvk_oid);
if (xt) if (xt)
xml_free(xt); xml_free(xt);
if (nsc) if (nsc)
@ -462,7 +487,7 @@ mibyang_traverse(clicon_handle h,
clicon_debug(1, "%s %s", __FUNCTION__, yang_argument_get(yn)); clicon_debug(1, "%s %s", __FUNCTION__, yang_argument_get(yn));
switch(yang_keyword_get(yn)){ switch(yang_keyword_get(yn)){
case Y_LEAF: case Y_LEAF:
if (mibyang_leaf_register(h, yn, NULL) < 0) if (mibyang_leaf_register(h, yn, NULL, NULL) < 0)
goto done; goto done;
break; break;
case Y_CONTAINER: /* See list case */ case Y_CONTAINER: /* See list case */