Skip to content

Commit 31900cd

Browse files
author
mmirecki
committed
Tap plugin
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 <[email protected]>
1 parent ec76e3c commit 31900cd

29 files changed

+4369
-0
lines changed

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ require (
1717
github.com/networkplumbing/go-nft v0.2.0
1818
github.com/onsi/ginkgo v1.16.4
1919
github.com/onsi/gomega v1.15.0
20+
github.com/opencontainers/selinux v1.8.0
2021
github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1
2122
github.com/vishvananda/netlink v1.2.0-beta
2223
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e
@@ -32,6 +33,7 @@ require (
3233
github.com/pkg/errors v0.9.1 // indirect
3334
github.com/sirupsen/logrus v1.8.1 // indirect
3435
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
36+
github.com/willf/bitset v1.1.11 // indirect
3537
go.opencensus.io v0.22.3 // indirect
3638
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
3739
golang.org/x/text v0.3.6 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
478478
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
479479
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
480480
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
481+
github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM=
481482
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
482483
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
483484
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
@@ -590,6 +591,7 @@ github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1
590591
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA=
591592
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
592593
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
594+
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
593595
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
594596
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
595597
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=

plugins/main/tap/distro/distro.go

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package distro
2+
3+
type Distro interface {
4+
CreateLink(tmpName string, mtu int, nsFd int, nsPath string, multiqueue bool, mac string, owner int, group int) error
5+
}

plugins/main/tap/distro/rhel/rhel.go

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package rhel
2+
3+
import (
4+
"fmt"
5+
"github.com/containernetworking/plugins/plugins/main/tap/distro"
6+
"github.com/opencontainers/selinux/go-selinux"
7+
"os/exec"
8+
"strconv"
9+
"strings"
10+
"syscall"
11+
)
12+
13+
var Rhel distro.Distro = CreateLink{}
14+
15+
type CreateLink struct{}
16+
17+
func (l CreateLink) CreateLink(tmpName string, mtu int, nsFd int, nsPath string, multique bool, mac string, owner int, group int) error {
18+
19+
err := setContainerSeBool()
20+
if err != nil {
21+
return err
22+
}
23+
err = createSelinuxTap(tmpName, mtu, nsFd, nsPath, multique, mac, owner, group)
24+
if err != nil {
25+
return err
26+
}
27+
return nil
28+
}
29+
30+
func setContainerSeBool() error {
31+
output, err := exec.Command("cat", "/sys/fs/selinux/booleans/container_use_devices").CombinedOutput()
32+
if err != nil {
33+
return fmt.Errorf("failed to run getsebool command %s: %v", string(output), err)
34+
}
35+
if strings.Contains(string(output), "off") {
36+
output, err := exec.Command("setsebool", "-P", "container_use_devices", "true").CombinedOutput()
37+
if err != nil {
38+
return fmt.Errorf("failed to run setsebool command %s: %v", string(output), err)
39+
}
40+
}
41+
return nil
42+
}
43+
44+
// Due to issues with the vishvananda/netlink library (fix pending) this method is using the ip tool to set up
45+
// the tap device.
46+
func createSelinuxTap(tmpName string, mtu int, nsFd int, nsPath string, multiqueue bool, mac string, owner int, group int) error {
47+
if err := selinux.SetExecLabel("system_u:system_r:container_t:s0"); err != nil {
48+
return fmt.Errorf("failed set socket label: %v", err)
49+
}
50+
51+
minFDToCloseOnExec := 3
52+
maxFDToCloseOnExec := 256
53+
// we want to share the parent process std{in|out|err} - fds 0 through 2.
54+
// Since the FDs are inherited on fork / exec, we close on exec all others.
55+
for fd := minFDToCloseOnExec; fd < maxFDToCloseOnExec; fd++ {
56+
syscall.CloseOnExec(fd)
57+
}
58+
59+
tapDeviceArgs := []string{"tuntap", "add", "mode", "tap", "name", tmpName}
60+
if multiqueue {
61+
tapDeviceArgs = append(tapDeviceArgs, "multi_queue")
62+
}
63+
64+
if owner >= 0 {
65+
tapDeviceArgs = append(tapDeviceArgs, "user", strconv.Itoa(owner))
66+
}
67+
if group >= 0 {
68+
tapDeviceArgs = append(tapDeviceArgs, "group", strconv.Itoa(group))
69+
}
70+
output, err := exec.Command("ip", tapDeviceArgs...).CombinedOutput()
71+
if err != nil {
72+
return fmt.Errorf("failed to run command %s: %v", output, err)
73+
}
74+
75+
tapDeviceArgs = []string{"link", "set", tmpName}
76+
if mtu != 0 {
77+
tapDeviceArgs = append(tapDeviceArgs, "mtu", strconv.Itoa(mtu))
78+
}
79+
if mac != "" {
80+
tapDeviceArgs = append(tapDeviceArgs, "address", mac)
81+
}
82+
output, err = exec.Command("ip", tapDeviceArgs...).CombinedOutput()
83+
if err != nil {
84+
return fmt.Errorf("failed to run command %s: %v", output, err)
85+
}
86+
return nil
87+
}

0 commit comments

Comments
 (0)