@@ -69,6 +69,12 @@ type Interface interface {
6969 AddReloadFunc (reloadFunc func ())
7070 // Destroy cleans up resources used by the Interface
7171 Destroy ()
72+ // HasRandomFully reveals whether `-j MASQUERADE` takes the
73+ // `--random-fully` option. This is helpful to work around a
74+ // Linux kernel bug that sometimes causes multiple flows to get
75+ // mapped to the same IP:PORT and consequently some suffer packet
76+ // drops.
77+ HasRandomFully () bool
7278}
7379
7480type Protocol byte
@@ -121,6 +127,8 @@ const NoFlushTables FlushFlag = false
121127// (test whether a rule exists).
122128var MinCheckVersion = utilversion .MustParseGeneric ("1.4.11" )
123129
130+ var RandomFullyMinVersion = utilversion .MustParseGeneric ("1.6.2" )
131+
124132// Minimum iptables versions supporting the -w and -w<seconds> flags
125133var WaitMinVersion = utilversion .MustParseGeneric ("1.4.20" )
126134var WaitSecondsMinVersion = utilversion .MustParseGeneric ("1.4.22" )
@@ -139,6 +147,7 @@ type runner struct {
139147 protocol Protocol
140148 hasCheck bool
141149 hasListener bool
150+ hasRandomFully bool
142151 waitFlag []string
143152 restoreWaitFlag []string
144153 lockfilePath string
@@ -166,6 +175,7 @@ func newInternal(exec utilexec.Interface, dbus utildbus.Interface, protocol Prot
166175 protocol : protocol ,
167176 hasCheck : version .AtLeast (MinCheckVersion ),
168177 hasListener : false ,
178+ hasRandomFully : version .AtLeast (RandomFullyMinVersion ),
169179 waitFlag : getIPTablesWaitFlag (version ),
170180 restoreWaitFlag : getIPTablesRestoreWaitFlag (version ),
171181 lockfilePath : lockfilePath ,
@@ -632,6 +642,10 @@ func (runner *runner) reload() {
632642 }
633643}
634644
645+ func (runner * runner ) HasRandomFully () bool {
646+ return runner .hasRandomFully
647+ }
648+
635649var iptablesNotFoundStrings = []string {
636650 // iptables-legacy [-A|-I] BAD-CHAIN [...]
637651 // iptables-legacy [-C|-D] GOOD-CHAIN [...non-matching rule...]
0 commit comments