Moves two config options, namely EnableIPTables and EnableUserlandProxy
from networks to the driver.
Closes #242
Signed-off-by: Mohammad Banikazemi <MBanikazemi@gmail.com>
| ... | ... |
@@ -1680,6 +1680,11 @@ func TestHttpHandlerUninit(t *testing.T) {
|
| 1680 | 1680 |
t.Fatal(err) |
| 1681 | 1681 |
} |
| 1682 | 1682 |
|
| 1683 |
+ err = c.ConfigureNetworkDriver(bridgeNetType, nil) |
|
| 1684 |
+ if err != nil {
|
|
| 1685 |
+ t.Fatal(err) |
|
| 1686 |
+ } |
|
| 1687 |
+ |
|
| 1683 | 1688 |
h := &httpHandler{c: c}
|
| 1684 | 1689 |
h.initRouter() |
| 1685 | 1690 |
if h.r == nil {
|
| ... | ... |
@@ -1777,6 +1782,11 @@ func TestEndToEnd(t *testing.T) {
|
| 1777 | 1777 |
if err != nil {
|
| 1778 | 1778 |
t.Fatal(err) |
| 1779 | 1779 |
} |
| 1780 |
+ err = c.ConfigureNetworkDriver(bridgeNetType, nil) |
|
| 1781 |
+ if err != nil {
|
|
| 1782 |
+ t.Fatal(err) |
|
| 1783 |
+ } |
|
| 1784 |
+ |
|
| 1780 | 1785 |
handleRequest := NewHTTPHandler(c) |
| 1781 | 1786 |
|
| 1782 | 1787 |
ops := options.Generic{
|
| ... | ... |
@@ -40,7 +40,9 @@ var ( |
| 40 | 40 |
|
| 41 | 41 |
// configuration info for the "bridge" driver. |
| 42 | 42 |
type configuration struct {
|
| 43 |
- EnableIPForwarding bool |
|
| 43 |
+ EnableIPForwarding bool |
|
| 44 |
+ EnableIPTables bool |
|
| 45 |
+ EnableUserlandProxy bool |
|
| 44 | 46 |
} |
| 45 | 47 |
|
| 46 | 48 |
// networkConfiguration for network specific configuration |
| ... | ... |
@@ -50,7 +52,6 @@ type networkConfiguration struct {
|
| 50 | 50 |
FixedCIDR *net.IPNet |
| 51 | 51 |
FixedCIDRv6 *net.IPNet |
| 52 | 52 |
EnableIPv6 bool |
| 53 |
- EnableIPTables bool |
|
| 54 | 53 |
EnableIPMasquerade bool |
| 55 | 54 |
EnableICC bool |
| 56 | 55 |
Mtu int |
| ... | ... |
@@ -58,7 +59,6 @@ type networkConfiguration struct {
|
| 58 | 58 |
DefaultGatewayIPv6 net.IP |
| 59 | 59 |
DefaultBindingIP net.IP |
| 60 | 60 |
AllowNonDefaultBridge bool |
| 61 |
- EnableUserlandProxy bool |
|
| 62 | 61 |
} |
| 63 | 62 |
|
| 64 | 63 |
// endpointConfiguration represents the user specified configuration for the sandbox endpoint |
| ... | ... |
@@ -91,13 +91,16 @@ type bridgeNetwork struct {
|
| 91 | 91 |
config *networkConfiguration |
| 92 | 92 |
endpoints map[types.UUID]*bridgeEndpoint // key: endpoint id |
| 93 | 93 |
portMapper *portmapper.PortMapper |
| 94 |
+ driver *driver // The network's driver |
|
| 94 | 95 |
sync.Mutex |
| 95 | 96 |
} |
| 96 | 97 |
|
| 97 | 98 |
type driver struct {
|
| 98 |
- config *configuration |
|
| 99 |
- network *bridgeNetwork |
|
| 100 |
- networks map[types.UUID]*bridgeNetwork |
|
| 99 |
+ config *configuration |
|
| 100 |
+ network *bridgeNetwork |
|
| 101 |
+ natChain *iptables.ChainInfo |
|
| 102 |
+ filterChain *iptables.ChainInfo |
|
| 103 |
+ networks map[types.UUID]*bridgeNetwork |
|
| 101 | 104 |
sync.Mutex |
| 102 | 105 |
} |
| 103 | 106 |
|
| ... | ... |
@@ -223,16 +226,6 @@ func (c *networkConfiguration) fromMap(data map[string]interface{}) error {
|
| 223 | 223 |
} |
| 224 | 224 |
} |
| 225 | 225 |
|
| 226 |
- if i, ok := data["EnableIPTables"]; ok && i != nil {
|
|
| 227 |
- if s, ok := i.(string); ok {
|
|
| 228 |
- if c.EnableIPTables, err = strconv.ParseBool(s); err != nil {
|
|
| 229 |
- return types.BadRequestErrorf("failed to parse EnableIPTables value: %s", err.Error())
|
|
| 230 |
- } |
|
| 231 |
- } else {
|
|
| 232 |
- return types.BadRequestErrorf("invalid type for EnableIPTables value")
|
|
| 233 |
- } |
|
| 234 |
- } |
|
| 235 |
- |
|
| 236 | 226 |
if i, ok := data["EnableIPMasquerade"]; ok && i != nil {
|
| 237 | 227 |
if s, ok := i.(string); ok {
|
| 238 | 228 |
if c.EnableIPMasquerade, err = strconv.ParseBool(s); err != nil {
|
| ... | ... |
@@ -334,6 +327,25 @@ func (c *networkConfiguration) fromMap(data map[string]interface{}) error {
|
| 334 | 334 |
return nil |
| 335 | 335 |
} |
| 336 | 336 |
|
| 337 |
+func (n *bridgeNetwork) getDriverChains() (*iptables.ChainInfo, *iptables.ChainInfo, error) {
|
|
| 338 |
+ n.Lock() |
|
| 339 |
+ defer n.Unlock() |
|
| 340 |
+ |
|
| 341 |
+ if n.driver == nil {
|
|
| 342 |
+ return nil, nil, types.BadRequestErrorf("no driver found")
|
|
| 343 |
+ } |
|
| 344 |
+ |
|
| 345 |
+ return n.driver.natChain, n.driver.filterChain, nil |
|
| 346 |
+} |
|
| 347 |
+ |
|
| 348 |
+func (n *bridgeNetwork) getNetworkBridgeName() string {
|
|
| 349 |
+ n.Lock() |
|
| 350 |
+ config := n.config |
|
| 351 |
+ n.Unlock() |
|
| 352 |
+ |
|
| 353 |
+ return config.BridgeName |
|
| 354 |
+} |
|
| 355 |
+ |
|
| 337 | 356 |
func (n *bridgeNetwork) getEndpoint(eid types.UUID) (*bridgeEndpoint, error) {
|
| 338 | 357 |
n.Lock() |
| 339 | 358 |
defer n.Unlock() |
| ... | ... |
@@ -418,6 +430,7 @@ func (c *networkConfiguration) conflictsWithNetworks(id types.UUID, others []*br |
| 418 | 418 |
|
| 419 | 419 |
func (d *driver) Config(option map[string]interface{}) error {
|
| 420 | 420 |
var config *configuration |
| 421 |
+ var err error |
|
| 421 | 422 |
|
| 422 | 423 |
d.Lock() |
| 423 | 424 |
defer d.Unlock() |
| ... | ... |
@@ -444,10 +457,19 @@ func (d *driver) Config(option map[string]interface{}) error {
|
| 444 | 444 |
d.config = config |
| 445 | 445 |
} else {
|
| 446 | 446 |
config = &configuration{}
|
| 447 |
+ d.config = config |
|
| 447 | 448 |
} |
| 448 | 449 |
|
| 449 | 450 |
if config.EnableIPForwarding {
|
| 450 |
- return setupIPForwarding() |
|
| 451 |
+ err = setupIPForwarding() |
|
| 452 |
+ if err != nil {
|
|
| 453 |
+ return err |
|
| 454 |
+ } |
|
| 455 |
+ } |
|
| 456 |
+ |
|
| 457 |
+ if config.EnableIPTables {
|
|
| 458 |
+ d.natChain, d.filterChain, err = setupIPChains(config) |
|
| 459 |
+ return err |
|
| 451 | 460 |
} |
| 452 | 461 |
|
| 453 | 462 |
return nil |
| ... | ... |
@@ -480,7 +502,6 @@ func parseNetworkGenericOptions(data interface{}) (*networkConfiguration, error)
|
| 480 | 480 |
case map[string]interface{}:
|
| 481 | 481 |
config = &networkConfiguration{
|
| 482 | 482 |
EnableICC: true, |
| 483 |
- EnableIPTables: true, |
|
| 484 | 483 |
EnableIPMasquerade: true, |
| 485 | 484 |
} |
| 486 | 485 |
err = config.fromMap(opt) |
| ... | ... |
@@ -578,6 +599,7 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err
|
| 578 | 578 |
endpoints: make(map[types.UUID]*bridgeEndpoint), |
| 579 | 579 |
config: config, |
| 580 | 580 |
portMapper: portmapper.New(), |
| 581 |
+ driver: d, |
|
| 581 | 582 |
} |
| 582 | 583 |
|
| 583 | 584 |
d.Lock() |
| ... | ... |
@@ -660,14 +682,14 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err
|
| 660 | 660 |
{enableIPv6Forwarding, setupIPv6Forwarding},
|
| 661 | 661 |
|
| 662 | 662 |
// Setup Loopback Adresses Routing |
| 663 |
- {!config.EnableUserlandProxy, setupLoopbackAdressesRouting},
|
|
| 663 |
+ {!d.config.EnableUserlandProxy, setupLoopbackAdressesRouting},
|
|
| 664 | 664 |
|
| 665 | 665 |
// Setup IPTables. |
| 666 |
- {config.EnableIPTables, network.setupIPTables},
|
|
| 666 |
+ {d.config.EnableIPTables, network.setupIPTables},
|
|
| 667 | 667 |
|
| 668 | 668 |
//We want to track firewalld configuration so that |
| 669 | 669 |
//if it is started/reloaded, the rules can be applied correctly |
| 670 |
- {config.EnableIPTables, network.setupFirewalld},
|
|
| 670 |
+ {d.config.EnableIPTables, network.setupFirewalld},
|
|
| 671 | 671 |
|
| 672 | 672 |
// Setup DefaultGatewayIPv4 |
| 673 | 673 |
{config.DefaultGatewayIPv4 != nil, setupGatewayIPv4},
|
| ... | ... |
@@ -676,10 +698,10 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err
|
| 676 | 676 |
{config.DefaultGatewayIPv6 != nil, setupGatewayIPv6},
|
| 677 | 677 |
|
| 678 | 678 |
// Add inter-network communication rules. |
| 679 |
- {config.EnableIPTables, setupNetworkIsolationRules},
|
|
| 679 |
+ {d.config.EnableIPTables, setupNetworkIsolationRules},
|
|
| 680 | 680 |
|
| 681 | 681 |
//Configure bridge networking filtering if ICC is off and IP tables are enabled |
| 682 |
- {!config.EnableICC && config.EnableIPTables, setupBridgeNetFiltering},
|
|
| 682 |
+ {!config.EnableICC && d.config.EnableIPTables, setupBridgeNetFiltering},
|
|
| 683 | 683 |
} {
|
| 684 | 684 |
if step.Condition {
|
| 685 | 685 |
bridgeSetup.queueStep(step.Fn) |
| ... | ... |
@@ -838,6 +860,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn |
| 838 | 838 |
// Get the network handler and make sure it exists |
| 839 | 839 |
d.Lock() |
| 840 | 840 |
n, ok := d.networks[nid] |
| 841 |
+ dconfig := d.config |
|
| 841 | 842 |
d.Unlock() |
| 842 | 843 |
|
| 843 | 844 |
if !ok {
|
| ... | ... |
@@ -950,7 +973,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn |
| 950 | 950 |
return fmt.Errorf("adding interface %s to bridge %s failed: %v", hostIfName, config.BridgeName, err)
|
| 951 | 951 |
} |
| 952 | 952 |
|
| 953 |
- if !config.EnableUserlandProxy {
|
|
| 953 |
+ if !dconfig.EnableUserlandProxy {
|
|
| 954 | 954 |
err = setHairpinMode(host, true) |
| 955 | 955 |
if err != nil {
|
| 956 | 956 |
return err |
| ... | ... |
@@ -1023,7 +1046,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn |
| 1023 | 1023 |
} |
| 1024 | 1024 |
|
| 1025 | 1025 |
// Program any required port mapping and store them in the endpoint |
| 1026 |
- endpoint.portMapping, err = n.allocatePorts(epConfig, endpoint, config.DefaultBindingIP, config.EnableUserlandProxy) |
|
| 1026 |
+ endpoint.portMapping, err = n.allocatePorts(epConfig, endpoint, config.DefaultBindingIP, d.config.EnableUserlandProxy) |
|
| 1027 | 1027 |
if err != nil {
|
| 1028 | 1028 |
return err |
| 1029 | 1029 |
} |
| ... | ... |
@@ -21,6 +21,7 @@ func TestCreateFullOptions(t *testing.T) {
|
| 21 | 21 |
|
| 22 | 22 |
config := &configuration{
|
| 23 | 23 |
EnableIPForwarding: true, |
| 24 |
+ EnableIPTables: true, |
|
| 24 | 25 |
} |
| 25 | 26 |
|
| 26 | 27 |
// Test this scenario: Default gw address does not belong to |
| ... | ... |
@@ -37,7 +38,6 @@ func TestCreateFullOptions(t *testing.T) {
|
| 37 | 37 |
FixedCIDR: cnw, |
| 38 | 38 |
DefaultGatewayIPv4: gw, |
| 39 | 39 |
EnableIPv6: true, |
| 40 |
- EnableIPTables: true, |
|
| 41 | 40 |
} |
| 42 | 41 |
_, netConfig.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48")
|
| 43 | 42 |
genericOption := make(map[string]interface{})
|
| ... | ... |
@@ -71,9 +71,13 @@ func TestCreate(t *testing.T) {
|
| 71 | 71 |
defer netutils.SetupTestNetNS(t)() |
| 72 | 72 |
d := newDriver() |
| 73 | 73 |
|
| 74 |
- config := &networkConfiguration{BridgeName: DefaultBridgeName}
|
|
| 74 |
+ if err := d.Config(nil); err != nil {
|
|
| 75 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 76 |
+ } |
|
| 77 |
+ |
|
| 78 |
+ netconfig := &networkConfiguration{BridgeName: DefaultBridgeName}
|
|
| 75 | 79 |
genericOption := make(map[string]interface{})
|
| 76 |
- genericOption[netlabel.GenericData] = config |
|
| 80 |
+ genericOption[netlabel.GenericData] = netconfig |
|
| 77 | 81 |
|
| 78 | 82 |
if err := d.CreateNetwork("dummy", genericOption); err != nil {
|
| 79 | 83 |
t.Fatalf("Failed to create bridge: %v", err)
|
| ... | ... |
@@ -100,9 +104,13 @@ func TestCreateFail(t *testing.T) {
|
| 100 | 100 |
defer netutils.SetupTestNetNS(t)() |
| 101 | 101 |
d := newDriver() |
| 102 | 102 |
|
| 103 |
- config := &networkConfiguration{BridgeName: "dummy0"}
|
|
| 103 |
+ if err := d.Config(nil); err != nil {
|
|
| 104 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 105 |
+ } |
|
| 106 |
+ |
|
| 107 |
+ netconfig := &networkConfiguration{BridgeName: "dummy0"}
|
|
| 104 | 108 |
genericOption := make(map[string]interface{})
|
| 105 |
- genericOption[netlabel.GenericData] = config |
|
| 109 |
+ genericOption[netlabel.GenericData] = netconfig |
|
| 106 | 110 |
|
| 107 | 111 |
if err := d.CreateNetwork("dummy", genericOption); err == nil {
|
| 108 | 112 |
t.Fatal("Bridge creation was expected to fail")
|
| ... | ... |
@@ -114,20 +122,30 @@ func TestCreateMultipleNetworks(t *testing.T) {
|
| 114 | 114 |
d := newDriver() |
| 115 | 115 |
dd, _ := d.(*driver) |
| 116 | 116 |
|
| 117 |
- config1 := &networkConfiguration{BridgeName: "net_test_1", AllowNonDefaultBridge: true, EnableIPTables: true}
|
|
| 117 |
+ config := &configuration{
|
|
| 118 |
+ EnableIPTables: true, |
|
| 119 |
+ } |
|
| 118 | 120 |
genericOption := make(map[string]interface{})
|
| 121 |
+ genericOption[netlabel.GenericData] = config |
|
| 122 |
+ |
|
| 123 |
+ if err := d.Config(genericOption); err != nil {
|
|
| 124 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 125 |
+ } |
|
| 126 |
+ |
|
| 127 |
+ config1 := &networkConfiguration{BridgeName: "net_test_1", AllowNonDefaultBridge: true}
|
|
| 128 |
+ genericOption = make(map[string]interface{})
|
|
| 119 | 129 |
genericOption[netlabel.GenericData] = config1 |
| 120 | 130 |
if err := d.CreateNetwork("1", genericOption); err != nil {
|
| 121 | 131 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 122 | 132 |
} |
| 123 | 133 |
|
| 124 |
- config2 := &networkConfiguration{BridgeName: "net_test_2", AllowNonDefaultBridge: true, EnableIPTables: true}
|
|
| 134 |
+ config2 := &networkConfiguration{BridgeName: "net_test_2", AllowNonDefaultBridge: true}
|
|
| 125 | 135 |
genericOption[netlabel.GenericData] = config2 |
| 126 | 136 |
if err := d.CreateNetwork("2", genericOption); err != nil {
|
| 127 | 137 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 128 | 138 |
} |
| 129 | 139 |
|
| 130 |
- config3 := &networkConfiguration{BridgeName: "net_test_3", AllowNonDefaultBridge: true, EnableIPTables: true}
|
|
| 140 |
+ config3 := &networkConfiguration{BridgeName: "net_test_3", AllowNonDefaultBridge: true}
|
|
| 131 | 141 |
genericOption[netlabel.GenericData] = config3 |
| 132 | 142 |
if err := d.CreateNetwork("3", genericOption); err != nil {
|
| 133 | 143 |
t.Fatalf("Failed to create bridge: %v", err)
|
| ... | ... |
@@ -136,7 +154,7 @@ func TestCreateMultipleNetworks(t *testing.T) {
|
| 136 | 136 |
// Verify the network isolation rules are installed, each network subnet should appear 4 times |
| 137 | 137 |
verifyV4INCEntries(dd.networks, 4, t) |
| 138 | 138 |
|
| 139 |
- config4 := &networkConfiguration{BridgeName: "net_test_4", AllowNonDefaultBridge: true, EnableIPTables: true}
|
|
| 139 |
+ config4 := &networkConfiguration{BridgeName: "net_test_4", AllowNonDefaultBridge: true}
|
|
| 140 | 140 |
genericOption[netlabel.GenericData] = config4 |
| 141 | 141 |
if err := d.CreateNetwork("4", genericOption); err != nil {
|
| 142 | 142 |
t.Fatalf("Failed to create bridge: %v", err)
|
| ... | ... |
@@ -278,15 +296,24 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
|
| 278 | 278 |
d := newDriver() |
| 279 | 279 |
dd, _ := d.(*driver) |
| 280 | 280 |
|
| 281 |
- config := &networkConfiguration{
|
|
| 282 |
- BridgeName: DefaultBridgeName, |
|
| 281 |
+ config := &configuration{
|
|
| 283 | 282 |
EnableIPTables: true, |
| 284 |
- EnableICC: false, |
|
| 285 | 283 |
EnableUserlandProxy: ulPxyEnabled, |
| 286 | 284 |
} |
| 287 | 285 |
genericOption := make(map[string]interface{})
|
| 288 | 286 |
genericOption[netlabel.GenericData] = config |
| 289 | 287 |
|
| 288 |
+ if err := d.Config(genericOption); err != nil {
|
|
| 289 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 290 |
+ } |
|
| 291 |
+ |
|
| 292 |
+ netconfig := &networkConfiguration{
|
|
| 293 |
+ BridgeName: DefaultBridgeName, |
|
| 294 |
+ EnableICC: false, |
|
| 295 |
+ } |
|
| 296 |
+ genericOption = make(map[string]interface{})
|
|
| 297 |
+ genericOption[netlabel.GenericData] = netconfig |
|
| 298 |
+ |
|
| 290 | 299 |
err := d.CreateNetwork("net1", genericOption)
|
| 291 | 300 |
if err != nil {
|
| 292 | 301 |
t.Fatalf("Failed to create bridge: %v", err)
|
| ... | ... |
@@ -339,9 +366,13 @@ func TestCreateLinkWithOptions(t *testing.T) {
|
| 339 | 339 |
defer netutils.SetupTestNetNS(t)() |
| 340 | 340 |
d := newDriver() |
| 341 | 341 |
|
| 342 |
- config := &networkConfiguration{BridgeName: DefaultBridgeName}
|
|
| 342 |
+ if err := d.Config(nil); err != nil {
|
|
| 343 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 344 |
+ } |
|
| 345 |
+ |
|
| 346 |
+ netconfig := &networkConfiguration{BridgeName: DefaultBridgeName}
|
|
| 343 | 347 |
netOptions := make(map[string]interface{})
|
| 344 |
- netOptions[netlabel.GenericData] = config |
|
| 348 |
+ netOptions[netlabel.GenericData] = netconfig |
|
| 345 | 349 |
|
| 346 | 350 |
err := d.CreateNetwork("net1", netOptions)
|
| 347 | 351 |
if err != nil {
|
| ... | ... |
@@ -395,14 +426,23 @@ func TestLinkContainers(t *testing.T) {
|
| 395 | 395 |
|
| 396 | 396 |
d := newDriver() |
| 397 | 397 |
|
| 398 |
- config := &networkConfiguration{
|
|
| 399 |
- BridgeName: DefaultBridgeName, |
|
| 398 |
+ config := &configuration{
|
|
| 400 | 399 |
EnableIPTables: true, |
| 401 |
- EnableICC: false, |
|
| 402 | 400 |
} |
| 403 | 401 |
genericOption := make(map[string]interface{})
|
| 404 | 402 |
genericOption[netlabel.GenericData] = config |
| 405 | 403 |
|
| 404 |
+ if err := d.Config(genericOption); err != nil {
|
|
| 405 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 406 |
+ } |
|
| 407 |
+ |
|
| 408 |
+ netconfig := &networkConfiguration{
|
|
| 409 |
+ BridgeName: DefaultBridgeName, |
|
| 410 |
+ EnableICC: false, |
|
| 411 |
+ } |
|
| 412 |
+ genericOption = make(map[string]interface{})
|
|
| 413 |
+ genericOption[netlabel.GenericData] = netconfig |
|
| 414 |
+ |
|
| 406 | 415 |
err := d.CreateNetwork("net1", genericOption)
|
| 407 | 416 |
if err != nil {
|
| 408 | 417 |
t.Fatalf("Failed to create bridge: %v", err)
|
| ... | ... |
@@ -602,6 +642,10 @@ func TestSetDefaultGw(t *testing.T) {
|
| 602 | 602 |
defer netutils.SetupTestNetNS(t)() |
| 603 | 603 |
d := newDriver() |
| 604 | 604 |
|
| 605 |
+ if err := d.Config(nil); err != nil {
|
|
| 606 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 607 |
+ } |
|
| 608 |
+ |
|
| 605 | 609 |
_, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
|
| 606 | 610 |
gw4 := bridgeNetworks[0].IP.To4() |
| 607 | 611 |
gw4[3] = 254 |
| ... | ... |
@@ -74,9 +74,9 @@ func linkContainers(action, parentIP, childIP string, ports []types.TransportPor |
| 74 | 74 |
return InvalidLinkIPAddrError(childIP) |
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 |
- chain := iptables.Chain{Name: DockerChain, Bridge: bridge}
|
|
| 77 |
+ chain := iptables.ChainInfo{Name: DockerChain}
|
|
| 78 | 78 |
for _, port := range ports {
|
| 79 |
- err := chain.Link(nfAction, ip1, ip2, int(port.Port), port.Proto.String()) |
|
| 79 |
+ err := chain.Link(nfAction, ip1, ip2, int(port.Port), port.Proto.String(), bridge) |
|
| 80 | 80 |
if !ignoreErrors && err != nil {
|
| 81 | 81 |
return err |
| 82 | 82 |
} |
| ... | ... |
@@ -14,6 +14,10 @@ func TestLinkCreate(t *testing.T) {
|
| 14 | 14 |
d := newDriver() |
| 15 | 15 |
dr := d.(*driver) |
| 16 | 16 |
|
| 17 |
+ if err := d.Config(nil); err != nil {
|
|
| 18 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 19 |
+ } |
|
| 20 |
+ |
|
| 17 | 21 |
mtu := 1490 |
| 18 | 22 |
config := &networkConfiguration{
|
| 19 | 23 |
BridgeName: DefaultBridgeName, |
| ... | ... |
@@ -108,6 +112,10 @@ func TestLinkCreateTwo(t *testing.T) {
|
| 108 | 108 |
defer netutils.SetupTestNetNS(t)() |
| 109 | 109 |
d := newDriver() |
| 110 | 110 |
|
| 111 |
+ if err := d.Config(nil); err != nil {
|
|
| 112 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 113 |
+ } |
|
| 114 |
+ |
|
| 111 | 115 |
config := &networkConfiguration{
|
| 112 | 116 |
BridgeName: DefaultBridgeName, |
| 113 | 117 |
EnableIPv6: true} |
| ... | ... |
@@ -140,6 +148,10 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) {
|
| 140 | 140 |
defer netutils.SetupTestNetNS(t)() |
| 141 | 141 |
d := newDriver() |
| 142 | 142 |
|
| 143 |
+ if err := d.Config(nil); err != nil {
|
|
| 144 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 145 |
+ } |
|
| 146 |
+ |
|
| 143 | 147 |
config := &networkConfiguration{
|
| 144 | 148 |
BridgeName: DefaultBridgeName} |
| 145 | 149 |
genericOption := make(map[string]interface{})
|
| ... | ... |
@@ -170,6 +182,10 @@ func TestLinkDelete(t *testing.T) {
|
| 170 | 170 |
defer netutils.SetupTestNetNS(t)() |
| 171 | 171 |
d := newDriver() |
| 172 | 172 |
|
| 173 |
+ if err := d.Config(nil); err != nil {
|
|
| 174 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 175 |
+ } |
|
| 176 |
+ |
|
| 173 | 177 |
config := &networkConfiguration{
|
| 174 | 178 |
BridgeName: DefaultBridgeName, |
| 175 | 179 |
EnableIPv6: true} |
| ... | ... |
@@ -21,6 +21,16 @@ func TestPortMappingConfig(t *testing.T) {
|
| 21 | 21 |
defer netutils.SetupTestNetNS(t)() |
| 22 | 22 |
d := newDriver() |
| 23 | 23 |
|
| 24 |
+ config := &configuration{
|
|
| 25 |
+ EnableIPTables: true, |
|
| 26 |
+ } |
|
| 27 |
+ genericOption := make(map[string]interface{})
|
|
| 28 |
+ genericOption[netlabel.GenericData] = config |
|
| 29 |
+ |
|
| 30 |
+ if err := d.Config(genericOption); err != nil {
|
|
| 31 |
+ t.Fatalf("Failed to setup driver config: %v", err)
|
|
| 32 |
+ } |
|
| 33 |
+ |
|
| 24 | 34 |
binding1 := types.PortBinding{Proto: types.UDP, Port: uint16(400), HostPort: uint16(54000)}
|
| 25 | 35 |
binding2 := types.PortBinding{Proto: types.TCP, Port: uint16(500), HostPort: uint16(65000)}
|
| 26 | 36 |
portBindings := []types.PortBinding{binding1, binding2}
|
| ... | ... |
@@ -29,8 +39,7 @@ func TestPortMappingConfig(t *testing.T) {
|
| 29 | 29 |
epOptions[netlabel.PortMap] = portBindings |
| 30 | 30 |
|
| 31 | 31 |
netConfig := &networkConfiguration{
|
| 32 |
- BridgeName: DefaultBridgeName, |
|
| 33 |
- EnableIPTables: true, |
|
| 32 |
+ BridgeName: DefaultBridgeName, |
|
| 34 | 33 |
} |
| 35 | 34 |
netOptions := make(map[string]interface{})
|
| 36 | 35 |
netOptions[netlabel.GenericData] = netConfig |
| ... | ... |
@@ -3,8 +3,13 @@ package bridge |
| 3 | 3 |
import "github.com/docker/libnetwork/iptables" |
| 4 | 4 |
|
| 5 | 5 |
func (n *bridgeNetwork) setupFirewalld(config *networkConfiguration, i *bridgeInterface) error {
|
| 6 |
+ d := n.driver |
|
| 7 |
+ d.Lock() |
|
| 8 |
+ driverConfig := d.config |
|
| 9 |
+ d.Unlock() |
|
| 10 |
+ |
|
| 6 | 11 |
// Sanity check. |
| 7 |
- if config.EnableIPTables == false {
|
|
| 12 |
+ if driverConfig.EnableIPTables == false {
|
|
| 8 | 13 |
return IPTableCfgError(config.BridgeName) |
| 9 | 14 |
} |
| 10 | 15 |
|
| ... | ... |
@@ -4,6 +4,7 @@ import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"net" |
| 6 | 6 |
|
| 7 |
+ "github.com/Sirupsen/logrus" |
|
| 7 | 8 |
"github.com/docker/libnetwork/iptables" |
| 8 | 9 |
"github.com/docker/libnetwork/netutils" |
| 9 | 10 |
) |
| ... | ... |
@@ -13,14 +14,48 @@ const ( |
| 13 | 13 |
DockerChain = "DOCKER" |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 |
-func (n *bridgeNetwork) setupIPTables(config *networkConfiguration, i *bridgeInterface) error {
|
|
| 16 |
+func setupIPChains(config *configuration) (*iptables.ChainInfo, *iptables.ChainInfo, error) {
|
|
| 17 | 17 |
// Sanity check. |
| 18 | 18 |
if config.EnableIPTables == false {
|
| 19 |
- return IPTableCfgError(config.BridgeName) |
|
| 19 |
+ return nil, nil, fmt.Errorf("Cannot create new chains, EnableIPTable is disabled")
|
|
| 20 | 20 |
} |
| 21 | 21 |
|
| 22 | 22 |
hairpinMode := !config.EnableUserlandProxy |
| 23 | 23 |
|
| 24 |
+ natChain, err := iptables.NewChain(DockerChain, iptables.Nat, hairpinMode) |
|
| 25 |
+ if err != nil {
|
|
| 26 |
+ return nil, nil, fmt.Errorf("Failed to create NAT chain: %s", err.Error())
|
|
| 27 |
+ } |
|
| 28 |
+ defer func() {
|
|
| 29 |
+ if err != nil {
|
|
| 30 |
+ if err := iptables.RemoveExistingChain(DockerChain, iptables.Nat); err != nil {
|
|
| 31 |
+ logrus.Warnf("Failed on removing iptables NAT chain on cleanup: %v", err)
|
|
| 32 |
+ } |
|
| 33 |
+ } |
|
| 34 |
+ }() |
|
| 35 |
+ |
|
| 36 |
+ filterChain, err := iptables.NewChain(DockerChain, iptables.Filter, hairpinMode) |
|
| 37 |
+ if err != nil {
|
|
| 38 |
+ return nil, nil, fmt.Errorf("Failed to create FILTER chain: %s", err.Error())
|
|
| 39 |
+ } |
|
| 40 |
+ |
|
| 41 |
+ return natChain, filterChain, nil |
|
| 42 |
+} |
|
| 43 |
+ |
|
| 44 |
+func (n *bridgeNetwork) setupIPTables(config *networkConfiguration, i *bridgeInterface) error {
|
|
| 45 |
+ d := n.driver |
|
| 46 |
+ d.Lock() |
|
| 47 |
+ driverConfig := d.config |
|
| 48 |
+ d.Unlock() |
|
| 49 |
+ |
|
| 50 |
+ // Sanity check. |
|
| 51 |
+ if driverConfig.EnableIPTables == false {
|
|
| 52 |
+ return fmt.Errorf("Cannot program chains, EnableIPTable is disabled")
|
|
| 53 |
+ } |
|
| 54 |
+ |
|
| 55 |
+ // Pickup this configuraton option from driver |
|
| 56 |
+ hairpinMode := !driverConfig.EnableUserlandProxy |
|
| 57 |
+ |
|
| 24 | 58 |
addrv4, _, err := netutils.GetIfaceAddr(config.BridgeName) |
| 25 | 59 |
if err != nil {
|
| 26 | 60 |
return fmt.Errorf("Failed to setup IP tables, cannot acquire Interface address: %s", err.Error())
|
| ... | ... |
@@ -34,17 +69,22 @@ func (n *bridgeNetwork) setupIPTables(config *networkConfiguration, i *bridgeInt |
| 34 | 34 |
return fmt.Errorf("Failed to Setup IP tables: %s", err.Error())
|
| 35 | 35 |
} |
| 36 | 36 |
|
| 37 |
- _, err = iptables.NewChain(DockerChain, config.BridgeName, iptables.Nat, hairpinMode) |
|
| 37 |
+ natChain, filterChain, err := n.getDriverChains() |
|
| 38 |
+ if err != nil {
|
|
| 39 |
+ return fmt.Errorf("Failed to setup IP tables, cannot acquire chain info %s", err.Error())
|
|
| 40 |
+ } |
|
| 41 |
+ |
|
| 42 |
+ err = iptables.ProgramChain(natChain, config.BridgeName, hairpinMode) |
|
| 38 | 43 |
if err != nil {
|
| 39 |
- return fmt.Errorf("Failed to create NAT chain: %s", err.Error())
|
|
| 44 |
+ return fmt.Errorf("Failed to program NAT chain: %s", err.Error())
|
|
| 40 | 45 |
} |
| 41 | 46 |
|
| 42 |
- chain, err := iptables.NewChain(DockerChain, config.BridgeName, iptables.Filter, hairpinMode) |
|
| 47 |
+ err = iptables.ProgramChain(filterChain, config.BridgeName, hairpinMode) |
|
| 43 | 48 |
if err != nil {
|
| 44 |
- return fmt.Errorf("Failed to create FILTER chain: %s", err.Error())
|
|
| 49 |
+ return fmt.Errorf("Failed to program FILTER chain: %s", err.Error())
|
|
| 45 | 50 |
} |
| 46 | 51 |
|
| 47 |
- n.portMapper.SetIptablesChain(chain) |
|
| 52 |
+ n.portMapper.SetIptablesChain(filterChain, n.getNetworkBridgeName()) |
|
| 48 | 53 |
|
| 49 | 54 |
return nil |
| 50 | 55 |
} |
| ... | ... |
@@ -37,26 +37,32 @@ func TestProgramIPTable(t *testing.T) {
|
| 37 | 37 |
} |
| 38 | 38 |
} |
| 39 | 39 |
|
| 40 |
-func TestSetupIPTables(t *testing.T) {
|
|
| 40 |
+func TestSetupIPChains(t *testing.T) {
|
|
| 41 | 41 |
// Create a test bridge with a basic bridge configuration (name + IPv4). |
| 42 | 42 |
defer netutils.SetupTestNetNS(t)() |
| 43 |
+ |
|
| 44 |
+ driverconfig := &configuration{
|
|
| 45 |
+ EnableIPTables: true, |
|
| 46 |
+ } |
|
| 47 |
+ d := &driver{
|
|
| 48 |
+ config: driverconfig, |
|
| 49 |
+ } |
|
| 50 |
+ assertChainConfig(d, t) |
|
| 51 |
+ |
|
| 43 | 52 |
config := getBasicTestConfig() |
| 44 | 53 |
br := &bridgeInterface{}
|
| 45 |
- |
|
| 46 | 54 |
createTestBridge(config, br, t) |
| 47 | 55 |
|
| 48 |
- // Modify iptables params in base configuration and apply them. |
|
| 49 |
- config.EnableIPTables = true |
|
| 50 |
- assertBridgeConfig(config, br, t) |
|
| 56 |
+ assertBridgeConfig(config, br, d, t) |
|
| 51 | 57 |
|
| 52 | 58 |
config.EnableIPMasquerade = true |
| 53 |
- assertBridgeConfig(config, br, t) |
|
| 59 |
+ assertBridgeConfig(config, br, d, t) |
|
| 54 | 60 |
|
| 55 | 61 |
config.EnableICC = true |
| 56 |
- assertBridgeConfig(config, br, t) |
|
| 62 |
+ assertBridgeConfig(config, br, d, t) |
|
| 57 | 63 |
|
| 58 | 64 |
config.EnableIPMasquerade = false |
| 59 |
- assertBridgeConfig(config, br, t) |
|
| 65 |
+ assertBridgeConfig(config, br, d, t) |
|
| 60 | 66 |
} |
| 61 | 67 |
|
| 62 | 68 |
func getBasicTestConfig() *networkConfiguration {
|
| ... | ... |
@@ -94,9 +100,22 @@ func assertIPTableChainProgramming(rule iptRule, descr string, t *testing.T) {
|
| 94 | 94 |
} |
| 95 | 95 |
} |
| 96 | 96 |
|
| 97 |
+// Assert function which create chains. |
|
| 98 |
+func assertChainConfig(d *driver, t *testing.T) {
|
|
| 99 |
+ var err error |
|
| 100 |
+ |
|
| 101 |
+ d.natChain, d.filterChain, err = setupIPChains(d.config) |
|
| 102 |
+ if err != nil {
|
|
| 103 |
+ t.Fatal(err) |
|
| 104 |
+ } |
|
| 105 |
+} |
|
| 106 |
+ |
|
| 97 | 107 |
// Assert function which pushes chains based on bridge config parameters. |
| 98 |
-func assertBridgeConfig(config *networkConfiguration, br *bridgeInterface, t *testing.T) {
|
|
| 99 |
- nw := bridgeNetwork{portMapper: portmapper.New()}
|
|
| 108 |
+func assertBridgeConfig(config *networkConfiguration, br *bridgeInterface, d *driver, t *testing.T) {
|
|
| 109 |
+ nw := bridgeNetwork{portMapper: portmapper.New(),
|
|
| 110 |
+ config: config} |
|
| 111 |
+ nw.driver = d |
|
| 112 |
+ |
|
| 100 | 113 |
// Attempt programming of ip tables. |
| 101 | 114 |
err := nw.setupIPTables(config, br) |
| 102 | 115 |
if err != nil {
|
| ... | ... |
@@ -17,9 +17,12 @@ func TestFirewalldInit(t *testing.T) {
|
| 17 | 17 |
|
| 18 | 18 |
func TestReloaded(t *testing.T) {
|
| 19 | 19 |
var err error |
| 20 |
- var fwdChain *Chain |
|
| 20 |
+ var fwdChain *ChainInfo |
|
| 21 | 21 |
|
| 22 |
- fwdChain, err = NewChain("FWD", "lo", Filter, false)
|
|
| 22 |
+ fwdChain, err = NewChain("FWD", Filter, false)
|
|
| 23 |
+ bridgeName := "lo" |
|
| 24 |
+ |
|
| 25 |
+ err = ProgramChain(fwdChain, bridgeName, false) |
|
| 23 | 26 |
if err != nil {
|
| 24 | 27 |
t.Fatal(err) |
| 25 | 28 |
} |
| ... | ... |
@@ -31,17 +34,17 @@ func TestReloaded(t *testing.T) {
|
| 31 | 31 |
port := 1234 |
| 32 | 32 |
proto := "tcp" |
| 33 | 33 |
|
| 34 |
- err = fwdChain.Link(Append, ip1, ip2, port, proto) |
|
| 34 |
+ err = fwdChain.Link(Append, ip1, ip2, port, proto, bridgeName) |
|
| 35 | 35 |
if err != nil {
|
| 36 | 36 |
t.Fatal(err) |
| 37 | 37 |
} else {
|
| 38 | 38 |
// to be re-called again later |
| 39 |
- OnReloaded(func() { fwdChain.Link(Append, ip1, ip2, port, proto) })
|
|
| 39 |
+ OnReloaded(func() { fwdChain.Link(Append, ip1, ip2, port, proto, bridgeName) })
|
|
| 40 | 40 |
} |
| 41 | 41 |
|
| 42 | 42 |
rule1 := []string{
|
| 43 |
- "-i", fwdChain.Bridge, |
|
| 44 |
- "-o", fwdChain.Bridge, |
|
| 43 |
+ "-i", bridgeName, |
|
| 44 |
+ "-o", bridgeName, |
|
| 45 | 45 |
"-p", proto, |
| 46 | 46 |
"-s", ip1.String(), |
| 47 | 47 |
"-d", ip2.String(), |
| ... | ... |
@@ -42,10 +42,9 @@ var ( |
| 42 | 42 |
ErrIptablesNotFound = errors.New("Iptables not found")
|
| 43 | 43 |
) |
| 44 | 44 |
|
| 45 |
-// Chain defines the iptables chain. |
|
| 46 |
-type Chain struct {
|
|
| 45 |
+// ChainInfo defines the iptables chain. |
|
| 46 |
+type ChainInfo struct {
|
|
| 47 | 47 |
Name string |
| 48 |
- Bridge string |
|
| 49 | 48 |
Table Table |
| 50 | 49 |
HairpinMode bool |
| 51 | 50 |
} |
| ... | ... |
@@ -74,14 +73,12 @@ func initCheck() error {
|
| 74 | 74 |
} |
| 75 | 75 |
|
| 76 | 76 |
// NewChain adds a new chain to ip table. |
| 77 |
-func NewChain(name, bridge string, table Table, hairpinMode bool) (*Chain, error) {
|
|
| 78 |
- c := &Chain{
|
|
| 77 |
+func NewChain(name string, table Table, hairpinMode bool) (*ChainInfo, error) {
|
|
| 78 |
+ c := &ChainInfo{
|
|
| 79 | 79 |
Name: name, |
| 80 |
- Bridge: bridge, |
|
| 81 | 80 |
Table: table, |
| 82 | 81 |
HairpinMode: hairpinMode, |
| 83 | 82 |
} |
| 84 |
- |
|
| 85 | 83 |
if string(c.Table) == "" {
|
| 86 | 84 |
c.Table = Filter |
| 87 | 85 |
} |
| ... | ... |
@@ -94,8 +91,16 @@ func NewChain(name, bridge string, table Table, hairpinMode bool) (*Chain, error |
| 94 | 94 |
return nil, fmt.Errorf("Could not create %s/%s chain: %s", c.Table, c.Name, output)
|
| 95 | 95 |
} |
| 96 | 96 |
} |
| 97 |
+ return c, nil |
|
| 98 |
+} |
|
| 99 |
+ |
|
| 100 |
+// ProgramChain is used to add rules to a chain |
|
| 101 |
+func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode bool) error {
|
|
| 102 |
+ if c.Name == "" {
|
|
| 103 |
+ return fmt.Errorf("Could not program chain, missing chain name.")
|
|
| 104 |
+ } |
|
| 97 | 105 |
|
| 98 |
- switch table {
|
|
| 106 |
+ switch c.Table {
|
|
| 99 | 107 |
case Nat: |
| 100 | 108 |
preroute := []string{
|
| 101 | 109 |
"-m", "addrtype", |
| ... | ... |
@@ -103,7 +108,7 @@ func NewChain(name, bridge string, table Table, hairpinMode bool) (*Chain, error |
| 103 | 103 |
"-j", c.Name} |
| 104 | 104 |
if !Exists(Nat, "PREROUTING", preroute...) {
|
| 105 | 105 |
if err := c.Prerouting(Append, preroute...); err != nil {
|
| 106 |
- return nil, fmt.Errorf("Failed to inject docker in PREROUTING chain: %s", err)
|
|
| 106 |
+ return fmt.Errorf("Failed to inject docker in PREROUTING chain: %s", err)
|
|
| 107 | 107 |
} |
| 108 | 108 |
} |
| 109 | 109 |
output := []string{
|
| ... | ... |
@@ -115,28 +120,32 @@ func NewChain(name, bridge string, table Table, hairpinMode bool) (*Chain, error |
| 115 | 115 |
} |
| 116 | 116 |
if !Exists(Nat, "OUTPUT", output...) {
|
| 117 | 117 |
if err := c.Output(Append, output...); err != nil {
|
| 118 |
- return nil, fmt.Errorf("Failed to inject docker in OUTPUT chain: %s", err)
|
|
| 118 |
+ return fmt.Errorf("Failed to inject docker in OUTPUT chain: %s", err)
|
|
| 119 | 119 |
} |
| 120 | 120 |
} |
| 121 | 121 |
case Filter: |
| 122 |
+ if bridgeName == "" {
|
|
| 123 |
+ return fmt.Errorf("Could not program chain %s/%s, missing bridge name.",
|
|
| 124 |
+ c.Table, c.Name) |
|
| 125 |
+ } |
|
| 122 | 126 |
link := []string{
|
| 123 |
- "-o", c.Bridge, |
|
| 127 |
+ "-o", bridgeName, |
|
| 124 | 128 |
"-j", c.Name} |
| 125 | 129 |
if !Exists(Filter, "FORWARD", link...) {
|
| 126 | 130 |
insert := append([]string{string(Insert), "FORWARD"}, link...)
|
| 127 | 131 |
if output, err := Raw(insert...); err != nil {
|
| 128 |
- return nil, err |
|
| 132 |
+ return err |
|
| 129 | 133 |
} else if len(output) != 0 {
|
| 130 |
- return nil, fmt.Errorf("Could not create linking rule to %s/%s: %s", c.Table, c.Name, output)
|
|
| 134 |
+ return fmt.Errorf("Could not create linking rule to %s/%s: %s", c.Table, c.Name, output)
|
|
| 131 | 135 |
} |
| 132 | 136 |
} |
| 133 | 137 |
} |
| 134 |
- return c, nil |
|
| 138 |
+ return nil |
|
| 135 | 139 |
} |
| 136 | 140 |
|
| 137 | 141 |
// RemoveExistingChain removes existing chain from the table. |
| 138 | 142 |
func RemoveExistingChain(name string, table Table) error {
|
| 139 |
- c := &Chain{
|
|
| 143 |
+ c := &ChainInfo{
|
|
| 140 | 144 |
Name: name, |
| 141 | 145 |
Table: table, |
| 142 | 146 |
} |
| ... | ... |
@@ -147,7 +156,7 @@ func RemoveExistingChain(name string, table Table) error {
|
| 147 | 147 |
} |
| 148 | 148 |
|
| 149 | 149 |
// Forward adds forwarding rule to 'filter' table and corresponding nat rule to 'nat' table. |
| 150 |
-func (c *Chain) Forward(action Action, ip net.IP, port int, proto, destAddr string, destPort int) error {
|
|
| 150 |
+func (c *ChainInfo) Forward(action Action, ip net.IP, port int, proto, destAddr string, destPort int, bridgeName string) error {
|
|
| 151 | 151 |
daddr := ip.String() |
| 152 | 152 |
if ip.IsUnspecified() {
|
| 153 | 153 |
// iptables interprets "0.0.0.0" as "0.0.0.0/32", whereas we |
| ... | ... |
@@ -162,7 +171,7 @@ func (c *Chain) Forward(action Action, ip net.IP, port int, proto, destAddr stri |
| 162 | 162 |
"-j", "DNAT", |
| 163 | 163 |
"--to-destination", net.JoinHostPort(destAddr, strconv.Itoa(destPort))} |
| 164 | 164 |
if !c.HairpinMode {
|
| 165 |
- args = append(args, "!", "-i", c.Bridge) |
|
| 165 |
+ args = append(args, "!", "-i", bridgeName) |
|
| 166 | 166 |
} |
| 167 | 167 |
if output, err := Raw(args...); err != nil {
|
| 168 | 168 |
return err |
| ... | ... |
@@ -171,8 +180,8 @@ func (c *Chain) Forward(action Action, ip net.IP, port int, proto, destAddr stri |
| 171 | 171 |
} |
| 172 | 172 |
|
| 173 | 173 |
if output, err := Raw("-t", string(Filter), string(action), c.Name,
|
| 174 |
- "!", "-i", c.Bridge, |
|
| 175 |
- "-o", c.Bridge, |
|
| 174 |
+ "!", "-i", bridgeName, |
|
| 175 |
+ "-o", bridgeName, |
|
| 176 | 176 |
"-p", proto, |
| 177 | 177 |
"-d", destAddr, |
| 178 | 178 |
"--dport", strconv.Itoa(destPort), |
| ... | ... |
@@ -198,9 +207,9 @@ func (c *Chain) Forward(action Action, ip net.IP, port int, proto, destAddr stri |
| 198 | 198 |
|
| 199 | 199 |
// Link adds reciprocal ACCEPT rule for two supplied IP addresses. |
| 200 | 200 |
// Traffic is allowed from ip1 to ip2 and vice-versa |
| 201 |
-func (c *Chain) Link(action Action, ip1, ip2 net.IP, port int, proto string) error {
|
|
| 201 |
+func (c *ChainInfo) Link(action Action, ip1, ip2 net.IP, port int, proto string, bridgeName string) error {
|
|
| 202 | 202 |
if output, err := Raw("-t", string(Filter), string(action), c.Name,
|
| 203 |
- "-i", c.Bridge, "-o", c.Bridge, |
|
| 203 |
+ "-i", bridgeName, "-o", bridgeName, |
|
| 204 | 204 |
"-p", proto, |
| 205 | 205 |
"-s", ip1.String(), |
| 206 | 206 |
"-d", ip2.String(), |
| ... | ... |
@@ -211,7 +220,7 @@ func (c *Chain) Link(action Action, ip1, ip2 net.IP, port int, proto string) err |
| 211 | 211 |
return fmt.Errorf("Error iptables forward: %s", output)
|
| 212 | 212 |
} |
| 213 | 213 |
if output, err := Raw("-t", string(Filter), string(action), c.Name,
|
| 214 |
- "-i", c.Bridge, "-o", c.Bridge, |
|
| 214 |
+ "-i", bridgeName, "-o", bridgeName, |
|
| 215 | 215 |
"-p", proto, |
| 216 | 216 |
"-s", ip2.String(), |
| 217 | 217 |
"-d", ip1.String(), |
| ... | ... |
@@ -225,7 +234,7 @@ func (c *Chain) Link(action Action, ip1, ip2 net.IP, port int, proto string) err |
| 225 | 225 |
} |
| 226 | 226 |
|
| 227 | 227 |
// Prerouting adds linking rule to nat/PREROUTING chain. |
| 228 |
-func (c *Chain) Prerouting(action Action, args ...string) error {
|
|
| 228 |
+func (c *ChainInfo) Prerouting(action Action, args ...string) error {
|
|
| 229 | 229 |
a := []string{"-t", string(Nat), string(action), "PREROUTING"}
|
| 230 | 230 |
if len(args) > 0 {
|
| 231 | 231 |
a = append(a, args...) |
| ... | ... |
@@ -239,7 +248,7 @@ func (c *Chain) Prerouting(action Action, args ...string) error {
|
| 239 | 239 |
} |
| 240 | 240 |
|
| 241 | 241 |
// Output adds linking rule to an OUTPUT chain. |
| 242 |
-func (c *Chain) Output(action Action, args ...string) error {
|
|
| 242 |
+func (c *ChainInfo) Output(action Action, args ...string) error {
|
|
| 243 | 243 |
a := []string{"-t", string(c.Table), string(action), "OUTPUT"}
|
| 244 | 244 |
if len(args) > 0 {
|
| 245 | 245 |
a = append(a, args...) |
| ... | ... |
@@ -253,7 +262,7 @@ func (c *Chain) Output(action Action, args ...string) error {
|
| 253 | 253 |
} |
| 254 | 254 |
|
| 255 | 255 |
// Remove removes the chain. |
| 256 |
-func (c *Chain) Remove() error {
|
|
| 256 |
+func (c *ChainInfo) Remove() error {
|
|
| 257 | 257 |
// Ignore errors - This could mean the chains were never set up |
| 258 | 258 |
if c.Table == Nat {
|
| 259 | 259 |
c.Prerouting(Delete, "-m", "addrtype", "--dst-type", "LOCAL", "-j", c.Name) |
| ... | ... |
@@ -13,18 +13,22 @@ import ( |
| 13 | 13 |
|
| 14 | 14 |
const chainName = "DOCKEREST" |
| 15 | 15 |
|
| 16 |
-var natChain *Chain |
|
| 17 |
-var filterChain *Chain |
|
| 16 |
+var natChain *ChainInfo |
|
| 17 |
+var filterChain *ChainInfo |
|
| 18 |
+var bridgeName string |
|
| 18 | 19 |
|
| 19 | 20 |
func TestNewChain(t *testing.T) {
|
| 20 | 21 |
var err error |
| 21 | 22 |
|
| 22 |
- natChain, err = NewChain(chainName, "lo", Nat, false) |
|
| 23 |
+ bridgeName = "lo" |
|
| 24 |
+ natChain, err = NewChain(chainName, Nat, false) |
|
| 25 |
+ err = ProgramChain(natChain, bridgeName, false) |
|
| 23 | 26 |
if err != nil {
|
| 24 | 27 |
t.Fatal(err) |
| 25 | 28 |
} |
| 26 | 29 |
|
| 27 |
- filterChain, err = NewChain(chainName, "lo", Filter, false) |
|
| 30 |
+ filterChain, err = NewChain(chainName, Filter, false) |
|
| 31 |
+ err = ProgramChain(filterChain, bridgeName, false) |
|
| 28 | 32 |
if err != nil {
|
| 29 | 33 |
t.Fatal(err) |
| 30 | 34 |
} |
| ... | ... |
@@ -37,7 +41,8 @@ func TestForward(t *testing.T) {
|
| 37 | 37 |
dstPort := 4321 |
| 38 | 38 |
proto := "tcp" |
| 39 | 39 |
|
| 40 |
- err := natChain.Forward(Insert, ip, port, proto, dstAddr, dstPort) |
|
| 40 |
+ bridgeName := "lo" |
|
| 41 |
+ err := natChain.Forward(Insert, ip, port, proto, dstAddr, dstPort, bridgeName) |
|
| 41 | 42 |
if err != nil {
|
| 42 | 43 |
t.Fatal(err) |
| 43 | 44 |
} |
| ... | ... |
@@ -48,7 +53,7 @@ func TestForward(t *testing.T) {
|
| 48 | 48 |
"--dport", strconv.Itoa(port), |
| 49 | 49 |
"-j", "DNAT", |
| 50 | 50 |
"--to-destination", dstAddr + ":" + strconv.Itoa(dstPort), |
| 51 |
- "!", "-i", natChain.Bridge, |
|
| 51 |
+ "!", "-i", bridgeName, |
|
| 52 | 52 |
} |
| 53 | 53 |
|
| 54 | 54 |
if !Exists(natChain.Table, natChain.Name, dnatRule...) {
|
| ... | ... |
@@ -56,8 +61,8 @@ func TestForward(t *testing.T) {
|
| 56 | 56 |
} |
| 57 | 57 |
|
| 58 | 58 |
filterRule := []string{
|
| 59 |
- "!", "-i", filterChain.Bridge, |
|
| 60 |
- "-o", filterChain.Bridge, |
|
| 59 |
+ "!", "-i", bridgeName, |
|
| 60 |
+ "-o", bridgeName, |
|
| 61 | 61 |
"-d", dstAddr, |
| 62 | 62 |
"-p", proto, |
| 63 | 63 |
"--dport", strconv.Itoa(dstPort), |
| ... | ... |
@@ -84,19 +89,20 @@ func TestForward(t *testing.T) {
|
| 84 | 84 |
func TestLink(t *testing.T) {
|
| 85 | 85 |
var err error |
| 86 | 86 |
|
| 87 |
+ bridgeName := "lo" |
|
| 87 | 88 |
ip1 := net.ParseIP("192.168.1.1")
|
| 88 | 89 |
ip2 := net.ParseIP("192.168.1.2")
|
| 89 | 90 |
port := 1234 |
| 90 | 91 |
proto := "tcp" |
| 91 | 92 |
|
| 92 |
- err = filterChain.Link(Append, ip1, ip2, port, proto) |
|
| 93 |
+ err = filterChain.Link(Append, ip1, ip2, port, proto, bridgeName) |
|
| 93 | 94 |
if err != nil {
|
| 94 | 95 |
t.Fatal(err) |
| 95 | 96 |
} |
| 96 | 97 |
|
| 97 | 98 |
rule1 := []string{
|
| 98 |
- "-i", filterChain.Bridge, |
|
| 99 |
- "-o", filterChain.Bridge, |
|
| 99 |
+ "-i", bridgeName, |
|
| 100 |
+ "-o", bridgeName, |
|
| 100 | 101 |
"-p", proto, |
| 101 | 102 |
"-s", ip1.String(), |
| 102 | 103 |
"-d", ip2.String(), |
| ... | ... |
@@ -108,8 +114,8 @@ func TestLink(t *testing.T) {
|
| 108 | 108 |
} |
| 109 | 109 |
|
| 110 | 110 |
rule2 := []string{
|
| 111 |
- "-i", filterChain.Bridge, |
|
| 112 |
- "-o", filterChain.Bridge, |
|
| 111 |
+ "-i", bridgeName, |
|
| 112 |
+ "-o", bridgeName, |
|
| 113 | 113 |
"-p", proto, |
| 114 | 114 |
"-s", ip2.String(), |
| 115 | 115 |
"-d", ip1.String(), |
| ... | ... |
@@ -192,7 +198,7 @@ func RunConcurrencyTest(t *testing.T, allowXlock bool) {
|
| 192 | 192 |
wg.Add(1) |
| 193 | 193 |
go func() {
|
| 194 | 194 |
defer wg.Done() |
| 195 |
- err := natChain.Forward(Append, ip, port, proto, dstAddr, dstPort) |
|
| 195 |
+ err := natChain.Forward(Append, ip, port, proto, dstAddr, dstPort, "lo") |
|
| 196 | 196 |
if err != nil {
|
| 197 | 197 |
t.Fatal(err) |
| 198 | 198 |
} |
| ... | ... |
@@ -208,7 +214,7 @@ func TestCleanup(t *testing.T) {
|
| 208 | 208 |
// Cleanup filter/FORWARD first otherwise output of iptables-save is dirty |
| 209 | 209 |
link := []string{"-t", string(filterChain.Table),
|
| 210 | 210 |
string(Delete), "FORWARD", |
| 211 |
- "-o", filterChain.Bridge, |
|
| 211 |
+ "-o", bridgeName, |
|
| 212 | 212 |
"-j", filterChain.Name} |
| 213 | 213 |
if _, err = Raw(link...); err != nil {
|
| 214 | 214 |
t.Fatal(err) |
| ... | ... |
@@ -251,10 +251,9 @@ func TestBridge(t *testing.T) {
|
| 251 | 251 |
"FixedCIDR": cidr, |
| 252 | 252 |
"FixedCIDRv6": cidrv6, |
| 253 | 253 |
"EnableIPv6": true, |
| 254 |
- "EnableIPTables": true, |
|
| 255 |
- "EnableIPMasquerade": true, |
|
| 256 | 254 |
"EnableICC": true, |
| 257 | 255 |
"AllowNonDefaultBridge": true, |
| 256 |
+ "EnableIPMasquerade": true, |
|
| 258 | 257 |
}, |
| 259 | 258 |
} |
| 260 | 259 |
|
| ... | ... |
@@ -31,7 +31,8 @@ var ( |
| 31 | 31 |
|
| 32 | 32 |
// PortMapper manages the network address translation |
| 33 | 33 |
type PortMapper struct {
|
| 34 |
- chain *iptables.Chain |
|
| 34 |
+ chain *iptables.ChainInfo |
|
| 35 |
+ bridgeName string |
|
| 35 | 36 |
|
| 36 | 37 |
// udp:ip:port |
| 37 | 38 |
currentMappings map[string]*mapping |
| ... | ... |
@@ -54,8 +55,9 @@ func NewWithPortAllocator(allocator *portallocator.PortAllocator) *PortMapper {
|
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 | 56 |
// SetIptablesChain sets the specified chain into portmapper |
| 57 |
-func (pm *PortMapper) SetIptablesChain(c *iptables.Chain) {
|
|
| 57 |
+func (pm *PortMapper) SetIptablesChain(c *iptables.ChainInfo, bridgeName string) {
|
|
| 58 | 58 |
pm.chain = c |
| 59 |
+ pm.bridgeName = bridgeName |
|
| 59 | 60 |
} |
| 60 | 61 |
|
| 61 | 62 |
// Map maps the specified container transport address to the host's network address and transport port |
| ... | ... |
@@ -215,5 +217,5 @@ func (pm *PortMapper) forward(action iptables.Action, proto string, sourceIP net |
| 215 | 215 |
if pm.chain == nil {
|
| 216 | 216 |
return nil |
| 217 | 217 |
} |
| 218 |
- return pm.chain.Forward(action, sourceIP, sourcePort, proto, containerIP, containerPort) |
|
| 218 |
+ return pm.chain.Forward(action, sourceIP, sourcePort, proto, containerIP, containerPort, pm.bridgeName) |
|
| 219 | 219 |
} |
| ... | ... |
@@ -17,16 +17,15 @@ func init() {
|
| 17 | 17 |
func TestSetIptablesChain(t *testing.T) {
|
| 18 | 18 |
pm := New() |
| 19 | 19 |
|
| 20 |
- c := &iptables.Chain{
|
|
| 21 |
- Name: "TEST", |
|
| 22 |
- Bridge: "192.168.1.1", |
|
| 20 |
+ c := &iptables.ChainInfo{
|
|
| 21 |
+ Name: "TEST", |
|
| 23 | 22 |
} |
| 24 | 23 |
|
| 25 | 24 |
if pm.chain != nil {
|
| 26 | 25 |
t.Fatal("chain should be nil at init")
|
| 27 | 26 |
} |
| 28 | 27 |
|
| 29 |
- pm.SetIptablesChain(c) |
|
| 28 |
+ pm.SetIptablesChain(c, "lo") |
|
| 30 | 29 |
if pm.chain == nil {
|
| 31 | 30 |
t.Fatal("chain should not be nil after set")
|
| 32 | 31 |
} |