fi
}
+xfail()
+{
+ FAIL_TO_XFAIL=yes "$@"
+}
+
xfail_on_slow()
{
if [[ $KSFT_MACHINE_SLOW = yes ]]; then
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
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"
+}
{
local send_if_name=$1; shift
local rcv_if_name=$1; shift
+ local no_unicast_flt=$1; shift
local test_name="$1"; shift
local smac=$(mac_get $send_if_name)
local rcv_dmac=$(mac_get $rcv_if_name)
+ local should_receive
tcpdump_start $rcv_if_name
"$smac > $MACVLAN_ADDR, ethertype IPv4 (0x0800)" \
true "$test_name"
- xfail_on_veth $h1 \
- check_rcv $rcv_if_name "Unicast IPv4 to unknown MAC address" \
- "$smac > $UNKNOWN_UC_ADDR1, ethertype IPv4 (0x0800)" \
- false "$test_name"
+ [ $no_unicast_flt = true ] && should_receive=true || should_receive=false
+ check_rcv $rcv_if_name "Unicast IPv4 to unknown MAC address" \
+ "$smac > $UNKNOWN_UC_ADDR1, ethertype IPv4 (0x0800)" \
+ $should_receive "$test_name"
check_rcv $rcv_if_name "Unicast IPv4 to unknown MAC address, promisc" \
"$smac > $UNKNOWN_UC_ADDR2, ethertype IPv4 (0x0800)" \
true "$test_name"
- xfail_on_veth $h1 \
- check_rcv $rcv_if_name \
- "Unicast IPv4 to unknown MAC address, allmulti" \
- "$smac > $UNKNOWN_UC_ADDR3, ethertype IPv4 (0x0800)" \
- false "$test_name"
+ [ $no_unicast_flt = true ] && should_receive=true || should_receive=false
+ check_rcv $rcv_if_name \
+ "Unicast IPv4 to unknown MAC address, allmulti" \
+ "$smac > $UNKNOWN_UC_ADDR3, ethertype IPv4 (0x0800)" \
+ $should_receive "$test_name"
check_rcv $rcv_if_name "Multicast IPv4 to joined group" \
"$smac > $JOINED_MACV4_MC_ADDR, ethertype IPv4 (0x0800)" \
true "$test_name"
- xfail_on_veth $h1 \
+ xfail \
check_rcv $rcv_if_name \
"Multicast IPv4 to unknown group" \
"$smac > $UNKNOWN_MACV4_MC_ADDR1, ethertype IPv4 (0x0800)" \
"$smac > $JOINED_MACV6_MC_ADDR, ethertype IPv6 (0x86dd)" \
true "$test_name"
- xfail_on_veth $h1 \
+ xfail \
check_rcv $rcv_if_name "Multicast IPv6 to unknown group" \
"$smac > $UNKNOWN_MACV6_MC_ADDR1, ethertype IPv6 (0x86dd)" \
false "$test_name"
standalone()
{
+ local no_unicast_flt=true
+
+ if [ $(has_unicast_flt $h2) = yes ]; then
+ no_unicast_flt=false
+ fi
+
h1_create
h2_create
macvlan_create $h2
- run_test $h1 $h2 "$h2"
+ run_test $h1 $h2 $no_unicast_flt "$h2"
macvlan_destroy
h2_destroy
test_bridge()
{
+ local no_unicast_flt=true
local vlan_filtering=$1
h1_create
simple_if_init br0 $H2_IPV4/24 $H2_IPV6/64
macvlan_create br0
- run_test $h1 br0 "vlan_filtering=$vlan_filtering bridge"
+ run_test $h1 br0 $no_unicast_flt "vlan_filtering=$vlan_filtering bridge"
macvlan_destroy
simple_if_fini br0 $H2_IPV4/24 $H2_IPV6/64
test_vlan()
{
+ local no_unicast_flt=true
+
+ if [ $(has_unicast_flt $h2) = yes ]; then
+ no_unicast_flt=false
+ fi
+
h1_vlan_create
h2_vlan_create
macvlan_create $h2.100
- run_test $h1.100 $h2.100 "VLAN upper"
+ run_test $h1.100 $h2.100 $no_unicast_flt "VLAN upper"
macvlan_destroy
h2_vlan_destroy
vlan_over_bridged_port()
{
+ local no_unicast_flt=true
local vlan_filtering=$1
+ # br_manage_promisc() will not force a single vlan_filtering port to
+ # promiscuous mode, so we should still expect unicast filtering to take
+ # place if the device can do it.
+ if [ $(has_unicast_flt $h2) = yes ] && [ $vlan_filtering = 1 ]; then
+ no_unicast_flt=false
+ fi
+
h1_vlan_create
h2_vlan_create
bridge_create $vlan_filtering
macvlan_create $h2.100
- run_test $h1.100 $h2.100 "VLAN over vlan_filtering=$vlan_filtering bridged port"
+ run_test $h1.100 $h2.100 $no_unicast_flt \
+ "VLAN over vlan_filtering=$vlan_filtering bridged port"
macvlan_destroy
bridge_destroy
vlan_over_bridge()
{
+ local no_unicast_flt=true
local vlan_filtering=$1
h1_vlan_create
bridge vlan add dev br0 vid 100 self
fi
- run_test $h1.100 br0.100 "VLAN over vlan_filtering=$vlan_filtering bridge"
+ run_test $h1.100 br0.100 $no_unicast_flt \
+ "VLAN over vlan_filtering=$vlan_filtering bridge"
if [ $vlan_filtering = 1 ]; then
bridge vlan del dev br0 vid 100 self