Merge pull request #421 from aojea/portmapErrors2
Portmap doesn't fail if chain doesn't exist
This commit is contained in:
commit
ec8f6c99d0
2
go.mod
2
go.mod
@ -8,7 +8,7 @@ require (
|
|||||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae
|
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae
|
||||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44
|
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44
|
||||||
github.com/containernetworking/cni v0.7.1
|
github.com/containernetworking/cni v0.7.1
|
||||||
github.com/coreos/go-iptables v0.4.2
|
github.com/coreos/go-iptables v0.4.5
|
||||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
|
||||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
|
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
|
||||||
github.com/d2g/dhcp4client v1.0.0
|
github.com/d2g/dhcp4client v1.0.0
|
||||||
|
4
go.sum
4
go.sum
@ -10,6 +10,10 @@ github.com/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK
|
|||||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||||
github.com/coreos/go-iptables v0.4.2 h1:KH0EwId05JwWIfb96gWvkiT2cbuOu8ygqUaB+yPAwIg=
|
github.com/coreos/go-iptables v0.4.2 h1:KH0EwId05JwWIfb96gWvkiT2cbuOu8ygqUaB+yPAwIg=
|
||||||
github.com/coreos/go-iptables v0.4.2/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
github.com/coreos/go-iptables v0.4.2/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||||
|
github.com/coreos/go-iptables v0.4.4 h1:5oOUvU7Fk53Hn/rkdJ0zcYGCffotqXpyi4ADCkO1TJ8=
|
||||||
|
github.com/coreos/go-iptables v0.4.4/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||||
|
github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38=
|
||||||
|
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM=
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM=
|
||||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c h1:Xo2rK1pzOm0jO6abTPIQwbAmqBIOj132otexc1mmzFc=
|
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c h1:Xo2rK1pzOm0jO6abTPIQwbAmqBIOj132otexc1mmzFc=
|
||||||
|
@ -62,3 +62,60 @@ func ChainExists(ipt *iptables.IPTables, table, chain string) (bool, error) {
|
|||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteRule idempotently delete the iptables rule in the specified table/chain.
|
||||||
|
// It does not return an error if the referring chain doesn't exist
|
||||||
|
func DeleteRule(ipt *iptables.IPTables, table, chain string, rulespec ...string) error {
|
||||||
|
if ipt == nil {
|
||||||
|
return errors.New("failed to ensure iptable chain: IPTables was nil")
|
||||||
|
}
|
||||||
|
if err := ipt.Delete(table, chain, rulespec...); err != nil {
|
||||||
|
eerr, eok := err.(*iptables.Error)
|
||||||
|
switch {
|
||||||
|
case eok && eerr.IsNotExist():
|
||||||
|
// swallow here, the chain was already deleted
|
||||||
|
return nil
|
||||||
|
case eok && eerr.ExitStatus() == 2:
|
||||||
|
// swallow here, invalid command line parameter because the referring rule is missing
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Failed to delete referring rule %s %s: %v", table, chain, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteChain idempotently deletes the specified table/chain.
|
||||||
|
// It does not return an errors if the chain does not exist
|
||||||
|
func DeleteChain(ipt *iptables.IPTables, table, chain string) error {
|
||||||
|
if ipt == nil {
|
||||||
|
return errors.New("failed to ensure iptable chain: IPTables was nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := ipt.DeleteChain(table, chain)
|
||||||
|
eerr, eok := err.(*iptables.Error)
|
||||||
|
switch {
|
||||||
|
case eok && eerr.IsNotExist():
|
||||||
|
// swallow here, the chain was already deleted
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearChain idempotently clear the iptables rules in the specified table/chain.
|
||||||
|
// If the chain does not exist, a new one will be created
|
||||||
|
func ClearChain(ipt *iptables.IPTables, table, chain string) error {
|
||||||
|
if ipt == nil {
|
||||||
|
return errors.New("failed to ensure iptable chain: IPTables was nil")
|
||||||
|
}
|
||||||
|
err := ipt.ClearChain(table, chain)
|
||||||
|
eerr, eok := err.(*iptables.Error)
|
||||||
|
switch {
|
||||||
|
case eok && eerr.IsNotExist():
|
||||||
|
// swallow here, the chain was already deleted
|
||||||
|
return EnsureChain(ipt, table, chain)
|
||||||
|
default:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -67,12 +67,31 @@ var _ = Describe("chain tests", func() {
|
|||||||
cleanup()
|
cleanup()
|
||||||
})
|
})
|
||||||
|
|
||||||
It("creates chains idempotently", func() {
|
Describe("EnsureChain", func() {
|
||||||
err := EnsureChain(ipt, TABLE, testChain)
|
It("creates chains idempotently", func() {
|
||||||
Expect(err).NotTo(HaveOccurred())
|
err := EnsureChain(ipt, TABLE, testChain)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
// Create it again!
|
// Create it again!
|
||||||
err = EnsureChain(ipt, TABLE, testChain)
|
err = EnsureChain(ipt, TABLE, testChain)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Describe("DeleteChain", func() {
|
||||||
|
It("delete chains idempotently", func() {
|
||||||
|
// Create chain
|
||||||
|
err := EnsureChain(ipt, TABLE, testChain)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Delete chain
|
||||||
|
err = DeleteChain(ipt, TABLE, testChain)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Delete it again!
|
||||||
|
err = DeleteChain(ipt, TABLE, testChain)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -70,7 +70,7 @@ func (c *chain) teardown(ipt *iptables.IPTables) error {
|
|||||||
// flush the chain
|
// flush the chain
|
||||||
// This will succeed *and create the chain* if it does not exist.
|
// This will succeed *and create the chain* if it does not exist.
|
||||||
// If the chain doesn't exist, the next checks will fail.
|
// If the chain doesn't exist, the next checks will fail.
|
||||||
if err := ipt.ClearChain(c.table, c.name); err != nil {
|
if err := utils.ClearChain(ipt, c.table, c.name); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,17 +90,15 @@ func (c *chain) teardown(ipt *iptables.IPTables) error {
|
|||||||
}
|
}
|
||||||
chainParts = chainParts[2:] // List results always include an -A CHAINNAME
|
chainParts = chainParts[2:] // List results always include an -A CHAINNAME
|
||||||
|
|
||||||
if err := ipt.Delete(c.table, entryChain, chainParts...); err != nil {
|
if err := utils.DeleteRule(ipt, c.table, entryChain, chainParts...); err != nil {
|
||||||
return fmt.Errorf("Failed to delete referring rule %s %s: %v", c.table, entryChainRule, err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ipt.DeleteChain(c.table, c.name); err != nil {
|
return utils.DeleteChain(ipt, c.table, c.name)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// insertUnique will add a rule to a chain if it does not already exist.
|
// insertUnique will add a rule to a chain if it does not already exist.
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/containernetworking/plugins/pkg/ns"
|
"github.com/containernetworking/plugins/pkg/ns"
|
||||||
"github.com/containernetworking/plugins/pkg/testutils"
|
"github.com/containernetworking/plugins/pkg/testutils"
|
||||||
@ -32,6 +33,7 @@ const TABLE = "filter" // We'll monkey around here
|
|||||||
var _ = Describe("chain tests", func() {
|
var _ = Describe("chain tests", func() {
|
||||||
var testChain chain
|
var testChain chain
|
||||||
var ipt *iptables.IPTables
|
var ipt *iptables.IPTables
|
||||||
|
var testNs ns.NetNS
|
||||||
var cleanup func()
|
var cleanup func()
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
@ -41,7 +43,7 @@ var _ = Describe("chain tests", func() {
|
|||||||
currNs, err := ns.GetCurrentNS()
|
currNs, err := ns.GetCurrentNS()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
testNs, err := testutils.NewNS()
|
testNs, err = testutils.NewNS()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
tlChainName := fmt.Sprintf("cni-test-%d", rand.Intn(10000000))
|
tlChainName := fmt.Sprintf("cni-test-%d", rand.Intn(10000000))
|
||||||
@ -195,4 +197,38 @@ var _ = Describe("chain tests", func() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("deletes chains idempotently in parallel", func() {
|
||||||
|
defer cleanup()
|
||||||
|
// number of parallel executions
|
||||||
|
N := 10
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
err := testChain.setup(ipt)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
errCh := make(chan error, N)
|
||||||
|
for i := 0; i < N; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
// teardown chain
|
||||||
|
errCh <- testNs.Do(func(ns.NetNS) error {
|
||||||
|
return testChain.teardown(ipt)
|
||||||
|
})
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
close(errCh)
|
||||||
|
for err := range errCh {
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
chains, err := ipt.ListChains(TABLE)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
for _, chain := range chains {
|
||||||
|
if chain == testChain.name {
|
||||||
|
Fail("Chain was not deleted")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -96,119 +96,133 @@ var _ = Describe("portmap integration tests", func() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// This needs to be done using Ginkgo's asynchronous testing mode.
|
Describe("Creating an interface in a namespace with the ptp plugin", func() {
|
||||||
It("forwards a TCP port on ipv4", func(done Done) {
|
// This needs to be done using Ginkgo's asynchronous testing mode.
|
||||||
var err error
|
It("forwards a TCP port on ipv4", func(done Done) {
|
||||||
hostPort := rand.Intn(10000) + 1025
|
var err error
|
||||||
runtimeConfig := libcni.RuntimeConf{
|
hostPort := rand.Intn(10000) + 1025
|
||||||
ContainerID: fmt.Sprintf("unit-test-%d", hostPort),
|
runtimeConfig := libcni.RuntimeConf{
|
||||||
NetNS: targetNS.Path(),
|
ContainerID: fmt.Sprintf("unit-test-%d", hostPort),
|
||||||
IfName: "eth0",
|
NetNS: targetNS.Path(),
|
||||||
CapabilityArgs: map[string]interface{}{
|
IfName: "eth0",
|
||||||
"portMappings": []map[string]interface{}{
|
CapabilityArgs: map[string]interface{}{
|
||||||
{
|
"portMappings": []map[string]interface{}{
|
||||||
"hostPort": hostPort,
|
{
|
||||||
"containerPort": containerPort,
|
"hostPort": hostPort,
|
||||||
"protocol": "tcp",
|
"containerPort": containerPort,
|
||||||
|
"protocol": "tcp",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make delete idempotent, so we can clean up on failure
|
|
||||||
netDeleted := false
|
|
||||||
deleteNetwork := func() error {
|
|
||||||
if netDeleted {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
netDeleted = true
|
|
||||||
return cniConf.DelNetworkList(context.TODO(), configList, &runtimeConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// we'll also manually check the iptables chains
|
// Make delete idempotent, so we can clean up on failure
|
||||||
ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv4)
|
netDeleted := false
|
||||||
Expect(err).NotTo(HaveOccurred())
|
deleteNetwork := func() error {
|
||||||
dnatChainName := genDnatChain("cni-portmap-unit-test", runtimeConfig.ContainerID).name
|
if netDeleted {
|
||||||
|
return nil
|
||||||
// Create the network
|
}
|
||||||
resI, err := cniConf.AddNetworkList(context.TODO(), configList, &runtimeConfig)
|
netDeleted = true
|
||||||
Expect(err).NotTo(HaveOccurred())
|
return cniConf.DelNetworkList(context.TODO(), configList, &runtimeConfig)
|
||||||
defer deleteNetwork()
|
|
||||||
|
|
||||||
// Undo Docker's forwarding policy
|
|
||||||
cmd := exec.Command("iptables", "-t", "filter",
|
|
||||||
"-P", "FORWARD", "ACCEPT")
|
|
||||||
cmd.Stderr = GinkgoWriter
|
|
||||||
err = cmd.Run()
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// Check the chain exists
|
|
||||||
_, err = ipt.List("nat", dnatChainName)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
result, err := current.GetResult(resI)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
var contIP net.IP
|
|
||||||
|
|
||||||
for _, ip := range result.IPs {
|
|
||||||
intfIndex := *ip.Interface
|
|
||||||
if result.Interfaces[intfIndex].Sandbox == "" {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
contIP = ip.Address.IP
|
|
||||||
}
|
|
||||||
if contIP == nil {
|
|
||||||
Fail("could not determine container IP")
|
|
||||||
}
|
|
||||||
|
|
||||||
hostIP := getLocalIP()
|
// we'll also manually check the iptables chains
|
||||||
fmt.Fprintf(GinkgoWriter, "hostIP: %s:%d, contIP: %s:%d\n",
|
ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv4)
|
||||||
hostIP, hostPort, contIP, containerPort)
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
dnatChainName := genDnatChain("cni-portmap-unit-test", runtimeConfig.ContainerID).name
|
||||||
|
|
||||||
// dump iptables-save output for debugging
|
// Create the network
|
||||||
cmd = exec.Command("iptables-save")
|
resI, err := cniConf.AddNetworkList(context.TODO(), configList, &runtimeConfig)
|
||||||
cmd.Stderr = GinkgoWriter
|
Expect(err).NotTo(HaveOccurred())
|
||||||
cmd.Stdout = GinkgoWriter
|
defer deleteNetwork()
|
||||||
Expect(cmd.Run()).To(Succeed())
|
|
||||||
|
|
||||||
// Sanity check: verify that the container is reachable directly
|
// Undo Docker's forwarding policy
|
||||||
contOK := testEchoServer(contIP.String(), containerPort, "")
|
cmd := exec.Command("iptables", "-t", "filter",
|
||||||
|
"-P", "FORWARD", "ACCEPT")
|
||||||
|
cmd.Stderr = GinkgoWriter
|
||||||
|
err = cmd.Run()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
// Verify that a connection to the forwarded port works
|
// Check the chain exists
|
||||||
dnatOK := testEchoServer(hostIP, hostPort, "")
|
_, err = ipt.List("nat", dnatChainName)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
// Verify that a connection to localhost works
|
result, err := current.GetResult(resI)
|
||||||
snatOK := testEchoServer("127.0.0.1", hostPort, "")
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
var contIP net.IP
|
||||||
|
|
||||||
// verify that hairpin works
|
for _, ip := range result.IPs {
|
||||||
hairpinOK := testEchoServer(hostIP, hostPort, targetNS.Path())
|
intfIndex := *ip.Interface
|
||||||
|
if result.Interfaces[intfIndex].Sandbox == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
contIP = ip.Address.IP
|
||||||
|
}
|
||||||
|
if contIP == nil {
|
||||||
|
Fail("could not determine container IP")
|
||||||
|
}
|
||||||
|
|
||||||
// Cleanup
|
hostIP := getLocalIP()
|
||||||
session.Terminate()
|
fmt.Fprintf(GinkgoWriter, "hostIP: %s:%d, contIP: %s:%d\n",
|
||||||
err = deleteNetwork()
|
hostIP, hostPort, contIP, containerPort)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// Verify iptables rules are gone
|
// dump iptables-save output for debugging
|
||||||
_, err = ipt.List("nat", dnatChainName)
|
cmd = exec.Command("iptables-save")
|
||||||
Expect(err).To(MatchError(ContainSubstring("iptables: No chain/target/match by that name.")))
|
cmd.Stderr = GinkgoWriter
|
||||||
|
cmd.Stdout = GinkgoWriter
|
||||||
|
Expect(cmd.Run()).To(Succeed())
|
||||||
|
|
||||||
// Check that everything succeeded *after* we clean up the network
|
// dump ip routes output for debugging
|
||||||
if !contOK {
|
cmd = exec.Command("ip", "route")
|
||||||
Fail("connection direct to " + contIP.String() + " failed")
|
cmd.Stderr = GinkgoWriter
|
||||||
}
|
cmd.Stdout = GinkgoWriter
|
||||||
if !dnatOK {
|
Expect(cmd.Run()).To(Succeed())
|
||||||
Fail("Connection to " + hostIP + " was not forwarded")
|
|
||||||
}
|
|
||||||
if !snatOK {
|
|
||||||
Fail("connection to 127.0.0.1 was not forwarded")
|
|
||||||
}
|
|
||||||
if !hairpinOK {
|
|
||||||
Fail("Hairpin connection failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
close(done)
|
// dump ip addresses output for debugging
|
||||||
|
cmd = exec.Command("ip", "addr")
|
||||||
|
cmd.Stderr = GinkgoWriter
|
||||||
|
cmd.Stdout = GinkgoWriter
|
||||||
|
Expect(cmd.Run()).To(Succeed())
|
||||||
|
|
||||||
}, TIMEOUT*9)
|
// Sanity check: verify that the container is reachable directly
|
||||||
|
contOK := testEchoServer(contIP.String(), containerPort, "")
|
||||||
|
|
||||||
|
// Verify that a connection to the forwarded port works
|
||||||
|
dnatOK := testEchoServer(hostIP, hostPort, "")
|
||||||
|
|
||||||
|
// Verify that a connection to localhost works
|
||||||
|
snatOK := testEchoServer("127.0.0.1", hostPort, "")
|
||||||
|
|
||||||
|
// verify that hairpin works
|
||||||
|
hairpinOK := testEchoServer(hostIP, hostPort, targetNS.Path())
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
session.Terminate()
|
||||||
|
err = deleteNetwork()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Verify iptables rules are gone
|
||||||
|
_, err = ipt.List("nat", dnatChainName)
|
||||||
|
Expect(err).To(MatchError(ContainSubstring("iptables: No chain/target/match by that name.")))
|
||||||
|
|
||||||
|
// Check that everything succeeded *after* we clean up the network
|
||||||
|
if !contOK {
|
||||||
|
Fail("connection direct to " + contIP.String() + " failed")
|
||||||
|
}
|
||||||
|
if !dnatOK {
|
||||||
|
Fail("Connection to " + hostIP + " was not forwarded")
|
||||||
|
}
|
||||||
|
if !snatOK {
|
||||||
|
Fail("connection to 127.0.0.1 was not forwarded")
|
||||||
|
}
|
||||||
|
if !hairpinOK {
|
||||||
|
Fail("Hairpin connection failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
close(done)
|
||||||
|
|
||||||
|
}, TIMEOUT*9)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// testEchoServer returns true if we found an echo server on the port
|
// testEchoServer returns true if we found an echo server on the port
|
||||||
|
29
vendor/github.com/coreos/go-iptables/iptables/iptables.go
generated
vendored
29
vendor/github.com/coreos/go-iptables/iptables/iptables.go
generated
vendored
@ -48,9 +48,13 @@ func (e *Error) Error() string {
|
|||||||
|
|
||||||
// IsNotExist returns true if the error is due to the chain or rule not existing
|
// IsNotExist returns true if the error is due to the chain or rule not existing
|
||||||
func (e *Error) IsNotExist() bool {
|
func (e *Error) IsNotExist() bool {
|
||||||
return e.ExitStatus() == 1 &&
|
if e.ExitStatus() != 1 {
|
||||||
(e.msg == fmt.Sprintf("%s: Bad rule (does a matching rule exist in that chain?).\n", getIptablesCommand(e.proto)) ||
|
return false
|
||||||
e.msg == fmt.Sprintf("%s: No chain/target/match by that name.\n", getIptablesCommand(e.proto)))
|
}
|
||||||
|
cmdIptables := getIptablesCommand(e.proto)
|
||||||
|
msgNoRuleExist := fmt.Sprintf("%s: Bad rule (does a matching rule exist in that chain?).\n", cmdIptables)
|
||||||
|
msgNoChainExist := fmt.Sprintf("%s: No chain/target/match by that name.\n", cmdIptables)
|
||||||
|
return strings.Contains(e.msg, msgNoRuleExist) || strings.Contains(e.msg, msgNoChainExist)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protocol to differentiate between IPv4 and IPv6
|
// Protocol to differentiate between IPv4 and IPv6
|
||||||
@ -101,7 +105,13 @@ func NewWithProtocol(proto Protocol) (*IPTables, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vstring, err := getIptablesVersionString(path)
|
vstring, err := getIptablesVersionString(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not get iptables version: %v", err)
|
||||||
|
}
|
||||||
v1, v2, v3, mode, err := extractIptablesVersion(vstring)
|
v1, v2, v3, mode, err := extractIptablesVersion(vstring)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to extract iptables version from [%s]: %v", vstring, err)
|
||||||
|
}
|
||||||
|
|
||||||
checkPresent, waitPresent, randomFullyPresent := getIptablesCommandSupport(v1, v2, v3)
|
checkPresent, waitPresent, randomFullyPresent := getIptablesCommandSupport(v1, v2, v3)
|
||||||
|
|
||||||
@ -348,18 +358,6 @@ func (ipt *IPTables) executeList(args []string) ([]string, error) {
|
|||||||
rules = rules[:len(rules)-1]
|
rules = rules[:len(rules)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// nftables mode doesn't return an error code when listing a non-existent
|
|
||||||
// chain. Patch that up.
|
|
||||||
if len(rules) == 0 && ipt.mode == "nf_tables" {
|
|
||||||
v := 1
|
|
||||||
return nil, &Error{
|
|
||||||
cmd: exec.Cmd{Args: args},
|
|
||||||
msg: fmt.Sprintf("%s: No chain/target/match by that name.\n", getIptablesCommand(ipt.proto)),
|
|
||||||
proto: ipt.proto,
|
|
||||||
exitStatus: &v,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, rule := range rules {
|
for i, rule := range rules {
|
||||||
rules[i] = filterRuleOutput(rule)
|
rules[i] = filterRuleOutput(rule)
|
||||||
}
|
}
|
||||||
@ -437,6 +435,7 @@ func (ipt *IPTables) runWithOutput(args []string, stdout io.Writer) error {
|
|||||||
}
|
}
|
||||||
ul, err := fmu.tryLock()
|
ul, err := fmu.tryLock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
syscall.Close(fmu.fd)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer ul.Unlock()
|
defer ul.Unlock()
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -32,7 +32,7 @@ github.com/containernetworking/cni/pkg/skel
|
|||||||
github.com/containernetworking/cni/pkg/version
|
github.com/containernetworking/cni/pkg/version
|
||||||
github.com/containernetworking/cni/pkg/types/020
|
github.com/containernetworking/cni/pkg/types/020
|
||||||
github.com/containernetworking/cni/libcni
|
github.com/containernetworking/cni/libcni
|
||||||
# github.com/coreos/go-iptables v0.4.2
|
# github.com/coreos/go-iptables v0.4.5
|
||||||
github.com/coreos/go-iptables/iptables
|
github.com/coreos/go-iptables/iptables
|
||||||
# github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
|
# github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
|
||||||
github.com/coreos/go-systemd/activation
|
github.com/coreos/go-systemd/activation
|
||||||
|
Loading…
x
Reference in New Issue
Block a user