func (gc *Cfg) checkErrors() error { var err error if net.ParseIP(gc.Auto.SubnetPool) == nil { return core.Errorf("invalid ip address pool %s", gc.Auto.SubnetPool) } _, err = netutils.ParseTagRanges(gc.Auto.VLANs, "vlan") if err != nil { return err } _, err = netutils.ParseTagRanges(gc.Auto.VXLANs, "vxlan") if err != nil { return err } if gc.Deploy.DefaultNetType != "vlan" && gc.Deploy.DefaultNetType != "vxlan" { return core.Errorf("unsupported net type %s", gc.Deploy.DefaultNetType) } if gc.Auto.SubnetLen > gc.Auto.AllocSubnetLen { return core.Errorf("subnet size %d is smaller than subnets (%d) to be allocated from it", gc.Auto.SubnetLen, gc.Auto.AllocSubnetLen) } return err }
func validateTenantConfig(tenant *intent.ConfigTenant) error { if tenant.Name == "" { return core.Errorf("invalid tenant name") } if err := checkPktTagType(tenant.DefaultNetType); err != nil { return err } if tenant.SubnetPool != "" { if _, _, err := net.ParseCIDR(tenant.SubnetPool); err != nil { return err } } if tenant.VLANs != "" { if _, err := netutils.ParseTagRanges(tenant.VLANs, "vlan"); err != nil { log.Errorf("error parsing vlan range '%s'. Error: %s", tenant.VLANs, err) return err } } if tenant.VXLANs != "" { if _, err := netutils.ParseTagRanges(tenant.VXLANs, "vxlan"); err != nil { log.Errorf("error parsing vxlan range '%s'.Error: %s", tenant.VXLANs, err) return err } } return nil }
// CreateGlobal sets the global state func CreateGlobal(stateDriver core.StateDriver, gc *intent.ConfigGlobal) error { // check for valid values switch gc.NwInfraType { case "default", "aci", "aci-opflex": // These values are acceptable. default: return errors.New("Invalid fabric mode") } _, err := netutils.ParseTagRanges(gc.VLANs, "vlan") if err != nil { return err } _, err = netutils.ParseTagRanges(gc.VXLANs, "vxlan") if err != nil { return err } masterGc := &mastercfg.GlobConfig{} masterGc.StateDriver = stateDriver masterGc.NwInfraType = gc.NwInfraType err = masterGc.Write() if err != nil { return err } // Setup global state gCfg := &gstate.Cfg{} gCfg.StateDriver = stateDriver gCfg.Auto.VLANs = gc.VLANs gCfg.Auto.VXLANs = gc.VXLANs // Delete old state gOper := &gstate.Oper{} gOper.StateDriver = stateDriver err = gOper.Read("") if err == nil { err = gCfg.DeleteResources() if err != nil { return err } } // setup resources err = gCfg.Process() if err != nil { log.Errorf("Error updating the config %+v. Error: %s", gCfg, err) return err } err = gCfg.Write() if err != nil { log.Errorf("error updating global config.Error: %s", err) return err } return nil }
func (gc *Cfg) checkErrors() error { var err error _, err = netutils.ParseTagRanges(gc.Auto.VLANs, "vlan") if err != nil { return err } _, err = netutils.ParseTagRanges(gc.Auto.VXLANs, "vxlan") if err != nil { return err } return err }
func (gc *Cfg) checkErrors(res string) error { var err error if res == "vlan" { _, err = netutils.ParseTagRanges(gc.Auto.VLANs, "vlan") if err != nil { return err } } else if res == "vxlan" { _, err = netutils.ParseTagRanges(gc.Auto.VXLANs, "vxlan") if err != nil { return err } } return err }
func (gc *Cfg) initVXLANBitset(vxlans string) (*resources.AutoVXLANCfgResource, uint, error) { vxlanRsrcCfg := &resources.AutoVXLANCfgResource{} vxlanRsrcCfg.VXLANs = netutils.CreateBitset(14) vxlanRange := netutils.TagRange{} vxlanRanges, err := netutils.ParseTagRanges(vxlans, "vxlan") if err != nil { return nil, 0, err } // XXX: REVISIT, we seem to accept one contiguous vxlan range vxlanRange = vxlanRanges[0] freeVXLANsStart := uint(vxlanRange.Min) - 1 for vxlan := vxlanRange.Min; vxlan <= vxlanRange.Max; vxlan++ { vxlanRsrcCfg.VXLANs.Set(uint(vxlan) - freeVXLANsStart) } // Initialize local vlan bitset vxlanRsrcCfg.LocalVLANs, err = gc.initVLANBitset(vxlanLocalVlanRange) if err != nil { return nil, 0, err } return vxlanRsrcCfg, freeVXLANsStart, nil }
//CheckInBitRange to check if range includes inuse vlans func (gc *Cfg) CheckInBitRange(ranges, inUse, pktTagType string) bool { tags := strings.Split(inUse, ",") if len(inUse) == 0 { return true } minUsed := 0 maxUsed := 0 if strings.Contains(tags[0], "-") { minUsed, _ = strconv.Atoi(strings.Split(tags[0], "-")[0]) maxUsed, _ = strconv.Atoi(strings.Split(tags[0], "-")[1]) } else { minUsed, _ = strconv.Atoi(tags[0]) maxUsed = minUsed } if len(inUse) > 1 { if strings.Contains(tags[len(tags)-1], "-") { maxUsed, _ = strconv.Atoi(strings.Split(tags[len(tags)-1], "-")[1]) } else { maxUsed, _ = strconv.Atoi(strings.TrimSpace(tags[len(tags)-1])) } } r, err := netutils.ParseTagRanges(ranges, pktTagType) if err != nil { return false } if r[0].Min > minUsed || r[0].Max < maxUsed { return false } return true }
func validateTenantConfig(tenant *intent.ConfigTenant) error { if tenant.Name == "" { return core.Errorf("invalid tenant name") } if tenant.VLANs != "" { if _, err := netutils.ParseTagRanges(tenant.VLANs, "vlan"); err != nil { log.Errorf("error parsing vlan range '%s'. Error: %s", tenant.VLANs, err) return err } } if tenant.VXLANs != "" { if _, err := netutils.ParseTagRanges(tenant.VXLANs, "vxlan"); err != nil { log.Errorf("error parsing vxlan range '%s'.Error: %s", tenant.VXLANs, err) return err } } return nil }
func (gc *Cfg) initVXLANBitset(vxlans string) (*resources.AutoVXLANCfgResource, uint, error) { vxlanRsrcCfg := &resources.AutoVXLANCfgResource{} vxlanRsrcCfg.VXLANs = netutils.CreateBitset(14) vxlanRange := netutils.TagRange{} vxlanRanges, err := netutils.ParseTagRanges(vxlans, "vxlan") if err != nil { return nil, 0, err } // XXX: REVISIT, we seem to accept one contiguous vxlan range vxlanRange = vxlanRanges[0] freeVXLANsStart := uint(vxlanRange.Min) for vxlan := vxlanRange.Min; vxlan <= vxlanRange.Max; vxlan++ { vxlanRsrcCfg.VXLANs.Set(uint(vxlan - vxlanRange.Min)) } availableVLANs, err := deriveAvailableVLANs(gc.StateDriver) if err != nil { return nil, 0, err } localVLANsReqd := vxlanRange.Max - vxlanRange.Min + 1 if count := availableVLANs.Count(); int(count) < localVLANsReqd { return nil, 0, core.Errorf("Available free local vlans (%d) is less than possible vxlans (%d)", count, vxlanRange.Max-vxlanRange.Min) } else if int(count) > localVLANsReqd { //only reserve the #vxlan amount of bits var clearBitMarker uint for i := 0; i < localVLANsReqd; i++ { clearBitMarker, _ = availableVLANs.NextSet(clearBitMarker) clearBitMarker++ } clearBitMarker++ for { if bit, ok := availableVLANs.NextSet(clearBitMarker); ok { availableVLANs.Clear(bit) } else { break } } } vxlanRsrcCfg.LocalVLANs = availableVLANs return vxlanRsrcCfg, freeVXLANsStart, nil }
func (gc *Cfg) initVLANBitset(vlans string) (*bitset.BitSet, error) { vlanBitset := netutils.CreateBitset(12) vlanRanges, err := netutils.ParseTagRanges(vlans, "vlan") if err != nil { return nil, err } for _, vlanRange := range vlanRanges { for vlan := vlanRange.Min; vlan <= vlanRange.Max; vlan++ { vlanBitset.Set(uint(vlan)) } } clearReservedVLANs(vlanBitset) return vlanBitset, nil }
// UpdateGlobal updates the global state func UpdateGlobal(stateDriver core.StateDriver, gc *intent.ConfigGlobal) error { log.Infof("Received global update with intent {%v}", gc) var err error gcfgUpdateList := []string{} masterGc := &mastercfg.GlobConfig{} masterGc.StateDriver = stateDriver masterGc.Read("global") gstate.GlobalMutex.Lock() defer gstate.GlobalMutex.Unlock() gCfg := &gstate.Cfg{} gCfg.StateDriver = stateDriver gCfg.Read("global") _, vlansInUse := gCfg.GetVlansInUse() _, vxlansInUse := gCfg.GetVxlansInUse() // check for valid values if gc.NwInfraType != "" { switch gc.NwInfraType { case "default", "aci", "aci-opflex": // These values are acceptable. default: return errors.New("Invalid fabric mode") } masterGc.NwInfraType = gc.NwInfraType } if gc.VLANs != "" { if !gCfg.CheckInBitRange(gc.VLANs, vlansInUse, "vlan") { return fmt.Errorf("cannot update the vlan range due to existing vlans %s", vlansInUse) } _, err := netutils.ParseTagRanges(gc.VLANs, "vlan") if err != nil { return err } gCfg.Auto.VLANs = gc.VLANs gcfgUpdateList = append(gcfgUpdateList, "vlan") } if gc.VXLANs != "" { if !gCfg.CheckInBitRange(gc.VXLANs, vxlansInUse, "vxlan") { return fmt.Errorf("cannot update the vxlan range due to existing vxlans %s", vxlansInUse) } _, err = netutils.ParseTagRanges(gc.VXLANs, "vxlan") if err != nil { return err } gCfg.Auto.VXLANs = gc.VXLANs gcfgUpdateList = append(gcfgUpdateList, "vxlan") } if gc.FwdMode != "" { masterGc.FwdMode = gc.FwdMode } if gc.ArpMode != "" { masterGc.ArpMode = gc.ArpMode } if len(gcfgUpdateList) > 0 { // Delete old state gOper := &gstate.Oper{} gOper.StateDriver = stateDriver err = gOper.Read("") if err == nil { for _, res := range gcfgUpdateList { err = gCfg.UpdateResources(res) if err != nil { return err } } } err = gCfg.Write() if err != nil { log.Errorf("error updating global config.Error: %s", err) return err } } err = masterGc.Write() if err != nil { return err } return nil }