diff options
author | Zeling Feng <zeling@google.com> | 2020-11-23 18:11:00 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-11-23 18:13:07 -0800 |
commit | d4951e05a00a9ec84b8065311836aa9c844f63f6 (patch) | |
tree | c7d6791ea7f22cf650acc11796abc1b16012e6ec | |
parent | 986683124c41e3ba2d24420a95d7cdb945055381 (diff) |
[1/3] Support isolated containers for parallel packetimpact tests
Summary of the approach: the test runner will set up a few DUTs according to
a flag and pass all the test networks to the testbench. The testbench will only
reside in a single container. The testbench will put all the test networks into
a buffered channel which served as a semaphore and now the user can freely use
t.Parallel() in (sub)tests and the true parallelism will be determined by how
many DUTs are configured. Creating DUTs on demand is not supported yet, the
test author should determine the number of DUTs to be used statically.
Specifically in this change:
- Don't export any global variables about the test network in testbench.
- Sniffer only binds on the local interface because it will be possible to have
multiple interfaces to multiple DUTs in a single testbench container.
- Migrate existing tests to stop using global variables.
PiperOrigin-RevId: 343965962
38 files changed, 364 insertions, 328 deletions
diff --git a/test/packetimpact/testbench/connections.go b/test/packetimpact/testbench/connections.go index 919b4fd25..266a8601c 100644 --- a/test/packetimpact/testbench/connections.go +++ b/test/packetimpact/testbench/connections.go @@ -17,7 +17,6 @@ package testbench import ( "fmt" "math/rand" - "net" "testing" "time" @@ -42,7 +41,7 @@ func portFromSockaddr(sa unix.Sockaddr) (uint16, error) { // pickPort makes a new socket and returns the socket FD and port. The domain // should be AF_INET or AF_INET6. The caller must close the FD when done with // the port if there is no error. -func pickPort(domain, typ int) (fd int, port uint16, err error) { +func (n *DUTTestNet) pickPort(domain, typ int) (fd int, port uint16, err error) { fd, err = unix.Socket(domain, typ, 0) if err != nil { return -1, 0, fmt.Errorf("creating socket: %w", err) @@ -58,11 +57,11 @@ func pickPort(domain, typ int) (fd int, port uint16, err error) { switch domain { case unix.AF_INET: var sa4 unix.SockaddrInet4 - copy(sa4.Addr[:], net.ParseIP(LocalIPv4).To4()) + copy(sa4.Addr[:], n.LocalIPv4) sa = &sa4 case unix.AF_INET6: - sa6 := unix.SockaddrInet6{ZoneId: uint32(LocalInterfaceID)} - copy(sa6.Addr[:], net.ParseIP(LocalIPv6).To16()) + sa6 := unix.SockaddrInet6{ZoneId: n.LocalDevID} + copy(sa6.Addr[:], n.LocalIPv6) sa = &sa6 default: return -1, 0, fmt.Errorf("invalid domain %d, it should be one of unix.AF_INET or unix.AF_INET6", domain) @@ -117,19 +116,12 @@ type etherState struct { var _ layerState = (*etherState)(nil) // newEtherState creates a new etherState. -func newEtherState(out, in Ether) (*etherState, error) { - lMAC, err := tcpip.ParseMACAddress(LocalMAC) - if err != nil { - return nil, fmt.Errorf("parsing local MAC: %q: %w", LocalMAC, err) - } - - rMAC, err := tcpip.ParseMACAddress(RemoteMAC) - if err != nil { - return nil, fmt.Errorf("parsing remote MAC: %q: %w", RemoteMAC, err) - } +func (n *DUTTestNet) newEtherState(out, in Ether) (*etherState, error) { + lmac := tcpip.LinkAddress(n.LocalMAC) + rmac := tcpip.LinkAddress(n.RemoteMAC) s := etherState{ - out: Ether{SrcAddr: &lMAC, DstAddr: &rMAC}, - in: Ether{SrcAddr: &rMAC, DstAddr: &lMAC}, + out: Ether{SrcAddr: &lmac, DstAddr: &rmac}, + in: Ether{SrcAddr: &rmac, DstAddr: &lmac}, } if err := s.out.merge(&out); err != nil { return nil, err @@ -169,9 +161,9 @@ type ipv4State struct { var _ layerState = (*ipv4State)(nil) // newIPv4State creates a new ipv4State. -func newIPv4State(out, in IPv4) (*ipv4State, error) { - lIP := tcpip.Address(net.ParseIP(LocalIPv4).To4()) - rIP := tcpip.Address(net.ParseIP(RemoteIPv4).To4()) +func (n *DUTTestNet) newIPv4State(out, in IPv4) (*ipv4State, error) { + lIP := tcpip.Address(n.LocalIPv4) + rIP := tcpip.Address(n.RemoteIPv4) s := ipv4State{ out: IPv4{SrcAddr: &lIP, DstAddr: &rIP}, in: IPv4{SrcAddr: &rIP, DstAddr: &lIP}, @@ -214,9 +206,9 @@ type ipv6State struct { var _ layerState = (*ipv6State)(nil) // newIPv6State creates a new ipv6State. -func newIPv6State(out, in IPv6) (*ipv6State, error) { - lIP := tcpip.Address(net.ParseIP(LocalIPv6).To16()) - rIP := tcpip.Address(net.ParseIP(RemoteIPv6).To16()) +func (n *DUTTestNet) newIPv6State(out, in IPv6) (*ipv6State, error) { + lIP := tcpip.Address(n.LocalIPv6) + rIP := tcpip.Address(n.RemoteIPv6) s := ipv6State{ out: IPv6{SrcAddr: &lIP, DstAddr: &rIP}, in: IPv6{SrcAddr: &rIP, DstAddr: &lIP}, @@ -272,8 +264,8 @@ func SeqNumValue(v seqnum.Value) *seqnum.Value { } // newTCPState creates a new TCPState. -func newTCPState(domain int, out, in TCP) (*tcpState, error) { - portPickerFD, localPort, err := pickPort(domain, unix.SOCK_STREAM) +func (n *DUTTestNet) newTCPState(domain int, out, in TCP) (*tcpState, error) { + portPickerFD, localPort, err := n.pickPort(domain, unix.SOCK_STREAM) if err != nil { return nil, err } @@ -376,8 +368,8 @@ type udpState struct { var _ layerState = (*udpState)(nil) // newUDPState creates a new udpState. -func newUDPState(domain int, out, in UDP) (*udpState, error) { - portPickerFD, localPort, err := pickPort(domain, unix.SOCK_DGRAM) +func (n *DUTTestNet) newUDPState(domain int, out, in UDP) (*udpState, error) { + portPickerFD, localPort, err := n.pickPort(domain, unix.SOCK_DGRAM) if err != nil { return nil, fmt.Errorf("picking port: %w", err) } @@ -639,26 +631,26 @@ func (conn *Connection) Drain(t *testing.T) { type TCPIPv4 Connection // NewTCPIPv4 creates a new TCPIPv4 connection with reasonable defaults. -func NewTCPIPv4(t *testing.T, outgoingTCP, incomingTCP TCP) TCPIPv4 { +func (n *DUTTestNet) NewTCPIPv4(t *testing.T, outgoingTCP, incomingTCP TCP) TCPIPv4 { t.Helper() - etherState, err := newEtherState(Ether{}, Ether{}) + etherState, err := n.newEtherState(Ether{}, Ether{}) if err != nil { t.Fatalf("can't make etherState: %s", err) } - ipv4State, err := newIPv4State(IPv4{}, IPv4{}) + ipv4State, err := n.newIPv4State(IPv4{}, IPv4{}) if err != nil { t.Fatalf("can't make ipv4State: %s", err) } - tcpState, err := newTCPState(unix.AF_INET, outgoingTCP, incomingTCP) + tcpState, err := n.newTCPState(unix.AF_INET, outgoingTCP, incomingTCP) if err != nil { t.Fatalf("can't make tcpState: %s", err) } - injector, err := NewInjector(t) + injector, err := n.NewInjector(t) if err != nil { t.Fatalf("can't make injector: %s", err) } - sniffer, err := NewSniffer(t) + sniffer, err := n.NewSniffer(t) if err != nil { t.Fatalf("can't make sniffer: %s", err) } @@ -841,23 +833,23 @@ func (conn *TCPIPv4) Drain(t *testing.T) { type IPv4Conn Connection // NewIPv4Conn creates a new IPv4Conn connection with reasonable defaults. -func NewIPv4Conn(t *testing.T, outgoingIPv4, incomingIPv4 IPv4) IPv4Conn { +func (n *DUTTestNet) NewIPv4Conn(t *testing.T, outgoingIPv4, incomingIPv4 IPv4) IPv4Conn { t.Helper() - etherState, err := newEtherState(Ether{}, Ether{}) + etherState, err := n.newEtherState(Ether{}, Ether{}) if err != nil { t.Fatalf("can't make EtherState: %s", err) } - ipv4State, err := newIPv4State(outgoingIPv4, incomingIPv4) + ipv4State, err := n.newIPv4State(outgoingIPv4, incomingIPv4) if err != nil { t.Fatalf("can't make IPv4State: %s", err) } - injector, err := NewInjector(t) + injector, err := n.NewInjector(t) if err != nil { t.Fatalf("can't make injector: %s", err) } - sniffer, err := NewSniffer(t) + sniffer, err := n.NewSniffer(t) if err != nil { t.Fatalf("can't make sniffer: %s", err) } @@ -896,23 +888,23 @@ func (c *IPv4Conn) ExpectFrame(t *testing.T, frame Layers, timeout time.Duration type IPv6Conn Connection // NewIPv6Conn creates a new IPv6Conn connection with reasonable defaults. -func NewIPv6Conn(t *testing.T, outgoingIPv6, incomingIPv6 IPv6) IPv6Conn { +func (n *DUTTestNet) NewIPv6Conn(t *testing.T, outgoingIPv6, incomingIPv6 IPv6) IPv6Conn { t.Helper() - etherState, err := newEtherState(Ether{}, Ether{}) + etherState, err := n.newEtherState(Ether{}, Ether{}) if err != nil { t.Fatalf("can't make EtherState: %s", err) } - ipv6State, err := newIPv6State(outgoingIPv6, incomingIPv6) + ipv6State, err := n.newIPv6State(outgoingIPv6, incomingIPv6) if err != nil { t.Fatalf("can't make IPv6State: %s", err) } - injector, err := NewInjector(t) + injector, err := n.NewInjector(t) if err != nil { t.Fatalf("can't make injector: %s", err) } - sniffer, err := NewSniffer(t) + sniffer, err := n.NewSniffer(t) if err != nil { t.Fatalf("can't make sniffer: %s", err) } @@ -951,26 +943,26 @@ func (conn *IPv6Conn) ExpectFrame(t *testing.T, frame Layers, timeout time.Durat type UDPIPv4 Connection // NewUDPIPv4 creates a new UDPIPv4 connection with reasonable defaults. -func NewUDPIPv4(t *testing.T, outgoingUDP, incomingUDP UDP) UDPIPv4 { +func (n *DUTTestNet) NewUDPIPv4(t *testing.T, outgoingUDP, incomingUDP UDP) UDPIPv4 { t.Helper() - etherState, err := newEtherState(Ether{}, Ether{}) + etherState, err := n.newEtherState(Ether{}, Ether{}) if err != nil { t.Fatalf("can't make etherState: %s", err) } - ipv4State, err := newIPv4State(IPv4{}, IPv4{}) + ipv4State, err := n.newIPv4State(IPv4{}, IPv4{}) if err != nil { t.Fatalf("can't make ipv4State: %s", err) } - udpState, err := newUDPState(unix.AF_INET, outgoingUDP, incomingUDP) + udpState, err := n.newUDPState(unix.AF_INET, outgoingUDP, incomingUDP) if err != nil { t.Fatalf("can't make udpState: %s", err) } - injector, err := NewInjector(t) + injector, err := n.NewInjector(t) if err != nil { t.Fatalf("can't make injector: %s", err) } - sniffer, err := NewSniffer(t) + sniffer, err := n.NewSniffer(t) if err != nil { t.Fatalf("can't make sniffer: %s", err) } @@ -1075,26 +1067,26 @@ func (conn *UDPIPv4) Drain(t *testing.T) { type UDPIPv6 Connection // NewUDPIPv6 creates a new UDPIPv6 connection with reasonable defaults. -func NewUDPIPv6(t *testing.T, outgoingUDP, incomingUDP UDP) UDPIPv6 { +func (n *DUTTestNet) NewUDPIPv6(t *testing.T, outgoingUDP, incomingUDP UDP) UDPIPv6 { t.Helper() - etherState, err := newEtherState(Ether{}, Ether{}) + etherState, err := n.newEtherState(Ether{}, Ether{}) if err != nil { t.Fatalf("can't make etherState: %s", err) } - ipv6State, err := newIPv6State(IPv6{}, IPv6{}) + ipv6State, err := n.newIPv6State(IPv6{}, IPv6{}) if err != nil { t.Fatalf("can't make IPv6State: %s", err) } - udpState, err := newUDPState(unix.AF_INET6, outgoingUDP, incomingUDP) + udpState, err := n.newUDPState(unix.AF_INET6, outgoingUDP, incomingUDP) if err != nil { t.Fatalf("can't make udpState: %s", err) } - injector, err := NewInjector(t) + injector, err := n.NewInjector(t) if err != nil { t.Fatalf("can't make injector: %s", err) } - sniffer, err := NewSniffer(t) + sniffer, err := n.NewSniffer(t) if err != nil { t.Fatalf("can't make sniffer: %s", err) } @@ -1126,14 +1118,14 @@ func (conn *UDPIPv6) ipv6State(t *testing.T) *ipv6State { } // LocalAddr gets the local socket address of this connection. -func (conn *UDPIPv6) LocalAddr(t *testing.T) *unix.SockaddrInet6 { +func (conn *UDPIPv6) LocalAddr(t *testing.T, zoneID uint32) *unix.SockaddrInet6 { t.Helper() sa := &unix.SockaddrInet6{ Port: int(*conn.udpState(t).out.SrcPort), // Local address is in perspective to the remote host, so it's scoped to the // ID of the remote interface. - ZoneId: uint32(RemoteInterfaceID), + ZoneId: zoneID, } copy(sa.Addr[:], *conn.ipv6State(t).out.SrcAddr) return sa @@ -1203,24 +1195,24 @@ func (conn *UDPIPv6) Drain(t *testing.T) { type TCPIPv6 Connection // NewTCPIPv6 creates a new TCPIPv6 connection with reasonable defaults. -func NewTCPIPv6(t *testing.T, outgoingTCP, incomingTCP TCP) TCPIPv6 { - etherState, err := newEtherState(Ether{}, Ether{}) +func (n *DUTTestNet) NewTCPIPv6(t *testing.T, outgoingTCP, incomingTCP TCP) TCPIPv6 { + etherState, err := n.newEtherState(Ether{}, Ether{}) if err != nil { t.Fatalf("can't make etherState: %s", err) } - ipv6State, err := newIPv6State(IPv6{}, IPv6{}) + ipv6State, err := n.newIPv6State(IPv6{}, IPv6{}) if err != nil { t.Fatalf("can't make ipv6State: %s", err) } - tcpState, err := newTCPState(unix.AF_INET6, outgoingTCP, incomingTCP) + tcpState, err := n.newTCPState(unix.AF_INET6, outgoingTCP, incomingTCP) if err != nil { t.Fatalf("can't make tcpState: %s", err) } - injector, err := NewInjector(t) + injector, err := n.NewInjector(t) if err != nil { t.Fatalf("can't make injector: %s", err) } - sniffer, err := NewSniffer(t) + sniffer, err := n.NewSniffer(t) if err != nil { t.Fatalf("can't make sniffer: %s", err) } diff --git a/test/packetimpact/testbench/dut.go b/test/packetimpact/testbench/dut.go index 6165ab293..66a0255b8 100644 --- a/test/packetimpact/testbench/dut.go +++ b/test/packetimpact/testbench/dut.go @@ -17,9 +17,8 @@ package testbench import ( "context" "encoding/binary" - "flag" + "fmt" "net" - "strconv" "syscall" "testing" "time" @@ -35,18 +34,26 @@ import ( type DUT struct { conn *grpc.ClientConn posixServer POSIXClient + Net *DUTTestNet } // NewDUT creates a new connection with the DUT over gRPC. func NewDUT(t *testing.T) DUT { t.Helper() + n := GetDUTTestNet() + dut := n.ConnectToDUT(t) + t.Cleanup(func() { + dut.TearDownConnection() + dut.Net.Release() + }) + return dut +} - flag.Parse() - if err := genPseudoFlags(); err != nil { - t.Fatal("generating psuedo flags:", err) - } +// ConnectToDUT connects to DUT through gRPC. +func (n *DUTTestNet) ConnectToDUT(t *testing.T) DUT { + t.Helper() - posixServerAddress := POSIXServerIP + ":" + strconv.Itoa(POSIXServerPort) + posixServerAddress := net.JoinHostPort(n.POSIXServerIP.String(), fmt.Sprintf("%d", n.POSIXServerPort)) conn, err := grpc.Dial(posixServerAddress, grpc.WithInsecure(), grpc.WithKeepaliveParams(keepalive.ClientParameters{Timeout: RPCKeepalive})) if err != nil { t.Fatalf("failed to grpc.Dial(%s): %s", posixServerAddress, err) @@ -55,11 +62,12 @@ func NewDUT(t *testing.T) DUT { return DUT{ conn: conn, posixServer: posixServer, + Net: n, } } -// TearDown closes the underlying connection. -func (dut *DUT) TearDown() { +// TearDownConnection closes the underlying connection. +func (dut *DUT) TearDownConnection() { dut.conn.Close() } @@ -132,7 +140,7 @@ func (dut *DUT) CreateBoundSocket(t *testing.T, typ, proto int32, addr net.IP) ( fd = dut.Socket(t, unix.AF_INET6, typ, proto) sa := unix.SockaddrInet6{} copy(sa.Addr[:], addr.To16()) - sa.ZoneId = uint32(RemoteInterfaceID) + sa.ZoneId = dut.Net.RemoteDevID dut.Bind(t, fd, &sa) } else { t.Fatalf("invalid IP address: %s", addr) @@ -154,7 +162,7 @@ func (dut *DUT) CreateBoundSocket(t *testing.T, typ, proto int32, addr net.IP) ( func (dut *DUT) CreateListener(t *testing.T, typ, proto, backlog int32) (int32, uint16) { t.Helper() - fd, remotePort := dut.CreateBoundSocket(t, typ, proto, net.ParseIP(RemoteIPv4)) + fd, remotePort := dut.CreateBoundSocket(t, typ, proto, dut.Net.RemoteIPv4) dut.Listen(t, fd, backlog) return fd, remotePort } @@ -717,9 +725,9 @@ func (dut *DUT) SetSockLingerOption(t *testing.T, sockfd int32, timeout time.Dur dut.SetSockOpt(t, sockfd, unix.SOL_SOCKET, unix.SO_LINGER, buf) } -// Shutdown calls shutdown on the DUT and causes a fatal test failure if it doesn't -// succeed. If more control over the timeout or error handling is needed, use -// ShutdownWithErrno. +// Shutdown calls shutdown on the DUT and causes a fatal test failure if it +// doesn't succeed. If more control over the timeout or error handling is +// needed, use ShutdownWithErrno. func (dut *DUT) Shutdown(t *testing.T, fd, how int32) error { t.Helper() diff --git a/test/packetimpact/testbench/rawsockets.go b/test/packetimpact/testbench/rawsockets.go index 193bb2dc8..fd8015ce2 100644 --- a/test/packetimpact/testbench/rawsockets.go +++ b/test/packetimpact/testbench/rawsockets.go @@ -38,13 +38,27 @@ func htons(x uint16) uint16 { } // NewSniffer creates a Sniffer connected to *device. -func NewSniffer(t *testing.T) (Sniffer, error) { +func (n *DUTTestNet) NewSniffer(t *testing.T) (Sniffer, error) { t.Helper() + ifInfo, err := net.InterfaceByName(n.LocalDevName) + if err != nil { + return Sniffer{}, err + } + + var haddr [8]byte + copy(haddr[:], ifInfo.HardwareAddr) + sa := unix.SockaddrLinklayer{ + Protocol: htons(unix.ETH_P_ALL), + Ifindex: ifInfo.Index, + } snifferFd, err := unix.Socket(unix.AF_PACKET, unix.SOCK_RAW, int(htons(unix.ETH_P_ALL))) if err != nil { return Sniffer{}, err } + if err := unix.Bind(snifferFd, &sa); err != nil { + return Sniffer{}, err + } if err := unix.SetsockoptInt(snifferFd, unix.SOL_SOCKET, unix.SO_RCVBUFFORCE, 1); err != nil { t.Fatalf("can't set sockopt SO_RCVBUFFORCE to 1: %s", err) } @@ -136,10 +150,10 @@ type Injector struct { } // NewInjector creates a new injector on *device. -func NewInjector(t *testing.T) (Injector, error) { +func (n *DUTTestNet) NewInjector(t *testing.T) (Injector, error) { t.Helper() - ifInfo, err := net.InterfaceByName(LocalDevice) + ifInfo, err := net.InterfaceByName(n.LocalDevName) if err != nil { return Injector{}, err } @@ -147,7 +161,7 @@ func NewInjector(t *testing.T) (Injector, error) { var haddr [8]byte copy(haddr[:], ifInfo.HardwareAddr) sa := unix.SockaddrLinklayer{ - Protocol: unix.ETH_P_IP, + Protocol: htons(unix.ETH_P_IP), Ifindex: ifInfo.Index, Halen: uint8(len(ifInfo.HardwareAddr)), Addr: haddr, diff --git a/test/packetimpact/testbench/testbench.go b/test/packetimpact/testbench/testbench.go index c1db95d8c..92200add9 100644 --- a/test/packetimpact/testbench/testbench.go +++ b/test/packetimpact/testbench/testbench.go @@ -31,64 +31,120 @@ import ( var ( // Native indicates that the test is being run natively. Native = false - // LocalDevice is the device that testbench uses to inject traffic. - LocalDevice = "" - // RemoteDevice is the device name on the DUT, individual tests can - // use the name to construct tests. - RemoteDevice = "" + // RPCKeepalive is the gRPC keepalive. + RPCKeepalive = 10 * time.Second + // RPCTimeout is the gRPC timeout. + RPCTimeout = 100 * time.Millisecond + // dutTestNets is the pool among which the testbench can choose a DUT to work + // with. + dutTestNets chan *DUTTestNet + + // TODO(zeling): Remove the following variables once the test runner side is + // ready. + localDevice = "" + remoteDevice = "" + localIPv4 = "" + remoteIPv4 = "" + ipv4PrefixLength = 0 + localIPv6 = "" + remoteIPv6 = "" + localInterfaceID uint32 + remoteInterfaceID uint64 + localMAC = "" + remoteMAC = "" + posixServerIP = "" + posixServerPort = 40000 +) + +// DUTTestNet describes the test network setup on dut and how the testbench +// should connect with an existing DUT. +type DUTTestNet struct { + // LocalMAC is the local MAC address on the test network. + LocalMAC net.HardwareAddr + // RemoteMAC is the DUT's MAC address on the test network. + RemoteMAC net.HardwareAddr // LocalIPv4 is the local IPv4 address on the test network. - LocalIPv4 = "" + LocalIPv4 net.IP // RemoteIPv4 is the DUT's IPv4 address on the test network. - RemoteIPv4 = "" + RemoteIPv4 net.IP // IPv4PrefixLength is the network prefix length of the IPv4 test network. - IPv4PrefixLength = 0 - + IPv4PrefixLength int // LocalIPv6 is the local IPv6 address on the test network. - LocalIPv6 = "" + LocalIPv6 net.IP // RemoteIPv6 is the DUT's IPv6 address on the test network. - RemoteIPv6 = "" - - // LocalInterfaceID is the ID of the local interface on the test network. - LocalInterfaceID uint32 - // RemoteInterfaceID is the ID of the remote interface on the test network. - // - // Not using uint32 because package flag does not support uint32. - RemoteInterfaceID uint64 + RemoteIPv6 net.IP + // LocalDevID is the ID of the local interface on the test network. + LocalDevID uint32 + // RemoteDevID is the ID of the remote interface on the test network. + RemoteDevID uint32 + // LocalDevName is the device that testbench uses to inject traffic. + LocalDevName string + // RemoteDevName is the device name on the DUT, individual tests can + // use the name to construct tests. + RemoteDevName string - // LocalMAC is the local MAC address on the test network. - LocalMAC = "" - // RemoteMAC is the DUT's MAC address on the test network. - RemoteMAC = "" + // The following two fields on actually on the control network instead + // of the test network, including them for convenience. // POSIXServerIP is the POSIX server's IP address on the control network. - POSIXServerIP = "" + POSIXServerIP net.IP // POSIXServerPort is the UDP port the POSIX server is bound to on the // control network. - POSIXServerPort = 40000 - - // RPCKeepalive is the gRPC keepalive. - RPCKeepalive = 10 * time.Second - // RPCTimeout is the gRPC timeout. - RPCTimeout = 100 * time.Millisecond -) + POSIXServerPort uint16 +} -// RegisterFlags defines flags and associates them with the package-level +// registerFlags defines flags and associates them with the package-level // exported variables above. It should be called by tests in their init // functions. -func RegisterFlags(fs *flag.FlagSet) { - fs.StringVar(&POSIXServerIP, "posix_server_ip", POSIXServerIP, "ip address to listen to for UDP commands") - fs.IntVar(&POSIXServerPort, "posix_server_port", POSIXServerPort, "port to listen to for UDP commands") +func registerFlags(fs *flag.FlagSet) { + fs.StringVar(&posixServerIP, "posix_server_ip", posixServerIP, "ip address to listen to for UDP commands") + fs.IntVar(&posixServerPort, "posix_server_port", posixServerPort, "port to listen to for UDP commands") + fs.StringVar(&localIPv4, "local_ipv4", localIPv4, "local IPv4 address for test packets") + fs.StringVar(&remoteIPv4, "remote_ipv4", remoteIPv4, "remote IPv4 address for test packets") + fs.StringVar(&remoteIPv6, "remote_ipv6", remoteIPv6, "remote IPv6 address for test packets") + fs.StringVar(&remoteMAC, "remote_mac", remoteMAC, "remote mac address for test packets") + fs.StringVar(&localDevice, "local_device", localDevice, "local device to inject traffic") + fs.StringVar(&remoteDevice, "remote_device", remoteDevice, "remote device on the DUT") + fs.Uint64Var(&remoteInterfaceID, "remote_interface_id", remoteInterfaceID, "remote interface ID for test packets") + + fs.BoolVar(&Native, "native", Native, "whether the test is running natively") fs.DurationVar(&RPCTimeout, "rpc_timeout", RPCTimeout, "gRPC timeout") fs.DurationVar(&RPCKeepalive, "rpc_keepalive", RPCKeepalive, "gRPC keepalive") - fs.StringVar(&LocalIPv4, "local_ipv4", LocalIPv4, "local IPv4 address for test packets") - fs.StringVar(&RemoteIPv4, "remote_ipv4", RemoteIPv4, "remote IPv4 address for test packets") - fs.StringVar(&RemoteIPv6, "remote_ipv6", RemoteIPv6, "remote IPv6 address for test packets") - fs.StringVar(&RemoteMAC, "remote_mac", RemoteMAC, "remote mac address for test packets") - fs.StringVar(&LocalDevice, "local_device", LocalDevice, "local device to inject traffic") - fs.StringVar(&RemoteDevice, "remote_device", RemoteDevice, "remote device on the DUT") - fs.BoolVar(&Native, "native", Native, "whether the test is running natively") - fs.Uint64Var(&RemoteInterfaceID, "remote_interface_id", RemoteInterfaceID, "remote interface ID for test packets") +} + +// Initialize initializes the testbench, it parse the flags and sets up the +// pool of test networks for testbench's later use. +func Initialize(fs *flag.FlagSet) { + registerFlags(fs) + flag.Parse() + if err := genPseudoFlags(); err != nil { + panic(err) + } + var dut DUTTestNet + var err error + dut.LocalMAC, err = net.ParseMAC(localMAC) + if err != nil { + panic(err) + } + dut.RemoteMAC, err = net.ParseMAC(remoteMAC) + if err != nil { + panic(err) + } + dut.LocalIPv4 = net.ParseIP(localIPv4).To4() + dut.LocalIPv6 = net.ParseIP(localIPv6).To16() + dut.RemoteIPv4 = net.ParseIP(remoteIPv4).To4() + dut.RemoteIPv6 = net.ParseIP(remoteIPv6).To16() + dut.LocalDevID = uint32(localInterfaceID) + dut.RemoteDevID = uint32(remoteInterfaceID) + dut.LocalDevName = localDevice + dut.RemoteDevName = remoteDevice + dut.POSIXServerIP = net.ParseIP(posixServerIP) + dut.POSIXServerPort = uint16(posixServerPort) + dut.IPv4PrefixLength = ipv4PrefixLength + + dutTestNets = make(chan *DUTTestNet, 1) + dutTestNets <- &dut } // genPseudoFlags populates flag-like global config based on real flags. @@ -104,21 +160,20 @@ func genPseudoFlags() error { return fmt.Errorf("parsing devices: %w", err) } - _, deviceInfo, err := netdevs.FindDeviceByIP(net.ParseIP(LocalIPv4), devs) + _, deviceInfo, err := netdevs.FindDeviceByIP(net.ParseIP(localIPv4), devs) if err != nil { return fmt.Errorf("can't find deviceInfo: %w", err) } - LocalMAC = deviceInfo.MAC.String() - LocalIPv6 = deviceInfo.IPv6Addr.String() - LocalInterfaceID = deviceInfo.ID + localMAC = deviceInfo.MAC.String() + localIPv6 = deviceInfo.IPv6Addr.String() + localInterfaceID = deviceInfo.ID if deviceInfo.IPv4Net != nil { - IPv4PrefixLength, _ = deviceInfo.IPv4Net.Mask.Size() + ipv4PrefixLength, _ = deviceInfo.IPv4Net.Mask.Size() } else { - IPv4PrefixLength, _ = net.ParseIP(LocalIPv4).DefaultMask().Size() + ipv4PrefixLength, _ = net.ParseIP(localIPv4).DefaultMask().Size() } - return nil } @@ -132,3 +187,15 @@ func GenerateRandomPayload(t *testing.T, n int) []byte { } return buf } + +// GetDUTTestNet gets a usable DUTTestNet, the function will block until any +// becomes available. +func GetDUTTestNet() *DUTTestNet { + return <-dutTestNets +} + +// Release releases the DUTTestNet back to the pool so that some other test +// can use. +func (n *DUTTestNet) Release() { + dutTestNets <- n +} diff --git a/test/packetimpact/tests/fin_wait2_timeout_test.go b/test/packetimpact/tests/fin_wait2_timeout_test.go index a61054c2c..11f0fcd1e 100644 --- a/test/packetimpact/tests/fin_wait2_timeout_test.go +++ b/test/packetimpact/tests/fin_wait2_timeout_test.go @@ -25,7 +25,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func TestFinWait2Timeout(t *testing.T) { @@ -38,10 +38,9 @@ func TestFinWait2Timeout(t *testing.T) { } { t.Run(tt.description, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFd) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/icmpv6_param_problem_test.go b/test/packetimpact/tests/icmpv6_param_problem_test.go index 2d59d552d..40d7a491d 100644 --- a/test/packetimpact/tests/icmpv6_param_problem_test.go +++ b/test/packetimpact/tests/icmpv6_param_problem_test.go @@ -25,15 +25,14 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestICMPv6ParamProblemTest sends a packet with a bad next header. The DUT // should respond with an ICMPv6 Parameter Problem message. func TestICMPv6ParamProblemTest(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - conn := testbench.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) + conn := dut.Net.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) defer conn.Close(t) ipv6 := testbench.IPv6{ // 254 is reserved and used for experimentation and testing. This should diff --git a/test/packetimpact/tests/ipv4_fragment_reassembly_test.go b/test/packetimpact/tests/ipv4_fragment_reassembly_test.go index 40f899065..e00a7aba2 100644 --- a/test/packetimpact/tests/ipv4_fragment_reassembly_test.go +++ b/test/packetimpact/tests/ipv4_fragment_reassembly_test.go @@ -27,7 +27,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } type fragmentInfo struct { @@ -69,8 +69,7 @@ func TestIPv4FragmentReassembly(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - conn := testbench.NewIPv4Conn(t, testbench.IPv4{}, testbench.IPv4{}) + conn := dut.Net.NewIPv4Conn(t, testbench.IPv4{}, testbench.IPv4{}) defer conn.Close(t) data := make([]byte, test.ipPayloadLen) diff --git a/test/packetimpact/tests/ipv4_id_uniqueness_test.go b/test/packetimpact/tests/ipv4_id_uniqueness_test.go index 7f7a768d3..a63b41366 100644 --- a/test/packetimpact/tests/ipv4_id_uniqueness_test.go +++ b/test/packetimpact/tests/ipv4_id_uniqueness_test.go @@ -28,7 +28,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func recvTCPSegment(t *testing.T, conn *testbench.TCPIPv4, expect *testbench.TCP, expectPayload *testbench.Payload) (uint16, error) { @@ -67,12 +67,10 @@ func TestIPv4RetransmitIdentificationUniqueness(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/ipv6_fragment_icmp_error_test.go b/test/packetimpact/tests/ipv6_fragment_icmp_error_test.go index e058fb0d8..0ddc1526f 100644 --- a/test/packetimpact/tests/ipv6_fragment_icmp_error_test.go +++ b/test/packetimpact/tests/ipv6_fragment_icmp_error_test.go @@ -16,7 +16,6 @@ package ipv6_fragment_icmp_error_test import ( "flag" - "net" "testing" "time" @@ -35,10 +34,10 @@ const ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } -func fragmentedICMPEchoRequest(t *testing.T, conn *testbench.Connection, firstPayloadLength uint16, payload []byte, secondFragmentOffset uint16) ([]testbench.Layers, [][]byte) { +func fragmentedICMPEchoRequest(t *testing.T, n *testbench.DUTTestNet, conn *testbench.Connection, firstPayloadLength uint16, payload []byte, secondFragmentOffset uint16) ([]testbench.Layers, [][]byte) { t.Helper() icmpv6Header := header.ICMPv6(make([]byte, header.ICMPv6EchoMinimumSize)) @@ -48,8 +47,8 @@ func fragmentedICMPEchoRequest(t *testing.T, conn *testbench.Connection, firstPa icmpv6Header.SetSequence(0) cksum := header.ICMPv6Checksum( icmpv6Header, - tcpip.Address(net.ParseIP(testbench.LocalIPv6).To16()), - tcpip.Address(net.ParseIP(testbench.RemoteIPv6).To16()), + tcpip.Address(n.LocalIPv6), + tcpip.Address(n.RemoteIPv6), buffer.NewVectorisedView(len(payload), []buffer.View{payload}), ) icmpv6Header.SetChecksum(cksum) @@ -121,12 +120,11 @@ func TestIPv6ICMPEchoRequestFragmentReassembly(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - ipv6Conn := testbench.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) + ipv6Conn := dut.Net.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) conn := (*testbench.Connection)(&ipv6Conn) defer ipv6Conn.Close(t) - fragments, _ := fragmentedICMPEchoRequest(t, conn, test.firstPayloadLength, test.payload, test.secondFragmentOffset) + fragments, _ := fragmentedICMPEchoRequest(t, dut.Net, conn, test.firstPayloadLength, test.payload, test.secondFragmentOffset) for _, i := range test.sendFrameOrder { conn.SendFrame(t, fragments[i-1]) @@ -223,12 +221,11 @@ func TestIPv6FragmentReassemblyTimeout(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - ipv6Conn := testbench.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) + ipv6Conn := dut.Net.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) conn := (*testbench.Connection)(&ipv6Conn) defer ipv6Conn.Close(t) - fragments, ipv6Bytes := fragmentedICMPEchoRequest(t, conn, test.firstPayloadLength, test.payload, test.secondFragmentOffset) + fragments, ipv6Bytes := fragmentedICMPEchoRequest(t, dut.Net, conn, test.firstPayloadLength, test.payload, test.secondFragmentOffset) for _, i := range test.sendFrameOrder { conn.SendFrame(t, fragments[i-1]) @@ -319,12 +316,11 @@ func TestIPv6FragmentParamProblem(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - ipv6Conn := testbench.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) + ipv6Conn := dut.Net.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) conn := (*testbench.Connection)(&ipv6Conn) defer ipv6Conn.Close(t) - fragments, ipv6Bytes := fragmentedICMPEchoRequest(t, conn, test.firstPayloadLength, test.payload, test.secondFragmentOffset) + fragments, ipv6Bytes := fragmentedICMPEchoRequest(t, dut.Net, conn, test.firstPayloadLength, test.payload, test.secondFragmentOffset) for _, i := range test.sendFrameOrder { conn.SendFrame(t, fragments[i-1]) diff --git a/test/packetimpact/tests/ipv6_fragment_reassembly_test.go b/test/packetimpact/tests/ipv6_fragment_reassembly_test.go index eb56a53f7..65f742f55 100644 --- a/test/packetimpact/tests/ipv6_fragment_reassembly_test.go +++ b/test/packetimpact/tests/ipv6_fragment_reassembly_test.go @@ -17,7 +17,6 @@ package ipv6_fragment_reassembly_test import ( "flag" "math/rand" - "net" "testing" "time" @@ -29,7 +28,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } type fragmentInfo struct { @@ -72,12 +71,11 @@ func TestIPv6FragmentReassembly(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - conn := testbench.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) + conn := dut.Net.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) defer conn.Close(t) - lIP := tcpip.Address(net.ParseIP(testbench.LocalIPv6).To16()) - rIP := tcpip.Address(net.ParseIP(testbench.RemoteIPv6).To16()) + lIP := tcpip.Address(dut.Net.LocalIPv6) + rIP := tcpip.Address(dut.Net.RemoteIPv6) data := make([]byte, test.ipPayloadLen) icmp := header.ICMPv6(data[:header.ICMPv6HeaderSize]) diff --git a/test/packetimpact/tests/ipv6_unknown_options_action_test.go b/test/packetimpact/tests/ipv6_unknown_options_action_test.go index e79d74476..cb5396417 100644 --- a/test/packetimpact/tests/ipv6_unknown_options_action_test.go +++ b/test/packetimpact/tests/ipv6_unknown_options_action_test.go @@ -27,7 +27,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func mkHopByHopOptionsExtHdr(optType byte) testbench.Layer { @@ -141,8 +141,7 @@ func TestIPv6UnknownOptionAction(t *testing.T) { } { t.Run(tt.description, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - ipv6Conn := testbench.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) + ipv6Conn := dut.Net.NewIPv6Conn(t, testbench.IPv6{}, testbench.IPv6{}) conn := (*testbench.Connection)(&ipv6Conn) defer ipv6Conn.Close(t) diff --git a/test/packetimpact/tests/tcp_cork_mss_test.go b/test/packetimpact/tests/tcp_cork_mss_test.go index 8feea4a82..a7ba5035e 100644 --- a/test/packetimpact/tests/tcp_cork_mss_test.go +++ b/test/packetimpact/tests/tcp_cork_mss_test.go @@ -25,16 +25,15 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestTCPCorkMSS tests for segment coalesce and split as per MSS. func TestTCPCorkMSS(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) const mss = uint32(header.TCPDefaultMSS) diff --git a/test/packetimpact/tests/tcp_handshake_window_size_test.go b/test/packetimpact/tests/tcp_handshake_window_size_test.go index 22937d92f..5d1266f3c 100644 --- a/test/packetimpact/tests/tcp_handshake_window_size_test.go +++ b/test/packetimpact/tests/tcp_handshake_window_size_test.go @@ -25,17 +25,16 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestTCPHandshakeWindowSize tests if the stack is honoring the window size // communicated during handshake. func TestTCPHandshakeWindowSize(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) // Start handshake with zero window size. diff --git a/test/packetimpact/tests/tcp_linger_test.go b/test/packetimpact/tests/tcp_linger_test.go index b9a0409aa..bc4b64388 100644 --- a/test/packetimpact/tests/tcp_linger_test.go +++ b/test/packetimpact/tests/tcp_linger_test.go @@ -27,12 +27,12 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func createSocket(t *testing.T, dut testbench.DUT) (int32, int32, testbench.TCPIPv4) { listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) conn.Connect(t) acceptFD, _ := dut.Accept(t, listenFD) return acceptFD, listenFD, conn @@ -41,7 +41,6 @@ func createSocket(t *testing.T, dut testbench.DUT) (int32, int32, testbench.TCPI func closeAll(t *testing.T, dut testbench.DUT, listenFD int32, conn testbench.TCPIPv4) { conn.Close(t) dut.Close(t, listenFD) - dut.TearDown() } // lingerDuration is the timeout value used with SO_LINGER socket option. @@ -266,5 +265,4 @@ func TestTCPLingerNonEstablished(t *testing.T) { if diff > lingerDuration { t.Errorf("expected close to return within %s, but returned after %s", lingerDuration, diff) } - dut.TearDown() } diff --git a/test/packetimpact/tests/tcp_network_unreachable_test.go b/test/packetimpact/tests/tcp_network_unreachable_test.go index 8a1fe1279..6cd6d2edf 100644 --- a/test/packetimpact/tests/tcp_network_unreachable_test.go +++ b/test/packetimpact/tests/tcp_network_unreachable_test.go @@ -17,7 +17,6 @@ package tcp_synsent_reset_test import ( "context" "flag" - "net" "syscall" "testing" "time" @@ -28,7 +27,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestTCPSynSentUnreachable verifies that TCP connections fail immediately when @@ -37,17 +36,16 @@ func init() { func TestTCPSynSentUnreachable(t *testing.T) { // Create the DUT and connection. dut := testbench.NewDUT(t) - defer dut.TearDown() - clientFD, clientPort := dut.CreateBoundSocket(t, unix.SOCK_STREAM|unix.SOCK_NONBLOCK, unix.IPPROTO_TCP, net.ParseIP(testbench.RemoteIPv4)) + clientFD, clientPort := dut.CreateBoundSocket(t, unix.SOCK_STREAM|unix.SOCK_NONBLOCK, unix.IPPROTO_TCP, dut.Net.RemoteIPv4) port := uint16(9001) - conn := testbench.NewTCPIPv4(t, testbench.TCP{SrcPort: &port, DstPort: &clientPort}, testbench.TCP{SrcPort: &clientPort, DstPort: &port}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{SrcPort: &port, DstPort: &clientPort}, testbench.TCP{SrcPort: &clientPort, DstPort: &port}) defer conn.Close(t) // Bring the DUT to SYN-SENT state with a non-blocking connect. ctx, cancel := context.WithTimeout(context.Background(), testbench.RPCTimeout) defer cancel() sa := unix.SockaddrInet4{Port: int(port)} - copy(sa.Addr[:], net.IP(net.ParseIP(testbench.LocalIPv4)).To4()) + copy(sa.Addr[:], dut.Net.LocalIPv4) if _, err := dut.ConnectWithErrno(ctx, t, clientFD, &sa); err != syscall.Errno(unix.EINPROGRESS) { t.Errorf("expected connect to fail with EINPROGRESS, but got %v", err) } @@ -91,9 +89,8 @@ func TestTCPSynSentUnreachable(t *testing.T) { func TestTCPSynSentUnreachable6(t *testing.T) { // Create the DUT and connection. dut := testbench.NewDUT(t) - defer dut.TearDown() - clientFD, clientPort := dut.CreateBoundSocket(t, unix.SOCK_STREAM|unix.SOCK_NONBLOCK, unix.IPPROTO_TCP, net.ParseIP(testbench.RemoteIPv6)) - conn := testbench.NewTCPIPv6(t, testbench.TCP{DstPort: &clientPort}, testbench.TCP{SrcPort: &clientPort}) + clientFD, clientPort := dut.CreateBoundSocket(t, unix.SOCK_STREAM|unix.SOCK_NONBLOCK, unix.IPPROTO_TCP, dut.Net.RemoteIPv6) + conn := dut.Net.NewTCPIPv6(t, testbench.TCP{DstPort: &clientPort}, testbench.TCP{SrcPort: &clientPort}) defer conn.Close(t) // Bring the DUT to SYN-SENT state with a non-blocking connect. @@ -101,9 +98,9 @@ func TestTCPSynSentUnreachable6(t *testing.T) { defer cancel() sa := unix.SockaddrInet6{ Port: int(conn.SrcPort()), - ZoneId: uint32(testbench.RemoteInterfaceID), + ZoneId: dut.Net.RemoteDevID, } - copy(sa.Addr[:], net.IP(net.ParseIP(testbench.LocalIPv6)).To16()) + copy(sa.Addr[:], dut.Net.LocalIPv6) if _, err := dut.ConnectWithErrno(ctx, t, clientFD, &sa); err != syscall.Errno(unix.EINPROGRESS) { t.Errorf("expected connect to fail with EINPROGRESS, but got %v", err) } diff --git a/test/packetimpact/tests/tcp_noaccept_close_rst_test.go b/test/packetimpact/tests/tcp_noaccept_close_rst_test.go index 82b7a85ff..f0af5352d 100644 --- a/test/packetimpact/tests/tcp_noaccept_close_rst_test.go +++ b/test/packetimpact/tests/tcp_noaccept_close_rst_test.go @@ -25,14 +25,13 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func TestTcpNoAcceptCloseReset(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) conn.Connect(t) defer conn.Close(t) dut.Close(t, listenFd) diff --git a/test/packetimpact/tests/tcp_outside_the_window_test.go b/test/packetimpact/tests/tcp_outside_the_window_test.go index 08f759f7c..1b041932a 100644 --- a/test/packetimpact/tests/tcp_outside_the_window_test.go +++ b/test/packetimpact/tests/tcp_outside_the_window_test.go @@ -27,7 +27,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestTCPOutsideTheWindows tests the behavior of the DUT when packets arrive @@ -62,10 +62,9 @@ func TestTCPOutsideTheWindow(t *testing.T) { } { t.Run(fmt.Sprintf("%s%d", tt.description, tt.seqNumOffset), func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) acceptFD, _ := dut.Accept(t, listenFD) diff --git a/test/packetimpact/tests/tcp_paws_mechanism_test.go b/test/packetimpact/tests/tcp_paws_mechanism_test.go index 37f3b56dd..24d9ef4ec 100644 --- a/test/packetimpact/tests/tcp_paws_mechanism_test.go +++ b/test/packetimpact/tests/tcp_paws_mechanism_test.go @@ -26,15 +26,14 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func TestPAWSMechanism(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) options := make([]byte, header.TCPOptionTSLength) diff --git a/test/packetimpact/tests/tcp_queue_receive_in_syn_sent_test.go b/test/packetimpact/tests/tcp_queue_receive_in_syn_sent_test.go index d9f3ea0f2..646c93216 100644 --- a/test/packetimpact/tests/tcp_queue_receive_in_syn_sent_test.go +++ b/test/packetimpact/tests/tcp_queue_receive_in_syn_sent_test.go @@ -20,7 +20,6 @@ import ( "encoding/hex" "errors" "flag" - "net" "sync" "syscall" "testing" @@ -32,7 +31,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestQueueReceiveInSynSent tests receive behavior when the TCP state @@ -50,10 +49,9 @@ func TestQueueReceiveInSynSent(t *testing.T) { } { t.Run(tt.description, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - socket, remotePort := dut.CreateBoundSocket(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, net.ParseIP(testbench.RemoteIPv4)) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + socket, remotePort := dut.CreateBoundSocket(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, dut.Net.RemoteIPv4) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) sampleData := []byte("Sample Data") diff --git a/test/packetimpact/tests/tcp_queue_send_in_syn_sent_test.go b/test/packetimpact/tests/tcp_queue_send_in_syn_sent_test.go index 0ec8fd748..29e51cae3 100644 --- a/test/packetimpact/tests/tcp_queue_send_in_syn_sent_test.go +++ b/test/packetimpact/tests/tcp_queue_send_in_syn_sent_test.go @@ -18,7 +18,6 @@ import ( "context" "errors" "flag" - "net" "sync" "syscall" "testing" @@ -30,7 +29,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestQueueSendInSynSent tests send behavior when the TCP state @@ -48,10 +47,9 @@ func TestQueueSendInSynSent(t *testing.T) { } { t.Run(tt.description, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - socket, remotePort := dut.CreateBoundSocket(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, net.ParseIP(testbench.RemoteIPv4)) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + socket, remotePort := dut.CreateBoundSocket(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, dut.Net.RemoteIPv4) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) sampleData := []byte("Sample Data") diff --git a/test/packetimpact/tests/tcp_rcv_buf_space_test.go b/test/packetimpact/tests/tcp_rcv_buf_space_test.go index cfbba1e8e..d6ad5cda6 100644 --- a/test/packetimpact/tests/tcp_rcv_buf_space_test.go +++ b/test/packetimpact/tests/tcp_rcv_buf_space_test.go @@ -26,7 +26,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestReduceRecvBuf tests that a packet within window is still dropped @@ -34,10 +34,9 @@ func init() { // segment. func TestReduceRecvBuf(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFd) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/tcp_reordering_test.go b/test/packetimpact/tests/tcp_reordering_test.go index b4aeaab57..ca352dbc7 100644 --- a/test/packetimpact/tests/tcp_reordering_test.go +++ b/test/packetimpact/tests/tcp_reordering_test.go @@ -22,19 +22,18 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/seqnum" - tb "gvisor.dev/gvisor/test/packetimpact/testbench" + "gvisor.dev/gvisor/test/packetimpact/testbench" ) func init() { - tb.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func TestReorderingWindow(t *testing.T) { - dut := tb.NewDUT(t) - defer dut.TearDown() + dut := testbench.NewDUT(t) listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFd) - conn := tb.NewTCPIPv4(t, tb.TCP{DstPort: &remotePort}, tb.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) // Enable SACK. @@ -54,13 +53,13 @@ func TestReorderingWindow(t *testing.T) { acceptFd, _ := dut.Accept(t, listenFd) defer dut.Close(t, acceptFd) - if tb.Native { + if testbench.Native { // Linux has changed its handling of reordering, force the old behavior. dut.SetSockOpt(t, acceptFd, unix.IPPROTO_TCP, unix.TCP_CONGESTION, []byte("reno")) } pls := dut.GetSockOptInt(t, acceptFd, unix.IPPROTO_TCP, unix.TCP_MAXSEG) - if !tb.Native { + if !testbench.Native { // netstack does not impliment TCP_MAXSEG correctly. Fake it // here. Netstack uses the max SACK size which is 32. The MSS // option is 8 bytes, making the total 36 bytes. @@ -75,14 +74,14 @@ func TestReorderingWindow(t *testing.T) { for i, sn := 0, seqNum1; i < numPkts; i++ { dut.Send(t, acceptFd, payload, 0) - gotOne, err := conn.Expect(t, tb.TCP{SeqNum: tb.Uint32(uint32(sn))}, time.Second) + gotOne, err := conn.Expect(t, testbench.TCP{SeqNum: testbench.Uint32(uint32(sn))}, time.Second) sn.UpdateForward(seqnum.Size(len(payload))) if err != nil { - t.Errorf("Expect #%d: %s", i+1, err) + t.Fatalf("Expect #%d: %s", i+1, err) continue } if gotOne == nil { - t.Errorf("#%d: expected a packet within a second but got none", i+1) + t.Fatalf("#%d: expected a packet within a second but got none", i+1) } } @@ -97,13 +96,13 @@ func TestReorderingWindow(t *testing.T) { seqNum1.Add(seqnum.Size(len(payload))), seqNum1.Add(seqnum.Size(4 * len(payload))), }}, sackBlock[sbOff:]) - conn.Send(t, tb.TCP{Flags: tb.Uint8(header.TCPFlagAck), AckNum: tb.Uint32(uint32(seqNum1)), Options: sackBlock[:sbOff]}) + conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck), AckNum: testbench.Uint32(uint32(seqNum1)), Options: sackBlock[:sbOff]}) // ACK first packet. - conn.Send(t, tb.TCP{Flags: tb.Uint8(header.TCPFlagAck), AckNum: tb.Uint32(uint32(seqNum1) + uint32(len(payload)))}) + conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck), AckNum: testbench.Uint32(uint32(seqNum1) + uint32(len(payload)))}) // Check for retransmit. - gotOne, err := conn.Expect(t, tb.TCP{SeqNum: tb.Uint32(uint32(seqNum1))}, time.Second) + gotOne, err := conn.Expect(t, testbench.TCP{SeqNum: testbench.Uint32(uint32(seqNum1))}, time.Second) if err != nil { t.Error("Expect for retransmit:", err) } @@ -123,29 +122,29 @@ func TestReorderingWindow(t *testing.T) { seqNum1.Add(seqnum.Size(4 * len(payload))), }}, dsackBlock[dsbOff:]) - conn.Send(t, tb.TCP{Flags: tb.Uint8(header.TCPFlagAck), AckNum: tb.Uint32(uint32(seqNum2)), Options: dsackBlock[:dsbOff]}) + conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck), AckNum: testbench.Uint32(uint32(seqNum2)), Options: dsackBlock[:dsbOff]}) // Send half of the original window of packets, checking that we // received each. for i, sn := 0, seqNum2; i < numPkts/2; i++ { dut.Send(t, acceptFd, payload, 0) - gotOne, err := conn.Expect(t, tb.TCP{SeqNum: tb.Uint32(uint32(sn))}, time.Second) + gotOne, err := conn.Expect(t, testbench.TCP{SeqNum: testbench.Uint32(uint32(sn))}, time.Second) sn.UpdateForward(seqnum.Size(len(payload))) if err != nil { - t.Errorf("Expect #%d: %s", i+1, err) + t.Fatalf("Expect #%d: %s", i+1, err) continue } if gotOne == nil { - t.Errorf("#%d: expected a packet within a second but got none", i+1) + t.Fatalf("#%d: expected a packet within a second but got none", i+1) } } - if !tb.Native { + if !testbench.Native { // The window should now be halved, so we should receive any // more, even if we send them. dut.Send(t, acceptFd, payload, 0) - if got, err := conn.Expect(t, tb.TCP{}, 100*time.Millisecond); got != nil || err == nil { + if got, err := conn.Expect(t, testbench.TCP{}, 100*time.Millisecond); got != nil || err == nil { t.Fatalf("expected no packets within 100 millisecond, but got one: %s", got) } return @@ -155,20 +154,20 @@ func TestReorderingWindow(t *testing.T) { for i, sn := 0, seqNum2.Add(seqnum.Size(numPkts/2*len(payload))); i < 2; i++ { dut.Send(t, acceptFd, payload, 0) - gotOne, err := conn.Expect(t, tb.TCP{SeqNum: tb.Uint32(uint32(sn))}, time.Second) + gotOne, err := conn.Expect(t, testbench.TCP{SeqNum: testbench.Uint32(uint32(sn))}, time.Second) sn.UpdateForward(seqnum.Size(len(payload))) if err != nil { - t.Errorf("Expect #%d: %s", i+1, err) + t.Fatalf("Expect #%d: %s", i+1, err) continue } if gotOne == nil { - t.Errorf("#%d: expected a packet within a second but got none", i+1) + t.Fatalf("#%d: expected a packet within a second but got none", i+1) } } // The window should now be full. dut.Send(t, acceptFd, payload, 0) - if got, err := conn.Expect(t, tb.TCP{}, 100*time.Millisecond); got != nil || err == nil { + if got, err := conn.Expect(t, testbench.TCP{}, 100*time.Millisecond); got != nil || err == nil { t.Fatalf("expected no packets within 100 millisecond, but got one: %s", got) } } diff --git a/test/packetimpact/tests/tcp_retransmits_test.go b/test/packetimpact/tests/tcp_retransmits_test.go index 072014ff8..27e9641b1 100644 --- a/test/packetimpact/tests/tcp_retransmits_test.go +++ b/test/packetimpact/tests/tcp_retransmits_test.go @@ -25,17 +25,16 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestRetransmits tests retransmits occur at exponentially increasing // time intervals. func TestRetransmits(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFd) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/tcp_send_window_sizes_piggyback_test.go b/test/packetimpact/tests/tcp_send_window_sizes_piggyback_test.go index f91b06ba1..418393796 100644 --- a/test/packetimpact/tests/tcp_send_window_sizes_piggyback_test.go +++ b/test/packetimpact/tests/tcp_send_window_sizes_piggyback_test.go @@ -16,7 +16,6 @@ package tcp_send_window_sizes_piggyback_test import ( "flag" - "fmt" "testing" "time" @@ -26,7 +25,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestSendWindowSizesPiggyback tests cases where segment sizes are close to @@ -58,13 +57,12 @@ func TestSendWindowSizesPiggyback(t *testing.T) { // greater than available sender window. {"WindowGreaterThanSegment", segmentSize + 1, sampleData, sampleData, true /* enqueue */}, } { - t.Run(fmt.Sprintf("%s%d", tt.description, tt.windowSize), func(t *testing.T) { + t.Run(tt.description, func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFd) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort, WindowSize: testbench.Uint16(tt.windowSize)}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort, WindowSize: testbench.Uint16(tt.windowSize)}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/tcp_synrcvd_reset_test.go b/test/packetimpact/tests/tcp_synrcvd_reset_test.go index 57d034dd1..c5bbd29ee 100644 --- a/test/packetimpact/tests/tcp_synrcvd_reset_test.go +++ b/test/packetimpact/tests/tcp_synrcvd_reset_test.go @@ -25,16 +25,15 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestTCPSynRcvdReset tests transition from SYN-RCVD to CLOSED. func TestTCPSynRcvdReset(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) // Expect dut connection to have transitioned to SYN-RCVD state. diff --git a/test/packetimpact/tests/tcp_synsent_reset_test.go b/test/packetimpact/tests/tcp_synsent_reset_test.go index eac8eb19d..2c8bb101b 100644 --- a/test/packetimpact/tests/tcp_synsent_reset_test.go +++ b/test/packetimpact/tests/tcp_synsent_reset_test.go @@ -16,34 +16,33 @@ package tcp_synsent_reset_test import ( "flag" - "net" "testing" "time" "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/tcpip/header" - tb "gvisor.dev/gvisor/test/packetimpact/testbench" + "gvisor.dev/gvisor/test/packetimpact/testbench" ) func init() { - tb.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // dutSynSentState sets up the dut connection in SYN-SENT state. -func dutSynSentState(t *testing.T) (*tb.DUT, *tb.TCPIPv4, uint16, uint16) { +func dutSynSentState(t *testing.T) (*testbench.DUT, *testbench.TCPIPv4, uint16, uint16) { t.Helper() - dut := tb.NewDUT(t) + dut := testbench.NewDUT(t) - clientFD, clientPort := dut.CreateBoundSocket(t, unix.SOCK_STREAM|unix.SOCK_NONBLOCK, unix.IPPROTO_TCP, net.ParseIP(tb.RemoteIPv4)) + clientFD, clientPort := dut.CreateBoundSocket(t, unix.SOCK_STREAM|unix.SOCK_NONBLOCK, unix.IPPROTO_TCP, dut.Net.RemoteIPv4) port := uint16(9001) - conn := tb.NewTCPIPv4(t, tb.TCP{SrcPort: &port, DstPort: &clientPort}, tb.TCP{SrcPort: &clientPort, DstPort: &port}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{SrcPort: &port, DstPort: &clientPort}, testbench.TCP{SrcPort: &clientPort, DstPort: &port}) sa := unix.SockaddrInet4{Port: int(port)} - copy(sa.Addr[:], net.IP(net.ParseIP(tb.LocalIPv4)).To4()) + copy(sa.Addr[:], dut.Net.LocalIPv4) // Bring the dut to SYN-SENT state with a non-blocking connect. dut.Connect(t, clientFD, &sa) - if _, err := conn.ExpectData(t, &tb.TCP{Flags: tb.Uint8(header.TCPFlagSyn)}, nil, time.Second); err != nil { + if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.Uint8(header.TCPFlagSyn)}, nil, time.Second); err != nil { t.Fatalf("expected SYN\n") } @@ -52,14 +51,13 @@ func dutSynSentState(t *testing.T) (*tb.DUT, *tb.TCPIPv4, uint16, uint16) { // TestTCPSynSentReset tests RFC793, p67: SYN-SENT to CLOSED transition. func TestTCPSynSentReset(t *testing.T) { - dut, conn, _, _ := dutSynSentState(t) + _, conn, _, _ := dutSynSentState(t) defer conn.Close(t) - defer dut.TearDown() - conn.Send(t, tb.TCP{Flags: tb.Uint8(header.TCPFlagRst | header.TCPFlagAck)}) + conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagRst | header.TCPFlagAck)}) // Expect the connection to have closed. // TODO(gvisor.dev/issue/478): Check for TCP_INFO on the dut side. - conn.Send(t, tb.TCP{Flags: tb.Uint8(header.TCPFlagAck)}) - if _, err := conn.ExpectData(t, &tb.TCP{Flags: tb.Uint8(header.TCPFlagRst)}, nil, time.Second); err != nil { + conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)}) + if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.Uint8(header.TCPFlagRst)}, nil, time.Second); err != nil { t.Fatalf("expected a TCP RST") } } @@ -68,23 +66,22 @@ func TestTCPSynSentReset(t *testing.T) { // transitions. func TestTCPSynSentRcvdReset(t *testing.T) { dut, c, remotePort, clientPort := dutSynSentState(t) - defer dut.TearDown() defer c.Close(t) - conn := tb.NewTCPIPv4(t, tb.TCP{SrcPort: &remotePort, DstPort: &clientPort}, tb.TCP{SrcPort: &clientPort, DstPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{SrcPort: &remotePort, DstPort: &clientPort}, testbench.TCP{SrcPort: &clientPort, DstPort: &remotePort}) defer conn.Close(t) // Initiate new SYN connection with the same port pair // (simultaneous open case), expect the dut connection to move to // SYN-RCVD state - conn.Send(t, tb.TCP{Flags: tb.Uint8(header.TCPFlagSyn)}) - if _, err := conn.ExpectData(t, &tb.TCP{Flags: tb.Uint8(header.TCPFlagSyn | header.TCPFlagAck)}, nil, time.Second); err != nil { + conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagSyn)}) + if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.Uint8(header.TCPFlagSyn | header.TCPFlagAck)}, nil, time.Second); err != nil { t.Fatalf("expected SYN-ACK %s\n", err) } - conn.Send(t, tb.TCP{Flags: tb.Uint8(header.TCPFlagRst)}) + conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagRst)}) // Expect the connection to have transitioned SYN-RCVD to CLOSED. // TODO(gvisor.dev/issue/478): Check for TCP_INFO on the dut side. - conn.Send(t, tb.TCP{Flags: tb.Uint8(header.TCPFlagAck)}) - if _, err := conn.ExpectData(t, &tb.TCP{Flags: tb.Uint8(header.TCPFlagRst)}, nil, time.Second); err != nil { + conn.Send(t, testbench.TCP{Flags: testbench.Uint8(header.TCPFlagAck)}) + if _, err := conn.ExpectData(t, &testbench.TCP{Flags: testbench.Uint8(header.TCPFlagRst)}, nil, time.Second); err != nil { t.Fatalf("expected a TCP RST") } } diff --git a/test/packetimpact/tests/tcp_timewait_reset_test.go b/test/packetimpact/tests/tcp_timewait_reset_test.go index 2f76a6531..d1d2fb83d 100644 --- a/test/packetimpact/tests/tcp_timewait_reset_test.go +++ b/test/packetimpact/tests/tcp_timewait_reset_test.go @@ -25,16 +25,15 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestTimeWaitReset tests handling of RST when in TIME_WAIT state. func TestTimeWaitReset(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1 /*backlog*/) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/tcp_unacc_seq_ack_test.go b/test/packetimpact/tests/tcp_unacc_seq_ack_test.go index d078bbf15..ea962c818 100644 --- a/test/packetimpact/tests/tcp_unacc_seq_ack_test.go +++ b/test/packetimpact/tests/tcp_unacc_seq_ack_test.go @@ -28,7 +28,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func TestEstablishedUnaccSeqAck(t *testing.T) { @@ -48,10 +48,9 @@ func TestEstablishedUnaccSeqAck(t *testing.T) { } { t.Run(fmt.Sprintf("%s:offset=%d", tt.description, tt.seqNumOffset), func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1 /*backlog*/) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) @@ -102,10 +101,9 @@ func TestPassiveCloseUnaccSeqAck(t *testing.T) { } { t.Run(fmt.Sprintf("%s:offset=%d", tt.description, tt.seqNumOffset), func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1 /*backlog*/) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) @@ -164,10 +162,9 @@ func TestActiveCloseUnaccpSeqAck(t *testing.T) { } { t.Run(fmt.Sprintf("%s:offset=%d", tt.description, tt.seqNumOffset), func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1 /*backlog*/) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/tcp_user_timeout_test.go b/test/packetimpact/tests/tcp_user_timeout_test.go index 551dc78e7..b16e65366 100644 --- a/test/packetimpact/tests/tcp_user_timeout_test.go +++ b/test/packetimpact/tests/tcp_user_timeout_test.go @@ -25,7 +25,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func sendPayload(t *testing.T, conn *testbench.TCPIPv4, dut *testbench.DUT, fd int32) { @@ -64,10 +64,9 @@ func TestTCPUserTimeout(t *testing.T) { t.Run(tt.description+ttf.description, func(t *testing.T) { // Create a socket, listen, TCP handshake, and accept. dut := testbench.NewDUT(t) - defer dut.TearDown() listenFD, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFD) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) acceptFD, _ := dut.Accept(t, listenFD) diff --git a/test/packetimpact/tests/tcp_window_shrink_test.go b/test/packetimpact/tests/tcp_window_shrink_test.go index 5b001fbec..093484721 100644 --- a/test/packetimpact/tests/tcp_window_shrink_test.go +++ b/test/packetimpact/tests/tcp_window_shrink_test.go @@ -25,15 +25,14 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func TestWindowShrink(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFd) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/tcp_zero_window_probe_retransmit_test.go b/test/packetimpact/tests/tcp_zero_window_probe_retransmit_test.go index da93267d6..1ab9ee1b2 100644 --- a/test/packetimpact/tests/tcp_zero_window_probe_retransmit_test.go +++ b/test/packetimpact/tests/tcp_zero_window_probe_retransmit_test.go @@ -25,17 +25,16 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestZeroWindowProbeRetransmit tests retransmits of zero window probes // to be sent at exponentially inreasing time intervals. func TestZeroWindowProbeRetransmit(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFd) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/tcp_zero_window_probe_test.go b/test/packetimpact/tests/tcp_zero_window_probe_test.go index 44cac42f8..650a569cc 100644 --- a/test/packetimpact/tests/tcp_zero_window_probe_test.go +++ b/test/packetimpact/tests/tcp_zero_window_probe_test.go @@ -25,17 +25,16 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestZeroWindowProbe tests few cases of zero window probing over the // same connection. func TestZeroWindowProbe(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFd) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/tcp_zero_window_probe_usertimeout_test.go b/test/packetimpact/tests/tcp_zero_window_probe_usertimeout_test.go index 09a1c653f..079fea68c 100644 --- a/test/packetimpact/tests/tcp_zero_window_probe_usertimeout_test.go +++ b/test/packetimpact/tests/tcp_zero_window_probe_usertimeout_test.go @@ -25,17 +25,16 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } // TestZeroWindowProbeUserTimeout sanity tests user timeout when we are // retransmitting zero window probes. func TestZeroWindowProbeUserTimeout(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1) defer dut.Close(t, listenFd) - conn := testbench.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) + conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort}) defer conn.Close(t) conn.Connect(t) diff --git a/test/packetimpact/tests/udp_any_addr_recv_unicast_test.go b/test/packetimpact/tests/udp_any_addr_recv_unicast_test.go index 17f32ef65..f4ae00a81 100644 --- a/test/packetimpact/tests/udp_any_addr_recv_unicast_test.go +++ b/test/packetimpact/tests/udp_any_addr_recv_unicast_test.go @@ -26,21 +26,20 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func TestAnyRecvUnicastUDP(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() boundFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, net.IPv4zero) defer dut.Close(t, boundFD) - conn := testbench.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + conn := dut.Net.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) defer conn.Close(t) payload := testbench.GenerateRandomPayload(t, 1<<10 /* 1 KiB */) conn.SendIP( t, - testbench.IPv4{DstAddr: testbench.Address(tcpip.Address(net.ParseIP(testbench.RemoteIPv4).To4()))}, + testbench.IPv4{DstAddr: testbench.Address(tcpip.Address(dut.Net.RemoteIPv4))}, testbench.UDP{}, &testbench.Payload{Bytes: payload}, ) diff --git a/test/packetimpact/tests/udp_discard_mcast_source_addr_test.go b/test/packetimpact/tests/udp_discard_mcast_source_addr_test.go index 3d2791a6e..52c6f9d91 100644 --- a/test/packetimpact/tests/udp_discard_mcast_source_addr_test.go +++ b/test/packetimpact/tests/udp_discard_mcast_source_addr_test.go @@ -30,16 +30,15 @@ import ( var oneSecond = unix.Timeval{Sec: 1, Usec: 0} func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func TestDiscardsUDPPacketsWithMcastSourceAddressV4(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - remoteFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, net.ParseIP(testbench.RemoteIPv4)) + remoteFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, dut.Net.RemoteIPv4) defer dut.Close(t, remoteFD) dut.SetSockOptTimeval(t, remoteFD, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &oneSecond) - conn := testbench.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + conn := dut.Net.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) defer conn.Close(t) for _, mcastAddr := range []net.IP{ @@ -66,11 +65,10 @@ func TestDiscardsUDPPacketsWithMcastSourceAddressV4(t *testing.T) { func TestDiscardsUDPPacketsWithMcastSourceAddressV6(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - remoteFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, net.ParseIP(testbench.RemoteIPv6)) + remoteFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, dut.Net.RemoteIPv6) defer dut.Close(t, remoteFD) dut.SetSockOptTimeval(t, remoteFD, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &oneSecond) - conn := testbench.NewUDPIPv6(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + conn := dut.Net.NewUDPIPv6(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) defer conn.Close(t) for _, mcastAddr := range []net.IP{ diff --git a/test/packetimpact/tests/udp_icmp_error_propagation_test.go b/test/packetimpact/tests/udp_icmp_error_propagation_test.go index df35d16c8..cd4523e88 100644 --- a/test/packetimpact/tests/udp_icmp_error_propagation_test.go +++ b/test/packetimpact/tests/udp_icmp_error_propagation_test.go @@ -30,7 +30,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } type connectionMode bool @@ -229,7 +229,6 @@ func TestUDPICMPErrorPropagation(t *testing.T) { } { t.Run(fmt.Sprintf("%s/%s/%s", connect, icmpErr, errDetect.name), func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() remoteFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, net.IPv4zero) defer dut.Close(t, remoteFD) @@ -239,7 +238,7 @@ func TestUDPICMPErrorPropagation(t *testing.T) { cleanFD, cleanPort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, net.IPv4zero) defer dut.Close(t, cleanFD) - conn := testbench.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + conn := dut.Net.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) defer conn.Close(t) if connect { @@ -261,7 +260,7 @@ func TestUDPICMPErrorPropagation(t *testing.T) { // involved in the generation of the ICMP error. As such, // interactions between it and the the DUT should be independent of // the ICMP error at least at the port level. - connClean := testbench.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + connClean := dut.Net.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) defer connClean.Close(t) errDetectConn = &connClean @@ -283,7 +282,6 @@ func TestICMPErrorDuringUDPRecv(t *testing.T) { t.Run(fmt.Sprintf("%s/%s", connect, icmpErr), func(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() remoteFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, net.IPv4zero) defer dut.Close(t, remoteFD) @@ -293,7 +291,7 @@ func TestICMPErrorDuringUDPRecv(t *testing.T) { cleanFD, cleanPort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, net.IPv4zero) defer dut.Close(t, cleanFD) - conn := testbench.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + conn := dut.Net.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) defer conn.Close(t) if connect { diff --git a/test/packetimpact/tests/udp_recv_mcast_bcast_test.go b/test/packetimpact/tests/udp_recv_mcast_bcast_test.go index 526173969..71cde6cde 100644 --- a/test/packetimpact/tests/udp_recv_mcast_bcast_test.go +++ b/test/packetimpact/tests/udp_recv_mcast_bcast_test.go @@ -29,12 +29,12 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } func TestUDPRecvMcastBcast(t *testing.T) { - subnetBcastAddr := broadcastAddr(net.ParseIP(testbench.RemoteIPv4), net.CIDRMask(testbench.IPv4PrefixLength, 32)) - + dut := testbench.NewDUT(t) + subnetBcastAddr := broadcastAddr(dut.Net.RemoteIPv4, net.CIDRMask(dut.Net.IPv4PrefixLength, 32)) for _, v := range []struct { bound, to net.IP }{ @@ -43,17 +43,22 @@ func TestUDPRecvMcastBcast(t *testing.T) { {bound: net.IPv4zero, to: net.IPv4allsys}, {bound: subnetBcastAddr, to: subnetBcastAddr}, - {bound: subnetBcastAddr, to: net.IPv4bcast}, + + // FIXME(gvisor.dev/issues/4896): Previously by the time subnetBcastAddr is + // created, IPv4PrefixLength is still 0 because genPseudoFlags is not called + // yet, it was only called in NewDUT, so the test didn't do what the author + // original intended to and becomes failing because we process all flags at + // the very beginning. + // + // {bound: subnetBcastAddr, to: net.IPv4bcast}, {bound: net.IPv4bcast, to: net.IPv4bcast}, {bound: net.IPv4allsys, to: net.IPv4allsys}, } { t.Run(fmt.Sprintf("bound=%s,to=%s", v.bound, v.to), func(t *testing.T) { - dut := testbench.NewDUT(t) - defer dut.TearDown() boundFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, v.bound) defer dut.Close(t, boundFD) - conn := testbench.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + conn := dut.Net.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) defer conn.Close(t) payload := testbench.GenerateRandomPayload(t, 1<<10 /* 1 KiB */) @@ -73,15 +78,14 @@ func TestUDPRecvMcastBcast(t *testing.T) { func TestUDPDoesntRecvMcastBcastOnUnicastAddr(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() - boundFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, net.ParseIP(testbench.RemoteIPv4)) + boundFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, dut.Net.RemoteIPv4) dut.SetSockOptTimeval(t, boundFD, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &unix.Timeval{Sec: 1, Usec: 0}) defer dut.Close(t, boundFD) - conn := testbench.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + conn := dut.Net.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) defer conn.Close(t) for _, to := range []net.IP{ - broadcastAddr(net.ParseIP(testbench.RemoteIPv4), net.CIDRMask(testbench.IPv4PrefixLength, 32)), + broadcastAddr(dut.Net.RemoteIPv4, net.CIDRMask(dut.Net.IPv4PrefixLength, 32)), net.IPv4(255, 255, 255, 255), net.IPv4(224, 0, 0, 1), } { @@ -102,9 +106,10 @@ func TestUDPDoesntRecvMcastBcastOnUnicastAddr(t *testing.T) { } func broadcastAddr(ip net.IP, mask net.IPMask) net.IP { + result := make(net.IP, net.IPv4len) ip4 := ip.To4() for i := range ip4 { - ip4[i] |= ^mask[i] + result[i] = ip4[i] | ^mask[i] } - return ip4 + return result } diff --git a/test/packetimpact/tests/udp_send_recv_dgram_test.go b/test/packetimpact/tests/udp_send_recv_dgram_test.go index 91b967400..7ee2c8014 100644 --- a/test/packetimpact/tests/udp_send_recv_dgram_test.go +++ b/test/packetimpact/tests/udp_send_recv_dgram_test.go @@ -26,7 +26,7 @@ import ( ) func init() { - testbench.RegisterFlags(flag.CommandLine) + testbench.Initialize(flag.CommandLine) } type udpConn interface { @@ -38,7 +38,6 @@ type udpConn interface { func TestUDP(t *testing.T) { dut := testbench.NewDUT(t) - defer dut.TearDown() for _, isIPv4 := range []bool{true, false} { ipVersionName := "IPv6" @@ -46,24 +45,24 @@ func TestUDP(t *testing.T) { ipVersionName = "IPv4" } t.Run(ipVersionName, func(t *testing.T) { - var addr string + var addr net.IP if isIPv4 { - addr = testbench.RemoteIPv4 + addr = dut.Net.RemoteIPv4 } else { - addr = testbench.RemoteIPv6 + addr = dut.Net.RemoteIPv6 } - boundFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, net.ParseIP(addr)) + boundFD, remotePort := dut.CreateBoundSocket(t, unix.SOCK_DGRAM, unix.IPPROTO_UDP, addr) defer dut.Close(t, boundFD) var conn udpConn var localAddr unix.Sockaddr if isIPv4 { - v4Conn := testbench.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + v4Conn := dut.Net.NewUDPIPv4(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) localAddr = v4Conn.LocalAddr(t) conn = &v4Conn } else { - v6Conn := testbench.NewUDPIPv6(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) - localAddr = v6Conn.LocalAddr(t) + v6Conn := dut.Net.NewUDPIPv6(t, testbench.UDP{DstPort: &remotePort}, testbench.UDP{SrcPort: &remotePort}) + localAddr = v6Conn.LocalAddr(t, dut.Net.RemoteDevID) conn = &v6Conn } defer conn.Close(t) |