diff --git a/pkg/util/net.go b/pkg/util/net.go index 4794a25eed9..800acea7d78 100644 --- a/pkg/util/net.go +++ b/pkg/util/net.go @@ -130,7 +130,6 @@ func CIDRContainIP(cidrStr, ipStr string) bool { return false } - found := false for _, ip := range ips { if CheckProtocol(cidr) != CheckProtocol(ip) { continue @@ -140,16 +139,10 @@ func CIDRContainIP(cidrStr, ipStr string) bool { return false } - // After ns supports multiple subnets, the ippool static addresses can be allocated in any subnets, such as "ovn.kubernetes.io/ip_pool: 11.16.10.14,12.26.11.21" - found = false - if cidrNet.Contains(ipAddr) { - found = true - break + if !cidrNet.Contains(ipAddr) { + return false } } - if !found { - return false - } } // v4 and v6 address should be both matched for dualstack check return true diff --git a/pkg/util/net_test.go b/pkg/util/net_test.go index 1ae5a7f45f5..bccc995aac0 100644 --- a/pkg/util/net_test.go +++ b/pkg/util/net_test.go @@ -1013,12 +1013,10 @@ func Test_CIDRContainIP(t *testing.T) { true, }, { - // After ns supports multiple subnets, the ippool static addresses can be allocated in any subnets, such as "ovn.kubernetes.io/ip_pool: 11.16.10.14,12.26.11.21" - // so if anyone ip is included in cidr, return true "ipv4 family which CIDR does't contain ip", "192.168.230.0/24", "192.168.231.10,192.168.230.11", - true, + false, }, { "ipv6 family", @@ -1039,12 +1037,10 @@ func Test_CIDRContainIP(t *testing.T) { true, }, { - // After ns supports multiple subnets, the ippool static addresses can be allocated in any subnets, such as "ovn.kubernetes.io/ip_pool: 11.16.10.14,12.26.11.21" - // so if anyone ip is included in cidr, return true "dual which CIDR does't contain ip", "192.168.230.0/24,fc00::0af4:00/112", "fc00::0af4:10,fd00::0af4:11,192.168.230.10,192.168.230.11", - true, + false, }, { "different family", @@ -1068,7 +1064,6 @@ func Test_CIDRContainIP(t *testing.T) { for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - t.Logf("test case %v", tt.desc) got := CIDRContainIP(tt.cidrs, tt.ips) require.Equal(t, got, tt.want) }) diff --git a/pkg/util/validator.go b/pkg/util/validator.go index a73bf824752..550493984ca 100644 --- a/pkg/util/validator.go +++ b/pkg/util/validator.go @@ -229,17 +229,29 @@ func ValidatePodNetwork(annotations map[string]string) error { if ipPool != "" { if strings.ContainsRune(ipPool, ';') || strings.ContainsRune(ipPool, ',') || net.ParseIP(ipPool) != nil { for _, ips := range strings.Split(ipPool, ";") { - if cidrStr := annotations[CidrAnnotation]; cidrStr != "" { - if !CIDRContainIP(cidrStr, ips) { - errors = append(errors, fmt.Errorf("%s not in cidr %s", ips, cidrStr)) - continue - } - } - + found := false for _, ip := range strings.Split(ips, ",") { if net.ParseIP(strings.TrimSpace(ip)) == nil { errors = append(errors, fmt.Errorf("%s in %s is not a valid address", ip, IPPoolAnnotation)) } + + // After ns supports multiple subnets, the ippool static addresses can be allocated in any subnets, such as "ovn.kubernetes.io/ip_pool: 11.16.10.14,12.26.11.21" + // so if anyone ip is included in cidr, return true + if cidrStr := annotations[CidrAnnotation]; cidrStr != "" { + if CIDRContainIP(cidrStr, ip) { + found = true + break + } + } else { + // annotation maybe empty when a pod is new created, do not return err in this situation + found = true + break + } + } + + if !found { + errors = append(errors, fmt.Errorf("%s not in cidr %s", ips, annotations[CidrAnnotation])) + continue } } } diff --git a/pkg/util/validator_test.go b/pkg/util/validator_test.go index 89fa6b8f178..8f37442ce13 100644 --- a/pkg/util/validator_test.go +++ b/pkg/util/validator_test.go @@ -584,7 +584,7 @@ func TestValidatePodNetwork(t *testing.T) { "ovn.kubernetes.io/egress_rate": "1", "ovn.kubernetes.io/cidr": "10.16.0.0/16", }, - err: "10.16.1111.15,10.16.0.16,10.16.0.17 not in cidr 10.16.0.0/16", + err: "10.16.1111.15 in ovn.kubernetes.io/ip_pool is not a valid address", }, { name: "ingRaErr", @@ -613,6 +613,7 @@ func TestValidatePodNetwork(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Logf("test case %v", tt.name) ret := ValidatePodNetwork(tt.annotations) if !ErrorContains(ret, tt.err) { t.Errorf("got %v, want a error %v", ret, tt.err)