github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/ipam/structures.go (about) 1 package ipam 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net" 7 "strings" 8 "sync" 9 10 "github.com/docker/libnetwork/datastore" 11 "github.com/docker/libnetwork/ipamapi" 12 "github.com/docker/libnetwork/types" 13 ) 14 15 // SubnetKey is the pointer to the configured pools in each address space 16 type SubnetKey struct { 17 AddressSpace string 18 Subnet string 19 ChildSubnet string 20 } 21 22 // PoolData contains the configured pool data 23 type PoolData struct { 24 ParentKey SubnetKey 25 Pool *net.IPNet 26 Range *AddressRange `json:",omitempty"` 27 RefCount int 28 } 29 30 // addrSpace contains the pool configurations for the address space 31 type addrSpace struct { 32 subnets map[SubnetKey]*PoolData 33 dbIndex uint64 34 dbExists bool 35 id string 36 scope string 37 ds datastore.DataStore 38 alloc *Allocator 39 sync.Mutex 40 } 41 42 // AddressRange specifies first and last ip ordinal which 43 // identifies a range in a pool of addresses 44 type AddressRange struct { 45 Sub *net.IPNet 46 Start, End uint64 47 } 48 49 // String returns the string form of the AddressRange object 50 func (r *AddressRange) String() string { 51 return fmt.Sprintf("Sub: %s, range [%d, %d]", r.Sub, r.Start, r.End) 52 } 53 54 // MarshalJSON returns the JSON encoding of the Range object 55 func (r *AddressRange) MarshalJSON() ([]byte, error) { 56 m := map[string]interface{}{ 57 "Sub": r.Sub.String(), 58 "Start": r.Start, 59 "End": r.End, 60 } 61 return json.Marshal(m) 62 } 63 64 // UnmarshalJSON decodes data into the Range object 65 func (r *AddressRange) UnmarshalJSON(data []byte) error { 66 m := map[string]interface{}{} 67 err := json.Unmarshal(data, &m) 68 if err != nil { 69 return err 70 } 71 if r.Sub, err = types.ParseCIDR(m["Sub"].(string)); err != nil { 72 return err 73 } 74 r.Start = uint64(m["Start"].(float64)) 75 r.End = uint64(m["End"].(float64)) 76 return nil 77 } 78 79 // String returns the string form of the SubnetKey object 80 func (s *SubnetKey) String() string { 81 k := fmt.Sprintf("%s/%s", s.AddressSpace, s.Subnet) 82 if s.ChildSubnet != "" { 83 k = fmt.Sprintf("%s/%s", k, s.ChildSubnet) 84 } 85 return k 86 } 87 88 // FromString populates the SubnetKey object reading it from string 89 func (s *SubnetKey) FromString(str string) error { 90 if str == "" || !strings.Contains(str, "/") { 91 return types.BadRequestErrorf("invalid string form for subnetkey: %s", str) 92 } 93 94 p := strings.Split(str, "/") 95 if len(p) != 3 && len(p) != 5 { 96 return types.BadRequestErrorf("invalid string form for subnetkey: %s", str) 97 } 98 s.AddressSpace = p[0] 99 s.Subnet = fmt.Sprintf("%s/%s", p[1], p[2]) 100 if len(p) == 5 { 101 s.ChildSubnet = fmt.Sprintf("%s/%s", p[3], p[4]) 102 } 103 104 return nil 105 } 106 107 // String returns the string form of the PoolData object 108 func (p *PoolData) String() string { 109 return fmt.Sprintf("ParentKey: %s, Pool: %s, Range: %s, RefCount: %d", 110 p.ParentKey.String(), p.Pool.String(), p.Range, p.RefCount) 111 } 112 113 // MarshalJSON returns the JSON encoding of the PoolData object 114 func (p *PoolData) MarshalJSON() ([]byte, error) { 115 m := map[string]interface{}{ 116 "ParentKey": p.ParentKey, 117 "RefCount": p.RefCount, 118 } 119 if p.Pool != nil { 120 m["Pool"] = p.Pool.String() 121 } 122 if p.Range != nil { 123 m["Range"] = p.Range 124 } 125 return json.Marshal(m) 126 } 127 128 // UnmarshalJSON decodes data into the PoolData object 129 func (p *PoolData) UnmarshalJSON(data []byte) error { 130 var ( 131 err error 132 t struct { 133 ParentKey SubnetKey 134 Pool string 135 Range *AddressRange `json:",omitempty"` 136 RefCount int 137 } 138 ) 139 140 if err = json.Unmarshal(data, &t); err != nil { 141 return err 142 } 143 144 p.ParentKey = t.ParentKey 145 p.Range = t.Range 146 p.RefCount = t.RefCount 147 if t.Pool != "" { 148 if p.Pool, err = types.ParseCIDR(t.Pool); err != nil { 149 return err 150 } 151 } 152 153 return nil 154 } 155 156 // MarshalJSON returns the JSON encoding of the addrSpace object 157 func (aSpace *addrSpace) MarshalJSON() ([]byte, error) { 158 aSpace.Lock() 159 defer aSpace.Unlock() 160 161 m := map[string]interface{}{ 162 "Scope": string(aSpace.scope), 163 } 164 165 if aSpace.subnets != nil { 166 s := map[string]*PoolData{} 167 for k, v := range aSpace.subnets { 168 s[k.String()] = v 169 } 170 m["Subnets"] = s 171 } 172 173 return json.Marshal(m) 174 } 175 176 // UnmarshalJSON decodes data into the addrSpace object 177 func (aSpace *addrSpace) UnmarshalJSON(data []byte) error { 178 aSpace.Lock() 179 defer aSpace.Unlock() 180 181 m := map[string]interface{}{} 182 err := json.Unmarshal(data, &m) 183 if err != nil { 184 return err 185 } 186 187 aSpace.scope = datastore.LocalScope 188 s := m["Scope"].(string) 189 if s == string(datastore.GlobalScope) { 190 aSpace.scope = datastore.GlobalScope 191 } 192 193 if v, ok := m["Subnets"]; ok { 194 sb, _ := json.Marshal(v) 195 var s map[string]*PoolData 196 err := json.Unmarshal(sb, &s) 197 if err != nil { 198 return err 199 } 200 for ks, v := range s { 201 k := SubnetKey{} 202 k.FromString(ks) 203 aSpace.subnets[k] = v 204 } 205 } 206 207 return nil 208 } 209 210 // CopyTo deep copies the pool data to the destination pooldata 211 func (p *PoolData) CopyTo(dstP *PoolData) error { 212 dstP.ParentKey = p.ParentKey 213 dstP.Pool = types.GetIPNetCopy(p.Pool) 214 215 if p.Range != nil { 216 dstP.Range = &AddressRange{} 217 dstP.Range.Sub = types.GetIPNetCopy(p.Range.Sub) 218 dstP.Range.Start = p.Range.Start 219 dstP.Range.End = p.Range.End 220 } 221 222 dstP.RefCount = p.RefCount 223 return nil 224 } 225 226 func (aSpace *addrSpace) CopyTo(o datastore.KVObject) error { 227 aSpace.Lock() 228 defer aSpace.Unlock() 229 230 dstAspace := o.(*addrSpace) 231 232 dstAspace.id = aSpace.id 233 dstAspace.ds = aSpace.ds 234 dstAspace.alloc = aSpace.alloc 235 dstAspace.scope = aSpace.scope 236 dstAspace.dbIndex = aSpace.dbIndex 237 dstAspace.dbExists = aSpace.dbExists 238 239 dstAspace.subnets = make(map[SubnetKey]*PoolData) 240 for k, v := range aSpace.subnets { 241 dstAspace.subnets[k] = &PoolData{} 242 v.CopyTo(dstAspace.subnets[k]) 243 } 244 245 return nil 246 } 247 248 func (aSpace *addrSpace) New() datastore.KVObject { 249 aSpace.Lock() 250 defer aSpace.Unlock() 251 252 return &addrSpace{ 253 id: aSpace.id, 254 ds: aSpace.ds, 255 alloc: aSpace.alloc, 256 scope: aSpace.scope, 257 } 258 } 259 260 func (aSpace *addrSpace) updatePoolDBOnAdd(k SubnetKey, nw *net.IPNet, ipr *AddressRange, pdf bool) (func() error, error) { 261 aSpace.Lock() 262 defer aSpace.Unlock() 263 264 // Check if already allocated 265 if p, ok := aSpace.subnets[k]; ok { 266 if pdf { 267 return nil, types.InternalMaskableErrorf("predefined pool %s is already reserved", nw) 268 } 269 aSpace.incRefCount(p, 1) 270 return func() error { return nil }, nil 271 } 272 273 // If master pool, check for overlap 274 if ipr == nil { 275 if aSpace.contains(k.AddressSpace, nw) { 276 return nil, ipamapi.ErrPoolOverlap 277 } 278 // This is a new master pool, add it along with corresponding bitmask 279 aSpace.subnets[k] = &PoolData{Pool: nw, RefCount: 1} 280 return func() error { return aSpace.alloc.insertBitMask(k, nw) }, nil 281 } 282 283 // This is a new non-master pool 284 p := &PoolData{ 285 ParentKey: SubnetKey{AddressSpace: k.AddressSpace, Subnet: k.Subnet}, 286 Pool: nw, 287 Range: ipr, 288 RefCount: 1, 289 } 290 aSpace.subnets[k] = p 291 292 // Look for parent pool 293 pp, ok := aSpace.subnets[p.ParentKey] 294 if ok { 295 aSpace.incRefCount(pp, 1) 296 return func() error { return nil }, nil 297 } 298 299 // Parent pool does not exist, add it along with corresponding bitmask 300 aSpace.subnets[p.ParentKey] = &PoolData{Pool: nw, RefCount: 1} 301 return func() error { return aSpace.alloc.insertBitMask(p.ParentKey, nw) }, nil 302 } 303 304 func (aSpace *addrSpace) updatePoolDBOnRemoval(k SubnetKey) (func() error, error) { 305 aSpace.Lock() 306 defer aSpace.Unlock() 307 308 p, ok := aSpace.subnets[k] 309 if !ok { 310 return nil, ipamapi.ErrBadPool 311 } 312 313 aSpace.incRefCount(p, -1) 314 315 c := p 316 for ok { 317 if c.RefCount == 0 { 318 delete(aSpace.subnets, k) 319 if c.Range == nil { 320 return func() error { 321 bm, err := aSpace.alloc.retrieveBitmask(k, c.Pool) 322 if err != nil { 323 return types.InternalErrorf("could not find bitmask in datastore for pool %s removal: %v", k.String(), err) 324 } 325 return bm.Destroy() 326 }, nil 327 } 328 } 329 k = c.ParentKey 330 c, ok = aSpace.subnets[k] 331 } 332 333 return func() error { return nil }, nil 334 } 335 336 func (aSpace *addrSpace) incRefCount(p *PoolData, delta int) { 337 c := p 338 ok := true 339 for ok { 340 c.RefCount += delta 341 c, ok = aSpace.subnets[c.ParentKey] 342 } 343 } 344 345 // Checks whether the passed subnet is a superset or subset of any of the subset in this config db 346 func (aSpace *addrSpace) contains(space string, nw *net.IPNet) bool { 347 for k, v := range aSpace.subnets { 348 if space == k.AddressSpace && k.ChildSubnet == "" { 349 if nw.Contains(v.Pool.IP) || v.Pool.Contains(nw.IP) { 350 return true 351 } 352 } 353 } 354 return false 355 } 356 357 func (aSpace *addrSpace) store() datastore.DataStore { 358 aSpace.Lock() 359 defer aSpace.Unlock() 360 361 return aSpace.ds 362 }