CONFIG_NFT_COMPAT=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NF_TABLES_INET=y
 CONFIG_NFT_TPROXY=m
 CONFIG_NFT_SOCKET=m
 CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_NET_ACT_CSUM=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_SCH_INGRESS=m
 
        ip netns exec $ns2 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns2_enable
 }
 
+# Modify TCP payload without corrupting the TCP packet
+#
+# This rule inverts a 8-bit word at byte offset 148 for the 2nd TCP ACK packets
+# carrying enough data.
+# Once it is done, the TCP Checksum field is updated so the packet is still
+# considered as valid at the TCP level.
+# Because the MPTCP checksum, covering the TCP options and data, has not been
+# updated, the modification will be detected and an MP_FAIL will be emitted:
+# what we want to validate here without corrupting "random" MPTCP options.
+#
+# To avoid having tc producing this pr_info() message for each TCP ACK packets
+# not carrying enough data:
+#
+#     tc action pedit offset 162 out of bounds
+#
+# Netfilter is used to mark packets with enough data.
+reset_with_fail()
+{
+       reset "${1}" || return 1
+
+       ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=1
+       ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=1
+
+       check_invert=1
+       validate_checksum=1
+       local i="$2"
+       local ip="${3:-4}"
+       local tables
+
+       tables="iptables"
+       if [ $ip -eq 6 ]; then
+               tables="ip6tables"
+       fi
+
+       ip netns exec $ns2 $tables \
+               -t mangle \
+               -A OUTPUT \
+               -o ns2eth$i \
+               -p tcp \
+               -m length --length 150:9999 \
+               -m statistic --mode nth --packet 1 --every 99999 \
+               -j MARK --set-mark 42 || exit 1
+
+       tc -n $ns2 qdisc add dev ns2eth$i clsact || exit 1
+       tc -n $ns2 filter add dev ns2eth$i egress \
+               protocol ip prio 1000 \
+               handle 42 fw \
+               action pedit munge offset 148 u8 invert \
+               pipe csum tcp \
+               index 100 || exit 1
+}
+
 fail_test()
 {
        ret=1
                echo "[ ok ]"
        fi
        [ "${dump_stats}" = 1 ] && dump_stats
-       if [ $checksum -eq 1 ]; then
+       if [ $validate_checksum -eq 1 ]; then
                chk_csum_nr $csum_ns1 $csum_ns2
                chk_fail_nr $fail_nr $fail_nr
                chk_rst_nr $rst_nr $rst_nr
        fi
 }
 
+pedit_action_pkts()
+{
+       tc -n $ns2 -j -s action show action pedit index 100 | \
+               sed 's/.*"packets":\([0-9]\+\),.*/\1/'
+}
+
+fail_tests()
+{
+       # single subflow
+       if reset_with_fail "Infinite map" 1; then
+               run_tests $ns1 $ns2 10.0.1.1 128
+               chk_join_nr 0 0 0 +1 +0 1 0 1 "$(pedit_action_pkts)"
+       fi
+}
+
 implicit_tests()
 {
        # userspace pm type prevents add_addr
        d@deny_join_id0_tests
        m@fullmesh_tests
        z@fastclose_tests
+       F@fail_tests
        I@implicit_tests
 )