mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add a flag to tcp_benchmarks that runs the workload over ipv6.
PiperOrigin-RevId: 465404721
This commit is contained in:
committed by
gVisor bot
parent
23c6100e92
commit
2f34113ec1
@@ -13,7 +13,9 @@ go_binary(
|
||||
"//pkg/tcpip/link/qdisc/fifo",
|
||||
"//pkg/tcpip/network/arp",
|
||||
"//pkg/tcpip/network/ipv4",
|
||||
"//pkg/tcpip/network/ipv6",
|
||||
"//pkg/tcpip/stack",
|
||||
"//pkg/tcpip/transport/icmp",
|
||||
"//pkg/tcpip/transport/tcp",
|
||||
"//pkg/tcpip/transport/udp",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
|
||||
@@ -19,11 +19,15 @@
|
||||
# Fixed parameters.
|
||||
iperf_port=45201 # Not likely to be privileged.
|
||||
proxy_port=44000 # Ditto.
|
||||
mask=8
|
||||
|
||||
client_addr=10.0.0.1
|
||||
client_proxy_addr=10.0.0.2
|
||||
server_proxy_addr=10.0.0.3
|
||||
server_addr=10.0.0.4
|
||||
mask=8
|
||||
full_server_addr=${server_addr}:${iperf_port}
|
||||
full_server_proxy_addr=${server_proxy_addr}:${proxy_port}
|
||||
iperf_version_arg=
|
||||
|
||||
# Defaults; this provides a reasonable approximation of a decent internet link.
|
||||
# Parameters can be varied independently from this set to see response to
|
||||
@@ -140,6 +144,16 @@ while [ $# -gt 0 ]; do
|
||||
--disable-linux-gro)
|
||||
disable_linux_gro=1
|
||||
;;
|
||||
--ipv6)
|
||||
client_addr=fd::1
|
||||
client_proxy_addr=fd::2
|
||||
server_proxy_addr=fd::3
|
||||
server_addr=fd::4
|
||||
full_server_addr=[${server_addr}]:${iperf_port}
|
||||
full_server_proxy_addr=[${server_proxy_addr}]:${proxy_port}
|
||||
iperf_version_arg=-V
|
||||
netstack_opts="${netstack_opts} -ipv6"
|
||||
;;
|
||||
--num-client-threads)
|
||||
shift
|
||||
num_client_threads=$1
|
||||
@@ -171,6 +185,7 @@ while [ $# -gt 0 ]; do
|
||||
echo " --num-client-threads number of parallel client threads to run"
|
||||
echo " --disable-linux-gso disable segmentation offload (TSO, GSO, GRO) in the Linux network stack"
|
||||
echo " --disable-linux-gro disable GRO in the Linux network stack"
|
||||
echo " --ipv6 use ipv6 for benchmarks"
|
||||
echo ""
|
||||
echo "The output will of the script will be:"
|
||||
echo " <throughput> <client-cpu-usage> <server-cpu-usage>"
|
||||
@@ -213,24 +228,24 @@ fi
|
||||
|
||||
# Client proxy that will listen on the client's iperf target forward traffic
|
||||
# using the host networking stack.
|
||||
client_args="${proxy_binary} -port ${proxy_port} -forward ${server_proxy_addr}:${proxy_port}"
|
||||
client_args="${proxy_binary} -port ${proxy_port} -forward ${full_server_proxy_addr}"
|
||||
if ${client}; then
|
||||
# Client proxy that will listen on the client's iperf target
|
||||
# and forward traffic using netstack.
|
||||
client_args="${proxy_binary} ${netstack_opts} -port ${proxy_port} -client \\
|
||||
-mtu ${mtu} -iface client.0 -addr ${client_proxy_addr} -mask ${mask} \\
|
||||
-forward ${server_proxy_addr}:${proxy_port} -gso=${gso} -swgso=${swgso}"
|
||||
-forward ${full_server_proxy_addr} -gso=${gso} -swgso=${swgso}"
|
||||
fi
|
||||
|
||||
# Server proxy that will listen on the proxy port and forward to the server's
|
||||
# iperf server using the host networking stack.
|
||||
server_args="${proxy_binary} -port ${proxy_port} -forward ${server_addr}:${iperf_port}"
|
||||
server_args="${proxy_binary} -port ${proxy_port} -forward ${full_server_addr}"
|
||||
if ${server}; then
|
||||
# Server proxy that will listen on the proxy port and forward to the servers'
|
||||
# iperf server using netstack.
|
||||
server_args="${proxy_binary} ${netstack_opts} -port ${proxy_port} -server \\
|
||||
-mtu ${mtu} -iface server.0 -addr ${server_proxy_addr} -mask ${mask} \\
|
||||
-forward ${server_addr}:${iperf_port} -gso=${gso} -swgso=${swgso}"
|
||||
-forward ${full_server_addr} -gso=${gso} -swgso=${swgso}"
|
||||
fi
|
||||
|
||||
# Specify loss and duplicate parameters only if they are non-zero
|
||||
@@ -344,15 +359,19 @@ ${nsjoin_binary} /tmp/server.netns ip link set lo up
|
||||
ip link set dev client.1 up
|
||||
ip link set dev server.1 up
|
||||
|
||||
${nsjoin_binary} /tmp/client.netns ${client_args} &
|
||||
client_pid=\$!
|
||||
${nsjoin_binary} /tmp/server.netns ${server_args} &
|
||||
server_pid=\$!
|
||||
|
||||
# Start the iperf server.
|
||||
${nsjoin_binary} /tmp/server.netns iperf -p ${iperf_port} -s >&2 &
|
||||
${nsjoin_binary} /tmp/server.netns iperf ${iperf_version_arg} -p ${iperf_port} -s >&2 &
|
||||
iperf_pid=\$!
|
||||
|
||||
# Give services time to start.
|
||||
sleep 5
|
||||
|
||||
${nsjoin_binary} /tmp/client.netns ${client_args} &
|
||||
client_pid=\$!
|
||||
|
||||
# Show traffic information.
|
||||
if ! ${client} && ! ${server}; then
|
||||
${nsjoin_binary} /tmp/client.netns ping -c 100 -i 0.001 -W 1 ${server_addr} >&2 || true
|
||||
@@ -374,7 +393,7 @@ trap cleanup EXIT
|
||||
|
||||
# Run the benchmark, recording the results file.
|
||||
while ${nsjoin_binary} /tmp/client.netns iperf \\
|
||||
-p ${proxy_port} -c ${client_addr} -t ${duration} -f m -P ${num_client_threads} 2>&1 \\
|
||||
${iperf_version_arg} -p ${proxy_port} -c ${client_addr} -t ${duration} -f m -P ${num_client_threads} 2>&1 \\
|
||||
| tee \$results_file \\
|
||||
| grep "connect failed" >/dev/null; do
|
||||
sleep 0.1 # Wait for all services.
|
||||
|
||||
@@ -38,7 +38,9 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/qdisc/fifo"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/network/arp"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
|
||||
)
|
||||
@@ -64,6 +66,7 @@ var (
|
||||
serverTCPProbeFile = flag.String("server_tcp_probe_file", "", "if specified, installs a tcp probe to dump endpoint state to the specified file.")
|
||||
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to the specified file.")
|
||||
memprofile = flag.String("memprofile", "", "write memory profile to the specified file.")
|
||||
useIpv6 = flag.Bool("ipv6", false, "use ipv6 instead of ipv4.")
|
||||
)
|
||||
|
||||
type impl interface {
|
||||
@@ -156,26 +159,37 @@ func newNetstackImpl(mode string) (impl, error) {
|
||||
|
||||
// Parse details.
|
||||
parsedAddr := tcpip.Address(net.ParseIP(*addr).To4())
|
||||
parsedDest := tcpip.Address("") // Filled in below.
|
||||
parsedMask := tcpip.AddressMask("") // Filled in below.
|
||||
if *useIpv6 {
|
||||
parsedAddr = tcpip.Address(net.ParseIP(*addr).To16())
|
||||
}
|
||||
parsedDest := tcpip.Address("") // Filled in below.
|
||||
parsedMask := tcpip.AddressMask("") // Filled in below.
|
||||
parsedDest6 := tcpip.Address("") // Filled in below.
|
||||
parsedMask6 := tcpip.AddressMask("") // Filled in below.
|
||||
switch *mask {
|
||||
case 8:
|
||||
parsedDest = tcpip.Address([]byte{parsedAddr[0], 0, 0, 0})
|
||||
parsedMask = tcpip.AddressMask([]byte{0xff, 0, 0, 0})
|
||||
parsedDest6 = tcpip.Address(append([]byte{parsedAddr[0]}, make([]byte, 15)...))
|
||||
parsedMask6 = tcpip.AddressMask(append([]byte{0xff}, make([]byte, 15)...))
|
||||
case 16:
|
||||
parsedDest = tcpip.Address([]byte{parsedAddr[0], parsedAddr[1], 0, 0})
|
||||
parsedMask = tcpip.AddressMask([]byte{0xff, 0xff, 0, 0})
|
||||
parsedDest6 = tcpip.Address(append([]byte{parsedAddr[0], parsedAddr[1]}, make([]byte, 14)...))
|
||||
parsedMask6 = tcpip.AddressMask(append([]byte{0xff, 0xff}, make([]byte, 14)...))
|
||||
case 24:
|
||||
parsedDest = tcpip.Address([]byte{parsedAddr[0], parsedAddr[1], parsedAddr[2], 0})
|
||||
parsedMask = tcpip.AddressMask([]byte{0xff, 0xff, 0xff, 0})
|
||||
parsedDest6 = tcpip.Address(append([]byte{parsedAddr[0], parsedAddr[1], parsedAddr[2]}, make([]byte, 13)...))
|
||||
parsedMask6 = tcpip.AddressMask(append([]byte{0xff, 0xff, 0xff}, make([]byte, 13)...))
|
||||
default:
|
||||
// This is just laziness; we don't expect a different mask.
|
||||
return nil, fmt.Errorf("mask %d not supported", mask)
|
||||
}
|
||||
|
||||
// Create a new network stack.
|
||||
netProtos := []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol}
|
||||
transProtos := []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol}
|
||||
netProtos := []stack.NetworkProtocolFactory{ipv6.NewProtocol, ipv4.NewProtocol, arp.NewProtocol}
|
||||
transProtos := []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol4, icmp.NewProtocol6}
|
||||
s := stack.New(stack.Options{
|
||||
NetworkProtocols: netProtos,
|
||||
TransportProtocols: transProtos,
|
||||
@@ -210,22 +224,35 @@ func newNetstackImpl(mode string) (impl, error) {
|
||||
if err := s.CreateNICWithOptions(nicID, ep, opts); err != nil {
|
||||
return nil, fmt.Errorf("error creating NIC %q: %v", *iface, err)
|
||||
}
|
||||
proto := ipv4.ProtocolNumber
|
||||
if *useIpv6 {
|
||||
proto = ipv6.ProtocolNumber
|
||||
}
|
||||
protocolAddr := tcpip.ProtocolAddress{
|
||||
Protocol: ipv4.ProtocolNumber,
|
||||
Protocol: proto,
|
||||
AddressWithPrefix: parsedAddr.WithPrefix(),
|
||||
}
|
||||
if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil {
|
||||
return nil, fmt.Errorf("error adding IP address %+v to %q: %s", protocolAddr, *iface, err)
|
||||
}
|
||||
|
||||
subnet, err := tcpip.NewSubnet(parsedDest, parsedMask)
|
||||
subnet4, err := tcpip.NewSubnet(parsedDest, parsedMask)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tcpip.Subnet(%s, %s): %s", parsedDest, parsedMask, err)
|
||||
}
|
||||
subnet6, err := tcpip.NewSubnet(parsedDest6, parsedMask6)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tcpip.Subnet(%s, %s): %s", parsedDest, parsedMask, err)
|
||||
}
|
||||
|
||||
// Add default route; we only support
|
||||
s.SetRouteTable([]tcpip.Route{
|
||||
{
|
||||
Destination: subnet,
|
||||
Destination: subnet4,
|
||||
NIC: nicID,
|
||||
},
|
||||
{
|
||||
Destination: subnet6,
|
||||
NIC: nicID,
|
||||
},
|
||||
})
|
||||
@@ -281,12 +308,20 @@ func (n netstackImpl) dial(address string) (net.Conn, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hostAddr := net.ParseIP(host).To4()
|
||||
if *useIpv6 {
|
||||
hostAddr = net.ParseIP(host).To16()
|
||||
}
|
||||
addr := tcpip.FullAddress{
|
||||
NIC: nicID,
|
||||
Addr: tcpip.Address(net.ParseIP(host).To4()),
|
||||
Addr: tcpip.Address(hostAddr),
|
||||
Port: uint16(portNumber),
|
||||
}
|
||||
conn, err := gonet.DialTCP(n.s, addr, ipv4.ProtocolNumber)
|
||||
proto := ipv4.ProtocolNumber
|
||||
if *useIpv6 {
|
||||
proto = ipv6.ProtocolNumber
|
||||
}
|
||||
conn, err := gonet.DialTCP(n.s, addr, proto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -298,7 +333,11 @@ func (n netstackImpl) listen(port int) (net.Listener, error) {
|
||||
NIC: nicID,
|
||||
Port: uint16(port),
|
||||
}
|
||||
listener, err := gonet.ListenTCP(n.s, addr, ipv4.ProtocolNumber)
|
||||
proto := ipv4.ProtocolNumber
|
||||
if *useIpv6 {
|
||||
proto = ipv6.ProtocolNumber
|
||||
}
|
||||
listener, err := gonet.ListenTCP(n.s, addr, proto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user