diff --git a/pkg/proxy/ipvs/proxier_test.go b/pkg/proxy/ipvs/proxier_test.go index 0b95a4e523..5c5f7492ff 100644 --- a/pkg/proxy/ipvs/proxier_test.go +++ b/pkg/proxy/ipvs/proxier_test.go @@ -2869,7 +2869,8 @@ func TestCleanLegacyService(t *testing.T) { fp.netlinkHandle.EnsureDummyDevice(DefaultDummyDevice) activeBindAddrs := map[string]bool{"1.1.1.1": true, "2.2.2.2": true, "3.3.3.3": true, "4.4.4.4": true} - currentBindAddrs := []string{"1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4", "5.5.5.5", "6.6.6.6"} + // This is ipv4-only so ipv6 addresses should be ignored + currentBindAddrs := []string{"1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4", "5.5.5.5", "6.6.6.6", "fd80::1:2:3", "fd80::1:2:4"} for i := range currentBindAddrs { fp.netlinkHandle.EnsureAddressBind(currentBindAddrs[i], DefaultDummyDevice) } @@ -2890,15 +2891,125 @@ func TestCleanLegacyService(t *testing.T) { } } - // Addresses 5.5.5.5 and 6.6.6.6 should not be bound any more + // Addresses 5.5.5.5 and 6.6.6.6 should not be bound any more, but the ipv6 addresses should remain remainingAddrs, _ := fp.netlinkHandle.ListBindAddress(DefaultDummyDevice) - if len(remainingAddrs) != 4 { - t.Errorf("Expected number of remaining bound addrs after cleanup to be %v. Got %v", 4, len(remainingAddrs)) + if len(remainingAddrs) != 6 { + t.Errorf("Expected number of remaining bound addrs after cleanup to be %v. Got %v", 6, len(remainingAddrs)) } - // check that address "1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4" are still bound + // check that address "1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4" are bound, ignore ipv6 addresses remainingAddrsMap := make(map[string]bool) - for i := range remainingAddrs { - remainingAddrsMap[remainingAddrs[i]] = true + for _, a := range remainingAddrs { + if net.ParseIP(a).To4() == nil { + continue + } + remainingAddrsMap[a] = true + } + if !reflect.DeepEqual(activeBindAddrs, remainingAddrsMap) { + t.Errorf("Expected remainingAddrsMap %v, got %v", activeBindAddrs, remainingAddrsMap) + } + +} + +func TestCleanLegacyService6(t *testing.T) { + ipt := iptablestest.NewFake() + ipvs := ipvstest.NewFake() + ipset := ipsettest.NewFake(testIPSetVersion) + fp := NewFakeProxier(ipt, ipvs, ipset, nil, []string{"3000::/64", "4000::/64"}) + fp.nodeIP = net.ParseIP("::1") + + // All ipvs services that were processed in the latest sync loop. + activeServices := map[string]bool{"ipvs0": true, "ipvs1": true} + // All ipvs services in the system. + currentServices := map[string]*utilipvs.VirtualServer{ + // Created by kube-proxy. + "ipvs0": { + Address: net.ParseIP("1000::1"), + Protocol: string(v1.ProtocolUDP), + Port: 53, + Scheduler: "rr", + Flags: utilipvs.FlagHashed, + }, + // Created by kube-proxy. + "ipvs1": { + Address: net.ParseIP("1000::2"), + Protocol: string(v1.ProtocolUDP), + Port: 54, + Scheduler: "rr", + Flags: utilipvs.FlagHashed, + }, + // Created by an external party. + "ipvs2": { + Address: net.ParseIP("3000::1"), + Protocol: string(v1.ProtocolUDP), + Port: 55, + Scheduler: "rr", + Flags: utilipvs.FlagHashed, + }, + // Created by an external party. + "ipvs3": { + Address: net.ParseIP("4000::1"), + Protocol: string(v1.ProtocolUDP), + Port: 56, + Scheduler: "rr", + Flags: utilipvs.FlagHashed, + }, + // Created by an external party. + "ipvs4": { + Address: net.ParseIP("5000::1"), + Protocol: string(v1.ProtocolUDP), + Port: 57, + Scheduler: "rr", + Flags: utilipvs.FlagHashed, + }, + // Created by kube-proxy, but now stale. + "ipvs5": { + Address: net.ParseIP("1000::6"), + Protocol: string(v1.ProtocolUDP), + Port: 58, + Scheduler: "rr", + Flags: utilipvs.FlagHashed, + }, + } + for v := range currentServices { + fp.ipvs.AddVirtualServer(currentServices[v]) + } + + fp.netlinkHandle.EnsureDummyDevice(DefaultDummyDevice) + activeBindAddrs := map[string]bool{"1000::1": true, "1000::2": true, "3000::1": true, "4000::1": true} + // This is ipv6-only so ipv4 addresses should be ignored + currentBindAddrs := []string{"1000::1", "1000::2", "3000::1", "4000::1", "5000::1", "1000::6", "1.1.1.1", "2.2.2.2"} + for i := range currentBindAddrs { + fp.netlinkHandle.EnsureAddressBind(currentBindAddrs[i], DefaultDummyDevice) + } + + fp.cleanLegacyService(activeServices, currentServices, map[string]bool{"5000::1": true, "1000::6": true}) + // ipvs4 and ipvs5 should have been cleaned. + remainingVirtualServers, _ := fp.ipvs.GetVirtualServers() + if len(remainingVirtualServers) != 4 { + t.Errorf("Expected number of remaining IPVS services after cleanup to be %v. Got %v", 4, len(remainingVirtualServers)) + } + for _, vs := range remainingVirtualServers { + // Checking that ipvs4 and ipvs5 were removed. + if vs.Port == 57 { + t.Errorf("Expected ipvs4 to be removed after cleanup. It still remains") + } + if vs.Port == 58 { + t.Errorf("Expected ipvs5 to be removed after cleanup. It still remains") + } + } + + // Addresses 5000::1 and 1000::6 should not be bound any more, but the ipv4 addresses should remain + remainingAddrs, _ := fp.netlinkHandle.ListBindAddress(DefaultDummyDevice) + if len(remainingAddrs) != 6 { + t.Errorf("Expected number of remaining bound addrs after cleanup to be %v. Got %v", 6, len(remainingAddrs)) + } + // check that address "1000::1", "1000::2", "3000::1", "4000::1" are still bound, ignore ipv4 addresses + remainingAddrsMap := make(map[string]bool) + for _, a := range remainingAddrs { + if net.ParseIP(a).To4() != nil { + continue + } + remainingAddrsMap[a] = true } if !reflect.DeepEqual(activeBindAddrs, remainingAddrsMap) { t.Errorf("Expected remainingAddrsMap %v, got %v", activeBindAddrs, remainingAddrsMap)