// Allocate a new subnet. Returns an interface{} which for this method is always // SubnetIPLenPair. func (r *AutoSubnetCfgResource) Allocate() (interface{}, error) { oper := &AutoSubnetOperResource{} oper.StateDriver = r.StateDriver err := oper.Read(r.ID) if err != nil { return nil, err } subnet, ok := oper.FreeSubnets.NextSet(0) if !ok { return nil, core.Errorf("no subnets available.") } oper.FreeSubnets.Clear(subnet) var subnetIP string subnetIP, err = netutils.GetSubnetIP(r.SubnetPool.String(), r.SubnetPoolLen, r.AllocSubnetLen, subnet) if err != nil { return nil, err } pair := SubnetIPLenPair{IP: net.ParseIP(subnetIP), Len: r.AllocSubnetLen} err = oper.Write() if err != nil { return nil, err } return pair, nil }
// Allocate an address from the network func networkAllocAddress(nwCfg *mastercfg.CfgNetworkState, reqAddr string) (string, error) { var ipAddress string var ipAddrValue uint var found bool var err error // alloc address if reqAddr == "" { ipAddrValue, found = nwCfg.IPAllocMap.NextClear(0) if !found { log.Errorf("auto allocation failed - address exhaustion in subnet %s/%d", nwCfg.SubnetIP, nwCfg.SubnetLen) err = core.Errorf("auto allocation failed - address exhaustion in subnet %s/%d", nwCfg.SubnetIP, nwCfg.SubnetLen) return "", err } ipAddress, err = netutils.GetSubnetIP(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, ipAddrValue) if err != nil { log.Errorf("create eps: error acquiring subnet ip. Error: %s", err) return "", err } } else if reqAddr != "" && nwCfg.SubnetIP != "" { ipAddrValue, err = netutils.GetIPNumber(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, reqAddr) if err != nil { log.Errorf("create eps: error getting host id from hostIP %s Subnet %s/%d. Error: %s", reqAddr, nwCfg.SubnetIP, nwCfg.SubnetLen, err) return "", err } ipAddress = reqAddr } // Set the bitmap nwCfg.IPAllocMap.Set(ipAddrValue) err = nwCfg.Write() if err != nil { log.Errorf("error writing nw config. Error: %s", err) return "", err } return ipAddress, nil }
func allocSetEpAddress(ep *intent.ConfigEP, epCfg *drivers.OvsCfgEndpointState, nwCfg *drivers.OvsCfgNetworkState) (err error) { var ipAddrValue uint var found bool ipAddress := ep.IPAddress if ipAddress == "" { if ipAddrValue, found = nwCfg.IPAllocMap.NextClear(0); !found { log.Errorf("auto allocation failed - address exhaustion in subnet %s/%d", nwCfg.SubnetIP, nwCfg.SubnetLen) err = core.Errorf("auto allocation failed - address exhaustion in subnet %s/%d", nwCfg.SubnetIP, nwCfg.SubnetLen) return } ipAddress, err = netutils.GetSubnetIP( nwCfg.SubnetIP, nwCfg.SubnetLen, 32, ipAddrValue) if err != nil { log.Errorf("create eps: error acquiring subnet ip. Error: %s", err) return } } else if ipAddress != "" && nwCfg.SubnetIP != "" { ipAddrValue, err = netutils.GetIPNumber( nwCfg.SubnetIP, nwCfg.SubnetLen, 32, ipAddress) if err != nil { log.Errorf("create eps: error getting host id from hostIP %s Subnet %s/%d. Error: %s", ipAddress, nwCfg.SubnetIP, nwCfg.SubnetLen, err) return } } epCfg.IPAddress = ipAddress nwCfg.IPAllocMap.Set(ipAddrValue) // Set mac address which is derived from IP address ipAddr := net.ParseIP(ipAddress) macAddr := fmt.Sprintf("02:02:%02x:%02x:%02x:%02x", ipAddr[12], ipAddr[13], ipAddr[14], ipAddr[15]) epCfg.MacAddress = macAddr return }
// CreateNetwork creates a network from intent func CreateNetwork(network intent.ConfigNetwork, stateDriver core.StateDriver, tenantName string) error { var extPktTag, pktTag uint gCfg := gstate.Cfg{} gCfg.StateDriver = stateDriver err := gCfg.Read(tenantName) if err != nil { log.Errorf("error reading tenant cfg state. Error: %s", err) return err } tempRm, err := resources.GetStateResourceManager() if err != nil { return err } rm := core.ResourceManager(tempRm) // Create network state networkID := network.Name + "." + tenantName nwCfg := &mastercfg.CfgNetworkState{} nwCfg.StateDriver = stateDriver if nwCfg.Read(networkID) == nil { // TODO: check if parameters changed and apply an update if needed return nil } subnetIP, subnetLen, _ := netutils.ParseCIDR(network.SubnetCIDR) // construct and update network state nwCfg = &mastercfg.CfgNetworkState{ Tenant: tenantName, NetworkName: network.Name, PktTagType: network.PktTagType, SubnetIP: subnetIP, SubnetLen: subnetLen, Gateway: network.Gateway, } nwCfg.ID = networkID nwCfg.StateDriver = stateDriver if network.PktTagType == "" { nwCfg.PktTagType = gCfg.Deploy.DefaultNetType } if network.PktTag == 0 { if nwCfg.PktTagType == "vlan" { pktTag, err = gCfg.AllocVLAN(rm) if err != nil { return err } } else if nwCfg.PktTagType == "vxlan" { extPktTag, pktTag, err = gCfg.AllocVXLAN(rm) if err != nil { return err } } nwCfg.ExtPktTag = int(extPktTag) nwCfg.PktTag = int(pktTag) } else if network.PktTagType == "vxlan" { nwCfg.ExtPktTag = network.PktTag nwCfg.PktTag = network.PktTag } else if network.PktTagType == "vlan" { nwCfg.PktTag = network.PktTag // XXX: do configuration check, to make sure it is allowed } if nwCfg.SubnetIP == "" { nwCfg.SubnetLen = gCfg.Auto.AllocSubnetLen nwCfg.SubnetIP, err = gCfg.AllocSubnet(rm) if err != nil { return err } nwCfg.SubnetIsAllocated = true } defaultNwName, err := gCfg.AssignDefaultNetwork(network.Name) if err != nil { log.Errorf("error assigning the default network. Error: %s", err) return err } if network.Name == defaultNwName { // For auto derived subnets assign gateway ip be the last valid unicast ip the subnet if nwCfg.Gateway == "" && nwCfg.SubnetIsAllocated { var ipAddrValue uint ipAddrValue = (1 << (32 - nwCfg.SubnetLen)) - 2 nwCfg.Gateway, err = netutils.GetSubnetIP(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, ipAddrValue) if err != nil { return err } nwCfg.IPAllocMap.Set(ipAddrValue) } } netutils.InitSubnetBitset(&nwCfg.IPAllocMap, nwCfg.SubnetLen) err = nwCfg.Write() if err != nil { return err } // Create the network in docker subnetCIDR := fmt.Sprintf("%s/%d", nwCfg.SubnetIP, nwCfg.SubnetLen) err = createDockNet(nwCfg.ID, subnetCIDR, nwCfg.Gateway) if err != nil { log.Errorf("Error creating network %s in docker. Err: %v", nwCfg.ID, err) return err } // Attach service container endpoint to the network err = attachServiceContainer(tenantName, networkID, stateDriver) if err != nil { log.Errorf("Error attaching service container to network: %s. Err: %v", networkID, err) } return nil }