mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
libnetwork to handle allocation of ipv6
Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
parent
d80f34b8e8
commit
b9596c89d6
5 changed files with 169 additions and 71 deletions
|
@ -343,15 +343,13 @@ func (c *controller) NewNetwork(networkType, name string, options ...NetworkOpti
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cnfs, err := network.ipamAllocate()
|
err := network.ipamAllocate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for _, cn := range cnfs {
|
network.ipamRelease()
|
||||||
cn()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -386,7 +384,7 @@ func (c *controller) addNetwork(n *network) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the network
|
// Create the network
|
||||||
if err := d.CreateNetwork(n.id, n.generic, n.getIPv4Data(), n.getIPv6Data()); err != nil {
|
if err := d.CreateNetwork(n.id, n.generic, n.getIPData(4), n.getIPData(6)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -630,13 +630,44 @@ func (ep *endpoint) assignAddress() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, d := range n.getIPInfo() {
|
err = ep.assignAddressVersion(4, ipam)
|
||||||
var addr *net.IPNet
|
if err != nil {
|
||||||
addr, _, err = ipam.RequestAddress(d.PoolID, nil, nil)
|
return err
|
||||||
|
}
|
||||||
|
return ep.assignAddressVersion(6, ipam)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
|
||||||
|
var (
|
||||||
|
poolID *string
|
||||||
|
address **net.IPNet
|
||||||
|
)
|
||||||
|
|
||||||
|
n := ep.getNetwork()
|
||||||
|
switch ipVer {
|
||||||
|
case 4:
|
||||||
|
poolID = &ep.iface.v4PoolID
|
||||||
|
address = &ep.iface.addr
|
||||||
|
case 6:
|
||||||
|
poolID = &ep.iface.v6PoolID
|
||||||
|
address = &ep.iface.addrv6
|
||||||
|
default:
|
||||||
|
return types.InternalErrorf("incorrect ip version number passed: %d", ipVer)
|
||||||
|
}
|
||||||
|
|
||||||
|
ipInfo := n.getIPInfo(ipVer)
|
||||||
|
|
||||||
|
// ipv6 address is not mandatory
|
||||||
|
if len(ipInfo) == 0 && ipVer == 6 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range ipInfo {
|
||||||
|
addr, _, err := ipam.RequestAddress(d.PoolID, nil, nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
ep.iface.addr = addr
|
*address = addr
|
||||||
ep.iface.poolID = d.PoolID
|
*poolID = d.PoolID
|
||||||
ep.Unlock()
|
ep.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -644,7 +675,7 @@ func (ep *endpoint) assignAddress() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Errorf("no available ip addresses on this network address pools: %s (%s)", n.Name(), n.ID())
|
return fmt.Errorf("no available IPv%d addresses on this network's address pools: %s (%s)", ipVer, n.Name(), n.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) releaseAddress() {
|
func (ep *endpoint) releaseAddress() {
|
||||||
|
@ -657,7 +688,12 @@ func (ep *endpoint) releaseAddress() {
|
||||||
log.Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
|
log.Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := ipam.ReleaseAddress(ep.iface.poolID, ep.iface.addr.IP); err != nil {
|
if err := ipam.ReleaseAddress(ep.iface.v4PoolID, ep.iface.addr.IP); err != nil {
|
||||||
log.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addr.IP, ep.Name(), ep.ID(), err)
|
log.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addr.IP, ep.Name(), ep.ID(), err)
|
||||||
}
|
}
|
||||||
|
if ep.iface.addrv6 != nil && ep.iface.addrv6.IP.IsGlobalUnicast() {
|
||||||
|
if err := ipam.ReleaseAddress(ep.iface.v6PoolID, ep.iface.addrv6.IP); err != nil {
|
||||||
|
log.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addrv6.IP, ep.Name(), ep.ID(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,8 @@ type endpointInterface struct {
|
||||||
srcName string
|
srcName string
|
||||||
dstPrefix string
|
dstPrefix string
|
||||||
routes []*net.IPNet
|
routes []*net.IPNet
|
||||||
poolID string
|
v4PoolID string
|
||||||
|
v6PoolID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (epi *endpointInterface) MarshalJSON() ([]byte, error) {
|
func (epi *endpointInterface) MarshalJSON() ([]byte, error) {
|
||||||
|
@ -69,7 +70,8 @@ func (epi *endpointInterface) MarshalJSON() ([]byte, error) {
|
||||||
routes = append(routes, route.String())
|
routes = append(routes, route.String())
|
||||||
}
|
}
|
||||||
epMap["routes"] = routes
|
epMap["routes"] = routes
|
||||||
epMap["poolID"] = epi.poolID
|
epMap["v4PoolID"] = epi.v4PoolID
|
||||||
|
epMap["v6PoolID"] = epi.v6PoolID
|
||||||
return json.Marshal(epMap)
|
return json.Marshal(epMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +113,8 @@ func (epi *endpointInterface) UnmarshalJSON(b []byte) error {
|
||||||
epi.routes = append(epi.routes, ipr)
|
epi.routes = append(epi.routes, ipr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
epi.poolID = epMap["poolID"].(string)
|
epi.v4PoolID = epMap["v4PoolID"].(string)
|
||||||
|
epi.v6PoolID = epMap["v6PoolID"].(string)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -122,7 +125,8 @@ func (epi *endpointInterface) CopyTo(dstEpi *endpointInterface) error {
|
||||||
dstEpi.addrv6 = types.GetIPNetCopy(epi.addrv6)
|
dstEpi.addrv6 = types.GetIPNetCopy(epi.addrv6)
|
||||||
dstEpi.srcName = epi.srcName
|
dstEpi.srcName = epi.srcName
|
||||||
dstEpi.dstPrefix = epi.dstPrefix
|
dstEpi.dstPrefix = epi.dstPrefix
|
||||||
dstEpi.poolID = epi.poolID
|
dstEpi.v4PoolID = epi.v4PoolID
|
||||||
|
dstEpi.v6PoolID = epi.v6PoolID
|
||||||
|
|
||||||
for _, route := range epi.routes {
|
for _, route := range epi.routes {
|
||||||
dstEpi.routes = append(dstEpi.routes, types.GetIPNetCopy(route))
|
dstEpi.routes = append(dstEpi.routes, types.GetIPNetCopy(route))
|
||||||
|
|
|
@ -197,7 +197,8 @@ func TestEndpointMarshalling(t *testing.T) {
|
||||||
addrv6: nw6,
|
addrv6: nw6,
|
||||||
srcName: "veth12ab1314",
|
srcName: "veth12ab1314",
|
||||||
dstPrefix: "eth",
|
dstPrefix: "eth",
|
||||||
poolID: "poolpool",
|
v4PoolID: "poolpool",
|
||||||
|
v6PoolID: "poolv6",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +225,7 @@ func compareEndpointInterface(a, b *endpointInterface) bool {
|
||||||
if a == nil || b == nil {
|
if a == nil || b == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return a.srcName == b.srcName && a.dstPrefix == b.dstPrefix && a.poolID == b.poolID &&
|
return a.srcName == b.srcName && a.dstPrefix == b.dstPrefix && a.v4PoolID == b.v4PoolID && a.v6PoolID == b.v6PoolID &&
|
||||||
types.CompareIPNet(a.addr, b.addr) && types.CompareIPNet(a.addrv6, b.addrv6)
|
types.CompareIPNet(a.addr, b.addr) && types.CompareIPNet(a.addrv6, b.addrv6)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +320,7 @@ func TestAuxAddresses(t *testing.T) {
|
||||||
|
|
||||||
n.ipamV4Config = []*IpamConf{&IpamConf{PreferredPool: i.masterPool, SubPool: i.subPool, AuxAddresses: i.auxAddresses}}
|
n.ipamV4Config = []*IpamConf{&IpamConf{PreferredPool: i.masterPool, SubPool: i.subPool, AuxAddresses: i.auxAddresses}}
|
||||||
|
|
||||||
_, err := n.ipamAllocate()
|
err = n.ipamAllocate()
|
||||||
|
|
||||||
if i.good != (err == nil) {
|
if i.good != (err == nil) {
|
||||||
t.Fatalf("Unexpected result for %v: %v", i, err)
|
t.Fatalf("Unexpected result for %v: %v", i, err)
|
||||||
|
|
|
@ -65,7 +65,7 @@ type IpamConf struct {
|
||||||
// this becomes the container pool
|
// this becomes the container pool
|
||||||
SubPool string
|
SubPool string
|
||||||
// Input options for IPAM Driver (optional)
|
// Input options for IPAM Driver (optional)
|
||||||
Options map[string]string // IPAM input options
|
Options map[string]string
|
||||||
// IPv6 flag, Needed when no preferred pool is specified
|
// IPv6 flag, Needed when no preferred pool is specified
|
||||||
IsV6 bool
|
IsV6 bool
|
||||||
// Preferred Network Gateway address (optional)
|
// Preferred Network Gateway address (optional)
|
||||||
|
@ -281,6 +281,14 @@ func (n *network) CopyTo(o datastore.KVObject) error {
|
||||||
dstN.ipamV4Info = append(dstN.ipamV4Info, dstV4Info)
|
dstN.ipamV4Info = append(dstN.ipamV4Info, dstV4Info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n.ipamV6Info != nil {
|
||||||
|
for _, v6info := range n.ipamV6Info {
|
||||||
|
dstV6Info := &IpamInfo{}
|
||||||
|
v6info.CopyTo(dstV6Info)
|
||||||
|
dstN.ipamV6Info = append(dstN.ipamV6Info, dstV6Info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dstN.generic = options.Generic{}
|
dstN.generic = options.Generic{}
|
||||||
for k, v := range n.generic {
|
for k, v := range n.generic {
|
||||||
dstN.generic[k] = v
|
dstN.generic[k] = v
|
||||||
|
@ -786,44 +794,76 @@ func (n *network) getController() *controller {
|
||||||
return n.ctrlr
|
return n.ctrlr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) ipamAllocate() ([]func(), error) {
|
func (n *network) ipamAllocate() error {
|
||||||
var (
|
|
||||||
cnl []func()
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
// For now also exclude bridge from using new ipam
|
// For now also exclude bridge from using new ipam
|
||||||
if n.Type() == "host" || n.Type() == "null" || n.Type() == "bridge" {
|
if n.Type() == "host" || n.Type() == "null" || n.Type() == "bridge" {
|
||||||
return cnl, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ipam, err := n.getController().getIpamDriver(n.ipamType)
|
ipam, err := n.getController().getIpamDriver(n.ipamType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.addrSpace == "" {
|
if n.addrSpace == "" {
|
||||||
if n.addrSpace, err = n.deriveAddressSpace(); err != nil {
|
if n.addrSpace, err = n.deriveAddressSpace(); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.ipamV4Config == nil {
|
err = n.ipamAllocateVersion(4, ipam)
|
||||||
n.ipamV4Config = []*IpamConf{&IpamConf{}}
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
n.ipamV4Info = make([]*IpamInfo, len(n.ipamV4Config))
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
n.ipamReleaseVersion(4, ipam)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
for i, cfg := range n.ipamV4Config {
|
return n.ipamAllocateVersion(6, ipam)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
|
||||||
|
var (
|
||||||
|
cfgList *[]*IpamConf
|
||||||
|
infoList *[]*IpamInfo
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
switch ipVer {
|
||||||
|
case 4:
|
||||||
|
cfgList = &n.ipamV4Config
|
||||||
|
infoList = &n.ipamV4Info
|
||||||
|
case 6:
|
||||||
|
cfgList = &n.ipamV6Config
|
||||||
|
infoList = &n.ipamV6Info
|
||||||
|
default:
|
||||||
|
return types.InternalErrorf("incorrect ip version passed to ipam allocate: %d", ipVer)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *cfgList == nil {
|
||||||
|
if ipVer == 6 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
*cfgList = []*IpamConf{&IpamConf{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
*infoList = make([]*IpamInfo, len(*cfgList))
|
||||||
|
|
||||||
|
log.Debugf("allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID())
|
||||||
|
|
||||||
|
for i, cfg := range *cfgList {
|
||||||
if err = cfg.Validate(); err != nil {
|
if err = cfg.Validate(); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
d := &IpamInfo{}
|
d := &IpamInfo{}
|
||||||
n.ipamV4Info[i] = d
|
(*infoList)[i] = d
|
||||||
|
|
||||||
d.PoolID, d.Pool, d.Meta, err = ipam.RequestPool(n.addrSpace, cfg.PreferredPool, cfg.SubPool, cfg.Options, cfg.IsV6)
|
d.PoolID, d.Pool, d.Meta, err = ipam.RequestPool(n.addrSpace, cfg.PreferredPool, cfg.SubPool, cfg.Options, cfg.IsV6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -836,7 +876,7 @@ func (n *network) ipamAllocate() ([]func(), error) {
|
||||||
|
|
||||||
if gws, ok := d.Meta[netlabel.Gateway]; ok {
|
if gws, ok := d.Meta[netlabel.Gateway]; ok {
|
||||||
if d.Gateway, err = types.ParseCIDR(gws); err != nil {
|
if d.Gateway, err = types.ParseCIDR(gws); err != nil {
|
||||||
return nil, types.BadRequestErrorf("failed to parse gateway address (%v) returned by ipam driver: %v", gws, err)
|
return types.BadRequestErrorf("failed to parse gateway address (%v) returned by ipam driver: %v", gws, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,15 +885,10 @@ func (n *network) ipamAllocate() ([]func(), error) {
|
||||||
// If none of the above is true, libnetwork will allocate one.
|
// If none of the above is true, libnetwork will allocate one.
|
||||||
if cfg.Gateway != "" || d.Gateway == nil {
|
if cfg.Gateway != "" || d.Gateway == nil {
|
||||||
if d.Gateway, _, err = ipam.RequestAddress(d.PoolID, net.ParseIP(cfg.Gateway), nil); err != nil {
|
if d.Gateway, _, err = ipam.RequestAddress(d.PoolID, net.ParseIP(cfg.Gateway), nil); err != nil {
|
||||||
return nil, types.InternalErrorf("failed to allocate gateway (%v): %v", cfg.Gateway, err)
|
return types.InternalErrorf("failed to allocate gateway (%v): %v", cfg.Gateway, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cnl = append(cnl, func() {
|
|
||||||
if err := ipam.ReleaseAddress(d.PoolID, d.Gateway.IP); err != nil {
|
|
||||||
log.Warnf("Failed to release gw address %s after failure to create network %s (%s)", d.Gateway, n.Name(), n.ID())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// Auxiliary addresses must be part of the master address pool
|
// Auxiliary addresses must be part of the master address pool
|
||||||
// If they fall into the container addressable pool, libnetwork will reserve them
|
// If they fall into the container addressable pool, libnetwork will reserve them
|
||||||
if cfg.AuxAddresses != nil {
|
if cfg.AuxAddresses != nil {
|
||||||
|
@ -861,27 +896,20 @@ func (n *network) ipamAllocate() ([]func(), error) {
|
||||||
d.IPAMData.AuxAddresses = make(map[string]*net.IPNet, len(cfg.AuxAddresses))
|
d.IPAMData.AuxAddresses = make(map[string]*net.IPNet, len(cfg.AuxAddresses))
|
||||||
for k, v := range cfg.AuxAddresses {
|
for k, v := range cfg.AuxAddresses {
|
||||||
if ip = net.ParseIP(v); ip == nil {
|
if ip = net.ParseIP(v); ip == nil {
|
||||||
return nil, types.BadRequestErrorf("non parsable secondary ip address (%s:%s) passed for network %s", k, v, n.Name())
|
return types.BadRequestErrorf("non parsable secondary ip address (%s:%s) passed for network %s", k, v, n.Name())
|
||||||
}
|
}
|
||||||
if !d.Pool.Contains(ip) {
|
if !d.Pool.Contains(ip) {
|
||||||
return cnl, types.ForbiddenErrorf("auxilairy address: (%s:%s) must belong to the master pool: %s", k, v, d.Pool)
|
return types.ForbiddenErrorf("auxilairy address: (%s:%s) must belong to the master pool: %s", k, v, d.Pool)
|
||||||
}
|
}
|
||||||
// Attempt reservation in the container addressable pool, silent the error if address does not belong to that pool
|
// Attempt reservation in the container addressable pool, silent the error if address does not belong to that pool
|
||||||
if d.IPAMData.AuxAddresses[k], _, err = ipam.RequestAddress(d.PoolID, ip, nil); err != nil && err != ipamapi.ErrIPOutOfRange {
|
if d.IPAMData.AuxAddresses[k], _, err = ipam.RequestAddress(d.PoolID, ip, nil); err != nil && err != ipamapi.ErrIPOutOfRange {
|
||||||
return nil, types.InternalErrorf("failed to allocate secondary ip address (%s:%s): %v", k, v, err)
|
return types.InternalErrorf("failed to allocate secondary ip address (%s:%s): %v", k, v, err)
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
cnl = append(cnl, func() {
|
|
||||||
if err := ipam.ReleaseAddress(d.PoolID, ip); err != nil {
|
|
||||||
log.Warnf("Failed to release secondary ip address %s(%s) after failure to create network %s (%s)", k, v, ip, n.Name(), n.ID())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cnl, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) ipamRelease() {
|
func (n *network) ipamRelease() {
|
||||||
|
@ -894,7 +922,30 @@ func (n *network) ipamRelease() {
|
||||||
log.Warnf("Failed to retrieve ipam driver to release address pool(s) on delete of network %s (%s): %v", n.Name(), n.ID(), err)
|
log.Warnf("Failed to retrieve ipam driver to release address pool(s) on delete of network %s (%s): %v", n.Name(), n.ID(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, d := range n.ipamV4Info {
|
n.ipamReleaseVersion(4, ipam)
|
||||||
|
n.ipamReleaseVersion(6, ipam)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *network) ipamReleaseVersion(ipVer int, ipam ipamapi.Ipam) {
|
||||||
|
var infoList []*IpamInfo
|
||||||
|
|
||||||
|
switch ipVer {
|
||||||
|
case 4:
|
||||||
|
infoList = n.ipamV4Info
|
||||||
|
case 6:
|
||||||
|
infoList = n.ipamV6Info
|
||||||
|
default:
|
||||||
|
log.Warnf("incorrect ip version passed to ipam release: %d", ipVer)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if infoList == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("releasing IPv%d pools from network %s (%s)", ipVer, n.Name(), n.ID())
|
||||||
|
|
||||||
|
for _, d := range infoList {
|
||||||
if d.Gateway != nil {
|
if d.Gateway != nil {
|
||||||
if err := ipam.ReleaseAddress(d.PoolID, d.Gateway.IP); err != nil {
|
if err := ipam.ReleaseAddress(d.PoolID, d.Gateway.IP); err != nil {
|
||||||
log.Warnf("Failed to release gateway ip address %s on delete of network %s (%s): %v", d.Gateway.IP, n.Name(), n.ID(), err)
|
log.Warnf("Failed to release gateway ip address %s on delete of network %s (%s): %v", d.Gateway.IP, n.Name(), n.ID(), err)
|
||||||
|
@ -915,30 +966,38 @@ func (n *network) ipamRelease() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) getIPInfo() []*IpamInfo {
|
func (n *network) getIPInfo(ipVer int) []*IpamInfo {
|
||||||
n.Lock()
|
var info []*IpamInfo
|
||||||
defer n.Unlock()
|
switch ipVer {
|
||||||
l := make([]*IpamInfo, 0, len(n.ipamV4Info))
|
case 4:
|
||||||
for _, d := range n.ipamV4Info {
|
info = n.ipamV4Info
|
||||||
l = append(l, d)
|
case 6:
|
||||||
|
info = n.ipamV6Info
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return l
|
l := make([]*IpamInfo, 0, len(info))
|
||||||
}
|
|
||||||
|
|
||||||
func (n *network) getIPv4Data() []driverapi.IPAMData {
|
|
||||||
l := make([]driverapi.IPAMData, 0, len(n.ipamV4Info))
|
|
||||||
n.Lock()
|
n.Lock()
|
||||||
for _, d := range n.ipamV4Info {
|
for _, d := range info {
|
||||||
l = append(l, d.IPAMData)
|
l = append(l, d)
|
||||||
}
|
}
|
||||||
n.Unlock()
|
n.Unlock()
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) getIPv6Data() []driverapi.IPAMData {
|
func (n *network) getIPData(ipVer int) []driverapi.IPAMData {
|
||||||
l := make([]driverapi.IPAMData, 0, len(n.ipamV6Info))
|
var info []*IpamInfo
|
||||||
|
switch ipVer {
|
||||||
|
case 4:
|
||||||
|
info = n.ipamV4Info
|
||||||
|
case 6:
|
||||||
|
info = n.ipamV6Info
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
l := make([]driverapi.IPAMData, 0, len(info))
|
||||||
n.Lock()
|
n.Lock()
|
||||||
for _, d := range n.ipamV6Info {
|
for _, d := range info {
|
||||||
l = append(l, d.IPAMData)
|
l = append(l, d.IPAMData)
|
||||||
}
|
}
|
||||||
n.Unlock()
|
n.Unlock()
|
||||||
|
|
Loading…
Reference in a new issue