Whamcloud - gitweb
LU-16027 tests: sanity:test_66: specify blocksize explicitly
[fs/lustre-release.git] / lustre / tests / sanity-lnet.sh
index ccea0d3..28afdfd 100755 (executable)
@@ -12,12 +12,6 @@ ONLY=${ONLY:-"$*"}
 ALWAYS_EXCEPT="$SANITY_LNET_EXCEPT "
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
-# skip the grant tests for ARM until they are fixed
-if [[ $(uname -m) = aarch64 ]]; then
-       # bug number:    LU-14067
-       ALWAYS_EXCEPT+=" 300"
-fi
-
 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
 
 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
@@ -68,35 +62,6 @@ cleanup_testsuite() {
        return 0
 }
 
-load_lnet() {
-       load_module ../libcfs/libcfs/libcfs
-       # Prevent local MODOPTS_LIBCFS being passed as part of environment
-       # variable to remote nodes
-       unset MODOPTS_LIBCFS
-
-       set_default_debug "neterror net nettrace malloc"
-       load_module ../lnet/lnet/lnet "$@"
-
-       LNDPATH=${LNDPATH:-"../lnet/klnds"}
-       if [ -z "$LNETLND" ]; then
-               case $NETTYPE in
-               o2ib*)  LNETLND="o2iblnd/ko2iblnd" ;;
-               tcp*)   LNETLND="socklnd/ksocklnd" ;;
-               *)      local lnd="${NETTYPE%%[0-9]}lnd"
-                       [ -f "$LNDPATH/$lnd/k$lnd.ko" ] &&
-                               LNETLND="$lnd/k$lnd" ||
-                               LNETLND="socklnd/ksocklnd"
-               esac
-       fi
-       load_module ../lnet/klnds/$LNETLND
-}
-
-do_lnetctl() {
-       $LCTL mark "$LNETCTL $*"
-       echo "$LNETCTL $*"
-       $LNETCTL "$@"
-}
-
 TESTNS='test_ns'
 FAKE_IF="test1pg"
 FAKE_IP="10.1.2.3"
@@ -196,7 +161,7 @@ validate_nid() {
        local num_re='[0-9]\+'
        local ip_re="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
 
-       if [[ $net =~ gni[0-9]* ]]; then
+       if [[ $net =~ gni[0-9]* ]] || [[ $net =~ kfi[0-9]* ]]; then
                [[ $addr =~ ${num_re} ]] && return 0
        else
                [[ $addr =~ ${ip_re} ]] && return 0
@@ -250,7 +215,7 @@ cleanupall -f
 setup_netns || error "setup_netns failed with $?"
 
 # Determine the local interface(s) used for LNet
-load_modules || error "Failed to load modules"
+load_lnet "config_on_load=1" || error "Failed to load modules"
 
 do_lnetctl net show
 ip a
@@ -393,10 +358,17 @@ peer:
         - nid: 6.6.3.6@o2ib
         - nid: 6@gni
         - nid: 10@gni
+        - nid: 6@kfi
+        - nid: 10@kfi
 EOF
        append_global_yaml
-       compare_peer_add "6.6.6.6@tcp" \
-               "6.6.[6-7].[0-4/2]@tcp,6.6.[1-4/2].[0-6/3]@o2ib,[6-12/4]@gni"
+
+       local nid_expr="6.6.[6-7].[0-4/2]@tcp"
+       nid_expr+=",6.6.[1-4/2].[0-6/3]@o2ib"
+       nid_expr+=",[6-12/4]@gni"
+       nid_expr+=",[6-12/4]@kfi"
+
+       compare_peer_add "6.6.6.6@tcp" "${nid_expr}"
 }
 run_test 6 "Add peer with multiple nidranges"
 
@@ -449,9 +421,18 @@ test_7() {
                error "Peer add failed $?"
        compare_peer_del "7@gni"
 
-       echo "Delete peer that has tcp, o2ib and gni nids"
+       echo "Delete peer with single nid (kfi)"
+       do_lnetctl peer add --prim_nid 7@kfi || error "Peer add failed $?"
+       compare_peer_del "7@kfi"
+
+       echo "Delete peer that has multiple nids (kfi)"
+       do_lnetctl peer add --prim_nid 7@kfi --nid [8-12]@kfi ||
+               error "Peer add failed $?"
+       compare_peer_del "7@kfi"
+
+       echo "Delete peer that has tcp, o2ib, gni and kfi nids"
        do_lnetctl peer add --prim_nid 7@gni \
-               --nid [8-12]@gni,7.7.7.[9-12]@tcp,7.7.7.[13-15]@o2ib ||
+               --nid [8-12]@gni,7.7.7.[1-4]@tcp,7.7.7.[5-9]@o2ib,[1-5]@kfi ||
                error "Peer add failed $?"
        compare_peer_del "7@gni"
 }
@@ -583,7 +564,7 @@ create_nid() {
        local num="$1"
        local net="$2"
 
-       if [[ $net =~ gni* ]]; then
+       if [[ $net =~ gni* ]] || [[ $net =~ kfi* ]]; then
                echo "${num}@${net}"
        else
                echo "${num}.${num}.${num}.${num}@${net}"
@@ -1437,7 +1418,7 @@ setup_health_test() {
 
        # Loading modules should configure LNet with the appropriate
        # test-framework configuration
-       load_modules || error "Failed to load modules"
+       load_lnet "config_on_load=1" || error "Failed to load modules"
 
        LNIDS=( $($LCTL list_nids | xargs echo) )
 
@@ -1445,7 +1426,7 @@ setup_health_test() {
        RNIDS=( $(do_node $RNODE $LCTL list_nids | xargs echo) )
 
        if [[ -z ${RNIDS[@]} ]]; then
-               do_rpc_nodes $RNODE load_modules_local
+               do_rpc_nodes $RNODE load_lnet "config_on_load=1"
                RLOADED=true
                RNIDS=( $(do_node $RNODE $LCTL list_nids | xargs echo) )
        fi
@@ -1866,6 +1847,18 @@ check_nid_in_recovq() {
 # If the recovery limit is 10 seconds, then when the 5th enqueue happens
 # we expect the peer NI to have aged out, so it will not actually be
 # queued.
+# If max_recovery_ping_interval is set to 2 then:
+#  First enqueue happens at time 0.
+#  2nd at 0 + 2^0 = 1
+#  3rd at 1 + 2^1 = 3
+#  4th at 3 + 2^1 = 5
+#  5th at 5 + 2^1 = 7
+#  6th at 7 + 2^1 = 9
+#  7th at 9 + 2^1 = 11
+# e.g. after 4 seconds we would expect to have seen the 3th enqueue,
+# (2 pings sent, 3rd about to happen), and the 4th enqueue is yet to happen
+# e.g. after 10 seconds we would expect to have seen the 6th enqueue,
+# (5 pings sent, 6th about to happen), and the 8th enqueue is yet to happen
 check_ping_count() {
        local queue="$1"
        local expect="$2"
@@ -1915,6 +1908,8 @@ test_210() {
        do_lnetctl discover $prim_nid ||
                error "failed to discover myself"
 
+       local default=$($LNETCTL global show |
+                       awk '/recovery_limit/{print $NF}')
        # Set recovery limit to 10 seconds.
        do_lnetctl set recovery_limit 10 ||
                error "failed to set recovery_limit"
@@ -1923,20 +1918,59 @@ test_210() {
        # Use local_error so LNet doesn't attempt to resend the discovery ping
        $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e local_error
        $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e local_error
-       do_lnetctl discover $($LCTL list_nids | head -n 1) &&
+       do_lnetctl discover $prim_nid &&
                error "Expected discovery to fail"
 
+       # See comment for check_ping_count()
        sleep 5
-       check_nid_in_recovq "-l" 1
+       check_nid_in_recovq "-l" "1"
        check_ping_count "ni" "2"
 
        sleep 5
 
-       check_nid_in_recovq "-l" 1
+       check_nid_in_recovq "-l" "1"
        check_ping_count "ni" "3"
 
        $LCTL net_drop_del -a
 
+       reinit_dlc || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
+       add_net "tcp1" "${INTERFACES[0]}" || return $?
+
+       local prim_nid=$($LCTL list_nids | head -n 1)
+
+       do_lnetctl discover $prim_nid ||
+               error "failed to discover myself"
+
+       do_lnetctl set recovery_limit $default ||
+               error "failed to set recovery_limit"
+
+       default=$($LNETCTL global show |
+                 awk '/max_recovery_ping_interval/{print $NF}')
+       do_lnetctl set max_recovery_ping_interval 2 ||
+               error "failed to set max_recovery_ping_interval"
+
+       $LCTL set_param debug=+net
+       # Use local_error so LNet doesn't attempt to resend the discovery ping
+       $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e local_error
+       $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e local_error
+       do_lnetctl discover $prim_nid &&
+               error "Expected discovery to fail"
+
+       # See comment for check_ping_count()
+       sleep 4
+       check_nid_in_recovq "-l" "1"
+       check_ping_count "ni" "2"
+
+       sleep 6
+       check_nid_in_recovq "-l" "1"
+       check_ping_count "ni" "5"
+
+       $LCTL net_drop_del -a
+
+       do_lnetctl set max_recovery_ping_interval $default ||
+               error "failed to set max_recovery_ping_interval"
+
        return 0
 }
 run_test 210 "Local NI recovery checks"
@@ -1951,6 +1985,8 @@ test_211() {
        do_lnetctl discover $prim_nid ||
                error "failed to discover myself"
 
+       local default=$($LNETCTL global show |
+                       awk '/recovery_limit/{print $NF}')
        # Set recovery limit to 10 seconds.
        do_lnetctl set recovery_limit 10 ||
                error "failed to set recovery_limit"
@@ -1995,6 +2031,44 @@ test_211() {
        check_nid_in_recovq "-p" 0
        check_ping_count "peer_ni" "0"
 
+       reinit_dlc || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
+       add_net "tcp1" "${INTERFACES[0]}" || return $?
+
+       local prim_nid=$($LCTL list_nids | head -n 1)
+
+       do_lnetctl discover $prim_nid ||
+               error "failed to discover myself"
+
+       do_lnetctl set recovery_limit $default ||
+               error "failed to set recovery_limit"
+
+       default=$($LNETCTL global show |
+                 awk '/max_recovery_ping_interval/{print $NF}')
+       do_lnetctl set max_recovery_ping_interval 2 ||
+               error "failed to set max_recovery_ping_interval"
+
+       $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e remote_error
+       $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e remote_error
+
+       # Set health to 0 on one interface. This forces it onto the recovery
+       # queue.
+       $LNETCTL peer set --nid $prim_nid --health 0
+
+       # See comment for check_ping_count()
+       sleep 4
+       check_nid_in_recovq "-p" "1"
+       check_ping_count "peer_ni" "2"
+
+       sleep 6
+       check_nid_in_recovq "-p" "1"
+       check_ping_count "peer_ni" "5"
+
+       $LCTL net_drop_del -a
+
+       do_lnetctl set max_recovery_ping_interval $default ||
+               error "failed to set max_recovery_ping_interval"
+
        return 0
 }
 run_test 211 "Remote NI recovery checks"
@@ -2007,7 +2081,7 @@ test_212() {
 
        # Loading modules should configure LNet with the appropriate
        # test-framework configuration
-       load_modules || error "Failed to load modules"
+       load_lnet "config_on_load=1" || error "Failed to load modules"
 
        local my_nid=$($LCTL list_nids | head -n 1)
        [[ -z $my_nid ]] &&
@@ -2018,7 +2092,7 @@ test_212() {
        local rloaded=false
 
        if [[ -z $rnodenids ]]; then
-               do_rpc_nodes $rnode load_modules_local
+               do_rpc_nodes $rnode load_lnet "config_on_load=1"
                rloaded=true
                rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
        fi
@@ -2423,6 +2497,499 @@ test_219() {
 }
 run_test 219 "Consolidate peer entries"
 
+do_net_add() {
+       local node=$1
+       local net=$2
+       local if=$3
+       local opts=$4
+
+       do_rpc_nodes $node "$LNETCTL net add --net $net --if $if $opts" ||
+               error "add $net on interface $if on node $node failed rc=$?"
+}
+
+do_route_add() {
+       local node=$1
+       local net=$2
+       local gw=$3
+
+       do_node $node "$LNETCTL route add --net $net --gateway $gw" ||
+               error "route add to $net via $gw failed rc=$?"
+}
+
+ROUTER=""
+ROUTER_INTERFACES=()
+RPEER=""
+RPEER_INTERFACES=()
+init_router_test_vars() {
+       local rnodes=$(remote_nodes_list)
+       [[ -z $rnodes || $(wc -w <<<$rnodes) -lt 2 ]] &&
+               skip "Need at least 2 remote nodes found \"$rnodes\""
+
+       ROUTER=$(awk '{print $1}' <<<$rnodes)
+       RPEER=$(awk '{print $2}' <<<$rnodes)
+
+       rnodes=$(comma_list $ROUTER $RPEER)
+       local all_nodes=$(comma_list $rnodes $HOSTNAME)
+
+       do_nodes $rnodes $LUSTRE_RMMOD ||
+               error "failed to unload modules"
+
+       do_rpc_nodes $rnodes "load_lnet config_on_load=1" ||
+               error "Failed to load and configure LNet"
+
+       ROUTER_INTERFACES=( $(do_rpc_nodes --quiet $ROUTER lnet_if_list) )
+
+       RPEER_INTERFACES=( $(do_rpc_nodes --quiet $RPEER lnet_if_list) )
+
+       do_nodes $all_nodes $LUSTRE_RMMOD ||
+               error "Failed to unload modules"
+
+       [[ ${#INTERFACES[@]} -eq 0 ]] &&
+               error "No interfaces configured for local host $HOSTNAME"
+       [[ ${#ROUTER_INTERFACES[@]} -eq 0 ]] &&
+               error "No interfaces configured for router $ROUTER"
+       [[ ${#RPEER_INTERFACES[@]} -eq 0 ]] &&
+               error "No interfaces configured for remote peer $RPEER"
+
+       return 0
+}
+
+ROUTER_NIDS=()
+RPEER_NIDS=()
+LNIDS=()
+LOCAL_NET=${NETTYPE}1
+REMOTE_NET=${NETTYPE}2
+setup_router_test() {
+       local mod_opts="$1"
+       local rtr_net_opts="$2"
+
+       if [[ ${#RPEER_INTERFACES[@]} -eq 0 ]]; then
+               init_router_test_vars ||
+                       return $?
+       fi
+
+       local all_nodes=$(comma_list $ROUTER $RPEER $HOSTNAME)
+
+       do_nodes $all_nodes $LUSTRE_RMMOD ||
+               error "failed to unload modules"
+
+       mod_opts+=" alive_router_check_interval=5"
+       mod_opts+=" router_ping_timeout=5"
+       do_rpc_nodes $all_nodes load_lnet "${mod_opts}" ||
+               error "Failed to load lnet"
+
+       do_nodes $all_nodes "$LNETCTL lnet configure" ||
+               error "Failed to initialize DLC"
+
+       do_net_add $ROUTER $LOCAL_NET ${ROUTER_INTERFACES[0]} $rtr_net_opts ||
+               return $?
+
+       do_net_add $ROUTER $REMOTE_NET ${ROUTER_INTERFACES[0]} ||
+               return $?
+
+       do_net_add $RPEER $REMOTE_NET ${RPEER_INTERFACES[0]} ||
+               return $?
+
+       add_net $LOCAL_NET ${INTERFACES[0]} ||
+               return $?
+
+       ROUTER_NIDS=( $(do_node $ROUTER $LCTL list_nids 2>/dev/null |
+                       xargs echo) )
+       RPEER_NIDS=( $(do_node $RPEER $LCTL list_nids 2>/dev/null |
+                      xargs echo) )
+       LNIDS=( $($LCTL list_nids 2>/dev/null | xargs echo) )
+}
+
+do_route_del() {
+       local node=$1
+       local net=$2
+       local gw=$3
+
+       do_nodesv $node "if $LNETCTL route show --net $net --gateway $gw; then \
+                               $LNETCTL route del --net $net --gateway $gw;   \
+                        else                                                  \
+                               exit 0;                                        \
+                        fi"
+}
+
+cleanup_router_test() {
+       local all_nodes=$(comma_list $HOSTNAME $ROUTER $RPEER)
+
+       do_route_del $HOSTNAME $REMOTE_NET ${ROUTER_NIDS[0]} ||
+               error "Failed to delete $REMOTE_NET route"
+
+       do_route_del $RPEER $LOCAL_NET ${ROUTER_NIDS[1]} ||
+               error "Failed to delete $LOCAL_NET route"
+
+       do_nodes $all_nodes $LUSTRE_RMMOD ||
+               error "failed to unload modules"
+
+       return 0
+}
+
+check_route_aliveness() {
+       local node="$1"
+       local expected="$2"
+
+       local lctl_actual
+       local lnetctl_actual
+       local chk_intvl
+       local i
+
+       chk_intvl=$(cat /sys/module/lnet/parameters/alive_router_check_interval)
+
+       lctl_actual=$(do_node $node $LCTL show_route | awk '{print $7}')
+       lnetctl_actual=$(do_node $node $LNETCTL route show -v |
+                        awk '/state/{print $NF}')
+
+       for ((i = 0; i < $chk_intvl; i++)); do
+               if [[ $lctl_actual == $expected ]] &&
+                  [[ $lnetctl_actual == $expected ]]; then
+                       break
+               fi
+
+               echo "wait 1s for route state change"
+               sleep 1
+
+               lctl_actual=$(do_node $node $LCTL show_route | awk '{print $7}')
+               lnetctl_actual=$(do_node $node $LNETCTL route show -v |
+                                awk '/state/{print $NF}')
+       done
+
+       [[ $lctl_actual != $expected ]] &&
+               error "Wanted \"$expected\" lctl found \"$lctl_actual\""
+
+       [[ $lnetctl_actual != $expected ]] &&
+               error "Wanted \"$expected\" lnetctl found \"$lnetctl_actual\""
+
+       return 0
+}
+
+check_router_ni_status() {
+       local expected_local="$1"
+       local expected_remote="$2"
+
+       local actual_local
+       local actual_remote
+       local chk_intvl
+       local timeout
+       local i
+
+       chk_intvl=$(cat /sys/module/lnet/parameters/alive_router_check_interval)
+       timeout=$(cat /sys/module/lnet/parameters/router_ping_timeout)
+
+       actual_local=$(do_node $ROUTER "$LNETCTL net show --net $LOCAL_NET" |
+                      awk '/status/{print $NF}')
+       actual_remote=$(do_node $ROUTER "$LNETCTL net show --net $REMOTE_NET" |
+                       awk '/status/{print $NF}')
+
+       for ((i = 0; i < $((chk_intvl + timeout)); i++)); do
+               if [[ $actual_local == $expected_local ]] &&
+                  [[ $actual_remote == $expected_remote ]]; then
+                       break
+               fi
+
+               echo "wait 1s for NI state change"
+               sleep 1
+
+               actual_local=$(do_node $ROUTER \
+                              "$LNETCTL net show --net $LOCAL_NET" |
+                               awk '/status/{print $NF}')
+               actual_remote=$(do_node $ROUTER \
+                               "$LNETCTL net show --net $REMOTE_NET" |
+                               awk '/status/{print $NF}')
+       done
+
+       [[ $actual_local == $expected_local ]] ||
+               error "$LOCAL_NET should be $expected_local"
+
+       [[ $actual_remote == $expected_remote ]] ||
+               error "$REMOTE_NET should be $expected_remote"
+
+       return 0
+}
+
+do_basic_rtr_test() {
+       do_node $ROUTER "$LNETCTL set routing 1" ||
+               error "Unable to enable routing on $ROUTER"
+
+       do_route_add $HOSTNAME $REMOTE_NET ${ROUTER_NIDS[0]} ||
+               return $?
+
+       do_route_add $RPEER $LOCAL_NET ${ROUTER_NIDS[1]} ||
+               return $?
+
+       check_route_aliveness "$HOSTNAME" "up" ||
+               return $?
+
+       check_route_aliveness "$RPEER" "up" ||
+               return $?
+
+       do_lnetctl ping ${RPEER_NIDS[0]} ||
+               error "Failed to ping ${RPEER_NIDS[0]}"
+
+       do_node $RPEER "$LNETCTL ping ${LNIDS[0]}" ||
+               error "$RPEER failed to ping ${LNIDS[0]}"
+
+       return 0
+}
+
+test_220() {
+       setup_router_test || return $?
+
+       do_basic_rtr_test || return $?
+
+       cleanup_router_test || return $?
+}
+run_test 220 "Add routes w/default options - check aliveness"
+
+test_221() {
+       setup_router_test lnet_peer_discovery_disabled=1 || return $?
+
+       do_basic_rtr_test || return $?
+
+       cleanup_router_test || return $?
+}
+run_test 221 "Add routes w/DD disabled - check aliveness"
+
+do_aarf_enabled_test() {
+       do_node $ROUTER "$LNETCTL set routing 1" ||
+               error "Unable to enable routing on $ROUTER"
+
+       check_router_ni_status "down" "down"
+
+       do_lnetctl ping ${RPEER_NIDS[0]} &&
+               error "Ping should fail"
+
+       do_node $RPEER "$LNETCTL ping ${LNIDS[0]}" &&
+               error "$RPEER ping should fail"
+
+       # Adding a route should cause the router's NI on LOCAL_NET to get up
+       do_route_add $HOSTNAME $REMOTE_NET ${ROUTER_NIDS[0]} ||
+               return $?
+
+       check_router_ni_status "up" "down" ||
+               return $?
+
+       # But route should still be down because of avoid_asym_router_failure
+       check_route_aliveness "$HOSTNAME" "down" ||
+               return $?
+
+       do_lnetctl ping ${RPEER_NIDS[0]} &&
+               error "Ping should fail"
+
+       do_node $RPEER "$LNETCTL ping ${LNIDS[0]}" &&
+               error "$RPEER ping should fail"
+
+       # Adding the symmetric route should cause the remote NI to go up and
+       # routes to go up
+       do_route_add $RPEER $LOCAL_NET ${ROUTER_NIDS[1]} ||
+               return $?
+
+       check_router_ni_status "up" "up" ||
+               return $?
+
+       check_route_aliveness "$HOSTNAME" "up" ||
+               return $?
+
+       check_route_aliveness "$RPEER" "up" ||
+               return $?
+
+       do_lnetctl ping ${RPEER_NIDS[0]} ||
+               error "Failed to ping ${RPEER_NIDS[0]}"
+
+       do_node $RPEER "$LNETCTL ping ${LNIDS[0]}" ||
+               error "$RPEER failed to ping ${LNIDS[0]}"
+
+       # Stop LNet on local host
+       do_lnetctl lnet unconfigure ||
+               error "Failed to stop LNet rc=$?"
+
+       check_router_ni_status "down" "up" ||
+               return $?
+
+       check_route_aliveness "$RPEER" "down" ||
+               return $?
+
+       do_lnetctl ping ${RPEER_NIDS[0]} &&
+               error "Ping should fail"
+
+       do_node $RPEER "$LNETCTL ping ${LNIDS[0]}" &&
+               error "$RPEER ping should fail"
+
+       return 0
+}
+
+test_222() {
+       setup_router_test avoid_asym_router_failure=1 || return $?
+
+       do_aarf_enabled_test || return $?
+
+       cleanup_router_test || return $?
+}
+run_test 222 "Check avoid_asym_router_failure=1"
+
+test_223() {
+       local opts="avoid_asym_router_failure=1 lnet_peer_discovery_disabled=1"
+
+       setup_router_test "$opts" || return $?
+
+       do_aarf_enabled_test || return $?
+
+       cleanup_router_test || return $?
+}
+run_test 223 "Check avoid_asym_router_failure=1 w/DD disabled"
+
+do_aarf_disabled_test() {
+       do_node $ROUTER "$LNETCTL set routing 1" ||
+               error "Unable to enable routing on $ROUTER"
+
+       check_router_ni_status "down" "down"
+
+       do_route_add $HOSTNAME $REMOTE_NET ${ROUTER_NIDS[0]} ||
+               return $?
+
+       check_router_ni_status "up" "down" ||
+               return $?
+
+       check_route_aliveness "$HOSTNAME" "up" ||
+               return $?
+
+       do_route_add $RPEER $LOCAL_NET ${ROUTER_NIDS[1]} ||
+               return $?
+
+       check_router_ni_status "up" "up" ||
+               return $?
+
+       check_route_aliveness "$HOSTNAME" "up" ||
+               return $?
+
+       check_route_aliveness "$RPEER" "up" ||
+               return $?
+
+       do_lnetctl ping ${RPEER_NIDS[0]} ||
+               error "Failed to ping ${RPEER_NIDS[0]}"
+
+       do_node $RPEER "$LNETCTL ping ${LNIDS[0]}" ||
+               error "$RPEER failed to ping ${LNIDS[0]}"
+
+       # Stop LNet on local host
+       do_lnetctl lnet unconfigure ||
+               error "Failed to stop LNet rc=$?"
+
+       check_router_ni_status "down" "up" ||
+               return $?
+
+       check_route_aliveness "$RPEER" "up" ||
+               return $?
+
+       return 0
+}
+
+test_224() {
+       setup_router_test avoid_asym_router_failure=0 ||
+               return $?
+
+       do_aarf_disabled_test ||
+               return $?
+
+       cleanup_router_test ||
+               return $?
+}
+run_test 224 "Check avoid_asym_router_failure=0"
+
+test_225() {
+       local opts="avoid_asym_router_failure=0 lnet_peer_discovery_disabled=1"
+
+       setup_router_test "$opts" || return $?
+
+       do_aarf_disabled_test || return $?
+
+       cleanup_router_test ||
+               return $?
+}
+run_test 225 "Check avoid_asym_router_failure=0 w/DD disabled"
+
+do_rtr_peer_health_test() {
+       local expected="$1"
+
+       do_node $ROUTER "$LNETCTL set routing 1" ||
+               error "Unable to enable routing on $ROUTER"
+
+       do_route_add $HOSTNAME $REMOTE_NET ${ROUTER_NIDS[0]} ||
+               return $?
+
+       do_route_add $RPEER $LOCAL_NET ${ROUTER_NIDS[1]} ||
+               return $?
+
+       check_router_ni_status "up" "up" ||
+               return $?
+
+       check_route_aliveness "$HOSTNAME" "up" ||
+               return $?
+
+       check_route_aliveness "$RPEER" "up" ||
+               return $?
+
+       do_lnetctl ping ${RPEER_NIDS[0]} ||
+               error "Failed to ping ${RPEER_NIDS[0]}"
+
+       do_node $RPEER "$LNETCTL ping ${LNIDS[0]}" ||
+               error "$RPEER failed to ping ${LNIDS[0]}"
+
+       # Stop LNet on local host
+       do_lnetctl lnet unconfigure ||
+               error "Failed to stop LNet rc=$?"
+
+       check_router_ni_status "down" "up" ||
+               return $?
+
+       check_route_aliveness "$RPEER" "up" ||
+               return $?
+
+       # The NI used to send the message to the destination will be the
+       # router's NI on LOCAL_NET, so that's the drop count that will be
+       # incremented
+       local d1=$(do_node $ROUTER $LNETCTL net show -v --net $LOCAL_NET | \
+                                  awk '/drop_count:/{print $NF}')
+
+       # Ping from RPEER to local host should be dropped by the router
+       do_node $RPEER "$LCTL ping ${LNIDS[0]}" &&
+               error "$RPEER expected ping to fail"
+
+       local d2=$(do_node $ROUTER $LNETCTL net show -v --net $LOCAL_NET | \
+                                  awk '/drop_count:/{print $NF}')
+
+       [[ $((d2 - d1)) -ne $expected ]] &&
+               error "Expected drop count change by $expected: $d1 -> $d2"
+
+       return 0
+}
+
+test_226() {
+       setup_router_test avoid_asym_router_failure=0 --peer-timeout=10 ||
+               return $?
+
+       do_rtr_peer_health_test 1 ||
+               return $?
+
+       cleanup_router_test ||
+               return $?
+}
+run_test 226 "Check router peer health enabled"
+
+test_227() {
+       setup_router_test avoid_asym_router_failure=0 --peer-timeout=0 ||
+               return $?
+
+       do_rtr_peer_health_test 0 ||
+               return $?
+
+       cleanup_router_test ||
+               return $?
+}
+run_test 227 "Check router peer health disabled"
+
 test_230() {
        # LU-12815
        echo "Check valid values; Should succeed"
@@ -2517,6 +3084,20 @@ test_300() {
 }
 run_test 300 "packaged LNet UAPI headers can be compiled"
 
+# LU-16081 lnet: Memory leak on adding existing interface
+
+test_301() {
+       reinit_dlc || return $?
+       do_lnetctl net add --net tcp --if ${INTERFACES[0]} ||
+               error "Failed to add net"
+       do_lnetctl net add --net tcp --if ${INTERFACES[0]} &&
+               error "add net should have failed"
+       do_lnetctl net del --net tcp --if ${INTERFACES[0]} ||
+               error "Failed to del net"
+       unload_modules
+}
+run_test 301 "Check for dynamic adds of same/wrong interface (memory leak)"
+
 complete $SECONDS
 
 cleanup_testsuite