Merge pull request #408 from tgross/idempotent_chain_creation
ensure iptables chain creation is idempotent
This commit is contained in:
@ -270,6 +270,13 @@ var _ = Describe("firewall plugin iptables backend", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
validateFullRuleset(fullConf)
|
||||
|
||||
// ensure creation is idempotent
|
||||
_, _, err = testutils.CmdAdd(targetNS.Path(), args.ContainerID, IFNAME, fullConf, func() error {
|
||||
return cmdAdd(args)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
return nil
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
"github.com/containernetworking/plugins/pkg/utils"
|
||||
"github.com/coreos/go-iptables/iptables"
|
||||
)
|
||||
|
||||
@ -32,20 +33,6 @@ func getPrivChainRules(ip string) [][]string {
|
||||
return rules
|
||||
}
|
||||
|
||||
func ensureChain(ipt *iptables.IPTables, table, chain string) error {
|
||||
chains, err := ipt.ListChains(table)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list iptables chains: %v", err)
|
||||
}
|
||||
for _, ch := range chains {
|
||||
if ch == chain {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return ipt.NewChain(table, chain)
|
||||
}
|
||||
|
||||
func generateFilterRule(privChainName string) []string {
|
||||
return []string{"-m", "comment", "--comment", "CNI firewall plugin rules", "-j", privChainName}
|
||||
}
|
||||
@ -73,10 +60,10 @@ func (ib *iptablesBackend) setupChains(ipt *iptables.IPTables) error {
|
||||
adminRule := generateFilterRule(ib.adminChainName)
|
||||
|
||||
// Ensure our private chains exist
|
||||
if err := ensureChain(ipt, "filter", ib.privChainName); err != nil {
|
||||
if err := utils.EnsureChain(ipt, "filter", ib.privChainName); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ensureChain(ipt, "filter", ib.adminChainName); err != nil {
|
||||
if err := utils.EnsureChain(ipt, "filter", ib.adminChainName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -160,10 +147,10 @@ func (ib *iptablesBackend) checkRules(conf *FirewallNetConf, result *current.Res
|
||||
}
|
||||
|
||||
// Ensure our private chains exist
|
||||
if err := ensureChain(ipt, "filter", ib.privChainName); err != nil {
|
||||
if err := utils.EnsureChain(ipt, "filter", ib.privChainName); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ensureChain(ipt, "filter", ib.adminChainName); err != nil {
|
||||
if err := utils.EnsureChain(ipt, "filter", ib.adminChainName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/utils"
|
||||
"github.com/coreos/go-iptables/iptables"
|
||||
"github.com/mattn/go-shellwords"
|
||||
)
|
||||
@ -35,16 +36,11 @@ type chain struct {
|
||||
|
||||
// setup idempotently creates the chain. It will not error if the chain exists.
|
||||
func (c *chain) setup(ipt *iptables.IPTables) error {
|
||||
// create the chain
|
||||
exists, err := chainExists(ipt, c.table, c.name)
|
||||
|
||||
err := utils.EnsureChain(ipt, c.table, c.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exists {
|
||||
if err := ipt.NewChain(c.table, c.name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Add the rules to the chain
|
||||
for _, rule := range c.rules {
|
||||
@ -125,24 +121,10 @@ func insertUnique(ipt *iptables.IPTables, table, chain string, prepend bool, rul
|
||||
}
|
||||
}
|
||||
|
||||
func chainExists(ipt *iptables.IPTables, tableName, chainName string) (bool, error) {
|
||||
chains, err := ipt.ListChains(tableName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, ch := range chains {
|
||||
if ch == chainName {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// check the chain.
|
||||
func (c *chain) check(ipt *iptables.IPTables) error {
|
||||
|
||||
exists, err := chainExists(ipt, c.table, c.name)
|
||||
exists, err := utils.ChainExists(ipt, c.table, c.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ func checkPorts(config *PortMapConf, containerIP net.IP) error {
|
||||
}
|
||||
|
||||
if ip4t != nil {
|
||||
exists, err := chainExists(ip4t, dnatChain.table, dnatChain.name)
|
||||
exists, err := utils.ChainExists(ip4t, dnatChain.table, dnatChain.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -137,7 +137,7 @@ func checkPorts(config *PortMapConf, containerIP net.IP) error {
|
||||
}
|
||||
|
||||
if ip6t != nil {
|
||||
exists, err := chainExists(ip6t, dnatChain.table, dnatChain.name)
|
||||
exists, err := utils.ChainExists(ip6t, dnatChain.table, dnatChain.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Reference in New Issue
Block a user