New function, clixon_table_create which will clear a table and create any rows, indexes and columns to avoid collissions.

This commit is contained in:
Kristofer Hallin 2022-05-17 15:38:04 +02:00 committed by Olof hagsand
parent 38d91a1305
commit 338be43e6a

View file

@ -93,6 +93,79 @@ struct clixon_snmp_handle {
}; };
typedef struct clixon_snmp_handle clixon_snmp_handle; typedef struct clixon_snmp_handle clixon_snmp_handle;
int clixon_table_create(netsnmp_table_data_set *table, yang_stmt *ys, clicon_handle h)
{
cvec *nsc = NULL;
cxobj *xt = NULL;
cbuf *cb = NULL;
cxobj *xerr;
char *xpath;
cxobj *xtable;
cxobj *xe;
cxobj *xleaf;
int i;
char *valstr;
netsnmp_table_row *row, *tmprow;
if (xml_nsctx_yang(ys, &nsc) < 0)
goto done;
/* XXX just for yang2xpath */
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (yang2xpath(ys, cb) < 0)
goto done;
xpath = cbuf_get(cb);
if (clicon_rpc_get(h, xpath, nsc, CONTENT_ALL, -1, &xt) < 0)
goto done;
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xerr, "clicon_rpc_get", NULL);
goto done;
}
netsnmp_table_dataset_add_index(table, ASN_OCTET_STR);
netsnmp_table_set_multi_add_default_row(table, 2, ASN_OCTET_STR, 1, NULL, 0, 3, ASN_OCTET_STR, 1, NULL, 0, 0);
if ((xtable = xpath_first(xt, nsc, "%s", xpath)) != NULL) {
for (tmprow = table->table->first_row; tmprow; tmprow = tmprow->next)
netsnmp_table_dataset_remove_and_delete_row(table, tmprow);
xe = NULL; /* Loop thru entries in table */
while ((xe = xml_child_each(xtable, xe, CX_ELMNT)) != NULL) {
row = netsnmp_create_table_data_row();
xleaf = NULL; /* Loop thru leafs in entry */
i = 1; /* tableindex start at 1 */
while ((xleaf = xml_child_each(xe, xleaf, CX_ELMNT)) != NULL) {
valstr = xml_body(xleaf);
if (i == 1) // Assume first netry is key XXX should check YANG
netsnmp_table_row_add_index(row, ASN_OCTET_STR, valstr, strlen(valstr));
else{
netsnmp_set_row_column(row, i, ASN_OCTET_STR, valstr, strlen(valstr));
netsnmp_mark_row_column_writable(row, i, 1);
}
i++;
}
netsnmp_table_dataset_add_row(table, row);
}
}
done:
if (xt)
xml_free(xt);
if (nsc)
xml_nsctx_free(nsc);
if (cb)
cbuf_free(cb);
return 0;
}
/*! SNMP table operation handlre /*! SNMP table operation handlre
* Callorder: 161,160,.... 0, 1,2,3, 160,161,... * Callorder: 161,160,.... 0, 1,2,3, 160,161,...
@ -107,86 +180,45 @@ snmp_table_handler(netsnmp_mib_handler *handler,
int retval = -1; int retval = -1;
clixon_snmp_handle *sh; clixon_snmp_handle *sh;
netsnmp_table_data_set *table; netsnmp_table_data_set *table;
netsnmp_table_row *row; yang_stmt *ys;
yang_stmt *ys; /* container */ clicon_handle h;
yang_stmt *ylist; yang_stmt *ylist;
clicon_handle h;
cvec *nsc = NULL; cvec *nsc = NULL;
cxobj *xt = NULL; cxobj *xt = NULL;
cbuf *cb = NULL; cbuf *cb = NULL;
cxobj *xerr;
char *xpath;
cxobj *xtable;
cxobj *xe;
cxobj *xleaf;
int i;
char *valstr;
clicon_debug(1, "%s %s %s", __FUNCTION__, clicon_debug(1, "%s %s %s", __FUNCTION__,
handler->handler_name, handler->handler_name,
snmp_msg_int2str(reqinfo->mode)); snmp_msg_int2str(reqinfo->mode));
sh = (clixon_snmp_handle*)nhreg->my_reg_void; sh = (clixon_snmp_handle*)nhreg->my_reg_void;
ys = sh->sh_ys; ys = sh->sh_ys;
h = sh->sh_h; h = sh->sh_h;
table = sh->sh_table; table = sh->sh_table;
if ((ylist = yang_find(ys, Y_LIST, NULL)) == NULL) if ((ylist = yang_find(ys, Y_LIST, NULL)) == NULL)
goto ok; goto ok;
clixon_table_create(table, ys, h);
switch(reqinfo->mode){ switch(reqinfo->mode){
case MODE_GETNEXT: // 160 case MODE_GETNEXT: // 160
if (xml_nsctx_yang(ys, &nsc) < 0) break;
goto done;
/* XXX just for yang2xpath */
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (yang2xpath(ys, cb) < 0)
goto done;
xpath = cbuf_get(cb);
if (clicon_rpc_get(h, xpath, nsc, CONTENT_ALL, -1, &xt) < 0)
goto done;
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clixon_netconf_error(xerr, "clicon_rpc_get", NULL);
goto done;
}
if ((xtable = xpath_first(xt, nsc, "%s", xpath)) != NULL) {
xe = NULL; /* Loop thru entries in table */
while ((xe = xml_child_each(xtable, xe, CX_ELMNT)) != NULL) {
row = netsnmp_create_table_data_row();
xleaf = NULL; /* Loop thru leafs in entry */
i = 1; /* tableindex start at 1 */
while ((xleaf = xml_child_each(xe, xleaf, CX_ELMNT)) != NULL) {
valstr = xml_body(xleaf);
if (i == 1) // Assume first netry is key XXX should check YANG
netsnmp_table_row_add_index(row, ASN_OCTET_STR, valstr, strlen(valstr));
else{
netsnmp_set_row_column(row, i, ASN_OCTET_STR, valstr, strlen(valstr));
netsnmp_mark_row_column_writable(row, i, 1);
}
i++;
}
netsnmp_table_dataset_add_row(table, row);
}
}
break;
case MODE_GET: // 160 case MODE_GET: // 160
case MODE_SET_RESERVE1: case MODE_SET_RESERVE1:
case MODE_SET_RESERVE2: case MODE_SET_RESERVE2:
case MODE_SET_ACTION: case MODE_SET_ACTION:
case MODE_SET_COMMIT: case MODE_SET_COMMIT:
break; break;
} }
ok: ok:
retval = SNMP_ERR_NOERROR; retval = SNMP_ERR_NOERROR;
done: done:
if (xt) if (xt)
xml_free(xt); xml_free(xt);
if (cb) if (cb)
cbuf_free(cb); cbuf_free(cb);
if (nsc) if (nsc)
xml_nsctx_free(nsc); xml_nsctx_free(nsc);
return retval; return retval;
} }
@ -220,7 +252,7 @@ snmp_scalar_handler(netsnmp_mib_handler *handler,
u_char *snmpval = NULL; u_char *snmpval = NULL;
size_t snmplen; size_t snmplen;
int ret; int ret;
/* /*
* can be used to pass information on a per-pdu basis from a * can be used to pass information on a per-pdu basis from a
* helper to the later handlers * helper to the later handlers
@ -381,6 +413,7 @@ mib_yang_table(clicon_handle h,
clixon_snmp_handle *sh; clixon_snmp_handle *sh;
int ret; int ret;
/* 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;
@ -407,8 +440,7 @@ mib_yang_table(clicon_handle h,
sh->sh_ys = ys; sh->sh_ys = ys;
sh->sh_table = table; sh->sh_table = table;
(void)netsnmp_table_dataset_add_index(table, ASN_OCTET_STR); clixon_table_create(table, ys, h);
(void)netsnmp_table_set_multi_add_default_row(table, 2, ASN_OCTET_STR, 1, NULL, 0, 3, ASN_OCTET_STR, 1, NULL, 0, 0);
if ((nhreg = netsnmp_create_handler_registration(name, if ((nhreg = netsnmp_create_handler_registration(name,
snmp_table_handler, snmp_table_handler,
@ -424,7 +456,7 @@ mib_yang_table(clicon_handle h,
if ((ret = netsnmp_register_table_data_set(nhreg, table, NULL)) != SNMPERR_SUCCESS){ if ((ret = netsnmp_register_table_data_set(nhreg, table, NULL)) != SNMPERR_SUCCESS){
//XXX err return? clicon_err(OE_SNMP, ret, "netsnmp_register_table_data_set"); //XXX err return? clicon_err(OE_SNMP, ret, "netsnmp_register_table_data_set");
// goto done; // goto done;
} }
(void)netsnmp_register_auto_data_table(table, NULL); (void)netsnmp_register_auto_data_table(table, NULL);