createNetNS creates a new network namespace with the given name. The returned file is a file descriptor to the network namespace. Note: all cleanup is handled for you, you do not need to call Close on the returned file.
(t *testing.T, name string)
| 612 | // Note: all cleanup is handled for you, you do not need to call Close on the |
| 613 | // returned file. |
| 614 | func createNetNS(t *testing.T, name string) *os.File { |
| 615 | // We use ip-netns here because it handles the process of creating a |
| 616 | // disowned netns for us. |
| 617 | // The only way to create a network namespace is by calling unshare(2) or |
| 618 | // clone(2) with the CLONE_NEWNET flag, and as soon as the last process in a |
| 619 | // network namespace exits, the namespace is destroyed. |
| 620 | // However, if you create a bind mount of /proc/$PID/ns/net to a file, it |
| 621 | // will keep the namespace alive until the mount is removed. |
| 622 | // ip-netns does this for us. Without it, we would have to fork anyways. |
| 623 | // Later, we will use nsenter to enter this network namespace. |
| 624 | _, err := exec.Command("ip", "netns", "add", name).Output() |
| 625 | require.NoError(t, wrapExitErr(err), "create network namespace via ip-netns") |
| 626 | t.Cleanup(func() { |
| 627 | _, _ = exec.Command("ip", "netns", "delete", name).Output() |
| 628 | }) |
| 629 | |
| 630 | // Open /run/netns/$name to get a file descriptor to the network namespace. |
| 631 | netnsPath := fmt.Sprintf("/run/netns/%s", name) |
| 632 | file, err := os.OpenFile(netnsPath, os.O_RDONLY, 0) |
| 633 | require.NoError(t, err, "open network namespace file") |
| 634 | t.Cleanup(func() { |
| 635 | _ = file.Close() |
| 636 | }) |
| 637 | |
| 638 | // Exec "ip link set lo up" in the namespace to bring up loopback |
| 639 | // networking. |
| 640 | //nolint:gosec |
| 641 | _, err = exec.Command("ip", "-netns", name, "link", "set", "lo", "up").Output() |
| 642 | require.NoError(t, wrapExitErr(err), "bring up loopback interface in network namespace") |
| 643 | |
| 644 | return file |
| 645 | } |
| 646 | |
| 647 | // createBridge creates a bridge in the given network namespace. The bridge is |
| 648 | // automatically brought up. |
no test coverage detected