SNMP: Added rowstatus destroy logic

This commit is contained in:
Olof hagsand 2022-07-10 11:49:15 +02:00
parent 7ecfd69398
commit 5175cb8223
6 changed files with 96 additions and 48 deletions

View file

@ -47,7 +47,7 @@
* New configure options: * New configure options:
* `--enable-netsnmp` * `--enable-netsnmp`
* `--with-mib-generated-yang-dir=DIR` * `--with-mib-generated-yang-dir=DIR`
* Thanks to Siklu Communications LTD for sponshoring this work * Thanks to Siklu Communications LTD for sponsoring this work
## 5.8.0 ## 5.8.0
Planned: July 2022 Planned: July 2022

View file

@ -313,18 +313,17 @@ snmp_scalar_get(clicon_handle h,
* @param[in] ys Yang node * @param[in] ys Yang node
* @param[in] cvk Vector of index/Key variables, if any * @param[in] cvk Vector of index/Key variables, if any
* @param[in] db Clixon datastore, typically "candidate" * @param[in] db Clixon datastore, typically "candidate"
* @param[in] rowstatus Special case: transform createAndGo -> active, createAndWait -> notInService
* @param[in] reqinfo * @param[in] reqinfo
* @param[in] requestvb SNMP variables * @param[in] requestvb SNMP variables
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
* @note contains special logic for rowstatus handling
*/ */
static int static int
snmp_scalar_set(clicon_handle h, snmp_scalar_set(clicon_handle h,
yang_stmt *ys, yang_stmt *ys,
cvec *cvk, cvec *cvk,
char *db, char *db,
int rowstatus,
netsnmp_agent_request_info *reqinfo, netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests) netsnmp_request_info *requests)
{ {
@ -342,6 +341,8 @@ snmp_scalar_set(clicon_handle h,
cvec *cvk1; cvec *cvk1;
int i; int i;
int asn1_type; int asn1_type;
int rowstatus = 0;
enum operation_type op = OP_MERGE;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(1, "%s", __FUNCTION__);
if ((yspec = clicon_dbspec_yang(h)) == NULL){ if ((yspec = clicon_dbspec_yang(h)) == NULL){
@ -372,6 +373,10 @@ snmp_scalar_set(clicon_handle h,
/* Extended */ /* Extended */
if (type_yang2asn1(ys, &asn1_type, 1) < 0) if (type_yang2asn1(ys, &asn1_type, 1) < 0)
goto done; goto done;
if (asn1_type == CLIXON_ASN_ROWSTATUS){
/* Must be done before type_snmp2xml: it translates asn1_type */
rowstatus = 1;
}
if ((ret = type_snmp2xml(ys, &asn1_type, requestvb, reqinfo, requests, &valstr)) < 0) if ((ret = type_snmp2xml(ys, &asn1_type, requestvb, reqinfo, requests, &valstr)) < 0)
goto done; goto done;
if (ret == 0) if (ret == 0)
@ -394,6 +399,19 @@ snmp_scalar_set(clicon_handle h,
goto done; goto done;
} }
} }
else if (strcmp(valstr, "destroy") == 0){ /* Remove entry */
cxobj *xe;
cxobj *xa;
if ((xe = xml_parent(xbot)) != NULL){
if ((xa = xml_new("operation", xe, CX_ATTR)) == NULL)
goto done;
if (xml_value_set(xa, "delete") < 0)
goto done;
if (xml_namespace_change(xa, NETCONF_BASE_NAMESPACE, NETCONF_BASE_PREFIX) < 0)
goto done;
op = OP_NONE;
}
}
} }
if (xml_value_set(xb, valstr) < 0) if (xml_value_set(xb, valstr) < 0)
goto done; goto done;
@ -403,7 +421,7 @@ snmp_scalar_set(clicon_handle h,
} }
if (clixon_xml2cbuf(cb, xtop, 0, 0, -1, 0) < 0) if (clixon_xml2cbuf(cb, xtop, 0, 0, -1, 0) < 0)
goto done; goto done;
if (clicon_rpc_edit_config(h, db, OP_MERGE, cbuf_get(cb)) < 0) if (clicon_rpc_edit_config(h, db, op, cbuf_get(cb)) < 0)
goto done; goto done;
ok: ok:
retval = 0; retval = 0;
@ -469,7 +487,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, sh->sh_ys, NULL, "candidate", 0, reqinfo, requests) < 0) if (snmp_scalar_set(sh->sh_h, sh->sh_ys, NULL, "candidate", reqinfo, requests) < 0)
goto done; goto done;
break; break;
case MODE_SET_COMMIT: /* 3 */ case MODE_SET_COMMIT: /* 3 */
@ -805,7 +823,6 @@ snmp_table_set(clicon_handle h,
if (snmp_scalar_set(h, ys, if (snmp_scalar_set(h, ys,
cvk_val, cvk_val,
"candidate", "candidate",
1,
reqinfo, reqinfo,
requests) < 0) requests) < 0)
goto done; goto done;
@ -836,7 +853,6 @@ snmp_table_set(clicon_handle h,
if (snmp_scalar_set(h, ys, if (snmp_scalar_set(h, ys,
cvk_val, cvk_val,
"candidate", "candidate",
0,
reqinfo, reqinfo,
requests) < 0) requests) < 0)
goto done; goto done;
@ -846,20 +862,17 @@ snmp_table_set(clicon_handle h,
if (snmp_scalar_set(h, ys, if (snmp_scalar_set(h, ys,
cvk_val, cvk_val,
"candidate", "candidate",
0,
reqinfo, reqinfo,
requests) < 0) requests) < 0)
goto done; goto done;
break; break;
case 3: // notReady case 3: // notReady
case 6: // destroy
if ((ret = netsnmp_request_set_error(requests, SNMP_ERR_INCONSISTENTVALUE)) != SNMPERR_SUCCESS){ if ((ret = netsnmp_request_set_error(requests, SNMP_ERR_INCONSISTENTVALUE)) != SNMPERR_SUCCESS){
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error"); clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
goto ok; goto ok;
} }
break; break;
case 6: // destroy
// XXX NYI
break;
} }
} }
ok: ok:

View file

@ -111,8 +111,6 @@ static const map_str2int snmp_type_map[] = {
{NULL, -1} {NULL, -1}
}; };
#define CLIXON_ASN_PHYS_ADDR 253 /* Special case phy-address */
#define CLIXON_ASN_FIXED_STRING 254 /* RFC2578 Sec 7.7: String-valued, fixed-length */
/* Map between clixon "orig" resolved type and ASN.1 types. /* Map between clixon "orig" resolved type and ASN.1 types.
*/ */
@ -127,6 +125,7 @@ static const map_str2int snmp_orig_map[] = {
{"timestamp", ASN_TIMETICKS}, // 0x43 / 67 {"timestamp", ASN_TIMETICKS}, // 0x43 / 67
{"InetAddress", ASN_IPADDRESS}, // 0x40 / 64 (Dont see this being used) {"InetAddress", ASN_IPADDRESS}, // 0x40 / 64 (Dont see this being used)
{"ipv4-address", ASN_IPADDRESS}, // 0x40 / 64 (This is used instead) {"ipv4-address", ASN_IPADDRESS}, // 0x40 / 64 (This is used instead)
{"RowStatus", CLIXON_ASN_ROWSTATUS}, // 0x40 / 64 (This is used instead)
{"phys-address", CLIXON_ASN_PHYS_ADDR}, /* Clixon extended string type */ {"phys-address", CLIXON_ASN_PHYS_ADDR}, /* Clixon extended string type */
{NULL, -1} {NULL, -1}
}; };
@ -442,7 +441,7 @@ type_yang2asn1(yang_stmt *ys,
* First try original type, first type * First try original type, first type
*/ */
if ((at = clicon_str2int(snmp_orig_map, origtype)) >= 0 && if ((at = clicon_str2int(snmp_orig_map, origtype)) >= 0 &&
(extended || (at != CLIXON_ASN_PHYS_ADDR && at != CLIXON_ASN_FIXED_STRING))){ (extended || (at < CLIXON_ASN_EXTRAS))){
; ;
} }
/* Then try fully resolved type */ /* Then try fully resolved type */
@ -522,6 +521,9 @@ type_snmp2xml(yang_stmt *ys,
goto done; goto done;
} }
switch (*asn1type){ switch (*asn1type){
case CLIXON_ASN_ROWSTATUS:
*asn1type = ASN_INTEGER;
/* fall through */
case ASN_TIMETICKS: // 67 case ASN_TIMETICKS: // 67
case ASN_INTEGER: // 2 case ASN_INTEGER: // 2
if (cvtype == CGV_STRING){ /* special case for enum */ if (cvtype == CGV_STRING){ /* special case for enum */
@ -699,6 +701,9 @@ type_xml2snmp(char *snmpstr,
goto done; goto done;
} }
switch (*asn1type){ switch (*asn1type){
case CLIXON_ASN_ROWSTATUS:
*asn1type = ASN_INTEGER;
/* fall through */
case ASN_INTEGER: // 2 case ASN_INTEGER: // 2
*snmplen = 4; *snmplen = 4;
if ((*snmpval = malloc(*snmplen)) == NULL){ if ((*snmpval = malloc(*snmplen)) == NULL){
@ -991,6 +996,7 @@ snmp_oid2str(oid **oidi,
case ASN_COUNTER64: case ASN_COUNTER64:
case ASN_COUNTER: case ASN_COUNTER:
case ASN_IPADDRESS: case ASN_IPADDRESS:
case CLIXON_ASN_ROWSTATUS:
cprintf(enc, "%lu", (*oidi)[i++]); cprintf(enc, "%lu", (*oidi)[i++]);
break; break;
case CLIXON_ASN_PHYS_ADDR: /* XXX may need special mapping: ether_aton() ? */ case CLIXON_ASN_PHYS_ADDR: /* XXX may need special mapping: ether_aton() ? */

View file

@ -49,6 +49,16 @@ extern "C" {
#define IETF_YANG_SMIV2_NS "urn:ietf:params:xml:ns:yang:ietf-yang-smiv2" #define IETF_YANG_SMIV2_NS "urn:ietf:params:xml:ns:yang:ietf-yang-smiv2"
/* Special case/extended Clixon ASN1 types
* Set in type_yang2asn1() if extended is true
* Must be back to proper net-snmp ASN_ types in type_snmp2xml and type_xml2snmp
* before calling netsnmp API
*/
#define CLIXON_ASN_EXTRAS 253 /* Special case clixon address >= this */
#define CLIXON_ASN_PHYS_ADDR 253 /* Special case phy-address */
#define CLIXON_ASN_FIXED_STRING 254 /* RFC2578 Sec 7.7: String-valued, fixed-length */
#define CLIXON_ASN_ROWSTATUS 255
/* /*
* Types * Types
*/ */

View file

@ -99,77 +99,86 @@ function testinit(){
function testrun_createAndGo() function testrun_createAndGo()
{ {
new "createAndGo" index=go
new "Configuring a value without a row is a failure" new "Configuring a value without a row is a failure"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\' = 2 2>&1)" 2 "Reason: inconsistentValue" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'$index\' = 2 2>&1)" 2 "Reason: inconsistentValue"
new "Set RowStatus to CreateAndGo and set tag" new "Set RowStatus to CreateAndGo and set tag"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = createAndGo SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\' = 2)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: createAndGo(4)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\' = createAndGo SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'$index\' = 2)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = INTEGER: createAndGo(4)"
new "Rowstatus is active" new "Rowstatus is active"
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: active(1)" expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = INTEGER: active(1)"
new "Get tag" new "Get tag"
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = STRING: 2" expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'$index\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyTag.'$index' = STRING: 2"
new "set storage type" new "set storage type"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.\'notify1\' = 1)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = INTEGER: other(1)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.\'$index\' = 1)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'$index' = INTEGER: other(1)"
} }
function testrun_createAndWait() function testrun_createAndWait()
{ {
new "createAndWait" index=wait
new "Configuring a value without a row is a failure"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'$index\' = 2 2>&1)" 2 "Reason: inconsistentValue"
new "Set RowStatus to CreateAndWait and set tag" new "Set RowStatus to CreateAndWait and set tag"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = createAndWait SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\' = 2)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: createAndWait(5)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\' = createAndWait SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'$index\' = 2)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = INTEGER: createAndWait(5)"
new "Get tag" new "Get tag"
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = STRING: 2" expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'$index\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyTag.'$index' = STRING: 2"
new "Get rowstatus" new "Get rowstatus"
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: notInService(2)" expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = INTEGER: notInService(2)"
new "Set storagetype" new "Set storagetype"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.\'notify1\' = 1)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = INTEGER: other(1)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.\'$index\' = 1)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'$index' = INTEGER: other(1)"
new "Set rowstatus to active/ commit" new "Set rowstatus to active/ commit"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = active)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: active(1)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\' = active)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = INTEGER: active(1)"
new "Set storagetype again" new "Set storagetype again"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.\'notify1\' = 5)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = INTEGER: readOnly(5)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.\'$index\' = 5)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'$index' = INTEGER: readOnly(5)"
new "Set rowstatus to createAndWait" new "Set rowstatus to createAndWait"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = createAndWait)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: createAndWait(5)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\' = createAndWait)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = INTEGER: createAndWait(5)"
new "Set second rowstatus to createAndGo" new "Set second rowstatus to createAndGo"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify2\' = createAndGo)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify2' = INTEGER: createAndGo(4)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'${index}2\' = createAndGo)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'${index}2' = INTEGER: createAndGo(4)"
new "Set third rowstatus to createAndWait" new "Set third rowstatus to createAndWait"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify3\' = createAndWait)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify3' = INTEGER: createAndWait(5)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'${index}3\' = createAndWait)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'${index}3' = INTEGER: createAndWait(5)"
new "Set third rowstatus to active" new "Set third rowstatus to active"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify3\' = active)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify3' = INTEGER: active(1)" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'${index}3\' = active)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'${index}3' = INTEGER: active(1)"
new "Get rowstatus" new "Get rowstatus"
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: notInService(2)" expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = INTEGER: notInService(2)"
} }
function testrun_removeRows() function testrun_removeRows()
{ {
new "removeRows" index=remove
new "Set rowstatus to createandgo" new "Set rowstatus to createandgo"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = createAndGo)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1'" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\' = createAndGo)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index'"
new "Set rowstatus to destroy" new "Set rowstatus to destroy"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = destroy)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = destroy" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\' = destroy)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = INTEGER: destroy(6)"
new "Get rowstatus"
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = No Such Instance currently exists at this OID"
new "Set rowstatus to createandwait"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\' = createAndWait)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index'"
new "Set rowstatus to destroy" new "Set rowstatus to destroy"
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1'" expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\' = destroy)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = INTEGER: destroy(6)"
new "get rowstatus" new "Get rowstatus"
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "No Such Instance currently exists at this OID)" expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'$index\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'$index' = No Such Instance currently exists at this OID"
} }
function testexit() function testexit()
@ -180,14 +189,14 @@ function testexit()
new "SNMP tests" new "SNMP tests"
testinit testinit
new "createAndGo"
testrun_createAndGo testrun_createAndGo
new "createAndWait"
testrun_createAndWait testrun_createAndWait
if $snmp_debug; then new "removeRows"
# NYI
testrun_removeRows testrun_removeRows
fi
new "Cleaning up" new "Cleaning up"
testexit testexit

View file

@ -227,9 +227,19 @@ testrun ifPromiscuousMode INTEGER 1 1 true ${MIB}.1.10 # boolean
testrun ifIpAddr IPADDRESS 1.2.3.4 1.2.3.4 1.2.3.4 ${MIB}.1.13 # InetAddress testrun ifIpAddr IPADDRESS 1.2.3.4 1.2.3.4 1.2.3.4 ${MIB}.1.13 # InetAddress
testrun ifPhysAddress STRING ff:ee:dd:cc:bb:aa ff:ee:dd:cc:bb:aa ff:ee:dd:cc:bb:aa ${IFMIB}.2.2.1.6.1 testrun ifPhysAddress STRING ff:ee:dd:cc:bb:aa ff:ee:dd:cc:bb:aa ff:ee:dd:cc:bb:aa ${IFMIB}.2.2.1.6.1
if $snmp_debug; then # rowstatus # Inline testrun for rowstatus complicated logic
testrun ifStackStatus INTEGER 4 "createAndGo(4)" active ${IFMIB}.31.1.2.1.3.5.9 name=ifStackStatus
fi type=INTEGER
oid=${IFMIB}.31.1.2.1.3.5.9
new "Set $name via SNMP"
expectpart "$($snmpset $oid i 4)" 0 "$type: createAndGo(4)"
new "Check $name via SNMP"
expectpart "$($snmpget $oid)" 0 "$type: active(1)"
new "Check $name via CLI"
expectpart "$($clixon_cli -1 -f $cfg show config xml)" 0 "<$name>active</$name>"
new "Cleaning up" new "Cleaning up"
testexit testexit