diff --git a/ipam/claim.go b/ipam/claim.go index fda36f15..f3803feb 100644 --- a/ipam/claim.go +++ b/ipam/claim.go @@ -77,26 +77,34 @@ func (c *claim) Try(alloc *Allocator) bool { return false } - if c.ident == "_" { // Special "I don't have a unique ID" identifier - c.ident = c.cidr.Addr.String() - } // We are the owner, check we haven't given it to another container - switch existingIdent := alloc.findOwner(c.cidr.Addr); existingIdent { - case "": + existingIdent := alloc.findOwner(c.cidr.Addr) + switch { + case existingIdent == "": + // Unused address, we try to claim it: if err := alloc.space.Claim(c.cidr.Addr); err == nil { alloc.debugln("Claimed", c.cidr, "for", c.ident) - alloc.addOwned(c.ident, c.cidr, c.isContainer) + if c.ident == "_" { // Special "I don't have a unique ID" identifier + alloc.addOwned(c.cidr.Addr.String(), c.cidr, c.isContainer) + } else { + alloc.addOwned(c.ident, c.cidr, c.isContainer) + } c.sendResult(nil) } else { c.sendResult(err) } - case c.ident: + case (existingIdent == c.ident) || (c.ident == "_" && existingIdent == c.cidr.Addr.String()): // same identifier is claiming same address; that's OK alloc.debugln("Re-Claimed", c.cidr, "for", c.ident) c.sendResult(nil) - case c.cidr.Addr.String(): - // Address already allocated via "_" name + case existingIdent == c.cidr.Addr.String(): + // Address already allocated via "_" name and current ID is a real container ID: c.sendResult(fmt.Errorf("address %s already in use", c.cidr)) + case c.ident == "_": + // We do not know whether this is the same container or another one, + // but we also cannot prove otherwise, so we let it reclaim the address: + alloc.debugln("Re-Claimed", c.cidr, "for ID", c.ident, "having existing ID as", existingIdent) + c.sendResult(nil) default: // Addr already owned by container on this machine c.sendResult(fmt.Errorf("address %s is already owned by %s", c.cidr.String(), existingIdent))