From f3b3496e1d26403440b853e6650110629d0339c5 Mon Sep 17 00:00:00 2001 From: wangyizhi1 Date: Thu, 31 Aug 2023 14:53:19 +0800 Subject: [PATCH] fix: Added single-cluster network protection Signed-off-by: wangyizhi1 --- pkg/constants/network.go | 27 ++++++++++ pkg/network-manager/handlers/host_network.go | 2 +- pkg/network-manager/handlers/pod_routes.go | 19 ++++++- .../handlers/vxbridge_mac_cache.go | 2 +- .../handlers/vxbridge_network.go | 2 +- .../handlers/vxlocal_mac_cache.go | 2 +- .../handlers/vxlocal_network.go | 2 +- pkg/network-manager/helpers/network.go | 19 ++++++- pkg/network-manager/helpers/network_test.go | 54 +++++++++++++++++++ 9 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 pkg/constants/network.go diff --git a/pkg/constants/network.go b/pkg/constants/network.go new file mode 100644 index 000000000..af77f6f44 --- /dev/null +++ b/pkg/constants/network.go @@ -0,0 +1,27 @@ +package constants + +type VxlanType int + +const ( + VXLAN_BRIDGE_NAME = "vx-bridge" + VXLAN_LOCAL_NAME = "vx-local" + + VXLAN_BRIDGE_NAME_6 = "vx-bridge-6" + VXLAN_LOCAL_NAME_6 = "vx-local-6" + + VXLAN_BRIDGE_ID = 54 + VXLAN_BRIDGE_PORT = 4876 + + VXLAN_LOCAL_ID = 55 + VXLAN_LOCAL_PORT = 4877 + + VXLAN_BRIDGE_ID_6 = 64 + VXLAN_BRIDGE_PORT_6 = 4866 + + VXLAN_LOCAL_ID_6 = 65 + VXLAN_LOCAL_PORT_6 = 4867 + + ALL_ZERO_MAC = "00:00:00:00:00:00" + + IPTablesPostRoutingChain = "POSTROUTING" +) diff --git a/pkg/network-manager/handlers/host_network.go b/pkg/network-manager/handlers/host_network.go index 46fcf881b..aae0d3c08 100644 --- a/pkg/network-manager/handlers/host_network.go +++ b/pkg/network-manager/handlers/host_network.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/kosmos.io/kosmos/pkg/apis/clusterlink/v1alpha1" - constants "github.com/kosmos.io/kosmos/pkg/network" + "github.com/kosmos.io/kosmos/pkg/constants" ) type HostNetwork struct { diff --git a/pkg/network-manager/handlers/pod_routes.go b/pkg/network-manager/handlers/pod_routes.go index b10282606..15c4ea9b8 100644 --- a/pkg/network-manager/handlers/pod_routes.go +++ b/pkg/network-manager/handlers/pod_routes.go @@ -6,7 +6,7 @@ import ( "k8s.io/klog/v2" "github.com/kosmos.io/kosmos/pkg/apis/clusterlink/v1alpha1" - constants "github.com/kosmos.io/kosmos/pkg/network" + "github.com/kosmos.io/kosmos/pkg/constants" "github.com/kosmos.io/kosmos/pkg/network-manager/helpers" ) @@ -52,6 +52,17 @@ func ConvertToGlobalCIDRs(cidrs []string, globalCIDRMap map[string]string) []str return mappedCIDRs } +// ifCIDRConflictWithSelf If the target CIDR conflicts with current CIDR, do not add the route, as it will otherwise +// impact the single-cluster network. +func ifCIDRConflictWithSelf(selfCIDRs []string, tarCIDR string) bool { + for _, cidr := range selfCIDRs { + if helpers.Intersect(cidr, tarCIDR) { + return true + } + } + return false +} + func BuildRoutes(ctx *Context, target *v1alpha1.ClusterNode, cidrs []string) { otherClusterNodes := ctx.Filter.GetAllNodesExceptCluster(target.Spec.ClusterName) @@ -77,6 +88,12 @@ func BuildRoutes(ctx *Context, target *v1alpha1.ClusterNode, cidrs []string) { for _, n := range otherClusterNodes { srcCluster := ctx.Filter.GetClusterByName(n.Spec.ClusterName) + + allCIDRs := append(srcCluster.Status.PodCIDRs, srcCluster.Status.ServiceCIDRs...) + if ifCIDRConflictWithSelf(allCIDRs, cidr) { + continue + } + if n.IsGateway() || srcCluster.IsP2P() { ctx.Results[n.Name].Routes = append(ctx.Results[n.Name].Routes, v1alpha1.Route{ CIDR: cidr, diff --git a/pkg/network-manager/handlers/vxbridge_mac_cache.go b/pkg/network-manager/handlers/vxbridge_mac_cache.go index 88716ba42..6cba1f87a 100644 --- a/pkg/network-manager/handlers/vxbridge_mac_cache.go +++ b/pkg/network-manager/handlers/vxbridge_mac_cache.go @@ -6,7 +6,7 @@ import ( "k8s.io/klog/v2" "github.com/kosmos.io/kosmos/pkg/apis/clusterlink/v1alpha1" - constants "github.com/kosmos.io/kosmos/pkg/network" + "github.com/kosmos.io/kosmos/pkg/constants" ) type VxBridgeMacCache struct { diff --git a/pkg/network-manager/handlers/vxbridge_network.go b/pkg/network-manager/handlers/vxbridge_network.go index f030092a5..3d7534eb2 100644 --- a/pkg/network-manager/handlers/vxbridge_network.go +++ b/pkg/network-manager/handlers/vxbridge_network.go @@ -2,7 +2,7 @@ package handlers import ( "github.com/kosmos.io/kosmos/pkg/apis/clusterlink/v1alpha1" - constants "github.com/kosmos.io/kosmos/pkg/network" + "github.com/kosmos.io/kosmos/pkg/constants" "github.com/kosmos.io/kosmos/pkg/network-manager/helpers" ) diff --git a/pkg/network-manager/handlers/vxlocal_mac_cache.go b/pkg/network-manager/handlers/vxlocal_mac_cache.go index 4c4e249f0..98083bbac 100644 --- a/pkg/network-manager/handlers/vxlocal_mac_cache.go +++ b/pkg/network-manager/handlers/vxlocal_mac_cache.go @@ -6,7 +6,7 @@ import ( "k8s.io/klog/v2" "github.com/kosmos.io/kosmos/pkg/apis/clusterlink/v1alpha1" - constants "github.com/kosmos.io/kosmos/pkg/network" + "github.com/kosmos.io/kosmos/pkg/constants" ) type VxLocalMacCache struct { diff --git a/pkg/network-manager/handlers/vxlocal_network.go b/pkg/network-manager/handlers/vxlocal_network.go index 2c47b5fb9..b0e4a0685 100644 --- a/pkg/network-manager/handlers/vxlocal_network.go +++ b/pkg/network-manager/handlers/vxlocal_network.go @@ -2,7 +2,7 @@ package handlers import ( "github.com/kosmos.io/kosmos/pkg/apis/clusterlink/v1alpha1" - constants "github.com/kosmos.io/kosmos/pkg/network" + "github.com/kosmos.io/kosmos/pkg/constants" "github.com/kosmos.io/kosmos/pkg/network-manager/helpers" ) diff --git a/pkg/network-manager/helpers/network.go b/pkg/network-manager/helpers/network.go index e985c8548..c6376f5aa 100644 --- a/pkg/network-manager/helpers/network.go +++ b/pkg/network-manager/helpers/network.go @@ -9,7 +9,7 @@ import ( "k8s.io/klog/v2" "github.com/kosmos.io/kosmos/pkg/apis/clusterlink/v1alpha1" - constants "github.com/kosmos.io/kosmos/pkg/network" + "github.com/kosmos.io/kosmos/pkg/constants" ) type IPType int @@ -159,3 +159,20 @@ func BuildVxlanDevice(devName string, underlayIP string, destNetString string, b return dev } + +func Intersect(net1 string, net2 string) bool { + _, ipNet1, err1 := net.ParseCIDR(net1) + _, ipNet2, err2 := net.ParseCIDR(net2) + + if err1 != nil || err2 != nil { + klog.Errorf("the net is invalid, err: %v, %v", err1, err2) + // In actual scenarios, true is more secure + return true + } + + if ipNet1.Contains(ipNet2.IP) || ipNet2.Contains(ipNet1.IP) { + return true + } + + return false +} diff --git a/pkg/network-manager/helpers/network_test.go b/pkg/network-manager/helpers/network_test.go index 6a4030f19..220e5aa64 100644 --- a/pkg/network-manager/helpers/network_test.go +++ b/pkg/network-manager/helpers/network_test.go @@ -34,3 +34,57 @@ func Test_GenerateVxlanIP(t *testing.T) { }) } } + +func Test_Intersect(t *testing.T) { + tests := []struct { + name string + cidr1 string + cidr2 string + want bool + }{ + { + name: "ipv4-1", + cidr1: "10.233.0.0/16", + cidr2: "10.233.0.0/18", + want: true, + }, + { + name: "ipv4-2", + cidr1: "10.233.0.0/18", + cidr2: "10.233.0.0/16", + want: true, + }, + { + name: "ipv4-3", + cidr1: "10.233.0.0/16", + cidr2: "10.233.1.0/23", + want: true, + }, + { + name: "ipv4-4", + cidr1: "10.222.0.0/16", + cidr2: "10.223.0.0/16", + want: false, + }, + { + name: "ipv6", + cidr1: "2409:7c85:6200::a0e:1722/16", + cidr2: "2409:7c85:6200::a0e:1702/12", + want: true, + }, + { + name: "err", + cidr1: "10.233.0/16", + cidr2: "10.233.0.0/18", + want: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Intersect(tt.cidr1, tt.cidr2); got != tt.want { + t.Errorf("helpers.Intersect() = %v, want %v", got, tt.want) + } + }) + } +}