Browse code

Vendoring in libnetwork to fix #13873.

Libnetwork sha# e578e95aa101441481411ff1d620f343895f24fe

Signed-off-by: Madhu Venugopal <madhu@docker.com>

Madhu Venugopal authored on 2015/06/12 10:04:03
Showing 4 changed files
... ...
@@ -17,7 +17,7 @@ clone hg code.google.com/p/go.net 84a4013f96e0
17 17
 clone hg code.google.com/p/gosqlite 74691fb6f837
18 18
 
19 19
 #get libnetwork packages
20
-clone git github.com/docker/libnetwork 90638ec9cf7fa7b7f5d0e96b0854f136d66bff92
20
+clone git github.com/docker/libnetwork e578e95aa101441481411ff1d620f343895f24fe
21 21
 clone git github.com/vishvananda/netns 5478c060110032f972e86a1f844fdb9a2f008f2c
22 22
 clone git github.com/vishvananda/netlink 8eb64238879fed52fd51c5b30ad20b928fb4c36c
23 23
 
... ...
@@ -98,3 +98,20 @@ func (s *DockerSuite) TestNetworkLocalhostTCPNat(c *check.C) {
98 98
 		c.Fatalf("Expected message %q but received %q", msg, final)
99 99
 	}
100 100
 }
101
+
102
+func (s *DockerSuite) TestNetworkLoopbackNat(c *check.C) {
103
+	testRequires(c, SameHostDaemon, NativeExecDriver)
104
+	msg := "it works"
105
+	startServerContainer(c, msg, 8080)
106
+	endpoint := getExternalAddress(c)
107
+	runCmd := exec.Command(dockerBinary, "run", "-t", "--net=container:server", "busybox",
108
+		"sh", "-c", fmt.Sprintf("stty raw && nc -w 5 %s 8080", endpoint.String()))
109
+	out, _, err := runCommandWithOutput(runCmd)
110
+	if err != nil {
111
+		c.Fatal(out, err)
112
+	}
113
+	final := strings.TrimRight(string(out), "\n")
114
+	if final != msg {
115
+		c.Fatalf("Expected message %q but received %q", msg, final)
116
+	}
117
+}
... ...
@@ -516,6 +516,13 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
516 516
 		return err
517 517
 	}
518 518
 
519
+	if !config.EnableUserlandProxy {
520
+		err = netlink.LinkSetHairpin(host, true)
521
+		if err != nil {
522
+			return err
523
+		}
524
+	}
525
+
519 526
 	// v4 address for the sandbox side pipe interface
520 527
 	ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, nil)
521 528
 	if err != nil {
... ...
@@ -44,9 +44,10 @@ var (
44 44
 
45 45
 // Chain defines the iptables chain.
46 46
 type Chain struct {
47
-	Name   string
48
-	Bridge string
49
-	Table  Table
47
+	Name        string
48
+	Bridge      string
49
+	Table       Table
50
+	HairpinMode bool
50 51
 }
51 52
 
52 53
 // ChainError is returned to represent errors during ip table operation.
... ...
@@ -75,9 +76,10 @@ func initCheck() error {
75 75
 // NewChain adds a new chain to ip table.
76 76
 func NewChain(name, bridge string, table Table, hairpinMode bool) (*Chain, error) {
77 77
 	c := &Chain{
78
-		Name:   name,
79
-		Bridge: bridge,
80
-		Table:  table,
78
+		Name:        name,
79
+		Bridge:      bridge,
80
+		Table:       table,
81
+		HairpinMode: hairpinMode,
81 82
 	}
82 83
 
83 84
 	if string(c.Table) == "" {
... ...
@@ -151,12 +153,16 @@ func (c *Chain) Forward(action Action, ip net.IP, port int, proto, destAddr stri
151 151
 		// value" by both iptables and ip6tables.
152 152
 		daddr = "0/0"
153 153
 	}
154
-	if output, err := Raw("-t", string(Nat), string(action), c.Name,
154
+	args := []string{"-t", string(Nat), string(action), c.Name,
155 155
 		"-p", proto,
156 156
 		"-d", daddr,
157 157
 		"--dport", strconv.Itoa(port),
158 158
 		"-j", "DNAT",
159
-		"--to-destination", net.JoinHostPort(destAddr, strconv.Itoa(destPort))); err != nil {
159
+		"--to-destination", net.JoinHostPort(destAddr, strconv.Itoa(destPort))}
160
+	if !c.HairpinMode {
161
+		args = append(args, "!", "-i", c.Bridge)
162
+	}
163
+	if output, err := Raw(args...); err != nil {
160 164
 		return err
161 165
 	} else if len(output) != 0 {
162 166
 		return ChainError{Chain: "FORWARD", Output: output}