diff --git a/cmd/fakeipam/fakeipam.go b/cmd/fakeipam/fakeipam.go index 150438ed..a85afbc5 100644 --- a/cmd/fakeipam/fakeipam.go +++ b/cmd/fakeipam/fakeipam.go @@ -4,8 +4,9 @@ import ( "errors" "net" "encoding/json" + "strconv" "github.com/containernetworking/cni/pkg/skel" - types "github.com/containernetworking/cni/pkg/types/020" + "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/cni/pkg/version" danmtypes "github.com/nokia/danm/crd/apis/danm/v1" ) @@ -44,27 +45,17 @@ func loadIpamConfig(rawConfig []byte) (danmtypes.IpamConfig,error) { return cniConf.Ipam, nil } -//TODO: CNI 0.2.0 style of result is used because SRIOV plugin can't handle newer format -//This should be generalized though, and return result should be current.Result in most cases -func createCniResult(ipamConf danmtypes.IpamConfig) (*types.Result,error) { - var ip4 = new(types.IPConfig) - var ip6 = new(types.IPConfig) +func createCniResult(ipamConf danmtypes.IpamConfig) (*current.Result,error) { + var resultIPs = []*current.IPConfig{} for _, ipamIp := range ipamConf.Ips { ip, ipNet, err := net.ParseCIDR(ipamIp.IpCidr) if err != nil { - return &types.Result{}, errors.New("Unable to parse the given IpamConfig.IpCidr: " + ipamIp.IpCidr) + return ¤t.Result{}, errors.New("Unable to parse the given IpamConfig.IpCidr: " + ipamIp.IpCidr) } ipNet.IP = ip - // CNI Result can have only one IP for each Version. - // In case multiple IPs are set with the same Version, the last one is used. - switch ipamIp.Version { - case 4: - ip4 = &types.IPConfig{IP: *ipNet} - case 6: - ip6 = &types.IPConfig{IP: *ipNet} - } + resultIPs = append(resultIPs, ¤t.IPConfig{Version: strconv.Itoa(ipamIp.Version), Address: *ipNet}) } - cniRes := &types.Result{IP4: ip4, IP6: ip6} + cniRes := ¤t.Result{CNIVersion: "0.3.1", IPs: resultIPs} return cniRes, nil } @@ -74,4 +65,4 @@ func freeIp(args *skel.CmdArgs) error { func main() { skel.PluginMain(reserveIp, freeIp, version.All) -} \ No newline at end of file +} diff --git a/crd/apis/danm/v1/types.go b/crd/apis/danm/v1/types.go index 41ecf14e..c98cfae1 100644 --- a/crd/apis/danm/v1/types.go +++ b/crd/apis/danm/v1/types.go @@ -9,8 +9,7 @@ const ( ) type CniBackend struct { - BackendName string - CniVersion string + CNIVersion string } // +genclient diff --git a/pkg/cnidel/cniconfs.go b/pkg/cnidel/cniconfs.go index a3de3fee..93722ad1 100644 --- a/pkg/cnidel/cniconfs.go +++ b/pkg/cnidel/cniconfs.go @@ -10,24 +10,22 @@ import ( ) var ( - supportedNativeCnis = []*cniBackendConfig { - &cniBackendConfig { - danmtypes.CniBackend { - BackendName: "sriov", - CniVersion: "0.3.1", + supportedNativeCnis = map[string]*cniBackendConfig { + "sriov": &cniBackendConfig { + CniBackend: danmtypes.CniBackend { + CNIVersion: "0.3.1", }, - cniConfigReader(getSriovCniConfig), - true, - true, + readConfig: cniConfigReader(getSriovCniConfig), + ipamNeeded: true, + deviceNeeded: true, }, - &cniBackendConfig { - danmtypes.CniBackend { - BackendName: "macvlan", - CniVersion: "0.3.1", + "macvlan": &cniBackendConfig { + CniBackend: danmtypes.CniBackend { + CNIVersion: "0.3.1", }, - cniConfigReader(getMacvlanCniConfig), - true, - false, + readConfig: cniConfigReader(getMacvlanCniConfig), + ipamNeeded: true, + deviceNeeded: false, }, } ) @@ -44,21 +42,22 @@ func readCniConfigFile(cniconfDir string, netInfo *danmtypes.DanmNet) ([]byte, e } //This function creates CNI configuration for the dynamic-level SR-IOV backend -func getSriovCniConfig(netInfo *danmtypes.DanmNet, ipamOptions danmtypes.IpamConfig, ep *danmtypes.DanmEp) ([]byte, error) { +func getSriovCniConfig(netInfo *danmtypes.DanmNet, ipamOptions danmtypes.IpamConfig, ep *danmtypes.DanmEp, cniVersion string) ([]byte, error) { + var sriovConfig SriovNet + // initialize common fields of "github.com/containernetworking/cni/pkg/types".NetConf + sriovConfig.CNIVersion = cniVersion + sriovConfig.Name = netInfo.Spec.NetworkID + sriovConfig.Type = "sriov" + // initialize SriovNet specific fields: pfname, err := sriov_utils.GetPfName(ep.Spec.Iface.DeviceID) if err != nil { return nil, errors.New("failed to get the name of the sriov PF for device "+ ep.Spec.Iface.DeviceID +" due to:" + err.Error()) } - vlanid := netInfo.Spec.Options.Vlan - sriovConfig := SriovNet { - Name: netInfo.Spec.NetworkID, - Type: "sriov", - PfName: pfname, - L2Mode: true, - Vlan: vlanid, - Ipam: ipamOptions, - DeviceID: ep.Spec.Iface.DeviceID, - } + sriovConfig.PfName = pfname + sriovConfig.L2Mode = true + sriovConfig.Vlan = netInfo.Spec.Options.Vlan + sriovConfig.Ipam = ipamOptions + sriovConfig.DeviceID = ep.Spec.Iface.DeviceID if len(ipamOptions.Ips) > 0 { sriovConfig.L2Mode = false } @@ -70,18 +69,18 @@ func getSriovCniConfig(netInfo *danmtypes.DanmNet, ipamOptions danmtypes.IpamCon } //This function creates CNI configuration for the dynamic-level MACVLAN backend -func getMacvlanCniConfig(netInfo *danmtypes.DanmNet, ipamOptions danmtypes.IpamConfig, ep *danmtypes.DanmEp) ([]byte, error) { - hDev := danmep.DetermineHostDeviceName(netInfo) - macvlanConfig := MacvlanNet { - Master: hDev, - //TODO: make these params configurable if required - Mode: "bridge", - MTU: 1500, - Ipam: ipamOptions, - } +func getMacvlanCniConfig(netInfo *danmtypes.DanmNet, ipamOptions danmtypes.IpamConfig, ep *danmtypes.DanmEp, cniVersion string) ([]byte, error) { + var macvlanConfig MacvlanNet + // initialize common fields of "github.com/containernetworking/cni/pkg/types".NetConf + macvlanConfig.CNIVersion = cniVersion + // initialize MacvlanNet specific fields: + macvlanConfig.Master = danmep.DetermineHostDeviceName(netInfo) + macvlanConfig.Mode = "bridge" //TODO: make these params configurable if required + macvlanConfig.MTU = 1500 + macvlanConfig.Ipam = ipamOptions rawConfig, err := json.Marshal(macvlanConfig) if err != nil { return nil, errors.New("Error putting together CNI config for MACVLAN plugin: " + err.Error()) } return rawConfig, nil -} \ No newline at end of file +} diff --git a/pkg/cnidel/cnidel.go b/pkg/cnidel/cnidel.go index 58bfc6ed..f5518a33 100644 --- a/pkg/cnidel/cnidel.go +++ b/pkg/cnidel/cnidel.go @@ -92,21 +92,19 @@ func DelegateInterfaceSetup(netConf *datastructs.NetConf, danmClient danmclients } func isIpamNeeded(cniType string) bool { - for _, cni := range supportedNativeCnis { - if cni.BackendName == cniType { - return cni.ipamNeeded - } + if cni, ok := supportedNativeCnis[strings.ToLower(cniType)]; ok { + return cni.ipamNeeded + } else { + return false } - return false } func IsDeviceNeeded(cniType string) bool { - for _, cni := range supportedNativeCnis { - if cni.BackendName == cniType { - return cni.deviceNeeded - } + if cni, ok := supportedNativeCnis[strings.ToLower(cniType)]; ok { + return cni.deviceNeeded + } else { + return false } - return false } func getCniIpamConfig(netinfo *danmtypes.DanmNet, ip4, ip6 string) (danmtypes.IpamConfig, error) { @@ -133,13 +131,11 @@ func getCniIpamConfig(netinfo *danmtypes.DanmNet, ip4, ip6 string) (danmtypes.Ip } func getCniPluginConfig(netConf *datastructs.NetConf, netInfo *danmtypes.DanmNet, ipamOptions danmtypes.IpamConfig, ep *danmtypes.DanmEp) ([]byte, error) { - cniType := strings.ToLower(netInfo.Spec.NetworkType) - for _, cni := range supportedNativeCnis { - if cni.BackendName == cniType { - return cni.readConfig(netInfo, ipamOptions, ep) - } + if cni, ok := supportedNativeCnis[strings.ToLower(netInfo.Spec.NetworkType)]; ok { + return cni.readConfig(netInfo, ipamOptions, ep, cni.CNIVersion) + } else { + return readCniConfigFile(netConf.CniConfigDir, netInfo) } - return readCniConfigFile(netConf.CniConfigDir, netInfo) } func execCniPlugin(cniType string, netInfo *danmtypes.DanmNet, rawConfig []byte, ep *danmtypes.DanmEp) (*current.Result,error) { diff --git a/pkg/cnidel/types.go b/pkg/cnidel/types.go index 1d295c3b..b83abd29 100644 --- a/pkg/cnidel/types.go +++ b/pkg/cnidel/types.go @@ -1,10 +1,11 @@ package cnidel import ( + "github.com/containernetworking/cni/pkg/types" danmtypes "github.com/nokia/danm/crd/apis/danm/v1" ) -type cniConfigReader func(netInfo *danmtypes.DanmNet, ipam danmtypes.IpamConfig, ep *danmtypes.DanmEp) ([]byte, error) +type cniConfigReader func(netInfo *danmtypes.DanmNet, ipam danmtypes.IpamConfig, ep *danmtypes.DanmEp, cniVersion string) ([]byte, error) type cniBackendConfig struct { danmtypes.CniBackend @@ -13,12 +14,9 @@ type cniBackendConfig struct { deviceNeeded bool } -// sriovNet represent the configuration of sriov plugin v1.0.0 +// sriovNet represent the configuration of sriov cni v1.0.0 type SriovNet struct { - // the name of the network - Name string `json:"name"` - // currently constant "sriov" - Type string `json:"type"` + types.NetConf // name of the PF since sriov cni v1.0.0 PfName string `json:"master"` // if true then add VF as L2 mode only, IPAM will not be executed @@ -31,7 +29,7 @@ type SriovNet struct { DeviceID string `json:"deviceID"` } -// VfInformation is a DeviceInfo desctiprtor expected by sriov plugin v1.0.0 +// VfInformation is a DeviceInfo descriptor expected by sriov cni v1.0.0 type VfInformation struct { PCIaddr string `json:"pci_addr"` Pfname string `json:"pfname"` @@ -39,6 +37,7 @@ type VfInformation struct { } type MacvlanNet struct { + types.NetConf //Name of the master NIC the MACVLAN slave needs to be connected to Master string `json:"master"` //The mode in which the MACVLAN slave is configured (default bridge) @@ -47,4 +46,4 @@ type MacvlanNet struct { MTU int `json:"mtu"` //IPAM configuration to be used for this network Ipam danmtypes.IpamConfig `json:"ipam,omitEmpty"` -} \ No newline at end of file +}