浏览代码

Update resolvconf and iptables packages from docker

Updated resolvconf and iptables packages based on upstream
changes which we need for libnetwork rebase. There were
docker engine changes based on this so we need this to
be integrated now.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Jana Radhakrishnan 10 年之前
父节点
当前提交
26a5a79374

+ 7 - 11
libnetwork/pkg/iptables/firewalld.go

@@ -38,19 +38,18 @@ var (
 )
 )
 
 
 // FirewalldInit initializes firewalld management code.
 // FirewalldInit initializes firewalld management code.
-func FirewalldInit() {
+func FirewalldInit() error {
 	var err error
 	var err error
 
 
-	connection, err = newConnection()
-
-	if err != nil {
-		logrus.Errorf("Failed to connect to D-Bus system bus: %s", err)
+	if connection, err = newConnection(); err != nil {
+		return fmt.Errorf("Failed to connect to D-Bus system bus: %v", err)
 	}
 	}
 	if connection != nil {
 	if connection != nil {
 		go signalHandler()
 		go signalHandler()
 	}
 	}
 
 
 	firewalldRunning = checkRunning()
 	firewalldRunning = checkRunning()
+	return nil
 }
 }
 
 
 // New() establishes a connection to the system bus.
 // New() establishes a connection to the system bus.
@@ -151,7 +150,6 @@ func checkRunning() bool {
 		logrus.Infof("Firewalld running: %t", err == nil)
 		logrus.Infof("Firewalld running: %t", err == nil)
 		return err == nil
 		return err == nil
 	}
 	}
-	logrus.Info("Firewalld not running")
 	return false
 	return false
 }
 }
 
 
@@ -160,10 +158,8 @@ func Passthrough(ipv IPV, args ...string) ([]byte, error) {
 	var output string
 	var output string
 
 
 	logrus.Debugf("Firewalld passthrough: %s, %s", ipv, args)
 	logrus.Debugf("Firewalld passthrough: %s, %s", ipv, args)
-	err := connection.sysobj.Call(dbusInterface+".direct.passthrough", 0, ipv, args).Store(&output)
-	if output != "" {
-		logrus.Debugf("passthrough output: %s", output)
+	if err := connection.sysobj.Call(dbusInterface+".direct.passthrough", 0, ipv, args).Store(&output); err != nil {
+		return nil, err
 	}
 	}
-
-	return []byte(output), err
+	return []byte(output), nil
 }
 }

+ 6 - 0
libnetwork/pkg/iptables/iptables.go

@@ -8,6 +8,7 @@ import (
 	"regexp"
 	"regexp"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
+	"sync"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 )
 )
@@ -36,6 +37,8 @@ const (
 var (
 var (
 	iptablesPath  string
 	iptablesPath  string
 	supportsXlock = false
 	supportsXlock = false
+	// used to lock iptables commands if xtables lock is not supported
+	bestEffortLock sync.Mutex
 	//ErrIptablesNotFound is returned when the rule is not found.
 	//ErrIptablesNotFound is returned when the rule is not found.
 	ErrIptablesNotFound = errors.New("Iptables not found")
 	ErrIptablesNotFound = errors.New("Iptables not found")
 )
 )
@@ -303,6 +306,9 @@ func Raw(args ...string) ([]byte, error) {
 	}
 	}
 	if supportsXlock {
 	if supportsXlock {
 		args = append([]string{"--wait"}, args...)
 		args = append([]string{"--wait"}, args...)
+	} else {
+		bestEffortLock.Lock()
+		defer bestEffortLock.Unlock()
 	}
 	}
 
 
 	logrus.Debugf("%s, %v", iptablesPath, args)
 	logrus.Debugf("%s, %v", iptablesPath, args)

+ 40 - 0
libnetwork/pkg/iptables/iptables_test.go

@@ -5,6 +5,7 @@ import (
 	"os/exec"
 	"os/exec"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
+	"sync"
 	"testing"
 	"testing"
 
 
 	_ "github.com/docker/libnetwork/netutils"
 	_ "github.com/docker/libnetwork/netutils"
@@ -171,6 +172,45 @@ func TestOutput(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestConcurrencyWithWait(t *testing.T) {
+	RunConcurrencyTest(t, true)
+}
+
+func TestConcurrencyNoWait(t *testing.T) {
+	RunConcurrencyTest(t, false)
+}
+
+// Runs 10 concurrent rule additions. This will fail if iptables
+// is actually invoked simultaneously without --wait.
+// Note that if iptables does not support the xtable lock on this
+// system, then allowXlock has no effect -- it will always be off.
+func RunConcurrencyTest(t *testing.T, allowXlock bool) {
+	var wg sync.WaitGroup
+
+	if !allowXlock && supportsXlock {
+		supportsXlock = false
+		defer func() { supportsXlock = true }()
+	}
+
+	ip := net.ParseIP("192.168.1.1")
+	port := 1234
+	dstAddr := "172.17.0.1"
+	dstPort := 4321
+	proto := "tcp"
+
+	for i := 0; i < 10; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			err := natChain.Forward(Append, ip, port, proto, dstAddr, dstPort)
+			if err != nil {
+				t.Fatal(err)
+			}
+		}()
+	}
+	wg.Wait()
+}
+
 func TestCleanup(t *testing.T) {
 func TestCleanup(t *testing.T) {
 	var err error
 	var err error
 	var rules []byte
 	var rules []byte

+ 17 - 0
libnetwork/pkg/resolvconf/dns/resolvconf.go

@@ -0,0 +1,17 @@
+package dns
+
+import (
+	"regexp"
+)
+
+// IPLocalhost is a regex patter for localhost IP address range.
+const IPLocalhost = `((127\.([0-9]{1,3}.){2}[0-9]{1,3})|(::1))`
+
+var localhostIPRegexp = regexp.MustCompile(IPLocalhost)
+
+// IsLocalhost returns true if ip matches the localhost IP regular expression.
+// Used for determining if nameserver settings are being passed which are
+// localhost addresses
+func IsLocalhost(ip string) bool {
+	return localhostIPRegexp.MatchString(ip)
+}

+ 2 - 10
libnetwork/pkg/resolvconf/resolvconf.go

@@ -10,6 +10,7 @@ import (
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/ioutils"
+	"github.com/docker/libnetwork/pkg/resolvconf/dns"
 )
 )
 
 
 var (
 var (
@@ -24,10 +25,8 @@ var (
 	// For readability and sufficiency for Docker purposes this seemed more reasonable than a
 	// For readability and sufficiency for Docker purposes this seemed more reasonable than a
 	// 1000+ character regexp with exact and complete IPv6 validation
 	// 1000+ character regexp with exact and complete IPv6 validation
 	ipv6Address = `([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})`
 	ipv6Address = `([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})`
-	ipLocalhost = `((127\.([0-9]{1,3}.){2}[0-9]{1,3})|(::1))`
 
 
-	localhostIPRegexp = regexp.MustCompile(ipLocalhost)
-	localhostNSRegexp = regexp.MustCompile(`(?m)^nameserver\s+` + ipLocalhost + `\s*\n*`)
+	localhostNSRegexp = regexp.MustCompile(`(?m)^nameserver\s+` + dns.IPLocalhost + `\s*\n*`)
 	nsIPv6Regexp      = regexp.MustCompile(`(?m)^nameserver\s+` + ipv6Address + `\s*\n*`)
 	nsIPv6Regexp      = regexp.MustCompile(`(?m)^nameserver\s+` + ipv6Address + `\s*\n*`)
 	nsRegexp          = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `)|(` + ipv6Address + `))\s*$`)
 	nsRegexp          = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `)|(` + ipv6Address + `))\s*$`)
 	searchRegexp      = regexp.MustCompile(`^\s*search\s*(([^\s]+\s*)*)$`)
 	searchRegexp      = regexp.MustCompile(`^\s*search\s*(([^\s]+\s*)*)$`)
@@ -128,13 +127,6 @@ func getLines(input []byte, commentMarker []byte) [][]byte {
 	return output
 	return output
 }
 }
 
 
-// IsLocalhost returns true if ip matches the localhost IP regular expression.
-// Used for determining if nameserver settings are being passed which are
-// localhost addresses
-func IsLocalhost(ip string) bool {
-	return localhostIPRegexp.MatchString(ip)
-}
-
 // GetNameservers returns nameservers (if any) listed in /etc/resolv.conf
 // GetNameservers returns nameservers (if any) listed in /etc/resolv.conf
 func GetNameservers(resolvConf []byte) []string {
 func GetNameservers(resolvConf []byte) []string {
 	nameservers := []string{}
 	nameservers := []string{}