selftests: net: local_termination: don't use xfail_on_veth()
xfail_on_veth() for this test is an incorrect approximation which gives false positives and false negatives. When local_termination fails with "reception succeeded, but should have failed", it is because the DUT ($h2) accepts packets even when not configured as promiscuous. This is not something specific to veth; even the bridge behaves that way, but this is not captured by the xfail_on_veth test. The IFF_UNICAST_FLT flag is not explicitly exported to user space, but it can somewhat be determined from the interface's behavior. We have to create a macvlan upper with a different MAC address. This forces a dev_uc_add() call in the kernel. When the unicast filtering list is not empty, but the device doesn't support IFF_UNICAST_FLT, __dev_set_rx_mode() force-enables promiscuity on the interface, to ensure correct behavior (that the requested address is received). We can monitor the change in the promiscuity flag and infer from it whether the device supports unicast filtering. There is no equivalent thing for allmulti, unfortunately. We never know what's hiding behind a device which has allmulti=off. Whether it will actually perform RX multicast filtering of unknown traffic is a strong "maybe". The bridge driver, for example, completely ignores the flag. We'll have to keep the xfail behavior, but instead of XFAIL on just veth, always XFAIL. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
5fea8bb009
commit
9aa3749ca4
@@ -500,6 +500,11 @@ check_err_fail()
|
||||
fi
|
||||
}
|
||||
|
||||
xfail()
|
||||
{
|
||||
FAIL_TO_XFAIL=yes "$@"
|
||||
}
|
||||
|
||||
xfail_on_slow()
|
||||
{
|
||||
if [[ $KSFT_MACHINE_SLOW = yes ]]; then
|
||||
@@ -1113,6 +1118,39 @@ mac_get()
|
||||
ip -j link show dev $if_name | jq -r '.[]["address"]'
|
||||
}
|
||||
|
||||
ether_addr_to_u64()
|
||||
{
|
||||
local addr="$1"
|
||||
local order="$((1 << 40))"
|
||||
local val=0
|
||||
local byte
|
||||
|
||||
addr="${addr//:/ }"
|
||||
|
||||
for byte in $addr; do
|
||||
byte="0x$byte"
|
||||
val=$((val + order * byte))
|
||||
order=$((order >> 8))
|
||||
done
|
||||
|
||||
printf "0x%x" $val
|
||||
}
|
||||
|
||||
u64_to_ether_addr()
|
||||
{
|
||||
local val=$1
|
||||
local byte
|
||||
local i
|
||||
|
||||
for ((i = 40; i >= 0; i -= 8)); do
|
||||
byte=$(((val & (0xff << i)) >> i))
|
||||
printf "%02x" $byte
|
||||
if [ $i -ne 0 ]; then
|
||||
printf ":"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
ipv6_lladdr_get()
|
||||
{
|
||||
local if_name=$1
|
||||
@@ -2229,3 +2267,22 @@ absval()
|
||||
|
||||
echo $((v > 0 ? v : -v))
|
||||
}
|
||||
|
||||
has_unicast_flt()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local mac_addr=$(mac_get $dev)
|
||||
local tmp=$(ether_addr_to_u64 $mac_addr)
|
||||
local promisc
|
||||
|
||||
ip link set $dev up
|
||||
ip link add link $dev name macvlan-tmp type macvlan mode private
|
||||
ip link set macvlan-tmp address $(u64_to_ether_addr $((tmp + 1)))
|
||||
ip link set macvlan-tmp up
|
||||
|
||||
promisc=$(ip -j -d link show dev $dev | jq -r '.[].promiscuity')
|
||||
|
||||
ip link del macvlan-tmp
|
||||
|
||||
[[ $promisc == 1 ]] && echo "no" || echo "yes"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user