diff options
Diffstat (limited to 'tools/testing/selftests/netfilter')
32 files changed, 0 insertions, 8895 deletions
diff --git a/tools/testing/selftests/netfilter/.gitignore b/tools/testing/selftests/netfilter/.gitignore deleted file mode 100644 index c2229b3e40d4..000000000000 --- a/tools/testing/selftests/netfilter/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -nf-queue -connect_close -audit_logread -conntrack_dump_flush -sctp_collision diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile deleted file mode 100644 index 936c3085bb83..000000000000 --- a/tools/testing/selftests/netfilter/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Makefile for netfilter selftests - -TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \ - conntrack_icmp_related.sh nft_flowtable.sh ipvs.sh \ - nft_concat_range.sh nft_conntrack_helper.sh \ - nft_queue.sh nft_meta.sh nf_nat_edemux.sh \ - ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \ - conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh \ - conntrack_sctp_collision.sh xt_string.sh \ - bridge_netfilter.sh - -HOSTPKG_CONFIG := pkg-config - -CFLAGS += $(shell $(HOSTPKG_CONFIG) --cflags libmnl 2>/dev/null) -LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) - -TEST_GEN_FILES = nf-queue connect_close audit_logread sctp_collision \ - conntrack_dump_flush - -include ../lib.mk diff --git a/tools/testing/selftests/netfilter/audit_logread.c b/tools/testing/selftests/netfilter/audit_logread.c deleted file mode 100644 index a0a880fc2d9d..000000000000 --- a/tools/testing/selftests/netfilter/audit_logread.c +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#define _GNU_SOURCE -#include <errno.h> -#include <fcntl.h> -#include <poll.h> -#include <signal.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/socket.h> -#include <unistd.h> -#include <linux/audit.h> -#include <linux/netlink.h> - -static int fd; - -#define MAX_AUDIT_MESSAGE_LENGTH 8970 -struct audit_message { - struct nlmsghdr nlh; - union { - struct audit_status s; - char data[MAX_AUDIT_MESSAGE_LENGTH]; - } u; -}; - -int audit_recv(int fd, struct audit_message *rep) -{ - struct sockaddr_nl addr; - socklen_t addrlen = sizeof(addr); - int ret; - - do { - ret = recvfrom(fd, rep, sizeof(*rep), 0, - (struct sockaddr *)&addr, &addrlen); - } while (ret < 0 && errno == EINTR); - - if (ret < 0 || - addrlen != sizeof(addr) || - addr.nl_pid != 0 || - rep->nlh.nlmsg_type == NLMSG_ERROR) /* short-cut for now */ - return -1; - - return ret; -} - -int audit_send(int fd, uint16_t type, uint32_t key, uint32_t val) -{ - static int seq = 0; - struct audit_message msg = { - .nlh = { - .nlmsg_len = NLMSG_SPACE(sizeof(msg.u.s)), - .nlmsg_type = type, - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, - .nlmsg_seq = ++seq, - }, - .u.s = { - .mask = key, - .enabled = key == AUDIT_STATUS_ENABLED ? val : 0, - .pid = key == AUDIT_STATUS_PID ? val : 0, - } - }; - struct sockaddr_nl addr = { - .nl_family = AF_NETLINK, - }; - int ret; - - do { - ret = sendto(fd, &msg, msg.nlh.nlmsg_len, 0, - (struct sockaddr *)&addr, sizeof(addr)); - } while (ret < 0 && errno == EINTR); - - if (ret != (int)msg.nlh.nlmsg_len) - return -1; - return 0; -} - -int audit_set(int fd, uint32_t key, uint32_t val) -{ - struct audit_message rep = { 0 }; - int ret; - - ret = audit_send(fd, AUDIT_SET, key, val); - if (ret) - return ret; - - ret = audit_recv(fd, &rep); - if (ret < 0) - return ret; - return 0; -} - -int readlog(int fd) -{ - struct audit_message rep = { 0 }; - int ret = audit_recv(fd, &rep); - const char *sep = ""; - char *k, *v; - - if (ret < 0) - return ret; - - if (rep.nlh.nlmsg_type != AUDIT_NETFILTER_CFG) - return 0; - - /* skip the initial "audit(...): " part */ - strtok(rep.u.data, " "); - - while ((k = strtok(NULL, "="))) { - v = strtok(NULL, " "); - - /* these vary and/or are uninteresting, ignore */ - if (!strcmp(k, "pid") || - !strcmp(k, "comm") || - !strcmp(k, "subj")) - continue; - - /* strip the varying sequence number */ - if (!strcmp(k, "table")) - *strchrnul(v, ':') = '\0'; - - printf("%s%s=%s", sep, k, v); - sep = " "; - } - if (*sep) { - printf("\n"); - fflush(stdout); - } - return 0; -} - -void cleanup(int sig) -{ - audit_set(fd, AUDIT_STATUS_ENABLED, 0); - close(fd); - if (sig) - exit(0); -} - -int main(int argc, char **argv) -{ - struct sigaction act = { - .sa_handler = cleanup, - }; - - fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_AUDIT); - if (fd < 0) { - perror("Can't open netlink socket"); - return -1; - } - - if (sigaction(SIGTERM, &act, NULL) < 0 || - sigaction(SIGINT, &act, NULL) < 0) { - perror("Can't set signal handler"); - close(fd); - return -1; - } - - audit_set(fd, AUDIT_STATUS_ENABLED, 1); - audit_set(fd, AUDIT_STATUS_PID, getpid()); - - while (1) - readlog(fd); -} diff --git a/tools/testing/selftests/netfilter/bridge_brouter.sh b/tools/testing/selftests/netfilter/bridge_brouter.sh deleted file mode 100755 index 29f3955b9af7..000000000000 --- a/tools/testing/selftests/netfilter/bridge_brouter.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/bash -# -# This test is for bridge 'brouting', i.e. make some packets being routed -# rather than getting bridged even though they arrive on interface that is -# part of a bridge. - -# eth0 br0 eth0 -# setup is: ns1 <-> ns0 <-> ns2 - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -ebtables -V > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ebtables" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -ip netns add ns0 -ip netns add ns1 -ip netns add ns2 - -ip link add veth0 netns ns0 type veth peer name eth0 netns ns1 -if [ $? -ne 0 ]; then - echo "SKIP: Can't create veth device" - exit $ksft_skip -fi -ip link add veth1 netns ns0 type veth peer name eth0 netns ns2 - -ip -net ns0 link set lo up -ip -net ns0 link set veth0 up -ip -net ns0 link set veth1 up - -ip -net ns0 link add br0 type bridge -if [ $? -ne 0 ]; then - echo "SKIP: Can't create bridge br0" - exit $ksft_skip -fi - -ip -net ns0 link set veth0 master br0 -ip -net ns0 link set veth1 master br0 -ip -net ns0 link set br0 up -ip -net ns0 addr add 10.0.0.1/24 dev br0 - -# place both in same subnet, ns1 and ns2 connected via ns0:br0 -for i in 1 2; do - ip -net ns$i link set lo up - ip -net ns$i link set eth0 up - ip -net ns$i addr add 10.0.0.1$i/24 dev eth0 -done - -test_ebtables_broute() -{ - local cipt - - # redirect is needed so the dstmac is rewritten to the bridge itself, - # ip stack won't process OTHERHOST (foreign unicast mac) packets. - ip netns exec ns0 ebtables -t broute -A BROUTING -p ipv4 --ip-protocol icmp -j redirect --redirect-target=DROP - if [ $? -ne 0 ]; then - echo "SKIP: Could not add ebtables broute redirect rule" - return $ksft_skip - fi - - # ping netns1, expected to not work (ip forwarding is off) - ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "ERROR: ping works, should have failed" 1>&2 - return 1 - fi - - # enable forwarding on both interfaces. - # neither needs an ip address, but at least the bridge needs - # an ip address in same network segment as ns1 and ns2 (ns0 - # needs to be able to determine route for to-be-forwarded packet). - ip netns exec ns0 sysctl -q net.ipv4.conf.veth0.forwarding=1 - ip netns exec ns0 sysctl -q net.ipv4.conf.veth1.forwarding=1 - - sleep 1 - - ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null - if [ $? -ne 0 ]; then - echo "ERROR: ping did not work, but it should (broute+forward)" 1>&2 - return 1 - fi - - echo "PASS: ns1/ns2 connectivity with active broute rule" - ip netns exec ns0 ebtables -t broute -F - - # ping netns1, expected to work (frames are bridged) - ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null - if [ $? -ne 0 ]; then - echo "ERROR: ping did not work, but it should (bridged)" 1>&2 - return 1 - fi - - ip netns exec ns0 ebtables -t filter -A FORWARD -p ipv4 --ip-protocol icmp -j DROP - - # ping netns1, expected to not work (DROP in bridge forward) - ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "ERROR: ping works, should have failed (icmp forward drop)" 1>&2 - return 1 - fi - - # re-activate brouter - ip netns exec ns0 ebtables -t broute -A BROUTING -p ipv4 --ip-protocol icmp -j redirect --redirect-target=DROP - - ip netns exec ns2 ping -q -c 1 10.0.0.11 > /dev/null - if [ $? -ne 0 ]; then - echo "ERROR: ping did not work, but it should (broute+forward 2)" 1>&2 - return 1 - fi - - echo "PASS: ns1/ns2 connectivity with active broute rule and bridge forward drop" - return 0 -} - -# test basic connectivity -ip netns exec ns1 ping -c 1 -q 10.0.0.12 > /dev/null -if [ $? -ne 0 ]; then - echo "ERROR: Could not reach ns2 from ns1" 1>&2 - ret=1 -fi - -ip netns exec ns2 ping -c 1 -q 10.0.0.11 > /dev/null -if [ $? -ne 0 ]; then - echo "ERROR: Could not reach ns1 from ns2" 1>&2 - ret=1 -fi - -if [ $ret -eq 0 ];then - echo "PASS: netns connectivity: ns1 and ns2 can reach each other" -fi - -test_ebtables_broute -ret=$? -for i in 0 1 2; do ip netns del ns$i;done - -exit $ret diff --git a/tools/testing/selftests/netfilter/bridge_netfilter.sh b/tools/testing/selftests/netfilter/bridge_netfilter.sh deleted file mode 100644 index 659b3ab02c8b..000000000000 --- a/tools/testing/selftests/netfilter/bridge_netfilter.sh +++ /dev/null @@ -1,188 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 -# -# Test bridge netfilter + conntrack, a combination that doesn't really work, -# with multicast/broadcast packets racing for hash table insertion. - -# eth0 br0 eth0 -# setup is: ns1 <->,ns0 <-> ns3 -# ns2 <-' `'-> ns4 - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -sfx=$(mktemp -u "XXXXXXXX") -ns0="ns0-$sfx" -ns1="ns1-$sfx" -ns2="ns2-$sfx" -ns3="ns3-$sfx" -ns4="ns4-$sfx" - -ebtables -V > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ebtables" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -for i in $(seq 0 4); do - eval ip netns add \$ns$i -done - -cleanup() { - for i in $(seq 0 4); do eval ip netns del \$ns$i;done -} - -trap cleanup EXIT - -do_ping() -{ - fromns="$1" - dstip="$2" - - ip netns exec $fromns ping -c 1 -q $dstip > /dev/null - if [ $? -ne 0 ]; then - echo "ERROR: ping from $fromns to $dstip" - ip netns exec ${ns0} nft list ruleset - ret=1 - fi -} - -bcast_ping() -{ - fromns="$1" - dstip="$2" - - for i in $(seq 1 1000); do - ip netns exec $fromns ping -q -f -b -c 1 -q $dstip > /dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "ERROR: ping -b from $fromns to $dstip" - ip netns exec ${ns0} nft list ruleset - fi - done -} - -ip link add veth1 netns ${ns0} type veth peer name eth0 netns ${ns1} -if [ $? -ne 0 ]; then - echo "SKIP: Can't create veth device" - exit $ksft_skip -fi - -ip link add veth2 netns ${ns0} type veth peer name eth0 netns $ns2 -ip link add veth3 netns ${ns0} type veth peer name eth0 netns $ns3 -ip link add veth4 netns ${ns0} type veth peer name eth0 netns $ns4 - -ip -net ${ns0} link set lo up - -for i in $(seq 1 4); do - ip -net ${ns0} link set veth$i up -done - -ip -net ${ns0} link add br0 type bridge stp_state 0 forward_delay 0 nf_call_iptables 1 nf_call_ip6tables 1 nf_call_arptables 1 -if [ $? -ne 0 ]; then - echo "SKIP: Can't create bridge br0" - exit $ksft_skip -fi - -# make veth0,1,2 part of bridge. -for i in $(seq 1 3); do - ip -net ${ns0} link set veth$i master br0 -done - -# add a macvlan on top of the bridge. -MACVLAN_ADDR=ba:f3:13:37:42:23 -ip -net ${ns0} link add link br0 name macvlan0 type macvlan mode private -ip -net ${ns0} link set macvlan0 address ${MACVLAN_ADDR} -ip -net ${ns0} link set macvlan0 up -ip -net ${ns0} addr add 10.23.0.1/24 dev macvlan0 - -# add a macvlan on top of veth4. -MACVLAN_ADDR=ba:f3:13:37:42:24 -ip -net ${ns0} link add link veth4 name macvlan4 type macvlan mode vepa -ip -net ${ns0} link set macvlan4 address ${MACVLAN_ADDR} -ip -net ${ns0} link set macvlan4 up - -# make the macvlan part of the bridge. -# veth4 is not a bridge port, only the macvlan on top of it. -ip -net ${ns0} link set macvlan4 master br0 - -ip -net ${ns0} link set br0 up -ip -net ${ns0} addr add 10.0.0.1/24 dev br0 -ip netns exec ${ns0} sysctl -q net.bridge.bridge-nf-call-iptables=1 -ret=$? -if [ $ret -ne 0 ] ; then - echo "SKIP: bridge netfilter not available" - ret=$ksft_skip -fi - -# for testing, so namespaces will reply to ping -b probes. -ip netns exec ${ns0} sysctl -q net.ipv4.icmp_echo_ignore_broadcasts=0 - -# enable conntrack in ns0 and drop broadcast packets in forward to -# avoid them from getting confirmed in the postrouting hook before -# the cloned skb is passed up the stack. -ip netns exec ${ns0} nft -f - <<EOF -table ip filter { - chain input { - type filter hook input priority 1; policy accept - iifname br0 counter - ct state new accept - } -} - -table bridge filter { - chain forward { - type filter hook forward priority 0; policy accept - meta pkttype broadcast ip protocol icmp counter drop - } -} -EOF - -# place 1, 2 & 3 in same subnet, connected via ns0:br0. -# ns4 is placed in same subnet as well, but its not -# part of the bridge: the corresponding veth4 is not -# part of the bridge, only its macvlan interface. -for i in $(seq 1 4); do - eval ip -net \$ns$i link set lo up - eval ip -net \$ns$i link set eth0 up -done -for i in $(seq 1 2); do - eval ip -net \$ns$i addr add 10.0.0.1$i/24 dev eth0 -done - -ip -net ${ns3} addr add 10.23.0.13/24 dev eth0 -ip -net ${ns4} addr add 10.23.0.14/24 dev eth0 - -# test basic connectivity -do_ping ${ns1} 10.0.0.12 -do_ping ${ns3} 10.23.0.1 -do_ping ${ns4} 10.23.0.1 - -if [ $ret -eq 0 ];then - echo "PASS: netns connectivity: ns1 can reach ns2, ns3 and ns4 can reach ns0" -fi - -bcast_ping ${ns1} 10.0.0.255 - -# This should deliver broadcast to macvlan0, which is on top of ns0:br0. -bcast_ping ${ns3} 10.23.0.255 - -# same, this time via veth4:macvlan4. -bcast_ping ${ns4} 10.23.0.255 - -read t < /proc/sys/kernel/tainted - -if [ $t -eq 0 ];then - echo PASS: kernel not tainted -else - echo ERROR: kernel is tainted - ret=1 -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/config b/tools/testing/selftests/netfilter/config deleted file mode 100644 index 7c42b1b2c69b..000000000000 --- a/tools/testing/selftests/netfilter/config +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG_NET_NS=y -CONFIG_NF_TABLES_INET=y -CONFIG_NFT_QUEUE=m -CONFIG_NFT_NAT=m -CONFIG_NFT_REDIR=m -CONFIG_NFT_MASQ=m -CONFIG_NFT_FLOW_OFFLOAD=m -CONFIG_NF_CT_NETLINK=m -CONFIG_AUDIT=y diff --git a/tools/testing/selftests/netfilter/connect_close.c b/tools/testing/selftests/netfilter/connect_close.c deleted file mode 100644 index 1c3b0add54c4..000000000000 --- a/tools/testing/selftests/netfilter/connect_close.c +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> - -#include <arpa/inet.h> -#include <sys/socket.h> - -#define PORT 12345 -#define RUNTIME 10 - -static struct { - unsigned int timeout; - unsigned int port; -} opts = { - .timeout = RUNTIME, - .port = PORT, -}; - -static void handler(int sig) -{ - _exit(sig == SIGALRM ? 0 : 1); -} - -static void set_timeout(void) -{ - struct sigaction action = { - .sa_handler = handler, - }; - - sigaction(SIGALRM, &action, NULL); - - alarm(opts.timeout); -} - -static void do_connect(const struct sockaddr_in *dst) -{ - int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - if (s >= 0) - fcntl(s, F_SETFL, O_NONBLOCK); - - connect(s, (struct sockaddr *)dst, sizeof(*dst)); - close(s); -} - -static void do_accept(const struct sockaddr_in *src) -{ - int c, one = 1, s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - if (s < 0) - return; - - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); - setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)); - - bind(s, (struct sockaddr *)src, sizeof(*src)); - - listen(s, 16); - - c = accept(s, NULL, NULL); - if (c >= 0) - close(c); - - close(s); -} - -static int accept_loop(void) -{ - struct sockaddr_in src = { - .sin_family = AF_INET, - .sin_port = htons(opts.port), - }; - - inet_pton(AF_INET, "127.0.0.1", &src.sin_addr); - - set_timeout(); - - for (;;) - do_accept(&src); - - return 1; -} - -static int connect_loop(void) -{ - struct sockaddr_in dst = { - .sin_family = AF_INET, - .sin_port = htons(opts.port), - }; - - inet_pton(AF_INET, "127.0.0.1", &dst.sin_addr); - - set_timeout(); - - for (;;) - do_connect(&dst); - - return 1; -} - -static void parse_opts(int argc, char **argv) -{ - int c; - - while ((c = getopt(argc, argv, "t:p:")) != -1) { - switch (c) { - case 't': - opts.timeout = atoi(optarg); - break; - case 'p': - opts.port = atoi(optarg); - break; - } - } -} - -int main(int argc, char *argv[]) -{ - pid_t p; - - parse_opts(argc, argv); - - p = fork(); - if (p < 0) - return 111; - - if (p > 0) - return accept_loop(); - - return connect_loop(); -} diff --git a/tools/testing/selftests/netfilter/conntrack_dump_flush.c b/tools/testing/selftests/netfilter/conntrack_dump_flush.c deleted file mode 100644 index b11ea8ee6719..000000000000 --- a/tools/testing/selftests/netfilter/conntrack_dump_flush.c +++ /dev/null @@ -1,471 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#define _GNU_SOURCE - -#include <time.h> -#include <libmnl/libmnl.h> -#include <netinet/ip.h> - -#include <linux/netlink.h> -#include <linux/netfilter/nfnetlink.h> -#include <linux/netfilter/nfnetlink_conntrack.h> -#include <linux/netfilter/nf_conntrack_tcp.h> -#include "../kselftest_harness.h" - -#define TEST_ZONE_ID 123 -#define NF_CT_DEFAULT_ZONE_ID 0 - -static int reply_counter; - -static int build_cta_tuple_v4(struct nlmsghdr *nlh, int type, - uint32_t src_ip, uint32_t dst_ip, - uint16_t src_port, uint16_t dst_port) -{ - struct nlattr *nest, *nest_ip, *nest_proto; - - nest = mnl_attr_nest_start(nlh, type); - if (!nest) - return -1; - - nest_ip = mnl_attr_nest_start(nlh, CTA_TUPLE_IP); - if (!nest_ip) - return -1; - mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, src_ip); - mnl_attr_put_u32(nlh, CTA_IP_V4_DST, dst_ip); - mnl_attr_nest_end(nlh, nest_ip); - - nest_proto = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO); - if (!nest_proto) - return -1; - mnl_attr_put_u8(nlh, CTA_PROTO_NUM, 6); - mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(src_port)); - mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(dst_port)); - mnl_attr_nest_end(nlh, nest_proto); - - mnl_attr_nest_end(nlh, nest); -} - -static int build_cta_tuple_v6(struct nlmsghdr *nlh, int type, - struct in6_addr src_ip, struct in6_addr dst_ip, - uint16_t src_port, uint16_t dst_port) -{ - struct nlattr *nest, *nest_ip, *nest_proto; - - nest = mnl_attr_nest_start(nlh, type); - if (!nest) - return -1; - - nest_ip = mnl_attr_nest_start(nlh, CTA_TUPLE_IP); - if (!nest_ip) - return -1; - mnl_attr_put(nlh, CTA_IP_V6_SRC, sizeof(struct in6_addr), &src_ip); - mnl_attr_put(nlh, CTA_IP_V6_DST, sizeof(struct in6_addr), &dst_ip); - mnl_attr_nest_end(nlh, nest_ip); - - nest_proto = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO); - if (!nest_proto) - return -1; - mnl_attr_put_u8(nlh, CTA_PROTO_NUM, 6); - mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(src_port)); - mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(dst_port)); - mnl_attr_nest_end(nlh, nest_proto); - - mnl_attr_nest_end(nlh, nest); -} - -static int build_cta_proto(struct nlmsghdr *nlh) -{ - struct nlattr *nest, *nest_proto; - - nest = mnl_attr_nest_start(nlh, CTA_PROTOINFO); - if (!nest) - return -1; - - nest_proto = mnl_attr_nest_start(nlh, CTA_PROTOINFO_TCP); - if (!nest_proto) - return -1; - mnl_attr_put_u8(nlh, CTA_PROTOINFO_TCP_STATE, TCP_CONNTRACK_ESTABLISHED); - mnl_attr_put_u16(nlh, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL, 0x0a0a); - mnl_attr_put_u16(nlh, CTA_PROTOINFO_TCP_FLAGS_REPLY, 0x0a0a); - mnl_attr_nest_end(nlh, nest_proto); - - mnl_attr_nest_end(nlh, nest); -} - -static int conntrack_data_insert(struct mnl_socket *sock, struct nlmsghdr *nlh, - uint16_t zone) -{ - char buf[MNL_SOCKET_BUFFER_SIZE]; - struct nlmsghdr *rplnlh; - unsigned int portid; - int err, ret; - - portid = mnl_socket_get_portid(sock); - - ret = build_cta_proto(nlh); - if (ret < 0) { - perror("build_cta_proto"); - return -1; - } - mnl_attr_put_u32(nlh, CTA_TIMEOUT, htonl(20000)); - mnl_attr_put_u16(nlh, CTA_ZONE, htons(zone)); - - if (mnl_socket_sendto(sock, nlh, nlh->nlmsg_len) < 0) { - perror("mnl_socket_sendto"); - return -1; - } - - ret = mnl_socket_recvfrom(sock, buf, MNL_SOCKET_BUFFER_SIZE); - if (ret < 0) { - perror("mnl_socket_recvfrom"); - return ret; - } - - ret = mnl_cb_run(buf, ret, nlh->nlmsg_seq, portid, NULL, NULL); - if (ret < 0) { - if (errno == EEXIST) { - /* The entries are probably still there from a previous - * run. So we are good - */ - return 0; - } - perror("mnl_cb_run"); - return ret; - } - - return 0; -} - -static int conntrack_data_generate_v4(struct mnl_socket *sock, uint32_t src_ip, - uint32_t dst_ip, uint16_t zone) -{ - char buf[MNL_SOCKET_BUFFER_SIZE]; - struct nlmsghdr *nlh; - struct nfgenmsg *nfh; - int ret; - - nlh = mnl_nlmsg_put_header(buf); - nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | - NLM_F_ACK | NLM_F_EXCL; - nlh->nlmsg_seq = time(NULL); - - nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg)); - nfh->nfgen_family = AF_INET; - nfh->version = NFNETLINK_V0; - nfh->res_id = 0; - - ret = build_cta_tuple_v4(nlh, CTA_TUPLE_ORIG, src_ip, dst_ip, 12345, 443); - if (ret < 0) { - perror("build_cta_tuple_v4"); - return ret; - } - ret = build_cta_tuple_v4(nlh, CTA_TUPLE_REPLY, dst_ip, src_ip, 443, 12345); - if (ret < 0) { - perror("build_cta_tuple_v4"); - return ret; - } - return conntrack_data_insert(sock, nlh, zone); -} - -static int conntrack_data_generate_v6(struct mnl_socket *sock, - struct in6_addr src_ip, - struct in6_addr dst_ip, - uint16_t zone) -{ - char buf[MNL_SOCKET_BUFFER_SIZE]; - struct nlmsghdr *nlh; - struct nfgenmsg *nfh; - int ret; - - nlh = mnl_nlmsg_put_header(buf); - nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | - NLM_F_ACK | NLM_F_EXCL; - nlh->nlmsg_seq = time(NULL); - - nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg)); - nfh->nfgen_family = AF_INET6; - nfh->version = NFNETLINK_V0; - nfh->res_id = 0; - - ret = build_cta_tuple_v6(nlh, CTA_TUPLE_ORIG, src_ip, dst_ip, - 12345, 443); - if (ret < 0) { - perror("build_cta_tuple_v6"); - return ret; - } - ret = build_cta_tuple_v6(nlh, CTA_TUPLE_REPLY, dst_ip, src_ip, - 12345, 443); - if (ret < 0) { - perror("build_cta_tuple_v6"); - return ret; - } - return conntrack_data_insert(sock, nlh, zone); -} - -static int count_entries(const struct nlmsghdr *nlh, void *data) -{ - reply_counter++; -} - -static int conntracK_count_zone(struct mnl_socket *sock, uint16_t zone) -{ - char buf[MNL_SOCKET_BUFFER_SIZE]; - struct nlmsghdr *nlh, *rplnlh; - struct nfgenmsg *nfh; - struct nlattr *nest; - unsigned int portid; - int err, ret; - - portid = mnl_socket_get_portid(sock); - - nlh = mnl_nlmsg_put_header(buf); - nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; - nlh->nlmsg_seq = time(NULL); - - nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg)); - nfh->nfgen_family = AF_UNSPEC; - nfh->version = NFNETLINK_V0; - nfh->res_id = 0; - - mnl_attr_put_u16(nlh, CTA_ZONE, htons(zone)); - - ret = mnl_socket_sendto(sock, nlh, nlh->nlmsg_len); - if (ret < 0) { - perror("mnl_socket_sendto"); - return ret; - } - - reply_counter = 0; - ret = mnl_socket_recvfrom(sock, buf, MNL_SOCKET_BUFFER_SIZE); - while (ret > 0) { - ret = mnl_cb_run(buf, ret, nlh->nlmsg_seq, portid, - count_entries, NULL); - if (ret <= MNL_CB_STOP) - break; - - ret = mnl_socket_recvfrom(sock, buf, MNL_SOCKET_BUFFER_SIZE); - } - if (ret < 0) { - perror("mnl_socket_recvfrom"); - return ret; - } - - return reply_counter; -} - -static int conntrack_flush_zone(struct mnl_socket *sock, uint16_t zone) -{ - char buf[MNL_SOCKET_BUFFER_SIZE]; - struct nlmsghdr *nlh, *rplnlh; - struct nfgenmsg *nfh; - struct nlattr *nest; - unsigned int portid; - int err, ret; - - portid = mnl_socket_get_portid(sock); - - nlh = mnl_nlmsg_put_header(buf); - nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_DELETE; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - nlh->nlmsg_seq = time(NULL); - - nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg)); - nfh->nfgen_family = AF_UNSPEC; - nfh->version = NFNETLINK_V0; - nfh->res_id = 0; - - mnl_attr_put_u16(nlh, CTA_ZONE, htons(zone)); - - ret = mnl_socket_sendto(sock, nlh, nlh->nlmsg_len); - if (ret < 0) { - perror("mnl_socket_sendto"); - return ret; - } - - ret = mnl_socket_recvfrom(sock, buf, MNL_SOCKET_BUFFER_SIZE); - if (ret < 0) { - perror("mnl_socket_recvfrom"); - return ret; - } - - ret = mnl_cb_run(buf, ret, nlh->nlmsg_seq, portid, NULL, NULL); - if (ret < 0) { - perror("mnl_cb_run"); - return ret; - } - - return 0; -} - -FIXTURE(conntrack_dump_flush) -{ - struct mnl_socket *sock; -}; - -FIXTURE_SETUP(conntrack_dump_flush) -{ - struct in6_addr src, dst; - int ret; - - self->sock = mnl_socket_open(NETLINK_NETFILTER); - if (!self->sock) { - perror("mnl_socket_open"); - exit(EXIT_FAILURE); - } - - if (mnl_socket_bind(self->sock, 0, MNL_SOCKET_AUTOPID) < 0) { - perror("mnl_socket_bind"); - exit(EXIT_FAILURE); - } - - ret = conntracK_count_zone(self->sock, TEST_ZONE_ID); - if (ret < 0 && errno == EPERM) - SKIP(return, "Needs to be run as root"); - else if (ret < 0 && errno == EOPNOTSUPP) - SKIP(return, "Kernel does not seem to support conntrack zones"); - - ret = conntrack_data_generate_v4(self->sock, 0xf0f0f0f0, 0xf1f1f1f1, - TEST_ZONE_ID); - EXPECT_EQ(ret, 0); - ret = conntrack_data_generate_v4(self->sock, 0xf2f2f2f2, 0xf3f3f3f3, - TEST_ZONE_ID + 1); - EXPECT_EQ(ret, 0); - ret = conntrack_data_generate_v4(self->sock, 0xf4f4f4f4, 0xf5f5f5f5, - TEST_ZONE_ID + 2); - EXPECT_EQ(ret, 0); - ret = conntrack_data_generate_v4(self->sock, 0xf6f6f6f6, 0xf7f7f7f7, - NF_CT_DEFAULT_ZONE_ID); - EXPECT_EQ(ret, 0); - - src = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x01000000 - } - }}; - dst = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x02000000 - } - }}; - ret = conntrack_data_generate_v6(self->sock, src, dst, - TEST_ZONE_ID); - EXPECT_EQ(ret, 0); - src = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x03000000 - } - }}; - dst = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x04000000 - } - }}; - ret = conntrack_data_generate_v6(self->sock, src, dst, - TEST_ZONE_ID + 1); - EXPECT_EQ(ret, 0); - src = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x05000000 - } - }}; - dst = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x06000000 - } - }}; - ret = conntrack_data_generate_v6(self->sock, src, dst, - TEST_ZONE_ID + 2); - EXPECT_EQ(ret, 0); - - src = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x07000000 - } - }}; - dst = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x08000000 - } - }}; - ret = conntrack_data_generate_v6(self->sock, src, dst, - NF_CT_DEFAULT_ZONE_ID); - EXPECT_EQ(ret, 0); - - ret = conntracK_count_zone(self->sock, TEST_ZONE_ID); - EXPECT_GE(ret, 2); - if (ret > 2) - SKIP(return, "kernel does not support filtering by zone"); -} - -FIXTURE_TEARDOWN(conntrack_dump_flush) -{ -} - -TEST_F(conntrack_dump_flush, test_dump_by_zone) -{ - int ret; - - ret = conntracK_count_zone(self->sock, TEST_ZONE_ID); - EXPECT_EQ(ret, 2); -} - -TEST_F(conntrack_dump_flush, test_flush_by_zone) -{ - int ret; - - ret = conntrack_flush_zone(self->sock, TEST_ZONE_ID); - EXPECT_EQ(ret, 0); - ret = conntracK_count_zone(self->sock, TEST_ZONE_ID); - EXPECT_EQ(ret, 0); - ret = conntracK_count_zone(self->sock, TEST_ZONE_ID + 1); - EXPECT_EQ(ret, 2); - ret = conntracK_count_zone(self->sock, TEST_ZONE_ID + 2); - EXPECT_EQ(ret, 2); - ret = conntracK_count_zone(self->sock, NF_CT_DEFAULT_ZONE_ID); - EXPECT_EQ(ret, 2); -} - -TEST_F(conntrack_dump_flush, test_flush_by_zone_default) -{ - int ret; - - ret = conntrack_flush_zone(self->sock, NF_CT_DEFAULT_ZONE_ID); - EXPECT_EQ(ret, 0); - ret = conntracK_count_zone(self->sock, TEST_ZONE_ID); - EXPECT_EQ(ret, 2); - ret = conntracK_count_zone(self->sock, TEST_ZONE_ID + 1); - EXPECT_EQ(ret, 2); - ret = conntracK_count_zone(self->sock, TEST_ZONE_ID + 2); - EXPECT_EQ(ret, 2); - ret = conntracK_count_zone(self->sock, NF_CT_DEFAULT_ZONE_ID); - EXPECT_EQ(ret, 0); -} - -TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh deleted file mode 100755 index 76645aaf2b58..000000000000 --- a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh +++ /dev/null @@ -1,315 +0,0 @@ -#!/bin/bash -# -# check that ICMP df-needed/pkttoobig icmp are set are set as related -# state -# -# Setup is: -# -# nsclient1 -> nsrouter1 -> nsrouter2 -> nsclient2 -# MTU 1500, except for nsrouter2 <-> nsclient2 link (1280). -# ping nsclient2 from nsclient1, checking that conntrack did set RELATED -# 'fragmentation needed' icmp packet. -# -# In addition, nsrouter1 will perform IP masquerading, i.e. also -# check the icmp errors are propagated to the correct host as per -# nat of "established" icmp-echo "connection". - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -nft --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -cleanup() { - for i in 1 2;do ip netns del nsclient$i;done - for i in 1 2;do ip netns del nsrouter$i;done -} - -trap cleanup EXIT - -ipv4() { - echo -n 192.168.$1.2 -} - -ipv6 () { - echo -n dead:$1::2 -} - -check_counter() -{ - ns=$1 - name=$2 - expect=$3 - local lret=0 - - cnt=$(ip netns exec $ns nft list counter inet filter "$name" | grep -q "$expect") - if [ $? -ne 0 ]; then - echo "ERROR: counter $name in $ns has unexpected value (expected $expect)" 1>&2 - ip netns exec $ns nft list counter inet filter "$name" 1>&2 - lret=1 - fi - - return $lret -} - -check_unknown() -{ - expect="packets 0 bytes 0" - for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do - check_counter $n "unknown" "$expect" - if [ $? -ne 0 ] ;then - return 1 - fi - done - - return 0 -} - -for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do - ip netns add $n - ip -net $n link set lo up -done - -DEV=veth0 -ip link add $DEV netns nsclient1 type veth peer name eth1 netns nsrouter1 -DEV=veth0 -ip link add $DEV netns nsclient2 type veth peer name eth1 netns nsrouter2 - -DEV=veth0 -ip link add $DEV netns nsrouter1 type veth peer name eth2 netns nsrouter2 - -DEV=veth0 -for i in 1 2; do - ip -net nsclient$i link set $DEV up - ip -net nsclient$i addr add $(ipv4 $i)/24 dev $DEV - ip -net nsclient$i addr add $(ipv6 $i)/64 dev $DEV -done - -ip -net nsrouter1 link set eth1 up -ip -net nsrouter1 link set veth0 up - -ip -net nsrouter2 link set eth1 up -ip -net nsrouter2 link set eth2 up - -ip -net nsclient1 route add default via 192.168.1.1 -ip -net nsclient1 -6 route add default via dead:1::1 - -ip -net nsclient2 route add default via 192.168.2.1 -ip -net nsclient2 route add default via dead:2::1 - -i=3 -ip -net nsrouter1 addr add 192.168.1.1/24 dev eth1 -ip -net nsrouter1 addr add 192.168.3.1/24 dev veth0 -ip -net nsrouter1 addr add dead:1::1/64 dev eth1 -ip -net nsrouter1 addr add dead:3::1/64 dev veth0 -ip -net nsrouter1 route add default via 192.168.3.10 -ip -net nsrouter1 -6 route add default via dead:3::10 - -ip -net nsrouter2 addr add 192.168.2.1/24 dev eth1 -ip -net nsrouter2 addr add 192.168.3.10/24 dev eth2 -ip -net nsrouter2 addr add dead:2::1/64 dev eth1 -ip -net nsrouter2 addr add dead:3::10/64 dev eth2 -ip -net nsrouter2 route add default via 192.168.3.1 -ip -net nsrouter2 route add default via dead:3::1 - -sleep 2 -for i in 4 6; do - ip netns exec nsrouter1 sysctl -q net.ipv$i.conf.all.forwarding=1 - ip netns exec nsrouter2 sysctl -q net.ipv$i.conf.all.forwarding=1 -done - -for netns in nsrouter1 nsrouter2; do -ip netns exec $netns nft -f - <<EOF -table inet filter { - counter unknown { } - counter related { } - chain forward { - type filter hook forward priority 0; policy accept; - meta l4proto icmpv6 icmpv6 type "packet-too-big" ct state "related" counter name "related" accept - meta l4proto icmp icmp type "destination-unreachable" ct state "related" counter name "related" accept - meta l4proto { icmp, icmpv6 } ct state new,established accept - counter name "unknown" drop - } -} -EOF -done - -ip netns exec nsclient1 nft -f - <<EOF -table inet filter { - counter unknown { } - counter related { } - counter redir4 { } - counter redir6 { } - chain input { - type filter hook input priority 0; policy accept; - - icmp type "redirect" ct state "related" counter name "redir4" accept - icmpv6 type "nd-redirect" ct state "related" counter name "redir6" accept - - meta l4proto { icmp, icmpv6 } ct state established,untracked accept - meta l4proto { icmp, icmpv6 } ct state "related" counter name "related" accept - - counter name "unknown" drop - } -} -EOF - -ip netns exec nsclient2 nft -f - <<EOF -table inet filter { - counter unknown { } - counter new { } - counter established { } - - chain input { - type filter hook input priority 0; policy accept; - meta l4proto { icmp, icmpv6 } ct state established,untracked accept - - meta l4proto { icmp, icmpv6 } ct state "new" counter name "new" accept - meta l4proto { icmp, icmpv6 } ct state "established" counter name "established" accept - counter name "unknown" drop - } - chain output { - type filter hook output priority 0; policy accept; - meta l4proto { icmp, icmpv6 } ct state established,untracked accept - - meta l4proto { icmp, icmpv6 } ct state "new" counter name "new" - meta l4proto { icmp, icmpv6 } ct state "established" counter name "established" - counter name "unknown" drop - } -} -EOF - - -# make sure NAT core rewrites adress of icmp error if nat is used according to -# conntrack nat information (icmp error will be directed at nsrouter1 address, -# but it needs to be routed to nsclient1 address). -ip netns exec nsrouter1 nft -f - <<EOF -table ip nat { - chain postrouting { - type nat hook postrouting priority 0; policy accept; - ip protocol icmp oifname "veth0" counter masquerade - } -} -table ip6 nat { - chain postrouting { - type nat hook postrouting priority 0; policy accept; - ip6 nexthdr icmpv6 oifname "veth0" counter masquerade - } -} -EOF - -ip netns exec nsrouter2 ip link set eth1 mtu 1280 -ip netns exec nsclient2 ip link set veth0 mtu 1280 -sleep 1 - -ip netns exec nsclient1 ping -c 1 -s 1000 -q -M do 192.168.2.2 >/dev/null -if [ $? -ne 0 ]; then - echo "ERROR: netns ip routing/connectivity broken" 1>&2 - cleanup - exit 1 -fi -ip netns exec nsclient1 ping6 -q -c 1 -s 1000 dead:2::2 >/dev/null -if [ $? -ne 0 ]; then - echo "ERROR: netns ipv6 routing/connectivity broken" 1>&2 - cleanup - exit 1 -fi - -check_unknown -if [ $? -ne 0 ]; then - ret=1 -fi - -expect="packets 0 bytes 0" -for netns in nsrouter1 nsrouter2 nsclient1;do - check_counter "$netns" "related" "$expect" - if [ $? -ne 0 ]; then - ret=1 - fi -done - -expect="packets 2 bytes 2076" -check_counter nsclient2 "new" "$expect" -if [ $? -ne 0 ]; then - ret=1 -fi - -ip netns exec nsclient1 ping -q -c 1 -s 1300 -M do 192.168.2.2 > /dev/null -if [ $? -eq 0 ]; then - echo "ERROR: ping should have failed with PMTU too big error" 1>&2 - ret=1 -fi - -# nsrouter2 should have generated the icmp error, so -# related counter should be 0 (its in forward). -expect="packets 0 bytes 0" -check_counter "nsrouter2" "related" "$expect" -if [ $? -ne 0 ]; then - ret=1 -fi - -# but nsrouter1 should have seen it, same for nsclient1. -expect="packets 1 bytes 576" -for netns in nsrouter1 nsclient1;do - check_counter "$netns" "related" "$expect" - if [ $? -ne 0 ]; then - ret=1 - fi -done - -ip netns exec nsclient1 ping6 -c 1 -s 1300 dead:2::2 > /dev/null -if [ $? -eq 0 ]; then - echo "ERROR: ping6 should have failed with PMTU too big error" 1>&2 - ret=1 -fi - -expect="packets 2 bytes 1856" -for netns in nsrouter1 nsclient1;do - check_counter "$netns" "related" "$expect" - if [ $? -ne 0 ]; then - ret=1 - fi -done - -if [ $ret -eq 0 ];then - echo "PASS: icmp mtu error had RELATED state" -else - echo "ERROR: icmp error RELATED state test has failed" -fi - -# add 'bad' route, expect icmp REDIRECT to be generated -ip netns exec nsclient1 ip route add 192.168.1.42 via 192.168.1.1 -ip netns exec nsclient1 ip route add dead:1::42 via dead:1::1 - -ip netns exec "nsclient1" ping -q -c 2 192.168.1.42 > /dev/null - -expect="packets 1 bytes 112" -check_counter nsclient1 "redir4" "$expect" -if [ $? -ne 0 ];then - ret=1 -fi - -ip netns exec "nsclient1" ping -c 1 dead:1::42 > /dev/null -expect="packets 1 bytes 192" -check_counter nsclient1 "redir6" "$expect" -if [ $? -ne 0 ];then - ret=1 -fi - -if [ $ret -eq 0 ];then - echo "PASS: icmp redirects had RELATED state" -else - echo "ERROR: icmp redirect RELATED state test has failed" -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/conntrack_sctp_collision.sh b/tools/testing/selftests/netfilter/conntrack_sctp_collision.sh deleted file mode 100755 index a924e595cfd8..000000000000 --- a/tools/testing/selftests/netfilter/conntrack_sctp_collision.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 -# -# Testing For SCTP COLLISION SCENARIO as Below: -# -# 14:35:47.655279 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT] [init tag: 2017837359] -# 14:35:48.353250 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT] [init tag: 1187206187] -# 14:35:48.353275 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT ACK] [init tag: 2017837359] -# 14:35:48.353283 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [COOKIE ECHO] -# 14:35:48.353977 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [COOKIE ACK] -# 14:35:48.855335 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT ACK] [init tag: 164579970] -# -# TOPO: SERVER_NS (link0)<--->(link1) ROUTER_NS (link2)<--->(link3) CLIENT_NS - -CLIENT_NS=$(mktemp -u client-XXXXXXXX) -CLIENT_IP="198.51.200.1" -CLIENT_PORT=1234 - -SERVER_NS=$(mktemp -u server-XXXXXXXX) -SERVER_IP="198.51.100.1" -SERVER_PORT=1234 - -ROUTER_NS=$(mktemp -u router-XXXXXXXX) -CLIENT_GW="198.51.200.2" -SERVER_GW="198.51.100.2" - -# setup the topo -setup() { - ip net add $CLIENT_NS - ip net add $SERVER_NS - ip net add $ROUTER_NS - ip -n $SERVER_NS link add link0 type veth peer name link1 netns $ROUTER_NS - ip -n $CLIENT_NS link add link3 type veth peer name link2 netns $ROUTER_NS - - ip -n $SERVER_NS link set link0 up - ip -n $SERVER_NS addr add $SERVER_IP/24 dev link0 - ip -n $SERVER_NS route add $CLIENT_IP dev link0 via $SERVER_GW - - ip -n $ROUTER_NS link set link1 up - ip -n $ROUTER_NS link set link2 up - ip -n $ROUTER_NS addr add $SERVER_GW/24 dev link1 - ip -n $ROUTER_NS addr add $CLIENT_GW/24 dev link2 - ip net exec $ROUTER_NS sysctl -wq net.ipv4.ip_forward=1 - - ip -n $CLIENT_NS link set link3 up - ip -n $CLIENT_NS addr add $CLIENT_IP/24 dev link3 - ip -n $CLIENT_NS route add $SERVER_IP dev link3 via $CLIENT_GW - - # simulate the delay on OVS upcall by setting up a delay for INIT_ACK with - # tc on $SERVER_NS side - tc -n $SERVER_NS qdisc add dev link0 root handle 1: htb - tc -n $SERVER_NS class add dev link0 parent 1: classid 1:1 htb rate 100mbit - tc -n $SERVER_NS filter add dev link0 parent 1: protocol ip u32 match ip protocol 132 \ - 0xff match u8 2 0xff at 32 flowid 1:1 - tc -n $SERVER_NS qdisc add dev link0 parent 1:1 handle 10: netem delay 1200ms - - # simulate the ctstate check on OVS nf_conntrack - ip net exec $ROUTER_NS iptables -A FORWARD -m state --state INVALID,UNTRACKED -j DROP - ip net exec $ROUTER_NS iptables -A INPUT -p sctp -j DROP - - # use a smaller number for assoc's max_retrans to reproduce the issue - modprobe sctp - ip net exec $CLIENT_NS sysctl -wq net.sctp.association_max_retrans=3 -} - -cleanup() { - ip net exec $CLIENT_NS pkill sctp_collision 2>&1 >/dev/null - ip net exec $SERVER_NS pkill sctp_collision 2>&1 >/dev/null - ip net del "$CLIENT_NS" - ip net del "$SERVER_NS" - ip net del "$ROUTER_NS" -} - -do_test() { - ip net exec $SERVER_NS ./sctp_collision server \ - $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT & - ip net exec $CLIENT_NS ./sctp_collision client \ - $CLIENT_IP $CLIENT_PORT $SERVER_IP $SERVER_PORT -} - -# NOTE: one way to work around the issue is set a smaller hb_interval -# ip net exec $CLIENT_NS sysctl -wq net.sctp.hb_interval=3500 - -# run the test case -trap cleanup EXIT -setup && \ -echo "Test for SCTP Collision in nf_conntrack:" && \ -do_test && echo "PASS!" -exit $? diff --git a/tools/testing/selftests/netfilter/conntrack_tcp_unreplied.sh b/tools/testing/selftests/netfilter/conntrack_tcp_unreplied.sh deleted file mode 100755 index e7d7bf13cff5..000000000000 --- a/tools/testing/selftests/netfilter/conntrack_tcp_unreplied.sh +++ /dev/null @@ -1,167 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 -# -# Check that UNREPLIED tcp conntrack will eventually timeout. -# - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -waittime=20 -sfx=$(mktemp -u "XXXXXXXX") -ns1="ns1-$sfx" -ns2="ns2-$sfx" - -nft --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -cleanup() { - ip netns pids $ns1 | xargs kill 2>/dev/null - ip netns pids $ns2 | xargs kill 2>/dev/null - - ip netns del $ns1 - ip netns del $ns2 -} - -ipv4() { - echo -n 192.168.$1.2 -} - -check_counter() -{ - ns=$1 - name=$2 - expect=$3 - local lret=0 - - cnt=$(ip netns exec $ns2 nft list counter inet filter "$name" | grep -q "$expect") - if [ $? -ne 0 ]; then - echo "ERROR: counter $name in $ns2 has unexpected value (expected $expect)" 1>&2 - ip netns exec $ns2 nft list counter inet filter "$name" 1>&2 - lret=1 - fi - - return $lret -} - -# Create test namespaces -ip netns add $ns1 || exit 1 - -trap cleanup EXIT - -ip netns add $ns2 || exit 1 - -# Connect the namespace to the host using a veth pair -ip -net $ns1 link add name veth1 type veth peer name veth2 -ip -net $ns1 link set netns $ns2 dev veth2 - -ip -net $ns1 link set up dev lo -ip -net $ns2 link set up dev lo -ip -net $ns1 link set up dev veth1 -ip -net $ns2 link set up dev veth2 - -ip -net $ns2 addr add 10.11.11.2/24 dev veth2 -ip -net $ns2 route add default via 10.11.11.1 - -ip netns exec $ns2 sysctl -q net.ipv4.conf.veth2.forwarding=1 - -# add a rule inside NS so we enable conntrack -ip netns exec $ns1 iptables -A INPUT -m state --state established,related -j ACCEPT - -ip -net $ns1 addr add 10.11.11.1/24 dev veth1 -ip -net $ns1 route add 10.99.99.99 via 10.11.11.2 - -# Check connectivity works -ip netns exec $ns1 ping -q -c 2 10.11.11.2 >/dev/null || exit 1 - -ip netns exec $ns2 nc -l -p 8080 < /dev/null & - -# however, conntrack entries are there - -ip netns exec $ns2 nft -f - <<EOF -table inet filter { - counter connreq { } - counter redir { } - chain input { - type filter hook input priority 0; policy accept; - ct state new tcp flags syn ip daddr 10.99.99.99 tcp dport 80 counter name "connreq" accept - ct state new ct status dnat tcp dport 8080 counter name "redir" accept - } -} -EOF -if [ $? -ne 0 ]; then - echo "ERROR: Could not load nft rules" - exit 1 -fi - -ip netns exec $ns2 sysctl -q net.netfilter.nf_conntrack_tcp_timeout_syn_sent=10 - -echo "INFO: connect $ns1 -> $ns2 to the virtual ip" -ip netns exec $ns1 bash -c 'while true ; do - nc -p 60000 10.99.99.99 80 - sleep 1 - done' & - -sleep 1 - -ip netns exec $ns2 nft -f - <<EOF -table inet nat { - chain prerouting { - type nat hook prerouting priority 0; policy accept; - ip daddr 10.99.99.99 tcp dport 80 redirect to :8080 - } -} -EOF -if [ $? -ne 0 ]; then - echo "ERROR: Could not load nat redirect" - exit 1 -fi - -count=$(ip netns exec $ns2 conntrack -L -p tcp --dport 80 2>/dev/null | wc -l) -if [ $count -eq 0 ]; then - echo "ERROR: $ns2 did not pick up tcp connection from peer" - exit 1 -fi - -echo "INFO: NAT redirect added in ns $ns2, waiting for $waittime seconds for nat to take effect" -for i in $(seq 1 $waittime); do - echo -n "." - - sleep 1 - - count=$(ip netns exec $ns2 conntrack -L -p tcp --reply-port-src 8080 2>/dev/null | wc -l) - if [ $count -gt 0 ]; then - echo - echo "PASS: redirection took effect after $i seconds" - break - fi - - m=$((i%20)) - if [ $m -eq 0 ]; then - echo " waited for $i seconds" - fi -done - -expect="packets 1 bytes 60" -check_counter "$ns2" "redir" "$expect" -if [ $? -ne 0 ]; then - ret=1 -fi - -if [ $ret -eq 0 ];then - echo "PASS: redirection counter has expected values" -else - echo "ERROR: no tcp connection was redirected" -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/conntrack_vrf.sh b/tools/testing/selftests/netfilter/conntrack_vrf.sh deleted file mode 100755 index 8b5ea9234588..000000000000 --- a/tools/testing/selftests/netfilter/conntrack_vrf.sh +++ /dev/null @@ -1,241 +0,0 @@ -#!/bin/sh - -# This script demonstrates interaction of conntrack and vrf. -# The vrf driver calls the netfilter hooks again, with oif/iif -# pointing at the VRF device. -# -# For ingress, this means first iteration has iifname of lower/real -# device. In this script, thats veth0. -# Second iteration is iifname set to vrf device, tvrf in this script. -# -# For egress, this is reversed: first iteration has the vrf device, -# second iteration is done with the lower/real/veth0 device. -# -# test_ct_zone_in demonstrates unexpected change of nftables -# behavior # caused by commit 09e856d54bda5f28 "vrf: Reset skb conntrack -# connection on VRF rcv" -# -# It was possible to assign conntrack zone to a packet (or mark it for -# `notracking`) in the prerouting chain before conntrack, based on real iif. -# -# After the change, the zone assignment is lost and the zone is assigned based -# on the VRF master interface (in case such a rule exists). -# assignment is lost. Instead, assignment based on the `iif` matching -# Thus it is impossible to distinguish packets based on the original -# interface. -# -# test_masquerade_vrf and test_masquerade_veth0 demonstrate the problem -# that was supposed to be fixed by the commit mentioned above to make sure -# that any fix to test case 1 won't break masquerade again. - -ksft_skip=4 - -IP0=172.30.30.1 -IP1=172.30.30.2 -PFXL=30 -ret=0 - -sfx=$(mktemp -u "XXXXXXXX") -ns0="ns0-$sfx" -ns1="ns1-$sfx" - -cleanup() -{ - ip netns pids $ns0 | xargs kill 2>/dev/null - ip netns pids $ns1 | xargs kill 2>/dev/null - - ip netns del $ns0 $ns1 -} - -nft --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -ip netns add "$ns0" -if [ $? -ne 0 ];then - echo "SKIP: Could not create net namespace $ns0" - exit $ksft_skip -fi -ip netns add "$ns1" - -trap cleanup EXIT - -ip netns exec $ns0 sysctl -q -w net.ipv4.conf.default.rp_filter=0 -ip netns exec $ns0 sysctl -q -w net.ipv4.conf.all.rp_filter=0 -ip netns exec $ns0 sysctl -q -w net.ipv4.conf.all.rp_filter=0 - -ip link add veth0 netns "$ns0" type veth peer name veth0 netns "$ns1" > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not add veth device" - exit $ksft_skip -fi - -ip -net $ns0 li add tvrf type vrf table 9876 -if [ $? -ne 0 ];then - echo "SKIP: Could not add vrf device" - exit $ksft_skip -fi - -ip -net $ns0 li set lo up - -ip -net $ns0 li set veth0 master tvrf -ip -net $ns0 li set tvrf up -ip -net $ns0 li set veth0 up -ip -net $ns1 li set veth0 up - -ip -net $ns0 addr add $IP0/$PFXL dev veth0 -ip -net $ns1 addr add $IP1/$PFXL dev veth0 - -ip netns exec $ns1 iperf3 -s > /dev/null 2>&1& -if [ $? -ne 0 ];then - echo "SKIP: Could not start iperf3" - exit $ksft_skip -fi - -# test vrf ingress handling. -# The incoming connection should be placed in conntrack zone 1, -# as decided by the first iteration of the ruleset. -test_ct_zone_in() -{ -ip netns exec $ns0 nft -f - <<EOF -table testct { - chain rawpre { - type filter hook prerouting priority raw; - - iif { veth0, tvrf } counter meta nftrace set 1 - iif veth0 counter ct zone set 1 counter return - iif tvrf counter ct zone set 2 counter return - ip protocol icmp counter - notrack counter - } - - chain rawout { - type filter hook output priority raw; - - oif veth0 counter ct zone set 1 counter return - oif tvrf counter ct zone set 2 counter return - notrack counter - } -} -EOF - ip netns exec $ns1 ping -W 1 -c 1 -I veth0 $IP0 > /dev/null - - # should be in zone 1, not zone 2 - count=$(ip netns exec $ns0 conntrack -L -s $IP1 -d $IP0 -p icmp --zone 1 2>/dev/null | wc -l) - if [ $count -eq 1 ]; then - echo "PASS: entry found in conntrack zone 1" - else - echo "FAIL: entry not found in conntrack zone 1" - count=$(ip netns exec $ns0 conntrack -L -s $IP1 -d $IP0 -p icmp --zone 2 2> /dev/null | wc -l) - if [ $count -eq 1 ]; then - echo "FAIL: entry found in zone 2 instead" - else - echo "FAIL: entry not in zone 1 or 2, dumping table" - ip netns exec $ns0 conntrack -L - ip netns exec $ns0 nft list ruleset - fi - fi -} - -# add masq rule that gets evaluated w. outif set to vrf device. -# This tests the first iteration of the packet through conntrack, -# oifname is the vrf device. -test_masquerade_vrf() -{ - local qdisc=$1 - - if [ "$qdisc" != "default" ]; then - tc -net $ns0 qdisc add dev tvrf root $qdisc - fi - - ip netns exec $ns0 conntrack -F 2>/dev/null - -ip netns exec $ns0 nft -f - <<EOF -flush ruleset -table ip nat { - chain rawout { - type filter hook output priority raw; - - oif tvrf ct state untracked counter - } - chain postrouting2 { - type filter hook postrouting priority mangle; - - oif tvrf ct state untracked counter - } - chain postrouting { - type nat hook postrouting priority 0; - # NB: masquerade should always be combined with 'oif(name) bla', - # lack of this is intentional here, we want to exercise double-snat. - ip saddr 172.30.30.0/30 counter masquerade random - } -} -EOF - ip netns exec $ns0 ip vrf exec tvrf iperf3 -t 1 -c $IP1 >/dev/null - if [ $? -ne 0 ]; then - echo "FAIL: iperf3 connect failure with masquerade + sport rewrite on vrf device" - ret=1 - return - fi - - # must also check that nat table was evaluated on second (lower device) iteration. - ip netns exec $ns0 nft list table ip nat |grep -q 'counter packets 2' && - ip netns exec $ns0 nft list table ip nat |grep -q 'untracked counter packets [1-9]' - if [ $? -eq 0 ]; then - echo "PASS: iperf3 connect with masquerade + sport rewrite on vrf device ($qdisc qdisc)" - else - echo "FAIL: vrf rules have unexpected counter value" - ret=1 - fi - - if [ "$qdisc" != "default" ]; then - tc -net $ns0 qdisc del dev tvrf root - fi -} - -# add masq rule that gets evaluated w. outif set to veth device. -# This tests the 2nd iteration of the packet through conntrack, -# oifname is the lower device (veth0 in this case). -test_masquerade_veth() -{ - ip netns exec $ns0 conntrack -F 2>/dev/null -ip netns exec $ns0 nft -f - <<EOF -flush ruleset -table ip nat { - chain postrouting { - type nat hook postrouting priority 0; - meta oif veth0 ip saddr 172.30.30.0/30 counter masquerade random - } -} -EOF - ip netns exec $ns0 ip vrf exec tvrf iperf3 -t 1 -c $IP1 > /dev/null - if [ $? -ne 0 ]; then - echo "FAIL: iperf3 connect failure with masquerade + sport rewrite on veth device" - ret=1 - return - fi - - # must also check that nat table was evaluated on second (lower device) iteration. - ip netns exec $ns0 nft list table ip nat |grep -q 'counter packets 2' - if [ $? -eq 0 ]; then - echo "PASS: iperf3 connect with masquerade + sport rewrite on veth device" - else - echo "FAIL: vrf masq rule has unexpected counter value" - ret=1 - fi -} - -test_ct_zone_in -test_masquerade_vrf "default" -test_masquerade_vrf "pfifo" -test_masquerade_veth - -exit $ret diff --git a/tools/testing/selftests/netfilter/ipip-conntrack-mtu.sh b/tools/testing/selftests/netfilter/ipip-conntrack-mtu.sh deleted file mode 100755 index eb9553e4986b..000000000000 --- a/tools/testing/selftests/netfilter/ipip-conntrack-mtu.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 - -# Conntrack needs to reassemble fragments in order to have complete -# packets for rule matching. Reassembly can lead to packet loss. - -# Consider the following setup: -# +--------+ +---------+ +--------+ -# |Router A|-------|Wanrouter|-------|Router B| -# | |.IPIP..| |..IPIP.| | -# +--------+ +---------+ +--------+ -# / mtu 1400 \ -# / \ -#+--------+ +--------+ -#|Client A| |Client B| -#| | | | -#+--------+ +--------+ - -# Router A and Router B use IPIP tunnel interfaces to tunnel traffic -# between Client A and Client B over WAN. Wanrouter has MTU 1400 set -# on its interfaces. - -rnd=$(mktemp -u XXXXXXXX) -rx=$(mktemp) - -r_a="ns-ra-$rnd" -r_b="ns-rb-$rnd" -r_w="ns-rw-$rnd" -c_a="ns-ca-$rnd" -c_b="ns-cb-$rnd" - -checktool (){ - if ! $1 > /dev/null 2>&1; then - echo "SKIP: Could not $2" - exit $ksft_skip - fi -} - -checktool "iptables --version" "run test without iptables" -checktool "ip -Version" "run test without ip tool" -checktool "which socat" "run test without socat" -checktool "ip netns add ${r_a}" "create net namespace" - -for n in ${r_b} ${r_w} ${c_a} ${c_b};do - ip netns add ${n} -done - -cleanup() { - for n in ${r_a} ${r_b} ${r_w} ${c_a} ${c_b};do - ip netns del ${n} - done - rm -f ${rx} -} - -trap cleanup EXIT - -test_path() { - msg="$1" - - ip netns exec ${c_b} socat -t 3 - udp4-listen:5000,reuseaddr > ${rx} < /dev/null & - - sleep 1 - for i in 1 2 3; do - head -c1400 /dev/zero | tr "\000" "a" | \ - ip netns exec ${c_a} socat -t 1 -u STDIN UDP:192.168.20.2:5000 - done - - wait - - bytes=$(wc -c < ${rx}) - - if [ $bytes -eq 1400 ];then - echo "OK: PMTU $msg connection tracking" - else - echo "FAIL: PMTU $msg connection tracking: got $bytes, expected 1400" - exit 1 - fi -} - -# Detailed setup for Router A -# --------------------------- -# Interfaces: -# eth0: 10.2.2.1/24 -# eth1: 192.168.10.1/24 -# ipip0: No IP address, local 10.2.2.1 remote 10.4.4.1 -# Routes: -# 192.168.20.0/24 dev ipip0 (192.168.20.0/24 is subnet of Client B) -# 10.4.4.1 via 10.2.2.254 (Router B via Wanrouter) -# No iptables rules at all. - -ip link add veth0 netns ${r_a} type veth peer name veth0 netns ${r_w} -ip link add veth1 netns ${r_a} type veth peer name veth0 netns ${c_a} - -l_addr="10.2.2.1" -r_addr="10.4.4.1" -ip netns exec ${r_a} ip link add ipip0 type ipip local ${l_addr} remote ${r_addr} mode ipip || exit $ksft_skip - -for dev in lo veth0 veth1 ipip0; do - ip -net ${r_a} link set $dev up -done - -ip -net ${r_a} addr add 10.2.2.1/24 dev veth0 -ip -net ${r_a} addr add 192.168.10.1/24 dev veth1 - -ip -net ${r_a} route add 192.168.20.0/24 dev ipip0 -ip -net ${r_a} route add 10.4.4.0/24 via 10.2.2.254 - -ip netns exec ${r_a} sysctl -q net.ipv4.conf.all.forwarding=1 > /dev/null - -# Detailed setup for Router B -# --------------------------- -# Interfaces: -# eth0: 10.4.4.1/24 -# eth1: 192.168.20.1/24 -# ipip0: No IP address, local 10.4.4.1 remote 10.2.2.1 -# Routes: -# 192.168.10.0/24 dev ipip0 (192.168.10.0/24 is subnet of Client A) -# 10.2.2.1 via 10.4.4.254 (Router A via Wanrouter) -# No iptables rules at all. - -ip link add veth0 netns ${r_b} type veth peer name veth1 netns ${r_w} -ip link add veth1 netns ${r_b} type veth peer name veth0 netns ${c_b} - -l_addr="10.4.4.1" -r_addr="10.2.2.1" - -ip netns exec ${r_b} ip link add ipip0 type ipip local ${l_addr} remote ${r_addr} mode ipip || exit $ksft_skip - -for dev in lo veth0 veth1 ipip0; do - ip -net ${r_b} link set $dev up -done - -ip -net ${r_b} addr add 10.4.4.1/24 dev veth0 -ip -net ${r_b} addr add 192.168.20.1/24 dev veth1 - -ip -net ${r_b} route add 192.168.10.0/24 dev ipip0 -ip -net ${r_b} route add 10.2.2.0/24 via 10.4.4.254 -ip netns exec ${r_b} sysctl -q net.ipv4.conf.all.forwarding=1 > /dev/null - -# Client A -ip -net ${c_a} addr add 192.168.10.2/24 dev veth0 -ip -net ${c_a} link set dev lo up -ip -net ${c_a} link set dev veth0 up -ip -net ${c_a} route add default via 192.168.10.1 - -# Client A -ip -net ${c_b} addr add 192.168.20.2/24 dev veth0 -ip -net ${c_b} link set dev veth0 up -ip -net ${c_b} link set dev lo up -ip -net ${c_b} route add default via 192.168.20.1 - -# Wan -ip -net ${r_w} addr add 10.2.2.254/24 dev veth0 -ip -net ${r_w} addr add 10.4.4.254/24 dev veth1 - -ip -net ${r_w} link set dev lo up -ip -net ${r_w} link set dev veth0 up mtu 1400 -ip -net ${r_w} link set dev veth1 up mtu 1400 - -ip -net ${r_a} link set dev veth0 mtu 1400 -ip -net ${r_b} link set dev veth0 mtu 1400 - -ip netns exec ${r_w} sysctl -q net.ipv4.conf.all.forwarding=1 > /dev/null - -# Path MTU discovery -# ------------------ -# Running tracepath from Client A to Client B shows PMTU discovery is working -# as expected: -# -# clienta:~# tracepath 192.168.20.2 -# 1?: [LOCALHOST] pmtu 1500 -# 1: 192.168.10.1 0.867ms -# 1: 192.168.10.1 0.302ms -# 2: 192.168.10.1 0.312ms pmtu 1480 -# 2: no reply -# 3: 192.168.10.1 0.510ms pmtu 1380 -# 3: 192.168.20.2 2.320ms reached -# Resume: pmtu 1380 hops 3 back 3 - -# ip netns exec ${c_a} traceroute --mtu 192.168.20.2 - -# Router A has learned PMTU (1400) to Router B from Wanrouter. -# Client A has learned PMTU (1400 - IPIP overhead = 1380) to Client B -# from Router A. - -#Send large UDP packet -#--------------------- -#Now we send a 1400 bytes UDP packet from Client A to Client B: - -# clienta:~# head -c1400 /dev/zero | tr "\000" "a" | socat -u STDIN UDP:192.168.20.2:5000 -test_path "without" - -# The IPv4 stack on Client A already knows the PMTU to Client B, so the -# UDP packet is sent as two fragments (1380 + 20). Router A forwards the -# fragments between eth1 and ipip0. The fragments fit into the tunnel and -# reach their destination. - -#When sending the large UDP packet again, Router A now reassembles the -#fragments before routing the packet over ipip0. The resulting IPIP -#packet is too big (1400) for the tunnel PMTU (1380) to Router B, it is -#dropped on Router A before sending. - -ip netns exec ${r_a} iptables -A FORWARD -m conntrack --ctstate NEW -test_path "with" diff --git a/tools/testing/selftests/netfilter/ipvs.sh b/tools/testing/selftests/netfilter/ipvs.sh deleted file mode 100755 index c3b8f90c497e..000000000000 --- a/tools/testing/selftests/netfilter/ipvs.sh +++ /dev/null @@ -1,228 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# -# End-to-end ipvs test suite -# Topology: -#--------------------------------------------------------------+ -# | | -# ns0 | ns1 | -# ----------- | ----------- ----------- | -# | veth01 | --------- | veth10 | | veth12 | | -# ----------- peer ----------- ----------- | -# | | | | -# ----------- | | | -# | br0 | |----------------- peer |--------------| -# ----------- | | | -# | | | | -# ---------- peer ---------- ----------- | -# | veth02 | --------- | veth20 | | veth21 | | -# ---------- | ---------- ----------- | -# | ns2 | -# | | -#--------------------------------------------------------------+ -# -# We assume that all network driver are loaded -# - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 -GREEN='\033[0;92m' -RED='\033[0;31m' -NC='\033[0m' # No Color - -readonly port=8080 - -readonly vip_v4=207.175.44.110 -readonly cip_v4=10.0.0.2 -readonly gip_v4=10.0.0.1 -readonly dip_v4=172.16.0.1 -readonly rip_v4=172.16.0.2 -readonly sip_v4=10.0.0.3 - -readonly infile="$(mktemp)" -readonly outfile="$(mktemp)" -readonly datalen=32 - -sysipvsnet="/proc/sys/net/ipv4/vs/" -if [ ! -d $sysipvsnet ]; then - modprobe -q ip_vs - if [ $? -ne 0 ]; then - echo "skip: could not run test without ipvs module" - exit $ksft_skip - fi -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ]; then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -ipvsadm -v > /dev/null 2>&1 -if [ $? -ne 0 ]; then - echo "SKIP: Could not run test without ipvsadm" - exit $ksft_skip -fi - -setup() { - ip netns add ns0 - ip netns add ns1 - ip netns add ns2 - - ip link add veth01 netns ns0 type veth peer name veth10 netns ns1 - ip link add veth02 netns ns0 type veth peer name veth20 netns ns2 - ip link add veth12 netns ns1 type veth peer name veth21 netns ns2 - - ip netns exec ns0 ip link set veth01 up - ip netns exec ns0 ip link set veth02 up - ip netns exec ns0 ip link add br0 type bridge - ip netns exec ns0 ip link set veth01 master br0 - ip netns exec ns0 ip link set veth02 master br0 - ip netns exec ns0 ip link set br0 up - ip netns exec ns0 ip addr add ${cip_v4}/24 dev br0 - - ip netns exec ns1 ip link set lo up - ip netns exec ns1 ip link set veth10 up - ip netns exec ns1 ip addr add ${gip_v4}/24 dev veth10 - ip netns exec ns1 ip link set veth12 up - ip netns exec ns1 ip addr add ${dip_v4}/24 dev veth12 - - ip netns exec ns2 ip link set lo up - ip netns exec ns2 ip link set veth21 up - ip netns exec ns2 ip addr add ${rip_v4}/24 dev veth21 - ip netns exec ns2 ip link set veth20 up - ip netns exec ns2 ip addr add ${sip_v4}/24 dev veth20 - - sleep 1 - - dd if=/dev/urandom of="${infile}" bs="${datalen}" count=1 status=none -} - -cleanup() { - for i in 0 1 2 - do - ip netns del ns$i > /dev/null 2>&1 - done - - if [ -f "${outfile}" ]; then - rm "${outfile}" - fi - if [ -f "${infile}" ]; then - rm "${infile}" - fi -} - -server_listen() { - ip netns exec ns2 nc -l -p 8080 > "${outfile}" & - server_pid=$! - sleep 0.2 -} - -client_connect() { - ip netns exec ns0 timeout 2 nc -w 1 ${vip_v4} ${port} < "${infile}" -} - -verify_data() { - wait "${server_pid}" - cmp "$infile" "$outfile" 2>/dev/null -} - -test_service() { - server_listen - client_connect - verify_data -} - - -test_dr() { - ip netns exec ns0 ip route add ${vip_v4} via ${gip_v4} dev br0 - - ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1 - ip netns exec ns1 ipvsadm -A -t ${vip_v4}:${port} -s rr - ip netns exec ns1 ipvsadm -a -t ${vip_v4}:${port} -r ${rip_v4}:${port} - ip netns exec ns1 ip addr add ${vip_v4}/32 dev lo:1 - - # avoid incorrect arp response - ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_ignore=1 - ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_announce=2 - # avoid reverse route lookup - ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=0 - ip netns exec ns2 sysctl -qw net.ipv4.conf.veth21.rp_filter=0 - ip netns exec ns2 ip addr add ${vip_v4}/32 dev lo:1 - - test_service -} - -test_nat() { - ip netns exec ns0 ip route add ${vip_v4} via ${gip_v4} dev br0 - - ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1 - ip netns exec ns1 ipvsadm -A -t ${vip_v4}:${port} -s rr - ip netns exec ns1 ipvsadm -a -m -t ${vip_v4}:${port} -r ${rip_v4}:${port} - ip netns exec ns1 ip addr add ${vip_v4}/32 dev lo:1 - - ip netns exec ns2 ip link del veth20 - ip netns exec ns2 ip route add default via ${dip_v4} dev veth21 - - test_service -} - -test_tun() { - ip netns exec ns0 ip route add ${vip_v4} via ${gip_v4} dev br0 - - ip netns exec ns1 modprobe ipip - ip netns exec ns1 ip link set tunl0 up - ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=0 - ip netns exec ns1 sysctl -qw net.ipv4.conf.all.send_redirects=0 - ip netns exec ns1 sysctl -qw net.ipv4.conf.default.send_redirects=0 - ip netns exec ns1 ipvsadm -A -t ${vip_v4}:${port} -s rr - ip netns exec ns1 ipvsadm -a -i -t ${vip_v4}:${port} -r ${rip_v4}:${port} - ip netns exec ns1 ip addr add ${vip_v4}/32 dev lo:1 - - ip netns exec ns2 modprobe ipip - ip netns exec ns2 ip link set tunl0 up - ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_ignore=1 - ip netns exec ns2 sysctl -qw net.ipv4.conf.all.arp_announce=2 - ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=0 - ip netns exec ns2 sysctl -qw net.ipv4.conf.tunl0.rp_filter=0 - ip netns exec ns2 sysctl -qw net.ipv4.conf.veth21.rp_filter=0 - ip netns exec ns2 ip addr add ${vip_v4}/32 dev lo:1 - - test_service -} - -run_tests() { - local errors= - - echo "Testing DR mode..." - cleanup - setup - test_dr - errors=$(( $errors + $? )) - - echo "Testing NAT mode..." - cleanup - setup - test_nat - errors=$(( $errors + $? )) - - echo "Testing Tunnel mode..." - cleanup - setup - test_tun - errors=$(( $errors + $? )) - - return $errors -} - -trap cleanup EXIT - -run_tests - -if [ $? -ne 0 ]; then - echo -e "$(basename $0): ${RED}FAIL${NC}" - exit 1 -fi -echo -e "$(basename $0): ${GREEN}PASS${NC}" -exit 0 diff --git a/tools/testing/selftests/netfilter/nf-queue.c b/tools/testing/selftests/netfilter/nf-queue.c deleted file mode 100644 index 9e56b9d47037..000000000000 --- a/tools/testing/selftests/netfilter/nf-queue.c +++ /dev/null @@ -1,395 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <time.h> -#include <arpa/inet.h> - -#include <libmnl/libmnl.h> -#include <linux/netfilter.h> -#include <linux/netfilter/nfnetlink.h> -#include <linux/netfilter/nfnetlink_queue.h> - -struct options { - bool count_packets; - bool gso_enabled; - int verbose; - unsigned int queue_num; - unsigned int timeout; - uint32_t verdict; - uint32_t delay_ms; -}; - -static unsigned int queue_stats[5]; -static struct options opts; - -static void help(const char *p) -{ - printf("Usage: %s [-c|-v [-vv] ] [-t timeout] [-q queue_num] [-Qdst_queue ] [ -d ms_delay ] [-G]\n", p); -} - -static int parse_attr_cb(const struct nlattr *attr, void *data) -{ - const struct nlattr **tb = data; - int type = mnl_attr_get_type(attr); - - /* skip unsupported attribute in user-space */ - if (mnl_attr_type_valid(attr, NFQA_MAX) < 0) - return MNL_CB_OK; - - switch (type) { - case NFQA_MARK: - case NFQA_IFINDEX_INDEV: - case NFQA_IFINDEX_OUTDEV: - case NFQA_IFINDEX_PHYSINDEV: - case NFQA_IFINDEX_PHYSOUTDEV: - if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { - perror("mnl_attr_validate"); - return MNL_CB_ERROR; - } - break; - case NFQA_TIMESTAMP: - if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, - sizeof(struct nfqnl_msg_packet_timestamp)) < 0) { - perror("mnl_attr_validate2"); - return MNL_CB_ERROR; - } - break; - case NFQA_HWADDR: - if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, - sizeof(struct nfqnl_msg_packet_hw)) < 0) { - perror("mnl_attr_validate2"); - return MNL_CB_ERROR; - } - break; - case NFQA_PAYLOAD: - break; - } - tb[type] = attr; - return MNL_CB_OK; -} - -static int queue_cb(const struct nlmsghdr *nlh, void *data) -{ - struct nlattr *tb[NFQA_MAX+1] = { 0 }; - struct nfqnl_msg_packet_hdr *ph = NULL; - uint32_t id = 0; - - (void)data; - - mnl_attr_parse(nlh, sizeof(struct nfgenmsg), parse_attr_cb, tb); - if (tb[NFQA_PACKET_HDR]) { - ph = mnl_attr_get_payload(tb[NFQA_PACKET_HDR]); - id = ntohl(ph->packet_id); - - if (opts.verbose > 0) - printf("packet hook=%u, hwproto 0x%x", - ntohs(ph->hw_protocol), ph->hook); - - if (ph->hook >= 5) { - fprintf(stderr, "Unknown hook %d\n", ph->hook); - return MNL_CB_ERROR; - } - - if (opts.verbose > 0) { - uint32_t skbinfo = 0; - - if (tb[NFQA_SKB_INFO]) - skbinfo = ntohl(mnl_attr_get_u32(tb[NFQA_SKB_INFO])); - if (skbinfo & NFQA_SKB_CSUMNOTREADY) - printf(" csumnotready"); - if (skbinfo & NFQA_SKB_GSO) - printf(" gso"); - if (skbinfo & NFQA_SKB_CSUM_NOTVERIFIED) - printf(" csumnotverified"); - puts(""); - } - - if (opts.count_packets) - queue_stats[ph->hook]++; - } - - return MNL_CB_OK + id; -} - -static struct nlmsghdr * -nfq_build_cfg_request(char *buf, uint8_t command, int queue_num) -{ - struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); - struct nfqnl_msg_config_cmd cmd = { - .command = command, - .pf = htons(AF_INET), - }; - struct nfgenmsg *nfg; - - nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG; - nlh->nlmsg_flags = NLM_F_REQUEST; - - nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); - - nfg->nfgen_family = AF_UNSPEC; - nfg->version = NFNETLINK_V0; - nfg->res_id = htons(queue_num); - - mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(cmd), &cmd); - - return nlh; -} - -static struct nlmsghdr * -nfq_build_cfg_params(char *buf, uint8_t mode, int range, int queue_num) -{ - struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); - struct nfqnl_msg_config_params params = { - .copy_range = htonl(range), - .copy_mode = mode, - }; - struct nfgenmsg *nfg; - - nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG; - nlh->nlmsg_flags = NLM_F_REQUEST; - - nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); - nfg->nfgen_family = AF_UNSPEC; - nfg->version = NFNETLINK_V0; - nfg->res_id = htons(queue_num); - - mnl_attr_put(nlh, NFQA_CFG_PARAMS, sizeof(params), ¶ms); - - return nlh; -} - -static struct nlmsghdr * -nfq_build_verdict(char *buf, int id, int queue_num, uint32_t verd) -{ - struct nfqnl_msg_verdict_hdr vh = { - .verdict = htonl(verd), - .id = htonl(id), - }; - struct nlmsghdr *nlh; - struct nfgenmsg *nfg; - - nlh = mnl_nlmsg_put_header(buf); - nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_VERDICT; - nlh->nlmsg_flags = NLM_F_REQUEST; - nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); - nfg->nfgen_family = AF_UNSPEC; - nfg->version = NFNETLINK_V0; - nfg->res_id = htons(queue_num); - - mnl_attr_put(nlh, NFQA_VERDICT_HDR, sizeof(vh), &vh); - - return nlh; -} - -static void print_stats(void) -{ - unsigned int last, total; - int i; - - total = 0; - last = queue_stats[0]; - - for (i = 0; i < 5; i++) { - printf("hook %d packets %08u\n", i, queue_stats[i]); - last = queue_stats[i]; - total += last; - } - - printf("%u packets total\n", total); -} - -struct mnl_socket *open_queue(void) -{ - char buf[MNL_SOCKET_BUFFER_SIZE]; - unsigned int queue_num; - struct mnl_socket *nl; - struct nlmsghdr *nlh; - struct timeval tv; - uint32_t flags; - - nl = mnl_socket_open(NETLINK_NETFILTER); - if (nl == NULL) { - perror("mnl_socket_open"); - exit(EXIT_FAILURE); - } - - if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { - perror("mnl_socket_bind"); - exit(EXIT_FAILURE); - } - - queue_num = opts.queue_num; - nlh = nfq_build_cfg_request(buf, NFQNL_CFG_CMD_BIND, queue_num); - - if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { - perror("mnl_socket_sendto"); - exit(EXIT_FAILURE); - } - - nlh = nfq_build_cfg_params(buf, NFQNL_COPY_PACKET, 0xFFFF, queue_num); - - flags = opts.gso_enabled ? NFQA_CFG_F_GSO : 0; - flags |= NFQA_CFG_F_UID_GID; - mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(flags)); - mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(flags)); - - if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { - perror("mnl_socket_sendto"); - exit(EXIT_FAILURE); - } - - memset(&tv, 0, sizeof(tv)); - tv.tv_sec = opts.timeout; - if (opts.timeout && setsockopt(mnl_socket_get_fd(nl), - SOL_SOCKET, SO_RCVTIMEO, - &tv, sizeof(tv))) { - perror("setsockopt(SO_RCVTIMEO)"); - exit(EXIT_FAILURE); - } - - return nl; -} - -static void sleep_ms(uint32_t delay) -{ - struct timespec ts = { .tv_sec = delay / 1000 }; - - delay %= 1000; - - ts.tv_nsec = delay * 1000llu * 1000llu; - - nanosleep(&ts, NULL); -} - -static int mainloop(void) -{ - unsigned int buflen = 64 * 1024 + MNL_SOCKET_BUFFER_SIZE; - struct mnl_socket *nl; - struct nlmsghdr *nlh; - unsigned int portid; - char *buf; - int ret; - - buf = malloc(buflen); - if (!buf) { - perror("malloc"); - exit(EXIT_FAILURE); - } - - nl = open_queue(); - portid = mnl_socket_get_portid(nl); - - for (;;) { - uint32_t id; - - ret = mnl_socket_recvfrom(nl, buf, buflen); - if (ret == -1) { - if (errno == ENOBUFS || errno == EINTR) - continue; - - if (errno == EAGAIN) { - errno = 0; - ret = 0; - break; - } - - perror("mnl_socket_recvfrom"); - exit(EXIT_FAILURE); - } - - ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL); - if (ret < 0) { - perror("mnl_cb_run"); - exit(EXIT_FAILURE); - } - - id = ret - MNL_CB_OK; - if (opts.delay_ms) - sleep_ms(opts.delay_ms); - - nlh = nfq_build_verdict(buf, id, opts.queue_num, opts.verdict); - if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { - perror("mnl_socket_sendto"); - exit(EXIT_FAILURE); - } - } - - mnl_socket_close(nl); - - return ret; -} - -static void parse_opts(int argc, char **argv) -{ - int c; - - while ((c = getopt(argc, argv, "chvt:q:Q:d:G")) != -1) { - switch (c) { - case 'c': - opts.count_packets = true; - break; - case 'h': - help(argv[0]); - exit(0); - break; - case 'q': - opts.queue_num = atoi(optarg); - if (opts.queue_num > 0xffff) - opts.queue_num = 0; - break; - case 'Q': - opts.verdict = atoi(optarg); - if (opts.verdict > 0xffff) { - fprintf(stderr, "Expected destination queue number\n"); - exit(1); - } - - opts.verdict <<= 16; - opts.verdict |= NF_QUEUE; - break; - case 'd': - opts.delay_ms = atoi(optarg); - if (opts.delay_ms == 0) { - fprintf(stderr, "Expected nonzero delay (in milliseconds)\n"); - exit(1); - } - break; - case 't': - opts.timeout = atoi(optarg); - break; - case 'G': - opts.gso_enabled = false; - break; - case 'v': - opts.verbose++; - break; - } - } - - if (opts.verdict != NF_ACCEPT && (opts.verdict >> 16 == opts.queue_num)) { - fprintf(stderr, "Cannot use same destination and source queue\n"); - exit(1); - } -} - -int main(int argc, char *argv[]) -{ - int ret; - - opts.verdict = NF_ACCEPT; - opts.gso_enabled = true; - - parse_opts(argc, argv); - - ret = mainloop(); - if (opts.count_packets) - print_stats(); - - return ret; -} diff --git a/tools/testing/selftests/netfilter/nf_nat_edemux.sh b/tools/testing/selftests/netfilter/nf_nat_edemux.sh deleted file mode 100755 index a1aa8f4a5828..000000000000 --- a/tools/testing/selftests/netfilter/nf_nat_edemux.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 -# -# Test NAT source port clash resolution -# - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -sfx=$(mktemp -u "XXXXXXXX") -ns1="ns1-$sfx" -ns2="ns2-$sfx" -socatpid=0 - -cleanup() -{ - [ $socatpid -gt 0 ] && kill $socatpid - ip netns del $ns1 - ip netns del $ns2 -} - -socat -h > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without socat" - exit $ksft_skip -fi - -iptables --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without iptables" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -ip netns add "$ns1" -if [ $? -ne 0 ];then - echo "SKIP: Could not create net namespace $ns1" - exit $ksft_skip -fi - -trap cleanup EXIT - -ip netns add $ns2 - -# Connect the namespaces using a veth pair -ip link add name veth2 type veth peer name veth1 -ip link set netns $ns1 dev veth1 -ip link set netns $ns2 dev veth2 - -ip netns exec $ns1 ip link set up dev lo -ip netns exec $ns1 ip link set up dev veth1 -ip netns exec $ns1 ip addr add 192.168.1.1/24 dev veth1 - -ip netns exec $ns2 ip link set up dev lo -ip netns exec $ns2 ip link set up dev veth2 -ip netns exec $ns2 ip addr add 192.168.1.2/24 dev veth2 - -# Create a server in one namespace -ip netns exec $ns1 socat -u TCP-LISTEN:5201,fork OPEN:/dev/null,wronly=1 & -socatpid=$! - -# Restrict source port to just one so we don't have to exhaust -# all others. -ip netns exec $ns2 sysctl -q net.ipv4.ip_local_port_range="10000 10000" - -# add a virtual IP using DNAT -ip netns exec $ns2 iptables -t nat -A OUTPUT -d 10.96.0.1/32 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.1:5201 - -# ... and route it to the other namespace -ip netns exec $ns2 ip route add 10.96.0.1 via 192.168.1.1 - -sleep 1 - -# add a persistent connection from the other namespace -ip netns exec $ns2 socat -t 10 - TCP:192.168.1.1:5201 > /dev/null & - -sleep 1 - -# ip daddr:dport will be rewritten to 192.168.1.1 5201 -# NAT must reallocate source port 10000 because -# 192.168.1.2:10000 -> 192.168.1.1:5201 is already in use -echo test | ip netns exec $ns2 socat -t 3 -u STDIN TCP:10.96.0.1:443,connect-timeout=3 >/dev/null -ret=$? - -# Check socat can connect to 10.96.0.1:443 (aka 192.168.1.1:5201). -if [ $ret -eq 0 ]; then - echo "PASS: socat can connect via NAT'd address" -else - echo "FAIL: socat cannot connect via NAT'd address" -fi - -# check sport clashres. -ip netns exec $ns1 iptables -t nat -A PREROUTING -p tcp --dport 5202 -j REDIRECT --to-ports 5201 -ip netns exec $ns1 iptables -t nat -A PREROUTING -p tcp --dport 5203 -j REDIRECT --to-ports 5201 - -sleep 5 | ip netns exec $ns2 socat -t 5 -u STDIN TCP:192.168.1.1:5202,connect-timeout=5 >/dev/null & -cpid1=$! -sleep 1 - -# if connect succeeds, client closes instantly due to EOF on stdin. -# if connect hangs, it will time out after 5s. -echo | ip netns exec $ns2 socat -t 3 -u STDIN TCP:192.168.1.1:5203,connect-timeout=5 >/dev/null & -cpid2=$! - -time_then=$(date +%s) -wait $cpid2 -rv=$? -time_now=$(date +%s) - -# Check how much time has elapsed, expectation is for -# 'cpid2' to connect and then exit (and no connect delay). -delta=$((time_now - time_then)) - -if [ $delta -lt 2 -a $rv -eq 0 ]; then - echo "PASS: could connect to service via redirected ports" -else - echo "FAIL: socat cannot connect to service via redirect ($delta seconds elapsed, returned $rv)" - ret=1 -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh deleted file mode 100755 index 99ed5bd6e840..000000000000 --- a/tools/testing/selftests/netfilter/nft_audit.sh +++ /dev/null @@ -1,245 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 -# -# Check that audit logs generated for nft commands are as expected. - -SKIP_RC=4 -RC=0 - -nft --version >/dev/null 2>&1 || { - echo "SKIP: missing nft tool" - exit $SKIP_RC -} - -# Run everything in a separate network namespace -[ "${1}" != "run" ] && { unshare -n "${0}" run; exit $?; } - -# give other scripts a chance to finish - audit_logread sees all activity -sleep 1 - -logfile=$(mktemp) -rulefile=$(mktemp) -echo "logging into $logfile" -./audit_logread >"$logfile" & -logread_pid=$! -trap 'kill $logread_pid; rm -f $logfile $rulefile' EXIT -exec 3<"$logfile" - -do_test() { # (cmd, log) - echo -n "testing for cmd: $1 ... " - cat <&3 >/dev/null - $1 >/dev/null || exit 1 - sleep 0.1 - res=$(diff -a -u <(echo "$2") - <&3) - [ $? -eq 0 ] && { echo "OK"; return; } - echo "FAIL" - grep -v '^\(---\|+++\|@@\)' <<< "$res" - ((RC--)) -} - -nft flush ruleset - -# adding tables, chains and rules - -for table in t1 t2; do - do_test "nft add table $table" \ - "table=$table family=2 entries=1 op=nft_register_table" - - do_test "nft add chain $table c1" \ - "table=$table family=2 entries=1 op=nft_register_chain" - - do_test "nft add chain $table c2; add chain $table c3" \ - "table=$table family=2 entries=2 op=nft_register_chain" - - cmd="add rule $table c1 counter" - - do_test "nft $cmd" \ - "table=$table family=2 entries=1 op=nft_register_rule" - - do_test "nft $cmd; $cmd" \ - "table=$table family=2 entries=2 op=nft_register_rule" - - cmd="" - sep="" - for chain in c2 c3; do - for i in {1..3}; do - cmd+="$sep add rule $table $chain counter" - sep=";" - done - done - do_test "nft $cmd" \ - "table=$table family=2 entries=6 op=nft_register_rule" -done - -for ((i = 0; i < 500; i++)); do - echo "add rule t2 c3 counter accept comment \"rule $i\"" -done >$rulefile -do_test "nft -f $rulefile" \ -'table=t2 family=2 entries=500 op=nft_register_rule' - -# adding sets and elements - -settype='type inet_service; counter' -setelem='{ 22, 80, 443 }' -setblock="{ $settype; elements = $setelem; }" -do_test "nft add set t1 s $setblock" \ -"table=t1 family=2 entries=4 op=nft_register_set" - -do_test "nft add set t1 s2 $setblock; add set t1 s3 { $settype; }" \ -"table=t1 family=2 entries=5 op=nft_register_set" - -do_test "nft add element t1 s3 $setelem" \ -"table=t1 family=2 entries=3 op=nft_register_setelem" - -# adding counters - -do_test 'nft add counter t1 c1' \ -'table=t1 family=2 entries=1 op=nft_register_obj' - -do_test 'nft add counter t2 c1; add counter t2 c2' \ -'table=t2 family=2 entries=2 op=nft_register_obj' - -for ((i = 3; i <= 500; i++)); do - echo "add counter t2 c$i" -done >$rulefile -do_test "nft -f $rulefile" \ -'table=t2 family=2 entries=498 op=nft_register_obj' - -# adding/updating quotas - -do_test 'nft add quota t1 q1 { 10 bytes }' \ -'table=t1 family=2 entries=1 op=nft_register_obj' - -do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \ -'table=t2 family=2 entries=2 op=nft_register_obj' - -for ((i = 3; i <= 500; i++)); do - echo "add quota t2 q$i { 10 bytes }" -done >$rulefile -do_test "nft -f $rulefile" \ -'table=t2 family=2 entries=498 op=nft_register_obj' - -# changing the quota value triggers obj update path -do_test 'nft add quota t1 q1 { 20 bytes }' \ -'table=t1 family=2 entries=1 op=nft_register_obj' - -# resetting rules - -do_test 'nft reset rules t1 c2' \ -'table=t1 family=2 entries=3 op=nft_reset_rule' - -do_test 'nft reset rules table t1' \ -'table=t1 family=2 entries=3 op=nft_reset_rule -table=t1 family=2 entries=3 op=nft_reset_rule -table=t1 family=2 entries=3 op=nft_reset_rule' - -do_test 'nft reset rules t2 c3' \ -'table=t2 family=2 entries=189 op=nft_reset_rule -table=t2 family=2 entries=188 op=nft_reset_rule -table=t2 family=2 entries=126 op=nft_reset_rule' - -do_test 'nft reset rules t2' \ -'table=t2 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=186 op=nft_reset_rule -table=t2 family=2 entries=188 op=nft_reset_rule -table=t2 family=2 entries=129 op=nft_reset_rule' - -do_test 'nft reset rules' \ -'table=t1 family=2 entries=3 op=nft_reset_rule -table=t1 family=2 entries=3 op=nft_reset_rule -table=t1 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=180 op=nft_reset_rule -table=t2 family=2 entries=188 op=nft_reset_rule -table=t2 family=2 entries=135 op=nft_reset_rule' - -# resetting sets and elements - -elem=(22 ,80 ,443) -relem="" -for i in {1..3}; do - relem+="${elem[((i - 1))]}" - do_test "nft reset element t1 s { $relem }" \ - "table=t1 family=2 entries=$i op=nft_reset_setelem" -done - -do_test 'nft reset set t1 s' \ -'table=t1 family=2 entries=3 op=nft_reset_setelem' - -# resetting counters - -do_test 'nft reset counter t1 c1' \ -'table=t1 family=2 entries=1 op=nft_reset_obj' - -do_test 'nft reset counters t1' \ -'table=t1 family=2 entries=1 op=nft_reset_obj' - -do_test 'nft reset counters t2' \ -'table=t2 family=2 entries=342 op=nft_reset_obj -table=t2 family=2 entries=158 op=nft_reset_obj' - -do_test 'nft reset counters' \ -'table=t1 family=2 entries=1 op=nft_reset_obj -table=t2 family=2 entries=341 op=nft_reset_obj -table=t2 family=2 entries=159 op=nft_reset_obj' - -# resetting quotas - -do_test 'nft reset quota t1 q1' \ -'table=t1 family=2 entries=1 op=nft_reset_obj' - -do_test 'nft reset quotas t1' \ -'table=t1 family=2 entries=1 op=nft_reset_obj' - -do_test 'nft reset quotas t2' \ -'table=t2 family=2 entries=315 op=nft_reset_obj -table=t2 family=2 entries=185 op=nft_reset_obj' - -do_test 'nft reset quotas' \ -'table=t1 family=2 entries=1 op=nft_reset_obj -table=t2 family=2 entries=314 op=nft_reset_obj -table=t2 family=2 entries=186 op=nft_reset_obj' - -# deleting rules - -readarray -t handles < <(nft -a list chain t1 c1 | \ - sed -n 's/.*counter.* handle \(.*\)$/\1/p') - -do_test "nft delete rule t1 c1 handle ${handles[0]}" \ -'table=t1 family=2 entries=1 op=nft_unregister_rule' - -cmd='delete rule t1 c1 handle' -do_test "nft $cmd ${handles[1]}; $cmd ${handles[2]}" \ -'table=t1 family=2 entries=2 op=nft_unregister_rule' - -do_test 'nft flush chain t1 c2' \ -'table=t1 family=2 entries=3 op=nft_unregister_rule' - -do_test 'nft flush table t2' \ -'table=t2 family=2 entries=509 op=nft_unregister_rule' - -# deleting chains - -do_test 'nft delete chain t2 c2' \ -'table=t2 family=2 entries=1 op=nft_unregister_chain' - -# deleting sets and elements - -do_test 'nft delete element t1 s { 22 }' \ -'table=t1 family=2 entries=1 op=nft_unregister_setelem' - -do_test 'nft delete element t1 s { 80, 443 }' \ -'table=t1 family=2 entries=2 op=nft_unregister_setelem' - -do_test 'nft flush set t1 s2' \ -'table=t1 family=2 entries=3 op=nft_unregister_setelem' - -do_test 'nft delete set t1 s2' \ -'table=t1 family=2 entries=1 op=nft_unregister_set' - -do_test 'nft delete set t1 s3' \ -'table=t1 family=2 entries=1 op=nft_unregister_set' - -exit $RC diff --git a/tools/testing/selftests/netfilter/nft_concat_range.sh b/tools/testing/selftests/netfilter/nft_concat_range.sh deleted file mode 100755 index e908009576c7..000000000000 --- a/tools/testing/selftests/netfilter/nft_concat_range.sh +++ /dev/null @@ -1,1645 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# -# nft_concat_range.sh - Tests for sets with concatenation of ranged fields -# -# Copyright (c) 2019 Red Hat GmbH -# -# Author: Stefano Brivio <sbrivio@redhat.com> -# -# shellcheck disable=SC2154,SC2034,SC2016,SC2030,SC2031 -# ^ Configuration and templates sourced with eval, counters reused in subshells - -KSELFTEST_SKIP=4 - -# Available test groups: -# - reported_issues: check for issues that were reported in the past -# - correctness: check that packets match given entries, and only those -# - concurrency: attempt races between insertion, deletion and lookup -# - timeout: check that packets match entries until they expire -# - performance: estimate matching rate, compare with rbtree and hash baselines -TESTS="reported_issues correctness concurrency timeout" -[ "${quicktest}" != "1" ] && TESTS="${TESTS} performance" - -# Set types, defined by TYPE_ variables below -TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto - net_port_net net_mac mac_net net_mac_icmp net6_mac_icmp - net6_port_net6_port net_port_mac_proto_net" - -# Reported bugs, also described by TYPE_ variables below -BUGS="flush_remove_add reload" - -# List of possible paths to pktgen script from kernel tree for performance tests -PKTGEN_SCRIPT_PATHS=" - ../../../../samples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh - pktgen/pktgen_bench_xmit_mode_netif_receive.sh" - -# Definition of set types: -# display display text for test report -# type_spec nftables set type specifier -# chain_spec nftables type specifier for rules mapping to set -# dst call sequence of format_*() functions for destination fields -# src call sequence of format_*() functions for source fields -# start initial integer used to generate addresses and ports -# count count of entries to generate and match -# src_delta number summed to destination generator for source fields -# tools list of tools for correctness and timeout tests, any can be used -# proto L4 protocol of test packets -# -# race_repeat race attempts per thread, 0 disables concurrency test for type -# flood_tools list of tools for concurrency tests, any can be used -# flood_proto L4 protocol of test packets for concurrency tests -# flood_spec nftables type specifier for concurrency tests -# -# perf_duration duration of single pktgen injection test -# perf_spec nftables type specifier for performance tests -# perf_dst format_*() functions for destination fields in performance test -# perf_src format_*() functions for source fields in performance test -# perf_entries number of set entries for performance test -# perf_proto L3 protocol of test packets -TYPE_net_port=" -display net,port -type_spec ipv4_addr . inet_service -chain_spec ip daddr . udp dport -dst addr4 port -src -start 1 -count 5 -src_delta 2000 -tools sendip nc bash -proto udp - -race_repeat 3 -flood_tools iperf3 iperf netperf -flood_proto udp -flood_spec ip daddr . udp dport - -perf_duration 5 -perf_spec ip daddr . udp dport -perf_dst addr4 port -perf_src -perf_entries 1000 -perf_proto ipv4 -" - -TYPE_port_net=" -display port,net -type_spec inet_service . ipv4_addr -chain_spec udp dport . ip daddr -dst port addr4 -src -start 1 -count 5 -src_delta 2000 -tools sendip socat nc bash -proto udp - -race_repeat 3 -flood_tools iperf3 iperf netperf -flood_proto udp -flood_spec udp dport . ip daddr - -perf_duration 5 -perf_spec udp dport . ip daddr -perf_dst port addr4 -perf_src -perf_entries 100 -perf_proto ipv4 -" - -TYPE_net6_port=" -display net6,port -type_spec ipv6_addr . inet_service -chain_spec ip6 daddr . udp dport -dst addr6 port -src -start 10 -count 5 -src_delta 2000 -tools sendip socat nc bash -proto udp6 - -race_repeat 3 -flood_tools iperf3 iperf netperf -flood_proto tcp6 -flood_spec ip6 daddr . udp dport - -perf_duration 5 -perf_spec ip6 daddr . udp dport -perf_dst addr6 port -perf_src -perf_entries 1000 -perf_proto ipv6 -" - -TYPE_port_proto=" -display port,proto -type_spec inet_service . inet_proto -chain_spec udp dport . meta l4proto -dst port proto -src -start 1 -count 5 -src_delta 2000 -tools sendip socat nc bash -proto udp - -race_repeat 0 - -perf_duration 5 -perf_spec udp dport . meta l4proto -perf_dst port proto -perf_src -perf_entries 30000 -perf_proto ipv4 -" - -TYPE_net6_port_mac=" -display net6,port,mac -type_spec ipv6_addr . inet_service . ether_addr -chain_spec ip6 daddr . udp dport . ether saddr -dst addr6 port -src mac -start 10 -count 5 -src_delta 2000 -tools sendip socat nc bash -proto udp6 - -race_repeat 0 - -perf_duration 5 -perf_spec ip6 daddr . udp dport . ether daddr -perf_dst addr6 port mac -perf_src -perf_entries 10 -perf_proto ipv6 -" - -TYPE_net6_port_mac_proto=" -display net6,port,mac,proto -type_spec ipv6_addr . inet_service . ether_addr . inet_proto -chain_spec ip6 daddr . udp dport . ether saddr . meta l4proto -dst addr6 port -src mac proto -start 10 -count 5 -src_delta 2000 -tools sendip socat nc bash -proto udp6 - -race_repeat 0 - -perf_duration 5 -perf_spec ip6 daddr . udp dport . ether daddr . meta l4proto -perf_dst addr6 port mac proto -perf_src -perf_entries 1000 -perf_proto ipv6 -" - -TYPE_net_port_net=" -display net,port,net -type_spec ipv4_addr . inet_service . ipv4_addr -chain_spec ip daddr . udp dport . ip saddr -dst addr4 port -src addr4 -start 1 -count 5 -src_delta 2000 -tools sendip socat nc bash -proto udp - -race_repeat 3 -flood_tools iperf3 iperf netperf -flood_proto tcp -flood_spec ip daddr . udp dport . ip saddr - -perf_duration 0 -" - -TYPE_net6_port_net6_port=" -display net6,port,net6,port -type_spec ipv6_addr . inet_service . ipv6_addr . inet_service -chain_spec ip6 daddr . udp dport . ip6 saddr . udp sport -dst addr6 port -src addr6 port -start 10 -count 5 -src_delta 2000 -tools sendip socat nc -proto udp6 - -race_repeat 3 -flood_tools iperf3 iperf netperf -flood_proto tcp6 -flood_spec ip6 daddr . tcp dport . ip6 saddr . tcp sport - -perf_duration 0 -" - -TYPE_net_port_mac_proto_net=" -display net,port,mac,proto,net -type_spec ipv4_addr . inet_service . ether_addr . inet_proto . ipv4_addr -chain_spec ip daddr . udp dport . ether saddr . meta l4proto . ip saddr -dst addr4 port -src mac proto addr4 -start 1 -count 5 -src_delta 2000 -tools sendip socat nc bash -proto udp - -race_repeat 0 - -perf_duration 0 -" - -TYPE_net_mac=" -display net,mac -type_spec ipv4_addr . ether_addr -chain_spec ip daddr . ether saddr -dst addr4 -src mac -start 1 -count 5 -src_delta 2000 -tools sendip socat nc bash -proto udp - -race_repeat 0 - -perf_duration 5 -perf_spec ip daddr . ether daddr -perf_dst addr4 mac -perf_src -perf_entries 1000 -perf_proto ipv4 -" - -TYPE_mac_net=" -display mac,net -type_spec ether_addr . ipv4_addr -chain_spec ether saddr . ip saddr -dst -src mac addr4 -start 1 -count 5 -src_delta 2000 -tools sendip socat nc bash -proto udp - -race_repeat 0 - -perf_duration 0 -" - -TYPE_net_mac_icmp=" -display net,mac - ICMP -type_spec ipv4_addr . ether_addr -chain_spec ip daddr . ether saddr -dst addr4 -src mac -start 1 -count 5 -src_delta 2000 -tools ping -proto icmp - -race_repeat 0 - -perf_duration 0 -" - -TYPE_net6_mac_icmp=" -display net6,mac - ICMPv6 -type_spec ipv6_addr . ether_addr -chain_spec ip6 daddr . ether saddr -dst addr6 -src mac -start 10 -count 50 -src_delta 2000 -tools ping -proto icmp6 - -race_repeat 0 - -perf_duration 0 -" - -TYPE_net_port_proto_net=" -display net,port,proto,net -type_spec ipv4_addr . inet_service . inet_proto . ipv4_addr -chain_spec ip daddr . udp dport . meta l4proto . ip saddr -dst addr4 port proto -src addr4 -start 1 -count 5 -src_delta 2000 -tools sendip socat nc -proto udp - -race_repeat 3 -flood_tools iperf3 iperf netperf -flood_proto tcp -flood_spec ip daddr . tcp dport . meta l4proto . ip saddr - -perf_duration 0 -" - -# Definition of tests for bugs reported in the past: -# display display text for test report -TYPE_flush_remove_add=" -display Add two elements, flush, re-add -" - -TYPE_reload=" -display net,mac with reload -type_spec ipv4_addr . ether_addr -chain_spec ip daddr . ether saddr -dst addr4 -src mac -start 1 -count 1 -src_delta 2000 -tools sendip socat nc bash -proto udp - -race_repeat 0 - -perf_duration 0 -" - -# Set template for all tests, types and rules are filled in depending on test -set_template=' -flush ruleset - -table inet filter { - counter test { - packets 0 bytes 0 - } - - set test { - type ${type_spec} - flags interval,timeout - } - - chain input { - type filter hook prerouting priority 0; policy accept; - ${chain_spec} @test counter name \"test\" - } -} - -table netdev perf { - counter test { - packets 0 bytes 0 - } - - counter match { - packets 0 bytes 0 - } - - set test { - type ${type_spec} - flags interval - } - - set norange { - type ${type_spec} - } - - set noconcat { - type ${type_spec%% *} - flags interval - } - - chain test { - type filter hook ingress device veth_a priority 0; - } -} -' - -err_buf= -info_buf= - -# Append string to error buffer -err() { - err_buf="${err_buf}${1} -" -} - -# Append string to information buffer -info() { - info_buf="${info_buf}${1} -" -} - -# Flush error buffer to stdout -err_flush() { - printf "%s" "${err_buf}" - err_buf= -} - -# Flush information buffer to stdout -info_flush() { - printf "%s" "${info_buf}" - info_buf= -} - -# Setup veth pair: this namespace receives traffic, B generates it -setup_veth() { - ip netns add B - ip link add veth_a type veth peer name veth_b || return 1 - - ip link set veth_a up - ip link set veth_b netns B - - ip -n B link set veth_b up - - ip addr add dev veth_a 10.0.0.1 - ip route add default dev veth_a - - ip -6 addr add fe80::1/64 dev veth_a nodad - ip -6 addr add 2001:db8::1/64 dev veth_a nodad - ip -6 route add default dev veth_a - - ip -n B route add default dev veth_b - - ip -6 -n B addr add fe80::2/64 dev veth_b nodad - ip -6 -n B addr add 2001:db8::2/64 dev veth_b nodad - ip -6 -n B route add default dev veth_b - - B() { - ip netns exec B "$@" >/dev/null 2>&1 - } - - sleep 2 -} - -# Fill in set template and initialise set -setup_set() { - eval "echo \"${set_template}\"" | nft -f - -} - -# Check that at least one of the needed tools is available -check_tools() { - [ -z "${tools}" ] && return 0 - - __tools= - for tool in ${tools}; do - if [ "${tool}" = "nc" ] && [ "${proto}" = "udp6" ] && \ - ! nc -u -w0 1.1.1.1 1 2>/dev/null; then - # Some GNU netcat builds might not support IPv6 - __tools="${__tools} netcat-openbsd" - continue - fi - __tools="${__tools} ${tool}" - - command -v "${tool}" >/dev/null && return 0 - done - err "need one of:${__tools}, skipping" && return 1 -} - -# Set up function to send ICMP packets -setup_send_icmp() { - send_icmp() { - B ping -c1 -W1 "${dst_addr4}" >/dev/null 2>&1 - } -} - -# Set up function to send ICMPv6 packets -setup_send_icmp6() { - if command -v ping6 >/dev/null; then - send_icmp6() { - ip -6 addr add "${dst_addr6}" dev veth_a nodad \ - 2>/dev/null - B ping6 -q -c1 -W1 "${dst_addr6}" - } - else - send_icmp6() { - ip -6 addr add "${dst_addr6}" dev veth_a nodad \ - 2>/dev/null - B ping -q -6 -c1 -W1 "${dst_addr6}" - } - fi -} - -# Set up function to send single UDP packets on IPv4 -setup_send_udp() { - if command -v sendip >/dev/null; then - send_udp() { - [ -n "${src_port}" ] && src_port="-us ${src_port}" - [ -n "${dst_port}" ] && dst_port="-ud ${dst_port}" - [ -n "${src_addr4}" ] && src_addr4="-is ${src_addr4}" - - # shellcheck disable=SC2086 # sendip needs split options - B sendip -p ipv4 -p udp ${src_addr4} ${src_port} \ - ${dst_port} "${dst_addr4}" - - src_port= - dst_port= - src_addr4= - } - elif command -v socat -v >/dev/null; then - send_udp() { - if [ -n "${src_addr4}" ]; then - B ip addr add "${src_addr4}" dev veth_b - __socatbind=",bind=${src_addr4}" - if [ -n "${src_port}" ];then - __socatbind="${__socatbind}:${src_port}" - fi - fi - - ip addr add "${dst_addr4}" dev veth_a 2>/dev/null - [ -z "${dst_port}" ] && dst_port=12345 - - echo "test4" | B socat -t 0.01 STDIN UDP4-DATAGRAM:${dst_addr4}:${dst_port}"${__socatbind}" - - src_addr4= - src_port= - } - elif command -v nc >/dev/null; then - if nc -u -w0 1.1.1.1 1 2>/dev/null; then - # OpenBSD netcat - nc_opt="-w0" - else - # GNU netcat - nc_opt="-q0" - fi - - send_udp() { - if [ -n "${src_addr4}" ]; then - B ip addr add "${src_addr4}" dev veth_b - __src_addr4="-s ${src_addr4}" - fi - ip addr add "${dst_addr4}" dev veth_a 2>/dev/null - [ -n "${src_port}" ] && src_port="-p ${src_port}" - - echo "" | B nc -u "${nc_opt}" "${__src_addr4}" \ - "${src_port}" "${dst_addr4}" "${dst_port}" - - src_addr4= - src_port= - } - elif [ -z "$(bash -c 'type -p')" ]; then - send_udp() { - ip addr add "${dst_addr4}" dev veth_a 2>/dev/null - if [ -n "${src_addr4}" ]; then - B ip addr add "${src_addr4}/16" dev veth_b - B ip route add default dev veth_b - fi - - B bash -c "echo > /dev/udp/${dst_addr4}/${dst_port}" - - if [ -n "${src_addr4}" ]; then - B ip addr del "${src_addr4}/16" dev veth_b - fi - src_addr4= - } - else - return 1 - fi -} - -# Set up function to send single UDP packets on IPv6 -setup_send_udp6() { - if command -v sendip >/dev/null; then - send_udp6() { - [ -n "${src_port}" ] && src_port="-us ${src_port}" - [ -n "${dst_port}" ] && dst_port="-ud ${dst_port}" - if [ -n "${src_addr6}" ]; then - src_addr6="-6s ${src_addr6}" - else - src_addr6="-6s 2001:db8::2" - fi - ip -6 addr add "${dst_addr6}" dev veth_a nodad \ - 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - B sendip -p ipv6 -p udp ${src_addr6} ${src_port} \ - ${dst_port} "${dst_addr6}" - - src_port= - dst_port= - src_addr6= - } - elif command -v socat -v >/dev/null; then - send_udp6() { - ip -6 addr add "${dst_addr6}" dev veth_a nodad \ - 2>/dev/null - - __socatbind6= - - if [ -n "${src_addr6}" ]; then - if [ -n "${src_addr6} != "${src_addr6_added} ]; then - B ip addr add "${src_addr6}" dev veth_b nodad - - src_addr6_added=${src_addr6} - fi - - __socatbind6=",bind=[${src_addr6}]" - - if [ -n "${src_port}" ] ;then - __socatbind6="${__socatbind6}:${src_port}" - fi - fi - - echo "test6" | B socat -t 0.01 STDIN UDP6-DATAGRAM:[${dst_addr6}]:${dst_port}"${__socatbind6}" - } - elif command -v nc >/dev/null && nc -u -w0 1.1.1.1 1 2>/dev/null; then - # GNU netcat might not work with IPv6, try next tool - send_udp6() { - ip -6 addr add "${dst_addr6}" dev veth_a nodad \ - 2>/dev/null - if [ -n "${src_addr6}" ]; then - B ip addr add "${src_addr6}" dev veth_b nodad - else - src_addr6="2001:db8::2" - fi - [ -n "${src_port}" ] && src_port="-p ${src_port}" - - # shellcheck disable=SC2086 # this needs split options - echo "" | B nc -u w0 "-s${src_addr6}" ${src_port} \ - ${dst_addr6} ${dst_port} - - src_addr6= - src_port= - } - elif [ -z "$(bash -c 'type -p')" ]; then - send_udp6() { - ip -6 addr add "${dst_addr6}" dev veth_a nodad \ - 2>/dev/null - B ip addr add "${src_addr6}" dev veth_b nodad - B bash -c "echo > /dev/udp/${dst_addr6}/${dst_port}" - ip -6 addr del "${dst_addr6}" dev veth_a 2>/dev/null - } - else - return 1 - fi -} - -# Set up function to send TCP traffic on IPv4 -setup_flood_tcp() { - if command -v iperf3 >/dev/null; then - flood_tcp() { - [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" - if [ -n "${src_addr4}" ]; then - B ip addr add "${src_addr4}/16" dev veth_b - src_addr4="-B ${src_addr4}" - else - B ip addr add dev veth_b 10.0.0.2 - src_addr4="-B 10.0.0.2" - fi - if [ -n "${src_port}" ]; then - src_port="--cport ${src_port}" - fi - B ip route add default dev veth_b 2>/dev/null - ip addr add "${dst_addr4}" dev veth_a 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - iperf3 -s -DB "${dst_addr4}" ${dst_port} >/dev/null 2>&1 - sleep 2 - - # shellcheck disable=SC2086 # this needs split options - B iperf3 -c "${dst_addr4}" ${dst_port} ${src_port} \ - ${src_addr4} -l16 -t 1000 - - src_addr4= - src_port= - dst_port= - } - elif command -v iperf >/dev/null; then - flood_tcp() { - [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" - if [ -n "${src_addr4}" ]; then - B ip addr add "${src_addr4}/16" dev veth_b - src_addr4="-B ${src_addr4}" - else - B ip addr add dev veth_b 10.0.0.2 2>/dev/null - src_addr4="-B 10.0.0.2" - fi - if [ -n "${src_port}" ]; then - src_addr4="${src_addr4}:${src_port}" - fi - B ip route add default dev veth_b - ip addr add "${dst_addr4}" dev veth_a 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - iperf -s -DB "${dst_addr4}" ${dst_port} >/dev/null 2>&1 - sleep 2 - - # shellcheck disable=SC2086 # this needs split options - B iperf -c "${dst_addr4}" ${dst_port} ${src_addr4} \ - -l20 -t 1000 - - src_addr4= - src_port= - dst_port= - } - elif command -v netperf >/dev/null; then - flood_tcp() { - [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" - if [ -n "${src_addr4}" ]; then - B ip addr add "${src_addr4}/16" dev veth_b - else - B ip addr add dev veth_b 10.0.0.2 - src_addr4="10.0.0.2" - fi - if [ -n "${src_port}" ]; then - dst_port="${dst_port},${src_port}" - fi - B ip route add default dev veth_b - ip addr add "${dst_addr4}" dev veth_a 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - netserver -4 ${dst_port} -L "${dst_addr4}" \ - >/dev/null 2>&1 - sleep 2 - - # shellcheck disable=SC2086 # this needs split options - B netperf -4 -H "${dst_addr4}" ${dst_port} \ - -L "${src_addr4}" -l 1000 -t TCP_STREAM - - src_addr4= - src_port= - dst_port= - } - else - return 1 - fi -} - -# Set up function to send TCP traffic on IPv6 -setup_flood_tcp6() { - if command -v iperf3 >/dev/null; then - flood_tcp6() { - [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" - if [ -n "${src_addr6}" ]; then - B ip addr add "${src_addr6}" dev veth_b nodad - src_addr6="-B ${src_addr6}" - else - src_addr6="-B 2001:db8::2" - fi - if [ -n "${src_port}" ]; then - src_port="--cport ${src_port}" - fi - B ip route add default dev veth_b - ip -6 addr add "${dst_addr6}" dev veth_a nodad \ - 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - iperf3 -s -DB "${dst_addr6}" ${dst_port} >/dev/null 2>&1 - sleep 2 - - # shellcheck disable=SC2086 # this needs split options - B iperf3 -c "${dst_addr6}" ${dst_port} \ - ${src_port} ${src_addr6} -l16 -t 1000 - - src_addr6= - src_port= - dst_port= - } - elif command -v iperf >/dev/null; then - flood_tcp6() { - [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" - if [ -n "${src_addr6}" ]; then - B ip addr add "${src_addr6}" dev veth_b nodad - src_addr6="-B ${src_addr6}" - else - src_addr6="-B 2001:db8::2" - fi - if [ -n "${src_port}" ]; then - src_addr6="${src_addr6}:${src_port}" - fi - B ip route add default dev veth_b - ip -6 addr add "${dst_addr6}" dev veth_a nodad \ - 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - iperf -s -VDB "${dst_addr6}" ${dst_port} >/dev/null 2>&1 - sleep 2 - - # shellcheck disable=SC2086 # this needs split options - B iperf -c "${dst_addr6}" -V ${dst_port} \ - ${src_addr6} -l1 -t 1000 - - src_addr6= - src_port= - dst_port= - } - elif command -v netperf >/dev/null; then - flood_tcp6() { - [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" - if [ -n "${src_addr6}" ]; then - B ip addr add "${src_addr6}" dev veth_b nodad - else - src_addr6="2001:db8::2" - fi - if [ -n "${src_port}" ]; then - dst_port="${dst_port},${src_port}" - fi - B ip route add default dev veth_b - ip -6 addr add "${dst_addr6}" dev veth_a nodad \ - 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - netserver -6 ${dst_port} -L "${dst_addr6}" \ - >/dev/null 2>&1 - sleep 2 - - # shellcheck disable=SC2086 # this needs split options - B netperf -6 -H "${dst_addr6}" ${dst_port} \ - -L "${src_addr6}" -l 1000 -t TCP_STREAM - - src_addr6= - src_port= - dst_port= - } - else - return 1 - fi -} - -# Set up function to send UDP traffic on IPv4 -setup_flood_udp() { - if command -v iperf3 >/dev/null; then - flood_udp() { - [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" - if [ -n "${src_addr4}" ]; then - B ip addr add "${src_addr4}/16" dev veth_b - src_addr4="-B ${src_addr4}" - else - B ip addr add dev veth_b 10.0.0.2 2>/dev/null - src_addr4="-B 10.0.0.2" - fi - if [ -n "${src_port}" ]; then - src_port="--cport ${src_port}" - fi - B ip route add default dev veth_b - ip addr add "${dst_addr4}" dev veth_a 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - iperf3 -s -DB "${dst_addr4}" ${dst_port} - sleep 2 - - # shellcheck disable=SC2086 # this needs split options - B iperf3 -u -c "${dst_addr4}" -Z -b 100M -l16 -t1000 \ - ${dst_port} ${src_port} ${src_addr4} - - src_addr4= - src_port= - dst_port= - } - elif command -v iperf >/dev/null; then - flood_udp() { - [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" - if [ -n "${src_addr4}" ]; then - B ip addr add "${src_addr4}/16" dev veth_b - src_addr4="-B ${src_addr4}" - else - B ip addr add dev veth_b 10.0.0.2 - src_addr4="-B 10.0.0.2" - fi - if [ -n "${src_port}" ]; then - src_addr4="${src_addr4}:${src_port}" - fi - B ip route add default dev veth_b - ip addr add "${dst_addr4}" dev veth_a 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - iperf -u -sDB "${dst_addr4}" ${dst_port} >/dev/null 2>&1 - sleep 2 - - # shellcheck disable=SC2086 # this needs split options - B iperf -u -c "${dst_addr4}" -b 100M -l1 -t1000 \ - ${dst_port} ${src_addr4} - - src_addr4= - src_port= - dst_port= - } - elif command -v netperf >/dev/null; then - flood_udp() { - [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" - if [ -n "${src_addr4}" ]; then - B ip addr add "${src_addr4}/16" dev veth_b - else - B ip addr add dev veth_b 10.0.0.2 - src_addr4="10.0.0.2" - fi - if [ -n "${src_port}" ]; then - dst_port="${dst_port},${src_port}" - fi - B ip route add default dev veth_b - ip addr add "${dst_addr4}" dev veth_a 2>/dev/null - - # shellcheck disable=SC2086 # this needs split options - netserver -4 ${dst_port} -L "${dst_addr4}" \ - >/dev/null 2>&1 - sleep 2 - - # shellcheck disable=SC2086 # this needs split options - B netperf -4 -H "${dst_addr4}" ${dst_port} \ - -L "${src_addr4}" -l 1000 -t UDP_STREAM - - src_addr4= - src_port= - dst_port= - } - else - return 1 - fi -} - -# Find pktgen script and set up function to start pktgen injection -setup_perf() { - for pktgen_script_path in ${PKTGEN_SCRIPT_PATHS} __notfound; do - command -v "${pktgen_script_path}" >/dev/null && break - done - [ "${pktgen_script_path}" = "__notfound" ] && return 1 - - perf_ipv4() { - ${pktgen_script_path} -s80 \ - -i veth_a -d "${dst_addr4}" -p "${dst_port}" \ - -m "${dst_mac}" \ - -t $(($(nproc) / 5 + 1)) -b10000 -n0 2>/dev/null & - perf_pid=$! - } - perf_ipv6() { - IP6=6 ${pktgen_script_path} -s100 \ - -i veth_a -d "${dst_addr6}" -p "${dst_port}" \ - -m "${dst_mac}" \ - -t $(($(nproc) / 5 + 1)) -b10000 -n0 2>/dev/null & - perf_pid=$! - } -} - -# Clean up before each test -cleanup() { - nft reset counter inet filter test >/dev/null 2>&1 - nft flush ruleset >/dev/null 2>&1 - ip link del dummy0 2>/dev/null - ip route del default 2>/dev/null - ip -6 route del default 2>/dev/null - ip netns del B 2>/dev/null - ip link del veth_a 2>/dev/null - timeout= - killall iperf3 2>/dev/null - killall iperf 2>/dev/null - killall netperf 2>/dev/null - killall netserver 2>/dev/null - rm -f ${tmp} - sleep 2 -} - -# Entry point for setup functions -setup() { - if [ "$(id -u)" -ne 0 ]; then - echo " need to run as root" - exit ${KSELFTEST_SKIP} - fi - - cleanup - check_tools || return 1 - for arg do - if ! eval setup_"${arg}"; then - err " ${arg} not supported" - return 1 - fi - done -} - -# Format integer into IPv4 address, summing 10.0.0.5 (arbitrary) to it -format_addr4() { - a=$((${1} + 16777216 * 10 + 5)) - printf "%i.%i.%i.%i" \ - "$((a / 16777216))" "$((a % 16777216 / 65536))" \ - "$((a % 65536 / 256))" "$((a % 256))" -} - -# Format integer into IPv6 address, summing 2001:db8:: to it -format_addr6() { - printf "2001:db8::%04x:%04x" "$((${1} / 65536))" "$((${1} % 65536))" -} - -# Format integer into EUI-48 address, summing 00:01:00:00:00:00 to it -format_mac() { - printf "00:01:%02x:%02x:%02x:%02x" \ - "$((${1} / 16777216))" "$((${1} % 16777216 / 65536))" \ - "$((${1} % 65536 / 256))" "$((${1} % 256))" -} - -# Format integer into port, avoid 0 port -format_port() { - printf "%i" "$((${1} % 65534 + 1))" -} - -# Drop suffixed '6' from L4 protocol, if any -format_proto() { - printf "%s" "${proto}" | tr -d 6 -} - -# Format destination and source fields into nft concatenated type -format() { - __start= - __end= - __expr="{ " - - for f in ${dst}; do - [ "${__expr}" != "{ " ] && __expr="${__expr} . " - - __start="$(eval format_"${f}" "${start}")" - __end="$(eval format_"${f}" "${end}")" - - if [ "${f}" = "proto" ]; then - __expr="${__expr}${__start}" - else - __expr="${__expr}${__start}-${__end}" - fi - done - for f in ${src}; do - [ "${__expr}" != "{ " ] && __expr="${__expr} . " - - __start="$(eval format_"${f}" "${srcstart}")" - __end="$(eval format_"${f}" "${srcend}")" - - if [ "${f}" = "proto" ]; then - __expr="${__expr}${__start}" - else - __expr="${__expr}${__start}-${__end}" - fi - done - - if [ -n "${timeout}" ]; then - echo "${__expr} timeout ${timeout}s }" - else - echo "${__expr} }" - fi -} - -# Format destination and source fields into nft type, start element only -format_norange() { - __expr="{ " - - for f in ${dst}; do - [ "${__expr}" != "{ " ] && __expr="${__expr} . " - - __expr="${__expr}$(eval format_"${f}" "${start}")" - done - for f in ${src}; do - __expr="${__expr} . $(eval format_"${f}" "${start}")" - done - - echo "${__expr} }" -} - -# Format first destination field into nft type -format_noconcat() { - for f in ${dst}; do - __start="$(eval format_"${f}" "${start}")" - __end="$(eval format_"${f}" "${end}")" - - if [ "${f}" = "proto" ]; then - echo "{ ${__start} }" - else - echo "{ ${__start}-${__end} }" - fi - return - done -} - -# Add single entry to 'test' set in 'inet filter' table -add() { - if ! nft add element inet filter test "${1}"; then - err "Failed to add ${1} given ruleset:" - err "$(nft -a list ruleset)" - return 1 - fi -} - -# Format and output entries for sets in 'netdev perf' table -add_perf() { - if [ "${1}" = "test" ]; then - echo "add element netdev perf test $(format)" - elif [ "${1}" = "norange" ]; then - echo "add element netdev perf norange $(format_norange)" - elif [ "${1}" = "noconcat" ]; then - echo "add element netdev perf noconcat $(format_noconcat)" - fi -} - -# Add single entry to 'norange' set in 'netdev perf' table -add_perf_norange() { - if ! nft add element netdev perf norange "${1}"; then - err "Failed to add ${1} given ruleset:" - err "$(nft -a list ruleset)" - return 1 - fi -} - -# Add single entry to 'noconcat' set in 'netdev perf' table -add_perf_noconcat() { - if ! nft add element netdev perf noconcat "${1}"; then - err "Failed to add ${1} given ruleset:" - err "$(nft -a list ruleset)" - return 1 - fi -} - -# Delete single entry from set -del() { - if ! nft delete element inet filter test "${1}"; then - err "Failed to delete ${1} given ruleset:" - err "$(nft -a list ruleset)" - return 1 - fi -} - -# Return packet count from 'test' counter in 'inet filter' table -count_packets() { - found=0 - for token in $(nft list counter inet filter test); do - [ ${found} -eq 1 ] && echo "${token}" && return - [ "${token}" = "packets" ] && found=1 - done -} - -# Return packet count from 'test' counter in 'netdev perf' table -count_perf_packets() { - found=0 - for token in $(nft list counter netdev perf test); do - [ ${found} -eq 1 ] && echo "${token}" && return - [ "${token}" = "packets" ] && found=1 - done -} - -# Set MAC addresses, send traffic according to specifier -flood() { - ip link set veth_a address "$(format_mac "${1}")" - ip -n B link set veth_b address "$(format_mac "${2}")" - - for f in ${dst}; do - eval dst_"$f"=\$\(format_\$f "${1}"\) - done - for f in ${src}; do - eval src_"$f"=\$\(format_\$f "${2}"\) - done - eval flood_\$proto -} - -# Set MAC addresses, start pktgen injection -perf() { - dst_mac="$(format_mac "${1}")" - ip link set veth_a address "${dst_mac}" - - for f in ${dst}; do - eval dst_"$f"=\$\(format_\$f "${1}"\) - done - for f in ${src}; do - eval src_"$f"=\$\(format_\$f "${2}"\) - done - eval perf_\$perf_proto -} - -# Set MAC addresses, send single packet, check that it matches, reset counter -send_match() { - ip link set veth_a address "$(format_mac "${1}")" - ip -n B link set veth_b address "$(format_mac "${2}")" - - for f in ${dst}; do - eval dst_"$f"=\$\(format_\$f "${1}"\) - done - for f in ${src}; do - eval src_"$f"=\$\(format_\$f "${2}"\) - done - eval send_\$proto - if [ "$(count_packets)" != "1" ]; then - err "${proto} packet to:" - err " $(for f in ${dst}; do - eval format_\$f "${1}"; printf ' '; done)" - err "from:" - err " $(for f in ${src}; do - eval format_\$f "${2}"; printf ' '; done)" - err "should have matched ruleset:" - err "$(nft -a list ruleset)" - return 1 - fi - nft reset counter inet filter test >/dev/null -} - -# Set MAC addresses, send single packet, check that it doesn't match -send_nomatch() { - ip link set veth_a address "$(format_mac "${1}")" - ip -n B link set veth_b address "$(format_mac "${2}")" - - for f in ${dst}; do - eval dst_"$f"=\$\(format_\$f "${1}"\) - done - for f in ${src}; do - eval src_"$f"=\$\(format_\$f "${2}"\) - done - eval send_\$proto - if [ "$(count_packets)" != "0" ]; then - err "${proto} packet to:" - err " $(for f in ${dst}; do - eval format_\$f "${1}"; printf ' '; done)" - err "from:" - err " $(for f in ${src}; do - eval format_\$f "${2}"; printf ' '; done)" - err "should not have matched ruleset:" - err "$(nft -a list ruleset)" - return 1 - fi -} - -# Correctness test template: -# - add ranged element, check that packets match it -# - check that packets outside range don't match it -# - remove some elements, check that packets don't match anymore -test_correctness() { - setup veth send_"${proto}" set || return ${KSELFTEST_SKIP} - - range_size=1 - for i in $(seq "${start}" $((start + count))); do - end=$((start + range_size)) - - # Avoid negative or zero-sized port ranges - if [ $((end / 65534)) -gt $((start / 65534)) ]; then - start=${end} - end=$((end + 1)) - fi - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - add "$(format)" || return 1 - for j in $(seq ${start} $((range_size / 2 + 1)) ${end}); do - send_match "${j}" $((j + src_delta)) || return 1 - done - send_nomatch $((end + 1)) $((end + 1 + src_delta)) || return 1 - - # Delete elements now and then - if [ $((i % 3)) -eq 0 ]; then - del "$(format)" || return 1 - for j in $(seq ${start} \ - $((range_size / 2 + 1)) ${end}); do - send_nomatch "${j}" $((j + src_delta)) \ - || return 1 - done - fi - - range_size=$((range_size + 1)) - start=$((end + range_size)) - done -} - -# Concurrency test template: -# - add all the elements -# - start a thread for each physical thread that: -# - adds all the elements -# - flushes the set -# - adds all the elements -# - flushes the entire ruleset -# - adds the set back -# - adds all the elements -# - delete all the elements -test_concurrency() { - proto=${flood_proto} - tools=${flood_tools} - chain_spec=${flood_spec} - setup veth flood_"${proto}" set || return ${KSELFTEST_SKIP} - - range_size=1 - cstart=${start} - flood_pids= - for i in $(seq ${start} $((start + count))); do - end=$((start + range_size)) - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - add "$(format)" || return 1 - - flood "${i}" $((i + src_delta)) & flood_pids="${flood_pids} $!" - - range_size=$((range_size + 1)) - start=$((end + range_size)) - done - - sleep 10 - - pids= - for c in $(seq 1 "$(nproc)"); do ( - for r in $(seq 1 "${race_repeat}"); do - range_size=1 - - # $start needs to be local to this subshell - # shellcheck disable=SC2030 - start=${cstart} - for i in $(seq ${start} $((start + count))); do - end=$((start + range_size)) - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - add "$(format)" 2>/dev/null - - range_size=$((range_size + 1)) - start=$((end + range_size)) - done - - nft flush inet filter test 2>/dev/null - - range_size=1 - start=${cstart} - for i in $(seq ${start} $((start + count))); do - end=$((start + range_size)) - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - add "$(format)" 2>/dev/null - - range_size=$((range_size + 1)) - start=$((end + range_size)) - done - - nft flush ruleset - setup set 2>/dev/null - - range_size=1 - start=${cstart} - for i in $(seq ${start} $((start + count))); do - end=$((start + range_size)) - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - add "$(format)" 2>/dev/null - - range_size=$((range_size + 1)) - start=$((end + range_size)) - done - - range_size=1 - start=${cstart} - for i in $(seq ${start} $((start + count))); do - end=$((start + range_size)) - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - del "$(format)" 2>/dev/null - - range_size=$((range_size + 1)) - start=$((end + range_size)) - done - done - ) & pids="${pids} $!" - done - - # shellcheck disable=SC2046,SC2086 # word splitting wanted here - wait $(for pid in ${pids}; do echo ${pid}; done) - # shellcheck disable=SC2046,SC2086 - kill $(for pid in ${flood_pids}; do echo ${pid}; done) 2>/dev/null - # shellcheck disable=SC2046,SC2086 - wait $(for pid in ${flood_pids}; do echo ${pid}; done) 2>/dev/null - - return 0 -} - -# Timeout test template: -# - add all the elements with 3s timeout while checking that packets match -# - wait 3s after the last insertion, check that packets don't match any entry -test_timeout() { - setup veth send_"${proto}" set || return ${KSELFTEST_SKIP} - - timeout=3 - range_size=1 - for i in $(seq "${start}" $((start + count))); do - end=$((start + range_size)) - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - add "$(format)" || return 1 - - for j in $(seq ${start} $((range_size / 2 + 1)) ${end}); do - send_match "${j}" $((j + src_delta)) || return 1 - done - - range_size=$((range_size + 1)) - start=$((end + range_size)) - done - sleep 3 - for i in $(seq ${start} $((start + count))); do - end=$((start + range_size)) - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - for j in $(seq ${start} $((range_size / 2 + 1)) ${end}); do - send_nomatch "${j}" $((j + src_delta)) || return 1 - done - - range_size=$((range_size + 1)) - start=$((end + range_size)) - done -} - -# Performance test template: -# - add concatenated ranged entries -# - add non-ranged concatenated entries (for hash set matching rate baseline) -# - add ranged entries with first field only (for rbhash baseline) -# - start pktgen injection directly on device rx path of this namespace -# - measure drop only rate, hash and rbtree baselines, then matching rate -test_performance() { - chain_spec=${perf_spec} - dst="${perf_dst}" - src="${perf_src}" - setup veth perf set || return ${KSELFTEST_SKIP} - - first=${start} - range_size=1 - for set in test norange noconcat; do - start=${first} - for i in $(seq ${start} $((start + perf_entries))); do - end=$((start + range_size)) - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - if [ $((end / 65534)) -gt $((start / 65534)) ]; then - start=${end} - end=$((end + 1)) - elif [ ${start} -eq ${end} ]; then - end=$((start + 1)) - fi - - add_perf ${set} - - start=$((end + range_size)) - done > "${tmp}" - nft -f "${tmp}" - done - - perf $((end - 1)) ${srcstart} - - sleep 2 - - nft add rule netdev perf test counter name \"test\" drop - nft reset counter netdev perf test >/dev/null 2>&1 - sleep "${perf_duration}" - pps="$(printf %10s $(($(count_perf_packets) / perf_duration)))" - info " baseline (drop from netdev hook): ${pps}pps" - handle="$(nft -a list chain netdev perf test | grep counter)" - handle="${handle##* }" - nft delete rule netdev perf test handle "${handle}" - - nft add rule "netdev perf test ${chain_spec} @norange \ - counter name \"test\" drop" - nft reset counter netdev perf test >/dev/null 2>&1 - sleep "${perf_duration}" - pps="$(printf %10s $(($(count_perf_packets) / perf_duration)))" - info " baseline hash (non-ranged entries): ${pps}pps" - handle="$(nft -a list chain netdev perf test | grep counter)" - handle="${handle##* }" - nft delete rule netdev perf test handle "${handle}" - - nft add rule "netdev perf test ${chain_spec%%. *} @noconcat \ - counter name \"test\" drop" - nft reset counter netdev perf test >/dev/null 2>&1 - sleep "${perf_duration}" - pps="$(printf %10s $(($(count_perf_packets) / perf_duration)))" - info " baseline rbtree (match on first field only): ${pps}pps" - handle="$(nft -a list chain netdev perf test | grep counter)" - handle="${handle##* }" - nft delete rule netdev perf test handle "${handle}" - - nft add rule "netdev perf test ${chain_spec} @test \ - counter name \"test\" drop" - nft reset counter netdev perf test >/dev/null 2>&1 - sleep "${perf_duration}" - pps="$(printf %10s $(($(count_perf_packets) / perf_duration)))" - p5="$(printf %5s "${perf_entries}")" - info " set with ${p5} full, ranged entries: ${pps}pps" - kill "${perf_pid}" -} - -test_bug_flush_remove_add() { - set_cmd='{ set s { type ipv4_addr . inet_service; flags interval; }; }' - elem1='{ 10.0.0.1 . 22-25, 10.0.0.1 . 10-20 }' - elem2='{ 10.0.0.1 . 10-20, 10.0.0.1 . 22-25 }' - for i in `seq 1 100`; do - nft add table t ${set_cmd} || return ${KSELFTEST_SKIP} - nft add element t s ${elem1} 2>/dev/null || return 1 - nft flush set t s 2>/dev/null || return 1 - nft add element t s ${elem2} 2>/dev/null || return 1 - done - nft flush ruleset -} - -# - add ranged element, check that packets match it -# - reload the set, check packets still match -test_bug_reload() { - setup veth send_"${proto}" set || return ${KSELFTEST_SKIP} - rstart=${start} - - range_size=1 - for i in $(seq "${start}" $((start + count))); do - end=$((start + range_size)) - - # Avoid negative or zero-sized port ranges - if [ $((end / 65534)) -gt $((start / 65534)) ]; then - start=${end} - end=$((end + 1)) - fi - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - add "$(format)" || return 1 - range_size=$((range_size + 1)) - start=$((end + range_size)) - done - - # check kernel does allocate pcpu sctrach map - # for reload with no elemet add/delete - ( echo flush set inet filter test ; - nft list set inet filter test ) | nft -f - - - start=${rstart} - range_size=1 - - for i in $(seq "${start}" $((start + count))); do - end=$((start + range_size)) - - # Avoid negative or zero-sized port ranges - if [ $((end / 65534)) -gt $((start / 65534)) ]; then - start=${end} - end=$((end + 1)) - fi - srcstart=$((start + src_delta)) - srcend=$((end + src_delta)) - - for j in $(seq ${start} $((range_size / 2 + 1)) ${end}); do - send_match "${j}" $((j + src_delta)) || return 1 - done - - range_size=$((range_size + 1)) - start=$((end + range_size)) - done - - nft flush ruleset -} - -test_reported_issues() { - eval test_bug_"${subtest}" -} - -# Run everything in a separate network namespace -[ "${1}" != "run" ] && { unshare -n "${0}" run; exit $?; } -tmp="$(mktemp)" -trap cleanup EXIT - -# Entry point for test runs -passed=0 -for name in ${TESTS}; do - printf "TEST: %s\n" "$(echo ${name} | tr '_' ' ')" - if [ "${name}" = "reported_issues" ]; then - SUBTESTS="${BUGS}" - else - SUBTESTS="${TYPES}" - fi - - for subtest in ${SUBTESTS}; do - eval desc=\$TYPE_"${subtest}" - IFS=' -' - for __line in ${desc}; do - # shellcheck disable=SC2086 - eval ${__line%% *}=\"${__line##* }\"; - done - IFS=' -' - - if [ "${name}" = "concurrency" ] && \ - [ "${race_repeat}" = "0" ]; then - continue - fi - if [ "${name}" = "performance" ] && \ - [ "${perf_duration}" = "0" ]; then - continue - fi - - printf " %-60s " "${display}" - eval test_"${name}" - ret=$? - - if [ $ret -eq 0 ]; then - printf "[ OK ]\n" - info_flush - passed=$((passed + 1)) - elif [ $ret -eq 1 ]; then - printf "[FAIL]\n" - err_flush - exit 1 - elif [ $ret -eq ${KSELFTEST_SKIP} ]; then - printf "[SKIP]\n" - err_flush - fi - done -done - -[ ${passed} -eq 0 ] && exit ${KSELFTEST_SKIP} || exit 0 diff --git a/tools/testing/selftests/netfilter/nft_conntrack_helper.sh b/tools/testing/selftests/netfilter/nft_conntrack_helper.sh deleted file mode 100755 index faa7778d7bd1..000000000000 --- a/tools/testing/selftests/netfilter/nft_conntrack_helper.sh +++ /dev/null @@ -1,197 +0,0 @@ -#!/bin/bash -# -# This tests connection tracking helper assignment: -# 1. can attach ftp helper to a connection from nft ruleset. -# 2. auto-assign still works. -# -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -sfx=$(mktemp -u "XXXXXXXX") -ns1="ns1-$sfx" -ns2="ns2-$sfx" -testipv6=1 - -cleanup() -{ - ip netns del ${ns1} - ip netns del ${ns2} -} - -nft --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -conntrack -V > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without conntrack tool" - exit $ksft_skip -fi - -which nc >/dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without netcat tool" - exit $ksft_skip -fi - -trap cleanup EXIT - -ip netns add ${ns1} -ip netns add ${ns2} - -ip link add veth0 netns ${ns1} type veth peer name veth0 netns ${ns2} > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: No virtual ethernet pair device support in kernel" - exit $ksft_skip -fi - -ip -net ${ns1} link set lo up -ip -net ${ns1} link set veth0 up - -ip -net ${ns2} link set lo up -ip -net ${ns2} link set veth0 up - -ip -net ${ns1} addr add 10.0.1.1/24 dev veth0 -ip -net ${ns1} addr add dead:1::1/64 dev veth0 - -ip -net ${ns2} addr add 10.0.1.2/24 dev veth0 -ip -net ${ns2} addr add dead:1::2/64 dev veth0 - -load_ruleset_family() { - local family=$1 - local ns=$2 - -ip netns exec ${ns} nft -f - <<EOF -table $family raw { - ct helper ftp { - type "ftp" protocol tcp - } - chain pre { - type filter hook prerouting priority 0; policy accept; - tcp dport 2121 ct helper set "ftp" - } - chain output { - type filter hook output priority 0; policy accept; - tcp dport 2121 ct helper set "ftp" - } -} -EOF - return $? -} - -check_for_helper() -{ - local netns=$1 - local message=$2 - local port=$3 - - if echo $message |grep -q 'ipv6';then - local family="ipv6" - else - local family="ipv4" - fi - - ip netns exec ${netns} conntrack -L -f $family -p tcp --dport $port 2> /dev/null |grep -q 'helper=ftp' - if [ $? -ne 0 ] ; then - if [ $autoassign -eq 0 ] ;then - echo "FAIL: ${netns} did not show attached helper $message" 1>&2 - ret=1 - else - echo "PASS: ${netns} did not show attached helper $message" 1>&2 - fi - else - if [ $autoassign -eq 0 ] ;then - echo "PASS: ${netns} connection on port $port has ftp helper attached" 1>&2 - else - echo "FAIL: ${netns} connection on port $port has ftp helper attached" 1>&2 - ret=1 - fi - fi - - return 0 -} - -test_helper() -{ - local port=$1 - local autoassign=$2 - - if [ $autoassign -eq 0 ] ;then - msg="set via ruleset" - else - msg="auto-assign" - fi - - sleep 3 | ip netns exec ${ns2} nc -w 2 -l -p $port > /dev/null & - - sleep 1 | ip netns exec ${ns1} nc -w 2 10.0.1.2 $port > /dev/null & - sleep 1 - - check_for_helper "$ns1" "ip $msg" $port $autoassign - check_for_helper "$ns2" "ip $msg" $port $autoassign - - wait - - if [ $testipv6 -eq 0 ] ;then - return 0 - fi - - ip netns exec ${ns1} conntrack -F 2> /dev/null - ip netns exec ${ns2} conntrack -F 2> /dev/null - - sleep 3 | ip netns exec ${ns2} nc -w 2 -6 -l -p $port > /dev/null & - - sleep 1 | ip netns exec ${ns1} nc -w 2 -6 dead:1::2 $port > /dev/null & - sleep 1 - - check_for_helper "$ns1" "ipv6 $msg" $port - check_for_helper "$ns2" "ipv6 $msg" $port - - wait -} - -load_ruleset_family ip ${ns1} -if [ $? -ne 0 ];then - echo "FAIL: ${ns1} cannot load ip ruleset" 1>&2 - exit 1 -fi - -load_ruleset_family ip6 ${ns1} -if [ $? -ne 0 ];then - echo "SKIP: ${ns1} cannot load ip6 ruleset" 1>&2 - testipv6=0 -fi - -load_ruleset_family inet ${ns2} -if [ $? -ne 0 ];then - echo "SKIP: ${ns1} cannot load inet ruleset" 1>&2 - load_ruleset_family ip ${ns2} - if [ $? -ne 0 ];then - echo "FAIL: ${ns2} cannot load ip ruleset" 1>&2 - exit 1 - fi - - if [ $testipv6 -eq 1 ] ;then - load_ruleset_family ip6 ${ns2} - if [ $? -ne 0 ];then - echo "FAIL: ${ns2} cannot load ip6 ruleset" 1>&2 - exit 1 - fi - fi -fi - -test_helper 2121 0 -ip netns exec ${ns1} sysctl -qe 'net.netfilter.nf_conntrack_helper=1' -ip netns exec ${ns2} sysctl -qe 'net.netfilter.nf_conntrack_helper=1' -test_helper 21 1 - -exit $ret diff --git a/tools/testing/selftests/netfilter/nft_fib.sh b/tools/testing/selftests/netfilter/nft_fib.sh deleted file mode 100755 index dff476e45e77..000000000000 --- a/tools/testing/selftests/netfilter/nft_fib.sh +++ /dev/null @@ -1,273 +0,0 @@ -#!/bin/bash -# -# This tests the fib expression. -# -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -sfx=$(mktemp -u "XXXXXXXX") -ns1="ns1-$sfx" -ns2="ns2-$sfx" -nsrouter="nsrouter-$sfx" -timeout=4 - -log_netns=$(sysctl -n net.netfilter.nf_log_all_netns) - -cleanup() -{ - ip netns del ${ns1} - ip netns del ${ns2} - ip netns del ${nsrouter} - - [ $log_netns -eq 0 ] && sysctl -q net.netfilter.nf_log_all_netns=$log_netns -} - -nft --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -ip netns add ${nsrouter} -if [ $? -ne 0 ];then - echo "SKIP: Could not create net namespace" - exit $ksft_skip -fi - -trap cleanup EXIT - -dmesg | grep -q ' nft_rpfilter: ' -if [ $? -eq 0 ]; then - dmesg -c | grep ' nft_rpfilter: ' - echo "WARN: a previous test run has failed" 1>&2 -fi - -sysctl -q net.netfilter.nf_log_all_netns=1 -ip netns add ${ns1} -ip netns add ${ns2} - -load_ruleset() { - local netns=$1 - -ip netns exec ${netns} nft -f /dev/stdin <<EOF -table inet filter { - chain prerouting { - type filter hook prerouting priority 0; policy accept; - fib saddr . iif oif missing counter log prefix "$netns nft_rpfilter: " drop - } -} -EOF -} - -load_pbr_ruleset() { - local netns=$1 - -ip netns exec ${netns} nft -f /dev/stdin <<EOF -table inet filter { - chain forward { - type filter hook forward priority raw; - fib saddr . iif oif gt 0 accept - log drop - } -} -EOF -} - -load_ruleset_count() { - local netns=$1 - -ip netns exec ${netns} nft -f /dev/stdin <<EOF -table inet filter { - chain prerouting { - type filter hook prerouting priority 0; policy accept; - ip daddr 1.1.1.1 fib saddr . iif oif missing counter drop - ip6 daddr 1c3::c01d fib saddr . iif oif missing counter drop - } -} -EOF -} - -check_drops() { - dmesg | grep -q ' nft_rpfilter: ' - if [ $? -eq 0 ]; then - dmesg | grep ' nft_rpfilter: ' - echo "FAIL: rpfilter did drop packets" - return 1 - fi - - return 0 -} - -check_fib_counter() { - local want=$1 - local ns=$2 - local address=$3 - - line=$(ip netns exec ${ns} nft list table inet filter | grep 'fib saddr . iif' | grep $address | grep "packets $want" ) - ret=$? - - if [ $ret -ne 0 ];then - echo "Netns $ns fib counter doesn't match expected packet count of $want for $address" 1>&2 - ip netns exec ${ns} nft list table inet filter - return 1 - fi - - if [ $want -gt 0 ]; then - echo "PASS: fib expression did drop packets for $address" - fi - - return 0 -} - -load_ruleset ${nsrouter} -load_ruleset ${ns1} -load_ruleset ${ns2} - -ip link add veth0 netns ${nsrouter} type veth peer name eth0 netns ${ns1} > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: No virtual ethernet pair device support in kernel" - exit $ksft_skip -fi -ip link add veth1 netns ${nsrouter} type veth peer name eth0 netns ${ns2} - -ip -net ${nsrouter} link set lo up -ip -net ${nsrouter} link set veth0 up -ip -net ${nsrouter} addr add 10.0.1.1/24 dev veth0 -ip -net ${nsrouter} addr add dead:1::1/64 dev veth0 - -ip -net ${nsrouter} link set veth1 up -ip -net ${nsrouter} addr add 10.0.2.1/24 dev veth1 -ip -net ${nsrouter} addr add dead:2::1/64 dev veth1 - -ip -net ${ns1} link set lo up -ip -net ${ns1} link set eth0 up - -ip -net ${ns2} link set lo up -ip -net ${ns2} link set eth0 up - -ip -net ${ns1} addr add 10.0.1.99/24 dev eth0 -ip -net ${ns1} addr add dead:1::99/64 dev eth0 -ip -net ${ns1} route add default via 10.0.1.1 -ip -net ${ns1} route add default via dead:1::1 - -ip -net ${ns2} addr add 10.0.2.99/24 dev eth0 -ip -net ${ns2} addr add dead:2::99/64 dev eth0 -ip -net ${ns2} route add default via 10.0.2.1 -ip -net ${ns2} route add default via dead:2::1 - -test_ping() { - local daddr4=$1 - local daddr6=$2 - - ip netns exec ${ns1} ping -c 1 -q $daddr4 > /dev/null - ret=$? - if [ $ret -ne 0 ];then - check_drops - echo "FAIL: ${ns1} cannot reach $daddr4, ret $ret" 1>&2 - return 1 - fi - - ip netns exec ${ns1} ping -c 3 -q $daddr6 > /dev/null - ret=$? - if [ $ret -ne 0 ];then - check_drops - echo "FAIL: ${ns1} cannot reach $daddr6, ret $ret" 1>&2 - return 1 - fi - - return 0 -} - -ip netns exec ${nsrouter} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null -ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null -ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null -ip netns exec ${nsrouter} sysctl net.ipv4.conf.all.rp_filter=0 > /dev/null -ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.rp_filter=0 > /dev/null - -sleep 3 - -test_ping 10.0.2.1 dead:2::1 || exit 1 -check_drops || exit 1 - -test_ping 10.0.2.99 dead:2::99 || exit 1 -check_drops || exit 1 - -echo "PASS: fib expression did not cause unwanted packet drops" - -ip netns exec ${nsrouter} nft flush table inet filter - -ip -net ${ns1} route del default -ip -net ${ns1} -6 route del default - -ip -net ${ns1} addr del 10.0.1.99/24 dev eth0 -ip -net ${ns1} addr del dead:1::99/64 dev eth0 - -ip -net ${ns1} addr add 10.0.2.99/24 dev eth0 -ip -net ${ns1} addr add dead:2::99/64 dev eth0 - -ip -net ${ns1} route add default via 10.0.2.1 -ip -net ${ns1} -6 route add default via dead:2::1 - -ip -net ${nsrouter} addr add dead:2::1/64 dev veth0 - -# switch to ruleset that doesn't log, this time -# its expected that this does drop the packets. -load_ruleset_count ${nsrouter} - -# ns1 has a default route, but nsrouter does not. -# must not check return value, ping to 1.1.1.1 will -# fail. -check_fib_counter 0 ${nsrouter} 1.1.1.1 || exit 1 -check_fib_counter 0 ${nsrouter} 1c3::c01d || exit 1 - -ip netns exec ${ns1} ping -c 1 -W 1 -q 1.1.1.1 > /dev/null -check_fib_counter 1 ${nsrouter} 1.1.1.1 || exit 1 - -sleep 2 -ip netns exec ${ns1} ping -c 3 -q 1c3::c01d > /dev/null -check_fib_counter 3 ${nsrouter} 1c3::c01d || exit 1 - -# delete all rules -ip netns exec ${ns1} nft flush ruleset -ip netns exec ${ns2} nft flush ruleset -ip netns exec ${nsrouter} nft flush ruleset - -ip -net ${ns1} addr add 10.0.1.99/24 dev eth0 -ip -net ${ns1} addr add dead:1::99/64 dev eth0 - -ip -net ${ns1} addr del 10.0.2.99/24 dev eth0 -ip -net ${ns1} addr del dead:2::99/64 dev eth0 - -ip -net ${nsrouter} addr del dead:2::1/64 dev veth0 - -# ... pbr ruleset for the router, check iif+oif. -load_pbr_ruleset ${nsrouter} -if [ $? -ne 0 ] ; then - echo "SKIP: Could not load fib forward ruleset" - exit $ksft_skip -fi - -ip -net ${nsrouter} rule add from all table 128 -ip -net ${nsrouter} rule add from all iif veth0 table 129 -ip -net ${nsrouter} route add table 128 to 10.0.1.0/24 dev veth0 -ip -net ${nsrouter} route add table 129 to 10.0.2.0/24 dev veth1 - -# drop main ipv4 table -ip -net ${nsrouter} -4 rule delete table main - -test_ping 10.0.2.99 dead:2::99 -if [ $? -ne 0 ] ; then - ip -net ${nsrouter} nft list ruleset - echo "FAIL: fib mismatch in pbr setup" - exit 1 -fi - -echo "PASS: fib expression forward check with policy based routing" -exit 0 diff --git a/tools/testing/selftests/netfilter/nft_flowtable.sh b/tools/testing/selftests/netfilter/nft_flowtable.sh deleted file mode 100755 index a32f490f7539..000000000000 --- a/tools/testing/selftests/netfilter/nft_flowtable.sh +++ /dev/null @@ -1,672 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 -# -# This tests basic flowtable functionality. -# Creates following default topology: -# -# Originator (MTU 9000) <-Router1-> MTU 1500 <-Router2-> Responder (MTU 2000) -# Router1 is the one doing flow offloading, Router2 has no special -# purpose other than having a link that is smaller than either Originator -# and responder, i.e. TCPMSS announced values are too large and will still -# result in fragmentation and/or PMTU discovery. -# -# You can check with different Orgininator/Link/Responder MTU eg: -# nft_flowtable.sh -o8000 -l1500 -r2000 -# - -sfx=$(mktemp -u "XXXXXXXX") -ns1="ns1-$sfx" -ns2="ns2-$sfx" -nsr1="nsr1-$sfx" -nsr2="nsr2-$sfx" - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -nsin="" -ns1out="" -ns2out="" - -log_netns=$(sysctl -n net.netfilter.nf_log_all_netns) - -checktool (){ - if ! $1 > /dev/null 2>&1; then - echo "SKIP: Could not $2" - exit $ksft_skip - fi -} - -checktool "nft --version" "run test without nft tool" -checktool "ip -Version" "run test without ip tool" -checktool "which nc" "run test without nc (netcat)" -checktool "ip netns add $nsr1" "create net namespace $nsr1" - -ip netns add $ns1 -ip netns add $ns2 -ip netns add $nsr2 - -cleanup() { - ip netns del $ns1 - ip netns del $ns2 - ip netns del $nsr1 - ip netns del $nsr2 - - rm -f "$nsin" "$ns1out" "$ns2out" - - [ $log_netns -eq 0 ] && sysctl -q net.netfilter.nf_log_all_netns=$log_netns -} - -trap cleanup EXIT - -sysctl -q net.netfilter.nf_log_all_netns=1 - -ip link add veth0 netns $nsr1 type veth peer name eth0 netns $ns1 -ip link add veth1 netns $nsr1 type veth peer name veth0 netns $nsr2 - -ip link add veth1 netns $nsr2 type veth peer name eth0 netns $ns2 - -for dev in lo veth0 veth1; do - ip -net $nsr1 link set $dev up - ip -net $nsr2 link set $dev up -done - -ip -net $nsr1 addr add 10.0.1.1/24 dev veth0 -ip -net $nsr1 addr add dead:1::1/64 dev veth0 - -ip -net $nsr2 addr add 10.0.2.1/24 dev veth1 -ip -net $nsr2 addr add dead:2::1/64 dev veth1 - -# set different MTUs so we need to push packets coming from ns1 (large MTU) -# to ns2 (smaller MTU) to stack either to perform fragmentation (ip_no_pmtu_disc=1), -# or to do PTMU discovery (send ICMP error back to originator). -# ns2 is going via nsr2 with a smaller mtu, so that TCPMSS announced by both peers -# is NOT the lowest link mtu. - -omtu=9000 -lmtu=1500 -rmtu=2000 - -usage(){ - echo "nft_flowtable.sh [OPTIONS]" - echo - echo "MTU options" - echo " -o originator" - echo " -l link" - echo " -r responder" - exit 1 -} - -while getopts "o:l:r:" o -do - case $o in - o) omtu=$OPTARG;; - l) lmtu=$OPTARG;; - r) rmtu=$OPTARG;; - *) usage;; - esac -done - -if ! ip -net $nsr1 link set veth0 mtu $omtu; then - exit 1 -fi - -ip -net $ns1 link set eth0 mtu $omtu - -if ! ip -net $nsr2 link set veth1 mtu $rmtu; then - exit 1 -fi - -ip -net $ns2 link set eth0 mtu $rmtu - -# transfer-net between nsr1 and nsr2. -# these addresses are not used for connections. -ip -net $nsr1 addr add 192.168.10.1/24 dev veth1 -ip -net $nsr1 addr add fee1:2::1/64 dev veth1 - -ip -net $nsr2 addr add 192.168.10.2/24 dev veth0 -ip -net $nsr2 addr add fee1:2::2/64 dev veth0 - -for i in 0 1; do - ip netns exec $nsr1 sysctl net.ipv4.conf.veth$i.forwarding=1 > /dev/null - ip netns exec $nsr2 sysctl net.ipv4.conf.veth$i.forwarding=1 > /dev/null -done - -for ns in $ns1 $ns2;do - ip -net $ns link set lo up - ip -net $ns link set eth0 up - - if ! ip netns exec $ns sysctl net.ipv4.tcp_no_metrics_save=1 > /dev/null; then - echo "ERROR: Check Originator/Responder values (problem during address addition)" - exit 1 - fi - # don't set ip DF bit for first two tests - ip netns exec $ns sysctl net.ipv4.ip_no_pmtu_disc=1 > /dev/null -done - -ip -net $ns1 addr add 10.0.1.99/24 dev eth0 -ip -net $ns2 addr add 10.0.2.99/24 dev eth0 -ip -net $ns1 route add default via 10.0.1.1 -ip -net $ns2 route add default via 10.0.2.1 -ip -net $ns1 addr add dead:1::99/64 dev eth0 -ip -net $ns2 addr add dead:2::99/64 dev eth0 -ip -net $ns1 route add default via dead:1::1 -ip -net $ns2 route add default via dead:2::1 - -ip -net $nsr1 route add default via 192.168.10.2 -ip -net $nsr2 route add default via 192.168.10.1 - -ip netns exec $nsr1 nft -f - <<EOF -table inet filter { - flowtable f1 { - hook ingress priority 0 - devices = { veth0, veth1 } - } - - counter routed_orig { } - counter routed_repl { } - - chain forward { - type filter hook forward priority 0; policy drop; - - # flow offloaded? Tag ct with mark 1, so we can detect when it fails. - meta oif "veth1" tcp dport 12345 ct mark set 1 flow add @f1 counter name routed_orig accept - - # count packets supposedly offloaded as per direction. - ct mark 1 counter name ct direction map { original : routed_orig, reply : routed_repl } accept - - ct state established,related accept - - meta nfproto ipv4 meta l4proto icmp accept - meta nfproto ipv6 meta l4proto icmpv6 accept - } -} -EOF - -if [ $? -ne 0 ]; then - echo "SKIP: Could not load nft ruleset" - exit $ksft_skip -fi - -ip netns exec $ns2 nft -f - <<EOF -table inet filter { - counter ip4dscp0 { } - counter ip4dscp3 { } - - chain input { - type filter hook input priority 0; policy accept; - meta l4proto tcp goto { - ip dscp cs3 counter name ip4dscp3 accept - ip dscp 0 counter name ip4dscp0 accept - } - } -} -EOF - -if [ $? -ne 0 ]; then - echo "SKIP: Could not load nft ruleset" - exit $ksft_skip -fi - -# test basic connectivity -if ! ip netns exec $ns1 ping -c 1 -q 10.0.2.99 > /dev/null; then - echo "ERROR: $ns1 cannot reach ns2" 1>&2 - exit 1 -fi - -if ! ip netns exec $ns2 ping -c 1 -q 10.0.1.99 > /dev/null; then - echo "ERROR: $ns2 cannot reach $ns1" 1>&2 - exit 1 -fi - -if [ $ret -eq 0 ];then - echo "PASS: netns routing/connectivity: $ns1 can reach $ns2" -fi - -nsin=$(mktemp) -ns1out=$(mktemp) -ns2out=$(mktemp) - -make_file() -{ - name=$1 - - SIZE=$((RANDOM % (1024 * 128))) - SIZE=$((SIZE + (1024 * 8))) - TSIZE=$((SIZE * 1024)) - - dd if=/dev/urandom of="$name" bs=1024 count=$SIZE 2> /dev/null - - SIZE=$((RANDOM % 1024)) - SIZE=$((SIZE + 128)) - TSIZE=$((TSIZE + SIZE)) - dd if=/dev/urandom conf=notrunc of="$name" bs=1 count=$SIZE 2> /dev/null -} - -check_counters() -{ - local what=$1 - local ok=1 - - local orig=$(ip netns exec $nsr1 nft reset counter inet filter routed_orig | grep packets) - local repl=$(ip netns exec $nsr1 nft reset counter inet filter routed_repl | grep packets) - - local orig_cnt=${orig#*bytes} - local repl_cnt=${repl#*bytes} - - local fs=$(du -sb $nsin) - local max_orig=${fs%%/*} - local max_repl=$((max_orig/4)) - - if [ $orig_cnt -gt $max_orig ];then - echo "FAIL: $what: original counter $orig_cnt exceeds expected value $max_orig" 1>&2 - ret=1 - ok=0 - fi - - if [ $repl_cnt -gt $max_repl ];then - echo "FAIL: $what: reply counter $repl_cnt exceeds expected value $max_repl" 1>&2 - ret=1 - ok=0 - fi - - if [ $ok -eq 1 ]; then - echo "PASS: $what" - fi -} - -check_dscp() -{ - local what=$1 - local ok=1 - - local counter=$(ip netns exec $ns2 nft reset counter inet filter ip4dscp3 | grep packets) - - local pc4=${counter%*bytes*} - local pc4=${pc4#*packets} - - local counter=$(ip netns exec $ns2 nft reset counter inet filter ip4dscp0 | grep packets) - local pc4z=${counter%*bytes*} - local pc4z=${pc4z#*packets} - - case "$what" in - "dscp_none") - if [ $pc4 -gt 0 ] || [ $pc4z -eq 0 ]; then - echo "FAIL: dscp counters do not match, expected dscp3 == 0, dscp0 > 0, but got $pc4,$pc4z" 1>&2 - ret=1 - ok=0 - fi - ;; - "dscp_fwd") - if [ $pc4 -eq 0 ] || [ $pc4z -eq 0 ]; then - echo "FAIL: dscp counters do not match, expected dscp3 and dscp0 > 0 but got $pc4,$pc4z" 1>&2 - ret=1 - ok=0 - fi - ;; - "dscp_ingress") - if [ $pc4 -eq 0 ] || [ $pc4z -gt 0 ]; then - echo "FAIL: dscp counters do not match, expected dscp3 > 0, dscp0 == 0 but got $pc4,$pc4z" 1>&2 - ret=1 - ok=0 - fi - ;; - "dscp_egress") - if [ $pc4 -eq 0 ] || [ $pc4z -gt 0 ]; then - echo "FAIL: dscp counters do not match, expected dscp3 > 0, dscp0 == 0 but got $pc4,$pc4z" 1>&2 - ret=1 - ok=0 - fi - ;; - *) - echo "FAIL: Unknown DSCP check" 1>&2 - ret=1 - ok=0 - esac - - if [ $ok -eq 1 ] ;then - echo "PASS: $what: dscp packet counters match" - fi -} - -check_transfer() -{ - in=$1 - out=$2 - what=$3 - - if ! cmp "$in" "$out" > /dev/null 2>&1; then - echo "FAIL: file mismatch for $what" 1>&2 - ls -l "$in" - ls -l "$out" - return 1 - fi - - return 0 -} - -test_tcp_forwarding_ip() -{ - local nsa=$1 - local nsb=$2 - local dstip=$3 - local dstport=$4 - local lret=0 - - ip netns exec $nsb nc -w 5 -l -p 12345 < "$nsin" > "$ns2out" & - lpid=$! - - sleep 1 - ip netns exec $nsa nc -w 4 "$dstip" "$dstport" < "$nsin" > "$ns1out" & - cpid=$! - - sleep 1 - - prev="$(ls -l $ns1out $ns2out)" - sleep 1 - - while [[ "$prev" != "$(ls -l $ns1out $ns2out)" ]]; do - sleep 1; - prev="$(ls -l $ns1out $ns2out)" - done - - if test -d /proc/"$lpid"/; then - kill $lpid - fi - - if test -d /proc/"$cpid"/; then - kill $cpid - fi - - wait $lpid - wait $cpid - - if ! check_transfer "$nsin" "$ns2out" "ns1 -> ns2"; then - lret=1 - fi - - if ! check_transfer "$nsin" "$ns1out" "ns1 <- ns2"; then - lret=1 - fi - - return $lret -} - -test_tcp_forwarding() -{ - test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 - - return $? -} - -test_tcp_forwarding_set_dscp() -{ - check_dscp "dscp_none" - -ip netns exec $nsr1 nft -f - <<EOF -table netdev dscpmangle { - chain setdscp0 { - type filter hook ingress device "veth0" priority 0; policy accept - ip dscp set cs3 - } -} -EOF -if [ $? -eq 0 ]; then - test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 - check_dscp "dscp_ingress" - - ip netns exec $nsr1 nft delete table netdev dscpmangle -else - echo "SKIP: Could not load netdev:ingress for veth0" -fi - -ip netns exec $nsr1 nft -f - <<EOF -table netdev dscpmangle { - chain setdscp0 { - type filter hook egress device "veth1" priority 0; policy accept - ip dscp set cs3 - } -} -EOF -if [ $? -eq 0 ]; then - test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 - check_dscp "dscp_egress" - - ip netns exec $nsr1 nft flush table netdev dscpmangle -else - echo "SKIP: Could not load netdev:egress for veth1" -fi - - # partial. If flowtable really works, then both dscp-is-0 and dscp-is-cs3 - # counters should have seen packets (before and after ft offload kicks in). - ip netns exec $nsr1 nft -a insert rule inet filter forward ip dscp set cs3 - test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 - check_dscp "dscp_fwd" -} - -test_tcp_forwarding_nat() -{ - local lret - local pmtu - - test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 - lret=$? - - pmtu=$3 - what=$4 - - if [ $lret -eq 0 ] ; then - if [ $pmtu -eq 1 ] ;then - check_counters "flow offload for ns1/ns2 with masquerade and pmtu discovery $what" - else - echo "PASS: flow offload for ns1/ns2 with masquerade $what" - fi - - test_tcp_forwarding_ip "$1" "$2" 10.6.6.6 1666 - lret=$? - if [ $pmtu -eq 1 ] ;then - check_counters "flow offload for ns1/ns2 with dnat and pmtu discovery $what" - elif [ $lret -eq 0 ] ; then - echo "PASS: flow offload for ns1/ns2 with dnat $what" - fi - fi - - return $lret -} - -make_file "$nsin" - -# First test: -# No PMTU discovery, nsr1 is expected to fragment packets from ns1 to ns2 as needed. -# Due to MTU mismatch in both directions, all packets (except small packets like pure -# acks) have to be handled by normal forwarding path. Therefore, packet counters -# are not checked. -if test_tcp_forwarding $ns1 $ns2; then - echo "PASS: flow offloaded for ns1/ns2" -else - echo "FAIL: flow offload for ns1/ns2:" 1>&2 - ip netns exec $nsr1 nft list ruleset - ret=1 -fi - -# delete default route, i.e. ns2 won't be able to reach ns1 and -# will depend on ns1 being masqueraded in nsr1. -# expect ns1 has nsr1 address. -ip -net $ns2 route del default via 10.0.2.1 -ip -net $ns2 route del default via dead:2::1 -ip -net $ns2 route add 192.168.10.1 via 10.0.2.1 - -# Second test: -# Same, but with NAT enabled. Same as in first test: we expect normal forward path -# to handle most packets. -ip netns exec $nsr1 nft -f - <<EOF -table ip nat { - chain prerouting { - type nat hook prerouting priority 0; policy accept; - meta iif "veth0" ip daddr 10.6.6.6 tcp dport 1666 counter dnat ip to 10.0.2.99:12345 - } - - chain postrouting { - type nat hook postrouting priority 0; policy accept; - meta oifname "veth1" counter masquerade - } -} -EOF - -if ! test_tcp_forwarding_set_dscp $ns1 $ns2 0 ""; then - echo "FAIL: flow offload for ns1/ns2 with dscp update" 1>&2 - exit 0 -fi - -if ! test_tcp_forwarding_nat $ns1 $ns2 0 ""; then - echo "FAIL: flow offload for ns1/ns2 with NAT" 1>&2 - ip netns exec $nsr1 nft list ruleset - ret=1 -fi - -# Third test: -# Same as second test, but with PMTU discovery enabled. This -# means that we expect the fastpath to handle packets as soon -# as the endpoints adjust the packet size. -ip netns exec $ns1 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null -ip netns exec $ns2 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null - -# reset counters. -# With pmtu in-place we'll also check that nft counters -# are lower than file size and packets were forwarded via flowtable layer. -# For earlier tests (large mtus), packets cannot be handled via flowtable -# (except pure acks and other small packets). -ip netns exec $nsr1 nft reset counters table inet filter >/dev/null - -if ! test_tcp_forwarding_nat $ns1 $ns2 1 ""; then - echo "FAIL: flow offload for ns1/ns2 with NAT and pmtu discovery" 1>&2 - ip netns exec $nsr1 nft list ruleset -fi - -# Another test: -# Add bridge interface br0 to Router1, with NAT enabled. -ip -net $nsr1 link add name br0 type bridge -ip -net $nsr1 addr flush dev veth0 -ip -net $nsr1 link set up dev veth0 -ip -net $nsr1 link set veth0 master br0 -ip -net $nsr1 addr add 10.0.1.1/24 dev br0 -ip -net $nsr1 addr add dead:1::1/64 dev br0 -ip -net $nsr1 link set up dev br0 - -ip netns exec $nsr1 sysctl net.ipv4.conf.br0.forwarding=1 > /dev/null - -# br0 with NAT enabled. -ip netns exec $nsr1 nft -f - <<EOF -flush table ip nat -table ip nat { - chain prerouting { - type nat hook prerouting priority 0; policy accept; - meta iif "br0" ip daddr 10.6.6.6 tcp dport 1666 counter dnat ip to 10.0.2.99:12345 - } - - chain postrouting { - type nat hook postrouting priority 0; policy accept; - meta oifname "veth1" counter masquerade - } -} -EOF - -if ! test_tcp_forwarding_nat $ns1 $ns2 1 "on bridge"; then - echo "FAIL: flow offload for ns1/ns2 with bridge NAT" 1>&2 - ip netns exec $nsr1 nft list ruleset - ret=1 -fi - - -# Another test: -# Add bridge interface br0 to Router1, with NAT and VLAN. -ip -net $nsr1 link set veth0 nomaster -ip -net $nsr1 link set down dev veth0 -ip -net $nsr1 link add link veth0 name veth0.10 type vlan id 10 -ip -net $nsr1 link set up dev veth0 -ip -net $nsr1 link set up dev veth0.10 -ip -net $nsr1 link set veth0.10 master br0 - -ip -net $ns1 addr flush dev eth0 -ip -net $ns1 link add link eth0 name eth0.10 type vlan id 10 -ip -net $ns1 link set eth0 up -ip -net $ns1 link set eth0.10 up -ip -net $ns1 addr add 10.0.1.99/24 dev eth0.10 -ip -net $ns1 route add default via 10.0.1.1 -ip -net $ns1 addr add dead:1::99/64 dev eth0.10 - -if ! test_tcp_forwarding_nat $ns1 $ns2 1 "bridge and VLAN"; then - echo "FAIL: flow offload for ns1/ns2 with bridge NAT and VLAN" 1>&2 - ip netns exec $nsr1 nft list ruleset - ret=1 -fi - -# restore test topology (remove bridge and VLAN) -ip -net $nsr1 link set veth0 nomaster -ip -net $nsr1 link set veth0 down -ip -net $nsr1 link set veth0.10 down -ip -net $nsr1 link delete veth0.10 type vlan -ip -net $nsr1 link delete br0 type bridge -ip -net $ns1 addr flush dev eth0.10 -ip -net $ns1 link set eth0.10 down -ip -net $ns1 link set eth0 down -ip -net $ns1 link delete eth0.10 type vlan - -# restore address in ns1 and nsr1 -ip -net $ns1 link set eth0 up -ip -net $ns1 addr add 10.0.1.99/24 dev eth0 -ip -net $ns1 route add default via 10.0.1.1 -ip -net $ns1 addr add dead:1::99/64 dev eth0 -ip -net $ns1 route add default via dead:1::1 -ip -net $nsr1 addr add 10.0.1.1/24 dev veth0 -ip -net $nsr1 addr add dead:1::1/64 dev veth0 -ip -net $nsr1 link set up dev veth0 - -KEY_SHA="0x"$(ps -af | sha1sum | cut -d " " -f 1) -KEY_AES="0x"$(ps -af | md5sum | cut -d " " -f 1) -SPI1=$RANDOM -SPI2=$RANDOM - -if [ $SPI1 -eq $SPI2 ]; then - SPI2=$((SPI2+1)) -fi - -do_esp() { - local ns=$1 - local me=$2 - local remote=$3 - local lnet=$4 - local rnet=$5 - local spi_out=$6 - local spi_in=$7 - - ip -net $ns xfrm state add src $remote dst $me proto esp spi $spi_in enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $rnet dst $lnet - ip -net $ns xfrm state add src $me dst $remote proto esp spi $spi_out enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $lnet dst $rnet - - # to encrypt packets as they go out (includes forwarded packets that need encapsulation) - ip -net $ns xfrm policy add src $lnet dst $rnet dir out tmpl src $me dst $remote proto esp mode tunnel priority 1 action allow - # to fwd decrypted packets after esp processing: - ip -net $ns xfrm policy add src $rnet dst $lnet dir fwd tmpl src $remote dst $me proto esp mode tunnel priority 1 action allow - -} - -do_esp $nsr1 192.168.10.1 192.168.10.2 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2 - -do_esp $nsr2 192.168.10.2 192.168.10.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1 - -ip netns exec $nsr1 nft delete table ip nat - -# restore default routes -ip -net $ns2 route del 192.168.10.1 via 10.0.2.1 -ip -net $ns2 route add default via 10.0.2.1 -ip -net $ns2 route add default via dead:2::1 - -if test_tcp_forwarding $ns1 $ns2; then - check_counters "ipsec tunnel mode for ns1/ns2" -else - echo "FAIL: ipsec tunnel mode for ns1/ns2" - ip netns exec $nsr1 nft list ruleset 1>&2 - ip netns exec $nsr1 cat /proc/net/xfrm_stat 1>&2 -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/nft_meta.sh b/tools/testing/selftests/netfilter/nft_meta.sh deleted file mode 100755 index f33154c04d34..000000000000 --- a/tools/testing/selftests/netfilter/nft_meta.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/bin/bash - -# check iif/iifname/oifgroup/iiftype match. - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -sfx=$(mktemp -u "XXXXXXXX") -ns0="ns0-$sfx" - -if ! nft --version > /dev/null 2>&1; then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -cleanup() -{ - ip netns del "$ns0" -} - -ip netns add "$ns0" -ip -net "$ns0" link set lo up -ip -net "$ns0" addr add 127.0.0.1 dev lo - -trap cleanup EXIT - -currentyear=$(date +%Y) -lastyear=$((currentyear-1)) -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table inet filter { - counter iifcount {} - counter iifnamecount {} - counter iifgroupcount {} - counter iiftypecount {} - counter infproto4count {} - counter il4protocounter {} - counter imarkcounter {} - counter icpu0counter {} - counter ilastyearcounter {} - counter icurrentyearcounter {} - - counter oifcount {} - counter oifnamecount {} - counter oifgroupcount {} - counter oiftypecount {} - counter onfproto4count {} - counter ol4protocounter {} - counter oskuidcounter {} - counter oskgidcounter {} - counter omarkcounter {} - - chain input { - type filter hook input priority 0; policy accept; - - meta iif lo counter name "iifcount" - meta iifname "lo" counter name "iifnamecount" - meta iifgroup "default" counter name "iifgroupcount" - meta iiftype "loopback" counter name "iiftypecount" - meta nfproto ipv4 counter name "infproto4count" - meta l4proto icmp counter name "il4protocounter" - meta mark 42 counter name "imarkcounter" - meta cpu 0 counter name "icpu0counter" - meta time "$lastyear-01-01" - "$lastyear-12-31" counter name ilastyearcounter - meta time "$currentyear-01-01" - "$currentyear-12-31" counter name icurrentyearcounter - } - - chain output { - type filter hook output priority 0; policy accept; - meta oif lo counter name "oifcount" counter - meta oifname "lo" counter name "oifnamecount" - meta oifgroup "default" counter name "oifgroupcount" - meta oiftype "loopback" counter name "oiftypecount" - meta nfproto ipv4 counter name "onfproto4count" - meta l4proto icmp counter name "ol4protocounter" - meta skuid 0 counter name "oskuidcounter" - meta skgid 0 counter name "oskgidcounter" - meta mark 42 counter name "omarkcounter" - } -} -EOF - -if [ $? -ne 0 ]; then - echo "SKIP: Could not add test ruleset" - exit $ksft_skip -fi - -ret=0 - -check_one_counter() -{ - local cname="$1" - local want="packets $2" - local verbose="$3" - - if ! ip netns exec "$ns0" nft list counter inet filter $cname | grep -q "$want"; then - echo "FAIL: $cname, want \"$want\", got" - ret=1 - ip netns exec "$ns0" nft list counter inet filter $cname - fi -} - -check_lo_counters() -{ - local want="$1" - local verbose="$2" - local counter - - for counter in iifcount iifnamecount iifgroupcount iiftypecount infproto4count \ - oifcount oifnamecount oifgroupcount oiftypecount onfproto4count \ - il4protocounter icurrentyearcounter ol4protocounter \ - ; do - check_one_counter "$counter" "$want" "$verbose" - done -} - -check_lo_counters "0" false -ip netns exec "$ns0" ping -q -c 1 127.0.0.1 -m 42 > /dev/null - -check_lo_counters "2" true - -check_one_counter oskuidcounter "1" true -check_one_counter oskgidcounter "1" true -check_one_counter imarkcounter "1" true -check_one_counter omarkcounter "1" true -check_one_counter ilastyearcounter "0" true - -if [ $ret -eq 0 ];then - echo "OK: nftables meta iif/oif counters at expected values" -else - exit $ret -fi - -#First CPU execution and counter -taskset -p 01 $$ > /dev/null -ip netns exec "$ns0" nft reset counters > /dev/null -ip netns exec "$ns0" ping -q -c 1 127.0.0.1 > /dev/null -check_one_counter icpu0counter "2" true - -if [ $ret -eq 0 ];then - echo "OK: nftables meta cpu counter at expected values" -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/nft_nat.sh b/tools/testing/selftests/netfilter/nft_nat.sh deleted file mode 100755 index dd40d9f6f259..000000000000 --- a/tools/testing/selftests/netfilter/nft_nat.sh +++ /dev/null @@ -1,1224 +0,0 @@ -#!/bin/bash -# -# This test is for basic NAT functionality: snat, dnat, redirect, masquerade. -# - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 -test_inet_nat=true - -sfx=$(mktemp -u "XXXXXXXX") -ns0="ns0-$sfx" -ns1="ns1-$sfx" -ns2="ns2-$sfx" - -cleanup() -{ - for i in 0 1 2; do ip netns del ns$i-"$sfx";done -} - -nft --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -ip netns add "$ns0" -if [ $? -ne 0 ];then - echo "SKIP: Could not create net namespace $ns0" - exit $ksft_skip -fi - -trap cleanup EXIT - -ip netns add "$ns1" -if [ $? -ne 0 ];then - echo "SKIP: Could not create net namespace $ns1" - exit $ksft_skip -fi - -ip netns add "$ns2" -if [ $? -ne 0 ];then - echo "SKIP: Could not create net namespace $ns2" - exit $ksft_skip -fi - -ip link add veth0 netns "$ns0" type veth peer name eth0 netns "$ns1" > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: No virtual ethernet pair device support in kernel" - exit $ksft_skip -fi -ip link add veth1 netns "$ns0" type veth peer name eth0 netns "$ns2" - -ip -net "$ns0" link set lo up -ip -net "$ns0" link set veth0 up -ip -net "$ns0" addr add 10.0.1.1/24 dev veth0 -ip -net "$ns0" addr add dead:1::1/64 dev veth0 - -ip -net "$ns0" link set veth1 up -ip -net "$ns0" addr add 10.0.2.1/24 dev veth1 -ip -net "$ns0" addr add dead:2::1/64 dev veth1 - -for i in 1 2; do - ip -net ns$i-$sfx link set lo up - ip -net ns$i-$sfx link set eth0 up - ip -net ns$i-$sfx addr add 10.0.$i.99/24 dev eth0 - ip -net ns$i-$sfx route add default via 10.0.$i.1 - ip -net ns$i-$sfx addr add dead:$i::99/64 dev eth0 - ip -net ns$i-$sfx route add default via dead:$i::1 -done - -bad_counter() -{ - local ns=$1 - local counter=$2 - local expect=$3 - local tag=$4 - - echo "ERROR: $counter counter in $ns has unexpected value (expected $expect) at $tag" 1>&2 - ip netns exec $ns nft list counter inet filter $counter 1>&2 -} - -check_counters() -{ - ns=$1 - local lret=0 - - cnt=$(ip netns exec $ns nft list counter inet filter ns0in | grep -q "packets 1 bytes 84") - if [ $? -ne 0 ]; then - bad_counter $ns ns0in "packets 1 bytes 84" "check_counters 1" - lret=1 - fi - cnt=$(ip netns exec $ns nft list counter inet filter ns0out | grep -q "packets 1 bytes 84") - if [ $? -ne 0 ]; then - bad_counter $ns ns0out "packets 1 bytes 84" "check_counters 2" - lret=1 - fi - - expect="packets 1 bytes 104" - cnt=$(ip netns exec $ns nft list counter inet filter ns0in6 | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter $ns ns0in6 "$expect" "check_counters 3" - lret=1 - fi - cnt=$(ip netns exec $ns nft list counter inet filter ns0out6 | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter $ns ns0out6 "$expect" "check_counters 4" - lret=1 - fi - - return $lret -} - -check_ns0_counters() -{ - local ns=$1 - local lret=0 - - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns0in | grep -q "packets 0 bytes 0") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns0in "packets 0 bytes 0" "check_ns0_counters 1" - lret=1 - fi - - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns0in6 | grep -q "packets 0 bytes 0") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns0in6 "packets 0 bytes 0" - lret=1 - fi - - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns0out | grep -q "packets 0 bytes 0") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns0out "packets 0 bytes 0" "check_ns0_counters 2" - lret=1 - fi - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns0out6 | grep -q "packets 0 bytes 0") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns0out6 "packets 0 bytes 0" "check_ns0_counters3 " - lret=1 - fi - - for dir in "in" "out" ; do - expect="packets 1 bytes 84" - cnt=$(ip netns exec "$ns0" nft list counter inet filter ${ns}${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" $ns$dir "$expect" "check_ns0_counters 4" - lret=1 - fi - - expect="packets 1 bytes 104" - cnt=$(ip netns exec "$ns0" nft list counter inet filter ${ns}${dir}6 | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" $ns$dir6 "$expect" "check_ns0_counters 5" - lret=1 - fi - done - - return $lret -} - -reset_counters() -{ - for i in 0 1 2;do - ip netns exec ns$i-$sfx nft reset counters inet > /dev/null - done -} - -test_local_dnat6() -{ - local family=$1 - local lret=0 - local IPF="" - - if [ $family = "inet" ];then - IPF="ip6" - fi - -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family nat { - chain output { - type nat hook output priority 0; policy accept; - ip6 daddr dead:1::99 dnat $IPF to dead:2::99 - } -} -EOF - if [ $? -ne 0 ]; then - echo "SKIP: Could not add add $family dnat hook" - return $ksft_skip - fi - - # ping netns1, expect rewrite to netns2 - ip netns exec "$ns0" ping -q -c 1 dead:1::99 > /dev/null - if [ $? -ne 0 ]; then - lret=1 - echo "ERROR: ping6 failed" - return $lret - fi - - expect="packets 0 bytes 0" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns1$dir "$expect" "test_local_dnat6 1" - lret=1 - fi - done - - expect="packets 1 bytes 104" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns2$dir "$expect" "test_local_dnat6 2" - lret=1 - fi - done - - # expect 0 count in ns1 - expect="packets 0 bytes 0" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns0${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_local_dnat6 3" - lret=1 - fi - done - - # expect 1 packet in ns2 - expect="packets 1 bytes 104" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns0${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns0$dir "$expect" "test_local_dnat6 4" - lret=1 - fi - done - - test $lret -eq 0 && echo "PASS: ipv6 ping to $ns1 was $family NATted to $ns2" - ip netns exec "$ns0" nft flush chain ip6 nat output - - return $lret -} - -test_local_dnat() -{ - local family=$1 - local lret=0 - local IPF="" - - if [ $family = "inet" ];then - IPF="ip" - fi - -ip netns exec "$ns0" nft -f /dev/stdin <<EOF 2>/dev/null -table $family nat { - chain output { - type nat hook output priority 0; policy accept; - ip daddr 10.0.1.99 dnat $IPF to 10.0.2.99 - } -} -EOF - if [ $? -ne 0 ]; then - if [ $family = "inet" ];then - echo "SKIP: inet nat tests" - test_inet_nat=false - return $ksft_skip - fi - echo "SKIP: Could not add add $family dnat hook" - return $ksft_skip - fi - - # ping netns1, expect rewrite to netns2 - ip netns exec "$ns0" ping -q -c 1 10.0.1.99 > /dev/null - if [ $? -ne 0 ]; then - lret=1 - echo "ERROR: ping failed" - return $lret - fi - - expect="packets 0 bytes 0" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns1$dir "$expect" "test_local_dnat 1" - lret=1 - fi - done - - expect="packets 1 bytes 84" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns2$dir "$expect" "test_local_dnat 2" - lret=1 - fi - done - - # expect 0 count in ns1 - expect="packets 0 bytes 0" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns0${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_local_dnat 3" - lret=1 - fi - done - - # expect 1 packet in ns2 - expect="packets 1 bytes 84" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns0${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns0$dir "$expect" "test_local_dnat 4" - lret=1 - fi - done - - test $lret -eq 0 && echo "PASS: ping to $ns1 was $family NATted to $ns2" - - ip netns exec "$ns0" nft flush chain $family nat output - - reset_counters - ip netns exec "$ns0" ping -q -c 1 10.0.1.99 > /dev/null - if [ $? -ne 0 ]; then - lret=1 - echo "ERROR: ping failed" - return $lret - fi - - expect="packets 1 bytes 84" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns1$dir "$expect" "test_local_dnat 5" - lret=1 - fi - done - expect="packets 0 bytes 0" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns2$dir "$expect" "test_local_dnat 6" - lret=1 - fi - done - - # expect 1 count in ns1 - expect="packets 1 bytes 84" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns0${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns0$dir "$expect" "test_local_dnat 7" - lret=1 - fi - done - - # expect 0 packet in ns2 - expect="packets 0 bytes 0" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns0${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns0$dir "$expect" "test_local_dnat 8" - lret=1 - fi - done - - test $lret -eq 0 && echo "PASS: ping to $ns1 OK after $family nat output chain flush" - - return $lret -} - -test_local_dnat_portonly() -{ - local family=$1 - local daddr=$2 - local lret=0 - local sr_s - local sr_r - -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family nat { - chain output { - type nat hook output priority 0; policy accept; - meta l4proto tcp dnat to :2000 - - } -} -EOF - if [ $? -ne 0 ]; then - if [ $family = "inet" ];then - echo "SKIP: inet port test" - test_inet_nat=false - return - fi - echo "SKIP: Could not add $family dnat hook" - return - fi - - echo SERVER-$family | ip netns exec "$ns1" timeout 5 socat -u STDIN TCP-LISTEN:2000 & - sc_s=$! - - sleep 1 - - result=$(ip netns exec "$ns0" timeout 1 socat TCP:$daddr:2000 STDOUT) - - if [ "$result" = "SERVER-inet" ];then - echo "PASS: inet port rewrite without l3 address" - else - echo "ERROR: inet port rewrite" - ret=1 - fi -} - -test_masquerade6() -{ - local family=$1 - local natflags=$2 - local lret=0 - - ip netns exec "$ns0" sysctl net.ipv6.conf.all.forwarding=1 > /dev/null - - ip netns exec "$ns2" ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2 via ipv6" - return 1 - lret=1 - fi - - expect="packets 1 bytes 104" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns2$dir "$expect" "test_masquerade6 1" - lret=1 - fi - - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns1$dir "$expect" "test_masquerade6 2" - lret=1 - fi - done - - reset_counters - -# add masquerading rule -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family nat { - chain postrouting { - type nat hook postrouting priority 0; policy accept; - meta oif veth0 masquerade $natflags - } -} -EOF - if [ $? -ne 0 ]; then - echo "SKIP: Could not add add $family masquerade hook" - return $ksft_skip - fi - - ip netns exec "$ns2" ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2 with active $family masquerade $natflags" - lret=1 - fi - - # ns1 should have seen packets from ns0, due to masquerade - expect="packets 1 bytes 104" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns0${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_masquerade6 3" - lret=1 - fi - - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns1$dir "$expect" "test_masquerade6 4" - lret=1 - fi - done - - # ns1 should not have seen packets from ns2, due to masquerade - expect="packets 0 bytes 0" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_masquerade6 5" - lret=1 - fi - - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns1$dir "$expect" "test_masquerade6 6" - lret=1 - fi - done - - ip netns exec "$ns2" ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2 with active ipv6 masquerade $natflags (attempt 2)" - lret=1 - fi - - ip netns exec "$ns0" nft flush chain $family nat postrouting - if [ $? -ne 0 ]; then - echo "ERROR: Could not flush $family nat postrouting" 1>&2 - lret=1 - fi - - test $lret -eq 0 && echo "PASS: $family IPv6 masquerade $natflags for $ns2" - - return $lret -} - -test_masquerade() -{ - local family=$1 - local natflags=$2 - local lret=0 - - ip netns exec "$ns0" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null - ip netns exec "$ns0" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null - - ip netns exec "$ns2" ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from "$ns2" $natflags" - lret=1 - fi - - expect="packets 1 bytes 84" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns2$dir "$expect" "test_masquerade 1" - lret=1 - fi - - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns1$dir "$expect" "test_masquerade 2" - lret=1 - fi - done - - reset_counters - -# add masquerading rule -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family nat { - chain postrouting { - type nat hook postrouting priority 0; policy accept; - meta oif veth0 masquerade $natflags - } -} -EOF - if [ $? -ne 0 ]; then - echo "SKIP: Could not add add $family masquerade hook" - return $ksft_skip - fi - - ip netns exec "$ns2" ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2 with active $family masquerade $natflags" - lret=1 - fi - - # ns1 should have seen packets from ns0, due to masquerade - expect="packets 1 bytes 84" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns0${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_masquerade 3" - lret=1 - fi - - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns1$dir "$expect" "test_masquerade 4" - lret=1 - fi - done - - # ns1 should not have seen packets from ns2, due to masquerade - expect="packets 0 bytes 0" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_masquerade 5" - lret=1 - fi - - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns1$dir "$expect" "test_masquerade 6" - lret=1 - fi - done - - ip netns exec "$ns2" ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2 with active ip masquerade $natflags (attempt 2)" - lret=1 - fi - - ip netns exec "$ns0" nft flush chain $family nat postrouting - if [ $? -ne 0 ]; then - echo "ERROR: Could not flush $family nat postrouting" 1>&2 - lret=1 - fi - - test $lret -eq 0 && echo "PASS: $family IP masquerade $natflags for $ns2" - - return $lret -} - -test_redirect6() -{ - local family=$1 - local lret=0 - - ip netns exec "$ns0" sysctl net.ipv6.conf.all.forwarding=1 > /dev/null - - ip netns exec "$ns2" ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannnot ping $ns1 from $ns2 via ipv6" - lret=1 - fi - - expect="packets 1 bytes 104" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns2$dir "$expect" "test_redirect6 1" - lret=1 - fi - - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns1$dir "$expect" "test_redirect6 2" - lret=1 - fi - done - - reset_counters - -# add redirect rule -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family nat { - chain prerouting { - type nat hook prerouting priority 0; policy accept; - meta iif veth1 meta l4proto icmpv6 ip6 saddr dead:2::99 ip6 daddr dead:1::99 redirect - } -} -EOF - if [ $? -ne 0 ]; then - echo "SKIP: Could not add add $family redirect hook" - return $ksft_skip - fi - - ip netns exec "$ns2" ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2 via ipv6 with active $family redirect" - lret=1 - fi - - # ns1 should have seen no packets from ns2, due to redirection - expect="packets 0 bytes 0" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_redirect6 3" - lret=1 - fi - done - - # ns0 should have seen packets from ns2, due to masquerade - expect="packets 1 bytes 104" - for dir in "in6" "out6" ; do - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_redirect6 4" - lret=1 - fi - done - - ip netns exec "$ns0" nft delete table $family nat - if [ $? -ne 0 ]; then - echo "ERROR: Could not delete $family nat table" 1>&2 - lret=1 - fi - - test $lret -eq 0 && echo "PASS: $family IPv6 redirection for $ns2" - - return $lret -} - -test_redirect() -{ - local family=$1 - local lret=0 - - ip netns exec "$ns0" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null - ip netns exec "$ns0" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null - - ip netns exec "$ns2" ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2" - lret=1 - fi - - expect="packets 1 bytes 84" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" $ns2$dir "$expect" "test_redirect 1" - lret=1 - fi - - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns1$dir "$expect" "test_redirect 2" - lret=1 - fi - done - - reset_counters - -# add redirect rule -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family nat { - chain prerouting { - type nat hook prerouting priority 0; policy accept; - meta iif veth1 ip protocol icmp ip saddr 10.0.2.99 ip daddr 10.0.1.99 redirect - } -} -EOF - if [ $? -ne 0 ]; then - echo "SKIP: Could not add add $family redirect hook" - return $ksft_skip - fi - - ip netns exec "$ns2" ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2 with active $family ip redirect" - lret=1 - fi - - # ns1 should have seen no packets from ns2, due to redirection - expect="packets 0 bytes 0" - for dir in "in" "out" ; do - - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_redirect 3" - lret=1 - fi - done - - # ns0 should have seen packets from ns2, due to masquerade - expect="packets 1 bytes 84" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns0$dir "$expect" "test_redirect 4" - lret=1 - fi - done - - ip netns exec "$ns0" nft delete table $family nat - if [ $? -ne 0 ]; then - echo "ERROR: Could not delete $family nat table" 1>&2 - lret=1 - fi - - test $lret -eq 0 && echo "PASS: $family IP redirection for $ns2" - - return $lret -} - -# test port shadowing. -# create two listening services, one on router (ns0), one -# on client (ns2), which is masqueraded from ns1 point of view. -# ns2 sends udp packet coming from service port to ns1, on a highport. -# Later, if n1 uses same highport to connect to ns0:service, packet -# might be port-forwarded to ns2 instead. - -# second argument tells if we expect the 'fake-entry' to take effect -# (CLIENT) or not (ROUTER). -test_port_shadow() -{ - local test=$1 - local expect=$2 - local daddrc="10.0.1.99" - local daddrs="10.0.1.1" - local result="" - local logmsg="" - - # make shadow entry, from client (ns2), going to (ns1), port 41404, sport 1405. - echo "fake-entry" | ip netns exec "$ns2" timeout 1 socat -u STDIN UDP:"$daddrc":41404,sourceport=1405 - - echo ROUTER | ip netns exec "$ns0" timeout 5 socat -u STDIN UDP4-LISTEN:1405 & - sc_r=$! - - echo CLIENT | ip netns exec "$ns2" timeout 5 socat -u STDIN UDP4-LISTEN:1405,reuseport & - sc_c=$! - - sleep 0.3 - - # ns1 tries to connect to ns0:1405. With default settings this should connect - # to client, it matches the conntrack entry created above. - - result=$(echo "data" | ip netns exec "$ns1" timeout 1 socat - UDP:"$daddrs":1405,sourceport=41404) - - if [ "$result" = "$expect" ] ;then - echo "PASS: portshadow test $test: got reply from ${expect}${logmsg}" - else - echo "ERROR: portshadow test $test: got reply from \"$result\", not $expect as intended" - ret=1 - fi - - kill $sc_r $sc_c 2>/dev/null - - # flush udp entries for next test round, if any - ip netns exec "$ns0" conntrack -F >/dev/null 2>&1 -} - -# This prevents port shadow of router service via packet filter, -# packets claiming to originate from service port from internal -# network are dropped. -test_port_shadow_filter() -{ - local family=$1 - -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family filter { - chain forward { - type filter hook forward priority 0; policy accept; - meta iif veth1 udp sport 1405 drop - } -} -EOF - test_port_shadow "port-filter" "ROUTER" - - ip netns exec "$ns0" nft delete table $family filter -} - -# This prevents port shadow of router service via notrack. -test_port_shadow_notrack() -{ - local family=$1 - -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family raw { - chain prerouting { - type filter hook prerouting priority -300; policy accept; - meta iif veth0 udp dport 1405 notrack - } - chain output { - type filter hook output priority -300; policy accept; - meta oif veth0 udp sport 1405 notrack - } -} -EOF - test_port_shadow "port-notrack" "ROUTER" - - ip netns exec "$ns0" nft delete table $family raw -} - -# This prevents port shadow of router service via sport remap. -test_port_shadow_pat() -{ - local family=$1 - -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family pat { - chain postrouting { - type nat hook postrouting priority -1; policy accept; - meta iif veth1 udp sport <= 1405 masquerade to : 1406-65535 random - } -} -EOF - test_port_shadow "pat" "ROUTER" - - ip netns exec "$ns0" nft delete table $family pat -} - -test_port_shadowing() -{ - local family="ip" - - conntrack -h >/dev/null 2>&1 - if [ $? -ne 0 ];then - echo "SKIP: Could not run nat port shadowing test without conntrack tool" - return - fi - - socat -h > /dev/null 2>&1 - if [ $? -ne 0 ];then - echo "SKIP: Could not run nat port shadowing test without socat tool" - return - fi - - ip netns exec "$ns0" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null - ip netns exec "$ns0" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null - - ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table $family nat { - chain postrouting { - type nat hook postrouting priority 0; policy accept; - meta oif veth0 masquerade - } -} -EOF - if [ $? -ne 0 ]; then - echo "SKIP: Could not add add $family masquerade hook" - return $ksft_skip - fi - - # test default behaviour. Packet from ns1 to ns0 is redirected to ns2. - test_port_shadow "default" "CLIENT" - - # test packet filter based mitigation: prevent forwarding of - # packets claiming to come from the service port. - test_port_shadow_filter "$family" - - # test conntrack based mitigation: connections going or coming - # from router:service bypass connection tracking. - test_port_shadow_notrack "$family" - - # test nat based mitigation: fowarded packets coming from service port - # are masqueraded with random highport. - test_port_shadow_pat "$family" - - ip netns exec "$ns0" nft delete table $family nat -} - -test_stateless_nat_ip() -{ - local lret=0 - - ip netns exec "$ns0" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null - ip netns exec "$ns0" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null - - ip netns exec "$ns2" ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2 before loading stateless rules" - return 1 - fi - -ip netns exec "$ns0" nft -f /dev/stdin <<EOF -table ip stateless { - map xlate_in { - typeof meta iifname . ip saddr . ip daddr : ip daddr - elements = { - "veth1" . 10.0.2.99 . 10.0.1.99 : 10.0.2.2, - } - } - map xlate_out { - typeof meta iifname . ip saddr . ip daddr : ip daddr - elements = { - "veth0" . 10.0.1.99 . 10.0.2.2 : 10.0.2.99 - } - } - - chain prerouting { - type filter hook prerouting priority -400; policy accept; - ip saddr set meta iifname . ip saddr . ip daddr map @xlate_in - ip daddr set meta iifname . ip saddr . ip daddr map @xlate_out - } -} -EOF - if [ $? -ne 0 ]; then - echo "SKIP: Could not add ip statless rules" - return $ksft_skip - fi - - reset_counters - - ip netns exec "$ns2" ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 - if [ $? -ne 0 ] ; then - echo "ERROR: cannot ping $ns1 from $ns2 with stateless rules" - lret=1 - fi - - # ns1 should have seen packets from .2.2, due to stateless rewrite. - expect="packets 1 bytes 84" - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns0insl | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0insl "$expect" "test_stateless 1" - lret=1 - fi - - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns2" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns2" ns1$dir "$expect" "test_stateless 2" - lret=1 - fi - done - - # ns1 should not have seen packets from ns2, due to masquerade - expect="packets 0 bytes 0" - for dir in "in" "out" ; do - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns2${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0$dir "$expect" "test_stateless 3" - lret=1 - fi - - cnt=$(ip netns exec "$ns0" nft list counter inet filter ns1${dir} | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns0" ns1$dir "$expect" "test_stateless 4" - lret=1 - fi - done - - reset_counters - - socat -h > /dev/null 2>&1 - if [ $? -ne 0 ];then - echo "SKIP: Could not run stateless nat frag test without socat tool" - if [ $lret -eq 0 ]; then - return $ksft_skip - fi - - ip netns exec "$ns0" nft delete table ip stateless - return $lret - fi - - local tmpfile=$(mktemp) - dd if=/dev/urandom of=$tmpfile bs=4096 count=1 2>/dev/null - - local outfile=$(mktemp) - ip netns exec "$ns1" timeout 3 socat -u UDP4-RECV:4233 OPEN:$outfile < /dev/null & - sc_r=$! - - sleep 1 - # re-do with large ping -> ip fragmentation - ip netns exec "$ns2" timeout 3 socat - UDP4-SENDTO:"10.0.1.99:4233" < "$tmpfile" > /dev/null - if [ $? -ne 0 ] ; then - echo "ERROR: failed to test udp $ns1 to $ns2 with stateless ip nat" 1>&2 - lret=1 - fi - - wait - - cmp "$tmpfile" "$outfile" - if [ $? -ne 0 ]; then - ls -l "$tmpfile" "$outfile" - echo "ERROR: in and output file mismatch when checking udp with stateless nat" 1>&2 - lret=1 - fi - - rm -f "$tmpfile" "$outfile" - - # ns1 should have seen packets from 2.2, due to stateless rewrite. - expect="packets 3 bytes 4164" - cnt=$(ip netns exec "$ns1" nft list counter inet filter ns0insl | grep -q "$expect") - if [ $? -ne 0 ]; then - bad_counter "$ns1" ns0insl "$expect" "test_stateless 5" - lret=1 - fi - - ip netns exec "$ns0" nft delete table ip stateless - if [ $? -ne 0 ]; then - echo "ERROR: Could not delete table ip stateless" 1>&2 - lret=1 - fi - - test $lret -eq 0 && echo "PASS: IP statless for $ns2" - - return $lret -} - -# ip netns exec "$ns0" ping -c 1 -q 10.0.$i.99 -for i in 0 1 2; do -ip netns exec ns$i-$sfx nft -f /dev/stdin <<EOF -table inet filter { - counter ns0in {} - counter ns1in {} - counter ns2in {} - - counter ns0out {} - counter ns1out {} - counter ns2out {} - - counter ns0in6 {} - counter ns1in6 {} - counter ns2in6 {} - - counter ns0out6 {} - counter ns1out6 {} - counter ns2out6 {} - - map nsincounter { - type ipv4_addr : counter - elements = { 10.0.1.1 : "ns0in", - 10.0.2.1 : "ns0in", - 10.0.1.99 : "ns1in", - 10.0.2.99 : "ns2in" } - } - - map nsincounter6 { - type ipv6_addr : counter - elements = { dead:1::1 : "ns0in6", - dead:2::1 : "ns0in6", - dead:1::99 : "ns1in6", - dead:2::99 : "ns2in6" } - } - - map nsoutcounter { - type ipv4_addr : counter - elements = { 10.0.1.1 : "ns0out", - 10.0.2.1 : "ns0out", - 10.0.1.99: "ns1out", - 10.0.2.99: "ns2out" } - } - - map nsoutcounter6 { - type ipv6_addr : counter - elements = { dead:1::1 : "ns0out6", - dead:2::1 : "ns0out6", - dead:1::99 : "ns1out6", - dead:2::99 : "ns2out6" } - } - - chain input { - type filter hook input priority 0; policy accept; - counter name ip saddr map @nsincounter - icmpv6 type { "echo-request", "echo-reply" } counter name ip6 saddr map @nsincounter6 - } - chain output { - type filter hook output priority 0; policy accept; - counter name ip daddr map @nsoutcounter - icmpv6 type { "echo-request", "echo-reply" } counter name ip6 daddr map @nsoutcounter6 - } -} -EOF -done - -# special case for stateless nat check, counter needs to -# be done before (input) ip defragmentation -ip netns exec ns1-$sfx nft -f /dev/stdin <<EOF -table inet filter { - counter ns0insl {} - - chain pre { - type filter hook prerouting priority -400; policy accept; - ip saddr 10.0.2.2 counter name "ns0insl" - } -} -EOF - -sleep 3 -# test basic connectivity -for i in 1 2; do - ip netns exec "$ns0" ping -c 1 -q 10.0.$i.99 > /dev/null - if [ $? -ne 0 ];then - echo "ERROR: Could not reach other namespace(s)" 1>&2 - ret=1 - fi - - ip netns exec "$ns0" ping -c 1 -q dead:$i::99 > /dev/null - if [ $? -ne 0 ];then - echo "ERROR: Could not reach other namespace(s) via ipv6" 1>&2 - ret=1 - fi - check_counters ns$i-$sfx - if [ $? -ne 0 ]; then - ret=1 - fi - - check_ns0_counters ns$i - if [ $? -ne 0 ]; then - ret=1 - fi - reset_counters -done - -if [ $ret -eq 0 ];then - echo "PASS: netns routing/connectivity: $ns0 can reach $ns1 and $ns2" -fi - -reset_counters -test_local_dnat ip -test_local_dnat6 ip6 - -reset_counters -test_local_dnat_portonly inet 10.0.1.99 - -reset_counters -$test_inet_nat && test_local_dnat inet -$test_inet_nat && test_local_dnat6 inet - -for flags in "" "fully-random"; do -reset_counters -test_masquerade ip $flags -test_masquerade6 ip6 $flags -reset_counters -$test_inet_nat && test_masquerade inet $flags -$test_inet_nat && test_masquerade6 inet $flags -done - -reset_counters -test_redirect ip -test_redirect6 ip6 -reset_counters -$test_inet_nat && test_redirect inet -$test_inet_nat && test_redirect6 inet - -test_port_shadowing -test_stateless_nat_ip - -if [ $ret -ne 0 ];then - echo -n "FAIL: " - nft --version -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/nft_nat_zones.sh b/tools/testing/selftests/netfilter/nft_nat_zones.sh deleted file mode 100755 index b9ab37380f33..000000000000 --- a/tools/testing/selftests/netfilter/nft_nat_zones.sh +++ /dev/null @@ -1,309 +0,0 @@ -#!/bin/bash -# -# Test connection tracking zone and NAT source port reallocation support. -# - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 - -# Don't increase too much, 2000 clients should work -# just fine but script can then take several minutes with -# KASAN/debug builds. -maxclients=100 - -have_iperf=1 -ret=0 - -# client1---. -# veth1-. -# | -# NAT Gateway --veth0--> Server -# | | -# veth2-' | -# client2---' | -# .... | -# clientX----vethX---' - -# All clients share identical IP address. -# NAT Gateway uses policy routing and conntrack zones to isolate client -# namespaces. Each client connects to Server, each with colliding tuples: -# clientsaddr:10000 -> serveraddr:dport -# NAT Gateway is supposed to do port reallocation for each of the -# connections. - -sfx=$(mktemp -u "XXXXXXXX") -gw="ns-gw-$sfx" -cl1="ns-cl1-$sfx" -cl2="ns-cl2-$sfx" -srv="ns-srv-$sfx" - -v4gc1=$(sysctl -n net.ipv4.neigh.default.gc_thresh1 2>/dev/null) -v4gc2=$(sysctl -n net.ipv4.neigh.default.gc_thresh2 2>/dev/null) -v4gc3=$(sysctl -n net.ipv4.neigh.default.gc_thresh3 2>/dev/null) -v6gc1=$(sysctl -n net.ipv6.neigh.default.gc_thresh1 2>/dev/null) -v6gc2=$(sysctl -n net.ipv6.neigh.default.gc_thresh2 2>/dev/null) -v6gc3=$(sysctl -n net.ipv6.neigh.default.gc_thresh3 2>/dev/null) - -cleanup() -{ - ip netns del $gw - ip netns del $srv - for i in $(seq 1 $maxclients); do - ip netns del ns-cl$i-$sfx 2>/dev/null - done - - sysctl -q net.ipv4.neigh.default.gc_thresh1=$v4gc1 2>/dev/null - sysctl -q net.ipv4.neigh.default.gc_thresh2=$v4gc2 2>/dev/null - sysctl -q net.ipv4.neigh.default.gc_thresh3=$v4gc3 2>/dev/null - sysctl -q net.ipv6.neigh.default.gc_thresh1=$v6gc1 2>/dev/null - sysctl -q net.ipv6.neigh.default.gc_thresh2=$v6gc2 2>/dev/null - sysctl -q net.ipv6.neigh.default.gc_thresh3=$v6gc3 2>/dev/null -} - -nft --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -conntrack -V > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without conntrack tool" - exit $ksft_skip -fi - -iperf3 -v >/dev/null 2>&1 -if [ $? -ne 0 ];then - have_iperf=0 -fi - -ip netns add "$gw" -if [ $? -ne 0 ];then - echo "SKIP: Could not create net namespace $gw" - exit $ksft_skip -fi -ip -net "$gw" link set lo up - -trap cleanup EXIT - -ip netns add "$srv" -if [ $? -ne 0 ];then - echo "SKIP: Could not create server netns $srv" - exit $ksft_skip -fi - -ip link add veth0 netns "$gw" type veth peer name eth0 netns "$srv" -ip -net "$gw" link set veth0 up -ip -net "$srv" link set lo up -ip -net "$srv" link set eth0 up - -sysctl -q net.ipv6.neigh.default.gc_thresh1=512 2>/dev/null -sysctl -q net.ipv6.neigh.default.gc_thresh2=1024 2>/dev/null -sysctl -q net.ipv6.neigh.default.gc_thresh3=4096 2>/dev/null -sysctl -q net.ipv4.neigh.default.gc_thresh1=512 2>/dev/null -sysctl -q net.ipv4.neigh.default.gc_thresh2=1024 2>/dev/null -sysctl -q net.ipv4.neigh.default.gc_thresh3=4096 2>/dev/null - -for i in $(seq 1 $maxclients);do - cl="ns-cl$i-$sfx" - - ip netns add "$cl" - if [ $? -ne 0 ];then - echo "SKIP: Could not create client netns $cl" - exit $ksft_skip - fi - ip link add veth$i netns "$gw" type veth peer name eth0 netns "$cl" > /dev/null 2>&1 - if [ $? -ne 0 ];then - echo "SKIP: No virtual ethernet pair device support in kernel" - exit $ksft_skip - fi -done - -for i in $(seq 1 $maxclients);do - cl="ns-cl$i-$sfx" - echo netns exec "$cl" ip link set lo up - echo netns exec "$cl" ip link set eth0 up - echo netns exec "$cl" sysctl -q net.ipv4.tcp_syn_retries=2 - echo netns exec "$gw" ip link set veth$i up - echo netns exec "$gw" sysctl -q net.ipv4.conf.veth$i.arp_ignore=2 - echo netns exec "$gw" sysctl -q net.ipv4.conf.veth$i.rp_filter=0 - - # clients have same IP addresses. - echo netns exec "$cl" ip addr add 10.1.0.3/24 dev eth0 - echo netns exec "$cl" ip addr add dead:1::3/64 dev eth0 - echo netns exec "$cl" ip route add default via 10.1.0.2 dev eth0 - echo netns exec "$cl" ip route add default via dead:1::2 dev eth0 - - # NB: same addresses on client-facing interfaces. - echo netns exec "$gw" ip addr add 10.1.0.2/24 dev veth$i - echo netns exec "$gw" ip addr add dead:1::2/64 dev veth$i - - # gw: policy routing - echo netns exec "$gw" ip route add 10.1.0.0/24 dev veth$i table $((1000+i)) - echo netns exec "$gw" ip route add dead:1::0/64 dev veth$i table $((1000+i)) - echo netns exec "$gw" ip route add 10.3.0.0/24 dev veth0 table $((1000+i)) - echo netns exec "$gw" ip route add dead:3::0/64 dev veth0 table $((1000+i)) - echo netns exec "$gw" ip rule add fwmark $i lookup $((1000+i)) -done | ip -batch /dev/stdin - -ip -net "$gw" addr add 10.3.0.1/24 dev veth0 -ip -net "$gw" addr add dead:3::1/64 dev veth0 - -ip -net "$srv" addr add 10.3.0.99/24 dev eth0 -ip -net "$srv" addr add dead:3::99/64 dev eth0 - -ip netns exec $gw nft -f /dev/stdin<<EOF -table inet raw { - map iiftomark { - type ifname : mark - } - - map iiftozone { - typeof iifname : ct zone - } - - set inicmp { - flags dynamic - type ipv4_addr . ifname . ipv4_addr - } - set inflows { - flags dynamic - type ipv4_addr . inet_service . ifname . ipv4_addr . inet_service - } - - set inflows6 { - flags dynamic - type ipv6_addr . inet_service . ifname . ipv6_addr . inet_service - } - - chain prerouting { - type filter hook prerouting priority -64000; policy accept; - ct original zone set meta iifname map @iiftozone - meta mark set meta iifname map @iiftomark - - tcp flags & (syn|ack) == ack add @inflows { ip saddr . tcp sport . meta iifname . ip daddr . tcp dport counter } - add @inflows6 { ip6 saddr . tcp sport . meta iifname . ip6 daddr . tcp dport counter } - ip protocol icmp add @inicmp { ip saddr . meta iifname . ip daddr counter } - } - - chain nat_postrouting { - type nat hook postrouting priority 0; policy accept; - ct mark set meta mark meta oifname veth0 masquerade - } - - chain mangle_prerouting { - type filter hook prerouting priority -100; policy accept; - ct direction reply meta mark set ct mark - } -} -EOF - -( echo add element inet raw iiftomark \{ - for i in $(seq 1 $((maxclients-1))); do - echo \"veth$i\" : $i, - done - echo \"veth$maxclients\" : $maxclients \} - echo add element inet raw iiftozone \{ - for i in $(seq 1 $((maxclients-1))); do - echo \"veth$i\" : $i, - done - echo \"veth$maxclients\" : $maxclients \} -) | ip netns exec $gw nft -f /dev/stdin - -ip netns exec "$gw" sysctl -q net.ipv4.conf.all.forwarding=1 > /dev/null -ip netns exec "$gw" sysctl -q net.ipv6.conf.all.forwarding=1 > /dev/null -ip netns exec "$gw" sysctl -q net.ipv4.conf.all.rp_filter=0 >/dev/null - -# useful for debugging: allows to use 'ping' from clients to gateway. -ip netns exec "$gw" sysctl -q net.ipv4.fwmark_reflect=1 > /dev/null -ip netns exec "$gw" sysctl -q net.ipv6.fwmark_reflect=1 > /dev/null - -for i in $(seq 1 $maxclients); do - cl="ns-cl$i-$sfx" - ip netns exec $cl ping -i 0.5 -q -c 3 10.3.0.99 > /dev/null 2>&1 & - if [ $? -ne 0 ]; then - echo FAIL: Ping failure from $cl 1>&2 - ret=1 - break - fi -done - -wait - -for i in $(seq 1 $maxclients); do - ip netns exec $gw nft get element inet raw inicmp "{ 10.1.0.3 . \"veth$i\" . 10.3.0.99 }" | grep -q "{ 10.1.0.3 . \"veth$i\" . 10.3.0.99 counter packets 3 bytes 252 }" - if [ $? -ne 0 ];then - ret=1 - echo "FAIL: counter icmp mismatch for veth$i" 1>&2 - ip netns exec $gw nft get element inet raw inicmp "{ 10.1.0.3 . \"veth$i\" . 10.3.0.99 }" 1>&2 - break - fi -done - -ip netns exec $gw nft get element inet raw inicmp "{ 10.3.0.99 . \"veth0\" . 10.3.0.1 }" | grep -q "{ 10.3.0.99 . \"veth0\" . 10.3.0.1 counter packets $((3 * $maxclients)) bytes $((252 * $maxclients)) }" -if [ $? -ne 0 ];then - ret=1 - echo "FAIL: counter icmp mismatch for veth0: { 10.3.0.99 . \"veth0\" . 10.3.0.1 counter packets $((3 * $maxclients)) bytes $((252 * $maxclients)) }" - ip netns exec $gw nft get element inet raw inicmp "{ 10.3.99 . \"veth0\" . 10.3.0.1 }" 1>&2 -fi - -if [ $ret -eq 0 ]; then - echo "PASS: ping test from all $maxclients namespaces" -fi - -if [ $have_iperf -eq 0 ];then - echo "SKIP: iperf3 not installed" - if [ $ret -ne 0 ];then - exit $ret - fi - exit $ksft_skip -fi - -ip netns exec $srv iperf3 -s > /dev/null 2>&1 & -iperfpid=$! -sleep 1 - -for i in $(seq 1 $maxclients); do - if [ $ret -ne 0 ]; then - break - fi - cl="ns-cl$i-$sfx" - ip netns exec $cl iperf3 -c 10.3.0.99 --cport 10000 -n 1 > /dev/null - if [ $? -ne 0 ]; then - echo FAIL: Failure to connect for $cl 1>&2 - ip netns exec $gw conntrack -S 1>&2 - ret=1 - fi -done -if [ $ret -eq 0 ];then - echo "PASS: iperf3 connections for all $maxclients net namespaces" -fi - -kill $iperfpid -wait - -for i in $(seq 1 $maxclients); do - ip netns exec $gw nft get element inet raw inflows "{ 10.1.0.3 . 10000 . \"veth$i\" . 10.3.0.99 . 5201 }" > /dev/null - if [ $? -ne 0 ];then - ret=1 - echo "FAIL: can't find expected tcp entry for veth$i" 1>&2 - break - fi -done -if [ $ret -eq 0 ];then - echo "PASS: Found client connection for all $maxclients net namespaces" -fi - -ip netns exec $gw nft get element inet raw inflows "{ 10.3.0.99 . 5201 . \"veth0\" . 10.3.0.1 . 10000 }" > /dev/null -if [ $? -ne 0 ];then - ret=1 - echo "FAIL: cannot find return entry on veth0" 1>&2 -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/nft_queue.sh b/tools/testing/selftests/netfilter/nft_queue.sh deleted file mode 100755 index e12729753351..000000000000 --- a/tools/testing/selftests/netfilter/nft_queue.sh +++ /dev/null @@ -1,449 +0,0 @@ -#!/bin/bash -# -# This tests nf_queue: -# 1. can process packets from all hooks -# 2. support running nfqueue from more than one base chain -# -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -sfx=$(mktemp -u "XXXXXXXX") -ns1="ns1-$sfx" -ns2="ns2-$sfx" -nsrouter="nsrouter-$sfx" -timeout=4 - -cleanup() -{ - ip netns pids ${ns1} | xargs kill 2>/dev/null - ip netns pids ${ns2} | xargs kill 2>/dev/null - ip netns pids ${nsrouter} | xargs kill 2>/dev/null - - ip netns del ${ns1} - ip netns del ${ns2} - ip netns del ${nsrouter} - rm -f "$TMPFILE0" - rm -f "$TMPFILE1" - rm -f "$TMPFILE2" "$TMPFILE3" -} - -nft --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -ip netns add ${nsrouter} -if [ $? -ne 0 ];then - echo "SKIP: Could not create net namespace" - exit $ksft_skip -fi - -TMPFILE0=$(mktemp) -TMPFILE1=$(mktemp) -TMPFILE2=$(mktemp) -TMPFILE3=$(mktemp) -trap cleanup EXIT - -ip netns add ${ns1} -ip netns add ${ns2} - -ip link add veth0 netns ${nsrouter} type veth peer name eth0 netns ${ns1} > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: No virtual ethernet pair device support in kernel" - exit $ksft_skip -fi -ip link add veth1 netns ${nsrouter} type veth peer name eth0 netns ${ns2} - -ip -net ${nsrouter} link set lo up -ip -net ${nsrouter} link set veth0 up -ip -net ${nsrouter} addr add 10.0.1.1/24 dev veth0 -ip -net ${nsrouter} addr add dead:1::1/64 dev veth0 - -ip -net ${nsrouter} link set veth1 up -ip -net ${nsrouter} addr add 10.0.2.1/24 dev veth1 -ip -net ${nsrouter} addr add dead:2::1/64 dev veth1 - -ip -net ${ns1} link set lo up -ip -net ${ns1} link set eth0 up - -ip -net ${ns2} link set lo up -ip -net ${ns2} link set eth0 up - -ip -net ${ns1} addr add 10.0.1.99/24 dev eth0 -ip -net ${ns1} addr add dead:1::99/64 dev eth0 -ip -net ${ns1} route add default via 10.0.1.1 -ip -net ${ns1} route add default via dead:1::1 - -ip -net ${ns2} addr add 10.0.2.99/24 dev eth0 -ip -net ${ns2} addr add dead:2::99/64 dev eth0 -ip -net ${ns2} route add default via 10.0.2.1 -ip -net ${ns2} route add default via dead:2::1 - -load_ruleset() { - local name=$1 - local prio=$2 - -ip netns exec ${nsrouter} nft -f /dev/stdin <<EOF -table inet $name { - chain nfq { - ip protocol icmp queue bypass - icmpv6 type { "echo-request", "echo-reply" } queue num 1 bypass - } - chain pre { - type filter hook prerouting priority $prio; policy accept; - jump nfq - } - chain input { - type filter hook input priority $prio; policy accept; - jump nfq - } - chain forward { - type filter hook forward priority $prio; policy accept; - tcp dport 12345 queue num 2 - jump nfq - } - chain output { - type filter hook output priority $prio; policy accept; - tcp dport 12345 queue num 3 - tcp sport 23456 queue num 3 - jump nfq - } - chain post { - type filter hook postrouting priority $prio; policy accept; - jump nfq - } -} -EOF -} - -load_counter_ruleset() { - local prio=$1 - -ip netns exec ${nsrouter} nft -f /dev/stdin <<EOF -table inet countrules { - chain pre { - type filter hook prerouting priority $prio; policy accept; - counter - } - chain input { - type filter hook input priority $prio; policy accept; - counter - } - chain forward { - type filter hook forward priority $prio; policy accept; - counter - } - chain output { - type filter hook output priority $prio; policy accept; - counter - } - chain post { - type filter hook postrouting priority $prio; policy accept; - counter - } -} -EOF -} - -test_ping() { - ip netns exec ${ns1} ping -c 1 -q 10.0.2.99 > /dev/null - if [ $? -ne 0 ];then - return 1 - fi - - ip netns exec ${ns1} ping -c 1 -q dead:2::99 > /dev/null - if [ $? -ne 0 ];then - return 1 - fi - - return 0 -} - -test_ping_router() { - ip netns exec ${ns1} ping -c 1 -q 10.0.2.1 > /dev/null - if [ $? -ne 0 ];then - return 1 - fi - - ip netns exec ${ns1} ping -c 1 -q dead:2::1 > /dev/null - if [ $? -ne 0 ];then - return 1 - fi - - return 0 -} - -test_queue_blackhole() { - local proto=$1 - -ip netns exec ${nsrouter} nft -f /dev/stdin <<EOF -table $proto blackh { - chain forward { - type filter hook forward priority 0; policy accept; - queue num 600 - } -} -EOF - if [ $proto = "ip" ] ;then - ip netns exec ${ns1} ping -W 2 -c 1 -q 10.0.2.99 > /dev/null - lret=$? - elif [ $proto = "ip6" ]; then - ip netns exec ${ns1} ping -W 2 -c 1 -q dead:2::99 > /dev/null - lret=$? - else - lret=111 - fi - - # queue without bypass keyword should drop traffic if no listener exists. - if [ $lret -eq 0 ];then - echo "FAIL: $proto expected failure, got $lret" 1>&2 - exit 1 - fi - - ip netns exec ${nsrouter} nft delete table $proto blackh - if [ $? -ne 0 ] ;then - echo "FAIL: $proto: Could not delete blackh table" - exit 1 - fi - - echo "PASS: $proto: statement with no listener results in packet drop" -} - -test_queue() -{ - local expected=$1 - local last="" - - # spawn nf-queue listeners - ip netns exec ${nsrouter} ./nf-queue -c -q 0 -t $timeout > "$TMPFILE0" & - ip netns exec ${nsrouter} ./nf-queue -c -q 1 -t $timeout > "$TMPFILE1" & - sleep 1 - test_ping - ret=$? - if [ $ret -ne 0 ];then - echo "FAIL: netns routing/connectivity with active listener on queue $queue: $ret" 1>&2 - exit $ret - fi - - test_ping_router - ret=$? - if [ $ret -ne 0 ];then - echo "FAIL: netns router unreachable listener on queue $queue: $ret" 1>&2 - exit $ret - fi - - wait - ret=$? - - for file in $TMPFILE0 $TMPFILE1; do - last=$(tail -n1 "$file") - if [ x"$last" != x"$expected packets total" ]; then - echo "FAIL: Expected $expected packets total, but got $last" 1>&2 - cat "$file" 1>&2 - - ip netns exec ${nsrouter} nft list ruleset - exit 1 - fi - done - - echo "PASS: Expected and received $last" -} - -test_tcp_forward() -{ - ip netns exec ${nsrouter} ./nf-queue -q 2 -t $timeout & - local nfqpid=$! - - tmpfile=$(mktemp) || exit 1 - dd conv=sparse status=none if=/dev/zero bs=1M count=200 of=$tmpfile - ip netns exec ${ns2} nc -w 5 -l -p 12345 <"$tmpfile" >/dev/null & - local rpid=$! - - sleep 1 - ip netns exec ${ns1} nc -w 5 10.0.2.99 12345 <"$tmpfile" >/dev/null & - - rm -f "$tmpfile" - - wait $rpid - wait $lpid - [ $? -eq 0 ] && echo "PASS: tcp and nfqueue in forward chain" -} - -test_tcp_localhost() -{ - tmpfile=$(mktemp) || exit 1 - - dd conv=sparse status=none if=/dev/zero bs=1M count=200 of=$tmpfile - ip netns exec ${nsrouter} nc -w 5 -l -p 12345 <"$tmpfile" >/dev/null & - local rpid=$! - - ip netns exec ${nsrouter} ./nf-queue -q 3 -t $timeout & - local nfqpid=$! - - sleep 1 - ip netns exec ${nsrouter} nc -w 5 127.0.0.1 12345 <"$tmpfile" > /dev/null - rm -f "$tmpfile" - - wait $rpid - [ $? -eq 0 ] && echo "PASS: tcp via loopback" - wait 2>/dev/null -} - -test_tcp_localhost_connectclose() -{ - tmpfile=$(mktemp) || exit 1 - - ip netns exec ${nsrouter} ./connect_close -p 23456 -t $timeout & - - ip netns exec ${nsrouter} ./nf-queue -q 3 -t $timeout & - local nfqpid=$! - - sleep 1 - rm -f "$tmpfile" - - wait $rpid - [ $? -eq 0 ] && echo "PASS: tcp via loopback with connect/close" - wait 2>/dev/null -} - -test_tcp_localhost_requeue() -{ -ip netns exec ${nsrouter} nft -f /dev/stdin <<EOF -flush ruleset -table inet filter { - chain output { - type filter hook output priority 0; policy accept; - tcp dport 12345 limit rate 1/second burst 1 packets counter queue num 0 - } - chain post { - type filter hook postrouting priority 0; policy accept; - tcp dport 12345 limit rate 1/second burst 1 packets counter queue num 0 - } -} -EOF - tmpfile=$(mktemp) || exit 1 - dd conv=sparse status=none if=/dev/zero bs=1M count=200 of=$tmpfile - ip netns exec ${nsrouter} nc -w 5 -l -p 12345 <"$tmpfile" >/dev/null & - local rpid=$! - - ip netns exec ${nsrouter} ./nf-queue -c -q 1 -t $timeout > "$TMPFILE2" & - - # nfqueue 1 will be called via output hook. But this time, - # re-queue the packet to nfqueue program on queue 2. - ip netns exec ${nsrouter} ./nf-queue -G -d 150 -c -q 0 -Q 1 -t $timeout > "$TMPFILE3" & - - sleep 1 - ip netns exec ${nsrouter} nc -w 5 127.0.0.1 12345 <"$tmpfile" > /dev/null - rm -f "$tmpfile" - - wait - - if ! diff -u "$TMPFILE2" "$TMPFILE3" ; then - echo "FAIL: lost packets during requeue?!" 1>&2 - return - fi - - echo "PASS: tcp via loopback and re-queueing" -} - -test_icmp_vrf() { - ip -net $ns1 link add tvrf type vrf table 9876 - if [ $? -ne 0 ];then - echo "SKIP: Could not add vrf device" - return - fi - - ip -net $ns1 li set eth0 master tvrf - ip -net $ns1 li set tvrf up - - ip -net $ns1 route add 10.0.2.0/24 via 10.0.1.1 dev eth0 table 9876 -ip netns exec ${ns1} nft -f /dev/stdin <<EOF -flush ruleset -table inet filter { - chain output { - type filter hook output priority 0; policy accept; - meta oifname "tvrf" icmp type echo-request counter queue num 1 - meta oifname "eth0" icmp type echo-request counter queue num 1 - } - chain post { - type filter hook postrouting priority 0; policy accept; - meta oifname "tvrf" icmp type echo-request counter queue num 1 - meta oifname "eth0" icmp type echo-request counter queue num 1 - } -} -EOF - ip netns exec ${ns1} ./nf-queue -q 1 -t $timeout & - local nfqpid=$! - - sleep 1 - ip netns exec ${ns1} ip vrf exec tvrf ping -c 1 10.0.2.99 > /dev/null - - for n in output post; do - for d in tvrf eth0; do - ip netns exec ${ns1} nft list chain inet filter $n | grep -q "oifname \"$d\" icmp type echo-request counter packets 1" - if [ $? -ne 0 ] ; then - echo "FAIL: chain $n: icmp packet counter mismatch for device $d" 1>&2 - ip netns exec ${ns1} nft list ruleset - ret=1 - return - fi - done - done - - wait $nfqpid - [ $? -eq 0 ] && echo "PASS: icmp+nfqueue via vrf" - wait 2>/dev/null -} - -ip netns exec ${nsrouter} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null -ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null -ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null - -load_ruleset "filter" 0 - -sleep 3 - -test_ping -ret=$? -if [ $ret -eq 0 ];then - # queue bypass works (rules were skipped, no listener) - echo "PASS: ${ns1} can reach ${ns2}" -else - echo "FAIL: ${ns1} cannot reach ${ns2}: $ret" 1>&2 - exit $ret -fi - -test_queue_blackhole ip -test_queue_blackhole ip6 - -# dummy ruleset to add base chains between the -# queueing rules. We don't want the second reinject -# to re-execute the old hooks. -load_counter_ruleset 10 - -# we are hooking all: prerouting/input/forward/output/postrouting. -# we ping ${ns2} from ${ns1} via ${nsrouter} using ipv4 and ipv6, so: -# 1x icmp prerouting,forward,postrouting -> 3 queue events (6 incl. reply). -# 1x icmp prerouting,input,output postrouting -> 4 queue events incl. reply. -# so we expect that userspace program receives 10 packets. -test_queue 10 - -# same. We queue to a second program as well. -load_ruleset "filter2" 20 -test_queue 20 - -test_tcp_forward -test_tcp_localhost -test_tcp_localhost_connectclose -test_tcp_localhost_requeue -test_icmp_vrf - -exit $ret diff --git a/tools/testing/selftests/netfilter/nft_synproxy.sh b/tools/testing/selftests/netfilter/nft_synproxy.sh deleted file mode 100755 index b62933b680d6..000000000000 --- a/tools/testing/selftests/netfilter/nft_synproxy.sh +++ /dev/null @@ -1,117 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 -# - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 -ret=0 - -rnd=$(mktemp -u XXXXXXXX) -nsr="nsr-$rnd" # synproxy machine -ns1="ns1-$rnd" # iperf client -ns2="ns2-$rnd" # iperf server - -checktool (){ - if ! $1 > /dev/null 2>&1; then - echo "SKIP: Could not $2" - exit $ksft_skip - fi -} - -checktool "nft --version" "run test without nft tool" -checktool "ip -Version" "run test without ip tool" -checktool "iperf3 --version" "run test without iperf3" -checktool "ip netns add $nsr" "create net namespace" - -modprobe -q nf_conntrack - -ip netns add $ns1 -ip netns add $ns2 - -cleanup() { - ip netns pids $ns1 | xargs kill 2>/dev/null - ip netns pids $ns2 | xargs kill 2>/dev/null - ip netns del $ns1 - ip netns del $ns2 - - ip netns del $nsr -} - -trap cleanup EXIT - -ip link add veth0 netns $nsr type veth peer name eth0 netns $ns1 -ip link add veth1 netns $nsr type veth peer name eth0 netns $ns2 - -for dev in lo veth0 veth1; do -ip -net $nsr link set $dev up -done - -ip -net $nsr addr add 10.0.1.1/24 dev veth0 -ip -net $nsr addr add 10.0.2.1/24 dev veth1 - -ip netns exec $nsr sysctl -q net.ipv4.conf.veth0.forwarding=1 -ip netns exec $nsr sysctl -q net.ipv4.conf.veth1.forwarding=1 -ip netns exec $nsr sysctl -q net.netfilter.nf_conntrack_tcp_loose=0 - -for n in $ns1 $ns2; do - ip -net $n link set lo up - ip -net $n link set eth0 up -done -ip -net $ns1 addr add 10.0.1.99/24 dev eth0 -ip -net $ns2 addr add 10.0.2.99/24 dev eth0 -ip -net $ns1 route add default via 10.0.1.1 -ip -net $ns2 route add default via 10.0.2.1 - -# test basic connectivity -if ! ip netns exec $ns1 ping -c 1 -q 10.0.2.99 > /dev/null; then - echo "ERROR: $ns1 cannot reach $ns2" 1>&2 - exit 1 -fi - -if ! ip netns exec $ns2 ping -c 1 -q 10.0.1.99 > /dev/null; then - echo "ERROR: $ns2 cannot reach $ns1" 1>&2 - exit 1 -fi - -ip netns exec $ns2 iperf3 -s > /dev/null 2>&1 & -# ip netns exec $nsr tcpdump -vvv -n -i veth1 tcp | head -n 10 & - -sleep 1 - -ip netns exec $nsr nft -f - <<EOF -table inet filter { - chain prerouting { - type filter hook prerouting priority -300; policy accept; - meta iif veth0 tcp flags syn counter notrack - } - - chain forward { - type filter hook forward priority 0; policy accept; - - ct state new,established counter accept - - meta iif veth0 meta l4proto tcp ct state untracked,invalid synproxy mss 1460 sack-perm timestamp - - ct state invalid counter drop - - # make ns2 unreachable w.o. tcp synproxy - tcp flags syn counter drop - } -} -EOF -if [ $? -ne 0 ]; then - echo "SKIP: Cannot add nft synproxy" - exit $ksft_skip -fi - -ip netns exec $ns1 timeout 5 iperf3 -c 10.0.2.99 -n $((1 * 1024 * 1024)) > /dev/null - -if [ $? -ne 0 ]; then - echo "FAIL: iperf3 returned an error" 1>&2 - ret=$? - ip netns exec $nsr nft list ruleset -else - echo "PASS: synproxy connection successful" -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/nft_trans_stress.sh b/tools/testing/selftests/netfilter/nft_trans_stress.sh deleted file mode 100755 index 2ffba45a78bf..000000000000 --- a/tools/testing/selftests/netfilter/nft_trans_stress.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/bin/bash -# -# This test is for stress-testing the nf_tables config plane path vs. -# packet path processing: Make sure we never release rules that are -# still visible to other cpus. -# -# set -e - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 - -testns=testns-$(mktemp -u "XXXXXXXX") -tmp="" - -tables="foo bar baz quux" -global_ret=0 -eret=0 -lret=0 - -cleanup() { - ip netns pids "$testns" | xargs kill 2>/dev/null - ip netns del "$testns" - - rm -f "$tmp" -} - -check_result() -{ - local r=$1 - local OK="PASS" - - if [ $r -ne 0 ] ;then - OK="FAIL" - global_ret=$r - fi - - echo "$OK: nft $2 test returned $r" - - eret=0 -} - -nft --version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without nft tool" - exit $ksft_skip -fi - -ip -Version > /dev/null 2>&1 -if [ $? -ne 0 ];then - echo "SKIP: Could not run test without ip tool" - exit $ksft_skip -fi - -trap cleanup EXIT -tmp=$(mktemp) - -for table in $tables; do - echo add table inet "$table" >> "$tmp" - echo flush table inet "$table" >> "$tmp" - - echo "add chain inet $table INPUT { type filter hook input priority 0; }" >> "$tmp" - echo "add chain inet $table OUTPUT { type filter hook output priority 0; }" >> "$tmp" - for c in $(seq 1 400); do - chain=$(printf "chain%03u" "$c") - echo "add chain inet $table $chain" >> "$tmp" - done - - for c in $(seq 1 400); do - chain=$(printf "chain%03u" "$c") - for BASE in INPUT OUTPUT; do - echo "add rule inet $table $BASE counter jump $chain" >> "$tmp" - done - echo "add rule inet $table $chain counter return" >> "$tmp" - done -done - -ip netns add "$testns" -ip -netns "$testns" link set lo up - -lscpu | grep ^CPU\(s\): | ( read cpu cpunum ; -cpunum=$((cpunum-1)) -for i in $(seq 0 $cpunum);do - mask=$(printf 0x%x $((1<<$i))) - ip netns exec "$testns" taskset $mask ping -4 127.0.0.1 -fq > /dev/null & - ip netns exec "$testns" taskset $mask ping -6 ::1 -fq > /dev/null & -done) - -sleep 1 - -ip netns exec "$testns" nft -f "$tmp" -for i in $(seq 1 10) ; do ip netns exec "$testns" nft -f "$tmp" & done - -for table in $tables;do - randsleep=$((RANDOM%2)) - sleep $randsleep - ip netns exec "$testns" nft delete table inet $table - lret=$? - if [ $lret -ne 0 ]; then - eret=$lret - fi -done - -check_result $eret "add/delete" - -for i in $(seq 1 10) ; do - (echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin - - lret=$? - if [ $lret -ne 0 ]; then - eret=$lret - fi -done - -check_result $eret "reload" - -for i in $(seq 1 10) ; do - (echo "flush ruleset"; cat "$tmp" - echo "insert rule inet foo INPUT meta nftrace set 1" - echo "insert rule inet foo OUTPUT meta nftrace set 1" - ) | ip netns exec "$testns" nft -f /dev/stdin - lret=$? - if [ $lret -ne 0 ]; then - eret=$lret - fi - - (echo "flush ruleset"; cat "$tmp" - ) | ip netns exec "$testns" nft -f /dev/stdin - - lret=$? - if [ $lret -ne 0 ]; then - eret=$lret - fi -done - -check_result $eret "add/delete with nftrace enabled" - -echo "insert rule inet foo INPUT meta nftrace set 1" >> $tmp -echo "insert rule inet foo OUTPUT meta nftrace set 1" >> $tmp - -for i in $(seq 1 10) ; do - (echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin - - lret=$? - if [ $lret -ne 0 ]; then - eret=1 - fi -done - -check_result $lret "add/delete with nftrace enabled" - -exit $global_ret diff --git a/tools/testing/selftests/netfilter/nft_zones_many.sh b/tools/testing/selftests/netfilter/nft_zones_many.sh deleted file mode 100755 index 5a8db0b48928..000000000000 --- a/tools/testing/selftests/netfilter/nft_zones_many.sh +++ /dev/null @@ -1,163 +0,0 @@ -#!/bin/bash - -# Test insertion speed for packets with identical addresses/ports -# that are all placed in distinct conntrack zones. - -sfx=$(mktemp -u "XXXXXXXX") -ns="ns-$sfx" - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 - -zones=2000 -have_ct_tool=0 -ret=0 - -cleanup() -{ - ip netns del $ns -} - -checktool (){ - if ! $1 > /dev/null 2>&1; then - echo "SKIP: Could not $2" - exit $ksft_skip - fi -} - -checktool "nft --version" "run test without nft tool" -checktool "ip -Version" "run test without ip tool" -checktool "socat -V" "run test without socat tool" -checktool "ip netns add $ns" "create net namespace" - -trap cleanup EXIT - -conntrack -V > /dev/null 2>&1 -if [ $? -eq 0 ];then - have_ct_tool=1 -fi - -ip -net "$ns" link set lo up - -test_zones() { - local max_zones=$1 - -ip netns exec $ns sysctl -q net.netfilter.nf_conntrack_udp_timeout=3600 -ip netns exec $ns nft -f /dev/stdin<<EOF -flush ruleset -table inet raw { - map rndzone { - typeof numgen inc mod $max_zones : ct zone - } - - chain output { - type filter hook output priority -64000; policy accept; - udp dport 12345 ct zone set numgen inc mod 65536 map @rndzone - } -} -EOF - ( - echo "add element inet raw rndzone {" - for i in $(seq 1 $max_zones);do - echo -n "$i : $i" - if [ $i -lt $max_zones ]; then - echo "," - else - echo "}" - fi - done - ) | ip netns exec $ns nft -f /dev/stdin - - local i=0 - local j=0 - local outerstart=$(date +%s%3N) - local stop=$outerstart - - while [ $i -lt $max_zones ]; do - local start=$(date +%s%3N) - i=$((i + 1000)) - j=$((j + 1)) - # nft rule in output places each packet in a different zone. - dd if=/dev/zero of=/dev/stdout bs=8k count=1000 2>/dev/null | ip netns exec "$ns" socat STDIN UDP:127.0.0.1:12345,sourceport=12345 - if [ $? -ne 0 ] ;then - ret=1 - break - fi - - stop=$(date +%s%3N) - local duration=$((stop-start)) - echo "PASS: added 1000 entries in $duration ms (now $i total, loop $j)" - done - - if [ $have_ct_tool -eq 1 ]; then - local count=$(ip netns exec "$ns" conntrack -C) - local duration=$((stop-outerstart)) - - if [ $count -eq $max_zones ]; then - echo "PASS: inserted $count entries from packet path in $duration ms total" - else - ip netns exec $ns conntrack -S 1>&2 - echo "FAIL: inserted $count entries from packet path in $duration ms total, expected $max_zones entries" - ret=1 - fi - fi - - if [ $ret -ne 0 ];then - echo "FAIL: insert $max_zones entries from packet path" 1>&2 - fi -} - -test_conntrack_tool() { - local max_zones=$1 - - ip netns exec $ns conntrack -F >/dev/null 2>/dev/null - - local outerstart=$(date +%s%3N) - local start=$(date +%s%3N) - local stop=$start - local i=0 - while [ $i -lt $max_zones ]; do - i=$((i + 1)) - ip netns exec "$ns" conntrack -I -s 1.1.1.1 -d 2.2.2.2 --protonum 6 \ - --timeout 3600 --state ESTABLISHED --sport 12345 --dport 1000 --zone $i >/dev/null 2>&1 - if [ $? -ne 0 ];then - ip netns exec "$ns" conntrack -I -s 1.1.1.1 -d 2.2.2.2 --protonum 6 \ - --timeout 3600 --state ESTABLISHED --sport 12345 --dport 1000 --zone $i > /dev/null - echo "FAIL: conntrack -I returned an error" - ret=1 - break - fi - - if [ $((i%1000)) -eq 0 ];then - stop=$(date +%s%3N) - - local duration=$((stop-start)) - echo "PASS: added 1000 entries in $duration ms (now $i total)" - start=$stop - fi - done - - local count=$(ip netns exec "$ns" conntrack -C) - local duration=$((stop-outerstart)) - - if [ $count -eq $max_zones ]; then - echo "PASS: inserted $count entries via ctnetlink in $duration ms" - else - ip netns exec $ns conntrack -S 1>&2 - echo "FAIL: inserted $count entries via ctnetlink in $duration ms, expected $max_zones entries ($duration ms)" - ret=1 - fi -} - -test_zones $zones - -if [ $have_ct_tool -eq 1 ];then - test_conntrack_tool $zones -else - echo "SKIP: Could not run ctnetlink insertion test without conntrack tool" - if [ $ret -eq 0 ];then - exit $ksft_skip - fi -fi - -exit $ret diff --git a/tools/testing/selftests/netfilter/rpath.sh b/tools/testing/selftests/netfilter/rpath.sh deleted file mode 100755 index 5289c8447a41..000000000000 --- a/tools/testing/selftests/netfilter/rpath.sh +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 - -# return code to signal skipped test -ksft_skip=4 - -# search for legacy iptables (it uses the xtables extensions -if iptables-legacy --version >/dev/null 2>&1; then - iptables='iptables-legacy' -elif iptables --version >/dev/null 2>&1; then - iptables='iptables' -else - iptables='' -fi - -if ip6tables-legacy --version >/dev/null 2>&1; then - ip6tables='ip6tables-legacy' -elif ip6tables --version >/dev/null 2>&1; then - ip6tables='ip6tables' -else - ip6tables='' -fi - -if nft --version >/dev/null 2>&1; then - nft='nft' -else - nft='' -fi - -if [ -z "$iptables$ip6tables$nft" ]; then - echo "SKIP: Test needs iptables, ip6tables or nft" - exit $ksft_skip -fi - -sfx=$(mktemp -u "XXXXXXXX") -ns1="ns1-$sfx" -ns2="ns2-$sfx" -trap "ip netns del $ns1; ip netns del $ns2" EXIT - -# create two netns, disable rp_filter in ns2 and -# keep IPv6 address when moving into VRF -ip netns add "$ns1" -ip netns add "$ns2" -ip netns exec "$ns2" sysctl -q net.ipv4.conf.all.rp_filter=0 -ip netns exec "$ns2" sysctl -q net.ipv4.conf.default.rp_filter=0 -ip netns exec "$ns2" sysctl -q net.ipv6.conf.all.keep_addr_on_down=1 - -# a standard connection between the netns, should not trigger rp filter -ip -net "$ns1" link add v0 type veth peer name v0 netns "$ns2" -ip -net "$ns1" link set v0 up; ip -net "$ns2" link set v0 up -ip -net "$ns1" a a 192.168.23.2/24 dev v0 -ip -net "$ns2" a a 192.168.23.1/24 dev v0 -ip -net "$ns1" a a fec0:23::2/64 dev v0 nodad -ip -net "$ns2" a a fec0:23::1/64 dev v0 nodad - -# rp filter testing: ns1 sends packets via v0 which ns2 would route back via d0 -ip -net "$ns2" link add d0 type dummy -ip -net "$ns2" link set d0 up -ip -net "$ns1" a a 192.168.42.2/24 dev v0 -ip -net "$ns2" a a 192.168.42.1/24 dev d0 -ip -net "$ns1" a a fec0:42::2/64 dev v0 nodad -ip -net "$ns2" a a fec0:42::1/64 dev d0 nodad - -# firewall matches to test -[ -n "$iptables" ] && { - common='-t raw -A PREROUTING -s 192.168.0.0/16' - ip netns exec "$ns2" "$iptables" $common -m rpfilter - ip netns exec "$ns2" "$iptables" $common -m rpfilter --invert -} -[ -n "$ip6tables" ] && { - common='-t raw -A PREROUTING -s fec0::/16' - ip netns exec "$ns2" "$ip6tables" $common -m rpfilter - ip netns exec "$ns2" "$ip6tables" $common -m rpfilter --invert -} -[ -n "$nft" ] && ip netns exec "$ns2" $nft -f - <<EOF -table inet t { - chain c { - type filter hook prerouting priority raw; - ip saddr 192.168.0.0/16 fib saddr . iif oif exists counter - ip6 saddr fec0::/16 fib saddr . iif oif exists counter - } -} -EOF - -die() { - echo "FAIL: $*" - #ip netns exec "$ns2" "$iptables" -t raw -vS - #ip netns exec "$ns2" "$ip6tables" -t raw -vS - #ip netns exec "$ns2" nft list ruleset - exit 1 -} - -# check rule counters, return true if rule did not match -ipt_zero_rule() { # (command) - [ -n "$1" ] || return 0 - ip netns exec "$ns2" "$1" -t raw -vS | grep -q -- "-m rpfilter -c 0 0" -} -ipt_zero_reverse_rule() { # (command) - [ -n "$1" ] || return 0 - ip netns exec "$ns2" "$1" -t raw -vS | \ - grep -q -- "-m rpfilter --invert -c 0 0" -} -nft_zero_rule() { # (family) - [ -n "$nft" ] || return 0 - ip netns exec "$ns2" "$nft" list chain inet t c | \ - grep -q "$1 saddr .* counter packets 0 bytes 0" -} - -netns_ping() { # (netns, args...) - local netns="$1" - shift - ip netns exec "$netns" ping -q -c 1 -W 1 "$@" >/dev/null -} - -clear_counters() { - [ -n "$iptables" ] && ip netns exec "$ns2" "$iptables" -t raw -Z - [ -n "$ip6tables" ] && ip netns exec "$ns2" "$ip6tables" -t raw -Z - if [ -n "$nft" ]; then - ( - echo "delete table inet t"; - ip netns exec "$ns2" $nft -s list table inet t; - ) | ip netns exec "$ns2" $nft -f - - fi -} - -testrun() { - clear_counters - - # test 1: martian traffic should fail rpfilter matches - netns_ping "$ns1" -I v0 192.168.42.1 && \ - die "martian ping 192.168.42.1 succeeded" - netns_ping "$ns1" -I v0 fec0:42::1 && \ - die "martian ping fec0:42::1 succeeded" - - ipt_zero_rule "$iptables" || die "iptables matched martian" - ipt_zero_rule "$ip6tables" || die "ip6tables matched martian" - ipt_zero_reverse_rule "$iptables" && die "iptables not matched martian" - ipt_zero_reverse_rule "$ip6tables" && die "ip6tables not matched martian" - nft_zero_rule ip || die "nft IPv4 matched martian" - nft_zero_rule ip6 || die "nft IPv6 matched martian" - - clear_counters - - # test 2: rpfilter match should pass for regular traffic - netns_ping "$ns1" 192.168.23.1 || \ - die "regular ping 192.168.23.1 failed" - netns_ping "$ns1" fec0:23::1 || \ - die "regular ping fec0:23::1 failed" - - ipt_zero_rule "$iptables" && die "iptables match not effective" - ipt_zero_rule "$ip6tables" && die "ip6tables match not effective" - ipt_zero_reverse_rule "$iptables" || die "iptables match over-effective" - ipt_zero_reverse_rule "$ip6tables" || die "ip6tables match over-effective" - nft_zero_rule ip && die "nft IPv4 match not effective" - nft_zero_rule ip6 && die "nft IPv6 match not effective" - -} - -testrun - -# repeat test with vrf device in $ns2 -ip -net "$ns2" link add vrf0 type vrf table 10 -ip -net "$ns2" link set vrf0 up -ip -net "$ns2" link set v0 master vrf0 - -testrun - -echo "PASS: netfilter reverse path match works as intended" -exit 0 diff --git a/tools/testing/selftests/netfilter/sctp_collision.c b/tools/testing/selftests/netfilter/sctp_collision.c deleted file mode 100644 index 21bb1cfd8a85..000000000000 --- a/tools/testing/selftests/netfilter/sctp_collision.c +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <arpa/inet.h> - -int main(int argc, char *argv[]) -{ - struct sockaddr_in saddr = {}, daddr = {}; - int sd, ret, len = sizeof(daddr); - struct timeval tv = {25, 0}; - char buf[] = "hello"; - - if (argc != 6 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) { - printf("%s <server|client> <LOCAL_IP> <LOCAL_PORT> <REMOTE_IP> <REMOTE_PORT>\n", - argv[0]); - return -1; - } - - sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); - if (sd < 0) { - printf("Failed to create sd\n"); - return -1; - } - - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = inet_addr(argv[2]); - saddr.sin_port = htons(atoi(argv[3])); - - ret = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr)); - if (ret < 0) { - printf("Failed to bind to address\n"); - goto out; - } - - ret = listen(sd, 5); - if (ret < 0) { - printf("Failed to listen on port\n"); - goto out; - } - - daddr.sin_family = AF_INET; - daddr.sin_addr.s_addr = inet_addr(argv[4]); - daddr.sin_port = htons(atoi(argv[5])); - - /* make test shorter than 25s */ - ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - if (ret < 0) { - printf("Failed to setsockopt SO_RCVTIMEO\n"); - goto out; - } - - if (!strcmp(argv[1], "server")) { - sleep(1); /* wait a bit for client's INIT */ - ret = connect(sd, (struct sockaddr *)&daddr, len); - if (ret < 0) { - printf("Failed to connect to peer\n"); - goto out; - } - ret = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&daddr, &len); - if (ret < 0) { - printf("Failed to recv msg %d\n", ret); - goto out; - } - ret = sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&daddr, len); - if (ret < 0) { - printf("Failed to send msg %d\n", ret); - goto out; - } - printf("Server: sent! %d\n", ret); - } - - if (!strcmp(argv[1], "client")) { - usleep(300000); /* wait a bit for server's listening */ - ret = connect(sd, (struct sockaddr *)&daddr, len); - if (ret < 0) { - printf("Failed to connect to peer\n"); - goto out; - } - sleep(1); /* wait a bit for server's delayed INIT_ACK to reproduce the issue */ - ret = sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&daddr, len); - if (ret < 0) { - printf("Failed to send msg %d\n", ret); - goto out; - } - ret = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&daddr, &len); - if (ret < 0) { - printf("Failed to recv msg %d\n", ret); - goto out; - } - printf("Client: rcvd! %d\n", ret); - } - ret = 0; -out: - close(sd); - return ret; -} diff --git a/tools/testing/selftests/netfilter/settings b/tools/testing/selftests/netfilter/settings deleted file mode 100644 index 6091b45d226b..000000000000 --- a/tools/testing/selftests/netfilter/settings +++ /dev/null @@ -1 +0,0 @@ -timeout=120 diff --git a/tools/testing/selftests/netfilter/xt_string.sh b/tools/testing/selftests/netfilter/xt_string.sh deleted file mode 100755 index 1802653a4728..000000000000 --- a/tools/testing/selftests/netfilter/xt_string.sh +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 - -# return code to signal skipped test -ksft_skip=4 -rc=0 - -if ! iptables --version >/dev/null 2>&1; then - echo "SKIP: Test needs iptables" - exit $ksft_skip -fi -if ! ip -V >/dev/null 2>&1; then - echo "SKIP: Test needs iproute2" - exit $ksft_skip -fi -if ! nc -h >/dev/null 2>&1; then - echo "SKIP: Test needs netcat" - exit $ksft_skip -fi - -pattern="foo bar baz" -patlen=11 -hdrlen=$((20 + 8)) # IPv4 + UDP -ns="ns-$(mktemp -u XXXXXXXX)" -trap 'ip netns del $ns' EXIT -ip netns add "$ns" -ip -net "$ns" link add d0 type dummy -ip -net "$ns" link set d0 up -ip -net "$ns" addr add 10.1.2.1/24 dev d0 - -#ip netns exec "$ns" tcpdump -npXi d0 & -#tcpdump_pid=$! -#trap 'kill $tcpdump_pid; ip netns del $ns' EXIT - -add_rule() { # (alg, from, to) - ip netns exec "$ns" \ - iptables -A OUTPUT -o d0 -m string \ - --string "$pattern" --algo $1 --from $2 --to $3 -} -showrules() { # () - ip netns exec "$ns" iptables -v -S OUTPUT | grep '^-A' -} -zerorules() { - ip netns exec "$ns" iptables -Z OUTPUT -} -countrule() { # (pattern) - showrules | grep -c -- "$*" -} -send() { # (offset) - ( for ((i = 0; i < $1 - $hdrlen; i++)); do - printf " " - done - printf "$pattern" - ) | ip netns exec "$ns" nc -w 1 -u 10.1.2.2 27374 -} - -add_rule bm 1000 1500 -add_rule bm 1400 1600 -add_rule kmp 1000 1500 -add_rule kmp 1400 1600 - -zerorules -send 0 -send $((1000 - $patlen)) -if [ $(countrule -c 0 0) -ne 4 ]; then - echo "FAIL: rules match data before --from" - showrules - ((rc--)) -fi - -zerorules -send 1000 -send $((1400 - $patlen)) -if [ $(countrule -c 2) -ne 2 ]; then - echo "FAIL: only two rules should match at low offset" - showrules - ((rc--)) -fi - -zerorules -send $((1500 - $patlen)) -if [ $(countrule -c 1) -ne 4 ]; then - echo "FAIL: all rules should match at end of packet" - showrules - ((rc--)) -fi - -zerorules -send 1495 -if [ $(countrule -c 1) -ne 1 ]; then - echo "FAIL: only kmp with proper --to should match pattern spanning fragments" - showrules - ((rc--)) -fi - -zerorules -send 1500 -if [ $(countrule -c 1) -ne 2 ]; then - echo "FAIL: two rules should match pattern at start of second fragment" - showrules - ((rc--)) -fi - -zerorules -send $((1600 - $patlen)) -if [ $(countrule -c 1) -ne 2 ]; then - echo "FAIL: two rules should match pattern at end of largest --to" - showrules - ((rc--)) -fi - -zerorules -send $((1600 - $patlen + 1)) -if [ $(countrule -c 1) -ne 0 ]; then - echo "FAIL: no rules should match pattern extending largest --to" - showrules - ((rc--)) -fi - -zerorules -send 1600 -if [ $(countrule -c 1) -ne 0 ]; then - echo "FAIL: no rule should match pattern past largest --to" - showrules - ((rc--)) -fi - -exit $rc |