gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/packetimpact/dut/native/main.go (about)

     1  // Copyright 2021 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //go:build linux && go1.10
    16  // +build linux,go1.10
    17  
    18  // The native binary is used to bring up a native linux DUT.
    19  package main
    20  
    21  import (
    22  	"context"
    23  	"flag"
    24  	"fmt"
    25  	"log"
    26  	"os"
    27  	"os/exec"
    28  	"strconv"
    29  
    30  	"golang.org/x/sys/unix"
    31  	"gvisor.dev/gvisor/pkg/test/testutil"
    32  	"gvisor.dev/gvisor/test/packetimpact/dut"
    33  	"gvisor.dev/gvisor/test/packetimpact/dut/linux"
    34  	"gvisor.dev/gvisor/test/packetimpact/testbench"
    35  )
    36  
    37  var _ dut.DUT = (*native)(nil)
    38  
    39  type native struct {
    40  	dut.Ifaces
    41  }
    42  
    43  func main() {
    44  	ifaces, err := dut.Init(flag.CommandLine)
    45  	if err != nil {
    46  		log.Fatal(err)
    47  	}
    48  	if err := dut.Run(&native{
    49  		Ifaces: ifaces,
    50  	}); err != nil {
    51  		log.Fatal(err)
    52  	}
    53  }
    54  
    55  // Bootstrap implements dut.DUT.
    56  func (n *native) Bootstrap(ctx context.Context) (testbench.DUTInfo, func() error, error) {
    57  	// Enable ICMP sockets.
    58  	if err := os.WriteFile("/proc/sys/net/ipv4/ping_group_range", []byte("0 0"), 0); err != nil {
    59  		return testbench.DUTInfo{}, nil, fmt.Errorf("failed to enable icmp sockets: %w", err)
    60  	}
    61  
    62  	// Find the posix_server binary.
    63  	path, err := testutil.FindFile(linux.PosixServerPath)
    64  	if err != nil {
    65  		return testbench.DUTInfo{}, nil, fmt.Errorf("failed to find the posix_server binary: %w", err)
    66  	}
    67  
    68  	// Start the process.
    69  	cmd := exec.CommandContext(ctx, path, "--ip", "0.0.0.0", "--port", strconv.FormatUint(dut.PosixServerPort, 10))
    70  	cmd.SysProcAttr = &unix.SysProcAttr{
    71  		Pdeathsig: unix.SIGKILL,
    72  	}
    73  	errPipe, err := cmd.StderrPipe()
    74  	if err != nil {
    75  		return testbench.DUTInfo{}, nil, fmt.Errorf("failed to create stderr pipe to the posix server process: %w", err)
    76  	}
    77  	if err := cmd.Start(); err != nil {
    78  		return testbench.DUTInfo{}, nil, fmt.Errorf("failed to start the posix server process: %w", err)
    79  	}
    80  	if err := dut.WaitForServer(errPipe); err != nil {
    81  		return testbench.DUTInfo{}, nil, fmt.Errorf("failed to wait for the server to listen: %w", err)
    82  	}
    83  
    84  	// Collect DUT information.
    85  	info, err := linux.DUTInfo(n.Ifaces)
    86  	if err != nil {
    87  		return testbench.DUTInfo{}, nil, fmt.Errorf("failed to collect information about the DUT: %w", err)
    88  	}
    89  	return info, cmd.Wait, nil
    90  }
    91  
    92  // Bootstrap implements dut.DUT
    93  func (*native) Cleanup() {
    94  	// For a native DUT case, we only need to cleanup the posix_server process which we set up to
    95  	// deliver a SIGKILL signal whenever we exit, so there is nothing to do here.
    96  }