From 9b5b085ddb5ee649a7fc518ad534d513c68ad699 Mon Sep 17 00:00:00 2001 From: Stefan Zegenhagen Date: Tue, 31 Jul 2012 10:38:49 +0200 Subject: [snmp/agent] Errors in vacmAccessTable RowStatus handling There are problems with the handling of vacmAccessTableStatus that cause some SNMP test suites to report errors. Most notably, errorneous set operations frequently cause "genErr" errors to be returned which usually is a sign for bad coding. These "genErr" errors are usually caused by badmatch exceptions coming from {ok, Row} = snmpa_vacm:get_row(RowIndex) if the row does not exist. This patch fixes the badmatch errors and adjusts the semantic of the RowStatus handling in that table to be compliant with the RowStatus textual description of SNPMv2-TC MIB. --- lib/snmp/src/agent/snmp_view_based_acm_mib.erl | 121 ++++++++++++++++--------- 1 file changed, 79 insertions(+), 42 deletions(-) (limited to 'lib') diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl index 479a44795f..71dcc0f849 100644 --- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl +++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl @@ -565,48 +565,85 @@ vacmAccessTable(is_set_ok, RowIndex, Cols0) -> case (catch verify_vacmAccessTable_cols(Cols0, [])) of {ok, Cols} -> IsValidKey = is_valid_key(RowIndex), - case lists:keysearch(?vacmAccessStatus, 1, Cols) of - %% Ok, if contextMatch is init - {value, {Col, ?'RowStatus_active'}} -> - {ok, Row} = snmpa_vacm:get_row(RowIndex), - case element(?vacmAContextMatch, Row) of - noinit -> {inconsistentValue, Col}; - _ -> {noError, 0} - end; - {value, {Col, ?'RowStatus_notInService'}} -> % Ok, if not notReady - {ok, Row} = snmpa_vacm:get_row(RowIndex), - case element(?vacmAStatus, Row) of - ?'RowStatus_notReady' -> {inconsistentValue, Col}; - _ -> {noError, 0} - end; - {value, {Col, ?'RowStatus_notReady'}} -> % never ok! - {inconsistentValue, Col}; - {value, {Col, ?'RowStatus_createAndGo'}} -> % ok, if it doesn't exist - Res = lists:keysearch(?vacmAccessContextMatch, 1, Cols), - case snmpa_vacm:get_row(RowIndex) of - false when (IsValidKey =:= true) andalso - is_tuple(Res) -> {noError, 0}; - false -> {noCreation, Col}; % Bad RowIndex - _ -> {inconsistentValue, Col} - end; - {value, {Col, ?'RowStatus_createAndWait'}} -> % ok, if it doesn't exist - case snmpa_vacm:get_row(RowIndex) of - false when (IsValidKey =:= true) -> {noError, 0}; - false -> {noCreation, Col}; % Bad RowIndex - _ -> {inconsistentValue, Col} - end; - {value, {_Col, ?'RowStatus_destroy'}} -> % always ok! - {noError, 0}; - _ -> % otherwise, it's a change; it must exist - case snmpa_vacm:get_row(RowIndex) of - {ok, _} -> - {noError, 0}; - false -> - {inconsistentName, element(1, hd(Cols))} - end - end; - Error -> - Error + StatusCol = lists:keyfind(?vacmAccessStatus, 1, Cols), + OldRow = snmpa_vacm:get_row(RowIndex), + case {StatusCol, OldRow} of + {{Col, ?'RowStatus_active'}, false} -> + % row does not yet exist => inconsistentValue + % (see SNMPv2-TC.mib, RowStatus textual convention) + {inconsistentValue, Col}; + {{Col, ?'RowStatus_active'}, {ok, Row}} -> + %% Ok, if contextMatch is init + case element(?vacmAContextMatch, Row) of + noinit -> + % check whether ContextMatch is being set in the same operation + case proplists:get_value(?vacmAccessContextMatch, Cols) of + undefined -> + % no, we can't make this row active yet + {inconsistentValue, Col}; + _ -> + % ok, activate the row + {noError, 0} + end; + _ -> + {noError, 0} + end; + {{Col, ?'RowStatus_notInService'}, false} -> + % row does not yet exist => inconsistentValue + % (see SNMPv2-TC.mib, RowStatus textual convention) + {inconsistentValue, Col}; + {{Col, ?'RowStatus_notInService'}, {ok, Row}} -> + % Ok, if not notReady + case element(?vacmAStatus, Row) of + ?'RowStatus_notReady' -> + {inconsistentValue, Col}; + _ -> + {noError, 0} + end; + {{Col, ?'RowStatus_notReady'}, _} -> + % never ok! + {inconsistentValue, Col}; + {{Col, ?'RowStatus_createAndGo'}, false} -> + % ok, if it doesn't exist + Res = lists:keysearch(?vacmAccessContextMatch, 1, Cols), + if + IsValidKey /= true -> + % bad RowIndex => noCreation + {noCreation, Col}; + is_tuple(Res) -> + % required field is present => noError + {noError, 0}; + true -> + % required field is missing => inconsistentValue + {inconsistentValue, Col} + end; + {{Col, ?'RowStatus_createAndGo'}, _} -> + % row already exists => inconsistentValue + {inconsistentValue, Col}; + {{Col, ?'RowStatus_createAndWait'}, false} -> + % ok, if it doesn't exist + if + IsValidKey =:= true -> + % RowIndex is valid => noError + {noError, 0}; + true -> + {noCreation, Col} + end; + {{Col, ?'RowStatus_createAndWait'}, _} -> + % Row already exists => inconsistentValue + {inconsistentValue, Col}; + {value, {_Col, ?'RowStatus_destroy'}} -> + % always ok! + {noError, 0}; + {_, false} -> + % otherwise, it's a row change; row does not exist => inconsistentName + {inconsistentName, element(1, hd(Cols))}; + _ -> + % row change and row exists => noError + {noError, 0} + end; + Error -> + Error end; vacmAccessTable(set, RowIndex, Cols0) -> case (catch verify_vacmAccessTable_cols(Cols0, [])) of -- cgit v1.2.3 From 730ef404d96a9db21e92101409cf9043b2126848 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 1 Aug 2012 10:20:16 +0200 Subject: [snmp] Add release notes, appup instruction and proper version --- lib/snmp/doc/src/notes.xml | 60 +++++++++++++++++++++++++++++++++++++++++ lib/snmp/src/app/snmp.appup.src | 10 +++++++ lib/snmp/vsn.mk | 2 +- 3 files changed, 71 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 2d045faa0f..4ec254971b 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -33,6 +33,66 @@ +
+ SNMP Development Toolkit 4.22.1 +

Version 4.22.1 supports code replacement in runtime from/to + version 4.22, 4.21.7 4.21.6 4.21.5, 4.21.4, 4.21.3, 4.21.2, 4.21.1 and 4.21.

+ +
+ Improvements and new features + + + + +

[agent] Errors in vacmAccessTable RowStatus handling. + There are problems with the handling of vacmAccessTableStatus + that cause some SNMP test suites to report errors. + Most notably, erroneous set operations frequently cause "genErr" + errors to be returned. These "genErr" errors are usually caused + by badmatch exceptions coming from + {ok, Row} = snmpa_vacm:get_row(RowIndex) + if the row does not exist.

+

The semantics of the RowStatus handling in that table has + been adjusted to be compliant with the RowStatus + textual description of SNPMv2-TC MIB.

+

Stefan Zegenhagen

+

Own Id: OTP-10164

+
+
+ +
+ +
+ Fixed Bugs and Malfunctions +

-

+ + + +
+ +
+ Incompatibilities +

-

+
+ +
+ +
SNMP Development Toolkit 4.22

Version 4.22 supports code replacement in runtime from/to diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index 8360d88c94..54c07bed26 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -22,6 +22,11 @@ %% ----- U p g r a d e ------------------------------------------------------- [ + {"4.22", + [ + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []} + ] + }, {"4.21.7", [ {load_module, snmp_config, soft_purge, soft_purge, []}, @@ -288,6 +293,11 @@ %% ------D o w n g r a d e --------------------------------------------------- [ + {"4.22", + [ + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []} + ] + }, {"4.21.7", [ {load_module, snmp_config, soft_purge, soft_purge, []}, diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 36b9764bc8..b90dbe4eef 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -18,6 +18,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 4.22 +SNMP_VSN = 4.22.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" -- cgit v1.2.3 From 6c3ce92734fe80bec370857a83ccf375c3f20565 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 1 Aug 2012 10:28:50 +0200 Subject: [snmp/agent] Cleanup --- lib/snmp/src/agent/snmp_view_based_acm_mib.erl | 161 +++++++++++++------------ 1 file changed, 82 insertions(+), 79 deletions(-) (limited to 'lib') diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl index 71dcc0f849..e7dea52857 100644 --- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl +++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl @@ -565,85 +565,88 @@ vacmAccessTable(is_set_ok, RowIndex, Cols0) -> case (catch verify_vacmAccessTable_cols(Cols0, [])) of {ok, Cols} -> IsValidKey = is_valid_key(RowIndex), - StatusCol = lists:keyfind(?vacmAccessStatus, 1, Cols), - OldRow = snmpa_vacm:get_row(RowIndex), - case {StatusCol, OldRow} of - {{Col, ?'RowStatus_active'}, false} -> - % row does not yet exist => inconsistentValue - % (see SNMPv2-TC.mib, RowStatus textual convention) - {inconsistentValue, Col}; - {{Col, ?'RowStatus_active'}, {ok, Row}} -> - %% Ok, if contextMatch is init - case element(?vacmAContextMatch, Row) of - noinit -> - % check whether ContextMatch is being set in the same operation - case proplists:get_value(?vacmAccessContextMatch, Cols) of - undefined -> - % no, we can't make this row active yet - {inconsistentValue, Col}; - _ -> - % ok, activate the row - {noError, 0} - end; - _ -> - {noError, 0} - end; - {{Col, ?'RowStatus_notInService'}, false} -> - % row does not yet exist => inconsistentValue - % (see SNMPv2-TC.mib, RowStatus textual convention) - {inconsistentValue, Col}; - {{Col, ?'RowStatus_notInService'}, {ok, Row}} -> - % Ok, if not notReady - case element(?vacmAStatus, Row) of - ?'RowStatus_notReady' -> - {inconsistentValue, Col}; - _ -> - {noError, 0} - end; - {{Col, ?'RowStatus_notReady'}, _} -> - % never ok! - {inconsistentValue, Col}; - {{Col, ?'RowStatus_createAndGo'}, false} -> - % ok, if it doesn't exist - Res = lists:keysearch(?vacmAccessContextMatch, 1, Cols), - if - IsValidKey /= true -> - % bad RowIndex => noCreation - {noCreation, Col}; - is_tuple(Res) -> - % required field is present => noError - {noError, 0}; - true -> - % required field is missing => inconsistentValue - {inconsistentValue, Col} - end; - {{Col, ?'RowStatus_createAndGo'}, _} -> - % row already exists => inconsistentValue - {inconsistentValue, Col}; - {{Col, ?'RowStatus_createAndWait'}, false} -> - % ok, if it doesn't exist - if - IsValidKey =:= true -> - % RowIndex is valid => noError - {noError, 0}; - true -> - {noCreation, Col} - end; - {{Col, ?'RowStatus_createAndWait'}, _} -> - % Row already exists => inconsistentValue - {inconsistentValue, Col}; - {value, {_Col, ?'RowStatus_destroy'}} -> - % always ok! - {noError, 0}; - {_, false} -> - % otherwise, it's a row change; row does not exist => inconsistentName - {inconsistentName, element(1, hd(Cols))}; - _ -> - % row change and row exists => noError - {noError, 0} - end; - Error -> - Error + StatusCol = lists:keyfind(?vacmAccessStatus, 1, Cols), + MaybeRow = snmpa_vacm:get_row(RowIndex), + case {StatusCol, MaybeRow} of + {{Col, ?'RowStatus_active'}, false} -> + %% row does not yet exist => inconsistentValue + %% (see SNMPv2-TC.mib, RowStatus textual convention) + {inconsistentValue, Col}; + {{Col, ?'RowStatus_active'}, {ok, Row}} -> + %% Ok, if contextMatch is init + case element(?vacmAContextMatch, Row) of + noinit -> + %% check whether ContextMatch is being set in + %% the same operation + case proplists:get_value(?vacmAccessContextMatch, + Cols) of + undefined -> + %% no, we can't make this row active yet + {inconsistentValue, Col}; + _ -> + %% ok, activate the row + {noError, 0} + end; + _ -> + {noError, 0} + end; + {{Col, ?'RowStatus_notInService'}, false} -> + %% row does not yet exist => inconsistentValue + %% (see SNMPv2-TC.mib, RowStatus textual convention) + {inconsistentValue, Col}; + {{Col, ?'RowStatus_notInService'}, {ok, Row}} -> + %% Ok, if not notReady + case element(?vacmAStatus, Row) of + ?'RowStatus_notReady' -> + {inconsistentValue, Col}; + _ -> + {noError, 0} + end; + {{Col, ?'RowStatus_notReady'}, _} -> + %% never ok! + {inconsistentValue, Col}; + {{Col, ?'RowStatus_createAndGo'}, false} -> + %% ok, if it doesn't exist + Res = lists:keysearch(?vacmAccessContextMatch, 1, Cols), + if + IsValidKey =/= true -> + %% bad RowIndex => noCreation + {noCreation, Col}; + is_tuple(Res) -> + %% required field is present => noError + {noError, 0}; + true -> + %% required field is missing => inconsistentValue + {inconsistentValue, Col} + end; + {{Col, ?'RowStatus_createAndGo'}, _} -> + %% row already exists => inconsistentValue + {inconsistentValue, Col}; + {{Col, ?'RowStatus_createAndWait'}, false} -> + %% ok, if it doesn't exist + if + IsValidKey =:= true -> + %% RowIndex is valid => noError + {noError, 0}; + true -> + {noCreation, Col} + end; + {{Col, ?'RowStatus_createAndWait'}, _} -> + %% Row already exists => inconsistentValue + {inconsistentValue, Col}; + {value, {_Col, ?'RowStatus_destroy'}} -> + %% always ok! + {noError, 0}; + {_, false} -> + %% otherwise, it's a row change; + %% row does not exist => inconsistentName + {inconsistentName, element(1, hd(Cols))}; + _ -> + %% row change and row exists => noError + {noError, 0} + end; + Error -> + Error end; vacmAccessTable(set, RowIndex, Cols0) -> case (catch verify_vacmAccessTable_cols(Cols0, [])) of -- cgit v1.2.3