-
Notifications
You must be signed in to change notification settings - Fork 780
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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]>
- Loading branch information
mmirecki
committed
Jan 17, 2023
1 parent
ec76e3c
commit 6a616b0
Showing
29 changed files
with
4,372 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, securityContext string) error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package rhel | ||
|
||
import ( | ||
"fmt" | ||
"github.com/containernetworking/plugins/plugins/main/tap/distro" | ||
"github.com/opencontainers/selinux/go-selinux" | ||
"os" | ||
"os/exec" | ||
"strconv" | ||
"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, securityContext string) error { | ||
|
||
err := setContainerSeBool() | ||
if err != nil { | ||
return err | ||
} | ||
err = createSelinuxTap(tmpName, mtu, nsFd, nsPath, multique, mac, owner, group, securityContext) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func getSeBoolValue(sebool string) bool { | ||
file, err := os.ReadFile(sebool) | ||
if err != nil { | ||
return false | ||
} | ||
return len(file) > 0 && file[0] == '1' | ||
} | ||
|
||
func setContainerSeBool() error { | ||
if getSeBoolValue("/sys/fs/selinux/booleans/container_use_devices") { | ||
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, securityContext string) error { | ||
if securityContext != "" { | ||
if err := selinux.SetExecLabel(securityContext); 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 | ||
} |
Oops, something went wrong.