Exemplo n.º 1
0
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
}
Exemplo n.º 2
0
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
}