libnetwork: don't embed mutex in endpoint

Embedded structs are part of the exported surface of a struct type.
Boxing a struct value into an interface value does not erase that;
any code could gain access to the embedded struct value with a simple
type assertion. The mutex is supposed to be a private implementation
detail, but *endpoint implements sync.Locker because the mutex is
embedded. Change the mutex to an unexported field so *endpoint no
longer spuriously implements the sync.Locker interface.

Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
Cory Snider 2023-01-11 17:51:59 -05:00
parent 0e91d2e0e9
commit 581f005aad
3 changed files with 93 additions and 93 deletions

View file

@ -72,12 +72,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()
ep.mu.Lock()
defer ep.mu.Unlock()
epMap := make(map[string]interface{})
epMap["name"] = ep.name
@ -103,8 +103,8 @@ func (ep *endpoint) MarshalJSON() ([]byte, error) {
}
func (ep *endpoint) UnmarshalJSON(b []byte) (err error) {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
var epMap map[string]interface{}
if err := json.Unmarshal(b, &epMap); err != nil {
@ -226,8 +226,8 @@ func (ep *endpoint) New() datastore.KVObject {
}
func (ep *endpoint) CopyTo(o datastore.KVObject) error {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
dstEp := o.(*endpoint)
dstEp.name = ep.name
@ -277,22 +277,22 @@ func (ep *endpoint) CopyTo(o datastore.KVObject) error {
}
func (ep *endpoint) ID() string {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
return ep.id
}
func (ep *endpoint) Name() string {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
return ep.name
}
func (ep *endpoint) MyAliases() []string {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
return ep.myAliases
}
@ -306,35 +306,35 @@ func (ep *endpoint) Network() string {
}
func (ep *endpoint) isAnonymous() bool {
ep.Lock()
defer ep.Unlock()
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()
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()
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()
ep.mu.Lock()
defer ep.mu.Unlock()
ep.serviceEnabled = false
}
func (ep *endpoint) needResolver() bool {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
return !ep.disableResolution
}
@ -368,21 +368,21 @@ func (ep *endpoint) SetValue(value []byte) error {
}
func (ep *endpoint) Index() uint64 {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
return ep.dbIndex
}
func (ep *endpoint) SetIndex(index uint64) {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
ep.dbIndex = index
ep.dbExists = true
}
func (ep *endpoint) Exists() bool {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
return ep.dbExists
}
@ -391,8 +391,8 @@ func (ep *endpoint) Skip() bool {
}
func (ep *endpoint) processOptions(options ...EndpointOption) {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
for _, opt := range options {
if opt != nil {
@ -402,8 +402,8 @@ func (ep *endpoint) processOptions(options ...EndpointOption) {
}
func (ep *endpoint) getNetwork() *network {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
return ep.network
}
@ -438,21 +438,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()
}
}()
@ -670,8 +670,8 @@ func (ep *endpoint) rename(name string) error {
}
func (ep *endpoint) hasInterface(iName string) bool {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
return ep.iface != nil && ep.iface.srcName == iName
}
@ -698,9 +698,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")
@ -716,10 +716,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()
@ -807,11 +807,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 {
@ -854,11 +854,11 @@ func (ep *endpoint) Delete(force bool) error {
}
func (ep *endpoint) deleteEndpoint(force bool) error {
ep.Lock()
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 {
@ -884,9 +884,9 @@ func (ep *endpoint) deleteEndpoint(force bool) error {
func (ep *endpoint) getSandbox() (*Sandbox, bool) {
c := ep.network.getController()
ep.Lock()
ep.mu.Lock()
sid := ep.sandboxID
ep.Unlock()
ep.mu.Unlock()
c.mu.Lock()
ps, ok := c.sandboxes[sid]
@ -896,8 +896,8 @@ func (ep *endpoint) getSandbox() (*Sandbox, bool) {
}
func (ep *endpoint) getFirstInterfaceIPv4Address() net.IP {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
if ep.iface.addr != nil {
return ep.iface.addr.IP
@ -907,8 +907,8 @@ func (ep *endpoint) getFirstInterfaceIPv4Address() net.IP {
}
func (ep *endpoint) getFirstInterfaceIPv6Address() net.IP {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
if ep.iface.addrv6 != nil {
return ep.iface.addrv6.IP
@ -1120,10 +1120,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 {

View file

@ -212,8 +212,8 @@ func (ep *endpoint) Info() EndpointInfo {
}
func (ep *endpoint) Iface() InterfaceInfo {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
if ep.iface != nil {
return ep.iface
@ -223,8 +223,8 @@ func (ep *endpoint) Iface() InterfaceInfo {
}
func (ep *endpoint) Interface() driverapi.InterfaceInfo {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
if ep.iface != nil {
return ep.iface
@ -289,8 +289,8 @@ func (epi *endpointInterface) SetNames(srcName string, dstPrefix string) error {
}
func (ep *endpoint) InterfaceName() driverapi.InterfaceNameInfo {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
if ep.iface != nil {
return ep.iface
@ -300,8 +300,8 @@ func (ep *endpoint) InterfaceName() driverapi.InterfaceNameInfo {
}
func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
r := types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop}
@ -316,8 +316,8 @@ func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHo
}
func (ep *endpoint) AddTableEntry(tableName, key string, value []byte) error {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
ep.joinInfo.driverTableEntries = append(ep.joinInfo.driverTableEntries, &tableEntry{
tableName: tableName,
@ -337,14 +337,14 @@ func (ep *endpoint) Sandbox() *Sandbox {
}
func (ep *endpoint) LoadBalancer() bool {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
return ep.loadBalancer
}
func (ep *endpoint) StaticRoutes() []*types.StaticRoute {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
if ep.joinInfo == nil {
return nil
@ -354,8 +354,8 @@ func (ep *endpoint) StaticRoutes() []*types.StaticRoute {
}
func (ep *endpoint) Gateway() net.IP {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
if ep.joinInfo == nil {
return net.IP{}
@ -365,8 +365,8 @@ func (ep *endpoint) Gateway() net.IP {
}
func (ep *endpoint) GatewayIPv6() net.IP {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
if ep.joinInfo == nil {
return net.IP{}
@ -376,16 +376,16 @@ func (ep *endpoint) GatewayIPv6() net.IP {
}
func (ep *endpoint) SetGateway(gw net.IP) error {
ep.Lock()
defer ep.Unlock()
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()
ep.mu.Lock()
defer ep.mu.Unlock()
ep.joinInfo.gw6 = types.GetIPCopy(gw6)
return nil
@ -400,8 +400,8 @@ func (ep *endpoint) retrieveFromStore() (*endpoint, error) {
}
func (ep *endpoint) DisableGatewayService() {
ep.Lock()
defer ep.Unlock()
ep.mu.Lock()
defer ep.mu.Unlock()
ep.joinInfo.disableGatewayService = true
}

View file

@ -395,9 +395,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)
@ -585,21 +585,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)
@ -728,11 +728,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)}
@ -778,10 +778,10 @@ func (sb *Sandbox) restoreOslSandbox() error {
// 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())
@ -828,11 +828,11 @@ func (sb *Sandbox) populateNetworkResources(ep *endpoint) error {
inDelete := sb.inDelete
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)