//go:build (linux || freebsd) && cni package network import ( "errors" "fmt" "os" "path/filepath" "github.com/containers/common/libnetwork/cni" "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/machine" "github.com/containers/storage" "github.com/containers/storage/pkg/homedir" "github.com/containers/storage/pkg/unshare" ) const ( // cniConfigDirRootless is the directory in XDG_CONFIG_HOME for cni plugins cniConfigDirRootless = "cni/net.d/" cniSupported = true ) func getCniInterface(conf *config.Config) (types.ContainerNetwork, error) { confDir := conf.Network.NetworkConfigDir if confDir == "" { var err error confDir, err = getDefaultCNIConfigDir() if err != nil { return nil, err } } return cni.NewCNINetworkInterface(&cni.InitConfig{ Config: conf, CNIConfigDir: confDir, RunDir: conf.Engine.TmpDir, IsMachine: machine.IsGvProxyBased(), }) } func getDefaultCNIConfigDir() (string, error) { if !unshare.IsRootless() { return cniConfigDir, nil } configHome, err := homedir.GetConfigHome() if err != nil { return "", err } return filepath.Join(configHome, cniConfigDirRootless), nil } func networkBackendFromStore(store storage.Store, conf *config.Config) (backend types.NetworkBackend, err error) { _, err = conf.FindHelperBinary("netavark", false) if err != nil { // if we cannot find netavark use CNI return types.CNI, nil } // If there are any containers then return CNI cons, err := store.Containers() if err != nil { return "", err } if len(cons) != 0 { return types.CNI, nil } // If there are any non ReadOnly images then return CNI imgs, err := store.Images() if err != nil { return "", err } for _, i := range imgs { if !i.ReadOnly { return types.CNI, nil } } // If there are CNI Networks then return CNI cniInterface, err := getCniInterface(conf) if err == nil { nets, err := cniInterface.NetworkList() // there is always a default network so check > 1 if err != nil && !errors.Is(err, os.ErrNotExist) { return "", err } if len(nets) > 1 { // we do not have a fresh system so use CNI return types.CNI, nil } } return types.Netavark, nil } func backendFromType(backend types.NetworkBackend, store storage.Store, conf *config.Config, syslog bool) (types.NetworkBackend, types.ContainerNetwork, error) { switch backend { case types.Netavark: netInt, err := netavarkBackendFromConf(store, conf, syslog) if err != nil { return "", nil, err } return types.Netavark, netInt, err case types.CNI: netInt, err := getCniInterface(conf) if err != nil { return "", nil, err } return types.CNI, netInt, err default: return "", nil, fmt.Errorf("unsupported network backend %q, check network_backend in containers.conf", backend) } }