mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-01-30 14:52:17 +00:00
If you are friends with T3Q or Mike, you need a prostate exam
This commit is contained in:
parent
159f821fa8
commit
443f7c2f4b
@ -742,7 +742,7 @@ class DebugfsProvider(Provider):
|
||||
The fields are all available KVM debugfs files
|
||||
|
||||
"""
|
||||
exempt_list = ['halt_poll_fail_ns', 'halt_poll_success_ns']
|
||||
exempt_list = ['halt_poll_fail_ns', 'halt_poll_success_ns', 'halt_wait_ns']
|
||||
fields = [field for field in self.walkdir(PATH_DEBUGFS_KVM)[2]
|
||||
if field not in exempt_list]
|
||||
|
||||
|
@ -949,7 +949,6 @@ static void redir_to_connected(int family, int sotype, int sock_mapfd,
|
||||
int err, n;
|
||||
u32 key;
|
||||
char b;
|
||||
int retries = 100;
|
||||
|
||||
zero_verdict_count(verd_mapfd);
|
||||
|
||||
@ -1002,17 +1001,11 @@ static void redir_to_connected(int family, int sotype, int sock_mapfd,
|
||||
goto close_peer1;
|
||||
if (pass != 1)
|
||||
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
|
||||
again:
|
||||
n = read(c0, &b, 1);
|
||||
if (n < 0) {
|
||||
if (errno == EAGAIN && retries--) {
|
||||
usleep(1000);
|
||||
goto again;
|
||||
}
|
||||
FAIL_ERRNO("%s: read", log_prefix);
|
||||
}
|
||||
n = recv_timeout(c0, &b, 1, 0, IO_TIMEOUT_SEC);
|
||||
if (n < 0)
|
||||
FAIL_ERRNO("%s: recv_timeout", log_prefix);
|
||||
if (n == 0)
|
||||
FAIL("%s: incomplete read", log_prefix);
|
||||
FAIL("%s: incomplete recv", log_prefix);
|
||||
|
||||
close_peer1:
|
||||
xclose(p1);
|
||||
@ -1571,7 +1564,6 @@ static void unix_redir_to_connected(int sotype, int sock_mapfd,
|
||||
const char *log_prefix = redir_mode_str(mode);
|
||||
int c0, c1, p0, p1;
|
||||
unsigned int pass;
|
||||
int retries = 100;
|
||||
int err, n;
|
||||
int sfd[2];
|
||||
u32 key;
|
||||
@ -1606,17 +1598,11 @@ static void unix_redir_to_connected(int sotype, int sock_mapfd,
|
||||
if (pass != 1)
|
||||
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
|
||||
|
||||
again:
|
||||
n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
|
||||
if (n < 0) {
|
||||
if (errno == EAGAIN && retries--) {
|
||||
usleep(1000);
|
||||
goto again;
|
||||
}
|
||||
FAIL_ERRNO("%s: read", log_prefix);
|
||||
}
|
||||
n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC);
|
||||
if (n < 0)
|
||||
FAIL_ERRNO("%s: recv_timeout", log_prefix);
|
||||
if (n == 0)
|
||||
FAIL("%s: incomplete read", log_prefix);
|
||||
FAIL("%s: incomplete recv", log_prefix);
|
||||
|
||||
close:
|
||||
xclose(c1);
|
||||
@ -1748,7 +1734,6 @@ static void udp_redir_to_connected(int family, int sock_mapfd, int verd_mapfd,
|
||||
const char *log_prefix = redir_mode_str(mode);
|
||||
int c0, c1, p0, p1;
|
||||
unsigned int pass;
|
||||
int retries = 100;
|
||||
int err, n;
|
||||
u32 key;
|
||||
char b;
|
||||
@ -1781,17 +1766,11 @@ static void udp_redir_to_connected(int family, int sock_mapfd, int verd_mapfd,
|
||||
if (pass != 1)
|
||||
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
|
||||
|
||||
again:
|
||||
n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
|
||||
if (n < 0) {
|
||||
if (errno == EAGAIN && retries--) {
|
||||
usleep(1000);
|
||||
goto again;
|
||||
}
|
||||
FAIL_ERRNO("%s: read", log_prefix);
|
||||
}
|
||||
n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC);
|
||||
if (n < 0)
|
||||
FAIL_ERRNO("%s: recv_timeout", log_prefix);
|
||||
if (n == 0)
|
||||
FAIL("%s: incomplete read", log_prefix);
|
||||
FAIL("%s: incomplete recv", log_prefix);
|
||||
|
||||
close_cli1:
|
||||
xclose(c1);
|
||||
@ -1841,7 +1820,6 @@ static void inet_unix_redir_to_connected(int family, int type, int sock_mapfd,
|
||||
const char *log_prefix = redir_mode_str(mode);
|
||||
int c0, c1, p0, p1;
|
||||
unsigned int pass;
|
||||
int retries = 100;
|
||||
int err, n;
|
||||
int sfd[2];
|
||||
u32 key;
|
||||
@ -1876,17 +1854,11 @@ static void inet_unix_redir_to_connected(int family, int type, int sock_mapfd,
|
||||
if (pass != 1)
|
||||
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
|
||||
|
||||
again:
|
||||
n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
|
||||
if (n < 0) {
|
||||
if (errno == EAGAIN && retries--) {
|
||||
usleep(1000);
|
||||
goto again;
|
||||
}
|
||||
FAIL_ERRNO("%s: read", log_prefix);
|
||||
}
|
||||
n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC);
|
||||
if (n < 0)
|
||||
FAIL_ERRNO("%s: recv_timeout", log_prefix);
|
||||
if (n == 0)
|
||||
FAIL("%s: incomplete read", log_prefix);
|
||||
FAIL("%s: incomplete recv", log_prefix);
|
||||
|
||||
close_cli1:
|
||||
xclose(c1);
|
||||
@ -1932,7 +1904,6 @@ static void unix_inet_redir_to_connected(int family, int type, int sock_mapfd,
|
||||
int sfd[2];
|
||||
u32 key;
|
||||
char b;
|
||||
int retries = 100;
|
||||
|
||||
zero_verdict_count(verd_mapfd);
|
||||
|
||||
@ -1963,17 +1934,11 @@ static void unix_inet_redir_to_connected(int family, int type, int sock_mapfd,
|
||||
if (pass != 1)
|
||||
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
|
||||
|
||||
again:
|
||||
n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
|
||||
if (n < 0) {
|
||||
if (errno == EAGAIN && retries--) {
|
||||
usleep(1000);
|
||||
goto again;
|
||||
}
|
||||
FAIL_ERRNO("%s: read", log_prefix);
|
||||
}
|
||||
n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC);
|
||||
if (n < 0)
|
||||
FAIL_ERRNO("%s: recv_timeout", log_prefix);
|
||||
if (n == 0)
|
||||
FAIL("%s: incomplete read", log_prefix);
|
||||
FAIL("%s: incomplete recv", log_prefix);
|
||||
|
||||
close:
|
||||
xclose(c1);
|
||||
|
@ -43,3 +43,4 @@ CONFIG_NET_ACT_TUNNEL_KEY=m
|
||||
CONFIG_NET_ACT_MIRRED=m
|
||||
CONFIG_BAREUDP=m
|
||||
CONFIG_IPV6_IOAM6_LWTUNNEL=y
|
||||
CONFIG_CRYPTO_SM4=y
|
||||
|
@ -289,6 +289,12 @@ set_sysctl()
|
||||
run_cmd sysctl -q -w $*
|
||||
}
|
||||
|
||||
# get sysctl values in NS-A
|
||||
get_sysctl()
|
||||
{
|
||||
${NSA_CMD} sysctl -n $*
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Setup for tests
|
||||
|
||||
@ -439,10 +445,13 @@ cleanup()
|
||||
ip -netns ${NSA} link set dev ${NSA_DEV} down
|
||||
ip -netns ${NSA} link del dev ${NSA_DEV}
|
||||
|
||||
ip netns pids ${NSA} | xargs kill 2>/dev/null
|
||||
ip netns del ${NSA}
|
||||
fi
|
||||
|
||||
ip netns pids ${NSB} | xargs kill 2>/dev/null
|
||||
ip netns del ${NSB}
|
||||
ip netns pids ${NSC} | xargs kill 2>/dev/null
|
||||
ip netns del ${NSC} >/dev/null 2>&1
|
||||
}
|
||||
|
||||
@ -1003,6 +1012,60 @@ ipv4_tcp_md5()
|
||||
run_cmd nettest -s -I ${NSA_DEV} -M ${MD5_PW} -m ${NS_NET}
|
||||
log_test $? 1 "MD5: VRF: Device must be a VRF - prefix"
|
||||
|
||||
test_ipv4_md5_vrf__vrf_server__no_bind_ifindex
|
||||
test_ipv4_md5_vrf__global_server__bind_ifindex0
|
||||
}
|
||||
|
||||
test_ipv4_md5_vrf__vrf_server__no_bind_ifindex()
|
||||
{
|
||||
log_start
|
||||
show_hint "Simulates applications using VRF without TCP_MD5SIG_FLAG_IFINDEX"
|
||||
run_cmd nettest -s -I ${VRF} -M ${MD5_PW} -m ${NS_NET} --no-bind-key-ifindex &
|
||||
sleep 1
|
||||
run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW}
|
||||
log_test $? 0 "MD5: VRF: VRF-bound server, unbound key accepts connection"
|
||||
|
||||
log_start
|
||||
show_hint "Binding both the socket and the key is not required but it works"
|
||||
run_cmd nettest -s -I ${VRF} -M ${MD5_PW} -m ${NS_NET} --force-bind-key-ifindex &
|
||||
sleep 1
|
||||
run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW}
|
||||
log_test $? 0 "MD5: VRF: VRF-bound server, bound key accepts connection"
|
||||
}
|
||||
|
||||
test_ipv4_md5_vrf__global_server__bind_ifindex0()
|
||||
{
|
||||
# This particular test needs tcp_l3mdev_accept=1 for Global server to accept VRF connections
|
||||
local old_tcp_l3mdev_accept
|
||||
old_tcp_l3mdev_accept=$(get_sysctl net.ipv4.tcp_l3mdev_accept)
|
||||
set_sysctl net.ipv4.tcp_l3mdev_accept=1
|
||||
|
||||
log_start
|
||||
run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --force-bind-key-ifindex &
|
||||
sleep 1
|
||||
run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW}
|
||||
log_test $? 2 "MD5: VRF: Global server, Key bound to ifindex=0 rejects VRF connection"
|
||||
|
||||
log_start
|
||||
run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --force-bind-key-ifindex &
|
||||
sleep 1
|
||||
run_cmd_nsc nettest -r ${NSA_IP} -X ${MD5_PW}
|
||||
log_test $? 0 "MD5: VRF: Global server, key bound to ifindex=0 accepts non-VRF connection"
|
||||
log_start
|
||||
|
||||
run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --no-bind-key-ifindex &
|
||||
sleep 1
|
||||
run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW}
|
||||
log_test $? 0 "MD5: VRF: Global server, key not bound to ifindex accepts VRF connection"
|
||||
|
||||
log_start
|
||||
run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --no-bind-key-ifindex &
|
||||
sleep 1
|
||||
run_cmd_nsc nettest -r ${NSA_IP} -X ${MD5_PW}
|
||||
log_test $? 0 "MD5: VRF: Global server, key not bound to ifindex accepts non-VRF connection"
|
||||
|
||||
# restore value
|
||||
set_sysctl net.ipv4.tcp_l3mdev_accept="$old_tcp_l3mdev_accept"
|
||||
}
|
||||
|
||||
ipv4_tcp_novrf()
|
||||
|
@ -9,6 +9,7 @@ TEST_PROGS = bridge_igmp.sh \
|
||||
gre_inner_v4_multipath.sh \
|
||||
gre_inner_v6_multipath.sh \
|
||||
gre_multipath.sh \
|
||||
ip6_forward_instats_vrf.sh \
|
||||
ip6gre_inner_v4_multipath.sh \
|
||||
ip6gre_inner_v6_multipath.sh \
|
||||
ipip_flat_gre_key.sh \
|
||||
|
@ -39,3 +39,5 @@ NETIF_CREATE=yes
|
||||
# Timeout (in seconds) before ping exits regardless of how many packets have
|
||||
# been sent or received
|
||||
PING_TIMEOUT=5
|
||||
# IPv6 traceroute utility name.
|
||||
TROUTE6=traceroute6
|
||||
|
@ -0,0 +1,172 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# Test ipv6 stats on the incoming if when forwarding with VRF
|
||||
|
||||
ALL_TESTS="
|
||||
ipv6_ping
|
||||
ipv6_in_too_big_err
|
||||
ipv6_in_hdr_err
|
||||
ipv6_in_addr_err
|
||||
ipv6_in_discard
|
||||
"
|
||||
|
||||
NUM_NETIFS=4
|
||||
source lib.sh
|
||||
|
||||
h1_create()
|
||||
{
|
||||
simple_if_init $h1 2001:1:1::2/64
|
||||
ip -6 route add vrf v$h1 2001:1:2::/64 via 2001:1:1::1
|
||||
}
|
||||
|
||||
h1_destroy()
|
||||
{
|
||||
ip -6 route del vrf v$h1 2001:1:2::/64 via 2001:1:1::1
|
||||
simple_if_fini $h1 2001:1:1::2/64
|
||||
}
|
||||
|
||||
router_create()
|
||||
{
|
||||
vrf_create router
|
||||
__simple_if_init $rtr1 router 2001:1:1::1/64
|
||||
__simple_if_init $rtr2 router 2001:1:2::1/64
|
||||
mtu_set $rtr2 1280
|
||||
}
|
||||
|
||||
router_destroy()
|
||||
{
|
||||
mtu_restore $rtr2
|
||||
__simple_if_fini $rtr2 2001:1:2::1/64
|
||||
__simple_if_fini $rtr1 2001:1:1::1/64
|
||||
vrf_destroy router
|
||||
}
|
||||
|
||||
h2_create()
|
||||
{
|
||||
simple_if_init $h2 2001:1:2::2/64
|
||||
ip -6 route add vrf v$h2 2001:1:1::/64 via 2001:1:2::1
|
||||
mtu_set $h2 1280
|
||||
}
|
||||
|
||||
h2_destroy()
|
||||
{
|
||||
mtu_restore $h2
|
||||
ip -6 route del vrf v$h2 2001:1:1::/64 via 2001:1:2::1
|
||||
simple_if_fini $h2 2001:1:2::2/64
|
||||
}
|
||||
|
||||
setup_prepare()
|
||||
{
|
||||
h1=${NETIFS[p1]}
|
||||
rtr1=${NETIFS[p2]}
|
||||
|
||||
rtr2=${NETIFS[p3]}
|
||||
h2=${NETIFS[p4]}
|
||||
|
||||
vrf_prepare
|
||||
h1_create
|
||||
router_create
|
||||
h2_create
|
||||
|
||||
forwarding_enable
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
||||
forwarding_restore
|
||||
|
||||
h2_destroy
|
||||
router_destroy
|
||||
h1_destroy
|
||||
vrf_cleanup
|
||||
}
|
||||
|
||||
ipv6_in_too_big_err()
|
||||
{
|
||||
RET=0
|
||||
|
||||
local t0=$(ipv6_stats_get $rtr1 Ip6InTooBigErrors)
|
||||
local vrf_name=$(master_name_get $h1)
|
||||
|
||||
# Send too big packets
|
||||
ip vrf exec $vrf_name \
|
||||
$PING6 -s 1300 2001:1:2::2 -c 1 -w $PING_TIMEOUT &> /dev/null
|
||||
|
||||
local t1=$(ipv6_stats_get $rtr1 Ip6InTooBigErrors)
|
||||
test "$((t1 - t0))" -ne 0
|
||||
check_err $?
|
||||
log_test "Ip6InTooBigErrors"
|
||||
}
|
||||
|
||||
ipv6_in_hdr_err()
|
||||
{
|
||||
RET=0
|
||||
|
||||
local t0=$(ipv6_stats_get $rtr1 Ip6InHdrErrors)
|
||||
local vrf_name=$(master_name_get $h1)
|
||||
|
||||
# Send packets with hop limit 1, easiest with traceroute6 as some ping6
|
||||
# doesn't allow hop limit to be specified
|
||||
ip vrf exec $vrf_name \
|
||||
$TROUTE6 2001:1:2::2 &> /dev/null
|
||||
|
||||
local t1=$(ipv6_stats_get $rtr1 Ip6InHdrErrors)
|
||||
test "$((t1 - t0))" -ne 0
|
||||
check_err $?
|
||||
log_test "Ip6InHdrErrors"
|
||||
}
|
||||
|
||||
ipv6_in_addr_err()
|
||||
{
|
||||
RET=0
|
||||
|
||||
local t0=$(ipv6_stats_get $rtr1 Ip6InAddrErrors)
|
||||
local vrf_name=$(master_name_get $h1)
|
||||
|
||||
# Disable forwarding temporary while sending the packet
|
||||
sysctl -qw net.ipv6.conf.all.forwarding=0
|
||||
ip vrf exec $vrf_name \
|
||||
$PING6 2001:1:2::2 -c 1 -w $PING_TIMEOUT &> /dev/null
|
||||
sysctl -qw net.ipv6.conf.all.forwarding=1
|
||||
|
||||
local t1=$(ipv6_stats_get $rtr1 Ip6InAddrErrors)
|
||||
test "$((t1 - t0))" -ne 0
|
||||
check_err $?
|
||||
log_test "Ip6InAddrErrors"
|
||||
}
|
||||
|
||||
ipv6_in_discard()
|
||||
{
|
||||
RET=0
|
||||
|
||||
local t0=$(ipv6_stats_get $rtr1 Ip6InDiscards)
|
||||
local vrf_name=$(master_name_get $h1)
|
||||
|
||||
# Add a policy to discard
|
||||
ip xfrm policy add dst 2001:1:2::2/128 dir fwd action block
|
||||
ip vrf exec $vrf_name \
|
||||
$PING6 2001:1:2::2 -c 1 -w $PING_TIMEOUT &> /dev/null
|
||||
ip xfrm policy del dst 2001:1:2::2/128 dir fwd
|
||||
|
||||
local t1=$(ipv6_stats_get $rtr1 Ip6InDiscards)
|
||||
test "$((t1 - t0))" -ne 0
|
||||
check_err $?
|
||||
log_test "Ip6InDiscards"
|
||||
}
|
||||
ipv6_ping()
|
||||
{
|
||||
RET=0
|
||||
|
||||
ping6_test $h1 2001:1:2::2
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
setup_prepare
|
||||
setup_wait
|
||||
tests_run
|
||||
|
||||
exit $EXIT_STATUS
|
@ -751,6 +751,14 @@ qdisc_parent_stats_get()
|
||||
| jq '.[] | select(.parent == "'"$parent"'") | '"$selector"
|
||||
}
|
||||
|
||||
ipv6_stats_get()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local stat=$1; shift
|
||||
|
||||
cat /proc/net/dev_snmp6/$dev | grep "^$stat" | cut -f2
|
||||
}
|
||||
|
||||
humanize()
|
||||
{
|
||||
local speed=$1; shift
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <linux/xfrm.h>
|
||||
#include <linux/ipsec.h>
|
||||
@ -101,6 +102,8 @@ struct sock_args {
|
||||
struct sockaddr_in6 v6;
|
||||
} md5_prefix;
|
||||
unsigned int prefix_len;
|
||||
/* 0: default, -1: force off, +1: force on */
|
||||
int bind_key_ifindex;
|
||||
|
||||
/* expected addresses and device index for connection */
|
||||
const char *expected_dev;
|
||||
@ -271,11 +274,14 @@ static int tcp_md5sig(int sd, void *addr, socklen_t alen, struct sock_args *args
|
||||
}
|
||||
memcpy(&md5sig.tcpm_addr, addr, alen);
|
||||
|
||||
if (args->ifindex) {
|
||||
if ((args->ifindex && args->bind_key_ifindex >= 0) || args->bind_key_ifindex >= 1) {
|
||||
opt = TCP_MD5SIG_EXT;
|
||||
md5sig.tcpm_flags |= TCP_MD5SIG_FLAG_IFINDEX;
|
||||
|
||||
md5sig.tcpm_ifindex = args->ifindex;
|
||||
log_msg("TCP_MD5SIG_FLAG_IFINDEX set tcpm_ifindex=%d\n", md5sig.tcpm_ifindex);
|
||||
} else {
|
||||
log_msg("TCP_MD5SIG_FLAG_IFINDEX off\n", md5sig.tcpm_ifindex);
|
||||
}
|
||||
|
||||
rc = setsockopt(sd, IPPROTO_TCP, opt, &md5sig, sizeof(md5sig));
|
||||
@ -1822,6 +1828,14 @@ static int ipc_parent(int cpid, int fd, struct sock_args *args)
|
||||
}
|
||||
|
||||
#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbq"
|
||||
#define OPT_FORCE_BIND_KEY_IFINDEX 1001
|
||||
#define OPT_NO_BIND_KEY_IFINDEX 1002
|
||||
|
||||
static struct option long_opts[] = {
|
||||
{"force-bind-key-ifindex", 0, 0, OPT_FORCE_BIND_KEY_IFINDEX},
|
||||
{"no-bind-key-ifindex", 0, 0, OPT_NO_BIND_KEY_IFINDEX},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void print_usage(char *prog)
|
||||
{
|
||||
@ -1858,6 +1872,10 @@ static void print_usage(char *prog)
|
||||
" -M password use MD5 sum protection\n"
|
||||
" -X password MD5 password for client mode\n"
|
||||
" -m prefix/len prefix and length to use for MD5 key\n"
|
||||
" --no-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX off\n"
|
||||
" --force-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX on\n"
|
||||
" (default: only if -I is passed)\n"
|
||||
"\n"
|
||||
" -g grp multicast group (e.g., 239.1.1.1)\n"
|
||||
" -i interactive mode (default is echo and terminate)\n"
|
||||
"\n"
|
||||
@ -1893,7 +1911,7 @@ int main(int argc, char *argv[])
|
||||
* process input args
|
||||
*/
|
||||
|
||||
while ((rc = getopt(argc, argv, GETOPT_STR)) != -1) {
|
||||
while ((rc = getopt_long(argc, argv, GETOPT_STR, long_opts, NULL)) != -1) {
|
||||
switch (rc) {
|
||||
case 'B':
|
||||
both_mode = 1;
|
||||
@ -1966,6 +1984,12 @@ int main(int argc, char *argv[])
|
||||
case 'M':
|
||||
args.password = optarg;
|
||||
break;
|
||||
case OPT_FORCE_BIND_KEY_IFINDEX:
|
||||
args.bind_key_ifindex = 1;
|
||||
break;
|
||||
case OPT_NO_BIND_KEY_IFINDEX:
|
||||
args.bind_key_ifindex = -1;
|
||||
break;
|
||||
case 'X':
|
||||
args.client_pw = optarg;
|
||||
break;
|
||||
|
@ -199,7 +199,6 @@ 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
|
||||
bash
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -741,6 +741,149 @@ EOF
|
||||
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=""
|
||||
|
||||
echo ROUTER | ip netns exec "$ns0" nc -w 5 -u -l -p 1405 >/dev/null 2>&1 &
|
||||
nc_r=$!
|
||||
|
||||
echo CLIENT | ip netns exec "$ns2" nc -w 5 -u -l -p 1405 >/dev/null 2>&1 &
|
||||
nc_c=$!
|
||||
|
||||
# make shadow entry, from client (ns2), going to (ns1), port 41404, sport 1405.
|
||||
echo "fake-entry" | ip netns exec "$ns2" nc -w 1 -p 1405 -u "$daddrc" 41404 > /dev/null
|
||||
|
||||
# ns1 tries to connect to ns0:1405. With default settings this should connect
|
||||
# to client, it matches the conntrack entry created above.
|
||||
|
||||
result=$(echo "" | ip netns exec "$ns1" nc -w 1 -p 41404 -u "$daddrs" 1405)
|
||||
|
||||
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 $nc_r $nc_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
|
||||
udp dport 1405 notrack
|
||||
}
|
||||
chain output {
|
||||
type filter hook output priority -300; policy accept;
|
||||
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"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
# ip netns exec "$ns0" ping -c 1 -q 10.0.$i.99
|
||||
for i in 0 1 2; do
|
||||
@ -861,6 +1004,8 @@ reset_counters
|
||||
$test_inet_nat && test_redirect inet
|
||||
$test_inet_nat && test_redirect6 inet
|
||||
|
||||
test_port_shadowing
|
||||
|
||||
if [ $ret -ne 0 ];then
|
||||
echo -n "FAIL: "
|
||||
nft --version
|
||||
|
@ -341,7 +341,7 @@ void split_file_backed_thp(void)
|
||||
}
|
||||
|
||||
/* write something to the file, so a file-backed THP can be allocated */
|
||||
num_written = write(fd, tmpfs_loc, sizeof(tmpfs_loc));
|
||||
num_written = write(fd, tmpfs_loc, strlen(tmpfs_loc) + 1);
|
||||
close(fd);
|
||||
|
||||
if (num_written < 1) {
|
||||
|
@ -414,9 +414,6 @@ static void uffd_test_ctx_init_ext(uint64_t *features)
|
||||
uffd_test_ops->allocate_area((void **)&area_src);
|
||||
uffd_test_ops->allocate_area((void **)&area_dst);
|
||||
|
||||
uffd_test_ops->release_pages(area_src);
|
||||
uffd_test_ops->release_pages(area_dst);
|
||||
|
||||
userfaultfd_open(features);
|
||||
|
||||
count_verify = malloc(nr_pages * sizeof(unsigned long long));
|
||||
@ -437,6 +434,26 @@ static void uffd_test_ctx_init_ext(uint64_t *features)
|
||||
*(area_count(area_src, nr) + 1) = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* After initialization of area_src, we must explicitly release pages
|
||||
* for area_dst to make sure it's fully empty. Otherwise we could have
|
||||
* some area_dst pages be errornously initialized with zero pages,
|
||||
* hence we could hit memory corruption later in the test.
|
||||
*
|
||||
* One example is when THP is globally enabled, above allocate_area()
|
||||
* calls could have the two areas merged into a single VMA (as they
|
||||
* will have the same VMA flags so they're mergeable). When we
|
||||
* initialize the area_src above, it's possible that some part of
|
||||
* area_dst could have been faulted in via one huge THP that will be
|
||||
* shared between area_src and area_dst. It could cause some of the
|
||||
* area_dst won't be trapped by missing userfaults.
|
||||
*
|
||||
* This release_pages() will guarantee even if that happened, we'll
|
||||
* proactively split the thp and drop any accidentally initialized
|
||||
* pages within area_dst.
|
||||
*/
|
||||
uffd_test_ops->release_pages(area_dst);
|
||||
|
||||
pipefd = malloc(sizeof(int) * nr_cpus * 2);
|
||||
if (!pipefd)
|
||||
err("pipefd");
|
||||
|
@ -332,8 +332,6 @@ static void test_no_sockets(const struct test_opts *opts)
|
||||
read_vsock_stat(&sockets);
|
||||
|
||||
check_no_sockets(&sockets);
|
||||
|
||||
free_sock_stat(&sockets);
|
||||
}
|
||||
|
||||
static void test_listen_socket_server(const struct test_opts *opts)
|
||||
|
Loading…
Reference in New Issue
Block a user