Skip to content
Open
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
17 changes: 16 additions & 1 deletion plugins/meta/portmap/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,22 @@ func cmdDel(args *skel.CmdArgs) error {

// We don't need to parse out whether or not we're using v6 or snat,
// deletion is idempotent
return netConf.mapper.unforwardPorts(netConf)
if err := netConf.mapper.unforwardPorts(netConf); err != nil {
return err
}

// Flush UDP conntrack after removing the DNAT rules. Without this, a later
// consumer of the same hostPort (for example a pod that switches to
// hostNetwork:true and binds the port directly) can be blackholed by stale
// NAT state left from the previous mapping. cmdAdd already flushes on the
// setup path; DEL needs the same cleanup. Failures are informative only.
if err := deletePortmapStaleConnections(netConf.RuntimeConfig.PortMaps, unix.AF_INET); err != nil {
log.Printf("failed to delete stale UDP conntrack entries on DEL: %v", err)
}
if err := deletePortmapStaleConnections(netConf.RuntimeConfig.PortMaps, unix.AF_INET6); err != nil {
log.Printf("failed to delete stale UDP conntrack entries on DEL: %v", err)
}
return nil
}

func main() {
Expand Down
17 changes: 17 additions & 0 deletions plugins/meta/portmap/portmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,23 @@ import (
"github.com/containernetworking/cni/pkg/types"
)

// deletePortmapStaleConnections is a no-op for non-UDP mappings and must not
// fail when given only TCP entries (no conntrack call is made).
var _ = Describe("deletePortmapStaleConnections", func() {
It("skips non-UDP port mappings without error", func() {
err := deletePortmapStaleConnections([]PortMapEntry{
{HostPort: 8080, ContainerPort: 80, Protocol: "tcp"},
{HostPort: 8081, ContainerPort: 81, Protocol: "TCP"},
}, 2 /* AF_INET */)
Expect(err).NotTo(HaveOccurred())
})

It("accepts an empty mapping list", func() {
err := deletePortmapStaleConnections(nil, 2)
Expect(err).NotTo(HaveOccurred())
})
})

var _ = Describe("portmapping configuration", func() {
for _, ver := range []string{"0.3.0", "0.3.1", "0.4.0", "1.0.0"} {
// Redefine ver inside for scope so real value is picked up by each dynamically defined It()
Expand Down
Loading