diff options
author | Micael Karlberg <bmk@erlang.org> | 2019-09-12 12:50:30 +0200 |
---|---|---|
committer | Micael Karlberg <bmk@erlang.org> | 2019-09-12 16:09:38 +0200 |
commit | a57bf61158accddbde6c67b402bcf47f48c5b670 (patch) | |
tree | 5f5c92eb8e889b4ee2ab40ff54249e2a9b928030 | |
parent | 4e5a593041a8aa1f616dfcb3357238c78f56a54c (diff) | |
download | erlang-a57bf61158accddbde6c67b402bcf47f48c5b670.tar.gz |
[snmp|manager|test] Add test cases using the new (cbproxy) feature
Add some test cases that exercise the new (cbproxy) feature.
OTP-15947
-rw-r--r-- | lib/snmp/test/snmp_manager_test.erl | 308 | ||||
-rw-r--r-- | lib/snmp/test/snmp_test_lib.erl | 65 |
2 files changed, 290 insertions, 83 deletions
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 6ced55f0cc..77698d1f99 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -80,21 +80,27 @@ simple_sync_get_next3/1, simple_async_get_next1/1, simple_async_get_next2/1, - simple_async_get_next3/1, + simple_async_get_next3_cbp_def/1, + simple_async_get_next3_cbp_temp/1, + simple_async_get_next3_cbp_perm/1, simple_sync_set1/1, simple_sync_set2/1, simple_sync_set3/1, simple_async_set1/1, simple_async_set2/1, - simple_async_set3/1, + simple_async_set3_cbp_def/1, + simple_async_set3_cbp_temp/1, + simple_async_set3_cbp_perm/1, simple_sync_get_bulk1/1, simple_sync_get_bulk2/1, simple_sync_get_bulk3/1, simple_async_get_bulk1/1, simple_async_get_bulk2/1, - simple_async_get_bulk3/1, + simple_async_get_bulk3_cbp_def/1, + simple_async_get_bulk3_cbp_temp/1, + simple_async_get_bulk3_cbp_perm/1, misc_async1/1, misc_async2/1, @@ -108,7 +114,9 @@ inform2/1, inform3/1, inform4/1, - inform_swarm/1, + inform_swarm_cbp_def/1, + inform_swarm_cbp_temp/1, + inform_swarm_cbp_perm/1, report/1, @@ -253,8 +261,19 @@ init_per_testcase2(Case, Config) -> Family = proplists:get_value(ipfamily, Config, inet), - Conf = [{watchdog, ?WD_START(?MINS(5))}, - {ipfamily, Family}, + TO = case Case of + inform3 -> + ?MINS(2); + InformSwarm when (InformSwarm =:= inform_swarm_cbp_def) orelse + (InformSwarm =:= inform_swarm_cbp_temp) orelse + (InformSwarm =:= inform_swarm_cbp_perm) -> + ?MINS(60); + _ -> + ?MINS(1) + end, + ct:timetrap(TO), + + Conf = [{ipfamily, Family}, {ip, ?LOCALHOST(Family)}, {case_top_dir, CaseTopDir}, {agent_dir, AgTopDir}, @@ -287,13 +306,19 @@ init_per_testcase3(Case, Config) -> ApiCases03 = [ simple_sync_get3, - simple_async_get3, - simple_sync_get_next3, - simple_async_get_next3, - simple_sync_set3, - simple_async_set3, - simple_sync_get_bulk3, - simple_async_get_bulk3 + simple_async_get3, + simple_sync_get_next3, + simple_async_get_next3_cbp_def, + simple_async_get_next3_cbp_temp, + simple_async_get_next3_cbp_perm, + simple_sync_set3, + simple_async_set3_cbp_def, + simple_async_set3_cbp_temp, + simple_async_set3_cbp_perm, + simple_sync_get_bulk3, + simple_async_get_bulk3_cbp_def, + simple_async_get_bulk3_cbp_temp, + simple_async_get_bulk3_cbp_perm ], Cases = [ @@ -303,17 +328,26 @@ init_per_testcase3(Case, Config) -> inform2, inform3, inform4, - inform_swarm, + inform_swarm_cbp_def, + inform_swarm_cbp_temp, + inform_swarm_cbp_perm, report ] ++ ApiCases02 ++ ApiCases03, case lists:member(Case, Cases) of true -> - NoAutoInformCases = [inform1, inform2, inform3, inform_swarm], + NoAutoInformCases = [inform1, inform2, inform3, + inform_swarm_cbp_def, + inform_swarm_cbp_temp, + inform_swarm_cbp_perm], AutoInform = not lists:member(Case, NoAutoInformCases), Conf1 = if - Case =:= inform_swarm -> + %% We turn off verbosity for the swarm cases + %% (too much output). + (Case =:= inform_swarm_cbp_def) orelse + (Case =:= inform_swarm_cbp_temp) orelse + (Case =:= inform_swarm_cbp_perm) -> Verb = [{manager_config_verbosity, silence}, {manager_note_store_verbosity, silence}, {manager_server_verbosity, info}, @@ -326,14 +360,28 @@ init_per_testcase3(Case, Config) -> true -> Config end, - Conf2 = init_agent(Conf1), - Conf3 = init_manager(AutoInform, Conf2), - Conf4 = init_mgr_user(Conf3), + Conf2 = if + (Case =:= simple_async_get_next3_cbp_temp) orelse + (Case =:= simple_async_set3_cbp_temp) orelse + (Case =:= simple_async_get_bulk3_cbp_temp) orelse + (Case =:= inform_swarm_cbp_temp) -> + [{manager_server_cbproxy, temporary} | Conf1]; + (Case =:= simple_async_get_next3_cbp_perm) orelse + (Case =:= simple_async_set3_cbp_perm) orelse + (Case =:= simple_async_get_bulk3_cbp_perm) orelse + (Case =:= inform_swarm_cbp_perm) -> + [{manager_server_cbproxy, permanent} | Conf1]; + true -> + Conf1 + end, + Conf3 = init_agent(Conf2), + Conf4 = init_manager(AutoInform, Conf3), + Conf5 = init_mgr_user(Conf4), case lists:member(Case, ApiCases02 ++ ApiCases03) of true -> - init_mgr_user_data2(Conf4); + init_mgr_user_data2(Conf5); false -> - init_mgr_user_data1(Conf4) + init_mgr_user_data1(Conf5) end; false -> Config @@ -343,13 +391,12 @@ end_per_testcase(Case, Config) when is_list(Config) -> p(Case, "end_per_testcase begin when" "~n Nodes: ~p~n~n", [erlang:nodes()]), ?DBG("fin [~w] Nodes [1]: ~p", [Case, erlang:nodes()]), - Dog = ?config(watchdog, Config), - ?WD_STOP(Dog), - Conf1 = lists:keydelete(watchdog, 1, Config), + %% Dog = ?config(watchdog, Config), + %% ?WD_STOP(Dog), + %% Conf1 = lists:keydelete(watchdog, 1, Config), + Conf1 = Config, Conf2 = end_per_testcase2(Case, Conf1), ?DBG("fin [~w] Nodes [2]: ~p", [Case, erlang:nodes()]), - %% TopDir = ?config(top_dir, Conf2), - %% ?DEL_DIR(TopDir), p(Case, "end_per_testcase end when" "~n Nodes: ~p~n~n", [erlang:nodes()]), Conf2. @@ -373,11 +420,17 @@ end_per_testcase2(Case, Config) -> simple_sync_get3, simple_async_get3, simple_sync_get_next3, - simple_async_get_next3, + simple_async_get_next3_cbp_def, + simple_async_get_next3_cbp_temp, + simple_async_get_next3_cbp_perm, simple_sync_set3, - simple_async_set3, + simple_async_set3_cbp_def, + simple_async_set3_cbp_temp, + simple_async_set3_cbp_perm, simple_sync_get_bulk3, - simple_async_get_bulk3 + simple_async_get_bulk3_cbp_def, + simple_async_get_bulk3_cbp_temp, + simple_async_get_bulk3_cbp_perm ], Cases = [ @@ -387,7 +440,9 @@ end_per_testcase2(Case, Config) -> inform2, inform3, inform4, - inform_swarm, + inform_swarm_cbp_def, + inform_swarm_cbp_temp, + inform_swarm_cbp_perm, report ] ++ ApiCases02 ++ @@ -487,12 +542,14 @@ groups() -> }, {get_next_tests, [], [ - simple_sync_get_next1, + simple_sync_get_next1, simple_sync_get_next2, simple_sync_get_next3, - simple_async_get_next1, - simple_async_get_next2, - simple_async_get_next3 + simple_async_get_next1, + simple_async_get_next2, + simple_async_get_next3_cbp_def, + simple_async_get_next3_cbp_temp, + simple_async_get_next3_cbp_perm ] }, {set_tests, [], @@ -501,8 +558,10 @@ groups() -> simple_sync_set2, simple_sync_set3, simple_async_set1, - simple_async_set2, - simple_async_set3 + simple_async_set2, + simple_async_set3_cbp_def, + simple_async_set3_cbp_temp, + simple_async_set3_cbp_perm ] }, {bulk_tests, [], @@ -512,7 +571,9 @@ groups() -> simple_sync_get_bulk3, simple_async_get_bulk1, simple_async_get_bulk2, - simple_async_get_bulk3 + simple_async_get_bulk3_cbp_def, + simple_async_get_bulk3_cbp_temp, + simple_async_get_bulk3_cbp_perm ] }, {misc_request_tests, [], @@ -529,7 +590,9 @@ groups() -> inform2, inform3, inform4, - inform_swarm, + inform_swarm_cbp_def, + inform_swarm_cbp_temp, + inform_swarm_cbp_perm, report ] }, @@ -541,7 +604,9 @@ groups() -> inform2, inform3, inform4, - inform_swarm, + inform_swarm_cbp_def, + inform_swarm_cbp_temp, + inform_swarm_cbp_perm, report ] }, @@ -576,10 +641,14 @@ ipv6_tests() -> simple_sync_set3, simple_async_set2, simple_sync_get_bulk2, - simple_async_get_bulk3, + simple_async_get_bulk3_cbp_def, + simple_async_get_bulk3_cbp_temp, + simple_async_get_bulk3_cbp_perm, misc_async2, inform1, - inform_swarm + inform_swarm_cbp_def, + inform_swarm_cbp_temp, + inform_swarm_cbp_perm ]. @@ -2550,13 +2619,32 @@ async_gn_exec2(Node, TargetName, Oids) -> %%====================================================================== -simple_async_get_next3(doc) -> +simple_async_get_next3_cbp_def(doc) -> + ["Simple (async) get_next-request - " + "Version 3 API (TargetName with send-opts)"]; +simple_async_get_next3_cbp_def(suite) -> []; +simple_async_get_next3_cbp_def(Config) when is_list(Config) -> + put(tname, ssgn2_cbp_def), + simple_async_get_next3(Config). + +simple_async_get_next3_cbp_temp(doc) -> + ["Simple (async) get_next-request - " + "Version 3 API (TargetName with send-opts)"]; +simple_async_get_next3_cbp_temp(suite) -> []; +simple_async_get_next3_cbp_temp(Config) when is_list(Config) -> + put(tname, ssgn2_cbp_temp), + simple_async_get_next3(Config). + +simple_async_get_next3_cbp_perm(doc) -> ["Simple (async) get_next-request - " "Version 3 API (TargetName with send-opts)"]; -simple_async_get_next3(suite) -> []; +simple_async_get_next3_cbp_perm(suite) -> []; +simple_async_get_next3_cbp_perm(Config) when is_list(Config) -> + put(tname, ssgn2_cbp_perm), + simple_async_get_next3(Config). + simple_async_get_next3(Config) when is_list(Config) -> process_flag(trap_exit, true), - put(tname, ssgn2), p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -2934,12 +3022,29 @@ async_s_exec2(Node, TargetName, VAVs) -> %%====================================================================== -simple_async_set3(doc) -> +simple_async_set3_cbp_def(doc) -> + ["Simple (async) set-request - Version 3 API (TargetName with send-opts)"]; +simple_async_set3_cbp_def(suite) -> []; +simple_async_set3_cbp_def(Config) when is_list(Config) -> + put(tname, sas3_cbp_def), + simple_async_set3(Config). + +simple_async_set3_cbp_temp(doc) -> + ["Simple (async) set-request - Version 3 API (TargetName with send-opts)"]; +simple_async_set3_cbp_temp(suite) -> []; +simple_async_set3_cbp_temp(Config) when is_list(Config) -> + put(tname, sas3_cbp_temp), + simple_async_set3(Config). + +simple_async_set3_cbp_perm(doc) -> ["Simple (async) set-request - Version 3 API (TargetName with send-opts)"]; -simple_async_set3(suite) -> []; -simple_async_set3(Config) when is_list(Config) -> +simple_async_set3_cbp_perm(suite) -> []; +simple_async_set3_cbp_perm(Config) when is_list(Config) -> + put(tname, sas3_cbp_perm), + simple_async_set3(Config). + +simple_async_set3(Config) when is_list(Config) -> process_flag(trap_exit, true), - put(tname, sas3), p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -3646,13 +3751,16 @@ async_gb_exec2(Node, TargetName, {NR, MR, Oids}) -> %%====================================================================== -simple_async_get_bulk3(doc) -> +simple_async_get_bulk3_cbp_def(doc) -> ["Simple (async) get_bulk-request - " "Version 3 API (TargetName with send-opts)"]; -simple_async_get_bulk3(suite) -> []; -simple_async_get_bulk3(Config) when is_list(Config) -> +simple_async_get_bulk3_cbp_def(suite) -> []; +simple_async_get_bulk3_cbp_def(Config) when is_list(Config) -> + put(tname, sagb3_cbp_def), + simple_async_get_bulk3(Config). + +simple_async_get_bulk3(Config) -> process_flag(trap_exit, true), - put(tname, sagb3), p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -3691,6 +3799,28 @@ async_gb_exec3(Node, TargetName, {NR, MR, Oids}, SendOpts) -> %%====================================================================== +simple_async_get_bulk3_cbp_temp(doc) -> + ["Simple (async) get_bulk-request - " + "Version 3 API (TargetName with send-opts)"]; +simple_async_get_bulk3_cbp_temp(suite) -> []; +simple_async_get_bulk3_cbp_temp(Config) when is_list(Config) -> + put(tname, sagb3_cbp_temp), + simple_async_get_bulk3([{manager_server_cbproxy, temporary}|Config]). + + +%%====================================================================== + +simple_async_get_bulk3_cbp_perm(doc) -> + ["Simple (async) get_bulk-request - " + "Version 3 API (TargetName with send-opts)"]; +simple_async_get_bulk3_cbp_perm(suite) -> []; +simple_async_get_bulk3_cbp_perm(Config) when is_list(Config) -> + put(tname, sagb3_cbp_perm), + simple_async_get_bulk3([{manager_server_cbproxy, permanent}|Config]). + + +%%====================================================================== + misc_async1(doc) -> ["Misc (async) request(s) - " "Old style (Addr & Port)"]; misc_async1(suite) -> []; @@ -5034,12 +5164,25 @@ inform4(Config) when is_list(Config) -> %%====================================================================== %% -%% Test: ts:run(snmp, snmp_manager_test, inform_swarm, [batch]). +%% Test: ts:run(snmp, snmp_manager_test, inform_swarm_cbp_def, [batch]). -inform_swarm(suite) -> []; -inform_swarm(Config) when is_list(Config) -> +inform_swarm_cbp_def(suite) -> []; +inform_swarm_cbp_def(Config) when is_list(Config) -> + put(tname, is_cbp_def), + inform_swarm(Config). + +inform_swarm_cbp_temp(suite) -> []; +inform_swarm_cbp_temp(Config) when is_list(Config) -> + put(tname, is_cbp_temp), + inform_swarm([{manager_server_cbproxy, temporary}|Config]). + +inform_swarm_cbp_perm(suite) -> []; +inform_swarm_cbp_perm(Config) when is_list(Config) -> + put(tname, is_cbp_perm), + inform_swarm([{manager_server_cbproxy, permanent}|Config]). + +inform_swarm(Config) -> process_flag(trap_exit, true), - put(tname, is), p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -5055,7 +5198,7 @@ inform_swarm(Config) when is_list(Config) -> ?line ok = agent_load_mib(AgentNode, Test2Mib), ?line ok = agent_load_mib(AgentNode, TestTrapMib), ?line ok = agent_load_mib(AgentNode, TestTrapv2Mib), - NumInforms = 100, + NumInforms = 100000, Collector = self(), @@ -5077,10 +5220,13 @@ inform_swarm(Config) when is_list(Config) -> []), %% Sleep some [(N div 10)*100 ms] %% every tenth notification - if + if + N rem 100 == 0 -> + Sleep = 1000, + p("sleep ~w [~w]", [Sleep, N]), + ?SLEEP(Sleep); N rem 10 == 0 -> - %% Time to sleep some - Sleep = (N div 10) * 50, + Sleep = 100, p("sleep ~w [~w]", [Sleep, N]), ?SLEEP(Sleep); true -> @@ -5140,17 +5286,17 @@ inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, _) (N == RespCnt) and (N =< RecvCnt)) -> p("inform_swarm_collector -> done when" - "~n N: ~w" - "~n SentAckCnt: ~w" - "~n RecvCnt: ~w" - "~n RespCnt: ~w", [N, SentAckCnt, RecvCnt, RespCnt]), + "~n N: ~w" + "~n SentAckCnt: ~w" + "~n RecvCnt: ~w" + "~n RespCnt: ~w", [N, SentAckCnt, RecvCnt, RespCnt]), ok; inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, Timeout) -> p("inform_swarm_collector -> entry with" - "~n N: ~w" - "~n SentAckCnt: ~w" - "~n RecvCnt: ~w" - "~n RespCnt: ~w", [N, SentAckCnt, RecvCnt, RespCnt]), + "~n N: ~w" + "~n SentAckCnt: ~w" + "~n RecvCnt: ~w" + "~n RespCnt: ~w", [N, SentAckCnt, RecvCnt, RespCnt]), receive {snmp_targets, {inform2_tag1, Id}, [_Addr]} -> p("received inform-sent acknowledgement for ~w", [Id]), @@ -5167,18 +5313,18 @@ inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, Timeout) -> Timeout); {Err, Idx, VBs} -> p("<ERROR> unexpected error status: " - "~n Err: ~p" - "~n Idx: ~p" - "~n VBs: ~p", [Err, Idx, VBs]), + "~n Err: ~p" + "~n Idx: ~p" + "~n VBs: ~p", [Err, Idx, VBs]), Reason = {unexpected_status, {Err, Idx, VBs}}, {error, Reason} end; %% The agent has received ack from the manager {snmp_notification, {inform2_tag1, Id}, {got_response, Addr}} -> - p("received expected \"got response\" for ~w" + p("received expected \"got response\" for ~w " "notification from: " - "~n ~p", + "~n ~p", [Id, Addr]), inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt+1, Timeout); @@ -5187,7 +5333,7 @@ inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, Timeout) -> {snmp_notification, inform2_tag1, {no_response, Addr}} -> p("<ERROR> received expected \"no response\" notification " "from: " - "~n ~p", [Addr]), + "~n ~p", [Addr]), Reason = {no_response, Addr, {N, SentAckCnt, RecvCnt, RespCnt}}, {error, Reason} @@ -5373,11 +5519,11 @@ command_handler([{No, Desc, Cmd}|Cmds]) -> %% -- Misc manager functions -- init_manager(AutoInform, Config) -> + ?LOG("init_manager -> entry with" "~n AutoInform: ~p" "~n Config: ~p", [AutoInform, Config]), - %% -- %% Start node %% @@ -6089,16 +6235,17 @@ mgr_user_name_to_oid(Node, Name) -> start_manager(Node, Vsns, Config) -> start_manager(Node, Vsns, Config, []). start_manager(Node, Vsns, Conf0, _Opts) -> + ?DBG("start_manager -> entry with" "~n Node: ~p" "~n Vsns: ~p" "~n Conf0: ~p" "~n Opts: ~p", [Node, Vsns, Conf0, _Opts]), - + AtlDir = ?config(manager_log_dir, Conf0), ConfDir = ?config(manager_conf_dir, Conf0), - DbDir = ?config(manager_db_dir, Conf0), - IRB = ?config(irb, Conf0), + DbDir = ?config(manager_db_dir, Conf0), + IRB = ?config(irb, Conf0), ConfigVerbosity = get_opt(manager_config_verbosity, Conf0, trace), NoteStoreVerbosity = get_opt(manager_note_store_verbosity, Conf0, log), @@ -6107,6 +6254,8 @@ start_manager(Node, Vsns, Conf0, _Opts) -> AtlSeqNo = get_opt(manager_atl_seqno, Conf0, false), + CBP = get_opt(manager_server_cbproxy, Conf0, temporary), + NetIfConf = case get_opt(manager_net_if_module, Conf0, no_module) of no_module -> @@ -6127,7 +6276,8 @@ start_manager(Node, Vsns, Conf0, _Opts) -> {db_dir, DbDir}, {verbosity, ConfigVerbosity}]}, {note_store, [{verbosity, NoteStoreVerbosity}]}, - {server, [{verbosity, ServerVerbosity}]}, + {server, [{verbosity, ServerVerbosity}, + {cbproxy, CBP}]}, {net_if, NetIfConf}], ?line ok = set_mgr_env(Node, Env), diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl index 290f1bc31a..4c57b42134 100644 --- a/lib/snmp/test/snmp_test_lib.erl +++ b/lib/snmp/test/snmp_test_lib.erl @@ -58,12 +58,69 @@ from(H, [H | T]) -> T; from(H, [_ | T]) -> from(H, T); from(_H, []) -> []. +%% localhost() -> +%% {ok, Ip} = snmp_misc:ip(net_adm:localhost()), +%% Ip. +%% localhost(Family) -> +%% {ok, Ip} = snmp_misc:ip(net_adm:localhost(), Family), +%% Ip. + localhost() -> - {ok, Ip} = snmp_misc:ip(net_adm:localhost()), - Ip. + localhost(inet). + localhost(Family) -> - {ok, Ip} = snmp_misc:ip(net_adm:localhost(), Family), - Ip. + case inet:getaddr(net_adm:localhost(), Family) of + {ok, {127, _, _, _}} when (Family =:= inet) -> + %% Ouch, we need to use something else + case inet:getifaddrs() of + {ok, IfList} -> + which_addr(Family, IfList); + {error, Reason1} -> + fail({getifaddrs, Reason1}, ?MODULE, ?LINE) + end; + {ok, {A1, _, _, _, _, _, _, _}} when (Family =:= inet6) andalso + ((A1 =:= 0) orelse + (A1 =:= 16#fe80)) -> + %% Ouch, we need to use something else + case inet:getifaddrs() of + {ok, IfList} -> + which_addr(Family, IfList); + {error, Reason1} -> + fail({getifaddrs, Reason1}, ?MODULE, ?LINE) + end; + {ok, Addr} -> + Addr; + {error, Reason2} -> + fail({getaddr, Reason2}, ?MODULE, ?LINE) + end. + +which_addr(_Family, []) -> + fail(no_valid_addr, ?MODULE, ?LINE); +which_addr(Family, [{"lo", _} | IfList]) -> + which_addr(Family, IfList); +which_addr(Family, [{"docker" ++ _, _} | IfList]) -> + which_addr(Family, IfList); +which_addr(Family, [{"br-" ++ _, _} | IfList]) -> + which_addr(Family, IfList); +which_addr(Family, [{_Name, IfOpts} | IfList]) -> + case which_addr2(Family, IfOpts) of + {ok, Addr} -> + Addr; + {error, _} -> + which_addr(Family, IfList) + end. + +which_addr2(_Family, []) -> + {error, not_found}; +which_addr2(Family, [{addr, Addr}|_]) + when (Family =:= inet) andalso (size(Addr) =:= 4) -> + {ok, Addr}; +which_addr2(Family, [{addr, Addr}|_]) + when (Family =:= inet6) andalso (size(Addr) =:= 8) -> + {ok, Addr}; +which_addr2(Family, [_|IfOpts]) -> + which_addr2(Family, IfOpts). + sz(L) when is_list(L) -> length(L); |