portmap: support hairpin, improve performance

This change improves the performance of the portmap plugin and fixes
hairpin, when a container is mapped back to itself.

Performance is improved by using a multiport test to reduce rule
traversal, and by using a masquerade mark.

Hairpin is fixed by enabling masquerading for hairpin traffic.
This commit is contained in:
Casey Callendrello
2017-11-03 16:53:12 +00:00
parent 7f98c94613
commit 5576f3120e
8 changed files with 513 additions and 296 deletions

View File

@ -25,12 +25,14 @@ import (
type chain struct {
table string
name string
entryRule []string // the rule that enters this chain
entryChains []string // the chains to add the entry rule
entryRules [][]string // the rules that "point" to this chain
rules [][]string // the rules this chain contains
}
// setup idempotently creates the chain. It will not error if the chain exists.
func (c *chain) setup(ipt *iptables.IPTables, rules [][]string) error {
func (c *chain) setup(ipt *iptables.IPTables) error {
// create the chain
exists, err := chainExists(ipt, c.table, c.name)
if err != nil {
@ -43,17 +45,21 @@ func (c *chain) setup(ipt *iptables.IPTables, rules [][]string) error {
}
// Add the rules to the chain
for i := len(rules) - 1; i >= 0; i-- {
if err := prependUnique(ipt, c.table, c.name, rules[i]); err != nil {
for i := len(c.rules) - 1; i >= 0; i-- {
if err := prependUnique(ipt, c.table, c.name, c.rules[i]); err != nil {
return err
}
}
// Add the entry rules
entryRule := append(c.entryRule, "-j", c.name)
// Add the entry rules to the entry chains
for _, entryChain := range c.entryChains {
if err := prependUnique(ipt, c.table, entryChain, entryRule); err != nil {
return err
for i := len(c.entryRules) - 1; i >= 0; i-- {
r := []string{}
r = append(r, c.entryRules[i]...)
r = append(r, "-j", c.name)
if err := prependUnique(ipt, c.table, entryChain, r); err != nil {
return err
}
}
}