--- /dev/null
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_bitshift)
+
+set -e
+
+$NFT -f - <<EOF
+table ip t {
+ map m {
+ typeof ip saddr : mark
+ elements = { 1.2.3.4 : 42 }
+ }
+
+ chain c {
+ meta mark set ip saddr map @m
+ meta mark set ip saddr & 255.255.255.0 map @m
+ meta mark set ip saddr ^ 255.255.255.0 map @m
+ meta mark set ip saddr ^ ip daddr map @m
+ meta mark set ip saddr ^ 1 map @m
+
+ meta mark set ip saddr & ip daddr map { 10.1.2.3 : 1, 10.2.3.4 : 2 }
+ meta mark set ip saddr ^ ip daddr map { 10.1.2.3 : 1, 10.2.3.4 : 2 }
+ }
+}
+EOF
+
+$NFT add element "t m { 10.1.2.1 : 23 }"
--- /dev/null
+table ip t {
+ map m {
+ typeof ip saddr : meta mark
+ elements = { 1.2.3.4 : 0x0000002a,
+ 10.1.2.1 : 0x00000017 }
+ }
+
+ chain c {
+ meta mark set ip saddr map @m
+ meta mark set ip saddr & 255.255.255.0 map @m
+ meta mark set ip saddr ^ 255.255.255.0 map @m
+ meta mark set ip saddr ^ ip daddr map @m
+ meta mark set ip saddr ^ 0.0.0.1 map @m
+ meta mark set ip saddr & ip daddr map { 10.1.2.3 : 0x00000001, 10.2.3.4 : 0x00000002 }
+ meta mark set ip saddr ^ ip daddr map { 10.1.2.3 : 0x00000001, 10.2.3.4 : 0x00000002 }
+ }
+}
--- /dev/null
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_bitshift)
+
+set -e
+ret=0
+
+ip link set lo up
+
+$NFT -f - <<EOF
+table ip test-binop {
+ chain in {
+ type filter hook input priority 0
+
+ icmp type echo-request jump {
+ meta mark 0 counter
+ meta mark 1 counter
+ meta mark 2 counter
+ meta mark 3 counter
+ }
+ }
+
+ chain out {
+ type filter hook output priority 0
+
+ icmp type echo-request meta mark set ip saddr ^ ip daddr map { 0.0.0.0 : 1, 0.1.2.2 : 2, 127.0.0.1 : 3 }
+ }
+}
+EOF
+
+test_match()
+{
+ mark="$1"
+ packets="$2"
+ str=$(printf "mark 0x%08x" $mark)
+
+ if ! $NFT list chain test-binop in | grep "$str" | grep "packets $packets"; then
+ $NFT list chain test-binop in
+ echo "Failed counter for mark $mark: not $packets"
+ ret=1
+ fi
+}
+
+test_ping_and_match()
+{
+ ping="$1"
+ mark="$2"
+ packets="$3"
+
+ ping -q -c 1 "$ping"
+ test_match "$mark" "$packets"
+}
+
+test_ping_and_match "127.0.0.1" 1 1
+test_ping_and_match "127.1.2.3" 2 1
+
+# validation of 0 counters done via dump.
+# validation of 1-counters done manually to make
+# sure each ping triggers the expected counter.
+
+exit $ret
--- /dev/null
+table ip test-binop {
+ chain in {
+ type filter hook input priority filter; policy accept;
+ icmp type echo-request jump {
+ meta mark 0x00000000 counter packets 0 bytes 0
+ meta mark 0x00000001 counter packets 1 bytes 84
+ meta mark 0x00000002 counter packets 1 bytes 84
+ meta mark 0x00000003 counter packets 0 bytes 0
+ }
+ }
+
+ chain out {
+ type filter hook output priority filter; policy accept;
+ icmp type echo-request meta mark set ip saddr ^ ip daddr map { 0.0.0.0 : 0x00000001, 0.1.2.2 : 0x00000002, 127.0.0.1 : 0x00000003 }
+ }
+}