@@ -163,6 +163,48 @@ func (g *Oper) Clear() error {
163
163
return g .StateDriver .ClearState (key )
164
164
}
165
165
166
+ // The following function derives the number of available vlan tags.
167
+ // XXX: Since it is run at netmaster, it is guaranteed to have a consistent view of
168
+ // resource usage. Revisit if this assumption changes, as then it might need to
169
+ // be moved to resource-manager
170
+ func deriveAvailableVlans (stateDriver core.StateDriver ) (* bitset.BitSet , error ) {
171
+ // available vlans = vlan-space - For each tenant (vlans + local-vxlan-vlans)
172
+ availableVlans := netutils .CreateBitset (12 )
173
+
174
+ // get all vlans
175
+ readVlanRsrc := & resources.AutoVlanCfgResource {}
176
+ readVlanRsrc .StateDriver = stateDriver
177
+ vlanRsrcs , err := readVlanRsrc .ReadAll ()
178
+ if core .ErrIfKeyExists (err ) != nil {
179
+ return nil , err
180
+ } else if err != nil {
181
+ vlanRsrcs = []core.State {}
182
+ }
183
+ for _ , rsrc := range vlanRsrcs {
184
+ cfg := rsrc .(* resources.AutoVlanCfgResource )
185
+ availableVlans = availableVlans .Union (cfg .Vlans )
186
+ }
187
+
188
+ //get all vxlan-vlans
189
+ readVxlanRsrc := & resources.AutoVxlanCfgResource {}
190
+ readVxlanRsrc .StateDriver = stateDriver
191
+ vxlanRsrcs , err := readVxlanRsrc .ReadAll ()
192
+ if core .ErrIfKeyExists (err ) != nil {
193
+ return nil , err
194
+ } else if err != nil {
195
+ vxlanRsrcs = []core.State {}
196
+ }
197
+ for _ , rsrc := range vxlanRsrcs {
198
+ cfg := rsrc .(* resources.AutoVxlanCfgResource )
199
+ availableVlans = availableVlans .Union (cfg .LocalVlans )
200
+ }
201
+
202
+ // subtract to get availableVlans
203
+ availableVlans = availableVlans .Complement ()
204
+ clearReservedVlans (availableVlans )
205
+ return availableVlans , nil
206
+ }
207
+
166
208
func (gc * Cfg ) initVxlanBitset (vxlans string ) (* resources.AutoVxlanCfgResource ,
167
209
uint , error ) {
168
210
@@ -182,26 +224,30 @@ func (gc *Cfg) initVxlanBitset(vxlans string) (*resources.AutoVxlanCfgResource,
182
224
vxlanRsrcCfg .Vxlans .Set (uint (vxlan - vxlanRange .Min ))
183
225
}
184
226
185
- // XXX: we should derive free-vlans by looking at all tenants,
186
- // instead of just one.
187
- vlanRsrcCfg := & resources.AutoVlanCfgResource {}
188
- vlanRsrcCfg .StateDriver = gc .StateDriver
189
- err = vlanRsrcCfg .Read (gc .Tenant )
190
- if core .ErrIfKeyExists (err ) != nil {
227
+ availableVlans , err := deriveAvailableVlans (gc .StateDriver )
228
+ if err != nil {
191
229
return nil , 0 , err
192
- } else if err != nil {
193
- // a vlan resource has not been defined, assume entire space available
194
- // for vxlan.
195
- vlanRsrcCfg .Vlans = netutils .CreateBitset (12 )
196
- vlanRsrcCfg .Vlans .ClearAll ()
197
230
}
198
- // available vlans are the ones that are configured to be not consumed by
199
- // vlan networks
200
- availableVlans := vlanRsrcCfg .Vlans .Complement ()
201
- clearReservedVlans (availableVlans )
202
- if count := availableVlans .Count (); int (count ) < vxlanRange .Max - vxlanRange .Min {
231
+
232
+ localVlansReqd := vxlanRange .Max - vxlanRange .Min + 1
233
+ if count := availableVlans .Count (); int (count ) < localVlansReqd {
203
234
return nil , 0 , & core.Error {Desc : fmt .Sprintf ("Available free local vlans (%d) is less than possible vxlans (%d)" ,
204
235
count , vxlanRange .Max - vxlanRange .Min )}
236
+ } else if int (count ) > localVlansReqd {
237
+ //only reserve the #vxlan amount of bits
238
+ var clearBitMarker uint = 0
239
+ for i := 0 ; i < localVlansReqd ; i ++ {
240
+ clearBitMarker , _ = availableVlans .NextSet (clearBitMarker )
241
+ clearBitMarker += 1
242
+ }
243
+ clearBitMarker += 1
244
+ for {
245
+ if bit , ok := availableVlans .NextSet (clearBitMarker ); ok {
246
+ availableVlans .Clear (bit )
247
+ } else {
248
+ break
249
+ }
250
+ }
205
251
}
206
252
207
253
vxlanRsrcCfg .LocalVlans = availableVlans
0 commit comments