Skip to content

Commit

Permalink
Tap plugin
Browse files Browse the repository at this point in the history
This PR adds a plugin to create tap devices.

The tap device creation might differ between distros, so the plugin allows
to specify a distro parameter for customized handling of tap device creation
for a specific distro

Signed-off-by: mmirecki <mmirecki@redhat.com>
  • Loading branch information
mmirecki committed Jan 13, 2023
1 parent ec76e3c commit db6a11d
Show file tree
Hide file tree
Showing 29 changed files with 4,363 additions and 0 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/networkplumbing/go-nft v0.2.0
github.com/onsi/ginkgo v1.16.4
github.com/onsi/gomega v1.15.0
github.com/opencontainers/selinux v1.8.0
github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1
github.com/vishvananda/netlink v1.2.0-beta
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e
Expand All @@ -32,6 +33,7 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
github.com/willf/bitset v1.1.11 // indirect
go.opencensus.io v0.22.3 // indirect
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
golang.org/x/text v0.3.6 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
Expand Down Expand Up @@ -590,6 +591,7 @@ github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA=
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
Expand Down
5 changes: 5 additions & 0 deletions plugins/main/tap/distro/distro.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package distro

type Distro interface {
CreateLink(tmpName string, mtu int, nsFd int, nsPath string, multiqueue bool, mac string, owner int, group int) error
}
87 changes: 87 additions & 0 deletions plugins/main/tap/distro/rhel/rhel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package rhel

import (
"fmt"
"github.com/containernetworking/plugins/plugins/main/tap/distro"
"github.com/opencontainers/selinux/go-selinux"
"os/exec"
"strconv"
"strings"
"syscall"
)

var Rhel distro.Distro = CreateLink{}

type CreateLink struct{}

func (l CreateLink) CreateLink(tmpName string, mtu int, nsFd int, nsPath string, multique bool, mac string, owner int, group int) error {

err := setContainerSeBool()
if err != nil {
return err
}
err = createSelinuxTap(tmpName, mtu, nsFd, nsPath, multique, mac, owner, group)
if err != nil {
return err
}
return nil
}

func setContainerSeBool() error {
output, err := exec.Command("cat", "/sys/fs/selinux/booleans/container_use_devices").CombinedOutput()
if err != nil {
return fmt.Errorf("failed to run getsebool command %s: %v", string(output), err)
}
if strings.Contains(string(output), "off") {
output, err := exec.Command("setsebool", "-P", "container_use_devices", "true").CombinedOutput()
if err != nil {
return fmt.Errorf("failed to run setsebool command %s: %v", string(output), err)
}
}
return nil
}

// Due to issues with the vishvananda/netlink library (fix pending) this method is using the ip tool to set up
// the tap device.
func createSelinuxTap(tmpName string, mtu int, nsFd int, nsPath string, multiqueue bool, mac string, owner int, group int) error {
if err := selinux.SetExecLabel("system_u:system_r:container_t:s0"); err != nil {
return fmt.Errorf("failed set socket label: %v", err)
}

minFDToCloseOnExec := 3
maxFDToCloseOnExec := 256
// we want to share the parent process std{in|out|err} - fds 0 through 2.
// Since the FDs are inherited on fork / exec, we close on exec all others.
for fd := minFDToCloseOnExec; fd < maxFDToCloseOnExec; fd++ {
syscall.CloseOnExec(fd)
}

tapDeviceArgs := []string{"tuntap", "add", "mode", "tap", "name", tmpName}
if multiqueue {
tapDeviceArgs = append(tapDeviceArgs, "multi_queue")
}

if owner >= 0 {
tapDeviceArgs = append(tapDeviceArgs, "user", strconv.Itoa(owner))
}
if group >= 0 {
tapDeviceArgs = append(tapDeviceArgs, "group", strconv.Itoa(group))
}
output, err := exec.Command("ip", tapDeviceArgs...).CombinedOutput()
if err != nil {
return fmt.Errorf("failed to run command %s: %v", output, err)
}

tapDeviceArgs = []string{"link", "set", tmpName}
if mtu != 0 {
tapDeviceArgs = append(tapDeviceArgs, "mtu", strconv.Itoa(mtu))
}
if mac != "" {
tapDeviceArgs = append(tapDeviceArgs, "address", mac)
}
output, err = exec.Command("ip", tapDeviceArgs...).CombinedOutput()
if err != nil {
return fmt.Errorf("failed to run command %s: %v", output, err)
}
return nil
}

0 comments on commit db6a11d

Please sign in to comment.