diff --git a/link_linux.go b/link_linux.go index a424ade3..0818f466 100644 --- a/link_linux.go +++ b/link_linux.go @@ -1074,8 +1074,6 @@ func (h *Handle) linkModify(link Link, flags int) error { } if isTuntap { - // TODO: support user - // TODO: support group if tuntap.Mode < unix.IFF_TUN || tuntap.Mode > unix.IFF_TAP { return fmt.Errorf("Tuntap.Mode %v unknown", tuntap.Mode) } @@ -1121,6 +1119,18 @@ func (h *Handle) linkModify(link Link, flags int) error { return fmt.Errorf("Tuntap IOCTL TUNSETIFF failed [%d], errno %v", i, errno) } + _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TUNSETOWNER, uintptr(tuntap.Owner)) + if errno != 0 { + cleanupFds(fds) + return fmt.Errorf("Tuntap IOCTL TUNSETOWNER failed [%d], errno %v", i, errno) + } + + _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TUNSETGROUP, uintptr(tuntap.Group)) + if errno != 0 { + cleanupFds(fds) + return fmt.Errorf("Tuntap IOCTL TUNSETGROUP failed [%d], errno %v", i, errno) + } + // Set the tun device to non-blocking before use. The below comment // taken from: // diff --git a/link_test.go b/link_test.go index ce336719..af52a6ad 100644 --- a/link_test.go +++ b/link_test.go @@ -2191,6 +2191,28 @@ func TestLinkAddDelTuntapMq(t *testing.T) { Flags: TUNTAP_MULTI_QUEUE_DEFAULTS | TUNTAP_VNET_HDR}) } +func TestLinkAddDelTuntapOwnerGroup(t *testing.T) { + tearDown := setUpNetlinkTest(t) + defer tearDown() + + if err := syscall.Mount("sysfs", "/sys", "sysfs", syscall.MS_RDONLY, ""); err != nil { + t.Fatal("Cannot mount sysfs") + } + + defer func() { + if err := syscall.Unmount("/sys", 0); err != nil { + t.Fatal("Cannot umount /sys") + } + }() + + testLinkAddDel(t, &Tuntap{ + LinkAttrs: LinkAttrs{Name: "foo"}, + Mode: TUNTAP_MODE_TAP, + Owner: 0, + Group: 0, + }) +} + func TestVethPeerIndex(t *testing.T) { tearDown := setUpNetlinkTest(t) defer tearDown()