Commit 5ccbf891 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

Merge tag 'ipvs-next-for-v5.5' of https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next

Pablo Neira Ayuso says:

====================
IPVS updates for v5.5

1) Two patches to speedup ipvs netns dismantle, from Haishuang Yan.

2) Three patches to add selftest script for ipvs, also from
   Haishuang Yan.

3) Simplify __ip_vs_get_out_rt() from zhang kai.
====================
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parents 63f55acf 176a5204
...@@ -1324,7 +1324,7 @@ void ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs); ...@@ -1324,7 +1324,7 @@ void ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_control_net_cleanup(struct netns_ipvs *ipvs); void ip_vs_control_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_estimator_net_cleanup(struct netns_ipvs *ipvs); void ip_vs_estimator_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_sync_net_cleanup(struct netns_ipvs *ipvs); void ip_vs_sync_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_service_net_cleanup(struct netns_ipvs *ipvs); void ip_vs_service_nets_cleanup(struct list_head *net_list);
/* IPVS application functions /* IPVS application functions
* (from ip_vs_app.c) * (from ip_vs_app.c)
......
...@@ -2402,18 +2402,22 @@ static int __net_init __ip_vs_init(struct net *net) ...@@ -2402,18 +2402,22 @@ static int __net_init __ip_vs_init(struct net *net)
return -ENOMEM; return -ENOMEM;
} }
static void __net_exit __ip_vs_cleanup(struct net *net) static void __net_exit __ip_vs_cleanup_batch(struct list_head *net_list)
{ {
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs;
struct net *net;
ip_vs_service_net_cleanup(ipvs); /* ip_vs_flush() with locks */
ip_vs_conn_net_cleanup(ipvs); ip_vs_service_nets_cleanup(net_list); /* ip_vs_flush() with locks */
ip_vs_app_net_cleanup(ipvs); list_for_each_entry(net, net_list, exit_list) {
ip_vs_protocol_net_cleanup(ipvs); ipvs = net_ipvs(net);
ip_vs_control_net_cleanup(ipvs); ip_vs_conn_net_cleanup(ipvs);
ip_vs_estimator_net_cleanup(ipvs); ip_vs_app_net_cleanup(ipvs);
IP_VS_DBG(2, "ipvs netns %d released\n", ipvs->gen); ip_vs_protocol_net_cleanup(ipvs);
net->ipvs = NULL; ip_vs_control_net_cleanup(ipvs);
ip_vs_estimator_net_cleanup(ipvs);
IP_VS_DBG(2, "ipvs netns %d released\n", ipvs->gen);
net->ipvs = NULL;
}
} }
static int __net_init __ip_vs_dev_init(struct net *net) static int __net_init __ip_vs_dev_init(struct net *net)
...@@ -2429,27 +2433,32 @@ static int __net_init __ip_vs_dev_init(struct net *net) ...@@ -2429,27 +2433,32 @@ static int __net_init __ip_vs_dev_init(struct net *net)
return ret; return ret;
} }
static void __net_exit __ip_vs_dev_cleanup(struct net *net) static void __net_exit __ip_vs_dev_cleanup_batch(struct list_head *net_list)
{ {
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs;
struct net *net;
EnterFunction(2); EnterFunction(2);
nf_unregister_net_hooks(net, ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); list_for_each_entry(net, net_list, exit_list) {
ipvs->enable = 0; /* Disable packet reception */ ipvs = net_ipvs(net);
smp_wmb(); nf_unregister_net_hooks(net, ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
ip_vs_sync_net_cleanup(ipvs); ipvs->enable = 0; /* Disable packet reception */
smp_wmb();
ip_vs_sync_net_cleanup(ipvs);
}
LeaveFunction(2); LeaveFunction(2);
} }
static struct pernet_operations ipvs_core_ops = { static struct pernet_operations ipvs_core_ops = {
.init = __ip_vs_init, .init = __ip_vs_init,
.exit = __ip_vs_cleanup, .exit_batch = __ip_vs_cleanup_batch,
.id = &ip_vs_net_id, .id = &ip_vs_net_id,
.size = sizeof(struct netns_ipvs), .size = sizeof(struct netns_ipvs),
}; };
static struct pernet_operations ipvs_core_dev_ops = { static struct pernet_operations ipvs_core_dev_ops = {
.init = __ip_vs_dev_init, .init = __ip_vs_dev_init,
.exit = __ip_vs_dev_cleanup, .exit_batch = __ip_vs_dev_cleanup_batch,
}; };
/* /*
......
...@@ -1607,14 +1607,20 @@ static int ip_vs_flush(struct netns_ipvs *ipvs, bool cleanup) ...@@ -1607,14 +1607,20 @@ static int ip_vs_flush(struct netns_ipvs *ipvs, bool cleanup)
/* /*
* Delete service by {netns} in the service table. * Delete service by {netns} in the service table.
* Called by __ip_vs_cleanup() * Called by __ip_vs_batch_cleanup()
*/ */
void ip_vs_service_net_cleanup(struct netns_ipvs *ipvs) void ip_vs_service_nets_cleanup(struct list_head *net_list)
{ {
struct netns_ipvs *ipvs;
struct net *net;
EnterFunction(2); EnterFunction(2);
/* Check for "full" addressed entries */ /* Check for "full" addressed entries */
mutex_lock(&__ip_vs_mutex); mutex_lock(&__ip_vs_mutex);
ip_vs_flush(ipvs, true); list_for_each_entry(net, net_list, exit_list) {
ipvs = net_ipvs(net);
ip_vs_flush(ipvs, true);
}
mutex_unlock(&__ip_vs_mutex); mutex_unlock(&__ip_vs_mutex);
LeaveFunction(2); LeaveFunction(2);
} }
......
...@@ -407,12 +407,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, ...@@ -407,12 +407,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
goto err_put; goto err_put;
skb_dst_drop(skb); skb_dst_drop(skb);
if (noref) { if (noref)
if (!local) skb_dst_set_noref(skb, &rt->dst);
skb_dst_set_noref(skb, &rt->dst); else
else
skb_dst_set(skb, dst_clone(&rt->dst));
} else
skb_dst_set(skb, &rt->dst); skb_dst_set(skb, &rt->dst);
return local; return local;
...@@ -574,12 +571,9 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, ...@@ -574,12 +571,9 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
goto err_put; goto err_put;
skb_dst_drop(skb); skb_dst_drop(skb);
if (noref) { if (noref)
if (!local) skb_dst_set_noref(skb, &rt->dst);
skb_dst_set_noref(skb, &rt->dst); else
else
skb_dst_set(skb, dst_clone(&rt->dst));
} else
skb_dst_set(skb, &rt->dst); skb_dst_set(skb, &rt->dst);
return local; return local;
......
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
# Makefile for netfilter selftests # Makefile for netfilter selftests
TEST_PROGS := nft_trans_stress.sh nft_nat.sh bridge_brouter.sh \ TEST_PROGS := nft_trans_stress.sh nft_nat.sh bridge_brouter.sh \
conntrack_icmp_related.sh nft_flowtable.sh conntrack_icmp_related.sh nft_flowtable.sh ipvs.sh
include ../lib.mk include ../lib.mk
#!/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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment