Browse Source

Merge pull request #44805 from corhere/libnet/return-concrete-types

libnetwork: replace some unnecessary interfaces with their concrete types
Cory Snider 2 years ago
parent
commit
2504e4ad0d
44 changed files with 863 additions and 1051 deletions
  1. 1 1
      builder/builder-next/builder.go
  2. 8 8
      builder/builder-next/executor_unix.go
  3. 1 1
      builder/builder-next/executor_windows.go
  4. 9 9
      daemon/container_operations.go
  5. 1 1
      daemon/daemon.go
  6. 3 3
      daemon/daemon_unix.go
  7. 1 1
      daemon/daemon_windows.go
  8. 5 5
      daemon/network.go
  9. 1 1
      daemon/network_windows.go
  10. 1 1
      daemon/rename.go
  11. 30 30
      libnetwork/agent.go
  12. 143 195
      libnetwork/controller.go
  13. 12 14
      libnetwork/default_gateway.go
  14. 1 1
      libnetwork/default_gateway_freebsd.go
  15. 1 1
      libnetwork/default_gateway_linux.go
  16. 1 1
      libnetwork/default_gateway_windows.go
  17. 131 161
      libnetwork/endpoint.go
  18. 41 40
      libnetwork/endpoint_info.go
  19. 2 1
      libnetwork/endpoint_info_unix.go
  20. 2 1
      libnetwork/endpoint_info_windows.go
  21. 1 2
      libnetwork/endpoint_test.go
  22. 2 2
      libnetwork/firewall_linux.go
  23. 2 3
      libnetwork/firewall_linux_test.go
  24. 1 1
      libnetwork/firewall_others.go
  25. 5 7
      libnetwork/libnetwork_internal_test.go
  26. 6 6
      libnetwork/libnetwork_linux_test.go
  27. 5 68
      libnetwork/libnetwork_test.go
  28. 103 110
      libnetwork/network.go
  29. 2 2
      libnetwork/resolver_test.go
  30. 162 188
      libnetwork/sandbox.go
  31. 14 14
      libnetwork/sandbox_dns_unix.go
  32. 9 9
      libnetwork/sandbox_dns_windows.go
  33. 7 7
      libnetwork/sandbox_externalkey_unix.go
  34. 4 4
      libnetwork/sandbox_externalkey_windows.go
  35. 15 18
      libnetwork/sandbox_store.go
  36. 4 8
      libnetwork/sandbox_test.go
  37. 22 22
      libnetwork/service_common.go
  38. 31 31
      libnetwork/service_common_test.go
  39. 7 7
      libnetwork/service_linux.go
  40. 3 3
      libnetwork/service_unsupported.go
  41. 1 1
      libnetwork/service_windows.go
  42. 60 60
      libnetwork/store.go
  43. 1 1
      libnetwork/store_linux_test.go
  44. 1 1
      libnetwork/store_test.go

+ 1 - 1
builder/builder-next/builder.go

@@ -69,7 +69,7 @@ type Opt struct {
 	SessionManager      *session.Manager
 	Root                string
 	Dist                images.DistributionServices
-	NetworkController   libnetwork.NetworkController
+	NetworkController   *libnetwork.Controller
 	DefaultCgroupParent string
 	RegistryHosts       docker.RegistryHosts
 	BuilderConfig       config.BuilderConfig

+ 8 - 8
builder/builder-next/executor_unix.go

@@ -25,10 +25,10 @@ import (
 
 const networkName = "bridge"
 
-func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dnsConfig *oci.DNSConfig, rootless bool, idmap idtools.IdentityMapping, apparmorProfile string) (executor.Executor, error) {
+func newExecutor(root, cgroupParent string, net *libnetwork.Controller, dnsConfig *oci.DNSConfig, rootless bool, idmap idtools.IdentityMapping, apparmorProfile string) (executor.Executor, error) {
 	netRoot := filepath.Join(root, "net")
 	networkProviders := map[pb.NetMode]network.Provider{
-		pb.NetMode_UNSET: &bridgeProvider{NetworkController: net, Root: netRoot},
+		pb.NetMode_UNSET: &bridgeProvider{Controller: net, Root: netRoot},
 		pb.NetMode_HOST:  network.NewHostProvider(),
 		pb.NetMode_NONE:  network.NewNoneProvider(),
 	}
@@ -64,7 +64,7 @@ func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dn
 }
 
 type bridgeProvider struct {
-	libnetwork.NetworkController
+	*libnetwork.Controller
 	Root string
 }
 
@@ -76,22 +76,22 @@ func (p *bridgeProvider) New() (network.Namespace, error) {
 
 	iface := &lnInterface{ready: make(chan struct{}), provider: p}
 	iface.Once.Do(func() {
-		go iface.init(p.NetworkController, n)
+		go iface.init(p.Controller, n)
 	})
 
 	return iface, nil
 }
 
 type lnInterface struct {
-	ep  libnetwork.Endpoint
-	sbx libnetwork.Sandbox
+	ep  *libnetwork.Endpoint
+	sbx *libnetwork.Sandbox
 	sync.Once
 	err      error
 	ready    chan struct{}
 	provider *bridgeProvider
 }
 
-func (iface *lnInterface) init(c libnetwork.NetworkController, n libnetwork.Network) {
+func (iface *lnInterface) init(c *libnetwork.Controller, n libnetwork.Network) {
 	defer close(iface.ready)
 	id := identity.NewID()
 
@@ -123,7 +123,7 @@ func (iface *lnInterface) Set(s *specs.Spec) error {
 		logrus.WithError(iface.err).Error("failed to set networking spec")
 		return iface.err
 	}
-	shortNetCtlrID := stringid.TruncateID(iface.provider.NetworkController.ID())
+	shortNetCtlrID := stringid.TruncateID(iface.provider.Controller.ID())
 	// attach netns to bridge within the container namespace, using reexec in a prestart hook
 	s.Hooks = &specs.Hooks{
 		Prestart: []specs.Hook{{

+ 1 - 1
builder/builder-next/executor_windows.go

@@ -11,7 +11,7 @@ import (
 	"github.com/moby/buildkit/executor/oci"
 )
 
-func newExecutor(_, _ string, _ libnetwork.NetworkController, _ *oci.DNSConfig, _ bool, _ idtools.IdentityMapping, _ string) (executor.Executor, error) {
+func newExecutor(_, _ string, _ *libnetwork.Controller, _ *oci.DNSConfig, _ bool, _ idtools.IdentityMapping, _ string) (executor.Executor, error) {
 	return &winExecutor{}, nil
 }
 

+ 9 - 9
daemon/container_operations.go

@@ -291,7 +291,7 @@ func (daemon *Daemon) updateNetworkSettings(container *container.Container, n li
 	return nil
 }
 
-func (daemon *Daemon) updateEndpointNetworkSettings(container *container.Container, n libnetwork.Network, ep libnetwork.Endpoint) error {
+func (daemon *Daemon) updateEndpointNetworkSettings(container *container.Container, n libnetwork.Network, ep *libnetwork.Endpoint) error {
 	if err := buildEndpointInfo(container.NetworkSettings, n, ep); err != nil {
 		return err
 	}
@@ -602,9 +602,9 @@ func (daemon *Daemon) allocateNetwork(container *container.Container) (retErr er
 	return nil
 }
 
-func (daemon *Daemon) getNetworkSandbox(container *container.Container) libnetwork.Sandbox {
-	var sb libnetwork.Sandbox
-	daemon.netController.WalkSandboxes(func(s libnetwork.Sandbox) bool {
+func (daemon *Daemon) getNetworkSandbox(container *container.Container) *libnetwork.Sandbox {
+	var sb *libnetwork.Sandbox
+	daemon.netController.WalkSandboxes(func(s *libnetwork.Sandbox) bool {
 		if s.ContainerID() == container.ID {
 			sb = s
 			return true
@@ -834,7 +834,7 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName
 	return nil
 }
 
-func updateJoinInfo(networkSettings *network.Settings, n libnetwork.Network, ep libnetwork.Endpoint) error {
+func updateJoinInfo(networkSettings *network.Settings, n libnetwork.Network, ep *libnetwork.Endpoint) error {
 	if ep == nil {
 		return errors.New("invalid enppoint whhile building portmap info")
 	}
@@ -881,11 +881,11 @@ func (daemon *Daemon) ForceEndpointDelete(name string, networkName string) error
 
 func (daemon *Daemon) disconnectFromNetwork(container *container.Container, n libnetwork.Network, force bool) error {
 	var (
-		ep   libnetwork.Endpoint
-		sbox libnetwork.Sandbox
+		ep   *libnetwork.Endpoint
+		sbox *libnetwork.Sandbox
 	)
 
-	s := func(current libnetwork.Endpoint) bool {
+	s := func(current *libnetwork.Endpoint) bool {
 		epInfo := current.Info()
 		if epInfo == nil {
 			return false
@@ -1164,7 +1164,7 @@ func getNetworkID(name string, endpointSettings *networktypes.EndpointSettings)
 }
 
 // updateSandboxNetworkSettings updates the sandbox ID and Key.
-func updateSandboxNetworkSettings(c *container.Container, sb libnetwork.Sandbox) error {
+func updateSandboxNetworkSettings(c *container.Container, sb *libnetwork.Sandbox) error {
 	c.NetworkSettings.SandboxID = sb.ID()
 	c.NetworkSettings.SandboxKey = sb.Key()
 	return nil

+ 1 - 1
daemon/daemon.go

@@ -83,7 +83,7 @@ type Daemon struct {
 	defaultLogConfig      containertypes.LogConfig
 	registryService       registry.Service
 	EventsService         *events.Events
-	netController         libnetwork.NetworkController
+	netController         *libnetwork.Controller
 	volumes               *volumesservice.VolumesService
 	root                  string
 	sysInfoOnce           sync.Once

+ 3 - 3
daemon/daemon_unix.go

@@ -864,7 +864,7 @@ func (daemon *Daemon) initNetworkController(activeSandboxes map[string]interface
 	return nil
 }
 
-func configureNetworking(controller libnetwork.NetworkController, conf *config.Config) error {
+func configureNetworking(controller *libnetwork.Controller, conf *config.Config) error {
 	// Initialize default network on "null"
 	if n, _ := controller.NetworkByName("none"); n == nil {
 		if _, err := controller.NewNetwork("null", "none", "", libnetwork.NetworkOptionPersist(true)); err != nil {
@@ -902,7 +902,7 @@ func configureNetworking(controller libnetwork.NetworkController, conf *config.C
 }
 
 // setHostGatewayIP sets cfg.HostGatewayIP to the default bridge's IP if it is empty.
-func setHostGatewayIP(controller libnetwork.NetworkController, config *config.Config) {
+func setHostGatewayIP(controller *libnetwork.Controller, config *config.Config) {
 	if config.HostGatewayIP != nil {
 		return
 	}
@@ -930,7 +930,7 @@ func driverOptions(config *config.Config) nwconfig.Option {
 	})
 }
 
-func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error {
+func initBridgeDriver(controller *libnetwork.Controller, config *config.Config) error {
 	bridgeName := bridge.DefaultBridgeName
 	if config.BridgeConfig.Iface != "" {
 		bridgeName = config.BridgeConfig.Iface

+ 1 - 1
daemon/daemon_windows.go

@@ -409,7 +409,7 @@ func (daemon *Daemon) initNetworkController(activeSandboxes map[string]interface
 	return nil
 }
 
-func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error {
+func initBridgeDriver(controller *libnetwork.Controller, config *config.Config) error {
 	if _, err := controller.NetworkByName(runconfig.DefaultDaemonNetworkMode().NetworkName()); err == nil {
 		return nil
 	}

+ 5 - 5
daemon/network.go

@@ -50,7 +50,7 @@ func (daemon *Daemon) NetworkControllerEnabled() bool {
 }
 
 // NetworkController returns the network controller created by the daemon.
-func (daemon *Daemon) NetworkController() libnetwork.NetworkController {
+func (daemon *Daemon) NetworkController() *libnetwork.Controller {
 	return daemon.netController
 }
 
@@ -782,7 +782,7 @@ func (daemon *Daemon) clearAttachableNetworks() {
 }
 
 // buildCreateEndpointOptions builds endpoint options from a given network.
-func buildCreateEndpointOptions(c *container.Container, n libnetwork.Network, epConfig *network.EndpointSettings, sb libnetwork.Sandbox, daemonDNS []string) ([]libnetwork.EndpointOption, error) {
+func buildCreateEndpointOptions(c *container.Container, n libnetwork.Network, epConfig *network.EndpointSettings, sb *libnetwork.Sandbox, daemonDNS []string) ([]libnetwork.EndpointOption, error) {
 	var (
 		bindings      = make(nat.PortMap)
 		pbList        []networktypes.PortBinding
@@ -954,7 +954,7 @@ func buildCreateEndpointOptions(c *container.Container, n libnetwork.Network, ep
 }
 
 // getPortMapInfo retrieves the current port-mapping programmed for the given sandbox
-func getPortMapInfo(sb libnetwork.Sandbox) nat.PortMap {
+func getPortMapInfo(sb *libnetwork.Sandbox) nat.PortMap {
 	pm := nat.PortMap{}
 	if sb == nil {
 		return pm
@@ -969,7 +969,7 @@ func getPortMapInfo(sb libnetwork.Sandbox) nat.PortMap {
 	return pm
 }
 
-func getEndpointPortMapInfo(ep libnetwork.Endpoint) (nat.PortMap, error) {
+func getEndpointPortMapInfo(ep *libnetwork.Endpoint) (nat.PortMap, error) {
 	pm := nat.PortMap{}
 	driverInfo, err := ep.DriverInfo()
 	if err != nil {
@@ -1013,7 +1013,7 @@ func getEndpointPortMapInfo(ep libnetwork.Endpoint) (nat.PortMap, error) {
 }
 
 // buildEndpointInfo sets endpoint-related fields on container.NetworkSettings based on the provided network and endpoint.
-func buildEndpointInfo(networkSettings *internalnetwork.Settings, n libnetwork.Network, ep libnetwork.Endpoint) error {
+func buildEndpointInfo(networkSettings *internalnetwork.Settings, n libnetwork.Network, ep *libnetwork.Endpoint) error {
 	if ep == nil {
 		return errors.New("endpoint cannot be nil")
 	}

+ 1 - 1
daemon/network_windows.go

@@ -7,7 +7,7 @@ import (
 )
 
 // getEndpointInNetwork returns the container's endpoint to the provided network.
-func getEndpointInNetwork(name string, n libnetwork.Network) (libnetwork.Endpoint, error) {
+func getEndpointInNetwork(name string, n libnetwork.Network) (*libnetwork.Endpoint, error) {
 	endpointName := strings.TrimPrefix(name, "/")
 	return n.EndpointByName(endpointName)
 }

+ 1 - 1
daemon/rename.go

@@ -16,7 +16,7 @@ import (
 func (daemon *Daemon) ContainerRename(oldName, newName string) error {
 	var (
 		sid string
-		sb  libnetwork.Sandbox
+		sb  *libnetwork.Sandbox
 	)
 
 	if oldName == "" || newName == "" {

+ 30 - 30
libnetwork/agent.go

@@ -97,7 +97,7 @@ func resolveAddr(addrOrInterface string) (string, error) {
 	return addr.String(), nil
 }
 
-func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
+func (c *Controller) handleKeyChange(keys []*types.EncryptionKey) error {
 	drvEnc := discoverapi.DriverEncryptionUpdate{}
 
 	a := c.getAgent()
@@ -108,7 +108,7 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
 
 	// Find the deleted key. If the deleted key was the primary key,
 	// a new primary key should be set before removing if from keyring.
-	c.Lock()
+	c.mu.Lock()
 	added := []byte{}
 	deleted := []byte{}
 	j := len(c.keys)
@@ -157,7 +157,7 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
 			}
 		}
 	}
-	c.Unlock()
+	c.mu.Unlock()
 
 	if len(added) > 0 {
 		a.networkDB.SetKey(added)
@@ -201,7 +201,7 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
 	return nil
 }
 
-func (c *controller) agentSetup(clusterProvider cluster.Provider) error {
+func (c *Controller) agentSetup(clusterProvider cluster.Provider) error {
 	agent := c.getAgent()
 
 	// If the agent is already present there is no need to try to initialize it again
@@ -248,9 +248,9 @@ func (c *controller) agentSetup(clusterProvider cluster.Provider) error {
 
 // For a given subsystem getKeys sorts the keys by lamport time and returns
 // slice of keys and lamport time which can used as a unique tag for the keys
-func (c *controller) getKeys(subsys string) ([][]byte, []uint64) {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) getKeys(subsys string) ([][]byte, []uint64) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 
 	sort.Sort(ByTime(c.keys))
 
@@ -270,9 +270,9 @@ func (c *controller) getKeys(subsys string) ([][]byte, []uint64) {
 
 // getPrimaryKeyTag returns the primary key for a given subsystem from the
 // list of sorted key and the associated tag
-func (c *controller) getPrimaryKeyTag(subsys string) ([]byte, uint64, error) {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) getPrimaryKeyTag(subsys string) ([]byte, uint64, error) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	sort.Sort(ByTime(c.keys))
 	keys := []*types.EncryptionKey{}
 	for _, key := range c.keys {
@@ -283,7 +283,7 @@ func (c *controller) getPrimaryKeyTag(subsys string) ([]byte, uint64, error) {
 	return keys[1].Key, keys[1].LamportTime, nil
 }
 
-func (c *controller) agentInit(listenAddr, bindAddrOrInterface, advertiseAddr, dataPathAddr string) error {
+func (c *Controller) agentInit(listenAddr, bindAddrOrInterface, advertiseAddr, dataPathAddr string) error {
 	bindAddr, err := resolveAddr(bindAddrOrInterface)
 	if err != nil {
 		return err
@@ -316,7 +316,7 @@ func (c *controller) agentInit(listenAddr, bindAddrOrInterface, advertiseAddr, d
 	nodeCh, cancel := nDB.Watch(networkdb.NodeTable, "", "")
 	cancelList = append(cancelList, cancel)
 
-	c.Lock()
+	c.mu.Lock()
 	c.agent = &agent{
 		networkDB:         nDB,
 		bindAddr:          bindAddr,
@@ -325,7 +325,7 @@ func (c *controller) agentInit(listenAddr, bindAddrOrInterface, advertiseAddr, d
 		coreCancelFuncs:   cancelList,
 		driverCancelFuncs: make(map[string][]func()),
 	}
-	c.Unlock()
+	c.mu.Unlock()
 
 	go c.handleTableEvents(ch, c.handleEpTableEvent)
 	go c.handleTableEvents(nodeCh, c.handleNodeTableEvent)
@@ -348,7 +348,7 @@ func (c *controller) agentInit(listenAddr, bindAddrOrInterface, advertiseAddr, d
 	return nil
 }
 
-func (c *controller) agentJoin(remoteAddrList []string) error {
+func (c *Controller) agentJoin(remoteAddrList []string) error {
 	agent := c.getAgent()
 	if agent == nil {
 		return nil
@@ -356,7 +356,7 @@ func (c *controller) agentJoin(remoteAddrList []string) error {
 	return agent.networkDB.Join(remoteAddrList)
 }
 
-func (c *controller) agentDriverNotify(d driverapi.Driver) {
+func (c *Controller) agentDriverNotify(d driverapi.Driver) {
 	agent := c.getAgent()
 	if agent == nil {
 		return
@@ -380,13 +380,13 @@ func (c *controller) agentDriverNotify(d driverapi.Driver) {
 	}
 }
 
-func (c *controller) agentClose() {
+func (c *Controller) agentClose() {
 	// Acquire current agent instance and reset its pointer
 	// then run closing functions
-	c.Lock()
+	c.mu.Lock()
 	agent := c.agent
 	c.agent = nil
-	c.Unlock()
+	c.mu.Unlock()
 
 	// when the agent is closed the cluster provider should be cleaned up
 	c.SetClusterProvider(nil)
@@ -551,7 +551,7 @@ func (n *network) leaveCluster() error {
 	return agent.networkDB.LeaveNetwork(n.ID())
 }
 
-func (ep *endpoint) addDriverInfoToCluster() error {
+func (ep *Endpoint) addDriverInfoToCluster() error {
 	n := ep.getNetwork()
 	if !n.isClusterEligible() {
 		return nil
@@ -573,7 +573,7 @@ func (ep *endpoint) addDriverInfoToCluster() error {
 	return nil
 }
 
-func (ep *endpoint) deleteDriverInfoFromCluster() error {
+func (ep *Endpoint) deleteDriverInfoFromCluster() error {
 	n := ep.getNetwork()
 	if !n.isClusterEligible() {
 		return nil
@@ -595,7 +595,7 @@ func (ep *endpoint) deleteDriverInfoFromCluster() error {
 	return nil
 }
 
-func (ep *endpoint) addServiceInfoToCluster(sb *sandbox) error {
+func (ep *Endpoint) addServiceInfoToCluster(sb *Sandbox) error {
 	if ep.isAnonymous() && len(ep.myAliases) == 0 || ep.Iface() == nil || ep.Iface().Address() == nil {
 		return nil
 	}
@@ -605,8 +605,8 @@ func (ep *endpoint) addServiceInfoToCluster(sb *sandbox) error {
 		return nil
 	}
 
-	sb.Service.Lock()
-	defer sb.Service.Unlock()
+	sb.service.Lock()
+	defer sb.service.Unlock()
 	logrus.Debugf("addServiceInfoToCluster START for %s %s", ep.svcName, ep.ID())
 
 	// Check that the endpoint is still present on the sandbox before adding it to the service discovery.
@@ -677,7 +677,7 @@ func (ep *endpoint) addServiceInfoToCluster(sb *sandbox) error {
 	return nil
 }
 
-func (ep *endpoint) deleteServiceInfoFromCluster(sb *sandbox, fullRemove bool, method string) error {
+func (ep *Endpoint) deleteServiceInfoFromCluster(sb *Sandbox, fullRemove bool, method string) error {
 	if ep.isAnonymous() && len(ep.myAliases) == 0 {
 		return nil
 	}
@@ -687,8 +687,8 @@ func (ep *endpoint) deleteServiceInfoFromCluster(sb *sandbox, fullRemove bool, m
 		return nil
 	}
 
-	sb.Service.Lock()
-	defer sb.Service.Unlock()
+	sb.service.Lock()
+	defer sb.service.Unlock()
 	logrus.Debugf("deleteServiceInfoFromCluster from %s START for %s %s", method, ep.svcName, ep.ID())
 
 	// Avoid a race w/ with a container that aborts preemptively.  This would
@@ -742,7 +742,7 @@ func (ep *endpoint) deleteServiceInfoFromCluster(sb *sandbox, fullRemove bool, m
 	return nil
 }
 
-func disableServiceInNetworkDB(a *agent, n *network, ep *endpoint) {
+func disableServiceInNetworkDB(a *agent, n *network, ep *Endpoint) {
 	var epRec EndpointRecord
 
 	logrus.Debugf("disableServiceInNetworkDB for %s %s", ep.svcName, ep.ID())
@@ -827,7 +827,7 @@ func (n *network) cancelDriverWatches() {
 	}
 }
 
-func (c *controller) handleTableEvents(ch *events.Channel, fn func(events.Event)) {
+func (c *Controller) handleTableEvents(ch *events.Channel, fn func(events.Event)) {
 	for {
 		select {
 		case ev := <-ch.C:
@@ -873,7 +873,7 @@ func (n *network) handleDriverTableEvent(ev events.Event) {
 	d.EventNotify(etype, n.ID(), tname, key, value)
 }
 
-func (c *controller) handleNodeTableEvent(ev events.Event) {
+func (c *Controller) handleNodeTableEvent(ev events.Event) {
 	var (
 		value    []byte
 		isAdd    bool
@@ -897,7 +897,7 @@ func (c *controller) handleNodeTableEvent(ev events.Event) {
 	c.processNodeDiscovery([]net.IP{nodeAddr.Addr}, isAdd)
 }
 
-func (c *controller) handleEpTableEvent(ev events.Event) {
+func (c *Controller) handleEpTableEvent(ev events.Event) {
 	var (
 		nid   string
 		eid   string

+ 143 - 195
libnetwork/controller.go

@@ -72,101 +72,31 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-// NetworkController provides the interface for controller instance which manages
-// networks.
-type NetworkController interface {
-	// ID provides a unique identity for the controller
-	ID() string
-
-	// BuiltinDrivers returns list of builtin drivers
-	BuiltinDrivers() []string
-
-	// BuiltinIPAMDrivers returns list of builtin ipam drivers
-	BuiltinIPAMDrivers() []string
-
-	// Config method returns the bootup configuration for the controller
-	Config() config.Config
-
-	// Create a new network. The options parameter carries network specific options.
-	NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error)
-
-	// Networks returns the list of Network(s) managed by this controller.
-	Networks() []Network
-
-	// WalkNetworks uses the provided function to walk the Network(s) managed by this controller.
-	WalkNetworks(walker NetworkWalker)
-
-	// NetworkByName returns the Network which has the passed name. If not found, the error ErrNoSuchNetwork is returned.
-	NetworkByName(name string) (Network, error)
-
-	// NetworkByID returns the Network which has the passed id. If not found, the error ErrNoSuchNetwork is returned.
-	NetworkByID(id string) (Network, error)
-
-	// NewSandbox creates a new network sandbox for the passed container id
-	NewSandbox(containerID string, options ...SandboxOption) (Sandbox, error)
-
-	// Sandboxes returns the list of Sandbox(s) managed by this controller.
-	Sandboxes() []Sandbox
-
-	// WalkSandboxes uses the provided function to walk the Sandbox(s) managed by this controller.
-	WalkSandboxes(walker SandboxWalker)
-
-	// SandboxByID returns the Sandbox which has the passed id. If not found, a types.NotFoundError is returned.
-	SandboxByID(id string) (Sandbox, error)
-
-	// SandboxDestroy destroys a sandbox given a container ID
-	SandboxDestroy(id string) error
-
-	// Stop network controller
-	Stop()
-
-	// ReloadConfiguration updates the controller configuration
-	ReloadConfiguration(cfgOptions ...config.Option) error
-
-	// SetClusterProvider sets cluster provider
-	SetClusterProvider(provider cluster.Provider)
-
-	// Wait for agent initialization complete in libnetwork controller
-	AgentInitWait()
-
-	// Wait for agent to stop if running
-	AgentStopWait()
-
-	// SetKeys configures the encryption key for gossip and overlay data path
-	SetKeys(keys []*types.EncryptionKey) error
-
-	// StartDiagnostic start the network diagnostic mode
-	StartDiagnostic(port int)
-	// StopDiagnostic start the network diagnostic mode
-	StopDiagnostic()
-	// IsDiagnosticEnabled returns true if the diagnostic is enabled
-	IsDiagnosticEnabled() bool
-}
-
 // NetworkWalker is a client provided function which will be used to walk the Networks.
 // When the function returns true, the walk will stop.
 type NetworkWalker func(nw Network) bool
 
 // SandboxWalker is a client provided function which will be used to walk the Sandboxes.
 // When the function returns true, the walk will stop.
-type SandboxWalker func(sb Sandbox) bool
+type SandboxWalker func(sb *Sandbox) bool
 
-type sandboxTable map[string]*sandbox
+type sandboxTable map[string]*Sandbox
 
-type controller struct {
+// Controller manages networks.
+type Controller struct {
 	id               string
 	drvRegistry      *drvregistry.DrvRegistry
 	sandboxes        sandboxTable
 	cfg              *config.Config
 	stores           []datastore.DataStore
 	extKeyListener   net.Listener
-	watchCh          chan *endpoint
-	unWatchCh        chan *endpoint
+	watchCh          chan *Endpoint
+	unWatchCh        chan *Endpoint
 	svcRecords       map[string]svcInfo
 	nmap             map[string]*netWatch
 	serviceBindings  map[serviceKey]*service
 	defOsSbox        osl.Sandbox
-	ingressSandbox   *sandbox
+	ingressSandbox   *Sandbox
 	sboxOnce         sync.Once
 	agent            *agent
 	networkLocker    *locker.Locker
@@ -174,7 +104,7 @@ type controller struct {
 	agentStopDone    chan struct{}
 	keys             []*types.EncryptionKey
 	DiagnosticServer *diagnostic.Server
-	sync.Mutex
+	mu               sync.Mutex
 }
 
 type initializer struct {
@@ -183,8 +113,8 @@ type initializer struct {
 }
 
 // New creates a new instance of network controller.
-func New(cfgOptions ...config.Option) (NetworkController, error) {
-	c := &controller{
+func New(cfgOptions ...config.Option) (*Controller, error) {
+	c := &Controller{
 		id:               stringid.GenerateRandomID(),
 		cfg:              config.New(cfgOptions...),
 		sandboxes:        sandboxTable{},
@@ -245,9 +175,10 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
 	return c, nil
 }
 
-func (c *controller) SetClusterProvider(provider cluster.Provider) {
+// SetClusterProvider sets the cluster provider.
+func (c *Controller) SetClusterProvider(provider cluster.Provider) {
 	var sameProvider bool
-	c.Lock()
+	c.mu.Lock()
 	// Avoids to spawn multiple goroutine for the same cluster provider
 	if c.cfg.ClusterProvider == provider {
 		// If the cluster provider is already set, there is already a go routine spawned
@@ -256,7 +187,7 @@ func (c *controller) SetClusterProvider(provider cluster.Provider) {
 	} else {
 		c.cfg.ClusterProvider = provider
 	}
-	c.Unlock()
+	c.mu.Unlock()
 
 	if provider == nil || sameProvider {
 		return
@@ -266,9 +197,10 @@ func (c *controller) SetClusterProvider(provider cluster.Provider) {
 	go c.clusterAgentInit()
 }
 
-// libnetwork side of agent depends on the keys. On the first receipt of
-// keys setup the agent. For subsequent key set handle the key change
-func (c *controller) SetKeys(keys []*types.EncryptionKey) error {
+// SetKeys configures the encryption key for gossip and overlay data path.
+func (c *Controller) SetKeys(keys []*types.EncryptionKey) error {
+	// libnetwork side of agent depends on the keys. On the first receipt of
+	// keys setup the agent. For subsequent key set handle the key change
 	subsysKeys := make(map[string]int)
 	for _, key := range keys {
 		if key.Subsystem != subsysGossip &&
@@ -284,21 +216,21 @@ func (c *controller) SetKeys(keys []*types.EncryptionKey) error {
 	}
 
 	if c.getAgent() == nil {
-		c.Lock()
+		c.mu.Lock()
 		c.keys = keys
-		c.Unlock()
+		c.mu.Unlock()
 		return nil
 	}
 	return c.handleKeyChange(keys)
 }
 
-func (c *controller) getAgent() *agent {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) getAgent() *agent {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	return c.agent
 }
 
-func (c *controller) clusterAgentInit() {
+func (c *Controller) clusterAgentInit() {
 	clusterProvider := c.cfg.ClusterProvider
 	var keysAvailable bool
 	for {
@@ -309,9 +241,9 @@ func (c *controller) clusterAgentInit() {
 		case cluster.EventNetworkKeysAvailable:
 			// Validates that the keys are actually available before starting the initialization
 			// This will handle old spurious messages left on the channel
-			c.Lock()
+			c.mu.Lock()
 			keysAvailable = c.keys != nil
-			c.Unlock()
+			c.mu.Unlock()
 			fallthrough
 		case cluster.EventSocketChange, cluster.EventNodeReady:
 			if keysAvailable && !c.isDistributedControl() {
@@ -324,9 +256,9 @@ func (c *controller) clusterAgentInit() {
 			}
 		case cluster.EventNodeLeave:
 			c.agentOperationStart()
-			c.Lock()
+			c.mu.Lock()
 			c.keys = nil
-			c.Unlock()
+			c.mu.Unlock()
 
 			// We are leaving the cluster. Make sure we
 			// close the gossip so that we stop all
@@ -347,59 +279,59 @@ func (c *controller) clusterAgentInit() {
 }
 
 // AgentInitWait waits for agent initialization to be completed in the controller.
-func (c *controller) AgentInitWait() {
-	c.Lock()
+func (c *Controller) AgentInitWait() {
+	c.mu.Lock()
 	agentInitDone := c.agentInitDone
-	c.Unlock()
+	c.mu.Unlock()
 
 	if agentInitDone != nil {
 		<-agentInitDone
 	}
 }
 
-// AgentStopWait waits for the Agent stop to be completed in the controller
-func (c *controller) AgentStopWait() {
-	c.Lock()
+// AgentStopWait waits for the Agent stop to be completed in the controller.
+func (c *Controller) AgentStopWait() {
+	c.mu.Lock()
 	agentStopDone := c.agentStopDone
-	c.Unlock()
+	c.mu.Unlock()
 	if agentStopDone != nil {
 		<-agentStopDone
 	}
 }
 
 // agentOperationStart marks the start of an Agent Init or Agent Stop
-func (c *controller) agentOperationStart() {
-	c.Lock()
+func (c *Controller) agentOperationStart() {
+	c.mu.Lock()
 	if c.agentInitDone == nil {
 		c.agentInitDone = make(chan struct{})
 	}
 	if c.agentStopDone == nil {
 		c.agentStopDone = make(chan struct{})
 	}
-	c.Unlock()
+	c.mu.Unlock()
 }
 
 // agentInitComplete notifies the successful completion of the Agent initialization
-func (c *controller) agentInitComplete() {
-	c.Lock()
+func (c *Controller) agentInitComplete() {
+	c.mu.Lock()
 	if c.agentInitDone != nil {
 		close(c.agentInitDone)
 		c.agentInitDone = nil
 	}
-	c.Unlock()
+	c.mu.Unlock()
 }
 
 // agentStopComplete notifies the successful completion of the Agent stop
-func (c *controller) agentStopComplete() {
-	c.Lock()
+func (c *Controller) agentStopComplete() {
+	c.mu.Lock()
 	if c.agentStopDone != nil {
 		close(c.agentStopDone)
 		c.agentStopDone = nil
 	}
-	c.Unlock()
+	c.mu.Unlock()
 }
 
-func (c *controller) makeDriverConfig(ntype string) map[string]interface{} {
+func (c *Controller) makeDriverConfig(ntype string) map[string]interface{} {
 	if c.cfg == nil {
 		return nil
 	}
@@ -438,7 +370,8 @@ func (c *controller) makeDriverConfig(ntype string) map[string]interface{} {
 
 var procReloadConfig = make(chan (bool), 1)
 
-func (c *controller) ReloadConfiguration(cfgOptions ...config.Option) error {
+// ReloadConfiguration updates the controller configuration.
+func (c *Controller) ReloadConfiguration(cfgOptions ...config.Option) error {
 	procReloadConfig <- true
 	defer func() { <-procReloadConfig }()
 
@@ -469,9 +402,9 @@ func (c *controller) ReloadConfiguration(cfgOptions ...config.Option) error {
 		return nil
 	}
 
-	c.Lock()
+	c.mu.Lock()
 	c.cfg = cfg
-	c.Unlock()
+	c.mu.Unlock()
 
 	var dsConfig *discoverapi.DatastoreConfigData
 	for scope, sCfg := range cfg.Scopes {
@@ -508,11 +441,13 @@ func (c *controller) ReloadConfiguration(cfgOptions ...config.Option) error {
 	return nil
 }
 
-func (c *controller) ID() string {
+// ID returns the controller's unique identity.
+func (c *Controller) ID() string {
 	return c.id
 }
 
-func (c *controller) BuiltinDrivers() []string {
+// BuiltinDrivers returns the list of builtin network drivers.
+func (c *Controller) BuiltinDrivers() []string {
 	drivers := []string{}
 	c.drvRegistry.WalkDrivers(func(name string, driver driverapi.Driver, capability driverapi.Capability) bool {
 		if driver.IsBuiltIn() {
@@ -523,7 +458,8 @@ func (c *controller) BuiltinDrivers() []string {
 	return drivers
 }
 
-func (c *controller) BuiltinIPAMDrivers() []string {
+// BuiltinIPAMDrivers returns the list of builtin ipam drivers.
+func (c *Controller) BuiltinIPAMDrivers() []string {
 	drivers := []string{}
 	c.drvRegistry.WalkIPAMs(func(name string, driver ipamapi.Ipam, cap *ipamapi.Capability) bool {
 		if driver.IsBuiltIn() {
@@ -534,14 +470,14 @@ func (c *controller) BuiltinIPAMDrivers() []string {
 	return drivers
 }
 
-func (c *controller) processNodeDiscovery(nodes []net.IP, add bool) {
+func (c *Controller) processNodeDiscovery(nodes []net.IP, add bool) {
 	c.drvRegistry.WalkDrivers(func(name string, driver driverapi.Driver, capability driverapi.Capability) bool {
 		c.pushNodeDiscovery(driver, capability, nodes, add)
 		return false
 	})
 }
 
-func (c *controller) pushNodeDiscovery(d driverapi.Driver, cap driverapi.Capability, nodes []net.IP, add bool) {
+func (c *Controller) pushNodeDiscovery(d driverapi.Driver, cap driverapi.Capability, nodes []net.IP, add bool) {
 	var self net.IP
 	// try swarm-mode config
 	if agent := c.getAgent(); agent != nil {
@@ -566,42 +502,43 @@ func (c *controller) pushNodeDiscovery(d driverapi.Driver, cap driverapi.Capabil
 	}
 }
 
-func (c *controller) Config() config.Config {
-	c.Lock()
-	defer c.Unlock()
+// Config returns the bootup configuration for the controller.
+func (c *Controller) Config() config.Config {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	if c.cfg == nil {
 		return config.Config{}
 	}
 	return *c.cfg
 }
 
-func (c *controller) isManager() bool {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) isManager() bool {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	if c.cfg == nil || c.cfg.ClusterProvider == nil {
 		return false
 	}
 	return c.cfg.ClusterProvider.IsManager()
 }
 
-func (c *controller) isAgent() bool {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) isAgent() bool {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	if c.cfg == nil || c.cfg.ClusterProvider == nil {
 		return false
 	}
 	return c.cfg.ClusterProvider.IsAgent()
 }
 
-func (c *controller) isDistributedControl() bool {
+func (c *Controller) isDistributedControl() bool {
 	return !c.isManager() && !c.isAgent()
 }
 
-func (c *controller) GetPluginGetter() plugingetter.PluginGetter {
+func (c *Controller) GetPluginGetter() plugingetter.PluginGetter {
 	return c.drvRegistry.GetPluginGetter()
 }
 
-func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error {
+func (c *Controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error {
 	c.agentDriverNotify(driver)
 	return nil
 }
@@ -611,7 +548,7 @@ const overlayDSROptionString = "dsr"
 
 // NewNetwork creates a new network of the specified network type. The options
 // are network specific and modeled in a generic way.
-func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
+func (c *Controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
 	var (
 		caps           *driverapi.Capability
 		err            error
@@ -811,9 +748,9 @@ addToStore:
 	}
 
 	if !c.isDistributedControl() {
-		c.Lock()
+		c.mu.Lock()
 		arrangeIngressFilterRule()
-		c.Unlock()
+		c.mu.Unlock()
 	}
 	arrangeUserFilterRule()
 
@@ -832,7 +769,7 @@ var joinCluster NetworkWalker = func(nw Network) bool {
 	return false
 }
 
-func (c *controller) reservePools() {
+func (c *Controller) reservePools() {
 	networks, err := c.getNetworksForScope(datastore.LocalScope)
 	if err != nil {
 		logrus.Warnf("Could not retrieve networks from local store during ipam allocation for existing networks: %v", err)
@@ -905,7 +842,7 @@ func doReplayPoolReserve(n *network) bool {
 	return caps.RequiresRequestReplay
 }
 
-func (c *controller) addNetwork(n *network) error {
+func (c *Controller) addNetwork(n *network) error {
 	d, err := n.driver(true)
 	if err != nil {
 		return err
@@ -921,7 +858,8 @@ func (c *controller) addNetwork(n *network) error {
 	return nil
 }
 
-func (c *controller) Networks() []Network {
+// Networks returns the list of Network(s) managed by this controller.
+func (c *Controller) Networks() []Network {
 	var list []Network
 
 	for _, n := range c.getNetworksFromStore() {
@@ -934,7 +872,8 @@ func (c *controller) Networks() []Network {
 	return list
 }
 
-func (c *controller) WalkNetworks(walker NetworkWalker) {
+// WalkNetworks uses the provided function to walk the Network(s) managed by this controller.
+func (c *Controller) WalkNetworks(walker NetworkWalker) {
 	for _, n := range c.Networks() {
 		if walker(n) {
 			return
@@ -942,7 +881,9 @@ func (c *controller) WalkNetworks(walker NetworkWalker) {
 	}
 }
 
-func (c *controller) NetworkByName(name string) (Network, error) {
+// NetworkByName returns the Network which has the passed name.
+// If not found, the error [ErrNoSuchNetwork] is returned.
+func (c *Controller) NetworkByName(name string) (Network, error) {
 	if name == "" {
 		return nil, ErrInvalidName(name)
 	}
@@ -965,7 +906,9 @@ func (c *controller) NetworkByName(name string) (Network, error) {
 	return n, nil
 }
 
-func (c *controller) NetworkByID(id string) (Network, error) {
+// NetworkByID returns the Network which has the passed id.
+// If not found, the error [ErrNoSuchNetwork] is returned.
+func (c *Controller) NetworkByID(id string) (Network, error) {
 	if id == "" {
 		return nil, ErrInvalidID(id)
 	}
@@ -978,20 +921,20 @@ func (c *controller) NetworkByID(id string) (Network, error) {
 	return n, nil
 }
 
-// NewSandbox creates a new sandbox for the passed container id
-func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (Sandbox, error) {
+// NewSandbox creates a new sandbox for containerID.
+func (c *Controller) NewSandbox(containerID string, options ...SandboxOption) (*Sandbox, error) {
 	if containerID == "" {
 		return nil, types.BadRequestErrorf("invalid container ID")
 	}
 
-	var sb *sandbox
-	c.Lock()
+	var sb *Sandbox
+	c.mu.Lock()
 	for _, s := range c.sandboxes {
 		if s.containerID == containerID {
 			// If not a stub, then we already have a complete sandbox.
 			if !s.isStub {
 				sbID := s.ID()
-				c.Unlock()
+				c.mu.Unlock()
 				return nil, types.ForbiddenErrorf("container %s is already present in sandbox %s", containerID, sbID)
 			}
 
@@ -1004,7 +947,7 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
 			break
 		}
 	}
-	c.Unlock()
+	c.mu.Unlock()
 
 	sandboxID := stringid.GenerateRandomID()
 	if runtime.GOOS == "windows" {
@@ -1013,10 +956,10 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
 
 	// Create sandbox and process options first. Key generation depends on an option
 	if sb == nil {
-		sb = &sandbox{
+		sb = &Sandbox{
 			id:                 sandboxID,
 			containerID:        containerID,
-			endpoints:          []*endpoint{},
+			endpoints:          []*Endpoint{},
 			epPriority:         map[string]int{},
 			populatedEndpoints: map[string]struct{}{},
 			config:             containerConfig{},
@@ -1027,9 +970,9 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
 
 	sb.processOptions(options...)
 
-	c.Lock()
+	c.mu.Lock()
 	if sb.ingress && c.ingressSandbox != nil {
-		c.Unlock()
+		c.mu.Unlock()
 		return nil, types.ForbiddenErrorf("ingress sandbox already present")
 	}
 
@@ -1041,16 +984,16 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
 	} else if sb.loadBalancerNID != "" {
 		sb.id = "lb_" + sb.loadBalancerNID
 	}
-	c.Unlock()
+	c.mu.Unlock()
 
 	var err error
 	defer func() {
 		if err != nil {
-			c.Lock()
+			c.mu.Lock()
 			if sb.ingress {
 				c.ingressSandbox = nil
 			}
-			c.Unlock()
+			c.mu.Unlock()
 		}
 	}()
 
@@ -1090,14 +1033,14 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
 		sb.osSbox.ApplyOSTweaks(sb.oslTypes)
 	}
 
-	c.Lock()
+	c.mu.Lock()
 	c.sandboxes[sb.id] = sb
-	c.Unlock()
+	c.mu.Unlock()
 	defer func() {
 		if err != nil {
-			c.Lock()
+			c.mu.Lock()
 			delete(c.sandboxes, sb.id)
-			c.Unlock()
+			c.mu.Unlock()
 		}
 	}()
 
@@ -1109,11 +1052,12 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
 	return sb, nil
 }
 
-func (c *controller) Sandboxes() []Sandbox {
-	c.Lock()
-	defer c.Unlock()
+// Sandboxes returns the list of Sandbox(s) managed by this controller.
+func (c *Controller) Sandboxes() []*Sandbox {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 
-	list := make([]Sandbox, 0, len(c.sandboxes))
+	list := make([]*Sandbox, 0, len(c.sandboxes))
 	for _, s := range c.sandboxes {
 		// Hide stub sandboxes from libnetwork users
 		if s.isStub {
@@ -1126,7 +1070,8 @@ func (c *controller) Sandboxes() []Sandbox {
 	return list
 }
 
-func (c *controller) WalkSandboxes(walker SandboxWalker) {
+// WalkSandboxes uses the provided function to walk the Sandbox(s) managed by this controller.
+func (c *Controller) WalkSandboxes(walker SandboxWalker) {
 	for _, sb := range c.Sandboxes() {
 		if walker(sb) {
 			return
@@ -1134,30 +1079,32 @@ func (c *controller) WalkSandboxes(walker SandboxWalker) {
 	}
 }
 
-func (c *controller) SandboxByID(id string) (Sandbox, error) {
+// SandboxByID returns the Sandbox which has the passed id.
+// If not found, a [types.NotFoundError] is returned.
+func (c *Controller) SandboxByID(id string) (*Sandbox, error) {
 	if id == "" {
 		return nil, ErrInvalidID(id)
 	}
-	c.Lock()
+	c.mu.Lock()
 	s, ok := c.sandboxes[id]
-	c.Unlock()
+	c.mu.Unlock()
 	if !ok {
 		return nil, types.NotFoundErrorf("sandbox %s not found", id)
 	}
 	return s, nil
 }
 
-// SandboxDestroy destroys a sandbox given a container ID
-func (c *controller) SandboxDestroy(id string) error {
-	var sb *sandbox
-	c.Lock()
+// SandboxDestroy destroys a sandbox given a container ID.
+func (c *Controller) SandboxDestroy(id string) error {
+	var sb *Sandbox
+	c.mu.Lock()
 	for _, s := range c.sandboxes {
 		if s.containerID == id {
 			sb = s
 			break
 		}
 	}
-	c.Unlock()
+	c.mu.Unlock()
 
 	// It is not an error if sandbox is not available
 	if sb == nil {
@@ -1168,8 +1115,8 @@ func (c *controller) SandboxDestroy(id string) error {
 }
 
 // SandboxContainerWalker returns a Sandbox Walker function which looks for an existing Sandbox with the passed containerID
-func SandboxContainerWalker(out *Sandbox, containerID string) SandboxWalker {
-	return func(sb Sandbox) bool {
+func SandboxContainerWalker(out **Sandbox, containerID string) SandboxWalker {
+	return func(sb *Sandbox) bool {
 		if sb.ContainerID() == containerID {
 			*out = sb
 			return true
@@ -1179,8 +1126,8 @@ func SandboxContainerWalker(out *Sandbox, containerID string) SandboxWalker {
 }
 
 // SandboxKeyWalker returns a Sandbox Walker function which looks for an existing Sandbox with the passed key
-func SandboxKeyWalker(out *Sandbox, key string) SandboxWalker {
-	return func(sb Sandbox) bool {
+func SandboxKeyWalker(out **Sandbox, key string) SandboxWalker {
+	return func(sb *Sandbox) bool {
 		if sb.Key() == key {
 			*out = sb
 			return true
@@ -1189,7 +1136,7 @@ func SandboxKeyWalker(out *Sandbox, key string) SandboxWalker {
 	}
 }
 
-func (c *controller) loadDriver(networkType string) error {
+func (c *Controller) loadDriver(networkType string) error {
 	var err error
 
 	if pg := c.GetPluginGetter(); pg != nil {
@@ -1208,7 +1155,7 @@ func (c *controller) loadDriver(networkType string) error {
 	return nil
 }
 
-func (c *controller) loadIPAMDriver(name string) error {
+func (c *Controller) loadIPAMDriver(name string) error {
 	var err error
 
 	if pg := c.GetPluginGetter(); pg != nil {
@@ -1227,7 +1174,7 @@ func (c *controller) loadIPAMDriver(name string) error {
 	return nil
 }
 
-func (c *controller) getIPAMDriver(name string) (ipamapi.Ipam, *ipamapi.Capability, error) {
+func (c *Controller) getIPAMDriver(name string) (ipamapi.Ipam, *ipamapi.Capability, error) {
 	id, cap := c.drvRegistry.IPAM(name)
 	if id == nil {
 		// Might be a plugin name. Try loading it
@@ -1245,40 +1192,41 @@ func (c *controller) getIPAMDriver(name string) (ipamapi.Ipam, *ipamapi.Capabili
 	return id, cap, nil
 }
 
-func (c *controller) Stop() {
+// Stop stops the network controller.
+func (c *Controller) Stop() {
 	c.closeStores()
 	c.stopExternalKeyListener()
 	osl.GC()
 }
 
-// StartDiagnostic start the network dias mode
-func (c *controller) StartDiagnostic(port int) {
-	c.Lock()
+// StartDiagnostic starts the network diagnostic server listening on port.
+func (c *Controller) StartDiagnostic(port int) {
+	c.mu.Lock()
 	if !c.DiagnosticServer.IsDiagnosticEnabled() {
 		c.DiagnosticServer.EnableDiagnostic("127.0.0.1", port)
 	}
-	c.Unlock()
+	c.mu.Unlock()
 }
 
-// StopDiagnostic start the network dias mode
-func (c *controller) StopDiagnostic() {
-	c.Lock()
+// StopDiagnostic stops the network diagnostic server.
+func (c *Controller) StopDiagnostic() {
+	c.mu.Lock()
 	if c.DiagnosticServer.IsDiagnosticEnabled() {
 		c.DiagnosticServer.DisableDiagnostic()
 	}
-	c.Unlock()
+	c.mu.Unlock()
 }
 
-// IsDiagnosticEnabled returns true if the dias is enabled
-func (c *controller) IsDiagnosticEnabled() bool {
-	c.Lock()
-	defer c.Unlock()
+// IsDiagnosticEnabled returns true if the diagnostic server is running.
+func (c *Controller) IsDiagnosticEnabled() bool {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	return c.DiagnosticServer.IsDiagnosticEnabled()
 }
 
-func (c *controller) iptablesEnabled() bool {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) iptablesEnabled() bool {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 
 	if c.cfg == nil {
 		return false

+ 12 - 14
libnetwork/default_gateway.go

@@ -29,7 +29,7 @@ var procGwNetwork = make(chan (bool), 1)
    - its deleted when an endpoint with GW joins the container
 */
 
-func (sb *sandbox) setupDefaultGW() error {
+func (sb *Sandbox) setupDefaultGW() error {
 	// check if the container already has a GW endpoint
 	if ep := sb.getEndpointInGWNetwork(); ep != nil {
 		return nil
@@ -84,9 +84,7 @@ func (sb *sandbox) setupDefaultGW() error {
 		}
 	}()
 
-	epLocal := newEp.(*endpoint)
-
-	if err = epLocal.sbJoin(sb); err != nil {
+	if err = newEp.sbJoin(sb); err != nil {
 		return fmt.Errorf("container %s: endpoint join on GW Network failed: %v", sb.containerID, err)
 	}
 
@@ -94,8 +92,8 @@ func (sb *sandbox) setupDefaultGW() error {
 }
 
 // If present, detach and remove the endpoint connecting the sandbox to the default gw network.
-func (sb *sandbox) clearDefaultGW() error {
-	var ep *endpoint
+func (sb *Sandbox) clearDefaultGW() error {
+	var ep *Endpoint
 
 	if ep = sb.getEndpointInGWNetwork(); ep == nil {
 		return nil
@@ -113,10 +111,10 @@ func (sb *sandbox) clearDefaultGW() error {
 // on the endpoints to which it is connected. It does not account
 // for the default gateway network endpoint.
 
-func (sb *sandbox) needDefaultGW() bool {
+func (sb *Sandbox) needDefaultGW() bool {
 	var needGW bool
 
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		if ep.endpointInGWNetwork() {
 			continue
 		}
@@ -145,8 +143,8 @@ func (sb *sandbox) needDefaultGW() bool {
 	return needGW
 }
 
-func (sb *sandbox) getEndpointInGWNetwork() *endpoint {
-	for _, ep := range sb.getConnectedEndpoints() {
+func (sb *Sandbox) getEndpointInGWNetwork() *Endpoint {
+	for _, ep := range sb.Endpoints() {
 		if ep.getNetwork().name == libnGWNetwork && strings.HasPrefix(ep.Name(), "gateway_") {
 			return ep
 		}
@@ -154,7 +152,7 @@ func (sb *sandbox) getEndpointInGWNetwork() *endpoint {
 	return nil
 }
 
-func (ep *endpoint) endpointInGWNetwork() bool {
+func (ep *Endpoint) endpointInGWNetwork() bool {
 	if ep.getNetwork().name == libnGWNetwork && strings.HasPrefix(ep.Name(), "gateway_") {
 		return true
 	}
@@ -163,7 +161,7 @@ func (ep *endpoint) endpointInGWNetwork() bool {
 
 // Looks for the default gw network and creates it if not there.
 // Parallel executions are serialized.
-func (c *controller) defaultGwNetwork() (Network, error) {
+func (c *Controller) defaultGwNetwork() (Network, error) {
 	procGwNetwork <- true
 	defer func() { <-procGwNetwork }()
 
@@ -175,8 +173,8 @@ func (c *controller) defaultGwNetwork() (Network, error) {
 }
 
 // Returns the endpoint which is providing external connectivity to the sandbox
-func (sb *sandbox) getGatewayEndpoint() *endpoint {
-	for _, ep := range sb.getConnectedEndpoints() {
+func (sb *Sandbox) getGatewayEndpoint() *Endpoint {
+	for _, ep := range sb.Endpoints() {
 		if ep.getNetwork().Type() == "null" || ep.getNetwork().Type() == "host" {
 			continue
 		}

+ 1 - 1
libnetwork/default_gateway_freebsd.go

@@ -8,6 +8,6 @@ func getPlatformOption() EndpointOption {
 	return nil
 }
 
-func (c *controller) createGWNetwork() (Network, error) {
+func (c *Controller) createGWNetwork() (Network, error) {
 	return nil, types.NotImplementedErrorf("default gateway functionality is not implemented in freebsd")
 }

+ 1 - 1
libnetwork/default_gateway_linux.go

@@ -13,7 +13,7 @@ func getPlatformOption() EndpointOption {
 	return nil
 }
 
-func (c *controller) createGWNetwork() (Network, error) {
+func (c *Controller) createGWNetwork() (Network, error) {
 	netOption := map[string]string{
 		bridge.BridgeName:         libnGWNetwork,
 		bridge.EnableICC:          strconv.FormatBool(false),

+ 1 - 1
libnetwork/default_gateway_windows.go

@@ -17,6 +17,6 @@ func getPlatformOption() EndpointOption {
 	return EndpointOptionGeneric(epOption)
 }
 
-func (c *controller) createGWNetwork() (Network, error) {
+func (c *Controller) createGWNetwork() (Network, error) {
 	return nil, types.NotImplementedErrorf("default gateway functionality is not implemented in windows")
 }

+ 131 - 161
libnetwork/endpoint.go

@@ -14,40 +14,13 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-// Endpoint represents a logical connection between a network and a sandbox.
-type Endpoint interface {
-	// A system generated id for this endpoint.
-	ID() string
-
-	// Name returns the name of this endpoint.
-	Name() string
-
-	// Network returns the name of the network to which this endpoint is attached.
-	Network() string
-
-	// Join joins the sandbox to the endpoint and populates into the sandbox
-	// the network resources allocated for the endpoint.
-	Join(sandbox Sandbox, options ...EndpointOption) error
-
-	// Leave detaches the network resources populated in the sandbox.
-	Leave(sandbox Sandbox, options ...EndpointOption) error
-
-	// Return certain operational data belonging to this endpoint
-	Info() EndpointInfo
-
-	// DriverInfo returns a collection of driver operational data related to this endpoint retrieved from the driver
-	DriverInfo() (map[string]interface{}, error)
-
-	// Delete and detaches this endpoint from the network.
-	Delete(force bool) error
-}
-
 // EndpointOption is an option setter function type used to pass various options to Network
 // and Endpoint interfaces methods. The various setter functions of type EndpointOption are
 // provided by libnetwork, they look like <Create|Join|Leave>Option[...](...)
-type EndpointOption func(ep *endpoint)
+type EndpointOption func(ep *Endpoint)
 
-type endpoint struct {
+// Endpoint represents a logical connection between a network and a sandbox.
+type Endpoint struct {
 	name              string
 	id                string
 	network           *network
@@ -72,12 +45,12 @@ type endpoint struct {
 	dbExists          bool
 	serviceEnabled    bool
 	loadBalancer      bool
-	sync.Mutex
+	mu                sync.Mutex
 }
 
-func (ep *endpoint) MarshalJSON() ([]byte, error) {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) MarshalJSON() ([]byte, error) {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	epMap := make(map[string]interface{})
 	epMap["name"] = ep.name
@@ -102,9 +75,9 @@ func (ep *endpoint) MarshalJSON() ([]byte, error) {
 	return json.Marshal(epMap)
 }
 
-func (ep *endpoint) UnmarshalJSON(b []byte) (err error) {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) UnmarshalJSON(b []byte) (err error) {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	var epMap map[string]interface{}
 	if err := json.Unmarshal(b, &epMap); err != nil {
@@ -221,15 +194,15 @@ func (ep *endpoint) UnmarshalJSON(b []byte) (err error) {
 	return nil
 }
 
-func (ep *endpoint) New() datastore.KVObject {
-	return &endpoint{network: ep.getNetwork()}
+func (ep *Endpoint) New() datastore.KVObject {
+	return &Endpoint{network: ep.getNetwork()}
 }
 
-func (ep *endpoint) CopyTo(o datastore.KVObject) error {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) CopyTo(o datastore.KVObject) error {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
-	dstEp := o.(*endpoint)
+	dstEp := o.(*Endpoint)
 	dstEp.name = ep.name
 	dstEp.id = ep.id
 	dstEp.sandboxID = ep.sandboxID
@@ -276,28 +249,31 @@ func (ep *endpoint) CopyTo(o datastore.KVObject) error {
 	return nil
 }
 
-func (ep *endpoint) ID() string {
-	ep.Lock()
-	defer ep.Unlock()
+// ID returns the system-generated id for this endpoint.
+func (ep *Endpoint) ID() string {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	return ep.id
 }
 
-func (ep *endpoint) Name() string {
-	ep.Lock()
-	defer ep.Unlock()
+// Name returns the name of this endpoint.
+func (ep *Endpoint) Name() string {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	return ep.name
 }
 
-func (ep *endpoint) MyAliases() []string {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) MyAliases() []string {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	return ep.myAliases
 }
 
-func (ep *endpoint) Network() string {
+// Network returns the name of the network to which this endpoint is attached.
+func (ep *Endpoint) Network() string {
 	if ep.network == nil {
 		return ""
 	}
@@ -305,41 +281,41 @@ func (ep *endpoint) Network() string {
 	return ep.network.name
 }
 
-func (ep *endpoint) isAnonymous() bool {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) isAnonymous() bool {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 	return ep.anonymous
 }
 
 // isServiceEnabled check if service is enabled on the endpoint
-func (ep *endpoint) isServiceEnabled() bool {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) isServiceEnabled() bool {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 	return ep.serviceEnabled
 }
 
 // enableService sets service enabled on the endpoint
-func (ep *endpoint) enableService() {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) enableService() {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 	ep.serviceEnabled = true
 }
 
 // disableService disables service on the endpoint
-func (ep *endpoint) disableService() {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) disableService() {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 	ep.serviceEnabled = false
 }
 
-func (ep *endpoint) needResolver() bool {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) needResolver() bool {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 	return !ep.disableResolution
 }
 
 // endpoint Key structure : endpoint/network-id/endpoint-id
-func (ep *endpoint) Key() []string {
+func (ep *Endpoint) Key() []string {
 	if ep.network == nil {
 		return nil
 	}
@@ -347,7 +323,7 @@ func (ep *endpoint) Key() []string {
 	return []string{datastore.EndpointKeyPrefix, ep.network.id, ep.id}
 }
 
-func (ep *endpoint) KeyPrefix() []string {
+func (ep *Endpoint) KeyPrefix() []string {
 	if ep.network == nil {
 		return nil
 	}
@@ -355,7 +331,7 @@ func (ep *endpoint) KeyPrefix() []string {
 	return []string{datastore.EndpointKeyPrefix, ep.network.id}
 }
 
-func (ep *endpoint) Value() []byte {
+func (ep *Endpoint) Value() []byte {
 	b, err := json.Marshal(ep)
 	if err != nil {
 		return nil
@@ -363,36 +339,36 @@ func (ep *endpoint) Value() []byte {
 	return b
 }
 
-func (ep *endpoint) SetValue(value []byte) error {
+func (ep *Endpoint) SetValue(value []byte) error {
 	return json.Unmarshal(value, ep)
 }
 
-func (ep *endpoint) Index() uint64 {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) Index() uint64 {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 	return ep.dbIndex
 }
 
-func (ep *endpoint) SetIndex(index uint64) {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) SetIndex(index uint64) {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 	ep.dbIndex = index
 	ep.dbExists = true
 }
 
-func (ep *endpoint) Exists() bool {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) Exists() bool {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 	return ep.dbExists
 }
 
-func (ep *endpoint) Skip() bool {
+func (ep *Endpoint) Skip() bool {
 	return ep.getNetwork().Skip()
 }
 
-func (ep *endpoint) processOptions(options ...EndpointOption) {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) processOptions(options ...EndpointOption) {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	for _, opt := range options {
 		if opt != nil {
@@ -401,14 +377,14 @@ func (ep *endpoint) processOptions(options ...EndpointOption) {
 	}
 }
 
-func (ep *endpoint) getNetwork() *network {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) getNetwork() *network {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	return ep.network
 }
 
-func (ep *endpoint) getNetworkFromStore() (*network, error) {
+func (ep *Endpoint) getNetworkFromStore() (*network, error) {
 	if ep.network == nil {
 		return nil, fmt.Errorf("invalid network object in endpoint %s", ep.Name())
 	}
@@ -416,14 +392,11 @@ func (ep *endpoint) getNetworkFromStore() (*network, error) {
 	return ep.network.getController().getNetworkFromStore(ep.network.id)
 }
 
-func (ep *endpoint) Join(sbox Sandbox, options ...EndpointOption) error {
-	if sbox == nil {
-		return types.BadRequestErrorf("endpoint cannot be joined by nil container")
-	}
-
-	sb, ok := sbox.(*sandbox)
-	if !ok {
-		return types.BadRequestErrorf("not a valid Sandbox interface")
+// Join joins the sandbox to the endpoint and populates into the sandbox
+// the network resources allocated for the endpoint.
+func (ep *Endpoint) Join(sb *Sandbox, options ...EndpointOption) error {
+	if sb == nil || sb.ID() == "" || sb.Key() == "" {
+		return types.BadRequestErrorf("invalid Sandbox passed to endpoint join: %v", sb)
 	}
 
 	sb.joinLeaveStart()
@@ -432,7 +405,7 @@ func (ep *endpoint) Join(sbox Sandbox, options ...EndpointOption) error {
 	return ep.sbJoin(sb, options...)
 }
 
-func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) {
+func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) {
 	n, err := ep.getNetworkFromStore()
 	if err != nil {
 		return fmt.Errorf("failed to get network from store during join: %v", err)
@@ -443,21 +416,21 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) {
 		return fmt.Errorf("failed to get endpoint from store during join: %v", err)
 	}
 
-	ep.Lock()
+	ep.mu.Lock()
 	if ep.sandboxID != "" {
-		ep.Unlock()
+		ep.mu.Unlock()
 		return types.ForbiddenErrorf("another container is attached to the same network endpoint")
 	}
 	ep.network = n
 	ep.sandboxID = sb.ID()
 	ep.joinInfo = &endpointJoinInfo{}
 	epid := ep.id
-	ep.Unlock()
+	ep.mu.Unlock()
 	defer func() {
 		if err != nil {
-			ep.Lock()
+			ep.mu.Lock()
 			ep.sandboxID = ""
-			ep.Unlock()
+			ep.mu.Unlock()
 		}
 	}()
 
@@ -591,7 +564,7 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) {
 	return nil
 }
 
-func (ep *endpoint) rename(name string) error {
+func (ep *Endpoint) rename(name string) error {
 	var (
 		err      error
 		netWatch *netWatch
@@ -616,9 +589,9 @@ func (ep *endpoint) rename(name string) error {
 			return types.InternalErrorf("Could not delete service state for endpoint %s from cluster on rename: %v", ep.Name(), err)
 		}
 	} else {
-		c.Lock()
+		c.mu.Lock()
 		netWatch, ok = c.nmap[n.ID()]
-		c.Unlock()
+		c.mu.Unlock()
 		if !ok {
 			return fmt.Errorf("watch null for network %q", n.Name())
 		}
@@ -674,21 +647,17 @@ func (ep *endpoint) rename(name string) error {
 	return err
 }
 
-func (ep *endpoint) hasInterface(iName string) bool {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) hasInterface(iName string) bool {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	return ep.iface != nil && ep.iface.srcName == iName
 }
 
-func (ep *endpoint) Leave(sbox Sandbox, options ...EndpointOption) error {
-	if sbox == nil || sbox.ID() == "" || sbox.Key() == "" {
-		return types.BadRequestErrorf("invalid Sandbox passed to endpoint leave: %v", sbox)
-	}
-
-	sb, ok := sbox.(*sandbox)
-	if !ok {
-		return types.BadRequestErrorf("not a valid Sandbox interface")
+// Leave detaches the network resources populated in the sandbox.
+func (ep *Endpoint) Leave(sb *Sandbox, options ...EndpointOption) error {
+	if sb == nil || sb.ID() == "" || sb.Key() == "" {
+		return types.BadRequestErrorf("invalid Sandbox passed to endpoint leave: %v", sb)
 	}
 
 	sb.joinLeaveStart()
@@ -697,7 +666,7 @@ func (ep *endpoint) Leave(sbox Sandbox, options ...EndpointOption) error {
 	return ep.sbLeave(sb, false, options...)
 }
 
-func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption) error {
+func (ep *Endpoint) sbLeave(sb *Sandbox, force bool, options ...EndpointOption) error {
 	n, err := ep.getNetworkFromStore()
 	if err != nil {
 		return fmt.Errorf("failed to get network from store during leave: %v", err)
@@ -708,9 +677,9 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption)
 		return fmt.Errorf("failed to get endpoint from store during leave: %v", err)
 	}
 
-	ep.Lock()
+	ep.mu.Lock()
 	sid := ep.sandboxID
-	ep.Unlock()
+	ep.mu.Unlock()
 
 	if sid == "" {
 		return types.ForbiddenErrorf("cannot leave endpoint with no attached sandbox")
@@ -726,10 +695,10 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption)
 		return fmt.Errorf("failed to get driver during endpoint leave: %v", err)
 	}
 
-	ep.Lock()
+	ep.mu.Lock()
 	ep.sandboxID = ""
 	ep.network = n
-	ep.Unlock()
+	ep.mu.Unlock()
 
 	// Current endpoint providing external connectivity to the sandbox
 	extEp := sb.getGatewayEndpoint()
@@ -805,7 +774,8 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption)
 	return nil
 }
 
-func (ep *endpoint) Delete(force bool) error {
+// Delete deletes and detaches this endpoint from the network.
+func (ep *Endpoint) Delete(force bool) error {
 	var err error
 	n, err := ep.getNetworkFromStore()
 	if err != nil {
@@ -817,11 +787,11 @@ func (ep *endpoint) Delete(force bool) error {
 		return fmt.Errorf("failed to get endpoint from store during Delete: %v", err)
 	}
 
-	ep.Lock()
+	ep.mu.Lock()
 	epid := ep.id
 	name := ep.name
 	sbid := ep.sandboxID
-	ep.Unlock()
+	ep.mu.Unlock()
 
 	sb, _ := n.getController().SandboxByID(sbid)
 	if sb != nil && !force {
@@ -829,7 +799,7 @@ func (ep *endpoint) Delete(force bool) error {
 	}
 
 	if sb != nil {
-		if e := ep.sbLeave(sb.(*sandbox), force); e != nil {
+		if e := ep.sbLeave(sb, force); e != nil {
 			logrus.Warnf("failed to leave sandbox for endpoint %s : %v", name, e)
 		}
 	}
@@ -863,12 +833,12 @@ func (ep *endpoint) Delete(force bool) error {
 	return nil
 }
 
-func (ep *endpoint) deleteEndpoint(force bool) error {
-	ep.Lock()
+func (ep *Endpoint) deleteEndpoint(force bool) error {
+	ep.mu.Lock()
 	n := ep.network
 	name := ep.name
 	epid := ep.id
-	ep.Unlock()
+	ep.mu.Unlock()
 
 	driver, err := n.driver(!force)
 	if err != nil {
@@ -892,22 +862,22 @@ func (ep *endpoint) deleteEndpoint(force bool) error {
 	return nil
 }
 
-func (ep *endpoint) getSandbox() (*sandbox, bool) {
+func (ep *Endpoint) getSandbox() (*Sandbox, bool) {
 	c := ep.network.getController()
-	ep.Lock()
+	ep.mu.Lock()
 	sid := ep.sandboxID
-	ep.Unlock()
+	ep.mu.Unlock()
 
-	c.Lock()
+	c.mu.Lock()
 	ps, ok := c.sandboxes[sid]
-	c.Unlock()
+	c.mu.Unlock()
 
 	return ps, ok
 }
 
-func (ep *endpoint) getFirstInterfaceIPv4Address() net.IP {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) getFirstInterfaceIPv4Address() net.IP {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	if ep.iface.addr != nil {
 		return ep.iface.addr.IP
@@ -916,9 +886,9 @@ func (ep *endpoint) getFirstInterfaceIPv4Address() net.IP {
 	return nil
 }
 
-func (ep *endpoint) getFirstInterfaceIPv6Address() net.IP {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) getFirstInterfaceIPv6Address() net.IP {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	if ep.iface.addrv6 != nil {
 		return ep.iface.addrv6.IP
@@ -930,7 +900,7 @@ func (ep *endpoint) getFirstInterfaceIPv6Address() net.IP {
 // EndpointOptionGeneric function returns an option setter for a Generic option defined
 // in a Dictionary of Key-Value pair
 func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		for k, v := range generic {
 			ep.generic[k] = v
 		}
@@ -944,7 +914,7 @@ var (
 
 // CreateOptionIpam function returns an option setter for the ipam configuration for this endpoint
 func CreateOptionIpam(ipV4, ipV6 net.IP, llIPs []net.IP, ipamOptions map[string]string) EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		ep.prefAddress = ipV4
 		ep.prefAddressV6 = ipV6
 		if len(llIPs) != 0 {
@@ -963,7 +933,7 @@ func CreateOptionIpam(ipV4, ipV6 net.IP, llIPs []net.IP, ipamOptions map[string]
 // CreateOptionExposedPorts function returns an option setter for the container exposed
 // ports option to be passed to network.CreateEndpoint() method.
 func CreateOptionExposedPorts(exposedPorts []types.TransportPort) EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		// Defensive copy
 		eps := make([]types.TransportPort, len(exposedPorts))
 		copy(eps, exposedPorts)
@@ -976,7 +946,7 @@ func CreateOptionExposedPorts(exposedPorts []types.TransportPort) EndpointOption
 // CreateOptionPortMapping function returns an option setter for the mapping
 // ports option to be passed to network.CreateEndpoint() method.
 func CreateOptionPortMapping(portBindings []types.PortBinding) EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		// Store a copy of the bindings as generic data to pass to the driver
 		pbs := make([]types.PortBinding, len(portBindings))
 		copy(pbs, portBindings)
@@ -987,7 +957,7 @@ func CreateOptionPortMapping(portBindings []types.PortBinding) EndpointOption {
 // CreateOptionDNS function returns an option setter for dns entry option to
 // be passed to container Create method.
 func CreateOptionDNS(dns []string) EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		ep.generic[netlabel.DNSServers] = dns
 	}
 }
@@ -995,7 +965,7 @@ func CreateOptionDNS(dns []string) EndpointOption {
 // CreateOptionAnonymous function returns an option setter for setting
 // this endpoint as anonymous
 func CreateOptionAnonymous() EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		ep.anonymous = true
 	}
 }
@@ -1003,14 +973,14 @@ func CreateOptionAnonymous() EndpointOption {
 // CreateOptionDisableResolution function returns an option setter to indicate
 // this endpoint doesn't want embedded DNS server functionality
 func CreateOptionDisableResolution() EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		ep.disableResolution = true
 	}
 }
 
 // CreateOptionAlias function returns an option setter for setting endpoint alias
 func CreateOptionAlias(name string, alias string) EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		if ep.aliases == nil {
 			ep.aliases = make(map[string]string)
 		}
@@ -1020,7 +990,7 @@ func CreateOptionAlias(name string, alias string) EndpointOption {
 
 // CreateOptionService function returns an option setter for setting service binding configuration
 func CreateOptionService(name, id string, vip net.IP, ingressPorts []*PortConfig, aliases []string) EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		ep.svcName = name
 		ep.svcID = id
 		ep.virtualIP = vip
@@ -1031,14 +1001,14 @@ func CreateOptionService(name, id string, vip net.IP, ingressPorts []*PortConfig
 
 // CreateOptionMyAlias function returns an option setter for setting endpoint's self alias
 func CreateOptionMyAlias(alias string) EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		ep.myAliases = append(ep.myAliases, alias)
 	}
 }
 
 // CreateOptionLoadBalancer function returns an option setter for denoting the endpoint is a load balancer for a network
 func CreateOptionLoadBalancer() EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		ep.loadBalancer = true
 	}
 }
@@ -1046,12 +1016,12 @@ func CreateOptionLoadBalancer() EndpointOption {
 // JoinOptionPriority function returns an option setter for priority option to
 // be passed to the endpoint.Join() method.
 func JoinOptionPriority(prio int) EndpointOption {
-	return func(ep *endpoint) {
+	return func(ep *Endpoint) {
 		// ep lock already acquired
 		c := ep.network.getController()
-		c.Lock()
+		c.mu.Lock()
 		sb, ok := c.sandboxes[ep.sandboxID]
-		c.Unlock()
+		c.mu.Unlock()
 		if !ok {
 			logrus.Errorf("Could not set endpoint priority value during Join to endpoint %s: No sandbox id present in endpoint", ep.id)
 			return
@@ -1060,11 +1030,11 @@ func JoinOptionPriority(prio int) EndpointOption {
 	}
 }
 
-func (ep *endpoint) DataScope() string {
+func (ep *Endpoint) DataScope() string {
 	return ep.getNetwork().DataScope()
 }
 
-func (ep *endpoint) assignAddress(ipam ipamapi.Ipam, assignIPv4, assignIPv6 bool) error {
+func (ep *Endpoint) assignAddress(ipam ipamapi.Ipam, assignIPv4, assignIPv6 bool) error {
 	var err error
 
 	n := ep.getNetwork()
@@ -1087,7 +1057,7 @@ func (ep *endpoint) assignAddress(ipam ipamapi.Ipam, assignIPv4, assignIPv6 bool
 	return err
 }
 
-func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
+func (ep *Endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
 	var (
 		poolID  *string
 		address **net.IPNet
@@ -1130,10 +1100,10 @@ func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
 		}
 		addr, _, err := ipam.RequestAddress(d.PoolID, progAdd, ep.ipamOptions)
 		if err == nil {
-			ep.Lock()
+			ep.mu.Lock()
 			*address = addr
 			*poolID = d.PoolID
-			ep.Unlock()
+			ep.mu.Unlock()
 			return nil
 		}
 		if err != ipamapi.ErrNoAvailableIPs || progAdd != nil {
@@ -1146,7 +1116,7 @@ func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
 	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() {
 	n := ep.getNetwork()
 	if n.hasSpecialDriver() {
 		return
@@ -1173,7 +1143,7 @@ func (ep *endpoint) releaseAddress() {
 	}
 }
 
-func (c *controller) cleanupLocalEndpoints() {
+func (c *Controller) cleanupLocalEndpoints() {
 	// Get used endpoints
 	eps := make(map[string]interface{})
 	for _, sb := range c.sandboxes {

+ 41 - 40
libnetwork/endpoint_info.go

@@ -30,7 +30,7 @@ type EndpointInfo interface {
 	StaticRoutes() []*types.StaticRoute
 
 	// Sandbox returns the attached sandbox if there, nil otherwise.
-	Sandbox() Sandbox
+	Sandbox() *Sandbox
 
 	// LoadBalancer returns whether the endpoint is the load balancer endpoint for the network.
 	LoadBalancer() bool
@@ -187,7 +187,8 @@ type tableEntry struct {
 	value     []byte
 }
 
-func (ep *endpoint) Info() EndpointInfo {
+// Info returns certain operational data belonging to this endpoint.
+func (ep *Endpoint) Info() EndpointInfo {
 	if ep.sandboxID != "" {
 		return ep
 	}
@@ -211,9 +212,9 @@ func (ep *endpoint) Info() EndpointInfo {
 	return sb.getEndpoint(ep.ID())
 }
 
-func (ep *endpoint) Iface() InterfaceInfo {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) Iface() InterfaceInfo {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	if ep.iface != nil {
 		return ep.iface
@@ -222,9 +223,9 @@ func (ep *endpoint) Iface() InterfaceInfo {
 	return nil
 }
 
-func (ep *endpoint) Interface() driverapi.InterfaceInfo {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) Interface() driverapi.InterfaceInfo {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	if ep.iface != nil {
 		return ep.iface
@@ -288,9 +289,9 @@ func (epi *endpointInterface) SetNames(srcName string, dstPrefix string) error {
 	return nil
 }
 
-func (ep *endpoint) InterfaceName() driverapi.InterfaceNameInfo {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) InterfaceName() driverapi.InterfaceNameInfo {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	if ep.iface != nil {
 		return ep.iface
@@ -299,9 +300,9 @@ func (ep *endpoint) InterfaceName() driverapi.InterfaceNameInfo {
 	return nil
 }
 
-func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	r := types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop}
 
@@ -315,9 +316,9 @@ func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHo
 	return nil
 }
 
-func (ep *endpoint) AddTableEntry(tableName, key string, value []byte) error {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) AddTableEntry(tableName, key string, value []byte) error {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	ep.joinInfo.driverTableEntries = append(ep.joinInfo.driverTableEntries, &tableEntry{
 		tableName: tableName,
@@ -328,7 +329,7 @@ func (ep *endpoint) AddTableEntry(tableName, key string, value []byte) error {
 	return nil
 }
 
-func (ep *endpoint) Sandbox() Sandbox {
+func (ep *Endpoint) Sandbox() *Sandbox {
 	cnt, ok := ep.getSandbox()
 	if !ok {
 		return nil
@@ -336,15 +337,15 @@ func (ep *endpoint) Sandbox() Sandbox {
 	return cnt
 }
 
-func (ep *endpoint) LoadBalancer() bool {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) LoadBalancer() bool {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 	return ep.loadBalancer
 }
 
-func (ep *endpoint) StaticRoutes() []*types.StaticRoute {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) StaticRoutes() []*types.StaticRoute {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	if ep.joinInfo == nil {
 		return nil
@@ -353,9 +354,9 @@ func (ep *endpoint) StaticRoutes() []*types.StaticRoute {
 	return ep.joinInfo.StaticRoutes
 }
 
-func (ep *endpoint) Gateway() net.IP {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) Gateway() net.IP {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	if ep.joinInfo == nil {
 		return net.IP{}
@@ -364,9 +365,9 @@ func (ep *endpoint) Gateway() net.IP {
 	return types.GetIPCopy(ep.joinInfo.gw)
 }
 
-func (ep *endpoint) GatewayIPv6() net.IP {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) GatewayIPv6() net.IP {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	if ep.joinInfo == nil {
 		return net.IP{}
@@ -375,23 +376,23 @@ func (ep *endpoint) GatewayIPv6() net.IP {
 	return types.GetIPCopy(ep.joinInfo.gw6)
 }
 
-func (ep *endpoint) SetGateway(gw net.IP) error {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) SetGateway(gw net.IP) error {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	ep.joinInfo.gw = types.GetIPCopy(gw)
 	return nil
 }
 
-func (ep *endpoint) SetGatewayIPv6(gw6 net.IP) error {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) SetGatewayIPv6(gw6 net.IP) error {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	ep.joinInfo.gw6 = types.GetIPCopy(gw6)
 	return nil
 }
 
-func (ep *endpoint) retrieveFromStore() (*endpoint, error) {
+func (ep *Endpoint) retrieveFromStore() (*Endpoint, error) {
 	n, err := ep.getNetworkFromStore()
 	if err != nil {
 		return nil, fmt.Errorf("could not find network in store to get latest endpoint %s: %v", ep.Name(), err)
@@ -399,9 +400,9 @@ func (ep *endpoint) retrieveFromStore() (*endpoint, error) {
 	return n.getEndpointFromStore(ep.ID())
 }
 
-func (ep *endpoint) DisableGatewayService() {
-	ep.Lock()
-	defer ep.Unlock()
+func (ep *Endpoint) DisableGatewayService() {
+	ep.mu.Lock()
+	defer ep.mu.Unlock()
 
 	ep.joinInfo.disableGatewayService = true
 }

+ 2 - 1
libnetwork/endpoint_info_unix.go

@@ -5,7 +5,8 @@ package libnetwork
 
 import "fmt"
 
-func (ep *endpoint) DriverInfo() (map[string]interface{}, error) {
+// DriverInfo returns a collection of driver operational data related to this endpoint retrieved from the driver.
+func (ep *Endpoint) DriverInfo() (map[string]interface{}, error) {
 	ep, err := ep.retrieveFromStore()
 	if err != nil {
 		return nil, err

+ 2 - 1
libnetwork/endpoint_info_windows.go

@@ -5,7 +5,8 @@ package libnetwork
 
 import "fmt"
 
-func (ep *endpoint) DriverInfo() (map[string]interface{}, error) {
+// DriverInfo returns a collection of driver operational data related to this endpoint retrieved from the driver.
+func (ep *Endpoint) DriverInfo() (map[string]interface{}, error) {
 	ep, err := ep.retrieveFromStore()
 	if err != nil {
 		return nil, err

+ 1 - 2
libnetwork/endpoint_test.go

@@ -30,8 +30,7 @@ fe90::2	somehost.example.com somehost
 		[]*IpamConf{{PreferredPool: "fe90::/64", Gateway: "fe90::1"}},
 		nil)}
 
-	c, nws := getTestEnv(t, opts)
-	ctrlr := c.(*controller)
+	ctrlr, nws := getTestEnv(t, opts)
 
 	hostsFile, err := os.CreateTemp("", "")
 	if err != nil {

+ 2 - 2
libnetwork/firewall_linux.go

@@ -7,9 +7,9 @@ import (
 
 const userChain = "DOCKER-USER"
 
-var ctrl *controller
+var ctrl *Controller
 
-func setupArrangeUserFilterRule(c *controller) {
+func setupArrangeUserFilterRule(c *Controller) {
 	ctrl = c
 	iptables.OnReloaded(arrangeUserFilterRule)
 }

+ 2 - 3
libnetwork/firewall_linux_test.go

@@ -51,10 +51,9 @@ func TestUserChain(t *testing.T) {
 			defer testutils.SetupTestOSContext(t)()
 			defer resetIptables(t)
 
-			nc, err := New()
+			c, err := New()
 			assert.NilError(t, err)
-			defer nc.Stop()
-			c := nc.(*controller)
+			defer c.Stop()
 			c.cfg.DriverCfg["bridge"] = map[string]interface{}{
 				netlabel.GenericData: options.Generic{
 					"EnableIPTables": tc.iptables,

+ 1 - 1
libnetwork/firewall_others.go

@@ -3,5 +3,5 @@
 
 package libnetwork
 
-func setupArrangeUserFilterRule(c *controller) {}
+func setupArrangeUserFilterRule(c *Controller) {}
 func arrangeUserFilterRule()                   {}

+ 5 - 7
libnetwork/libnetwork_internal_test.go

@@ -188,7 +188,7 @@ func TestEndpointMarshalling(t *testing.T) {
 		lla = append(lla, ll)
 	}
 
-	e := &endpoint{
+	e := &Endpoint{
 		name:      "Bau",
 		id:        "efghijklmno",
 		sandboxID: "ambarabaciccicocco",
@@ -213,7 +213,7 @@ func TestEndpointMarshalling(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	ee := &endpoint{}
+	ee := &Endpoint{}
 	err = json.Unmarshal(b, ee)
 	if err != nil {
 		t.Fatal(err)
@@ -320,7 +320,7 @@ func TestAuxAddresses(t *testing.T) {
 	}
 	defer c.Stop()
 
-	n := &network{ipamType: ipamapi.DefaultIPAM, networkType: "bridge", ctrlr: c.(*controller)}
+	n := &network{ipamType: ipamapi.DefaultIPAM, networkType: "bridge", ctrlr: c}
 
 	input := []struct {
 		masterPool   string
@@ -421,7 +421,7 @@ func TestSRVServiceQuery(t *testing.T) {
 	sr.service["web.swarm"] = append(sr.service["web.swarm"], httpPort)
 	sr.service["web.swarm"] = append(sr.service["web.swarm"], extHTTPPort)
 
-	c.(*controller).svcRecords[n.ID()] = sr
+	c.svcRecords[n.ID()] = sr
 
 	_, ip := ep.Info().Sandbox().ResolveService("_http._tcp.web.swarm")
 
@@ -576,9 +576,7 @@ func TestIpamReleaseOnNetDriverFailures(t *testing.T) {
 	}
 	defer c.Stop()
 
-	cc := c.(*controller)
-
-	if err := cc.drvRegistry.AddDriver(badDriverName, badDriverInit, nil); err != nil {
+	if err := c.drvRegistry.AddDriver(badDriverName, badDriverInit, nil); err != nil {
 		t.Fatal(err)
 	}
 

+ 6 - 6
libnetwork/libnetwork_linux_test.go

@@ -30,7 +30,7 @@ const (
 	bridgeNetType = "bridge"
 )
 
-func makeTesthostNetwork(t *testing.T, c libnetwork.NetworkController) libnetwork.Network {
+func makeTesthostNetwork(t *testing.T, c *libnetwork.Controller) libnetwork.Network {
 	t.Helper()
 	n, err := createTestNetwork(c, "host", "testhost", options.Generic{}, nil, nil)
 	if err != nil {
@@ -282,7 +282,7 @@ func TestEndpointJoin(t *testing.T) {
 		t.Fatalf("Unexpected error type returned: %T", err)
 	}
 
-	fsbx := &fakeSandbox{}
+	fsbx := &libnetwork.Sandbox{}
 	if err = ep1.Join(fsbx); err == nil {
 		t.Fatalf("Expected to fail join with invalid Sandbox")
 	}
@@ -845,15 +845,15 @@ func TestResolvConf(t *testing.T) {
 
 type parallelTester struct {
 	osctx      *testutils.OSContext
-	controller libnetwork.NetworkController
+	controller *libnetwork.Controller
 	net1, net2 libnetwork.Network
 	iterCnt    int
 }
 
 func (pt parallelTester) Do(t *testing.T, thrNumber int) error {
 	var (
-		ep  libnetwork.Endpoint
-		sb  libnetwork.Sandbox
+		ep  *libnetwork.Endpoint
+		sb  *libnetwork.Sandbox
 		err error
 	)
 
@@ -944,7 +944,7 @@ func TestParallel(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	sboxes := make([]libnetwork.Sandbox, numThreads)
+	sboxes := make([]*libnetwork.Sandbox, numThreads)
 	if sboxes[first-1], err = controller.NewSandbox(fmt.Sprintf("%drace", first), libnetwork.OptionUseDefaultSandbox()); err != nil {
 		t.Fatal(err)
 	}

+ 5 - 68
libnetwork/libnetwork_test.go

@@ -6,7 +6,6 @@ package libnetwork_test
 import (
 	"errors"
 	"fmt"
-	"net"
 	"net/http"
 	"net/http/httptest"
 	"os"
@@ -43,7 +42,7 @@ func TestMain(m *testing.M) {
 	os.Exit(m.Run())
 }
 
-func newController(t *testing.T) libnetwork.NetworkController {
+func newController(t *testing.T) *libnetwork.Controller {
 	t.Helper()
 	genericOption := map[string]interface{}{
 		netlabel.GenericData: options.Generic{
@@ -62,7 +61,7 @@ func newController(t *testing.T) libnetwork.NetworkController {
 	return c
 }
 
-func createTestNetwork(c libnetwork.NetworkController, networkType, networkName string, netOption options.Generic, ipamV4Configs, ipamV6Configs []*libnetwork.IpamConf) (libnetwork.Network, error) {
+func createTestNetwork(c *libnetwork.Controller, networkType, networkName string, netOption options.Generic, ipamV4Configs, ipamV6Configs []*libnetwork.IpamConf) (libnetwork.Network, error) {
 	return c.NewNetwork(networkType, networkName, "",
 		libnetwork.NetworkOptionGeneric(netOption),
 		libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4Configs, ipamV6Configs, nil))
@@ -521,8 +520,8 @@ func TestNetworkEndpointsWalkers(t *testing.T) {
 
 	// Test Endpoint Walk method
 	var epName string
-	var epWanted libnetwork.Endpoint
-	wlk := func(ep libnetwork.Endpoint) bool {
+	var epWanted *libnetwork.Endpoint
+	wlk := func(ep *libnetwork.Endpoint) bool {
 		if ep.Name() == epName {
 			epWanted = ep
 			return true
@@ -830,68 +829,6 @@ func TestNetworkQuery(t *testing.T) {
 
 const containerID = "valid_c"
 
-type fakeSandbox struct{}
-
-func (f *fakeSandbox) ID() string {
-	return "fake sandbox"
-}
-
-func (f *fakeSandbox) ContainerID() string {
-	return ""
-}
-
-func (f *fakeSandbox) Key() string {
-	return "fake key"
-}
-
-func (f *fakeSandbox) Labels() map[string]interface{} {
-	return nil
-}
-
-func (f *fakeSandbox) Statistics() (map[string]*types.InterfaceStatistics, error) {
-	return nil, nil
-}
-
-func (f *fakeSandbox) Refresh(opts ...libnetwork.SandboxOption) error {
-	return nil
-}
-
-func (f *fakeSandbox) Delete() error {
-	return nil
-}
-
-func (f *fakeSandbox) Rename(name string) error {
-	return nil
-}
-
-func (f *fakeSandbox) SetKey(key string) error {
-	return nil
-}
-
-func (f *fakeSandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
-	return nil, false
-}
-
-func (f *fakeSandbox) ResolveIP(ip string) string {
-	return ""
-}
-
-func (f *fakeSandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
-	return nil, nil
-}
-
-func (f *fakeSandbox) Endpoints() []libnetwork.Endpoint {
-	return nil
-}
-
-func (f *fakeSandbox) EnableService() error {
-	return nil
-}
-
-func (f *fakeSandbox) DisableService() error {
-	return nil
-}
-
 func TestEndpointDeleteWithActiveContainer(t *testing.T) {
 	defer testutils.SetupTestOSContext(t)()
 	controller := newController(t)
@@ -1159,7 +1096,7 @@ func TestContainerInvalidLeave(t *testing.T) {
 		t.Fatalf("Unexpected error type returned: %T. Desc: %s", err, err.Error())
 	}
 
-	fsbx := &fakeSandbox{}
+	fsbx := &libnetwork.Sandbox{}
 	if err = ep.Leave(fsbx); err == nil {
 		t.Fatalf("Expected to fail leave with invalid Sandbox")
 	}

+ 103 - 110
libnetwork/network.go

@@ -38,22 +38,22 @@ type Network interface {
 
 	// CreateEndpoint creates a new endpoint to this network symbolically identified by the
 	// specified unique name. The options parameter carries driver specific options.
-	CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error)
+	CreateEndpoint(name string, options ...EndpointOption) (*Endpoint, error)
 
 	// Delete the network.
 	Delete(options ...NetworkDeleteOption) error
 
 	// Endpoints returns the list of Endpoint(s) in this network.
-	Endpoints() []Endpoint
+	Endpoints() []*Endpoint
 
 	// WalkEndpoints uses the provided function to walk the Endpoints.
 	WalkEndpoints(walker EndpointWalker)
 
 	// EndpointByName returns the Endpoint which has the passed name. If not found, the error ErrNoSuchEndpoint is returned.
-	EndpointByName(name string) (Endpoint, error)
+	EndpointByName(name string) (*Endpoint, error)
 
 	// EndpointByID returns the Endpoint which has the passed id. If not found, the error ErrNoSuchEndpoint is returned.
-	EndpointByID(id string) (Endpoint, error)
+	EndpointByID(id string) (*Endpoint, error)
 
 	// Info returns certain operational data belonging to this network.
 	Info() NetworkInfo
@@ -86,7 +86,7 @@ type NetworkInfo interface {
 
 // EndpointWalker is a client provided function which will be used to walk the Endpoints.
 // When the function returns true, the walk will stop.
-type EndpointWalker func(ep Endpoint) bool
+type EndpointWalker func(ep *Endpoint) bool
 
 // ipInfo is the reverse mapping from IP to service name to serve the PTR query.
 // extResolver is set if an external server resolves a service name to this IP.
@@ -200,7 +200,7 @@ func (i *IpamInfo) UnmarshalJSON(data []byte) error {
 }
 
 type network struct {
-	ctrlr            *controller
+	ctrlr            *Controller
 	name             string
 	networkType      string
 	id               string
@@ -234,7 +234,7 @@ type network struct {
 	configFrom       string
 	loadBalancerIP   net.IP
 	loadBalancerMode string
-	sync.Mutex
+	mu               sync.Mutex
 }
 
 const (
@@ -244,36 +244,36 @@ const (
 )
 
 func (n *network) Name() string {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.name
 }
 
 func (n *network) ID() string {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.id
 }
 
 func (n *network) Created() time.Time {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.created
 }
 
 func (n *network) Type() string {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.networkType
 }
 
 func (n *network) Key() []string {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	return []string{datastore.NetworkKeyPrefix, n.id}
 }
 
@@ -282,8 +282,8 @@ func (n *network) KeyPrefix() []string {
 }
 
 func (n *network) Value() []byte {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	b, err := json.Marshal(n)
 	if err != nil {
 		return nil
@@ -296,33 +296,33 @@ func (n *network) SetValue(value []byte) error {
 }
 
 func (n *network) Index() uint64 {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	return n.dbIndex
 }
 
 func (n *network) SetIndex(index uint64) {
-	n.Lock()
+	n.mu.Lock()
 	n.dbIndex = index
 	n.dbExists = true
-	n.Unlock()
+	n.mu.Unlock()
 }
 
 func (n *network) Exists() bool {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	return n.dbExists
 }
 
 func (n *network) Skip() bool {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	return !n.persist
 }
 
 func (n *network) New() datastore.KVObject {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return &network{
 		ctrlr:   n.ctrlr,
@@ -456,8 +456,8 @@ func (n *network) applyConfigurationTo(to *network) error {
 }
 
 func (n *network) CopyTo(o datastore.KVObject) error {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	dstN := o.(*network)
 	dstN.name = n.name
@@ -547,8 +547,8 @@ func (n *network) DataScope() string {
 }
 
 func (n *network) getEpCnt() *endpointCnt {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.epCnt
 }
@@ -955,7 +955,7 @@ func (n *network) driver(load bool) (driverapi.Driver, error) {
 		return nil, err
 	}
 
-	n.Lock()
+	n.mu.Lock()
 	// If load is not required, driver, cap and err may all be nil
 	if n.scope == "" && cap != nil {
 		n.scope = cap.DataScope
@@ -965,7 +965,7 @@ func (n *network) driver(load bool) (driverapi.Driver, error) {
 		// scoped regardless of the backing driver.
 		n.scope = datastore.SwarmScope
 	}
-	n.Unlock()
+	n.mu.Unlock()
 	return d, nil
 }
 
@@ -986,11 +986,11 @@ func (n *network) Delete(options ...NetworkDeleteOption) error {
 //   - controller.networkCleanup() -- (true, true)
 //     remove the network no matter what
 func (n *network) delete(force bool, rmLBEndpoint bool) error {
-	n.Lock()
+	n.mu.Lock()
 	c := n.ctrlr
 	name := n.name
 	id := n.id
-	n.Unlock()
+	n.mu.Unlock()
 
 	c.networkLocker.Lock(id)
 	defer c.networkLocker.Unlock(id) //nolint:errcheck
@@ -1135,7 +1135,7 @@ func (n *network) deleteNetwork() error {
 	return nil
 }
 
-func (n *network) addEndpoint(ep *endpoint) error {
+func (n *network) addEndpoint(ep *Endpoint) error {
 	d, err := n.driver(true)
 	if err != nil {
 		return fmt.Errorf("failed to add endpoint: %v", err)
@@ -1150,7 +1150,7 @@ func (n *network) addEndpoint(ep *endpoint) error {
 	return nil
 }
 
-func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
+func (n *network) CreateEndpoint(name string, options ...EndpointOption) (*Endpoint, error) {
 	var err error
 	if !config.IsValidName(name) {
 		return nil, ErrInvalidName(name)
@@ -1170,10 +1170,10 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi
 	return n.createEndpoint(name, options...)
 }
 
-func (n *network) createEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
+func (n *network) createEndpoint(name string, options ...EndpointOption) (*Endpoint, error) {
 	var err error
 
-	ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}}
+	ep := &Endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}}
 	ep.id = stringid.GenerateRandomID()
 
 	// Initialize ep.network with a possibly stale copy of n. We need this to get network from
@@ -1268,19 +1268,12 @@ func (n *network) createEndpoint(name string, options ...EndpointOption) (Endpoi
 	return ep, nil
 }
 
-func (n *network) Endpoints() []Endpoint {
-	var list []Endpoint
-
+func (n *network) Endpoints() []*Endpoint {
 	endpoints, err := n.getEndpointsFromStore()
 	if err != nil {
 		logrus.Error(err)
 	}
-
-	for _, ep := range endpoints {
-		list = append(list, ep)
-	}
-
-	return list
+	return endpoints
 }
 
 func (n *network) WalkEndpoints(walker EndpointWalker) {
@@ -1291,13 +1284,13 @@ func (n *network) WalkEndpoints(walker EndpointWalker) {
 	}
 }
 
-func (n *network) EndpointByName(name string) (Endpoint, error) {
+func (n *network) EndpointByName(name string) (*Endpoint, error) {
 	if name == "" {
 		return nil, ErrInvalidName(name)
 	}
-	var e Endpoint
+	var e *Endpoint
 
-	s := func(current Endpoint) bool {
+	s := func(current *Endpoint) bool {
 		if current.Name() == name {
 			e = current
 			return true
@@ -1314,7 +1307,7 @@ func (n *network) EndpointByName(name string) (Endpoint, error) {
 	return e, nil
 }
 
-func (n *network) EndpointByID(id string) (Endpoint, error) {
+func (n *network) EndpointByID(id string) (*Endpoint, error) {
 	if id == "" {
 		return nil, ErrInvalidID(id)
 	}
@@ -1327,7 +1320,7 @@ func (n *network) EndpointByID(id string) (Endpoint, error) {
 	return ep, nil
 }
 
-func (n *network) updateSvcRecord(ep *endpoint, localEps []*endpoint, isAdd bool) {
+func (n *network) updateSvcRecord(ep *Endpoint, localEps []*Endpoint, isAdd bool) {
 	var ipv6 net.IP
 	epName := ep.Name()
 	if iface := ep.Iface(); iface != nil && iface.Address() != nil {
@@ -1413,8 +1406,8 @@ func (n *network) addSvcRecords(eID, name, serviceID string, epIP, epIPv6 net.IP
 	logrus.Debugf("%s (%.7s).addSvcRecords(%s, %s, %s, %t) %s sid:%s", eID, networkID, name, epIP, epIPv6, ipMapUpdate, method, serviceID)
 
 	c := n.getController()
-	c.Lock()
-	defer c.Unlock()
+	c.mu.Lock()
+	defer c.mu.Unlock()
 
 	sr, ok := c.svcRecords[networkID]
 	if !ok {
@@ -1449,8 +1442,8 @@ func (n *network) deleteSvcRecords(eID, name, serviceID string, epIP net.IP, epI
 	logrus.Debugf("%s (%.7s).deleteSvcRecords(%s, %s, %s, %t) %s sid:%s ", eID, networkID, name, epIP, epIPv6, ipMapUpdate, method, serviceID)
 
 	c := n.getController()
-	c.Lock()
-	defer c.Unlock()
+	c.mu.Lock()
+	defer c.mu.Unlock()
 
 	sr, ok := c.svcRecords[networkID]
 	if !ok {
@@ -1472,9 +1465,9 @@ func (n *network) deleteSvcRecords(eID, name, serviceID string, epIP net.IP, epI
 	}
 }
 
-func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record {
-	n.Lock()
-	defer n.Unlock()
+func (n *network) getSvcRecords(ep *Endpoint) []etchosts.Record {
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	if ep == nil {
 		return nil
@@ -1484,8 +1477,8 @@ func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record {
 
 	epName := ep.Name()
 
-	n.ctrlr.Lock()
-	defer n.ctrlr.Unlock()
+	n.ctrlr.mu.Lock()
+	defer n.ctrlr.mu.Unlock()
 	sr, ok := n.ctrlr.svcRecords[n.id]
 	if !ok || sr.svcMap == nil {
 		return nil
@@ -1517,9 +1510,9 @@ func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record {
 	return recs
 }
 
-func (n *network) getController() *controller {
-	n.Lock()
-	defer n.Unlock()
+func (n *network) getController() *Controller {
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	return n.ctrlr
 }
 
@@ -1753,9 +1746,9 @@ func (n *network) getIPInfo(ipVer int) []*IpamInfo {
 		return nil
 	}
 	l := make([]*IpamInfo, 0, len(info))
-	n.Lock()
+	n.mu.Lock()
 	l = append(l, info...)
-	n.Unlock()
+	n.mu.Unlock()
 	return l
 }
 
@@ -1770,11 +1763,11 @@ func (n *network) getIPData(ipVer int) []driverapi.IPAMData {
 		return nil
 	}
 	l := make([]driverapi.IPAMData, 0, len(info))
-	n.Lock()
+	n.mu.Lock()
 	for _, d := range info {
 		l = append(l, d.IPAMData)
 	}
-	n.Unlock()
+	n.mu.Unlock()
 	return l
 }
 
@@ -1807,8 +1800,8 @@ func (n *network) Peers() []networkdb.PeerInfo {
 }
 
 func (n *network) DriverOptions() map[string]string {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	if n.generic != nil {
 		if m, ok := n.generic[netlabel.GenericData]; ok {
 			return m.(map[string]string)
@@ -1818,14 +1811,14 @@ func (n *network) DriverOptions() map[string]string {
 }
 
 func (n *network) Scope() string {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	return n.scope
 }
 
 func (n *network) IpamConfig() (string, map[string]string, []*IpamConf, []*IpamConf) {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	v4L := make([]*IpamConf, len(n.ipamV4Config))
 	v6L := make([]*IpamConf, len(n.ipamV6Config))
@@ -1850,8 +1843,8 @@ func (n *network) IpamConfig() (string, map[string]string, []*IpamConf, []*IpamC
 }
 
 func (n *network) IpamInfo() ([]*IpamInfo, []*IpamInfo) {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	v4Info := make([]*IpamInfo, len(n.ipamV4Info))
 	v6Info := make([]*IpamInfo, len(n.ipamV6Info))
@@ -1876,57 +1869,57 @@ func (n *network) IpamInfo() ([]*IpamInfo, []*IpamInfo) {
 }
 
 func (n *network) Internal() bool {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.internal
 }
 
 func (n *network) Attachable() bool {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.attachable
 }
 
 func (n *network) Ingress() bool {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.ingress
 }
 
 func (n *network) Dynamic() bool {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.dynamic
 }
 
 func (n *network) IPv6Enabled() bool {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.enableIPv6
 }
 
 func (n *network) ConfigFrom() string {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.configFrom
 }
 
 func (n *network) ConfigOnly() bool {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	return n.configOnly
 }
 
 func (n *network) Labels() map[string]string {
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 
 	var lbls = make(map[string]string, len(n.labels))
 	for k, v := range n.labels {
@@ -1945,8 +1938,8 @@ func (n *network) TableEventRegister(tableName string, objType driverapi.ObjectT
 		name:    tableName,
 		objType: objType,
 	}
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	n.driverTables = append(n.driverTables, t)
 	return nil
 }
@@ -1961,8 +1954,8 @@ func (n *network) UpdateIpamConfig(ipV4Data []driverapi.IPAMData) {
 		ipamV4Config[i] = ic
 	}
 
-	n.Lock()
-	defer n.Unlock()
+	n.mu.Lock()
+	defer n.mu.Unlock()
 	n.ipamV4Config = ipamV4Config
 }
 
@@ -1980,8 +1973,8 @@ func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) {
 
 	c := n.getController()
 	networkID := n.ID()
-	c.Lock()
-	defer c.Unlock()
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	sr, ok := c.svcRecords[networkID]
 
 	if !ok {
@@ -2022,8 +2015,8 @@ func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) {
 func (n *network) HandleQueryResp(name string, ip net.IP) {
 	networkID := n.ID()
 	c := n.getController()
-	c.Lock()
-	defer c.Unlock()
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	sr, ok := c.svcRecords[networkID]
 
 	if !ok {
@@ -2042,8 +2035,8 @@ func (n *network) HandleQueryResp(name string, ip net.IP) {
 func (n *network) ResolveIP(ip string) string {
 	networkID := n.ID()
 	c := n.getController()
-	c.Lock()
-	defer c.Unlock()
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	sr, ok := c.svcRecords[networkID]
 
 	if !ok {
@@ -2096,8 +2089,8 @@ func (n *network) ResolveService(name string) ([]*net.SRV, []net.IP) {
 	svcName := strings.Join(parts[2:], ".")
 
 	networkID := n.ID()
-	c.Lock()
-	defer c.Unlock()
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	sr, ok := c.svcRecords[networkID]
 
 	if !ok {
@@ -2139,7 +2132,7 @@ func (n *network) NdotsSet() bool {
 }
 
 // config-only network is looked up by name
-func (c *controller) getConfigNetwork(name string) (*network, error) {
+func (c *Controller) getConfigNetwork(name string) (*network, error) {
 	var n Network
 
 	s := func(current Network) bool {
@@ -2219,10 +2212,10 @@ func (n *network) createLoadBalancerSandbox() (retErr error) {
 }
 
 func (n *network) deleteLoadBalancerSandbox() error {
-	n.Lock()
+	n.mu.Lock()
 	c := n.ctrlr
 	name := n.name
-	n.Unlock()
+	n.mu.Unlock()
 
 	sandboxName := n.lbSandboxName()
 	endpointName := n.lbEndpointName()

+ 2 - 2
libnetwork/resolver_test.go

@@ -122,7 +122,7 @@ func TestDNSIPQuery(t *testing.T) {
 
 	w := new(tstwriter)
 	// the unit tests right now will focus on non-proxyed DNS requests
-	r := NewResolver(resolverIPSandbox, false, sb.(*sandbox))
+	r := NewResolver(resolverIPSandbox, false, sb)
 
 	// test name1's IP is resolved correctly with the default A type query
 	// Also make sure DNS lookups are case insensitive
@@ -266,7 +266,7 @@ func TestDNSProxyServFail(t *testing.T) {
 	t.Log("DNS Server can be reached")
 
 	w := new(tstwriter)
-	r := NewResolver(resolverIPSandbox, true, sb.(*sandbox))
+	r := NewResolver(resolverIPSandbox, true, sb)
 	q := new(dns.Msg)
 	q.SetQuestion("name1.", dns.TypeA)
 

+ 162 - 188
libnetwork/sandbox.go

@@ -16,46 +16,12 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-// Sandbox provides the control over the network container entity. It is a one to one mapping with the container.
-type Sandbox interface {
-	// ID returns the ID of the sandbox
-	ID() string
-	// Key returns the sandbox's key
-	Key() string
-	// ContainerID returns the container id associated to this sandbox
-	ContainerID() string
-	// Labels returns the sandbox's labels
-	Labels() map[string]interface{}
-	// Statistics retrieves the interfaces' statistics for the sandbox
-	Statistics() (map[string]*types.InterfaceStatistics, error)
-	// Refresh leaves all the endpoints, resets and re-applies the options,
-	// re-joins all the endpoints without destroying the osl sandbox
-	Refresh(options ...SandboxOption) error
-	// SetKey updates the Sandbox Key
-	SetKey(key string) error
-	// Rename changes the name of all attached Endpoints
-	Rename(name string) error
-	// Delete destroys this container after detaching it from all connected endpoints.
-	Delete() error
-	// Endpoints returns all the endpoints connected to the sandbox
-	Endpoints() []Endpoint
-	// ResolveService returns all the backend details about the containers or hosts
-	// backing a service. Its purpose is to satisfy an SRV query
-	ResolveService(name string) ([]*net.SRV, []net.IP)
-	// EnableService  makes a managed container's service available by adding the
-	// endpoint to the service load balancer and service discovery
-	EnableService() error
-	// DisableService removes a managed container's endpoints from the load balancer
-	// and service discovery
-	DisableService() error
-}
-
 // SandboxOption is an option setter function type used to pass various options to
 // NewNetContainer method. The various setter functions of type SandboxOption are
 // provided by libnetwork, they look like ContainerOptionXXXX(...)
-type SandboxOption func(sb *sandbox)
+type SandboxOption func(sb *Sandbox)
 
-func (sb *sandbox) processOptions(options ...SandboxOption) {
+func (sb *Sandbox) processOptions(options ...SandboxOption) {
 	for _, opt := range options {
 		if opt != nil {
 			opt(sb)
@@ -63,16 +29,18 @@ func (sb *sandbox) processOptions(options ...SandboxOption) {
 	}
 }
 
-type sandbox struct {
+// Sandbox provides the control over the network container entity.
+// It is a one to one mapping with the container.
+type Sandbox struct {
 	id                 string
 	containerID        string
 	config             containerConfig
 	extDNS             []extDNSEntry
 	osSbox             osl.Sandbox
-	controller         *controller
+	controller         *Controller
 	resolver           Resolver
 	resolverOnce       sync.Once
-	endpoints          []*endpoint
+	endpoints          []*Endpoint
 	epPriority         map[string]int
 	populatedEndpoints map[string]struct{}
 	joinLeaveDone      chan struct{}
@@ -84,10 +52,10 @@ type sandbox struct {
 	ndotsSet           bool
 	oslTypes           []osl.SandboxType // slice of properties of this sandbox
 	loadBalancerNID    string            // NID that this SB is a load balancer for
-	sync.Mutex
+	mu                 sync.Mutex
 	// This mutex is used to serialize service related operation for an endpoint
 	// The lock is here because the endpoint is saved into the store so is not unique
-	Service sync.Mutex
+	service sync.Mutex
 }
 
 // These are the container configs used to customize container /etc/hosts file.
@@ -134,24 +102,28 @@ const (
 	resolverIPSandbox = "127.0.0.11"
 )
 
-func (sb *sandbox) ID() string {
+// ID returns the ID of the sandbox.
+func (sb *Sandbox) ID() string {
 	return sb.id
 }
 
-func (sb *sandbox) ContainerID() string {
+// ContainerID returns the container id associated to this sandbox.
+func (sb *Sandbox) ContainerID() string {
 	return sb.containerID
 }
 
-func (sb *sandbox) Key() string {
+// Key returns the sandbox's key.
+func (sb *Sandbox) Key() string {
 	if sb.config.useDefaultSandBox {
 		return osl.GenerateKey("default")
 	}
 	return osl.GenerateKey(sb.id)
 }
 
-func (sb *sandbox) Labels() map[string]interface{} {
-	sb.Lock()
-	defer sb.Unlock()
+// Labels returns the sandbox's labels.
+func (sb *Sandbox) Labels() map[string]interface{} {
+	sb.mu.Lock()
+	defer sb.mu.Unlock()
 	opts := make(map[string]interface{}, len(sb.config.generic))
 	for k, v := range sb.config.generic {
 		opts[k] = v
@@ -159,12 +131,13 @@ func (sb *sandbox) Labels() map[string]interface{} {
 	return opts
 }
 
-func (sb *sandbox) Statistics() (map[string]*types.InterfaceStatistics, error) {
+// Statistics retrieves the interfaces' statistics for the sandbox.
+func (sb *Sandbox) Statistics() (map[string]*types.InterfaceStatistics, error) {
 	m := make(map[string]*types.InterfaceStatistics)
 
-	sb.Lock()
+	sb.mu.Lock()
 	osb := sb.osSbox
-	sb.Unlock()
+	sb.mu.Unlock()
 	if osb == nil {
 		return m, nil
 	}
@@ -179,14 +152,15 @@ func (sb *sandbox) Statistics() (map[string]*types.InterfaceStatistics, error) {
 	return m, nil
 }
 
-func (sb *sandbox) Delete() error {
+// Delete destroys this container after detaching it from all connected endpoints.
+func (sb *Sandbox) Delete() error {
 	return sb.delete(false)
 }
 
-func (sb *sandbox) delete(force bool) error {
-	sb.Lock()
+func (sb *Sandbox) delete(force bool) error {
+	sb.mu.Lock()
 	if sb.inDelete {
-		sb.Unlock()
+		sb.mu.Unlock()
 		return types.ForbiddenErrorf("another sandbox delete in progress")
 	}
 	// Set the inDelete flag. This will ensure that we don't
@@ -198,13 +172,13 @@ func (sb *sandbox) delete(force bool) error {
 	// will have all the references to the endpoints in the
 	// sandbox so that we can clean them up when we restart
 	sb.inDelete = true
-	sb.Unlock()
+	sb.mu.Unlock()
 
 	c := sb.controller
 
 	// Detach from all endpoints
 	retain := false
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		// gw network endpoint detach and removal are automatic
 		if ep.endpointInGWNetwork() && !force {
 			continue
@@ -230,9 +204,9 @@ func (sb *sandbox) delete(force bool) error {
 	}
 
 	if retain {
-		sb.Lock()
+		sb.mu.Lock()
 		sb.inDelete = false
-		sb.Unlock()
+		sb.mu.Unlock()
 		return fmt.Errorf("could not cleanup all the endpoints in container %s / sandbox %s", sb.containerID, sb.id)
 	}
 	// Container is going away. Path cache in etchosts is most
@@ -253,20 +227,21 @@ func (sb *sandbox) delete(force bool) error {
 		logrus.Warnf("Failed to delete sandbox %s from store: %v", sb.ID(), err)
 	}
 
-	c.Lock()
+	c.mu.Lock()
 	if sb.ingress {
 		c.ingressSandbox = nil
 	}
 	delete(c.sandboxes, sb.ID())
-	c.Unlock()
+	c.mu.Unlock()
 
 	return nil
 }
 
-func (sb *sandbox) Rename(name string) error {
+// Rename changes the name of all attached Endpoints.
+func (sb *Sandbox) Rename(name string) error {
 	var err error
 
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		if ep.endpointInGWNetwork() {
 			continue
 		}
@@ -289,9 +264,11 @@ func (sb *sandbox) Rename(name string) error {
 	return err
 }
 
-func (sb *sandbox) Refresh(options ...SandboxOption) error {
+// Refresh leaves all the endpoints, resets and re-applies the options,
+// re-joins all the endpoints without destroying the osl sandbox
+func (sb *Sandbox) Refresh(options ...SandboxOption) error {
 	// Store connected endpoints
-	epList := sb.getConnectedEndpoints()
+	epList := sb.Endpoints()
 
 	// Detach from all endpoints
 	for _, ep := range epList {
@@ -319,17 +296,17 @@ func (sb *sandbox) Refresh(options ...SandboxOption) error {
 	return nil
 }
 
-func (sb *sandbox) MarshalJSON() ([]byte, error) {
-	sb.Lock()
-	defer sb.Unlock()
+func (sb *Sandbox) MarshalJSON() ([]byte, error) {
+	sb.mu.Lock()
+	defer sb.mu.Unlock()
 
 	// We are just interested in the container ID. This can be expanded to include all of containerInfo if there is a need
 	return json.Marshal(sb.id)
 }
 
-func (sb *sandbox) UnmarshalJSON(b []byte) (err error) {
-	sb.Lock()
-	defer sb.Unlock()
+func (sb *Sandbox) UnmarshalJSON(b []byte) (err error) {
+	sb.mu.Lock()
+	defer sb.mu.Unlock()
 
 	var id string
 	if err := json.Unmarshal(b, &id); err != nil {
@@ -339,30 +316,20 @@ func (sb *sandbox) UnmarshalJSON(b []byte) (err error) {
 	return nil
 }
 
-func (sb *sandbox) Endpoints() []Endpoint {
-	sb.Lock()
-	defer sb.Unlock()
-
-	endpoints := make([]Endpoint, len(sb.endpoints))
-	for i, ep := range sb.endpoints {
-		endpoints[i] = ep
-	}
-	return endpoints
-}
-
-func (sb *sandbox) getConnectedEndpoints() []*endpoint {
-	sb.Lock()
-	defer sb.Unlock()
+// Endpoints returns all the endpoints connected to the sandbox.
+func (sb *Sandbox) Endpoints() []*Endpoint {
+	sb.mu.Lock()
+	defer sb.mu.Unlock()
 
-	eps := make([]*endpoint, len(sb.endpoints))
+	eps := make([]*Endpoint, len(sb.endpoints))
 	copy(eps, sb.endpoints)
 
 	return eps
 }
 
-func (sb *sandbox) addEndpoint(ep *endpoint) {
-	sb.Lock()
-	defer sb.Unlock()
+func (sb *Sandbox) addEndpoint(ep *Endpoint) {
+	sb.mu.Lock()
+	defer sb.mu.Unlock()
 
 	l := len(sb.endpoints)
 	i := sort.Search(l, func(j int) bool {
@@ -374,14 +341,14 @@ func (sb *sandbox) addEndpoint(ep *endpoint) {
 	sb.endpoints[i] = ep
 }
 
-func (sb *sandbox) removeEndpoint(ep *endpoint) {
-	sb.Lock()
-	defer sb.Unlock()
+func (sb *Sandbox) removeEndpoint(ep *Endpoint) {
+	sb.mu.Lock()
+	defer sb.mu.Unlock()
 
 	sb.removeEndpointRaw(ep)
 }
 
-func (sb *sandbox) removeEndpointRaw(ep *endpoint) {
+func (sb *Sandbox) removeEndpointRaw(ep *Endpoint) {
 	for i, e := range sb.endpoints {
 		if e == ep {
 			sb.endpoints = append(sb.endpoints[:i], sb.endpoints[i+1:]...)
@@ -390,9 +357,9 @@ func (sb *sandbox) removeEndpointRaw(ep *endpoint) {
 	}
 }
 
-func (sb *sandbox) getEndpoint(id string) *endpoint {
-	sb.Lock()
-	defer sb.Unlock()
+func (sb *Sandbox) getEndpoint(id string) *Endpoint {
+	sb.mu.Lock()
+	defer sb.mu.Unlock()
 
 	for _, ep := range sb.endpoints {
 		if ep.id == id {
@@ -403,10 +370,10 @@ func (sb *sandbox) getEndpoint(id string) *endpoint {
 	return nil
 }
 
-func (sb *sandbox) updateGateway(ep *endpoint) error {
-	sb.Lock()
+func (sb *Sandbox) updateGateway(ep *Endpoint) error {
+	sb.mu.Lock()
 	osSbox := sb.osSbox
-	sb.Unlock()
+	sb.mu.Unlock()
 	if osSbox == nil {
 		return nil
 	}
@@ -417,9 +384,9 @@ func (sb *sandbox) updateGateway(ep *endpoint) error {
 		return nil
 	}
 
-	ep.Lock()
+	ep.mu.Lock()
 	joinInfo := ep.joinInfo
-	ep.Unlock()
+	ep.mu.Unlock()
 
 	if err := osSbox.SetGateway(joinInfo.gw); err != nil {
 		return fmt.Errorf("failed to set gateway while updating gateway: %v", err)
@@ -432,18 +399,18 @@ func (sb *sandbox) updateGateway(ep *endpoint) error {
 	return nil
 }
 
-func (sb *sandbox) HandleQueryResp(name string, ip net.IP) {
-	for _, ep := range sb.getConnectedEndpoints() {
+func (sb *Sandbox) HandleQueryResp(name string, ip net.IP) {
+	for _, ep := range sb.Endpoints() {
 		n := ep.getNetwork()
 		n.HandleQueryResp(name, ip)
 	}
 }
 
-func (sb *sandbox) ResolveIP(ip string) string {
+func (sb *Sandbox) ResolveIP(ip string) string {
 	var svc string
 	logrus.Debugf("IP To resolve %v", ip)
 
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		n := ep.getNetwork()
 		svc = n.ResolveIP(ip)
 		if len(svc) != 0 {
@@ -454,17 +421,19 @@ func (sb *sandbox) ResolveIP(ip string) string {
 	return svc
 }
 
-func (sb *sandbox) ExecFunc(f func()) error {
-	sb.Lock()
+func (sb *Sandbox) ExecFunc(f func()) error {
+	sb.mu.Lock()
 	osSbox := sb.osSbox
-	sb.Unlock()
+	sb.mu.Unlock()
 	if osSbox != nil {
 		return osSbox.InvokeFunc(f)
 	}
 	return fmt.Errorf("osl sandbox unavailable in ExecFunc for %v", sb.ContainerID())
 }
 
-func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
+// ResolveService returns all the backend details about the containers or hosts
+// backing a service. Its purpose is to satisfy an SRV query.
+func (sb *Sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
 	srv := []*net.SRV{}
 	ip := []net.IP{}
 
@@ -478,7 +447,7 @@ func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
 		return nil, nil
 	}
 
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		n := ep.getNetwork()
 
 		srv, ip = n.ResolveService(name)
@@ -489,8 +458,8 @@ func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
 	return srv, ip
 }
 
-func getDynamicNwEndpoints(epList []*endpoint) []*endpoint {
-	eps := []*endpoint{}
+func getDynamicNwEndpoints(epList []*Endpoint) []*Endpoint {
+	eps := []*Endpoint{}
 	for _, ep := range epList {
 		n := ep.getNetwork()
 		if n.dynamic && !n.ingress {
@@ -500,7 +469,7 @@ func getDynamicNwEndpoints(epList []*endpoint) []*endpoint {
 	return eps
 }
 
-func getIngressNwEndpoint(epList []*endpoint) *endpoint {
+func getIngressNwEndpoint(epList []*Endpoint) *Endpoint {
 	for _, ep := range epList {
 		n := ep.getNetwork()
 		if n.ingress {
@@ -510,8 +479,8 @@ func getIngressNwEndpoint(epList []*endpoint) *endpoint {
 	return nil
 }
 
-func getLocalNwEndpoints(epList []*endpoint) []*endpoint {
-	eps := []*endpoint{}
+func getLocalNwEndpoints(epList []*Endpoint) []*Endpoint {
+	eps := []*Endpoint{}
 	for _, ep := range epList {
 		n := ep.getNetwork()
 		if !n.dynamic && !n.ingress {
@@ -521,7 +490,7 @@ func getLocalNwEndpoints(epList []*endpoint) []*endpoint {
 	return eps
 }
 
-func (sb *sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
+func (sb *Sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
 	// Embedded server owns the docker network domain. Resolution should work
 	// for both container_name and container_name.network_name
 	// We allow '.' in service name and network name. For a name a.b.c.d the
@@ -550,12 +519,12 @@ func (sb *sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
 		}
 	}
 
-	epList := sb.getConnectedEndpoints()
+	epList := sb.Endpoints()
 
 	// In swarm mode services with exposed ports are connected to user overlay
 	// network, ingress network and docker_gwbridge network. Name resolution
 	// should prioritize returning the VIP/IPs on user overlay network.
-	newList := []*endpoint{}
+	newList := []*Endpoint{}
 	if !sb.controller.isDistributedControl() {
 		newList = append(newList, getDynamicNwEndpoints(epList)...)
 		ingressEP := getIngressNwEndpoint(epList)
@@ -588,7 +557,7 @@ func (sb *sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
 	return nil, false
 }
 
-func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoint, alias bool, ipType int) ([]net.IP, bool) {
+func (sb *Sandbox) resolveName(req string, networkName string, epList []*Endpoint, alias bool, ipType int) ([]net.IP, bool) {
 	var ipv6Miss bool
 
 	for _, ep := range epList {
@@ -605,21 +574,21 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin
 			}
 
 			var ok bool
-			ep.Lock()
+			ep.mu.Lock()
 			name, ok = ep.aliases[req]
-			ep.Unlock()
+			ep.mu.Unlock()
 			if !ok {
 				continue
 			}
 		} else {
 			// If it is a regular lookup and if the requested name is an alias
 			// don't perform a svc lookup for this endpoint.
-			ep.Lock()
+			ep.mu.Lock()
 			if _, ok := ep.aliases[req]; ok {
-				ep.Unlock()
+				ep.mu.Unlock()
 				continue
 			}
-			ep.Unlock()
+			ep.mu.Unlock()
 		}
 
 		ip, miss := n.ResolveName(name, ipType)
@@ -635,7 +604,8 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin
 	return nil, ipv6Miss
 }
 
-func (sb *sandbox) SetKey(basePath string) error {
+// SetKey updates the Sandbox Key.
+func (sb *Sandbox) SetKey(basePath string) error {
 	start := time.Now()
 	defer func() {
 		logrus.Debugf("sandbox set key processing took %s for container %s", time.Since(start), sb.ContainerID())
@@ -645,13 +615,13 @@ func (sb *sandbox) SetKey(basePath string) error {
 		return types.BadRequestErrorf("invalid sandbox key")
 	}
 
-	sb.Lock()
+	sb.mu.Lock()
 	if sb.inDelete {
-		sb.Unlock()
+		sb.mu.Unlock()
 		return types.ForbiddenErrorf("failed to SetKey: sandbox %q delete in progress", sb.id)
 	}
 	oldosSbox := sb.osSbox
-	sb.Unlock()
+	sb.mu.Unlock()
 
 	if oldosSbox != nil {
 		// If we already have an OS sandbox, release the network resources from that
@@ -665,9 +635,9 @@ func (sb *sandbox) SetKey(basePath string) error {
 		return err
 	}
 
-	sb.Lock()
+	sb.mu.Lock()
 	sb.osSbox = osSbox
-	sb.Unlock()
+	sb.mu.Unlock()
 
 	// If the resolver was setup before stop it and set it up in the
 	// new osl sandbox.
@@ -683,7 +653,7 @@ func (sb *sandbox) SetKey(basePath string) error {
 		}
 	}
 
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		if err = sb.populateNetworkResources(ep); err != nil {
 			return err
 		}
@@ -691,7 +661,9 @@ func (sb *sandbox) SetKey(basePath string) error {
 	return nil
 }
 
-func (sb *sandbox) EnableService() (err error) {
+// EnableService makes a managed container's service available by adding the
+// endpoint to the service load balancer and service discovery.
+func (sb *Sandbox) EnableService() (err error) {
 	logrus.Debugf("EnableService %s START", sb.containerID)
 	defer func() {
 		if err != nil {
@@ -700,7 +672,7 @@ func (sb *sandbox) EnableService() (err error) {
 			}
 		}
 	}()
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		if !ep.isServiceEnabled() {
 			if err := ep.addServiceInfoToCluster(sb); err != nil {
 				return fmt.Errorf("could not update state for endpoint %s into cluster: %v", ep.Name(), err)
@@ -712,7 +684,9 @@ func (sb *sandbox) EnableService() (err error) {
 	return nil
 }
 
-func (sb *sandbox) DisableService() (err error) {
+// DisableService removes a managed container's endpoints from the load balancer
+// and service discovery.
+func (sb *Sandbox) DisableService() (err error) {
 	logrus.Debugf("DisableService %s START", sb.containerID)
 	failedEps := []string{}
 	defer func() {
@@ -720,7 +694,7 @@ func (sb *sandbox) DisableService() (err error) {
 			err = fmt.Errorf("failed to disable service on sandbox:%s, for endpoints %s", sb.ID(), strings.Join(failedEps, ","))
 		}
 	}()
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		if ep.isServiceEnabled() {
 			if err := ep.deleteServiceInfoFromCluster(sb, false, "DisableService"); err != nil {
 				failedEps = append(failedEps, ep.Name())
@@ -733,7 +707,7 @@ func (sb *sandbox) DisableService() (err error) {
 	return nil
 }
 
-func releaseOSSboxResources(osSbox osl.Sandbox, ep *endpoint) {
+func releaseOSSboxResources(osSbox osl.Sandbox, ep *Endpoint) {
 	for _, i := range osSbox.Info().Interfaces() {
 		// Only remove the interfaces owned by this endpoint from the sandbox.
 		if ep.hasInterface(i.SrcName()) {
@@ -743,11 +717,11 @@ func releaseOSSboxResources(osSbox osl.Sandbox, ep *endpoint) {
 		}
 	}
 
-	ep.Lock()
+	ep.mu.Lock()
 	joinInfo := ep.joinInfo
 	vip := ep.virtualIP
 	lbModeIsDSR := ep.network.loadBalancerMode == loadBalancerModeDSR
-	ep.Unlock()
+	ep.mu.Unlock()
 
 	if len(vip) > 0 && lbModeIsDSR {
 		ipNet := &net.IPNet{IP: vip, Mask: net.CIDRMask(32, 32)}
@@ -768,17 +742,17 @@ func releaseOSSboxResources(osSbox osl.Sandbox, ep *endpoint) {
 	}
 }
 
-func (sb *sandbox) releaseOSSbox() {
-	sb.Lock()
+func (sb *Sandbox) releaseOSSbox() {
+	sb.mu.Lock()
 	osSbox := sb.osSbox
 	sb.osSbox = nil
-	sb.Unlock()
+	sb.mu.Unlock()
 
 	if osSbox == nil {
 		return
 	}
 
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		releaseOSSboxResources(osSbox, ep)
 	}
 
@@ -787,16 +761,16 @@ func (sb *sandbox) releaseOSSbox() {
 	}
 }
 
-func (sb *sandbox) restoreOslSandbox() error {
+func (sb *Sandbox) restoreOslSandbox() error {
 	var routes []*types.StaticRoute
 
 	// restore osl sandbox
 	Ifaces := make(map[string][]osl.IfaceOption)
 	for _, ep := range sb.endpoints {
-		ep.Lock()
+		ep.mu.Lock()
 		joinInfo := ep.joinInfo
 		i := ep.iface
-		ep.Unlock()
+		ep.mu.Unlock()
 
 		if i == nil {
 			logrus.Errorf("error restoring endpoint %s for container %s", ep.Name(), sb.ContainerID())
@@ -834,20 +808,20 @@ func (sb *sandbox) restoreOslSandbox() error {
 	return sb.osSbox.Restore(Ifaces, routes, gwep.joinInfo.gw, gwep.joinInfo.gw6)
 }
 
-func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
-	sb.Lock()
+func (sb *Sandbox) populateNetworkResources(ep *Endpoint) error {
+	sb.mu.Lock()
 	if sb.osSbox == nil {
-		sb.Unlock()
+		sb.mu.Unlock()
 		return nil
 	}
 	inDelete := sb.inDelete
-	sb.Unlock()
+	sb.mu.Unlock()
 
-	ep.Lock()
+	ep.mu.Lock()
 	joinInfo := ep.joinInfo
 	i := ep.iface
 	lbModeIsDSR := ep.network.loadBalancerMode == loadBalancerModeDSR
-	ep.Unlock()
+	ep.mu.Unlock()
 
 	if ep.needResolver() {
 		sb.startResolver(false)
@@ -901,9 +875,9 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
 
 	// Make sure to add the endpoint to the populated endpoint set
 	// before populating loadbalancers.
-	sb.Lock()
+	sb.mu.Lock()
 	sb.populatedEndpoints[ep.ID()] = struct{}{}
-	sb.Unlock()
+	sb.mu.Unlock()
 
 	// Populate load balancer only after updating all the other
 	// information including gateway and other routes so that
@@ -922,34 +896,34 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
 	return nil
 }
 
-func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
+func (sb *Sandbox) clearNetworkResources(origEp *Endpoint) error {
 	ep := sb.getEndpoint(origEp.id)
 	if ep == nil {
 		return fmt.Errorf("could not find the sandbox endpoint data for endpoint %s",
 			origEp.id)
 	}
 
-	sb.Lock()
+	sb.mu.Lock()
 	osSbox := sb.osSbox
 	inDelete := sb.inDelete
-	sb.Unlock()
+	sb.mu.Unlock()
 	if osSbox != nil {
 		releaseOSSboxResources(osSbox, ep)
 	}
 
-	sb.Lock()
+	sb.mu.Lock()
 	delete(sb.populatedEndpoints, ep.ID())
 
 	if len(sb.endpoints) == 0 {
 		// sb.endpoints should never be empty and this is unexpected error condition
 		// We log an error message to note this down for debugging purposes.
 		logrus.Errorf("No endpoints in sandbox while trying to remove endpoint %s", ep.Name())
-		sb.Unlock()
+		sb.mu.Unlock()
 		return nil
 	}
 
 	var (
-		gwepBefore, gwepAfter *endpoint
+		gwepBefore, gwepAfter *Endpoint
 		index                 = -1
 	)
 	for i, e := range sb.endpoints {
@@ -966,7 +940,7 @@ func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
 
 	if index == -1 {
 		logrus.Warnf("Endpoint %s has already been deleted", ep.Name())
-		sb.Unlock()
+		sb.mu.Unlock()
 		return nil
 	}
 
@@ -978,7 +952,7 @@ func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
 		}
 	}
 	delete(sb.epPriority, ep.ID())
-	sb.Unlock()
+	sb.mu.Unlock()
 
 	if gwepAfter != nil && gwepBefore != gwepAfter {
 		if err := sb.updateGateway(gwepAfter); err != nil {
@@ -999,17 +973,17 @@ func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
 
 // joinLeaveStart waits to ensure there are no joins or leaves in progress and
 // marks this join/leave in progress without race
-func (sb *sandbox) joinLeaveStart() {
-	sb.Lock()
-	defer sb.Unlock()
+func (sb *Sandbox) joinLeaveStart() {
+	sb.mu.Lock()
+	defer sb.mu.Unlock()
 
 	for sb.joinLeaveDone != nil {
 		joinLeaveDone := sb.joinLeaveDone
-		sb.Unlock()
+		sb.mu.Unlock()
 
 		<-joinLeaveDone
 
-		sb.Lock()
+		sb.mu.Lock()
 	}
 
 	sb.joinLeaveDone = make(chan struct{})
@@ -1017,9 +991,9 @@ func (sb *sandbox) joinLeaveStart() {
 
 // joinLeaveEnd marks the end of this join/leave operation and
 // signals the same without race to other join and leave waiters
-func (sb *sandbox) joinLeaveEnd() {
-	sb.Lock()
-	defer sb.Unlock()
+func (sb *Sandbox) joinLeaveEnd() {
+	sb.mu.Lock()
+	defer sb.mu.Unlock()
 
 	if sb.joinLeaveDone != nil {
 		close(sb.joinLeaveDone)
@@ -1030,7 +1004,7 @@ func (sb *sandbox) joinLeaveEnd() {
 // OptionHostname function returns an option setter for hostname option to
 // be passed to NewSandbox method.
 func OptionHostname(name string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.hostName = name
 	}
 }
@@ -1038,7 +1012,7 @@ func OptionHostname(name string) SandboxOption {
 // OptionDomainname function returns an option setter for domainname option to
 // be passed to NewSandbox method.
 func OptionDomainname(name string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.domainName = name
 	}
 }
@@ -1046,7 +1020,7 @@ func OptionDomainname(name string) SandboxOption {
 // OptionHostsPath function returns an option setter for hostspath option to
 // be passed to NewSandbox method.
 func OptionHostsPath(path string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.hostsPath = path
 	}
 }
@@ -1054,7 +1028,7 @@ func OptionHostsPath(path string) SandboxOption {
 // OptionOriginHostsPath function returns an option setter for origin hosts file path
 // to be passed to NewSandbox method.
 func OptionOriginHostsPath(path string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.originHostsPath = path
 	}
 }
@@ -1062,7 +1036,7 @@ func OptionOriginHostsPath(path string) SandboxOption {
 // OptionExtraHost function returns an option setter for extra /etc/hosts options
 // which is a name and IP as strings.
 func OptionExtraHost(name string, IP string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.extraHosts = append(sb.config.extraHosts, extraHost{name: name, IP: IP})
 	}
 }
@@ -1070,7 +1044,7 @@ func OptionExtraHost(name string, IP string) SandboxOption {
 // OptionParentUpdate function returns an option setter for parent container
 // which needs to update the IP address for the linked container.
 func OptionParentUpdate(cid string, name, ip string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.parentUpdates = append(sb.config.parentUpdates, parentUpdate{cid: cid, name: name, ip: ip})
 	}
 }
@@ -1078,7 +1052,7 @@ func OptionParentUpdate(cid string, name, ip string) SandboxOption {
 // OptionResolvConfPath function returns an option setter for resolvconfpath option to
 // be passed to net container methods.
 func OptionResolvConfPath(path string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.resolvConfPath = path
 	}
 }
@@ -1086,7 +1060,7 @@ func OptionResolvConfPath(path string) SandboxOption {
 // OptionOriginResolvConfPath function returns an option setter to set the path to the
 // origin resolv.conf file to be passed to net container methods.
 func OptionOriginResolvConfPath(path string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.originResolvConfPath = path
 	}
 }
@@ -1094,7 +1068,7 @@ func OptionOriginResolvConfPath(path string) SandboxOption {
 // OptionDNS function returns an option setter for dns entry option to
 // be passed to container Create method.
 func OptionDNS(dns string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.dnsList = append(sb.config.dnsList, dns)
 	}
 }
@@ -1102,7 +1076,7 @@ func OptionDNS(dns string) SandboxOption {
 // OptionDNSSearch function returns an option setter for dns search entry option to
 // be passed to container Create method.
 func OptionDNSSearch(search string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.dnsSearchList = append(sb.config.dnsSearchList, search)
 	}
 }
@@ -1110,7 +1084,7 @@ func OptionDNSSearch(search string) SandboxOption {
 // OptionDNSOptions function returns an option setter for dns options entry option to
 // be passed to container Create method.
 func OptionDNSOptions(options string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.dnsOptionsList = append(sb.config.dnsOptionsList, options)
 	}
 }
@@ -1118,7 +1092,7 @@ func OptionDNSOptions(options string) SandboxOption {
 // OptionUseDefaultSandbox function returns an option setter for using default sandbox
 // (host namespace) to be passed to container Create method.
 func OptionUseDefaultSandbox() SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.useDefaultSandBox = true
 	}
 }
@@ -1126,7 +1100,7 @@ func OptionUseDefaultSandbox() SandboxOption {
 // OptionUseExternalKey function returns an option setter for using provided namespace
 // instead of creating one.
 func OptionUseExternalKey() SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.config.useExternalKey = true
 	}
 }
@@ -1135,7 +1109,7 @@ func OptionUseExternalKey() SandboxOption {
 // that is not managed by libNetwork but can be used by the Drivers during the call to
 // net container creation method. Container Labels are a good example.
 func OptionGeneric(generic map[string]interface{}) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		if sb.config.generic == nil {
 			sb.config.generic = make(map[string]interface{}, len(generic))
 		}
@@ -1148,7 +1122,7 @@ func OptionGeneric(generic map[string]interface{}) SandboxOption {
 // OptionExposedPorts function returns an option setter for the container exposed
 // ports option to be passed to container Create method.
 func OptionExposedPorts(exposedPorts []types.TransportPort) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		if sb.config.generic == nil {
 			sb.config.generic = make(map[string]interface{})
 		}
@@ -1164,7 +1138,7 @@ func OptionExposedPorts(exposedPorts []types.TransportPort) SandboxOption {
 // OptionPortMapping function returns an option setter for the mapping
 // ports option to be passed to container Create method.
 func OptionPortMapping(portBindings []types.PortBinding) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		if sb.config.generic == nil {
 			sb.config.generic = make(map[string]interface{})
 		}
@@ -1178,7 +1152,7 @@ func OptionPortMapping(portBindings []types.PortBinding) SandboxOption {
 // OptionIngress function returns an option setter for marking a
 // sandbox as the controller's ingress sandbox.
 func OptionIngress() SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.ingress = true
 		sb.oslTypes = append(sb.oslTypes, osl.SandboxTypeIngress)
 	}
@@ -1187,7 +1161,7 @@ func OptionIngress() SandboxOption {
 // OptionLoadBalancer function returns an option setter for marking a
 // sandbox as a load balancer sandbox.
 func OptionLoadBalancer(nid string) SandboxOption {
-	return func(sb *sandbox) {
+	return func(sb *Sandbox) {
 		sb.loadBalancerNID = nid
 		sb.oslTypes = append(sb.oslTypes, osl.SandboxTypeLoadBalancer)
 	}
@@ -1199,7 +1173,7 @@ func OptionLoadBalancer(nid string) SandboxOption {
 // epi.internal <=> epj.internal   # non-internal < internal
 // epi.joininfo <=> epj.joininfo   # ipv6 < ipv4
 // epi.name <=> epj.name           # bar < foo
-func (epi *endpoint) Less(epj *endpoint) bool {
+func (epi *Endpoint) Less(epj *Endpoint) bool {
 	var (
 		prioi, prioj int
 	)
@@ -1258,6 +1232,6 @@ func (epi *endpoint) Less(epj *endpoint) bool {
 	return epi.network.Name() < epj.network.Name()
 }
 
-func (sb *sandbox) NdotsSet() bool {
+func (sb *Sandbox) NdotsSet() bool {
 	return sb.ndotsSet
 }

+ 14 - 14
libnetwork/sandbox_dns_unix.go

@@ -24,7 +24,7 @@ const (
 	filePerm      = 0o644
 )
 
-func (sb *sandbox) startResolver(restore bool) {
+func (sb *Sandbox) startResolver(restore bool) {
 	sb.resolverOnce.Do(func() {
 		var err error
 		sb.resolver = NewResolver(resolverIPSandbox, true, sb)
@@ -58,7 +58,7 @@ func (sb *sandbox) startResolver(restore bool) {
 	})
 }
 
-func (sb *sandbox) setupResolutionFiles() error {
+func (sb *Sandbox) setupResolutionFiles() error {
 	if err := sb.buildHostsFile(); err != nil {
 		return err
 	}
@@ -70,7 +70,7 @@ func (sb *sandbox) setupResolutionFiles() error {
 	return sb.setupDNS()
 }
 
-func (sb *sandbox) buildHostsFile() error {
+func (sb *Sandbox) buildHostsFile() error {
 	if sb.config.hostsPath == "" {
 		sb.config.hostsPath = defaultPrefix + "/" + sb.id + "/hosts"
 	}
@@ -98,7 +98,7 @@ func (sb *sandbox) buildHostsFile() error {
 	return etchosts.Build(sb.config.hostsPath, "", sb.config.hostName, sb.config.domainName, extraContent)
 }
 
-func (sb *sandbox) updateHostsFile(ifaceIPs []string) error {
+func (sb *Sandbox) updateHostsFile(ifaceIPs []string) error {
 	if len(ifaceIPs) == 0 {
 		return nil
 	}
@@ -128,27 +128,27 @@ func (sb *sandbox) updateHostsFile(ifaceIPs []string) error {
 	return nil
 }
 
-func (sb *sandbox) addHostsEntries(recs []etchosts.Record) {
+func (sb *Sandbox) addHostsEntries(recs []etchosts.Record) {
 	if err := etchosts.Add(sb.config.hostsPath, recs); err != nil {
 		logrus.Warnf("Failed adding service host entries to the running container: %v", err)
 	}
 }
 
-func (sb *sandbox) deleteHostsEntries(recs []etchosts.Record) {
+func (sb *Sandbox) deleteHostsEntries(recs []etchosts.Record) {
 	if err := etchosts.Delete(sb.config.hostsPath, recs); err != nil {
 		logrus.Warnf("Failed deleting service host entries to the running container: %v", err)
 	}
 }
 
-func (sb *sandbox) updateParentHosts() error {
-	var pSb Sandbox
+func (sb *Sandbox) updateParentHosts() error {
+	var pSb *Sandbox
 
 	for _, update := range sb.config.parentUpdates {
 		sb.controller.WalkSandboxes(SandboxContainerWalker(&pSb, update.cid))
 		if pSb == nil {
 			continue
 		}
-		if err := etchosts.Update(pSb.(*sandbox).config.hostsPath, update.ip, update.name); err != nil {
+		if err := etchosts.Update(pSb.config.hostsPath, update.ip, update.name); err != nil {
 			return err
 		}
 	}
@@ -156,7 +156,7 @@ func (sb *sandbox) updateParentHosts() error {
 	return nil
 }
 
-func (sb *sandbox) restorePath() {
+func (sb *Sandbox) restorePath() {
 	if sb.config.resolvConfPath == "" {
 		sb.config.resolvConfPath = defaultPrefix + "/" + sb.id + "/resolv.conf"
 	}
@@ -166,7 +166,7 @@ func (sb *sandbox) restorePath() {
 	}
 }
 
-func (sb *sandbox) setExternalResolvers(content []byte, addrType int, checkLoopback bool) {
+func (sb *Sandbox) setExternalResolvers(content []byte, addrType int, checkLoopback bool) {
 	servers := resolvconf.GetNameservers(content, addrType)
 	for _, ip := range servers {
 		hostLoopback := false
@@ -192,7 +192,7 @@ func isIPv4Loopback(ipAddress string) bool {
 	return false
 }
 
-func (sb *sandbox) setupDNS() error {
+func (sb *Sandbox) setupDNS() error {
 	if sb.config.resolvConfPath == "" {
 		sb.config.resolvConfPath = defaultPrefix + "/" + sb.id + "/resolv.conf"
 	}
@@ -286,7 +286,7 @@ func (sb *sandbox) setupDNS() error {
 	return nil
 }
 
-func (sb *sandbox) updateDNS(ipv6Enabled bool) error {
+func (sb *Sandbox) updateDNS(ipv6Enabled bool) error {
 	var (
 		currHash string
 		hashFile = sb.config.resolvConfHashFile
@@ -358,7 +358,7 @@ func (sb *sandbox) updateDNS(ipv6Enabled bool) error {
 // resolv.conf by doing the following
 // - Add only the embedded server's IP to container's resolv.conf
 // - If the embedded server needs any resolv.conf options add it to the current list
-func (sb *sandbox) rebuildDNS() error {
+func (sb *Sandbox) rebuildDNS() error {
 	currRC, err := os.ReadFile(sb.config.resolvConfPath)
 	if err != nil {
 		return err

+ 9 - 9
libnetwork/sandbox_dns_windows.go

@@ -9,30 +9,30 @@ import (
 
 // Stub implementations for DNS related functions
 
-func (sb *sandbox) startResolver(bool) {}
+func (sb *Sandbox) startResolver(bool) {}
 
-func (sb *sandbox) setupResolutionFiles() error {
+func (sb *Sandbox) setupResolutionFiles() error {
 	return nil
 }
 
-func (sb *sandbox) restorePath() {}
+func (sb *Sandbox) restorePath() {}
 
-func (sb *sandbox) updateHostsFile(ifaceIP []string) error {
+func (sb *Sandbox) updateHostsFile(ifaceIP []string) error {
 	return nil
 }
 
-func (sb *sandbox) addHostsEntries(recs []etchosts.Record) {}
+func (sb *Sandbox) addHostsEntries(recs []etchosts.Record) {}
 
-func (sb *sandbox) deleteHostsEntries(recs []etchosts.Record) {}
+func (sb *Sandbox) deleteHostsEntries(recs []etchosts.Record) {}
 
-func (sb *sandbox) updateDNS(ipv6Enabled bool) error {
+func (sb *Sandbox) updateDNS(ipv6Enabled bool) error {
 	return nil
 }
 
-func (sb *sandbox) setupDNS() error {
+func (sb *Sandbox) setupDNS() error {
 	return nil
 }
 
-func (sb *sandbox) rebuildDNS() error {
+func (sb *Sandbox) rebuildDNS() error {
 	return nil
 }

+ 7 - 7
libnetwork/sandbox_externalkey_unix.go

@@ -112,7 +112,7 @@ func processReturn(r io.Reader) error {
 	return nil
 }
 
-func (c *controller) startExternalKeyListener() error {
+func (c *Controller) startExternalKeyListener() error {
 	execRoot := defaultExecRoot
 	if v := c.Config().ExecRoot; v != "" {
 		execRoot = v
@@ -131,15 +131,15 @@ func (c *controller) startExternalKeyListener() error {
 		l.Close()
 		return err
 	}
-	c.Lock()
+	c.mu.Lock()
 	c.extKeyListener = l
-	c.Unlock()
+	c.mu.Unlock()
 
 	go c.acceptClientConnections(uds, l)
 	return nil
 }
 
-func (c *controller) acceptClientConnections(sock string, l net.Listener) {
+func (c *Controller) acceptClientConnections(sock string, l net.Listener) {
 	for {
 		conn, err := l.Accept()
 		if err != nil {
@@ -167,7 +167,7 @@ func (c *controller) acceptClientConnections(sock string, l net.Listener) {
 	}
 }
 
-func (c *controller) processExternalKey(conn net.Conn) error {
+func (c *Controller) processExternalKey(conn net.Conn) error {
 	buf := make([]byte, 1280)
 	nr, err := conn.Read(buf)
 	if err != nil {
@@ -178,7 +178,7 @@ func (c *controller) processExternalKey(conn net.Conn) error {
 		return err
 	}
 
-	var sandbox Sandbox
+	var sandbox *Sandbox
 	search := SandboxContainerWalker(&sandbox, s.ContainerID)
 	c.WalkSandboxes(search)
 	if sandbox == nil {
@@ -188,6 +188,6 @@ func (c *controller) processExternalKey(conn net.Conn) error {
 	return sandbox.SetKey(s.Key)
 }
 
-func (c *controller) stopExternalKeyListener() {
+func (c *Controller) stopExternalKeyListener() {
 	c.extKeyListener.Close()
 }

+ 4 - 4
libnetwork/sandbox_externalkey_windows.go

@@ -31,16 +31,16 @@ func processReturn(r io.Reader) error {
 }
 
 // no-op on non linux systems
-func (c *controller) startExternalKeyListener() error {
+func (c *Controller) startExternalKeyListener() error {
 	return nil
 }
 
-func (c *controller) acceptClientConnections(sock string, l net.Listener) {
+func (c *Controller) acceptClientConnections(sock string, l net.Listener) {
 }
 
-func (c *controller) processExternalKey(conn net.Conn) error {
+func (c *Controller) processExternalKey(conn net.Conn) error {
 	return types.NotImplementedErrorf("processExternalKey isn't supported on non linux systems")
 }
 
-func (c *controller) stopExternalKeyListener() {
+func (c *Controller) stopExternalKeyListener() {
 }

+ 15 - 18
libnetwork/sandbox_store.go

@@ -21,7 +21,7 @@ type epState struct {
 type sbState struct {
 	ID         string
 	Cid        string
-	c          *controller
+	c          *Controller
 	dbIndex    uint64
 	dbExists   bool
 	Eps        []epState
@@ -55,12 +55,11 @@ func (sbs *sbState) SetValue(value []byte) error {
 }
 
 func (sbs *sbState) Index() uint64 {
-	sbi, err := sbs.c.SandboxByID(sbs.ID)
+	sb, err := sbs.c.SandboxByID(sbs.ID)
 	if err != nil {
 		return sbs.dbIndex
 	}
 
-	sb := sbi.(*sandbox)
 	maxIndex := sb.dbIndex
 	if sbs.dbIndex > maxIndex {
 		maxIndex = sbs.dbIndex
@@ -73,12 +72,11 @@ func (sbs *sbState) SetIndex(index uint64) {
 	sbs.dbIndex = index
 	sbs.dbExists = true
 
-	sbi, err := sbs.c.SandboxByID(sbs.ID)
+	sb, err := sbs.c.SandboxByID(sbs.ID)
 	if err != nil {
 		return
 	}
 
-	sb := sbi.(*sandbox)
 	sb.dbIndex = index
 	sb.dbExists = true
 }
@@ -88,12 +86,11 @@ func (sbs *sbState) Exists() bool {
 		return sbs.dbExists
 	}
 
-	sbi, err := sbs.c.SandboxByID(sbs.ID)
+	sb, err := sbs.c.SandboxByID(sbs.ID)
 	if err != nil {
 		return false
 	}
 
-	sb := sbi.(*sandbox)
 	return sb.dbExists
 }
 
@@ -135,7 +132,7 @@ func (sbs *sbState) DataScope() string {
 	return datastore.LocalScope
 }
 
-func (sb *sandbox) storeUpdate() error {
+func (sb *Sandbox) storeUpdate() error {
 	sbs := &sbState{
 		c:          sb.controller,
 		ID:         sb.id,
@@ -150,7 +147,7 @@ func (sb *sandbox) storeUpdate() error {
 
 retry:
 	sbs.Eps = nil
-	for _, ep := range sb.getConnectedEndpoints() {
+	for _, ep := range sb.Endpoints() {
 		// If the endpoint is not persisted then do not add it to
 		// the sandbox checkpoint
 		if ep.Skip() {
@@ -177,7 +174,7 @@ retry:
 	return err
 }
 
-func (sb *sandbox) storeDelete() error {
+func (sb *Sandbox) storeDelete() error {
 	sbs := &sbState{
 		c:        sb.controller,
 		ID:       sb.id,
@@ -189,7 +186,7 @@ func (sb *sandbox) storeDelete() error {
 	return sb.controller.deleteFromStore(sbs)
 }
 
-func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
+func (c *Controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
 	store := c.getStore(datastore.LocalScope)
 	if store == nil {
 		logrus.Error("Could not find local scope store while trying to cleanup sandboxes")
@@ -210,11 +207,11 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
 	for _, kvo := range kvol {
 		sbs := kvo.(*sbState)
 
-		sb := &sandbox{
+		sb := &Sandbox{
 			id:                 sbs.ID,
 			controller:         sbs.c,
 			containerID:        sbs.Cid,
-			endpoints:          []*endpoint{},
+			endpoints:          []*Endpoint{},
 			populatedEndpoints: map[string]struct{}{},
 			dbIndex:            sbs.dbIndex,
 			isStub:             true,
@@ -248,22 +245,22 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
 			continue
 		}
 
-		c.Lock()
+		c.mu.Lock()
 		c.sandboxes[sb.id] = sb
-		c.Unlock()
+		c.mu.Unlock()
 
 		for _, eps := range sbs.Eps {
 			n, err := c.getNetworkFromStore(eps.Nid)
-			var ep *endpoint
+			var ep *Endpoint
 			if err != nil {
 				logrus.Errorf("getNetworkFromStore for nid %s failed while trying to build sandbox for cleanup: %v", eps.Nid, err)
 				n = &network{id: eps.Nid, ctrlr: c, drvOnce: &sync.Once{}, persist: true}
-				ep = &endpoint{id: eps.Eid, network: n, sandboxID: sbs.ID}
+				ep = &Endpoint{id: eps.Eid, network: n, sandboxID: sbs.ID}
 			} else {
 				ep, err = n.getEndpointFromStore(eps.Eid)
 				if err != nil {
 					logrus.Errorf("getEndpointFromStore for eid %s failed while trying to build sandbox for cleanup: %v", eps.Eid, err)
-					ep = &endpoint{id: eps.Eid, network: n, sandboxID: sbs.ID}
+					ep = &Endpoint{id: eps.Eid, network: n, sandboxID: sbs.ID}
 				}
 			}
 			if _, ok := activeSandboxes[sb.ID()]; ok && err != nil {

+ 4 - 8
libnetwork/sandbox_test.go

@@ -14,7 +14,7 @@ import (
 	"gotest.tools/v3/skip"
 )
 
-func getTestEnv(t *testing.T, opts ...[]NetworkOption) (NetworkController, []Network) {
+func getTestEnv(t *testing.T, opts ...[]NetworkOption) (*Controller, []Network) {
 	skip.If(t, runtime.GOOS == "windows", "test only works on linux")
 
 	netType := "bridge"
@@ -61,8 +61,7 @@ func getTestEnv(t *testing.T, opts ...[]NetworkOption) (NetworkController, []Net
 }
 
 func TestSandboxAddEmpty(t *testing.T) {
-	c, _ := getTestEnv(t)
-	ctrlr := c.(*controller)
+	ctrlr, _ := getTestEnv(t)
 
 	sbx, err := ctrlr.NewSandbox("sandbox0")
 	if err != nil {
@@ -90,8 +89,7 @@ func TestSandboxAddMultiPrio(t *testing.T) {
 		{},
 	}
 
-	c, nws := getTestEnv(t, opts...)
-	ctrlr := c.(*controller)
+	ctrlr, nws := getTestEnv(t, opts...)
 
 	sbx, err := ctrlr.NewSandbox("sandbox1")
 	if err != nil {
@@ -176,9 +174,7 @@ func TestSandboxAddSamePrio(t *testing.T) {
 		{NetworkOptionInternalNetwork()},
 	}
 
-	c, nws := getTestEnv(t, opts...)
-
-	ctrlr := c.(*controller)
+	ctrlr, nws := getTestEnv(t, opts...)
 
 	sbx, err := ctrlr.NewSandbox("sandbox1")
 	if err != nil {

+ 22 - 22
libnetwork/service_common.go

@@ -12,7 +12,7 @@ import (
 
 const maxSetStringLen = 350
 
-func (c *controller) addEndpointNameResolution(svcName, svcID, nID, eID, containerName string, vip net.IP, serviceAliases, taskAliases []string, ip net.IP, addService bool, method string) error {
+func (c *Controller) addEndpointNameResolution(svcName, svcID, nID, eID, containerName string, vip net.IP, serviceAliases, taskAliases []string, ip net.IP, addService bool, method string) error {
 	n, err := c.NetworkByID(nID)
 	if err != nil {
 		return err
@@ -55,7 +55,7 @@ func (c *controller) addEndpointNameResolution(svcName, svcID, nID, eID, contain
 	return nil
 }
 
-func (c *controller) addContainerNameResolution(nID, eID, containerName string, taskAliases []string, ip net.IP, method string) error {
+func (c *Controller) addContainerNameResolution(nID, eID, containerName string, taskAliases []string, ip net.IP, method string) error {
 	n, err := c.NetworkByID(nID)
 	if err != nil {
 		return err
@@ -73,7 +73,7 @@ func (c *controller) addContainerNameResolution(nID, eID, containerName string,
 	return nil
 }
 
-func (c *controller) deleteEndpointNameResolution(svcName, svcID, nID, eID, containerName string, vip net.IP, serviceAliases, taskAliases []string, ip net.IP, rmService, multipleEntries bool, method string) error {
+func (c *Controller) deleteEndpointNameResolution(svcName, svcID, nID, eID, containerName string, vip net.IP, serviceAliases, taskAliases []string, ip net.IP, rmService, multipleEntries bool, method string) error {
 	n, err := c.NetworkByID(nID)
 	if err != nil {
 		return err
@@ -119,7 +119,7 @@ func (c *controller) deleteEndpointNameResolution(svcName, svcID, nID, eID, cont
 	return nil
 }
 
-func (c *controller) delContainerNameResolution(nID, eID, containerName string, taskAliases []string, ip net.IP, method string) error {
+func (c *Controller) delContainerNameResolution(nID, eID, containerName string, taskAliases []string, ip net.IP, method string) error {
 	n, err := c.NetworkByID(nID)
 	if err != nil {
 		return err
@@ -148,14 +148,14 @@ func newService(name string, id string, ingressPorts []*PortConfig, serviceAlias
 	}
 }
 
-func (c *controller) getLBIndex(sid, nid string, ingressPorts []*PortConfig) int {
+func (c *Controller) getLBIndex(sid, nid string, ingressPorts []*PortConfig) int {
 	skey := serviceKey{
 		id:    sid,
 		ports: portConfigs(ingressPorts).String(),
 	}
-	c.Lock()
+	c.mu.Lock()
 	s, ok := c.serviceBindings[skey]
-	c.Unlock()
+	c.mu.Unlock()
 
 	if !ok {
 		return 0
@@ -169,9 +169,9 @@ func (c *controller) getLBIndex(sid, nid string, ingressPorts []*PortConfig) int
 }
 
 // cleanupServiceDiscovery when the network is being deleted, erase all the associated service discovery records
-func (c *controller) cleanupServiceDiscovery(cleanupNID string) {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) cleanupServiceDiscovery(cleanupNID string) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	if cleanupNID == "" {
 		logrus.Debugf("cleanupServiceDiscovery for all networks")
 		c.svcRecords = make(map[string]svcInfo)
@@ -181,16 +181,16 @@ func (c *controller) cleanupServiceDiscovery(cleanupNID string) {
 	delete(c.svcRecords, cleanupNID)
 }
 
-func (c *controller) cleanupServiceBindings(cleanupNID string) {
+func (c *Controller) cleanupServiceBindings(cleanupNID string) {
 	var cleanupFuncs []func()
 
 	logrus.Debugf("cleanupServiceBindings for %s", cleanupNID)
-	c.Lock()
+	c.mu.Lock()
 	services := make([]*service, 0, len(c.serviceBindings))
 	for _, s := range c.serviceBindings {
 		services = append(services, s)
 	}
-	c.Unlock()
+	c.mu.Unlock()
 
 	for _, s := range services {
 		s.Lock()
@@ -215,7 +215,7 @@ func (c *controller) cleanupServiceBindings(cleanupNID string) {
 	}
 }
 
-func makeServiceCleanupFunc(c *controller, s *service, nID, eID string, vip net.IP, ip net.IP) func() {
+func makeServiceCleanupFunc(c *Controller, s *service, nID, eID string, vip net.IP, ip net.IP) func() {
 	// ContainerName and taskAliases are not available here, this is still fine because the Service discovery
 	// cleanup already happened before. The only thing that rmServiceBinding is still doing here a part from the Load
 	// Balancer bookeeping, is to keep consistent the mapping of endpoint to IP.
@@ -226,7 +226,7 @@ func makeServiceCleanupFunc(c *controller, s *service, nID, eID string, vip net.
 	}
 }
 
-func (c *controller) addServiceBinding(svcName, svcID, nID, eID, containerName string, vip net.IP, ingressPorts []*PortConfig, serviceAliases, taskAliases []string, ip net.IP, method string) error {
+func (c *Controller) addServiceBinding(svcName, svcID, nID, eID, containerName string, vip net.IP, ingressPorts []*PortConfig, serviceAliases, taskAliases []string, ip net.IP, method string) error {
 	var addService bool
 
 	// Failure to lock the network ID on add can result in racing
@@ -248,7 +248,7 @@ func (c *controller) addServiceBinding(svcName, svcID, nID, eID, containerName s
 
 	var s *service
 	for {
-		c.Lock()
+		c.mu.Lock()
 		var ok bool
 		s, ok = c.serviceBindings[skey]
 		if !ok {
@@ -257,7 +257,7 @@ func (c *controller) addServiceBinding(svcName, svcID, nID, eID, containerName s
 			s = newService(svcName, svcID, ingressPorts, serviceAliases)
 			c.serviceBindings[skey] = s
 		}
-		c.Unlock()
+		c.mu.Unlock()
 		s.Lock()
 		if !s.deleted {
 			// ok the object is good to be used
@@ -313,7 +313,7 @@ func (c *controller) addServiceBinding(svcName, svcID, nID, eID, containerName s
 	return nil
 }
 
-func (c *controller) rmServiceBinding(svcName, svcID, nID, eID, containerName string, vip net.IP, ingressPorts []*PortConfig, serviceAliases []string, taskAliases []string, ip net.IP, method string, deleteSvcRecords bool, fullRemove bool) error {
+func (c *Controller) rmServiceBinding(svcName, svcID, nID, eID, containerName string, vip net.IP, ingressPorts []*PortConfig, serviceAliases []string, taskAliases []string, ip net.IP, method string, deleteSvcRecords bool, fullRemove bool) error {
 	var rmService bool
 
 	skey := serviceKey{
@@ -321,9 +321,9 @@ func (c *controller) rmServiceBinding(svcName, svcID, nID, eID, containerName st
 		ports: portConfigs(ingressPorts).String(),
 	}
 
-	c.Lock()
+	c.mu.Lock()
 	s, ok := c.serviceBindings[skey]
-	c.Unlock()
+	c.mu.Unlock()
 	if !ok {
 		logrus.Warnf("rmServiceBinding %s %s %s aborted c.serviceBindings[skey] !ok", method, svcName, eID)
 		return nil
@@ -398,14 +398,14 @@ func (c *controller) rmServiceBinding(svcName, svcID, nID, eID, containerName st
 	if len(s.loadBalancers) == 0 {
 		// All loadbalancers for the service removed. Time to
 		// remove the service itself.
-		c.Lock()
+		c.mu.Lock()
 
 		// Mark the object as deleted so that the add won't use it wrongly
 		s.deleted = true
 		// NOTE The delete from the serviceBindings map has to be the last operation else we are allowing a race between this service
 		// that is getting deleted and a new service that will be created if the entry is not anymore there
 		delete(c.serviceBindings, skey)
-		c.Unlock()
+		c.mu.Unlock()
 	}
 
 	logrus.Debugf("rmServiceBinding from %s END for %s %s", method, svcName, eID)

+ 31 - 31
libnetwork/service_common_test.go

@@ -39,21 +39,21 @@ func TestCleanupServiceDiscovery(t *testing.T) {
 	n2.(*network).addSvcRecords("N2ep1", "service_test", "serviceID1", net.ParseIP("192.168.1.1"), net.IP{}, true, "test")
 	n2.(*network).addSvcRecords("N2ep2", "service_test", "serviceID2", net.ParseIP("192.168.1.2"), net.IP{}, true, "test")
 
-	if len(c.(*controller).svcRecords) != 2 {
-		t.Fatalf("Service record not added correctly:%v", c.(*controller).svcRecords)
+	if len(c.svcRecords) != 2 {
+		t.Fatalf("Service record not added correctly:%v", c.svcRecords)
 	}
 
 	// cleanup net1
-	c.(*controller).cleanupServiceDiscovery(n1.ID())
+	c.cleanupServiceDiscovery(n1.ID())
 
-	if len(c.(*controller).svcRecords) != 1 {
-		t.Fatalf("Service record not cleaned correctly:%v", c.(*controller).svcRecords)
+	if len(c.svcRecords) != 1 {
+		t.Fatalf("Service record not cleaned correctly:%v", c.svcRecords)
 	}
 
-	c.(*controller).cleanupServiceDiscovery("")
+	c.cleanupServiceDiscovery("")
 
-	if len(c.(*controller).svcRecords) != 0 {
-		t.Fatalf("Service record not cleaned correctly:%v", c.(*controller).svcRecords)
+	if len(c.svcRecords) != 0 {
+		t.Fatalf("Service record not cleaned correctly:%v", c.svcRecords)
 	}
 }
 
@@ -63,70 +63,70 @@ func TestDNSOptions(t *testing.T) {
 	c, err := New()
 	assert.NilError(t, err)
 
-	sb, err := c.(*controller).NewSandbox("cnt1", nil)
+	sb, err := c.NewSandbox("cnt1", nil)
 	assert.NilError(t, err)
 
-	cleanup := func(s Sandbox) {
+	cleanup := func(s *Sandbox) {
 		if err := s.Delete(); err != nil {
 			t.Error(err)
 		}
 	}
 
 	defer cleanup(sb)
-	sb.(*sandbox).startResolver(false)
+	sb.startResolver(false)
 
-	err = sb.(*sandbox).setupDNS()
+	err = sb.setupDNS()
 	assert.NilError(t, err)
-	err = sb.(*sandbox).rebuildDNS()
+	err = sb.rebuildDNS()
 	assert.NilError(t, err)
-	currRC, err := resolvconf.GetSpecific(sb.(*sandbox).config.resolvConfPath)
+	currRC, err := resolvconf.GetSpecific(sb.config.resolvConfPath)
 	assert.NilError(t, err)
 	dnsOptionsList := resolvconf.GetOptions(currRC.Content)
 	assert.Check(t, is.Len(dnsOptionsList, 1))
 	assert.Check(t, is.Equal("ndots:0", dnsOptionsList[0]))
 
-	sb.(*sandbox).config.dnsOptionsList = []string{"ndots:5"}
-	err = sb.(*sandbox).setupDNS()
+	sb.config.dnsOptionsList = []string{"ndots:5"}
+	err = sb.setupDNS()
 	assert.NilError(t, err)
-	currRC, err = resolvconf.GetSpecific(sb.(*sandbox).config.resolvConfPath)
+	currRC, err = resolvconf.GetSpecific(sb.config.resolvConfPath)
 	assert.NilError(t, err)
 	dnsOptionsList = resolvconf.GetOptions(currRC.Content)
 	assert.Check(t, is.Len(dnsOptionsList, 1))
 	assert.Check(t, is.Equal("ndots:5", dnsOptionsList[0]))
 
-	err = sb.(*sandbox).rebuildDNS()
+	err = sb.rebuildDNS()
 	assert.NilError(t, err)
-	currRC, err = resolvconf.GetSpecific(sb.(*sandbox).config.resolvConfPath)
+	currRC, err = resolvconf.GetSpecific(sb.config.resolvConfPath)
 	assert.NilError(t, err)
 	dnsOptionsList = resolvconf.GetOptions(currRC.Content)
 	assert.Check(t, is.Len(dnsOptionsList, 1))
 	assert.Check(t, is.Equal("ndots:5", dnsOptionsList[0]))
 
-	sb2, err := c.(*controller).NewSandbox("cnt2", nil)
+	sb2, err := c.NewSandbox("cnt2", nil)
 	assert.NilError(t, err)
 	defer cleanup(sb2)
-	sb2.(*sandbox).startResolver(false)
+	sb2.startResolver(false)
 
-	sb2.(*sandbox).config.dnsOptionsList = []string{"ndots:0"}
-	err = sb2.(*sandbox).setupDNS()
+	sb2.config.dnsOptionsList = []string{"ndots:0"}
+	err = sb2.setupDNS()
 	assert.NilError(t, err)
-	err = sb2.(*sandbox).rebuildDNS()
+	err = sb2.rebuildDNS()
 	assert.NilError(t, err)
-	currRC, err = resolvconf.GetSpecific(sb2.(*sandbox).config.resolvConfPath)
+	currRC, err = resolvconf.GetSpecific(sb2.config.resolvConfPath)
 	assert.NilError(t, err)
 	dnsOptionsList = resolvconf.GetOptions(currRC.Content)
 	assert.Check(t, is.Len(dnsOptionsList, 1))
 	assert.Check(t, is.Equal("ndots:0", dnsOptionsList[0]))
 
-	sb2.(*sandbox).config.dnsOptionsList = []string{"ndots:foobar"}
-	err = sb2.(*sandbox).setupDNS()
+	sb2.config.dnsOptionsList = []string{"ndots:foobar"}
+	err = sb2.setupDNS()
 	assert.NilError(t, err)
-	err = sb2.(*sandbox).rebuildDNS()
+	err = sb2.rebuildDNS()
 	assert.Error(t, err, "invalid number for ndots option: foobar")
 
-	sb2.(*sandbox).config.dnsOptionsList = []string{"ndots:-1"}
-	err = sb2.(*sandbox).setupDNS()
+	sb2.config.dnsOptionsList = []string{"ndots:-1"}
+	err = sb2.setupDNS()
 	assert.NilError(t, err)
-	err = sb2.(*sandbox).rebuildDNS()
+	err = sb2.rebuildDNS()
 	assert.Error(t, err, "invalid number for ndots option: -1")
 }

+ 7 - 7
libnetwork/service_linux.go

@@ -21,7 +21,7 @@ import (
 
 // Populate all loadbalancers on the network that the passed endpoint
 // belongs to, into this sandbox.
-func (sb *sandbox) populateLoadBalancers(ep *endpoint) {
+func (sb *Sandbox) populateLoadBalancers(ep *Endpoint) {
 	// This is an interface less endpoint. Nothing to do.
 	if ep.Iface() == nil {
 		return
@@ -37,14 +37,14 @@ func (sb *sandbox) populateLoadBalancers(ep *endpoint) {
 	}
 }
 
-func (n *network) findLBEndpointSandbox() (*endpoint, *sandbox, error) {
+func (n *network) findLBEndpointSandbox() (*Endpoint, *Sandbox, error) {
 	// TODO: get endpoint from store?  See EndpointInfo()
-	var ep *endpoint
+	var ep *Endpoint
 	// Find this node's LB sandbox endpoint:  there should be exactly one
 	for _, e := range n.Endpoints() {
 		epi := e.Info()
 		if epi != nil && epi.LoadBalancer() {
-			ep = e.(*endpoint)
+			ep = e
 			break
 		}
 	}
@@ -66,7 +66,7 @@ func (n *network) findLBEndpointSandbox() (*endpoint, *sandbox, error) {
 // Searches the OS sandbox for the name of the endpoint interface
 // within the sandbox.   This is required for adding/removing IP
 // aliases to the interface.
-func findIfaceDstName(sb *sandbox, ep *endpoint) string {
+func findIfaceDstName(sb *Sandbox, ep *Endpoint) string {
 	srcName := ep.Iface().SrcName()
 	for _, i := range sb.osSbox.Info().Interfaces() {
 		if i.SrcName() == srcName {
@@ -532,7 +532,7 @@ func plumbProxy(iPort *PortConfig, isDelete bool) error {
 
 // configureFWMark configures the sandbox firewall to mark vip destined packets
 // with the firewall mark fwMark.
-func (sb *sandbox) configureFWMark(vip net.IP, fwMark uint32, ingressPorts []*PortConfig, eIP *net.IPNet, isDelete bool, lbMode string) error {
+func (sb *Sandbox) configureFWMark(vip net.IP, fwMark uint32, ingressPorts []*PortConfig, eIP *net.IPNet, isDelete bool, lbMode string) error {
 	// TODO IPv6 support
 	iptable := iptables.GetIptable(iptables.IPv4)
 
@@ -585,7 +585,7 @@ func (sb *sandbox) configureFWMark(vip net.IP, fwMark uint32, ingressPorts []*Po
 	return innerErr
 }
 
-func (sb *sandbox) addRedirectRules(eIP *net.IPNet, ingressPorts []*PortConfig) error {
+func (sb *Sandbox) addRedirectRules(eIP *net.IPNet, ingressPorts []*PortConfig) error {
 	// TODO IPv6 support
 	iptable := iptables.GetIptable(iptables.IPv4)
 	ipAddr := eIP.IP.String()

+ 3 - 3
libnetwork/service_unsupported.go

@@ -8,14 +8,14 @@ import (
 	"net"
 )
 
-func (c *controller) cleanupServiceBindings(nid string) {
+func (c *Controller) cleanupServiceBindings(nid string) {
 }
 
-func (c *controller) addServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
+func (c *Controller) addServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
 	return fmt.Errorf("not supported")
 }
 
-func (c *controller) rmServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
+func (c *Controller) rmServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
 	return fmt.Errorf("not supported")
 }
 

+ 1 - 1
libnetwork/service_windows.go

@@ -161,7 +161,7 @@ func numEnabledBackends(lb *loadBalancer) int {
 	return nEnabled
 }
 
-func (sb *sandbox) populateLoadBalancers(ep *endpoint) {
+func (sb *Sandbox) populateLoadBalancers(ep *Endpoint) {
 }
 
 func arrangeIngressFilterRule() {

+ 60 - 60
libnetwork/store.go

@@ -13,29 +13,29 @@ func registerKVStores() {
 	boltdb.Register()
 }
 
-func (c *controller) initScopedStore(scope string, scfg *datastore.ScopeCfg) error {
+func (c *Controller) initScopedStore(scope string, scfg *datastore.ScopeCfg) error {
 	store, err := datastore.NewDataStore(scope, scfg)
 	if err != nil {
 		return err
 	}
-	c.Lock()
+	c.mu.Lock()
 	c.stores = append(c.stores, store)
-	c.Unlock()
+	c.mu.Unlock()
 
 	return nil
 }
 
-func (c *controller) initStores() error {
+func (c *Controller) initStores() error {
 	registerKVStores()
 
-	c.Lock()
+	c.mu.Lock()
 	if c.cfg == nil {
-		c.Unlock()
+		c.mu.Unlock()
 		return nil
 	}
 	scopeConfigs := c.cfg.Scopes
 	c.stores = nil
-	c.Unlock()
+	c.mu.Unlock()
 
 	for scope, scfg := range scopeConfigs {
 		if err := c.initScopedStore(scope, scfg); err != nil {
@@ -47,15 +47,15 @@ func (c *controller) initStores() error {
 	return nil
 }
 
-func (c *controller) closeStores() {
+func (c *Controller) closeStores() {
 	for _, store := range c.getStores() {
 		store.Close()
 	}
 }
 
-func (c *controller) getStore(scope string) datastore.DataStore {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) getStore(scope string) datastore.DataStore {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 
 	for _, store := range c.stores {
 		if store.Scope() == scope {
@@ -66,14 +66,14 @@ func (c *controller) getStore(scope string) datastore.DataStore {
 	return nil
 }
 
-func (c *controller) getStores() []datastore.DataStore {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) getStores() []datastore.DataStore {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 
 	return c.stores
 }
 
-func (c *controller) getNetworkFromStore(nid string) (*network, error) {
+func (c *Controller) getNetworkFromStore(nid string) (*network, error) {
 	for _, n := range c.getNetworksFromStore() {
 		if n.id == nid {
 			return n, nil
@@ -82,7 +82,7 @@ func (c *controller) getNetworkFromStore(nid string) (*network, error) {
 	return nil, ErrNoSuchNetwork(nid)
 }
 
-func (c *controller) getNetworksForScope(scope string) ([]*network, error) {
+func (c *Controller) getNetworksForScope(scope string) ([]*network, error) {
 	var nl []*network
 
 	store := c.getStore(scope)
@@ -118,7 +118,7 @@ func (c *controller) getNetworksForScope(scope string) ([]*network, error) {
 	return nl, nil
 }
 
-func (c *controller) getNetworksFromStore() []*network {
+func (c *Controller) getNetworksFromStore() []*network {
 	var nl []*network
 
 	for _, store := range c.getStores() {
@@ -138,7 +138,7 @@ func (c *controller) getNetworksFromStore() []*network {
 
 		for _, kvo := range kvol {
 			n := kvo.(*network)
-			n.Lock()
+			n.mu.Lock()
 			n.ctrlr = c
 			ec := &endpointCnt{n: n}
 			// Trim the leading & trailing "/" to make it consistent across all stores
@@ -150,7 +150,7 @@ func (c *controller) getNetworksFromStore() []*network {
 			if n.scope == "" {
 				n.scope = store.Scope()
 			}
-			n.Unlock()
+			n.mu.Unlock()
 			nl = append(nl, n)
 		}
 	}
@@ -158,10 +158,10 @@ func (c *controller) getNetworksFromStore() []*network {
 	return nl
 }
 
-func (n *network) getEndpointFromStore(eid string) (*endpoint, error) {
+func (n *network) getEndpointFromStore(eid string) (*Endpoint, error) {
 	var errors []string
 	for _, store := range n.ctrlr.getStores() {
-		ep := &endpoint{id: eid, network: n}
+		ep := &Endpoint{id: eid, network: n}
 		err := store.GetObject(datastore.Key(ep.Key()...), ep)
 		// Continue searching in the next store if the key is not found in this store
 		if err != nil {
@@ -176,12 +176,12 @@ func (n *network) getEndpointFromStore(eid string) (*endpoint, error) {
 	return nil, fmt.Errorf("could not find endpoint %s: %v", eid, errors)
 }
 
-func (n *network) getEndpointsFromStore() ([]*endpoint, error) {
-	var epl []*endpoint
+func (n *network) getEndpointsFromStore() ([]*Endpoint, error) {
+	var epl []*Endpoint
 
-	tmp := endpoint{network: n}
+	tmp := Endpoint{network: n}
 	for _, store := range n.getController().getStores() {
-		kvol, err := store.List(datastore.Key(tmp.KeyPrefix()...), &endpoint{network: n})
+		kvol, err := store.List(datastore.Key(tmp.KeyPrefix()...), &Endpoint{network: n})
 		// Continue searching in the next store if no keys found in this store
 		if err != nil {
 			if err != datastore.ErrKeyNotFound {
@@ -192,7 +192,7 @@ func (n *network) getEndpointsFromStore() ([]*endpoint, error) {
 		}
 
 		for _, kvo := range kvol {
-			ep := kvo.(*endpoint)
+			ep := kvo.(*Endpoint)
 			epl = append(epl, ep)
 		}
 	}
@@ -200,7 +200,7 @@ func (n *network) getEndpointsFromStore() ([]*endpoint, error) {
 	return epl, nil
 }
 
-func (c *controller) updateToStore(kvObject datastore.KVObject) error {
+func (c *Controller) updateToStore(kvObject datastore.KVObject) error {
 	cs := c.getStore(kvObject.DataScope())
 	if cs == nil {
 		return ErrDataStoreNotInitialized(kvObject.DataScope())
@@ -216,7 +216,7 @@ func (c *controller) updateToStore(kvObject datastore.KVObject) error {
 	return nil
 }
 
-func (c *controller) deleteFromStore(kvObject datastore.KVObject) error {
+func (c *Controller) deleteFromStore(kvObject datastore.KVObject) error {
 	cs := c.getStore(kvObject.DataScope())
 	if cs == nil {
 		return ErrDataStoreNotInitialized(kvObject.DataScope())
@@ -238,16 +238,16 @@ retry:
 }
 
 type netWatch struct {
-	localEps  map[string]*endpoint
-	remoteEps map[string]*endpoint
+	localEps  map[string]*Endpoint
+	remoteEps map[string]*Endpoint
 	stopCh    chan struct{}
 }
 
-func (c *controller) getLocalEps(nw *netWatch) []*endpoint {
-	c.Lock()
-	defer c.Unlock()
+func (c *Controller) getLocalEps(nw *netWatch) []*Endpoint {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 
-	var epl []*endpoint
+	var epl []*Endpoint
 	for _, ep := range nw.localEps {
 		epl = append(epl, ep)
 	}
@@ -255,15 +255,15 @@ func (c *controller) getLocalEps(nw *netWatch) []*endpoint {
 	return epl
 }
 
-func (c *controller) watchSvcRecord(ep *endpoint) {
+func (c *Controller) watchSvcRecord(ep *Endpoint) {
 	c.watchCh <- ep
 }
 
-func (c *controller) unWatchSvcRecord(ep *endpoint) {
+func (c *Controller) unWatchSvcRecord(ep *Endpoint) {
 	c.unWatchCh <- ep
 }
 
-func (c *controller) networkWatchLoop(nw *netWatch, ep *endpoint, ecCh <-chan datastore.KVObject) {
+func (c *Controller) networkWatchLoop(nw *netWatch, ep *Endpoint, ecCh <-chan datastore.KVObject) {
 	for {
 		select {
 		case <-nw.stopCh:
@@ -276,10 +276,10 @@ func (c *controller) networkWatchLoop(nw *netWatch, ep *endpoint, ecCh <-chan da
 				break
 			}
 
-			c.Lock()
-			var addEp []*endpoint
+			c.mu.Lock()
+			var addEp []*Endpoint
 
-			delEpMap := make(map[string]*endpoint)
+			delEpMap := make(map[string]*Endpoint)
 			renameEpMap := make(map[string]bool)
 			for k, v := range nw.remoteEps {
 				delEpMap[k] = v
@@ -315,7 +315,7 @@ func (c *controller) networkWatchLoop(nw *netWatch, ep *endpoint, ecCh <-chan da
 					delete(nw.remoteEps, lEp.ID())
 				}
 			}
-			c.Unlock()
+			c.mu.Unlock()
 
 			for _, lEp := range delEpMap {
 				ep.getNetwork().updateSvcRecord(lEp, c.getLocalEps(nw), false)
@@ -327,7 +327,7 @@ func (c *controller) networkWatchLoop(nw *netWatch, ep *endpoint, ecCh <-chan da
 	}
 }
 
-func (c *controller) processEndpointCreate(nmap map[string]*netWatch, ep *endpoint) {
+func (c *Controller) processEndpointCreate(nmap map[string]*netWatch, ep *Endpoint) {
 	n := ep.getNetwork()
 	if !c.isDistributedControl() && n.Scope() == datastore.SwarmScope && n.driverIsMultihost() {
 		return
@@ -336,28 +336,28 @@ func (c *controller) processEndpointCreate(nmap map[string]*netWatch, ep *endpoi
 	networkID := n.ID()
 	endpointID := ep.ID()
 
-	c.Lock()
+	c.mu.Lock()
 	nw, ok := nmap[networkID]
-	c.Unlock()
+	c.mu.Unlock()
 
 	if ok {
 		// Update the svc db for the local endpoint join right away
 		n.updateSvcRecord(ep, c.getLocalEps(nw), true)
 
-		c.Lock()
+		c.mu.Lock()
 		nw.localEps[endpointID] = ep
 
 		// If we had learned that from the kv store remove it
 		// from remote ep list now that we know that this is
 		// indeed a local endpoint
 		delete(nw.remoteEps, endpointID)
-		c.Unlock()
+		c.mu.Unlock()
 		return
 	}
 
 	nw = &netWatch{
-		localEps:  make(map[string]*endpoint),
-		remoteEps: make(map[string]*endpoint),
+		localEps:  make(map[string]*Endpoint),
+		remoteEps: make(map[string]*Endpoint),
 	}
 
 	// Update the svc db for the local endpoint join right away
@@ -365,11 +365,11 @@ func (c *controller) processEndpointCreate(nmap map[string]*netWatch, ep *endpoi
 	// try to update this ep's container's svc records
 	n.updateSvcRecord(ep, c.getLocalEps(nw), true)
 
-	c.Lock()
+	c.mu.Lock()
 	nw.localEps[endpointID] = ep
 	nmap[networkID] = nw
 	nw.stopCh = make(chan struct{})
-	c.Unlock()
+	c.mu.Unlock()
 
 	store := c.getStore(n.DataScope())
 	if store == nil {
@@ -389,7 +389,7 @@ func (c *controller) processEndpointCreate(nmap map[string]*netWatch, ep *endpoi
 	go c.networkWatchLoop(nw, ep, ch)
 }
 
-func (c *controller) processEndpointDelete(nmap map[string]*netWatch, ep *endpoint) {
+func (c *Controller) processEndpointDelete(nmap map[string]*netWatch, ep *Endpoint) {
 	n := ep.getNetwork()
 	if !c.isDistributedControl() && n.Scope() == datastore.SwarmScope && n.driverIsMultihost() {
 		return
@@ -398,19 +398,19 @@ func (c *controller) processEndpointDelete(nmap map[string]*netWatch, ep *endpoi
 	networkID := n.ID()
 	endpointID := ep.ID()
 
-	c.Lock()
+	c.mu.Lock()
 	nw, ok := nmap[networkID]
 
 	if ok {
 		delete(nw.localEps, endpointID)
-		c.Unlock()
+		c.mu.Unlock()
 
 		// Update the svc db about local endpoint leave right away
 		// Do this after we remove this ep from localEps so that we
 		// don't try to remove this svc record from this ep's container.
 		n.updateSvcRecord(ep, c.getLocalEps(nw), false)
 
-		c.Lock()
+		c.mu.Lock()
 		if len(nw.localEps) == 0 {
 			close(nw.stopCh)
 
@@ -421,10 +421,10 @@ func (c *controller) processEndpointDelete(nmap map[string]*netWatch, ep *endpoi
 			delete(nmap, networkID)
 		}
 	}
-	c.Unlock()
+	c.mu.Unlock()
 }
 
-func (c *controller) watchLoop() {
+func (c *Controller) watchLoop() {
 	for {
 		select {
 		case ep := <-c.watchCh:
@@ -435,18 +435,18 @@ func (c *controller) watchLoop() {
 	}
 }
 
-func (c *controller) startWatch() {
+func (c *Controller) startWatch() {
 	if c.watchCh != nil {
 		return
 	}
-	c.watchCh = make(chan *endpoint)
-	c.unWatchCh = make(chan *endpoint)
+	c.watchCh = make(chan *Endpoint)
+	c.unWatchCh = make(chan *Endpoint)
 	c.nmap = make(map[string]*netWatch)
 
 	go c.watchLoop()
 }
 
-func (c *controller) networkCleanup() {
+func (c *Controller) networkCleanup() {
 	for _, n := range c.getNetworksFromStore() {
 		if n.inDelete {
 			logrus.Infof("Removing stale network %s (%s)", n.Name(), n.ID())

+ 1 - 1
libnetwork/store_linux_test.go

@@ -30,7 +30,7 @@ func TestNoPersist(t *testing.T) {
 	if err != nil {
 		t.Fatalf("Error creating endpoint: %v", err)
 	}
-	store := ctrl.(*controller).getStore(datastore.LocalScope).KVStore()
+	store := ctrl.getStore(datastore.LocalScope).KVStore()
 	if exists, _ := store.Exists(datastore.Key(datastore.NetworkKeyPrefix, nw.ID())); exists {
 		t.Fatalf("Network with persist=false should not be stored in KV Store")
 	}

+ 1 - 1
libnetwork/store_test.go

@@ -36,7 +36,7 @@ func testLocalBackend(t *testing.T, provider, url string, storeConfig *store.Con
 	if err != nil {
 		t.Fatalf("Error creating endpoint: %v", err)
 	}
-	store := ctrl.(*controller).getStore(datastore.LocalScope).KVStore()
+	store := ctrl.getStore(datastore.LocalScope).KVStore()
 	if exists, err := store.Exists(datastore.Key(datastore.NetworkKeyPrefix, nw.ID())); !exists || err != nil {
 		t.Fatalf("Network key should have been created.")
 	}