From 2d46bb0afcdda225edb36236bf54cf1baa2a392a Mon Sep 17 00:00:00 2001 From: Thomas Ferrandiz Date: Wed, 7 Feb 2024 10:10:02 +0000 Subject: [PATCH] refactor iptables package to prepare for nftables-based implementation There is now a trafficmngr package that declares the TrafficManager interface. This will allow us to have multiple implementation to manage NATing and forwarding the traffic. --- Makefile | 2 +- main.go | 57 ++++---- pkg/iptables/iptables_windows.go | 46 ------ pkg/{ => trafficmngr}/iptables/iptables.go | 132 +++++++++--------- .../iptables/iptables_restore.go | 0 .../iptables/iptables_restore_test.go | 0 .../iptables/iptables_test.go | 76 +++++----- pkg/trafficmngr/iptables/iptables_windows.go | 50 +++++++ pkg/trafficmngr/trafficmngr.go | 39 ++++++ 9 files changed, 225 insertions(+), 177 deletions(-) delete mode 100644 pkg/iptables/iptables_windows.go rename pkg/{ => trafficmngr}/iptables/iptables.go (60%) rename pkg/{ => trafficmngr}/iptables/iptables_restore.go (100%) rename pkg/{ => trafficmngr}/iptables/iptables_restore_test.go (100%) rename pkg/{ => trafficmngr}/iptables/iptables_test.go (75%) create mode 100644 pkg/trafficmngr/iptables/iptables_windows.go create mode 100644 pkg/trafficmngr/trafficmngr.go diff --git a/Makefile b/Makefile index 6773581ea3..19f6135132 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ K8S_VERSION=1.24.6 GOARM=7 # These variables can be overridden by setting an environment variable. -TEST_PACKAGES?=pkg/ip pkg/subnet pkg/subnet/etcd pkg/subnet/kube pkg/iptables pkg/backend +TEST_PACKAGES?=pkg/ip pkg/subnet pkg/subnet/etcd pkg/subnet/kube pkg/trafficmngr pkg/backend TEST_PACKAGES_EXPANDED=$(TEST_PACKAGES:%=github.com/flannel-io/flannel/%) PACKAGES?=$(TEST_PACKAGES) PACKAGES_EXPANDED=$(PACKAGES:%=github.com/flannel-io/flannel/%) diff --git a/main.go b/main.go index 147db1d752..fb8aa71bcd 100644 --- a/main.go +++ b/main.go @@ -31,11 +31,12 @@ import ( "github.com/coreos/pkg/flagutil" "github.com/flannel-io/flannel/pkg/ip" "github.com/flannel-io/flannel/pkg/ipmatch" - "github.com/flannel-io/flannel/pkg/iptables" "github.com/flannel-io/flannel/pkg/lease" "github.com/flannel-io/flannel/pkg/subnet" etcd "github.com/flannel-io/flannel/pkg/subnet/etcd" "github.com/flannel-io/flannel/pkg/subnet/kube" + "github.com/flannel-io/flannel/pkg/trafficmngr" + "github.com/flannel-io/flannel/pkg/trafficmngr/iptables" "github.com/flannel-io/flannel/pkg/version" "golang.org/x/net/context" log "k8s.io/klog/v2" @@ -335,6 +336,8 @@ func main() { os.Exit(1) } + //Create TrafficManager and instanciate it based on whether we use iptables or nftables + trafficMngr := newTrafficManager() // Set up ipMasq if needed if opts.ipMasq { if config.EnableIPv4 { @@ -345,22 +348,22 @@ func main() { wg.Wait() os.Exit(1) } - if err = recycleIPTables(net, bn.Lease()); err != nil { + if err = recycleIPTables(trafficMngr, net, bn.Lease()); err != nil { log.Errorf("Failed to recycle IPTables rules, %v", err) cancel() wg.Wait() os.Exit(1) } log.Infof("Setting up masking rules") - iptables.CreateIP4Chain("nat", "FLANNEL-POSTRTG") - getRules := func() []iptables.IPTablesRule { + trafficMngr.CreateIP4Chain("nat", "FLANNEL-POSTRTG") + getRules := func() []trafficmngr.IPTablesRule { if config.HasNetworks() { - return iptables.MasqRules(config.Networks, bn.Lease()) + return trafficMngr.MasqRules(config.Networks, bn.Lease()) } else { - return iptables.MasqRules([]ip.IP4Net{config.Network}, bn.Lease()) + return trafficMngr.MasqRules([]ip.IP4Net{config.Network}, bn.Lease()) } } - go iptables.SetupAndEnsureIP4Tables(getRules, opts.iptablesResyncSeconds) + go trafficMngr.SetupAndEnsureIP4Tables(getRules, opts.iptablesResyncSeconds) } if config.EnableIPv6 { @@ -371,22 +374,22 @@ func main() { wg.Wait() os.Exit(1) } - if err = recycleIP6Tables(ip6net, bn.Lease()); err != nil { + if err = recycleIP6Tables(trafficMngr, ip6net, bn.Lease()); err != nil { log.Errorf("Failed to recycle IP6Tables rules, %v", err) cancel() wg.Wait() os.Exit(1) } log.Infof("Setting up masking ip6 rules") - iptables.CreateIP6Chain("nat", "FLANNEL-POSTRTG") - getRules := func() []iptables.IPTablesRule { + trafficMngr.CreateIP6Chain("nat", "FLANNEL-POSTRTG") + getRules := func() []trafficmngr.IPTablesRule { if config.HasIPv6Networks() { - return iptables.MasqIP6Rules(config.IPv6Networks, bn.Lease()) + return trafficMngr.MasqIP6Rules(config.IPv6Networks, bn.Lease()) } else { - return iptables.MasqIP6Rules([]ip.IP6Net{config.IPv6Network}, bn.Lease()) + return trafficMngr.MasqIP6Rules([]ip.IP6Net{config.IPv6Network}, bn.Lease()) } } - go iptables.SetupAndEnsureIP6Tables(getRules, opts.iptablesResyncSeconds) + go trafficMngr.SetupAndEnsureIP6Tables(getRules, opts.iptablesResyncSeconds) } } @@ -403,11 +406,11 @@ func main() { os.Exit(1) } log.Infof("Changing default FORWARD chain policy to ACCEPT") - iptables.CreateIP4Chain("filter", "FLANNEL-FWD") - getRules := func() []iptables.IPTablesRule { - return iptables.ForwardRules(net.String()) + trafficMngr.CreateIP4Chain("filter", "FLANNEL-FWD") + getRules := func() []trafficmngr.IPTablesRule { + return trafficMngr.ForwardRules(net.String()) } - go iptables.SetupAndEnsureIP4Tables(getRules, opts.iptablesResyncSeconds) + go trafficMngr.SetupAndEnsureIP4Tables(getRules, opts.iptablesResyncSeconds) } if config.EnableIPv6 { ip6net, err := config.GetFlannelIPv6Network(&bn.Lease().IPv6Subnet) @@ -418,11 +421,11 @@ func main() { os.Exit(1) } log.Infof("IPv6: Changing default FORWARD chain policy to ACCEPT") - iptables.CreateIP6Chain("filter", "FLANNEL-FWD") - getRules := func() []iptables.IPTablesRule { - return iptables.ForwardRules(ip6net.String()) + trafficMngr.CreateIP6Chain("filter", "FLANNEL-FWD") + getRules := func() []trafficmngr.IPTablesRule { + return trafficMngr.ForwardRules(ip6net.String()) } - go iptables.SetupAndEnsureIP6Tables(getRules, opts.iptablesResyncSeconds) + go trafficMngr.SetupAndEnsureIP6Tables(getRules, opts.iptablesResyncSeconds) } } @@ -462,7 +465,7 @@ func main() { os.Exit(0) } -func recycleIPTables(nw ip.IP4Net, myLease *lease.Lease) error { +func recycleIPTables(tm trafficmngr.TrafficManager, nw ip.IP4Net, myLease *lease.Lease) error { prevNetworks := ReadCIDRsFromSubnetFile(opts.subnetFile, "FLANNEL_NETWORK") prevSubnet := ReadCIDRFromSubnetFile(opts.subnetFile, "FLANNEL_SUBNET") @@ -480,14 +483,14 @@ func recycleIPTables(nw ip.IP4Net, myLease *lease.Lease) error { newLease := &lease.Lease{ Subnet: prevSubnet, } - if err := iptables.DeleteIP4Tables(iptables.MasqRules(prevNetworks, newLease)); err != nil { + if err := tm.DeleteIP4Tables(tm.MasqRules(prevNetworks, newLease)); err != nil { return err } } return nil } -func recycleIP6Tables(nw ip.IP6Net, myLease *lease.Lease) error { +func recycleIP6Tables(tm trafficmngr.TrafficManager, nw ip.IP6Net, myLease *lease.Lease) error { prevNetworks := ReadIP6CIDRsFromSubnetFile(opts.subnetFile, "FLANNEL_IPV6_NETWORK") prevSubnet := ReadIP6CIDRFromSubnetFile(opts.subnetFile, "FLANNEL_IPV6_SUBNET") @@ -506,7 +509,7 @@ func recycleIP6Tables(nw ip.IP6Net, myLease *lease.Lease) error { lease := &lease.Lease{ IPv6Subnet: prevSubnet, } - if err := iptables.DeleteIP6Tables(iptables.MasqIP6Rules(prevNetworks, lease)); err != nil { + if err := tm.DeleteIP6Tables(tm.MasqIP6Rules(prevNetworks, lease)); err != nil { return err } } @@ -656,3 +659,7 @@ func ReadIP6CIDRsFromSubnetFile(path string, CIDRKey string) []ip.IP6Net { } return prevCIDRs } + +func newTrafficManager() trafficmngr.TrafficManager { + return iptables.IPTablesManager{} +} diff --git a/pkg/iptables/iptables_windows.go b/pkg/iptables/iptables_windows.go deleted file mode 100644 index e29e9723a1..0000000000 --- a/pkg/iptables/iptables_windows.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2015 flannel authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package iptables - -import ( - "github.com/flannel-io/flannel/pkg/ip" - "github.com/flannel-io/flannel/pkg/lease" -) - -type IPTables interface { - AppendUnique(table string, chain string, rulespec ...string) error - ChainExists(table, chain string) (bool, error) - ClearChain(table, chain string) error - Delete(table string, chain string, rulespec ...string) error - Exists(table string, chain string, rulespec ...string) (bool, error) -} - -type IPTablesRule struct { - table string - action string - chain string - rulespec []string -} - -func CreateIP4Chain(table, chain string) { return } -func CreateIP6Chain(table, chain string) { return } -func MasqRules(cluster_cidrs []ip.IP4Net, lease *lease.Lease) []IPTablesRule { return nil } -func ForwardRules(flannelNetwork string) []IPTablesRule { return nil } -func teardownIPTables(ipt IPTables, rules []IPTablesRule) {} -func SetupAndEnsureIP4Tables(getRules func() []IPTablesRule, resyncPeriod int) {} -func SetupAndEnsureIP6Tables(getRules func() []IPTablesRule, resyncPeriod int) {} -func MasqIP6Rules(cluster_cidrs []ip.IP6Net, lease *lease.Lease) []IPTablesRule { return nil } -func DeleteIP4Tables(rules []IPTablesRule) error { return nil } -func DeleteIP6Tables(rules []IPTablesRule) error { return nil } diff --git a/pkg/iptables/iptables.go b/pkg/trafficmngr/iptables/iptables.go similarity index 60% rename from pkg/iptables/iptables.go rename to pkg/trafficmngr/iptables/iptables.go index e46c8f8199..a7e5315239 100644 --- a/pkg/iptables/iptables.go +++ b/pkg/trafficmngr/iptables/iptables.go @@ -23,6 +23,7 @@ import ( "github.com/coreos/go-iptables/iptables" "github.com/flannel-io/flannel/pkg/ip" "github.com/flannel-io/flannel/pkg/lease" + "github.com/flannel-io/flannel/pkg/trafficmngr" log "k8s.io/klog/v2" ) @@ -39,95 +40,90 @@ type IPTablesError interface { Error() string } -type IPTablesRule struct { - table string - action string - chain string - rulespec []string -} +type IPTablesManager struct{} const kubeProxyMark string = "0x4000/0x4000" -func MasqRules(cluster_cidrs []ip.IP4Net, lease *lease.Lease) []IPTablesRule { +func (iptm IPTablesManager) MasqRules(cluster_cidrs []ip.IP4Net, lease *lease.Lease) []trafficmngr.IPTablesRule { pod_cidr := lease.Subnet.String() ipt, err := iptables.New() supports_random_fully := false if err == nil { supports_random_fully = ipt.HasRandomFully() } - rules := make([]IPTablesRule, 2) + rules := make([]trafficmngr.IPTablesRule, 2) // This rule ensure that the flannel iptables rules are executed before other rules on the node - rules[0] = IPTablesRule{"nat", "-A", "POSTROUTING", []string{"-m", "comment", "--comment", "flanneld masq", "-j", "FLANNEL-POSTRTG"}} + rules[0] = trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-m", "comment", "--comment", "flanneld masq", "-j", "FLANNEL-POSTRTG"}} // This rule will not masquerade traffic marked by the kube-proxy to avoid double NAT bug on some kernel version - rules[1] = IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-m", "mark", "--mark", kubeProxyMark, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}} + rules[1] = trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-m", "mark", "--mark", kubeProxyMark, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}} for _, ccidr := range cluster_cidrs { cluster_cidr := ccidr.String() // This rule makes sure we don't NAT traffic within overlay network (e.g. coming out of docker0), for any of the cluster_cidrs rules = append(rules, - IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-s", pod_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, - IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-s", cluster_cidr, "-d", pod_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, + trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-s", pod_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, + trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-s", cluster_cidr, "-d", pod_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, ) } for _, ccidr := range cluster_cidrs { cluster_cidr := ccidr.String() // Prevent performing Masquerade on external traffic which arrives from a Node that owns the container/pod IP address - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"!", "-s", cluster_cidr, "-d", pod_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"!", "-s", cluster_cidr, "-d", pod_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}) } for _, ccidr := range cluster_cidrs { cluster_cidr := ccidr.String() // NAT if it's not multicast traffic if supports_random_fully { - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-s", cluster_cidr, "!", "-d", "224.0.0.0/4", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-s", cluster_cidr, "!", "-d", "224.0.0.0/4", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}) } else { - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-s", cluster_cidr, "!", "-d", "224.0.0.0/4", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-s", cluster_cidr, "!", "-d", "224.0.0.0/4", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE"}}) } } for _, ccidr := range cluster_cidrs { cluster_cidr := ccidr.String() // Masquerade anything headed towards flannel from the host if supports_random_fully { - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"!", "-s", cluster_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"!", "-s", cluster_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}) } else { - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"!", "-s", cluster_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"!", "-s", cluster_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE"}}) } } return rules } -func MasqIP6Rules(cluster_cidrs []ip.IP6Net, lease *lease.Lease) []IPTablesRule { +func (iptm IPTablesManager) MasqIP6Rules(cluster_cidrs []ip.IP6Net, lease *lease.Lease) []trafficmngr.IPTablesRule { pod_cidr := lease.IPv6Subnet.String() ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv6) supports_random_fully := false if err == nil { supports_random_fully = ipt.HasRandomFully() } - rules := make([]IPTablesRule, 2) + rules := make([]trafficmngr.IPTablesRule, 2) // This rule ensure that the flannel iptables rules are executed before other rules on the node - rules[0] = IPTablesRule{"nat", "-A", "POSTROUTING", []string{"-m", "comment", "--comment", "flanneld masq", "-j", "FLANNEL-POSTRTG"}} + rules[0] = trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-m", "comment", "--comment", "flanneld masq", "-j", "FLANNEL-POSTRTG"}} // This rule will not masquerade traffic marked by the kube-proxy to avoid double NAT bug on some kernel version - rules[1] = IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-m", "mark", "--mark", kubeProxyMark, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}} + rules[1] = trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-m", "mark", "--mark", kubeProxyMark, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}} for _, ccidr := range cluster_cidrs { cluster_cidr := ccidr.String() // This rule makes sure we don't NAT traffic within overlay network (e.g. coming out of docker0), for any of the cluster_cidrs rules = append(rules, - IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-s", pod_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, - IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-s", cluster_cidr, "-d", pod_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, + trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-s", pod_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, + trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-s", cluster_cidr, "-d", pod_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, ) } for _, ccidr := range cluster_cidrs { cluster_cidr := ccidr.String() // Prevent performing Masquerade on external traffic which arrives from a Node that owns the container/pod IP address - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"!", "-s", cluster_cidr, "-d", pod_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"!", "-s", cluster_cidr, "-d", pod_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}) } for _, ccidr := range cluster_cidrs { cluster_cidr := ccidr.String() // NAT if it's not multicast traffic if supports_random_fully { - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-s", cluster_cidr, "!", "-d", "ff00::/8", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-s", cluster_cidr, "!", "-d", "ff00::/8", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}) } else { - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"-s", cluster_cidr, "!", "-d", "ff00::/8", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"-s", cluster_cidr, "!", "-d", "ff00::/8", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE"}}) } } @@ -135,9 +131,9 @@ func MasqIP6Rules(cluster_cidrs []ip.IP6Net, lease *lease.Lease) []IPTablesRule cluster_cidr := ccidr.String() // Masquerade anything headed towards flannel from the host if supports_random_fully { - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"!", "-s", cluster_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"!", "-s", cluster_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}) } else { - rules = append(rules, IPTablesRule{"nat", "-A", "FLANNEL-POSTRTG", []string{"!", "-s", cluster_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE"}}) + rules = append(rules, trafficmngr.IPTablesRule{Table: "nat", Action: "-A", Chain: "FLANNEL-POSTRTG", Rulespec: []string{"!", "-s", cluster_cidr, "-d", cluster_cidr, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE"}}) } } @@ -145,17 +141,17 @@ func MasqIP6Rules(cluster_cidrs []ip.IP6Net, lease *lease.Lease) []IPTablesRule return rules } -func ForwardRules(flannelNetwork string) []IPTablesRule { - return []IPTablesRule{ +func (iptm IPTablesManager) ForwardRules(flannelNetwork string) []trafficmngr.IPTablesRule { + return []trafficmngr.IPTablesRule{ // This rule ensure that the flannel iptables rules are executed before other rules on the node - {"filter", "-A", "FORWARD", []string{"-m", "comment", "--comment", "flanneld forward", "-j", "FLANNEL-FWD"}}, + {Table: "filter", Action: "-A", Chain: "FORWARD", Rulespec: []string{"-m", "comment", "--comment", "flanneld forward", "-j", "FLANNEL-FWD"}}, // These rules allow traffic to be forwarded if it is to or from the flannel network range. - {"filter", "-A", "FLANNEL-FWD", []string{"-s", flannelNetwork, "-m", "comment", "--comment", "flanneld forward", "-j", "ACCEPT"}}, - {"filter", "-A", "FLANNEL-FWD", []string{"-d", flannelNetwork, "-m", "comment", "--comment", "flanneld forward", "-j", "ACCEPT"}}, + {Table: "filter", Action: "-A", Chain: "FLANNEL-FWD", Rulespec: []string{"-s", flannelNetwork, "-m", "comment", "--comment", "flanneld forward", "-j", "ACCEPT"}}, + {Table: "filter", Action: "-A", Chain: "FLANNEL-FWD", Rulespec: []string{"-d", flannelNetwork, "-m", "comment", "--comment", "flanneld forward", "-j", "ACCEPT"}}, } } -func CreateIP4Chain(table, chain string) { +func (iptm IPTablesManager) CreateIP4Chain(table, chain string) { ipt, err := iptables.New() if err != nil { // if we can't find iptables, give up and return @@ -170,7 +166,7 @@ func CreateIP4Chain(table, chain string) { } } -func CreateIP6Chain(table, chain string) { +func (iptm IPTablesManager) CreateIP6Chain(table, chain string) { ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv6) if err != nil { // if we can't find iptables, give up and return @@ -185,18 +181,18 @@ func CreateIP6Chain(table, chain string) { } } -func ipTablesRulesExist(ipt IPTables, rules []IPTablesRule) (bool, error) { +func ipTablesRulesExist(ipt IPTables, rules []trafficmngr.IPTablesRule) (bool, error) { for _, rule := range rules { - if rule.chain == "FLANNEL-FWD" || rule.rulespec[len(rule.rulespec)-1] == "FLANNEL-FWD" { - chainExist, err := ipt.ChainExists(rule.table, "FLANNEL-FWD") + if rule.Chain == "FLANNEL-FWD" || rule.Rulespec[len(rule.Rulespec)-1] == "FLANNEL-FWD" { + chainExist, err := ipt.ChainExists(rule.Table, "FLANNEL-FWD") if err != nil { return false, fmt.Errorf("failed to check rule existence: %v", err) } if !chainExist { return false, nil } - } else if rule.chain == "FLANNEL-POSTRTG" || rule.rulespec[len(rule.rulespec)-1] == "FLANNEL-POSTRTG" { - chainExist, err := ipt.ChainExists(rule.table, "FLANNEL-POSTRTG") + } else if rule.Chain == "FLANNEL-POSTRTG" || rule.Rulespec[len(rule.Rulespec)-1] == "FLANNEL-POSTRTG" { + chainExist, err := ipt.ChainExists(rule.Table, "FLANNEL-POSTRTG") if err != nil { return false, fmt.Errorf("failed to check rule existence: %v", err) } @@ -204,7 +200,7 @@ func ipTablesRulesExist(ipt IPTables, rules []IPTablesRule) (bool, error) { return false, nil } } - exists, err := ipt.Exists(rule.table, rule.chain, rule.rulespec...) + exists, err := ipt.Exists(rule.Table, rule.Chain, rule.Rulespec...) if err != nil { // this shouldn't ever happen return false, fmt.Errorf("failed to check rule existence: %v", err) @@ -218,55 +214,55 @@ func ipTablesRulesExist(ipt IPTables, rules []IPTablesRule) (bool, error) { } // ipTablesCleanAndBuild create from a list of iptables rules a transaction (as string) for iptables-restore for ordering the rules that effectively running -func ipTablesCleanAndBuild(ipt IPTables, rules []IPTablesRule) (IPTablesRestoreRules, error) { +func ipTablesCleanAndBuild(ipt IPTables, rules []trafficmngr.IPTablesRule) (IPTablesRestoreRules, error) { tablesRules := IPTablesRestoreRules{} // Build append and delete rules for _, rule := range rules { - if rule.chain == "FLANNEL-FWD" || rule.rulespec[len(rule.rulespec)-1] == "FLANNEL-FWD" { - chainExist, err := ipt.ChainExists(rule.table, "FLANNEL-FWD") + if rule.Chain == "FLANNEL-FWD" || rule.Rulespec[len(rule.Rulespec)-1] == "FLANNEL-FWD" { + chainExist, err := ipt.ChainExists(rule.Table, "FLANNEL-FWD") if err != nil { return nil, fmt.Errorf("failed to check rule existence: %v", err) } if !chainExist { - err = ipt.ClearChain(rule.table, "FLANNEL-FWD") + err = ipt.ClearChain(rule.Table, "FLANNEL-FWD") if err != nil { return nil, fmt.Errorf("failed to create rule chain: %v", err) } } - } else if rule.chain == "FLANNEL-POSTRTG" || rule.rulespec[len(rule.rulespec)-1] == "FLANNEL-POSTRTG" { - chainExist, err := ipt.ChainExists(rule.table, "FLANNEL-POSTRTG") + } else if rule.Chain == "FLANNEL-POSTRTG" || rule.Rulespec[len(rule.Rulespec)-1] == "FLANNEL-POSTRTG" { + chainExist, err := ipt.ChainExists(rule.Table, "FLANNEL-POSTRTG") if err != nil { return nil, fmt.Errorf("failed to check rule existence: %v", err) } if !chainExist { - err = ipt.ClearChain(rule.table, "FLANNEL-POSTRTG") + err = ipt.ClearChain(rule.Table, "FLANNEL-POSTRTG") if err != nil { return nil, fmt.Errorf("failed to create rule chain: %v", err) } } } - exists, err := ipt.Exists(rule.table, rule.chain, rule.rulespec...) + exists, err := ipt.Exists(rule.Table, rule.Chain, rule.Rulespec...) if err != nil { // this shouldn't ever happen return nil, fmt.Errorf("failed to check rule existence: %v", err) } if exists { - if _, ok := tablesRules[rule.table]; !ok { - tablesRules[rule.table] = []IPTablesRestoreRuleSpec{} + if _, ok := tablesRules[rule.Table]; !ok { + tablesRules[rule.Table] = []IPTablesRestoreRuleSpec{} } // if the rule exists it's safer to delete it and then create them - tablesRules[rule.table] = append(tablesRules[rule.table], append(IPTablesRestoreRuleSpec{"-D", rule.chain}, rule.rulespec...)) + tablesRules[rule.Table] = append(tablesRules[rule.Table], append(IPTablesRestoreRuleSpec{"-D", rule.Chain}, rule.Rulespec...)) } // with iptables-restore we can ensure that all rules created are in good order and have no external rule between them - tablesRules[rule.table] = append(tablesRules[rule.table], append(IPTablesRestoreRuleSpec{rule.action, rule.chain}, rule.rulespec...)) + tablesRules[rule.Table] = append(tablesRules[rule.Table], append(IPTablesRestoreRuleSpec{rule.Action, rule.Chain}, rule.Rulespec...)) } return tablesRules, nil } // ipTablesBootstrap init iptables rules using iptables-restore (with some cleaning if some rules already exists) -func ipTablesBootstrap(ipt IPTables, iptRestore IPTablesRestore, rules []IPTablesRule) error { +func ipTablesBootstrap(ipt IPTables, iptRestore IPTablesRestore, rules []trafficmngr.IPTablesRule) error { tablesRules, err := ipTablesCleanAndBuild(ipt, rules) if err != nil { // if we can't find iptables or if we can check existing rules, give up and return @@ -285,7 +281,7 @@ func ipTablesBootstrap(ipt IPTables, iptRestore IPTablesRestore, rules []IPTable return nil } -func SetupAndEnsureIP4Tables(getRules func() []IPTablesRule, resyncPeriod int) { +func (iptm IPTablesManager) SetupAndEnsureIP4Tables(getRules func() []trafficmngr.IPTablesRule, resyncPeriod int) { rules := getRules() log.Infof("generated %d rules", len(rules)) ipt, err := iptables.New() @@ -324,7 +320,7 @@ func SetupAndEnsureIP4Tables(getRules func() []IPTablesRule, resyncPeriod int) { } } -func SetupAndEnsureIP6Tables(getRules func() []IPTablesRule, resyncPeriod int) { +func (iptm IPTablesManager) SetupAndEnsureIP6Tables(getRules func() []trafficmngr.IPTablesRule, resyncPeriod int) { rules := getRules() ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv6) if err != nil { @@ -363,7 +359,7 @@ func SetupAndEnsureIP6Tables(getRules func() []IPTablesRule, resyncPeriod int) { } // DeleteIP4Tables delete specified iptables rules -func DeleteIP4Tables(rules []IPTablesRule) error { +func (iptm IPTablesManager) DeleteIP4Tables(rules []trafficmngr.IPTablesRule) error { ipt, err := iptables.New() if err != nil { // if we can't find iptables, give up and return @@ -385,7 +381,7 @@ func DeleteIP4Tables(rules []IPTablesRule) error { } // DeleteIP6Tables delete specified iptables rules -func DeleteIP6Tables(rules []IPTablesRule) error { +func (iptm IPTablesManager) DeleteIP6Tables(rules []trafficmngr.IPTablesRule) error { ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv6) if err != nil { // if we can't find iptables, give up and return @@ -407,7 +403,7 @@ func DeleteIP6Tables(rules []IPTablesRule) error { return nil } -func ensureIPTables(ipt IPTables, iptRestore IPTablesRestore, rules []IPTablesRule) error { +func ensureIPTables(ipt IPTables, iptRestore IPTablesRestore, rules []trafficmngr.IPTablesRule) error { exists, err := ipTablesRulesExist(ipt, rules) if err != nil { return fmt.Errorf("error checking rule existence: %v", err) @@ -427,13 +423,13 @@ func ensureIPTables(ipt IPTables, iptRestore IPTablesRestore, rules []IPTablesRu return nil } -func teardownIPTables(ipt IPTables, iptr IPTablesRestore, rules []IPTablesRule) error { +func teardownIPTables(ipt IPTables, iptr IPTablesRestore, rules []trafficmngr.IPTablesRule) error { tablesRules := IPTablesRestoreRules{} // Build delete rules to a transaction for iptables restore for _, rule := range rules { - if rule.chain == "FLANNEL-FWD" || rule.rulespec[len(rule.rulespec)-1] == "FLANNEL-FWD" { - chainExists, err := ipt.ChainExists(rule.table, "FLANNEL-FWD") + if rule.Chain == "FLANNEL-FWD" || rule.Rulespec[len(rule.Rulespec)-1] == "FLANNEL-FWD" { + chainExists, err := ipt.ChainExists(rule.Table, "FLANNEL-FWD") if err != nil { // this shouldn't ever happen return fmt.Errorf("failed to check rule existence: %v", err) @@ -441,8 +437,8 @@ func teardownIPTables(ipt IPTables, iptr IPTablesRestore, rules []IPTablesRule) if !chainExists { continue } - } else if rule.chain == "FLANNEL-POSTRTG" || rule.rulespec[len(rule.rulespec)-1] == "FLANNEL-POSTRTG" { - chainExists, err := ipt.ChainExists(rule.table, "FLANNEL-POSTRTG") + } else if rule.Chain == "FLANNEL-POSTRTG" || rule.Rulespec[len(rule.Rulespec)-1] == "FLANNEL-POSTRTG" { + chainExists, err := ipt.ChainExists(rule.Table, "FLANNEL-POSTRTG") if err != nil { // this shouldn't ever happen return fmt.Errorf("failed to check rule existence: %v", err) @@ -451,16 +447,16 @@ func teardownIPTables(ipt IPTables, iptr IPTablesRestore, rules []IPTablesRule) continue } } - exists, err := ipt.Exists(rule.table, rule.chain, rule.rulespec...) + exists, err := ipt.Exists(rule.Table, rule.Chain, rule.Rulespec...) if err != nil { // this shouldn't ever happen return fmt.Errorf("failed to check rule existence: %v", err) } if exists { - if _, ok := tablesRules[rule.table]; !ok { - tablesRules[rule.table] = []IPTablesRestoreRuleSpec{} + if _, ok := tablesRules[rule.Table]; !ok { + tablesRules[rule.Table] = []IPTablesRestoreRuleSpec{} } - tablesRules[rule.table] = append(tablesRules[rule.table], append(IPTablesRestoreRuleSpec{"-D", rule.chain}, rule.rulespec...)) + tablesRules[rule.Table] = append(tablesRules[rule.Table], append(IPTablesRestoreRuleSpec{"-D", rule.Chain}, rule.Rulespec...)) } } err := iptr.ApplyWithoutFlush(tablesRules) // ApplyWithoutFlush make a diff, Apply make a replace (desired state) diff --git a/pkg/iptables/iptables_restore.go b/pkg/trafficmngr/iptables/iptables_restore.go similarity index 100% rename from pkg/iptables/iptables_restore.go rename to pkg/trafficmngr/iptables/iptables_restore.go diff --git a/pkg/iptables/iptables_restore_test.go b/pkg/trafficmngr/iptables/iptables_restore_test.go similarity index 100% rename from pkg/iptables/iptables_restore_test.go rename to pkg/trafficmngr/iptables/iptables_restore_test.go diff --git a/pkg/iptables/iptables_test.go b/pkg/trafficmngr/iptables/iptables_test.go similarity index 75% rename from pkg/iptables/iptables_test.go rename to pkg/trafficmngr/iptables/iptables_test.go index ac33a84472..376220e46f 100644 --- a/pkg/iptables/iptables_test.go +++ b/pkg/trafficmngr/iptables/iptables_test.go @@ -25,6 +25,7 @@ import ( "github.com/flannel-io/flannel/pkg/ip" "github.com/flannel-io/flannel/pkg/lease" + "github.com/flannel-io/flannel/pkg/trafficmngr" ) func testingLease() *lease.Lease { @@ -37,7 +38,7 @@ func testingLease() *lease.Lease { } type MockIPTables struct { - rules []IPTablesRule + rules []trafficmngr.IPTablesRule t *testing.T failures map[string]*MockIPTablesError } @@ -71,7 +72,7 @@ func (mock *MockIPTablesRestore) ApplyWithoutFlush(rules IPTablesRestoreRules) e func (mock *MockIPTables) ruleIndex(table string, chain string, rulespec []string) int { for i, rule := range mock.rules { - if rule.table == table && rule.chain == chain && reflect.DeepEqual(rule.rulespec, rulespec) { + if rule.Table == table && rule.Chain == chain && reflect.DeepEqual(rule.Rulespec, rulespec) { return i } } @@ -111,7 +112,7 @@ func (mock *MockIPTables) Exists(table string, chain string, rulespec ...string) func (mock *MockIPTables) AppendUnique(table string, chain string, rulespec ...string) error { var ruleIndex = mock.ruleIndex(table, chain, rulespec) if ruleIndex == -1 { - mock.rules = append(mock.rules, IPTablesRule{table: table, chain: chain, rulespec: rulespec}) + mock.rules = append(mock.rules, trafficmngr.IPTablesRule{Table: table, Chain: chain, Rulespec: rulespec}) } return nil } @@ -119,7 +120,8 @@ func (mock *MockIPTables) AppendUnique(table string, chain string, rulespec ...s func TestDeleteRules(t *testing.T) { ipt := &MockIPTables{t: t} iptr := &MockIPTablesRestore{t: t} - baseRules := MasqRules([]ip.IP4Net{{ + iptm := IPTablesManager{} + baseRules := iptm.MasqRules([]ip.IP4Net{{ IP: ip.MustParseIP4("10.0.1.0"), PrefixLen: 16, }}, testingLease()) @@ -152,21 +154,21 @@ func TestDeleteMoreRules(t *testing.T) { ipt := &MockIPTables{} iptr := &MockIPTablesRestore{} - baseRules := []IPTablesRule{ - {"filter", "-A", "INPUT", []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, - {"filter", "-A", "INPUT", []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, - {"nat", "-A", "POSTROUTING", []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, - {"nat", "-A", "POSTROUTING", []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, + baseRules := []trafficmngr.IPTablesRule{ + {Table: "filter", Action: "-A", Chain: "INPUT", Rulespec: []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, + {Table: "filter", Action: "-A", Chain: "INPUT", Rulespec: []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, } expectedRules := IPTablesRestoreRules{ "filter": []IPTablesRestoreRuleSpec{ - IPTablesRestoreRuleSpec{"-D", "INPUT", "-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}, - IPTablesRestoreRuleSpec{"-D", "INPUT", "-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}, + {"-D", "INPUT", "-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}, + {"-D", "INPUT", "-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}, }, "nat": []IPTablesRestoreRuleSpec{ - IPTablesRestoreRuleSpec{"-D", "POSTROUTING", "-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}, - IPTablesRestoreRuleSpec{"-D", "POSTROUTING", "-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}, + {"-D", "POSTROUTING", "-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}, + {"-D", "POSTROUTING", "-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}, }, } @@ -196,11 +198,11 @@ func TestBootstrapRules(t *testing.T) { iptr := &MockIPTablesRestore{} ipt := &MockIPTables{} - baseRules := []IPTablesRule{ - {"filter", "-A", "INPUT", []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, - {"filter", "-A", "INPUT", []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, - {"nat", "-A", "POSTROUTING", []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, - {"nat", "-A", "POSTROUTING", []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, + baseRules := []trafficmngr.IPTablesRule{ + {Table: "filter", Action: "-A", Chain: "INPUT", Rulespec: []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, + {Table: "filter", Action: "-A", Chain: "INPUT", Rulespec: []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, } err := ipTablesBootstrap(ipt, iptr, baseRules) @@ -289,17 +291,17 @@ func TestEnsureRules(t *testing.T) { ipt := &MockIPTables{} // Ensure iptable mock has other rules - otherRules := []IPTablesRule{ - {"nat", "-A", "POSTROUTING", []string{"-A", "POSTROUTING", "-j", "KUBE-POSTROUTING"}}, + otherRules := []trafficmngr.IPTablesRule{ + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-A", "POSTROUTING", "-j", "KUBE-POSTROUTING"}}, } err := setupIPTables(ipt, otherRules) if err != nil { t.Error("Error setting up iptables") } - baseRules := []IPTablesRule{ - {"nat", "-A", "POSTROUTING", []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, - {"nat", "-A", "POSTROUTING", []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, + baseRules := []trafficmngr.IPTablesRule{ + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-s", "127.0.0.1", "-d", "127.0.0.1", "-j", "RETURN"}}, + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-s", "127.0.0.1", "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "--random-fully"}}, } err = ensureIPTables(ipt, iptr, baseRules) @@ -339,8 +341,8 @@ func TestEnsureIP6Rules(t *testing.T) { ipt := &MockIPTables{} // Ensure iptable mock has other rules - otherRules := []IPTablesRule{ - {"nat", "-A", "POSTROUTING", []string{"-A", "POSTROUTING", "-j", "KUBE-POSTROUTING"}}, + otherRules := []trafficmngr.IPTablesRule{ + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-A", "POSTROUTING", "-j", "KUBE-POSTROUTING"}}, } err := setupIPTables(ipt, otherRules) if err != nil { @@ -377,9 +379,9 @@ func TestEnsureIP6Rules(t *testing.T) { } -func setupIPTables(ipt IPTables, rules []IPTablesRule) error { +func setupIPTables(ipt IPTables, rules []trafficmngr.IPTablesRule) error { for _, rule := range rules { - err := ipt.AppendUnique(rule.table, rule.chain, rule.rulespec...) + err := ipt.AppendUnique(rule.Table, rule.Chain, rule.Rulespec...) if err != nil { return fmt.Errorf("failed to insert IPTables rule: %v", err) } @@ -388,27 +390,27 @@ func setupIPTables(ipt IPTables, rules []IPTablesRule) error { return nil } -func expectedTearDownIPTablesRestoreRules(rules []IPTablesRule) []IPTablesRestoreRules { +func expectedTearDownIPTablesRestoreRules(rules []trafficmngr.IPTablesRule) []IPTablesRestoreRules { tablesRules := IPTablesRestoreRules{} for _, rule := range rules { - if _, ok := tablesRules[rule.table]; !ok { - tablesRules[rule.table] = []IPTablesRestoreRuleSpec{} + if _, ok := tablesRules[rule.Table]; !ok { + tablesRules[rule.Table] = []IPTablesRestoreRuleSpec{} } - tablesRules[rule.table] = append(tablesRules[rule.table], append(IPTablesRestoreRuleSpec{"-D", rule.chain}, rule.rulespec...)) + tablesRules[rule.Table] = append(tablesRules[rule.Table], append(IPTablesRestoreRuleSpec{"-D", rule.Chain}, rule.Rulespec...)) } return []IPTablesRestoreRules{tablesRules} } -func IP6Rules(ipn ip.IP6Net, lease *lease.Lease) []IPTablesRule { +func IP6Rules(ipn ip.IP6Net, lease *lease.Lease) []trafficmngr.IPTablesRule { n := ipn.String() sn := lease.IPv6Subnet.String() - return []IPTablesRule{ - {"nat", "-A", "POSTROUTING", []string{"-s", n, "-d", n, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, - {"nat", "-A", "POSTROUTING", []string{"-s", n, "!", "-d", "ff00::/8", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}, - {"nat", "-A", "POSTROUTING", []string{"!", "-s", n, "-d", sn, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, - {"nat", "-A", "POSTROUTING", []string{"!", "-s", n, "-d", n, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}, + return []trafficmngr.IPTablesRule{ + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-s", n, "-d", n, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"-s", n, "!", "-d", "ff00::/8", "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}, + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"!", "-s", n, "-d", sn, "-m", "comment", "--comment", "flanneld masq", "-j", "RETURN"}}, + {Table: "nat", Action: "-A", Chain: "POSTROUTING", Rulespec: []string{"!", "-s", n, "-d", n, "-m", "comment", "--comment", "flanneld masq", "-j", "MASQUERADE", "--random-fully"}}, } } diff --git a/pkg/trafficmngr/iptables/iptables_windows.go b/pkg/trafficmngr/iptables/iptables_windows.go new file mode 100644 index 0000000000..85cdf16126 --- /dev/null +++ b/pkg/trafficmngr/iptables/iptables_windows.go @@ -0,0 +1,50 @@ +// Copyright 2015 flannel authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package iptables + +import ( + "github.com/flannel-io/flannel/pkg/ip" + "github.com/flannel-io/flannel/pkg/lease" + "github.com/flannel-io/flannel/pkg/trafficmngr" +) + +type IPTablesManager struct{} + +type IPTables interface { + AppendUnique(table string, chain string, rulespec ...string) error + ChainExists(table, chain string) (bool, error) + ClearChain(table, chain string) error + Delete(table string, chain string, rulespec ...string) error + Exists(table string, chain string, rulespec ...string) (bool, error) +} + +func (iptm IPTablesManager) CreateIP4Chain(table, chain string) { return } +func (iptm IPTablesManager) CreateIP6Chain(table, chain string) { return } +func (iptm IPTablesManager) MasqRules(cluster_cidrs []ip.IP4Net, lease *lease.Lease) []trafficmngr.IPTablesRule { + return nil +} +func (iptm IPTablesManager) ForwardRules(flannelNetwork string) []trafficmngr.IPTablesRule { + return nil +} +func teardownIPTables(ipt IPTables, rules []trafficmngr.IPTablesRule) {} +func (iptm IPTablesManager) SetupAndEnsureIP4Tables(getRules func() []trafficmngr.IPTablesRule, resyncPeriod int) { +} +func (iptm IPTablesManager) SetupAndEnsureIP6Tables(getRules func() []trafficmngr.IPTablesRule, resyncPeriod int) { +} +func (iptm IPTablesManager) MasqIP6Rules(cluster_cidrs []ip.IP6Net, lease *lease.Lease) []trafficmngr.IPTablesRule { + return nil +} +func (iptm IPTablesManager) DeleteIP4Tables(rules []trafficmngr.IPTablesRule) error { return nil } +func (iptm IPTablesManager) DeleteIP6Tables(rules []trafficmngr.IPTablesRule) error { return nil } diff --git a/pkg/trafficmngr/trafficmngr.go b/pkg/trafficmngr/trafficmngr.go new file mode 100644 index 0000000000..6a0794e7c7 --- /dev/null +++ b/pkg/trafficmngr/trafficmngr.go @@ -0,0 +1,39 @@ +// Copyright 2024 flannel authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trafficmngr + +import ( + "github.com/flannel-io/flannel/pkg/ip" + "github.com/flannel-io/flannel/pkg/lease" +) + +type IPTablesRule struct { + Table string + Action string + Chain string + Rulespec []string +} + +type TrafficManager interface { + CreateIP4Chain(table, chain string) + CreateIP6Chain(table, chain string) + MasqRules(cluster_cidrs []ip.IP4Net, lease *lease.Lease) []IPTablesRule + MasqIP6Rules(cluster_cidrs []ip.IP6Net, lease *lease.Lease) []IPTablesRule + ForwardRules(flannelNetwork string) []IPTablesRule + SetupAndEnsureIP4Tables(getRules func() []IPTablesRule, resyncPeriod int) + SetupAndEnsureIP6Tables(getRules func() []IPTablesRule, resyncPeriod int) + DeleteIP4Tables(rules []IPTablesRule) error + DeleteIP6Tables(rules []IPTablesRule) error +}