Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit 837edf8

Browse files
committed
Fix dup rule generation with older iptables
With older iptables binary, kube-proxy generates duplicate iptables rules in NAT table every few seconds. This fixes the problem by properly unquoting && parsing older iptables-save output.
1 parent 736945f commit 837edf8

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed

pkg/util/iptables/iptables.go

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -326,12 +326,15 @@ func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...st
326326
return false, fmt.Errorf("error checking rule: %v", err)
327327
}
328328

329-
// Sadly, iptables has inconsistent quoting rules for comments.
330-
// Just unquote any arg that is wrapped in quotes.
331-
argsCopy := make([]string, len(args))
332-
copy(argsCopy, args)
333-
for i := range argsCopy {
334-
unquote(&argsCopy[i])
329+
// Sadly, iptables has inconsistent quoting rules for comments. Just remove all quotes.
330+
// Also, quoted multi-word comments (which are counted as a single arg)
331+
// will be unpacked into multiple args,
332+
// in order to compare against iptables-save output (which will be split at whitespace boundary)
333+
// e.g. a single arg('"this must be before the NodePort rules"') will be unquoted and unpacked into 7 args.
334+
var argsCopy []string
335+
for i := range args {
336+
tmpField := strings.Trim(args[i], "\"")
337+
argsCopy = append(argsCopy, strings.Fields(tmpField)...)
335338
}
336339
argset := util.NewStringSet(argsCopy...)
337340

@@ -340,14 +343,14 @@ func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...st
340343

341344
// Check that this is a rule for the correct chain, and that it has
342345
// the correct number of argument (+2 for "-A <chain name>")
343-
if !strings.HasPrefix(line, fmt.Sprintf("-A %s", string(chain))) || len(fields) != len(args)+2 {
346+
if !strings.HasPrefix(line, fmt.Sprintf("-A %s", string(chain))) || len(fields) != len(argsCopy)+2 {
344347
continue
345348
}
346349

347350
// Sadly, iptables has inconsistent quoting rules for comments.
348-
// Just unquote any arg that is wrapped in quotes.
351+
// Just remove all quotes.
349352
for i := range fields {
350-
unquote(&fields[i])
353+
fields[i] = strings.Trim(fields[i], "\"")
351354
}
352355

353356
// TODO: This misses reorderings e.g. "-x foo ! -y bar" will match "! -x foo -y bar"
@@ -360,12 +363,6 @@ func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...st
360363
return false, nil
361364
}
362365

363-
func unquote(strp *string) {
364-
if len(*strp) >= 2 && (*strp)[0] == '"' && (*strp)[len(*strp)-1] == '"' {
365-
*strp = strings.TrimPrefix(strings.TrimSuffix(*strp, `"`), `"`)
366-
}
367-
}
368-
369366
// Executes the rule check using the "-C" flag
370367
func (runner *runner) checkRuleUsingCheck(args []string) (bool, error) {
371368
out, err := runner.run(opCheckRule, args)

0 commit comments

Comments
 (0)