func (c *Context) addScope(s *Scope) error { defer trace.End(trace.Begin("")) if _, ok := c.scopes[s.name]; ok { return DuplicateResourceError{} } var err error var defaultPool bool var allzeros, allones net.IP var space *AddressSpace spaces := s.spaces subnet := s.subnet gateway := s.gateway // cleanup defer func() { if err == nil || space == nil || !defaultPool { return } for _, p := range spaces { // release DNS IPs for _, d := range s.dns { p.ReleaseIP4(d) } // release gateway if !ip.IsUnspecifiedIP(gateway) { p.ReleaseIP4(gateway) } // release all-ones and all-zeros addresses if !ip.IsUnspecifiedIP(allzeros) { p.ReleaseIP4(allzeros) } if !ip.IsUnspecifiedIP(allones) { p.ReleaseIP4(allones) } } c.defaultBridgePool.ReleaseIP4Range(space) }() // subnet may not be specified, e.g. for "external" networks if !ip.IsUnspecifiedSubnet(subnet) { // allocate the subnet space, defaultPool, err = c.reserveSubnet(subnet) if err != nil { return err } subnet = space.Network spaces, err = reservePools(space, spaces) if err != nil { return err } // reserve all-ones and all-zeros addresses, which are not routable and so // should not be handed out allones = ip.AllOnesAddr(subnet) allzeros = ip.AllZerosAddr(subnet) for _, p := range spaces { p.ReserveIP4(allones) p.ReserveIP4(allzeros) // reserve DNS IPs for _, d := range s.dns { if d.Equal(gateway) { continue // gateway will be reserved later } p.ReserveIP4(d) } } if gateway, err = reserveGateway(gateway, subnet, spaces); err != nil { return err } s.gateway = gateway s.spaces = spaces s.subnet = subnet } c.scopes[s.name] = s return nil }
func (c *Context) newScopeCommon(id uid.UID, name, scopeType string, subnet *net.IPNet, gateway net.IP, dns []net.IP, ipam *IPAM, network object.NetworkReference) (*Scope, error) { var err error var space *AddressSpace var defaultPool bool var allzeros, allones net.IP // cleanup defer func() { if err == nil || space == nil || !defaultPool { return } for _, p := range ipam.spaces { // release DNS IPs for _, d := range dns { p.ReleaseIP4(d) } // release gateway if !ip.IsUnspecifiedIP(gateway) { p.ReleaseIP4(gateway) } // release all-ones and all-zeros addresses if !ip.IsUnspecifiedIP(allzeros) { p.ReleaseIP4(allzeros) } if !ip.IsUnspecifiedIP(allones) { p.ReleaseIP4(allones) } } c.defaultBridgePool.ReleaseIP4Range(space) }() // subnet may not be specified, e.g. for "external" networks if !ip.IsUnspecifiedSubnet(subnet) { // allocate the subnet space, defaultPool, err = c.reserveSubnet(subnet) if err != nil { return nil, err } subnet = space.Network ipam.spaces, err = reservePools(space, ipam) if err != nil { return nil, err } // reserve all-ones and all-zeros addresses, which are not routable and so // should not be handed out allones = ip.AllOnesAddr(subnet) allzeros = ip.AllZerosAddr(subnet) for _, p := range ipam.spaces { p.ReserveIP4(allones) p.ReserveIP4(allzeros) // reserve DNS IPs for _, d := range dns { if d.Equal(gateway) { continue // gateway will be reserved later } p.ReserveIP4(d) } } if gateway, err = reserveGateway(gateway, subnet, ipam); err != nil { return nil, err } } newScope := &Scope{ id: id, name: name, subnet: *subnet, gateway: gateway, ipam: ipam, containers: make(map[uid.UID]*Container), scopeType: scopeType, space: space, dns: dns, builtin: false, network: network, } c.scopes[name] = newScope return newScope, nil }