浏览代码

libnetwork: fix sandbox restore

The method to restore a network namespace takes a collection of
interfaces to restore with the options to apply. The interface names are
structured data, tuples of (SrcName, DstPrefix) but for whatever reason
are being passed into Restore() serialized to strings. A refactor,
f0be4d126dacb19a35046536b041a5989ff0dc95, accidentally broke the
serialization by dropping the delimiter. Rather than fix the
serialization and leave the time-bomb for someone else to trip over,
pass the interface names as structured data.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 50eb2d27821df9ec19218c325534ae42d63016aa)
Signed-off-by: Cory Snider <csnider@mirantis.com>
Cory Snider 2 年之前
父节点
当前提交
3452a76589
共有 3 个文件被更改,包括 12 次插入14 次删除
  1. 5 11
      libnetwork/osl/namespace_linux.go
  2. 5 1
      libnetwork/osl/sandbox.go
  3. 2 2
      libnetwork/sandbox.go

+ 5 - 11
libnetwork/osl/namespace_linux.go

@@ -470,16 +470,10 @@ func (n *networkNamespace) Destroy() error {
 }
 
 // Restore restore the network namespace
-func (n *networkNamespace) Restore(ifsopt map[string][]IfaceOption, routes []*types.StaticRoute, gw net.IP, gw6 net.IP) error {
+func (n *networkNamespace) Restore(ifsopt map[Iface][]IfaceOption, routes []*types.StaticRoute, gw net.IP, gw6 net.IP) error {
 	// restore interfaces
 	for name, opts := range ifsopt {
-		if !strings.Contains(name, "+") {
-			return fmt.Errorf("wrong iface name in restore osl sandbox interface: %s", name)
-		}
-		seps := strings.Split(name, "+")
-		srcName := seps[0]
-		dstPrefix := seps[1]
-		i := &nwIface{srcName: srcName, dstName: dstPrefix, ns: n}
+		i := &nwIface{srcName: name.SrcName, dstName: name.DstPrefix, ns: n}
 		i.processInterfaceOptions(opts...)
 		if i.master != "" {
 			i.dstMaster = n.findDst(i.master, true)
@@ -531,7 +525,7 @@ func (n *networkNamespace) Restore(ifsopt map[string][]IfaceOption, routes []*ty
 			}
 
 			var index int
-			indexStr := strings.TrimPrefix(i.dstName, dstPrefix)
+			indexStr := strings.TrimPrefix(i.dstName, name.DstPrefix)
 			if indexStr != "" {
 				index, err = strconv.Atoi(indexStr)
 				if err != nil {
@@ -540,8 +534,8 @@ func (n *networkNamespace) Restore(ifsopt map[string][]IfaceOption, routes []*ty
 			}
 			index++
 			n.Lock()
-			if index > n.nextIfIndex[dstPrefix] {
-				n.nextIfIndex[dstPrefix] = index
+			if index > n.nextIfIndex[name.DstPrefix] {
+				n.nextIfIndex[name.DstPrefix] = index
 			}
 			n.iFaces = append(n.iFaces, i)
 			n.Unlock()

+ 5 - 1
libnetwork/osl/sandbox.go

@@ -17,6 +17,10 @@ const (
 	SandboxTypeLoadBalancer = iota
 )
 
+type Iface struct {
+	SrcName, DstPrefix string
+}
+
 // IfaceOption is a function option type to set interface options.
 type IfaceOption func(i *nwIface)
 
@@ -89,7 +93,7 @@ type Sandbox interface {
 	Destroy() error
 
 	// Restore restores the sandbox.
-	Restore(ifsopt map[string][]IfaceOption, routes []*types.StaticRoute, gw net.IP, gw6 net.IP) error
+	Restore(ifsopt map[Iface][]IfaceOption, routes []*types.StaticRoute, gw net.IP, gw6 net.IP) error
 
 	// ApplyOSTweaks applies operating system specific knobs on the sandbox.
 	ApplyOSTweaks([]SandboxType)

+ 2 - 2
libnetwork/sandbox.go

@@ -765,7 +765,7 @@ func (sb *Sandbox) restoreOslSandbox() error {
 	var routes []*types.StaticRoute
 
 	// restore osl sandbox
-	Ifaces := make(map[string][]osl.IfaceOption)
+	Ifaces := make(map[osl.Iface][]osl.IfaceOption)
 	for _, ep := range sb.endpoints {
 		ep.mu.Lock()
 		joinInfo := ep.joinInfo
@@ -790,7 +790,7 @@ func (sb *Sandbox) restoreOslSandbox() error {
 		if len(i.llAddrs) != 0 {
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
 		}
-		Ifaces[i.srcName+i.dstPrefix] = ifaceOptions
+		Ifaces[osl.Iface{SrcName: i.srcName, DstPrefix: i.dstPrefix}] = ifaceOptions
 		if joinInfo != nil {
 			routes = append(routes, joinInfo.StaticRoutes...)
 		}