Merge pull request #124529 from danwinship/localtraffic-cleanup-1

LocalTrafficDetector implementation cleanup
This commit is contained in:
Kubernetes Prow Robot 2024-04-26 14:16:03 -07:00 committed by GitHub
commit 4b2d1b6a20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 260 additions and 550 deletions

View File

@ -53,7 +53,6 @@ import (
proxymetrics "k8s.io/kubernetes/pkg/proxy/metrics"
"k8s.io/kubernetes/pkg/proxy/nftables"
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
"k8s.io/utils/exec"
)
@ -165,8 +164,8 @@ func (s *ProxyServer) platformCheckSupported(ctx context.Context) (ipv4Supported
func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.KubeProxyConfiguration, dualStack, initOnly bool) (proxy.Provider, error) {
logger := klog.FromContext(ctx)
var proxier proxy.Provider
var localDetectors [2]proxyutiliptables.LocalTrafficDetector
var localDetector proxyutiliptables.LocalTrafficDetector
var localDetectors [2]proxyutil.LocalTrafficDetector
var localDetector proxyutil.LocalTrafficDetector
var err error
if config.Mode == proxyconfigapi.ProxyModeIPTables {
@ -175,10 +174,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
if dualStack {
ipt, _ := getIPTables(s.PrimaryIPFamily)
localDetectors, err = getDualStackLocalDetectorTuple(logger, config.DetectLocalMode, config, s.podCIDRs)
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
localDetectors = getDualStackLocalDetectorTuple(logger, config.DetectLocalMode, config, s.podCIDRs)
// TODO this has side effects that should only happen when Run() is invoked.
proxier, err = iptables.NewDualStackProxier(
@ -202,10 +198,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
} else {
// Create a single-stack proxier if and only if the node does not support dual-stack (i.e, no iptables support).
_, iptInterface := getIPTables(s.PrimaryIPFamily)
localDetector, err = getLocalDetector(logger, s.PrimaryIPFamily, config.DetectLocalMode, config, s.podCIDRs)
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
localDetector = getLocalDetector(logger, s.PrimaryIPFamily, config.DetectLocalMode, config, s.podCIDRs)
// TODO this has side effects that should only happen when Run() is invoked.
proxier, err = iptables.NewProxier(
@ -245,10 +238,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
ipt, _ := getIPTables(s.PrimaryIPFamily)
// Always ordered to match []ipt
localDetectors, err = getDualStackLocalDetectorTuple(logger, config.DetectLocalMode, config, s.podCIDRs)
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
localDetectors = getDualStackLocalDetectorTuple(logger, config.DetectLocalMode, config, s.podCIDRs)
proxier, err = ipvs.NewDualStackProxier(
ctx,
@ -277,10 +267,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
)
} else {
_, iptInterface := getIPTables(s.PrimaryIPFamily)
localDetector, err = getLocalDetector(logger, s.PrimaryIPFamily, config.DetectLocalMode, config, s.podCIDRs)
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
localDetector = getLocalDetector(logger, s.PrimaryIPFamily, config.DetectLocalMode, config, s.podCIDRs)
proxier, err = ipvs.NewProxier(
ctx,
@ -316,10 +303,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
logger.Info("Using nftables Proxier")
if dualStack {
localDetectors, err = getDualStackLocalDetectorTuple(logger, config.DetectLocalMode, config, s.podCIDRs)
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
localDetectors = getDualStackLocalDetectorTuple(logger, config.DetectLocalMode, config, s.podCIDRs)
// TODO this has side effects that should only happen when Run() is invoked.
proxier, err = nftables.NewDualStackProxier(
@ -339,10 +323,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
)
} else {
// Create a single-stack proxier if and only if the node does not support dual-stack
localDetector, err = getLocalDetector(logger, s.PrimaryIPFamily, config.DetectLocalMode, config, s.podCIDRs)
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
localDetector = getLocalDetector(logger, s.PrimaryIPFamily, config.DetectLocalMode, config, s.podCIDRs)
// TODO this has side effects that should only happen when Run() is invoked.
proxier, err = nftables.NewProxier(
@ -505,7 +486,7 @@ func detectNumCPU() int {
return numCPU
}
func getLocalDetector(logger klog.Logger, ipFamily v1.IPFamily, mode proxyconfigapi.LocalMode, config *proxyconfigapi.KubeProxyConfiguration, nodePodCIDRs []string) (proxyutiliptables.LocalTrafficDetector, error) {
func getLocalDetector(logger klog.Logger, ipFamily v1.IPFamily, mode proxyconfigapi.LocalMode, config *proxyconfigapi.KubeProxyConfiguration, nodePodCIDRs []string) proxyutil.LocalTrafficDetector {
switch mode {
case proxyconfigapi.LocalModeClusterCIDR:
// LocalModeClusterCIDR is the default if --detect-local-mode wasn't passed,
@ -518,7 +499,7 @@ func getLocalDetector(logger klog.Logger, ipFamily v1.IPFamily, mode proxyconfig
cidrsByFamily := proxyutil.MapCIDRsByIPFamily(strings.Split(clusterCIDRs, ","))
if len(cidrsByFamily[ipFamily]) != 0 {
return proxyutiliptables.NewDetectLocalByCIDR(cidrsByFamily[ipFamily][0].String())
return proxyutil.NewDetectLocalByCIDR(cidrsByFamily[ipFamily][0].String())
}
logger.Info("Detect-local-mode set to ClusterCIDR, but no cluster CIDR for family", "ipFamily", ipFamily)
@ -526,35 +507,27 @@ func getLocalDetector(logger klog.Logger, ipFamily v1.IPFamily, mode proxyconfig
case proxyconfigapi.LocalModeNodeCIDR:
cidrsByFamily := proxyutil.MapCIDRsByIPFamily(nodePodCIDRs)
if len(cidrsByFamily[ipFamily]) != 0 {
return proxyutiliptables.NewDetectLocalByCIDR(cidrsByFamily[ipFamily][0].String())
return proxyutil.NewDetectLocalByCIDR(cidrsByFamily[ipFamily][0].String())
}
logger.Info("Detect-local-mode set to NodeCIDR, but no PodCIDR defined at node for family", "ipFamily", ipFamily)
case proxyconfigapi.LocalModeBridgeInterface:
return proxyutiliptables.NewDetectLocalByBridgeInterface(config.DetectLocal.BridgeInterface)
return proxyutil.NewDetectLocalByBridgeInterface(config.DetectLocal.BridgeInterface)
case proxyconfigapi.LocalModeInterfaceNamePrefix:
return proxyutiliptables.NewDetectLocalByInterfaceNamePrefix(config.DetectLocal.InterfaceNamePrefix)
return proxyutil.NewDetectLocalByInterfaceNamePrefix(config.DetectLocal.InterfaceNamePrefix)
}
logger.Info("Defaulting to no-op detect-local")
return proxyutiliptables.NewNoOpLocalDetector(), nil
return proxyutil.NewNoOpLocalDetector()
}
func getDualStackLocalDetectorTuple(logger klog.Logger, mode proxyconfigapi.LocalMode, config *proxyconfigapi.KubeProxyConfiguration, nodePodCIDRs []string) ([2]proxyutiliptables.LocalTrafficDetector, error) {
var localDetectors [2]proxyutiliptables.LocalTrafficDetector
var err error
localDetectors[0], err = getLocalDetector(logger, v1.IPv4Protocol, mode, config, nodePodCIDRs)
if err != nil {
return localDetectors, err
func getDualStackLocalDetectorTuple(logger klog.Logger, mode proxyconfigapi.LocalMode, config *proxyconfigapi.KubeProxyConfiguration, nodePodCIDRs []string) [2]proxyutil.LocalTrafficDetector {
return [2]proxyutil.LocalTrafficDetector{
getLocalDetector(logger, v1.IPv4Protocol, mode, config, nodePodCIDRs),
getLocalDetector(logger, v1.IPv6Protocol, mode, config, nodePodCIDRs),
}
localDetectors[1], err = getLocalDetector(logger, v1.IPv6Protocol, mode, config, nodePodCIDRs)
if err != nil {
return localDetectors, err
}
return localDetectors, nil
}
// platformCleanup removes stale kube-proxy rules that can be safely removed. If

View File

@ -39,7 +39,7 @@ import (
clientsetfake "k8s.io/client-go/kubernetes/fake"
clientgotesting "k8s.io/client-go/testing"
proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config"
proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
"k8s.io/kubernetes/test/utils/ktesting"
netutils "k8s.io/utils/net"
"k8s.io/utils/ptr"
@ -114,58 +114,51 @@ func Test_getLocalDetector(t *testing.T) {
mode proxyconfigapi.LocalMode
config *proxyconfigapi.KubeProxyConfiguration
family v1.IPFamily
expected proxyutiliptables.LocalTrafficDetector
expected proxyutil.LocalTrafficDetector
nodePodCIDRs []string
errExpected bool
}{
// LocalModeClusterCIDR
{
name: "LocalModeClusterCIDR, IPv4 cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
family: v1.IPv4Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/14")),
errExpected: false,
name: "LocalModeClusterCIDR, IPv4 cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
family: v1.IPv4Protocol,
expected: proxyutil.NewDetectLocalByCIDR("10.0.0.0/14"),
},
{
name: "LocalModeClusterCIDR, IPv6 cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64"},
family: v1.IPv6Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("2002:0:0:1234::/64")),
errExpected: false,
name: "LocalModeClusterCIDR, IPv6 cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64"},
family: v1.IPv6Protocol,
expected: proxyutil.NewDetectLocalByCIDR("2002:0:0:1234::/64"),
},
{
name: "LocalModeClusterCIDR, IPv6 cluster with IPv6 config",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
family: v1.IPv6Protocol,
expected: proxyutiliptables.NewNoOpLocalDetector(),
errExpected: false,
name: "LocalModeClusterCIDR, IPv6 cluster with IPv4 config",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
family: v1.IPv6Protocol,
expected: proxyutil.NewNoOpLocalDetector(),
},
{
name: "LocalModeClusterCIDR, IPv4 cluster with IPv6 config",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64"},
family: v1.IPv4Protocol,
expected: proxyutiliptables.NewNoOpLocalDetector(),
errExpected: false,
name: "LocalModeClusterCIDR, IPv4 cluster with IPv6 config",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64"},
family: v1.IPv4Protocol,
expected: proxyutil.NewNoOpLocalDetector(),
},
{
name: "LocalModeClusterCIDR, IPv4 kube-proxy in dual-stack IPv6-primary cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64,10.0.0.0/14"},
family: v1.IPv4Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/14")),
errExpected: false,
name: "LocalModeClusterCIDR, IPv4 kube-proxy in dual-stack IPv6-primary cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64,10.0.0.0/14"},
family: v1.IPv4Protocol,
expected: proxyutil.NewDetectLocalByCIDR("10.0.0.0/14"),
},
{
name: "LocalModeClusterCIDR, no ClusterCIDR",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
family: v1.IPv4Protocol,
expected: proxyutiliptables.NewNoOpLocalDetector(),
errExpected: false,
name: "LocalModeClusterCIDR, no ClusterCIDR",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
family: v1.IPv4Protocol,
expected: proxyutil.NewNoOpLocalDetector(),
},
// LocalModeNodeCIDR
{
@ -173,63 +166,56 @@ func Test_getLocalDetector(t *testing.T) {
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
family: v1.IPv4Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/24")),
expected: proxyutil.NewDetectLocalByCIDR("10.0.0.0/24"),
nodePodCIDRs: []string{"10.0.0.0/24"},
errExpected: false,
},
{
name: "LocalModeNodeCIDR, IPv6 cluster",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64"},
family: v1.IPv6Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96")),
expected: proxyutil.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96"),
nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96"},
errExpected: false,
},
{
name: "LocalModeNodeCIDR, IPv6 cluster with IPv4 config",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
family: v1.IPv6Protocol,
expected: proxyutiliptables.NewNoOpLocalDetector(),
expected: proxyutil.NewNoOpLocalDetector(),
nodePodCIDRs: []string{"10.0.0.0/24"},
errExpected: false,
},
{
name: "LocalModeNodeCIDR, IPv4 cluster with IPv6 config",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64"},
family: v1.IPv4Protocol,
expected: proxyutiliptables.NewNoOpLocalDetector(),
expected: proxyutil.NewNoOpLocalDetector(),
nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96"},
errExpected: false,
},
{
name: "LocalModeNodeCIDR, IPv6 kube-proxy in dual-stack IPv4-primary cluster",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14,2002:0:0:1234::/64"},
family: v1.IPv6Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96")),
expected: proxyutil.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96"),
nodePodCIDRs: []string{"10.0.0.0/24", "2002::1234:abcd:ffff:0:0/96"},
errExpected: false,
},
{
name: "LocalModeNodeCIDR, no PodCIDRs",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
family: v1.IPv4Protocol,
expected: proxyutiliptables.NewNoOpLocalDetector(),
expected: proxyutil.NewNoOpLocalDetector(),
nodePodCIDRs: []string{},
errExpected: false,
},
// unknown mode
{
name: "unknown LocalMode",
mode: proxyconfigapi.LocalMode("abcd"),
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
family: v1.IPv4Protocol,
expected: proxyutiliptables.NewNoOpLocalDetector(),
errExpected: false,
name: "unknown LocalMode",
mode: proxyconfigapi.LocalMode("abcd"),
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
family: v1.IPv4Protocol,
expected: proxyutil.NewNoOpLocalDetector(),
},
// LocalModeBridgeInterface
{
@ -238,9 +224,8 @@ func Test_getLocalDetector(t *testing.T) {
config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocal: proxyconfigapi.DetectLocalConfiguration{BridgeInterface: "eth"},
},
family: v1.IPv4Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByBridgeInterface("eth")),
errExpected: false,
family: v1.IPv4Protocol,
expected: proxyutil.NewDetectLocalByBridgeInterface("eth"),
},
{
name: "LocalModeBridgeInterface, strange bridge name",
@ -248,9 +233,8 @@ func Test_getLocalDetector(t *testing.T) {
config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocal: proxyconfigapi.DetectLocalConfiguration{BridgeInterface: "1234567890123456789"},
},
family: v1.IPv4Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByBridgeInterface("1234567890123456789")),
errExpected: false,
family: v1.IPv4Protocol,
expected: proxyutil.NewDetectLocalByBridgeInterface("1234567890123456789"),
},
// LocalModeInterfaceNamePrefix
{
@ -259,9 +243,8 @@ func Test_getLocalDetector(t *testing.T) {
config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocal: proxyconfigapi.DetectLocalConfiguration{InterfaceNamePrefix: "eth"},
},
family: v1.IPv4Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByInterfaceNamePrefix("eth")),
errExpected: false,
family: v1.IPv4Protocol,
expected: proxyutil.NewDetectLocalByInterfaceNamePrefix("eth"),
},
{
name: "LocalModeInterfaceNamePrefix, strange interface name",
@ -269,25 +252,14 @@ func Test_getLocalDetector(t *testing.T) {
config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocal: proxyconfigapi.DetectLocalConfiguration{InterfaceNamePrefix: "1234567890123456789"},
},
family: v1.IPv4Protocol,
expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByInterfaceNamePrefix("1234567890123456789")),
errExpected: false,
family: v1.IPv4Protocol,
expected: proxyutil.NewDetectLocalByInterfaceNamePrefix("1234567890123456789"),
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
logger, _ := ktesting.NewTestContext(t)
r, err := getLocalDetector(logger, c.family, c.mode, c.config, c.nodePodCIDRs)
if c.errExpected {
if err == nil {
t.Errorf("Expected error, but succeeded with %v", r)
}
return
}
if err != nil {
t.Errorf("Error resolving detect-local: %v", err)
return
}
r := getLocalDetector(logger, c.family, c.mode, c.config, c.nodePodCIDRs)
if !reflect.DeepEqual(r, c.expected) {
t.Errorf("Unexpected detect-local implementation, expected: %q, got: %q", c.expected, r)
}
@ -300,102 +272,105 @@ func Test_getDualStackLocalDetectorTuple(t *testing.T) {
name string
mode proxyconfigapi.LocalMode
config *proxyconfigapi.KubeProxyConfiguration
expected [2]proxyutiliptables.LocalTrafficDetector
expected [2]proxyutil.LocalTrafficDetector
nodePodCIDRs []string
errExpected bool
}{
// LocalModeClusterCIDR
{
name: "LocalModeClusterCIDR, dual-stack IPv4-primary cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14,2002:0:0:1234::/64"},
expected: resolveDualStackLocalDetectors(t)(
proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/14"))(
proxyutiliptables.NewDetectLocalByCIDR("2002:0:0:1234::/64")),
errExpected: false,
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewDetectLocalByCIDR("10.0.0.0/14"),
proxyutil.NewDetectLocalByCIDR("2002:0:0:1234::/64"),
},
},
{
name: "LocalModeClusterCIDR, dual-stack IPv6-primary cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64,10.0.0.0/14"},
expected: resolveDualStackLocalDetectors(t)(
proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/14"))(
proxyutiliptables.NewDetectLocalByCIDR("2002:0:0:1234::/64")),
errExpected: false,
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewDetectLocalByCIDR("10.0.0.0/14"),
proxyutil.NewDetectLocalByCIDR("2002:0:0:1234::/64"),
},
},
{
name: "LocalModeClusterCIDR, single-stack IPv4 cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
expected: [2]proxyutiliptables.LocalTrafficDetector{
resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/14")),
proxyutiliptables.NewNoOpLocalDetector()},
errExpected: false,
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewDetectLocalByCIDR("10.0.0.0/14"),
proxyutil.NewNoOpLocalDetector(),
},
},
{
name: "LocalModeClusterCIDR, single-stack IPv6 cluster",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64"},
expected: [2]proxyutiliptables.LocalTrafficDetector{
proxyutiliptables.NewNoOpLocalDetector(),
resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("2002:0:0:1234::/64"))},
errExpected: false,
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewNoOpLocalDetector(),
proxyutil.NewDetectLocalByCIDR("2002:0:0:1234::/64"),
},
},
{
name: "LocalModeClusterCIDR, no ClusterCIDR",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
expected: [2]proxyutiliptables.LocalTrafficDetector{proxyutiliptables.NewNoOpLocalDetector(), proxyutiliptables.NewNoOpLocalDetector()},
errExpected: false,
name: "LocalModeClusterCIDR, no ClusterCIDR",
mode: proxyconfigapi.LocalModeClusterCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewNoOpLocalDetector(),
proxyutil.NewNoOpLocalDetector(),
},
},
// LocalModeNodeCIDR
{
name: "LocalModeNodeCIDR, dual-stack IPv4-primary cluster",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14,2002:0:0:1234::/64"},
expected: resolveDualStackLocalDetectors(t)(
proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/24"))(
proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96")),
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewDetectLocalByCIDR("10.0.0.0/24"),
proxyutil.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96"),
},
nodePodCIDRs: []string{"10.0.0.0/24", "2002::1234:abcd:ffff:0:0/96"},
errExpected: false,
},
{
name: "LocalModeNodeCIDR, dual-stack IPv6-primary cluster",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64,10.0.0.0/14"},
expected: resolveDualStackLocalDetectors(t)(
proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/24"))(
proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96")),
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewDetectLocalByCIDR("10.0.0.0/24"),
proxyutil.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96"),
},
nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96", "10.0.0.0/24"},
errExpected: false,
},
{
name: "LocalModeNodeCIDR, single-stack IPv4 cluster",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
expected: [2]proxyutiliptables.LocalTrafficDetector{
resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/24")),
proxyutiliptables.NewNoOpLocalDetector()},
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewDetectLocalByCIDR("10.0.0.0/24"),
proxyutil.NewNoOpLocalDetector(),
},
nodePodCIDRs: []string{"10.0.0.0/24"},
errExpected: false,
},
{
name: "LocalModeNodeCIDR, single-stack IPv6 cluster",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002:0:0:1234::/64"},
expected: [2]proxyutiliptables.LocalTrafficDetector{
proxyutiliptables.NewNoOpLocalDetector(),
resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96"))},
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewNoOpLocalDetector(),
proxyutil.NewDetectLocalByCIDR("2002::1234:abcd:ffff:0:0/96"),
},
nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96"},
errExpected: false,
},
{
name: "LocalModeNodeCIDR, no PodCIDRs",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
expected: [2]proxyutiliptables.LocalTrafficDetector{proxyutiliptables.NewNoOpLocalDetector(), proxyutiliptables.NewNoOpLocalDetector()},
name: "LocalModeNodeCIDR, no PodCIDRs",
mode: proxyconfigapi.LocalModeNodeCIDR,
config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewNoOpLocalDetector(),
proxyutil.NewNoOpLocalDetector(),
},
nodePodCIDRs: []string{},
errExpected: false,
},
// LocalModeBridgeInterface
{
@ -404,10 +379,10 @@ func Test_getDualStackLocalDetectorTuple(t *testing.T) {
config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocal: proxyconfigapi.DetectLocalConfiguration{BridgeInterface: "eth"},
},
expected: resolveDualStackLocalDetectors(t)(
proxyutiliptables.NewDetectLocalByBridgeInterface("eth"))(
proxyutiliptables.NewDetectLocalByBridgeInterface("eth")),
errExpected: false,
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewDetectLocalByBridgeInterface("eth"),
proxyutil.NewDetectLocalByBridgeInterface("eth"),
},
},
// LocalModeInterfaceNamePrefix
{
@ -416,26 +391,16 @@ func Test_getDualStackLocalDetectorTuple(t *testing.T) {
config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocal: proxyconfigapi.DetectLocalConfiguration{InterfaceNamePrefix: "veth"},
},
expected: resolveDualStackLocalDetectors(t)(
proxyutiliptables.NewDetectLocalByInterfaceNamePrefix("veth"))(
proxyutiliptables.NewDetectLocalByInterfaceNamePrefix("veth")),
errExpected: false,
expected: [2]proxyutil.LocalTrafficDetector{
proxyutil.NewDetectLocalByInterfaceNamePrefix("veth"),
proxyutil.NewDetectLocalByInterfaceNamePrefix("veth"),
},
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
logger, _ := ktesting.NewTestContext(t)
r, err := getDualStackLocalDetectorTuple(logger, c.mode, c.config, c.nodePodCIDRs)
if c.errExpected {
if err == nil {
t.Errorf("Expected error, but succeeded with %q", r)
}
return
}
if err != nil {
t.Errorf("Error resolving detect-local: %v", err)
return
}
r := getDualStackLocalDetectorTuple(logger, c.mode, c.config, c.nodePodCIDRs)
if !reflect.DeepEqual(r, c.expected) {
t.Errorf("Unexpected detect-local implementation, expected: %q, got: %q", c.expected, r)
}
@ -455,32 +420,6 @@ func makeNodeWithPodCIDRs(cidrs ...string) *v1.Node {
}
}
func resolveLocalDetector(t *testing.T) func(proxyutiliptables.LocalTrafficDetector, error) proxyutiliptables.LocalTrafficDetector {
return func(localDetector proxyutiliptables.LocalTrafficDetector, err error) proxyutiliptables.LocalTrafficDetector {
t.Helper()
if err != nil {
t.Fatalf("Error resolving detect-local: %v", err)
}
return localDetector
}
}
func resolveDualStackLocalDetectors(t *testing.T) func(localDetector proxyutiliptables.LocalTrafficDetector, err1 error) func(proxyutiliptables.LocalTrafficDetector, error) [2]proxyutiliptables.LocalTrafficDetector {
return func(localDetector proxyutiliptables.LocalTrafficDetector, err error) func(proxyutiliptables.LocalTrafficDetector, error) [2]proxyutiliptables.LocalTrafficDetector {
t.Helper()
if err != nil {
t.Fatalf("Error resolving dual stack detect-local: %v", err)
}
return func(otherLocalDetector proxyutiliptables.LocalTrafficDetector, err1 error) [2]proxyutiliptables.LocalTrafficDetector {
t.Helper()
if err1 != nil {
t.Fatalf("Error resolving dual stack detect-local: %v", err)
}
return [2]proxyutiliptables.LocalTrafficDetector{localDetector, otherLocalDetector}
}
}
}
func TestConfigChange(t *testing.T) {
setUp := func() (*os.File, string, error) {
tempDir, err := os.MkdirTemp("", "kubeproxy-config-change")

View File

@ -51,7 +51,6 @@ import (
"k8s.io/kubernetes/pkg/proxy/metaproxier"
"k8s.io/kubernetes/pkg/proxy/metrics"
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
"k8s.io/kubernetes/pkg/util/async"
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
utilexec "k8s.io/utils/exec"
@ -107,7 +106,7 @@ func NewDualStackProxier(
masqueradeAll bool,
localhostNodePorts bool,
masqueradeBit int,
localDetectors [2]proxyutiliptables.LocalTrafficDetector,
localDetectors [2]proxyutil.LocalTrafficDetector,
hostname string,
nodeIPs map[v1.IPFamily]net.IP,
recorder events.EventRecorder,
@ -168,7 +167,7 @@ type Proxier struct {
masqueradeAll bool
masqueradeMark string
conntrack conntrack.Interface
localDetector proxyutiliptables.LocalTrafficDetector
localDetector proxyutil.LocalTrafficDetector
hostname string
nodeIP net.IP
recorder events.EventRecorder
@ -229,7 +228,7 @@ func NewProxier(ctx context.Context,
masqueradeAll bool,
localhostNodePorts bool,
masqueradeBit int,
localDetector proxyutiliptables.LocalTrafficDetector,
localDetector proxyutil.LocalTrafficDetector,
hostname string,
nodeIP net.IP,
recorder events.EventRecorder,

View File

@ -54,7 +54,6 @@ import (
"k8s.io/kubernetes/pkg/proxy/healthcheck"
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
proxyutiltest "k8s.io/kubernetes/pkg/proxy/util/testing"
"k8s.io/kubernetes/pkg/util/async"
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
@ -94,7 +93,7 @@ func NewFakeProxier(ipt utiliptables.Interface) *Proxier {
ipfamily = v1.IPv6Protocol
podCIDR = "fd00:10::/64"
}
detectLocal, _ := proxyutiliptables.NewDetectLocalByCIDR(podCIDR)
detectLocal := proxyutil.NewDetectLocalByCIDR(podCIDR)
networkInterfacer := proxyutiltest.NewFakeNetwork()
itf := net.Interface{Index: 0, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0}
@ -5588,7 +5587,7 @@ func TestInternalExternalMasquerade(t *testing.T) {
fp := NewFakeProxier(ipt)
fp.masqueradeAll = tc.masqueradeAll
if !tc.localDetector {
fp.localDetector = proxyutiliptables.NewNoOpLocalDetector()
fp.localDetector = proxyutil.NewNoOpLocalDetector()
}
setupTest(fp)

View File

@ -53,7 +53,6 @@ import (
"k8s.io/kubernetes/pkg/proxy/metaproxier"
"k8s.io/kubernetes/pkg/proxy/metrics"
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
"k8s.io/kubernetes/pkg/util/async"
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
utilkernel "k8s.io/kubernetes/pkg/util/kernel"
@ -127,7 +126,7 @@ func NewDualStackProxier(
udpTimeout time.Duration,
masqueradeAll bool,
masqueradeBit int,
localDetectors [2]proxyutiliptables.LocalTrafficDetector,
localDetectors [2]proxyutil.LocalTrafficDetector,
hostname string,
nodeIPs map[v1.IPFamily]net.IP,
recorder events.EventRecorder,
@ -207,7 +206,7 @@ type Proxier struct {
conntrack conntrack.Interface
masqueradeAll bool
masqueradeMark string
localDetector proxyutiliptables.LocalTrafficDetector
localDetector proxyutil.LocalTrafficDetector
hostname string
nodeIP net.IP
recorder events.EventRecorder
@ -282,7 +281,7 @@ func NewProxier(
udpTimeout time.Duration,
masqueradeAll bool,
masqueradeBit int,
localDetector proxyutiliptables.LocalTrafficDetector,
localDetector proxyutil.LocalTrafficDetector,
hostname string,
nodeIP net.IP,
recorder events.EventRecorder,

View File

@ -51,7 +51,6 @@ import (
ipvstest "k8s.io/kubernetes/pkg/proxy/ipvs/util/testing"
"k8s.io/kubernetes/pkg/proxy/metrics"
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
proxyutiltest "k8s.io/kubernetes/pkg/proxy/util/testing"
"k8s.io/kubernetes/pkg/util/async"
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
@ -148,7 +147,7 @@ func NewFakeProxier(ctx context.Context, ipt utiliptables.Interface, ipvs utilip
ipset: ipset,
conntrack: conntrack.NewFake(),
strictARP: false,
localDetector: proxyutiliptables.NewNoOpLocalDetector(),
localDetector: proxyutil.NewNoOpLocalDetector(),
hostname: testHostname,
serviceHealthServer: healthcheck.NewFakeServiceHealthServer(),
ipvsScheduler: defaultScheduler,

View File

@ -50,7 +50,6 @@ import (
"k8s.io/kubernetes/pkg/proxy/metaproxier"
"k8s.io/kubernetes/pkg/proxy/metrics"
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
"k8s.io/kubernetes/pkg/util/async"
utilexec "k8s.io/utils/exec"
netutils "k8s.io/utils/net"
@ -111,7 +110,7 @@ func NewDualStackProxier(
minSyncPeriod time.Duration,
masqueradeAll bool,
masqueradeBit int,
localDetectors [2]proxyutiliptables.LocalTrafficDetector,
localDetectors [2]proxyutil.LocalTrafficDetector,
hostname string,
nodeIPs map[v1.IPFamily]net.IP,
recorder events.EventRecorder,
@ -170,7 +169,7 @@ type Proxier struct {
masqueradeAll bool
masqueradeMark string
conntrack conntrack.Interface
localDetector proxyutiliptables.LocalTrafficDetector
localDetector proxyutil.LocalTrafficDetector
hostname string
nodeIP net.IP
recorder events.EventRecorder
@ -207,7 +206,7 @@ func NewProxier(ctx context.Context,
minSyncPeriod time.Duration,
masqueradeAll bool,
masqueradeBit int,
localDetector proxyutiliptables.LocalTrafficDetector,
localDetector proxyutil.LocalTrafficDetector,
hostname string,
nodeIP net.IP,
recorder events.EventRecorder,

View File

@ -44,7 +44,6 @@ import (
"k8s.io/kubernetes/pkg/proxy/healthcheck"
"k8s.io/kubernetes/pkg/proxy/metrics"
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
proxyutiltest "k8s.io/kubernetes/pkg/proxy/util/testing"
"k8s.io/kubernetes/pkg/util/async"
netutils "k8s.io/utils/net"
@ -85,7 +84,7 @@ func NewFakeProxier(ipFamily v1.IPFamily) (*knftables.Fake, *Proxier) {
podCIDR = "fd00:10::/64"
serviceCIDRs = "fd00:10:96::/112"
}
detectLocal, _ := proxyutiliptables.NewDetectLocalByCIDR(podCIDR)
detectLocal := proxyutil.NewDetectLocalByCIDR(podCIDR)
nodePortAddresses := []string{fmt.Sprintf("%s/32", testNodeIP), fmt.Sprintf("%s/128", testNodeIPv6)}
networkInterfacer := proxyutiltest.NewFakeNetwork()
@ -3905,7 +3904,7 @@ func TestInternalExternalMasquerade(t *testing.T) {
nft, fp := NewFakeProxier(v1.IPv4Protocol)
fp.masqueradeAll = tc.masqueradeAll
if !tc.localDetector {
fp.localDetector = proxyutiliptables.NewNoOpLocalDetector()
fp.localDetector = proxyutil.NewNoOpLocalDetector()
}
setupTest(fp)

View File

@ -1,200 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package iptables
import (
"fmt"
netutils "k8s.io/utils/net"
)
// LocalTrafficDetector in a interface to take action (jump) based on whether traffic originated locally
// at the node or not
type LocalTrafficDetector interface {
// IsImplemented returns true if the implementation does something, false otherwise
IsImplemented() bool
// IfLocal returns iptables arguments that will match traffic from a pod
IfLocal() []string
// IfNotLocal returns iptables arguments that will match traffic that is not from a pod
IfNotLocal() []string
// IfLocalNFT returns nftables arguments that will match traffic from a pod
IfLocalNFT() []string
// IfNotLocalNFT returns nftables arguments that will match traffic that is not from a pod
IfNotLocalNFT() []string
}
type noOpLocalDetector struct{}
// NewNoOpLocalDetector is a no-op implementation of LocalTrafficDetector
func NewNoOpLocalDetector() LocalTrafficDetector {
return &noOpLocalDetector{}
}
func (n *noOpLocalDetector) IsImplemented() bool {
return false
}
func (n *noOpLocalDetector) IfLocal() []string {
return nil // no-op; matches all traffic
}
func (n *noOpLocalDetector) IfNotLocal() []string {
return nil // no-op; matches all traffic
}
func (n *noOpLocalDetector) IfLocalNFT() []string {
return nil // no-op; matches all traffic
}
func (n *noOpLocalDetector) IfNotLocalNFT() []string {
return nil // no-op; matches all traffic
}
type detectLocalByCIDR struct {
ifLocal []string
ifNotLocal []string
ifLocalNFT []string
ifNotLocalNFT []string
}
// NewDetectLocalByCIDR implements the LocalTrafficDetector interface using a CIDR. This can be used when a single CIDR
// range can be used to capture the notion of local traffic.
func NewDetectLocalByCIDR(cidr string) (LocalTrafficDetector, error) {
_, parsed, err := netutils.ParseCIDRSloppy(cidr)
if err != nil {
return nil, err
}
nftFamily := "ip"
if netutils.IsIPv6CIDR(parsed) {
nftFamily = "ip6"
}
return &detectLocalByCIDR{
ifLocal: []string{"-s", cidr},
ifNotLocal: []string{"!", "-s", cidr},
ifLocalNFT: []string{nftFamily, "saddr", cidr},
ifNotLocalNFT: []string{nftFamily, "saddr", "!=", cidr},
}, nil
}
func (d *detectLocalByCIDR) IsImplemented() bool {
return true
}
func (d *detectLocalByCIDR) IfLocal() []string {
return d.ifLocal
}
func (d *detectLocalByCIDR) IfNotLocal() []string {
return d.ifNotLocal
}
func (d *detectLocalByCIDR) IfLocalNFT() []string {
return d.ifLocalNFT
}
func (d *detectLocalByCIDR) IfNotLocalNFT() []string {
return d.ifNotLocalNFT
}
type detectLocalByBridgeInterface struct {
ifLocal []string
ifNotLocal []string
ifLocalNFT []string
ifNotLocalNFT []string
}
// NewDetectLocalByBridgeInterface implements the LocalTrafficDetector interface using a bridge interface name.
// This can be used when a bridge can be used to capture the notion of local traffic from pods.
func NewDetectLocalByBridgeInterface(interfaceName string) (LocalTrafficDetector, error) {
if len(interfaceName) == 0 {
return nil, fmt.Errorf("no bridge interface name set")
}
return &detectLocalByBridgeInterface{
ifLocal: []string{"-i", interfaceName},
ifNotLocal: []string{"!", "-i", interfaceName},
ifLocalNFT: []string{"iif", interfaceName},
ifNotLocalNFT: []string{"iif", "!=", interfaceName},
}, nil
}
func (d *detectLocalByBridgeInterface) IsImplemented() bool {
return true
}
func (d *detectLocalByBridgeInterface) IfLocal() []string {
return d.ifLocal
}
func (d *detectLocalByBridgeInterface) IfNotLocal() []string {
return d.ifNotLocal
}
func (d *detectLocalByBridgeInterface) IfLocalNFT() []string {
return d.ifLocalNFT
}
func (d *detectLocalByBridgeInterface) IfNotLocalNFT() []string {
return d.ifNotLocalNFT
}
type detectLocalByInterfaceNamePrefix struct {
ifLocal []string
ifNotLocal []string
ifLocalNFT []string
ifNotLocalNFT []string
}
// NewDetectLocalByInterfaceNamePrefix implements the LocalTrafficDetector interface using an interface name prefix.
// This can be used when a pod interface name prefix can be used to capture the notion of local traffic. Note
// that this will match on all interfaces that start with the given prefix.
func NewDetectLocalByInterfaceNamePrefix(interfacePrefix string) (LocalTrafficDetector, error) {
if len(interfacePrefix) == 0 {
return nil, fmt.Errorf("no interface prefix set")
}
return &detectLocalByInterfaceNamePrefix{
ifLocal: []string{"-i", interfacePrefix + "+"},
ifNotLocal: []string{"!", "-i", interfacePrefix + "+"},
ifLocalNFT: []string{"iif", interfacePrefix + "*"},
ifNotLocalNFT: []string{"iif", "!=", interfacePrefix + "*"},
}, nil
}
func (d *detectLocalByInterfaceNamePrefix) IsImplemented() bool {
return true
}
func (d *detectLocalByInterfaceNamePrefix) IfLocal() []string {
return d.ifLocal
}
func (d *detectLocalByInterfaceNamePrefix) IfNotLocal() []string {
return d.ifNotLocal
}
func (d *detectLocalByInterfaceNamePrefix) IfLocalNFT() []string {
return d.ifLocalNFT
}
func (d *detectLocalByInterfaceNamePrefix) IfNotLocalNFT() []string {
return d.ifNotLocalNFT
}

View File

@ -0,0 +1,116 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package util
import (
netutils "k8s.io/utils/net"
)
// LocalTrafficDetector generates iptables or nftables rules to detect traffic from local pods.
type LocalTrafficDetector interface {
// IsImplemented returns true if the implementation does something, false
// otherwise. You should not call the other methods if IsImplemented() returns
// false.
IsImplemented() bool
// IfLocal returns iptables arguments that will match traffic from a local pod.
IfLocal() []string
// IfNotLocal returns iptables arguments that will match traffic that is not from
// a local pod.
IfNotLocal() []string
// IfLocalNFT returns nftables arguments that will match traffic from a local pod.
IfLocalNFT() []string
// IfNotLocalNFT returns nftables arguments that will match traffic that is not
// from a local pod.
IfNotLocalNFT() []string
}
type detectLocal struct {
ifLocal []string
ifNotLocal []string
ifLocalNFT []string
ifNotLocalNFT []string
}
func (d *detectLocal) IsImplemented() bool {
return len(d.ifLocal) > 0
}
func (d *detectLocal) IfLocal() []string {
return d.ifLocal
}
func (d *detectLocal) IfNotLocal() []string {
return d.ifNotLocal
}
func (d *detectLocal) IfLocalNFT() []string {
return d.ifLocalNFT
}
func (d *detectLocal) IfNotLocalNFT() []string {
return d.ifNotLocalNFT
}
// NewNoOpLocalDetector returns a no-op implementation of LocalTrafficDetector.
func NewNoOpLocalDetector() LocalTrafficDetector {
return &detectLocal{}
}
// NewDetectLocalByCIDR returns a LocalTrafficDetector that considers traffic from the
// provided cidr to be from a local pod, and other traffic to be non-local. cidr is
// assumed to be valid.
func NewDetectLocalByCIDR(cidr string) LocalTrafficDetector {
nftFamily := "ip"
if netutils.IsIPv6CIDRString(cidr) {
nftFamily = "ip6"
}
return &detectLocal{
ifLocal: []string{"-s", cidr},
ifNotLocal: []string{"!", "-s", cidr},
ifLocalNFT: []string{nftFamily, "saddr", cidr},
ifNotLocalNFT: []string{nftFamily, "saddr", "!=", cidr},
}
}
// NewDetectLocalByBridgeInterface returns a LocalTrafficDetector that considers traffic
// from interfaceName to be from a local pod, and traffic from other interfaces to be
// non-local.
func NewDetectLocalByBridgeInterface(interfaceName string) LocalTrafficDetector {
return &detectLocal{
ifLocal: []string{"-i", interfaceName},
ifNotLocal: []string{"!", "-i", interfaceName},
ifLocalNFT: []string{"iif", interfaceName},
ifNotLocalNFT: []string{"iif", "!=", interfaceName},
}
}
// NewDetectLocalByInterfaceNamePrefix returns a LocalTrafficDetector that considers
// traffic from interfaces starting with interfacePrefix to be from a local pod, and
// traffic from other interfaces to be non-local.
func NewDetectLocalByInterfaceNamePrefix(interfacePrefix string) LocalTrafficDetector {
return &detectLocal{
ifLocal: []string{"-i", interfacePrefix + "+"},
ifNotLocal: []string{"!", "-i", interfacePrefix + "+"},
ifLocalNFT: []string{"iif", interfacePrefix + "*"},
ifNotLocalNFT: []string{"iif", "!=", interfacePrefix + "*"},
}
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package iptables
package util
import (
"reflect"
@ -38,46 +38,6 @@ func TestNoOpLocalDetector(t *testing.T) {
}
}
func TestNewDetectLocalByCIDR(t *testing.T) {
cases := []struct {
cidr string
errExpected bool
}{
{
cidr: "10.0.0.0/14",
errExpected: false,
},
{
cidr: "2002:0:0:1234::/64",
errExpected: false,
},
{
cidr: "10.0.0.0",
errExpected: true,
},
{
cidr: "2002:0:0:1234::",
errExpected: true,
},
{
cidr: "",
errExpected: true,
},
}
for i, c := range cases {
r, err := NewDetectLocalByCIDR(c.cidr)
if c.errExpected {
if err == nil {
t.Errorf("Case[%d] expected error, but succeeded with: %q", i, r)
}
continue
}
if err != nil {
t.Errorf("Case[%d] failed with error: %v", i, err)
}
}
}
func TestDetectLocalByCIDR(t *testing.T) {
cases := []struct {
cidr string
@ -96,11 +56,7 @@ func TestDetectLocalByCIDR(t *testing.T) {
},
}
for _, c := range cases {
localDetector, err := NewDetectLocalByCIDR(c.cidr)
if err != nil {
t.Errorf("Error initializing localDetector: %v", err)
continue
}
localDetector := NewDetectLocalByCIDR(c.cidr)
if !localDetector.IsImplemented() {
t.Error("DetectLocalByCIDR returns false for IsImplemented")
}
@ -118,66 +74,6 @@ func TestDetectLocalByCIDR(t *testing.T) {
}
}
func TestNewDetectLocalByBridgeInterface(t *testing.T) {
cases := []struct {
ifaceName string
errExpected bool
}{
{
ifaceName: "avz",
errExpected: false,
},
{
ifaceName: "",
errExpected: true,
},
}
for i, c := range cases {
r, err := NewDetectLocalByBridgeInterface(c.ifaceName)
if c.errExpected {
if err == nil {
t.Errorf("Case[%d] expected error, but succeeded with: %q", i, r)
}
continue
}
if err != nil {
t.Errorf("Case[%d] failed with error: %v", i, err)
}
}
}
func TestNewDetectLocalByInterfaceNamePrefix(t *testing.T) {
cases := []struct {
ifacePrefix string
errExpected bool
}{
{
ifacePrefix: "veth",
errExpected: false,
},
{
ifacePrefix: "cbr0",
errExpected: false,
},
{
ifacePrefix: "",
errExpected: true,
},
}
for i, c := range cases {
r, err := NewDetectLocalByInterfaceNamePrefix(c.ifacePrefix)
if c.errExpected {
if err == nil {
t.Errorf("Case[%d] expected error, but succeeded with: %q", i, r)
}
continue
}
if err != nil {
t.Errorf("Case[%d] failed with error: %v", i, err)
}
}
}
func TestDetectLocalByBridgeInterface(t *testing.T) {
cases := []struct {
ifaceName string
@ -191,11 +87,7 @@ func TestDetectLocalByBridgeInterface(t *testing.T) {
},
}
for _, c := range cases {
localDetector, err := NewDetectLocalByBridgeInterface(c.ifaceName)
if err != nil {
t.Errorf("Error initializing localDetector: %v", err)
continue
}
localDetector := NewDetectLocalByBridgeInterface(c.ifaceName)
if !localDetector.IsImplemented() {
t.Error("DetectLocalByBridgeInterface returns false for IsImplemented")
}
@ -228,11 +120,7 @@ func TestDetectLocalByInterfaceNamePrefix(t *testing.T) {
},
}
for _, c := range cases {
localDetector, err := NewDetectLocalByInterfaceNamePrefix(c.ifacePrefix)
if err != nil {
t.Errorf("Error initializing localDetector: %v", err)
continue
}
localDetector := NewDetectLocalByInterfaceNamePrefix(c.ifacePrefix)
if !localDetector.IsImplemented() {
t.Error("DetectLocalByInterfaceNamePrefix returns false for IsImplemented")
}