Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions common/libnetwork/netavark/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strings"
"time"

"github.com/moby/sys/capability"
"github.com/sirupsen/logrus"
"go.podman.io/common/libnetwork/internal/rootlessnetns"
"go.podman.io/common/libnetwork/internal/util"
Expand Down Expand Up @@ -109,6 +110,11 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) {
// causes issues as this slower more complicated rootless-netns logic should not be used as root.
val, ok := os.LookupEnv(unshare.UsernsEnvName)
useRootlessNetns := ok && val == "done"
// Preserve rootless netns mode unless UID 0 has the networking capability
// needed to manage rootful netavark bridge state.
if useRootlessNetns && unshare.GetRootlessUID() == 0 && hasCapNetAdmin() {
useRootlessNetns = false
}
if useRootlessNetns {
netns, err = rootlessnetns.New(conf.NetworkRunDir, conf.Config)
if err != nil {
Expand Down Expand Up @@ -172,6 +178,17 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) {
return n, nil
}

func hasCapNetAdmin() bool {
currentCaps, err := capability.NewPid2(0)
if err != nil {
return false
}
if err = currentCaps.Load(); err != nil {
return false
}
return currentCaps.Get(capability.EFFECTIVE, capability.CAP_NET_ADMIN)
}

var builtinDrivers = []string{types.BridgeNetworkDriver, types.MacVLANNetworkDriver, types.IPVLANNetworkDriver}

// Drivers will return the list of supported network drivers
Expand Down
24 changes: 19 additions & 5 deletions common/libnetwork/network/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"path/filepath"

"github.com/moby/sys/capability"
"go.podman.io/common/libnetwork/netavark"
"go.podman.io/common/libnetwork/types"
"go.podman.io/common/pkg/config"
Expand Down Expand Up @@ -55,10 +56,10 @@ func netavarkBackendFromConf(store storage.Store, conf *config.Config, syslog bo

// We cannot use the runroot for rootful since the network namespace is shared for all
// libpod instances they also have to share the same ipam db.
// For rootless we have our own network namespace per libpod instances,
// For rootless users we have our own network namespace per libpod instances,
// so this is not a problem there.
runDir := netavarkRunDir
if unshare.IsRootless() {
if unshare.IsRootless() && (unshare.GetRootlessUID() != 0 || !hasCapNetAdmin()) {
runDir = filepath.Join(store.RunRoot(), "networks")
}

Expand All @@ -78,8 +79,21 @@ func netavarkBackendFromConf(store storage.Store, conf *config.Config, syslog bo
// use the graphroot for rootful since the network namespace is shared for all
// libpod instances.
func getDefaultNetavarkConfigDir(store storage.Store) string {
if !unshare.IsRootless() {
return netavarkConfigDir
// Preserve the existing rootless path layout unless UID 0 has the
// networking capability needed to manage rootful netavark bridge state.
if unshare.IsRootless() && (unshare.GetRootlessUID() != 0 || !hasCapNetAdmin()) {
return filepath.Join(store.GraphRoot(), "networks")
}
return filepath.Join(store.GraphRoot(), "networks")
return netavarkConfigDir
}

func hasCapNetAdmin() bool {
currentCaps, err := capability.NewPid2(0)
if err != nil {
return false
}
if err = currentCaps.Load(); err != nil {
return false
}
return currentCaps.Get(capability.EFFECTIVE, capability.CAP_NET_ADMIN)
}