diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index e223f0f9e8f..b7d4292dace 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -1070,8 +1070,13 @@ func (proxier *Proxier) syncProxyRules() { "-d", utilproxy.ToCIDR(net.ParseIP(externalIP)), "--dport", strconv.Itoa(svcInfo.Port()), ) - // We have to SNAT packets to external IPs. - writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) + + destChain := svcXlbChain + // We have to SNAT packets to external IPs if externalTrafficPolicy is cluster. + if !(utilfeature.DefaultFeatureGate.Enabled(features.ExternalPolicyForExternalIP) && svcInfo.OnlyNodeLocalEndpoints()) { + destChain = svcChain + writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) + } // Allow traffic for external IPs that does not come from a bridge (i.e. not from a container) // nor from a local process to be forwarded to the service. @@ -1080,11 +1085,11 @@ func (proxier *Proxier) syncProxyRules() { externalTrafficOnlyArgs := append(args, "-m", "physdev", "!", "--physdev-is-in", "-m", "addrtype", "!", "--src-type", "LOCAL") - writeLine(proxier.natRules, append(externalTrafficOnlyArgs, "-j", string(svcChain))...) + writeLine(proxier.natRules, append(externalTrafficOnlyArgs, "-j", string(destChain))...) dstLocalOnlyArgs := append(args, "-m", "addrtype", "--dst-type", "LOCAL") // Allow traffic bound for external IPs that happen to be recognized as local IPs to stay local. // This covers cases like GCE load-balancers which get added to the local routing table. - writeLine(proxier.natRules, append(dstLocalOnlyArgs, "-j", string(svcChain))...) + writeLine(proxier.natRules, append(dstLocalOnlyArgs, "-j", string(destChain))...) } else { // No endpoints. writeLine(proxier.filterRules,