Commit 6fa0174a authored by Paolo Abeni's avatar Paolo Abeni Committed by Jakub Kicinski

mptcp: more careful RM_ADDR generation

The in-kernel MPTCP path manager, when processing the MPTCP_PM_CMD_FLUSH_ADDR
command, generates RM_ADDR events for each known local address. While that
is allowed by the RFC, it makes unpredictable the exact number of RM_ADDR
generated when both ends flush the PM addresses.

This change restricts the RM_ADDR generation to previously explicitly
announced addresses, and adjust the expected results in a bunch of related
self-tests.
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f98c2bca
...@@ -1466,14 +1466,12 @@ static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk, ...@@ -1466,14 +1466,12 @@ static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
list_for_each_entry(entry, rm_list, list) { list_for_each_entry(entry, rm_list, list) {
if (lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) && if (lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) &&
alist.nr < MPTCP_RM_IDS_MAX && slist.nr < MPTCP_RM_IDS_MAX)
slist.nr < MPTCP_RM_IDS_MAX) {
alist.ids[alist.nr++] = entry->addr.id;
slist.ids[slist.nr++] = entry->addr.id; slist.ids[slist.nr++] = entry->addr.id;
} else if (remove_anno_list_by_saddr(msk, &entry->addr) &&
alist.nr < MPTCP_RM_IDS_MAX) { if (remove_anno_list_by_saddr(msk, &entry->addr) &&
alist.nr < MPTCP_RM_IDS_MAX)
alist.ids[alist.nr++] = entry->addr.id; alist.ids[alist.nr++] = entry->addr.id;
}
} }
if (alist.nr) { if (alist.nr) {
......
...@@ -1149,14 +1149,25 @@ chk_rm_nr() ...@@ -1149,14 +1149,25 @@ chk_rm_nr()
{ {
local rm_addr_nr=$1 local rm_addr_nr=$1
local rm_subflow_nr=$2 local rm_subflow_nr=$2
local invert=${3:-""} local invert
local simult
local count local count
local dump_stats local dump_stats
local addr_ns=$ns1 local addr_ns=$ns1
local subflow_ns=$ns2 local subflow_ns=$ns2
local extra_msg="" local extra_msg=""
if [[ $invert = "invert" ]]; then shift 2
while [ -n "$1" ]; do
[ "$1" = "invert" ] && invert=true
[ "$1" = "simult" ] && simult=true
shift
done
if [ -z $invert ]; then
addr_ns=$ns1
subflow_ns=$ns2
elif [ $invert = "true" ]; then
addr_ns=$ns2 addr_ns=$ns2
subflow_ns=$ns1 subflow_ns=$ns1
extra_msg=" invert" extra_msg=" invert"
...@@ -1176,6 +1187,25 @@ chk_rm_nr() ...@@ -1176,6 +1187,25 @@ chk_rm_nr()
echo -n " - rmsf " echo -n " - rmsf "
count=`ip netns exec $subflow_ns nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}'` count=`ip netns exec $subflow_ns nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}'`
[ -z "$count" ] && count=0 [ -z "$count" ] && count=0
if [ -n "$simult" ]; then
local cnt=$(ip netns exec $addr_ns nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}')
local suffix
# in case of simult flush, the subflow removal count on each side is
# unreliable
[ -z "$cnt" ] && cnt=0
count=$((count + cnt))
[ "$count" != "$rm_subflow_nr" ] && suffix="$count in [$rm_subflow_nr:$((rm_subflow_nr*2))]"
if [ $count -ge "$rm_subflow_nr" ] && \
[ "$count" -le "$((rm_subflow_nr *2 ))" ]; then
echo "[ ok ] $suffix"
else
echo "[fail] got $count RM_SUBFLOW[s] expected in range [$rm_subflow_nr:$((rm_subflow_nr*2))]"
ret=1
dump_stats=1
fi
return
fi
if [ "$count" != "$rm_subflow_nr" ]; then if [ "$count" != "$rm_subflow_nr" ]; then
echo "[fail] got $count RM_SUBFLOW[s] expected $rm_subflow_nr" echo "[fail] got $count RM_SUBFLOW[s] expected $rm_subflow_nr"
ret=1 ret=1
...@@ -1666,7 +1696,7 @@ remove_tests() ...@@ -1666,7 +1696,7 @@ remove_tests()
run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
chk_join_nr "flush subflows and signal" 3 3 3 chk_join_nr "flush subflows and signal" 3 3 3
chk_add_nr 1 1 chk_add_nr 1 1
chk_rm_nr 2 2 chk_rm_nr 1 3 invert simult
# subflows flush # subflows flush
reset reset
...@@ -1677,7 +1707,7 @@ remove_tests() ...@@ -1677,7 +1707,7 @@ remove_tests()
pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
chk_join_nr "flush subflows" 3 3 3 chk_join_nr "flush subflows" 3 3 3
chk_rm_nr 3 3 chk_rm_nr 0 3 simult
# addresses flush # addresses flush
reset reset
...@@ -1689,7 +1719,7 @@ remove_tests() ...@@ -1689,7 +1719,7 @@ remove_tests()
run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
chk_join_nr "flush addresses" 3 3 3 chk_join_nr "flush addresses" 3 3 3
chk_add_nr 3 3 chk_add_nr 3 3
chk_rm_nr 3 3 invert chk_rm_nr 3 3 invert simult
# invalid addresses flush # invalid addresses flush
reset reset
...@@ -1973,7 +2003,7 @@ add_addr_ports_tests() ...@@ -1973,7 +2003,7 @@ add_addr_ports_tests()
run_tests $ns1 $ns2 10.0.1.1 0 -8 -2 slow run_tests $ns1 $ns2 10.0.1.1 0 -8 -2 slow
chk_join_nr "flush subflows and signal with port" 3 3 3 chk_join_nr "flush subflows and signal with port" 3 3 3
chk_add_nr 1 1 chk_add_nr 1 1
chk_rm_nr 2 2 chk_rm_nr 1 3 invert simult
# multiple addresses with port # multiple addresses with port
reset reset
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment