func getDefaultCNINetwork(pluginDir, binDir, vendorCNIDirPrefix string) (*cniNetwork, error) {
// 默认 pluginDir `/etc/cni/net.d`
pluginDir = DefaultNetDir
files, err := libcni.ConfFiles(pluginDir, []string{".conf", ".conflist", ".json"})
return nil, fmt.Errorf("No networks found in %s", pluginDir)
// 遍历所有的配置文件,只要匹配文件满足条件就返回,因此多个配置设置是无效的
for _, confFile := range files {
var confList *libcni.NetworkConfigList
if strings.HasSuffix(confFile, ".conflist") {
confList, err = libcni.ConfListFromFile(confFile)
glog.Warningf("Error loading CNI config list file %s: %v", confFile, err)
conf, err := libcni.ConfFromFile(confFile)
glog.Warningf("Error loading CNI config file %s: %v", confFile, err)
// Ensure the config has a "type" so we know what plugin to run.
// Also catches the case where somebody put a conflist into a conf file.
if conf.Network.Type == "" {
glog.Warningf("Error loading CNI config file %s: no 'type'; perhaps this is a .conflist?", confFile)
confList, err = libcni.ConfListFromConf(conf)
glog.Warningf("Error converting CNI config file %s to list: %v", confFile, err)
if len(confList.Plugins) == 0 {
glog.Warningf("CNI config list %s has no networks, skipping", confFile)
confType := confList.Plugins[0].Network.Type
// Search for vendor-specific plugins as well as default plugins in the CNI codebase.
vendorDir := vendorCNIDir(vendorCNIDirPrefix, confType)
cninet := &libcni.CNIConfig{
Path: []string{vendorDir, binDir},
network := &cniNetwork{name: confList.Name, NetworkConfig: confList, CNIConfig: cninet}
return nil, fmt.Errorf("No valid networks found in %s", pluginDir)