Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

network: move ipmasq management into platform-specific files #854

Merged
merged 1 commit into from
Nov 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 1 addition & 22 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"strings"
"syscall"

"github.com/coreos/go-iptables/iptables"
"github.com/coreos/pkg/flagutil"
log "github.com/golang/glog"
"golang.org/x/net/context"
Expand Down Expand Up @@ -285,7 +284,7 @@ func main() {

// Set up ipMasq if needed
if opts.ipMasq {
go setupIPMasq(config, bn)
go network.SetupAndEnsureIPMasq(config.Network, bn.Lease())
}

if err := WriteSubnetFile(opts.subnetFile, config.Network, opts.ipMasq, bn); err != nil {
Expand Down Expand Up @@ -553,26 +552,6 @@ func mustRunHealthz() {
}
}

func setupIPMasq(config *subnet.Config, bn backend.Network) {
ipt, err := iptables.New()
if err != nil {
// if we can't find iptables, give up and return
log.Errorf("Failed to set up IP Masquerade. iptables was not found: %v", err)
return
}
defer func() {
network.TeardownIPMasq(ipt, config.Network, bn.Lease())
}()
for {
// Ensure that all the rules exist every 5 seconds
if err := network.EnsureIPMasq(ipt, config.Network, bn.Lease()); err != nil {
log.Errorf("Failed to ensure IP Masquerade: %v", err)
}
time.Sleep(5 * time.Second)
}

}

func ReadSubnetFromSubnetFile(path string) ip.IP4Net {
var prevSubnet ip.IP4Net
if _, err := os.Stat(path); !os.IsNotExist(err) {
Expand Down
34 changes: 29 additions & 5 deletions network/ipmasq.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (

"github.com/coreos/flannel/pkg/ip"
"github.com/coreos/flannel/subnet"
"github.com/coreos/go-iptables/iptables"
"time"
)

type IPTablesRules interface {
Expand Down Expand Up @@ -61,7 +63,29 @@ func ipMasqRulesExist(ipt IPTablesRules, ipn ip.IP4Net, lease *subnet.Lease) (bo
return true, nil
}

func EnsureIPMasq(ipt IPTablesRules, ipn ip.IP4Net, lease *subnet.Lease) error {
func SetupAndEnsureIPMasq(network ip.IP4Net, lease *subnet.Lease) {
ipt, err := iptables.New()
if err != nil {
// if we can't find iptables, give up and return
log.Errorf("Failed to setup IP Masquerade. IPTables was not found: %v", err)
return
}

defer func() {
teardownIPMasq(ipt, network, lease)
}()

for {
// Ensure that all the rules exist every 5 seconds
if err := ensureIPMasq(ipt, network, lease); err != nil {
log.Errorf("Failed to ensure IP Masquerade: %v", err)
}

time.Sleep(5 * time.Second)
}
}

func ensureIPMasq(ipt IPTablesRules, ipn ip.IP4Net, lease *subnet.Lease) error {
exists, err := ipMasqRulesExist(ipt, ipn, lease)
if err != nil {
return fmt.Errorf("Error checking rule existence: %v", err)
Expand All @@ -73,14 +97,14 @@ func EnsureIPMasq(ipt IPTablesRules, ipn ip.IP4Net, lease *subnet.Lease) error {
// Otherwise, teardown all the rules and set them up again
// We do this because the order of the rules is important
log.Info("Some iptables rules are missing; deleting and recreating rules")
TeardownIPMasq(ipt, ipn, lease)
if err = SetupIPMasq(ipt, ipn, lease); err != nil {
teardownIPMasq(ipt, ipn, lease)
if err = setupIPMasq(ipt, ipn, lease); err != nil {
return fmt.Errorf("Error setting up rules: %v", err)
}
return nil
}

func SetupIPMasq(ipt IPTablesRules, ipn ip.IP4Net, lease *subnet.Lease) error {
func setupIPMasq(ipt IPTablesRules, ipn ip.IP4Net, lease *subnet.Lease) error {
for _, rule := range rules(ipn, lease) {
log.Info("Adding iptables rule: ", strings.Join(rule, " "))
err := ipt.AppendUnique("nat", "POSTROUTING", rule...)
Expand All @@ -92,7 +116,7 @@ func SetupIPMasq(ipt IPTablesRules, ipn ip.IP4Net, lease *subnet.Lease) error {
return nil
}

func TeardownIPMasq(ipt IPTablesRules, ipn ip.IP4Net, lease *subnet.Lease) {
func teardownIPMasq(ipt IPTablesRules, ipn ip.IP4Net, lease *subnet.Lease) {
for _, rule := range rules(ipn, lease) {
log.Info("Deleting iptables rule: ", strings.Join(rule, " "))
// We ignore errors here because if there's an error it's almost certainly because the rule
Expand Down
14 changes: 7 additions & 7 deletions network/ipmasq_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ func (mock *MockIPTables) AppendUnique(table string, chain string, rulespec ...s

func TestDeleteRules(t *testing.T) {
ipt := &MockIPTables{}
SetupIPMasq(ipt, ip.IP4Net{}, lease())
setupIPMasq(ipt, ip.IP4Net{}, lease())
if len(ipt.rules) != 4 {
t.Errorf("Should be 4 rules, there are actually %d: %#v", len(ipt.rules), ipt.rules)
}
TeardownIPMasq(ipt, ip.IP4Net{}, lease())
teardownIPMasq(ipt, ip.IP4Net{}, lease())
if len(ipt.rules) != 0 {
t.Errorf("Should be 0 rules, there are actually %d: %#v", len(ipt.rules), ipt.rules)
}
Expand All @@ -87,13 +87,13 @@ func TestDeleteRules(t *testing.T) {
func TestEnsureRules(t *testing.T) {
// If any rules are missing, they should be all deleted and recreated in the correct order
ipt_correct := &MockIPTables{}
SetupIPMasq(ipt_correct, ip.IP4Net{}, lease())
// setup a mock instance where we delete some rules and run `EnsureIPMasq`
setupIPMasq(ipt_correct, ip.IP4Net{}, lease())
// setup a mock instance where we delete some rules and run `ensureIPMasq`
ipt_recreate := &MockIPTables{}
SetupIPMasq(ipt_recreate, ip.IP4Net{}, lease())
setupIPMasq(ipt_recreate, ip.IP4Net{}, lease())
ipt_recreate.rules = ipt_recreate.rules[0:2]
EnsureIPMasq(ipt_recreate, ip.IP4Net{}, lease())
ensureIPMasq(ipt_recreate, ip.IP4Net{}, lease())
if !reflect.DeepEqual(ipt_recreate.rules, ipt_correct.rules) {
t.Errorf("iptables rules after EnsureIPMasq are incorrected. Expected: %#v, Actual: %#v", ipt_recreate.rules, ipt_correct.rules)
t.Errorf("iptables rules after ensureIPMasq are incorrected. Expected: %#v, Actual: %#v", ipt_recreate.rules, ipt_correct.rules)
}
}