diff --git a/libnetwork/drivers/bridge/setup.go b/libnetwork/drivers/bridge/setup.go index c0cbbe98ae..b9d05a3b6e 100644 --- a/libnetwork/drivers/bridge/setup.go +++ b/libnetwork/drivers/bridge/setup.go @@ -29,7 +29,3 @@ func (b *BridgeSetup) QueueStep(step SetupStep) { func SetupIPTables(i *Interface) error { return nil } - -func SetupIPForwarding(i *Interface) error { - return nil -} diff --git a/libnetwork/drivers/bridge/setup_ip_forwarding.go b/libnetwork/drivers/bridge/setup_ip_forwarding.go new file mode 100644 index 0000000000..a8e58e90cd --- /dev/null +++ b/libnetwork/drivers/bridge/setup_ip_forwarding.go @@ -0,0 +1,20 @@ +package bridge + +import ( + "fmt" + "io/ioutil" +) + +const ( + IPV4_FORW_CONF_FILE = "/proc/sys/net/ipv4/ip_forward" + PERM = 0644 +) + +func SetupIPForwarding(i *Interface) error { + // Sanity Check + if i.Config.EnableIPForwarding == false { + return fmt.Errorf("Unexpected request to enable IP Forwarding for: %v", *i) + } + // Enable IPv4 forwarding + return ioutil.WriteFile(IPV4_FORW_CONF_FILE, []byte{'1', '\n'}, PERM) +} diff --git a/libnetwork/drivers/bridge/setup_ip_forwarding_test.go b/libnetwork/drivers/bridge/setup_ip_forwarding_test.go new file mode 100644 index 0000000000..a5b87befa1 --- /dev/null +++ b/libnetwork/drivers/bridge/setup_ip_forwarding_test.go @@ -0,0 +1,78 @@ +package bridge + +import ( + "bytes" + "io/ioutil" + "testing" +) + +func TestSetupIPForwarding(t *testing.T) { + // Read current setting and ensure the original value gets restored + procSetting := readCurrentIPForwardingSetting(t) + defer reconcileIPForwardingSetting(t, procSetting) + + // Disable IP Forwarding if enabled + if bytes.Compare(procSetting, []byte("1\n")) == 0 { + writeIPForwardingSetting(t, []byte{'0', '\n'}) + } + + // Create test interface with ip forwarding setting enabled + br := &Interface{ + Config: &Configuration{ + BridgeName: DefaultBridgeName, + EnableIPForwarding: true, + }, + } + + // Set IP Forwarding + if err := SetupIPForwarding(br); err != nil { + t.Fatalf("Failed to setup IP forwarding: %v", err) + } + + // Read new setting + procSetting = readCurrentIPForwardingSetting(t) + if bytes.Compare(procSetting, []byte("1\n")) != 0 { + t.Fatalf("Failed to effectively setup IP forwarding") + } +} + +func TestUnexpectedSetupIPForwarding(t *testing.T) { + // Read current setting and ensure the original value gets restored + procSetting := readCurrentIPForwardingSetting(t) + defer reconcileIPForwardingSetting(t, procSetting) + + // Create test interface without ip forwarding setting enabled + br := &Interface{ + Config: &Configuration{ + BridgeName: DefaultBridgeName, + EnableIPForwarding: false, + }, + } + + // Attempt Set IP Forwarding + if err := SetupIPForwarding(br); err == nil { + t.Fatalf(err.Error()) + } +} + +func readCurrentIPForwardingSetting(t *testing.T) []byte { + procSetting, err := ioutil.ReadFile(IPV4_FORW_CONF_FILE) + if err != nil { + t.Fatalf("Can't execute test: Failed to read current IP forwarding setting: %v", err) + } + return procSetting +} + +func writeIPForwardingSetting(t *testing.T, chars []byte) { + err := ioutil.WriteFile(IPV4_FORW_CONF_FILE, chars, PERM) + if err != nil { + t.Fatalf("Can't execute or cleanup after test: Failed to reset IP forwarding: %v", err) + } +} + +func reconcileIPForwardingSetting(t *testing.T, original []byte) { + current := readCurrentIPForwardingSetting(t) + if bytes.Compare(original, current) != 0 { + writeIPForwardingSetting(t, original) + } +}