From 21b02ad5747ec7950d37a8bd9c2f1519c88d0210 Mon Sep 17 00:00:00 2001 From: m1093782566 Date: Tue, 12 Sep 2017 17:25:30 +0800 Subject: [PATCH] fix service hash flags --- pkg/util/ipvs/ipvs.go | 2 ++ pkg/util/ipvs/ipvs_linux.go | 9 ++++- pkg/util/ipvs/ipvs_linux_test.go | 56 +++++++++++++++++++++++++------- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/pkg/util/ipvs/ipvs.go b/pkg/util/ipvs/ipvs.go index 74917b9b7b..5b51acbf8f 100644 --- a/pkg/util/ipvs/ipvs.go +++ b/pkg/util/ipvs/ipvs.go @@ -63,6 +63,8 @@ type ServiceFlags uint32 const ( // FlagPersistent specify IPVS service session affinity FlagPersistent = 0x1 + // FlagHashed specify IPVS service hash flag + FlagHashed = 0x2 ) // Equal check the equality of virtual server. diff --git a/pkg/util/ipvs/ipvs_linux.go b/pkg/util/ipvs/ipvs_linux.go index be50ad515c..a1651ca645 100644 --- a/pkg/util/ipvs/ipvs_linux.go +++ b/pkg/util/ipvs/ipvs_linux.go @@ -214,10 +214,17 @@ func toVirtualServer(svc *ipvs.Service) (*VirtualServer, error) { Port: svc.Port, Scheduler: svc.SchedName, Protocol: protocolNumbeToString(ProtoType(svc.Protocol)), - Flags: ServiceFlags(svc.Flags), Timeout: svc.Timeout, } + // Test Flags >= 0x2, valid Flags ranges [0x2, 0x3] + if svc.Flags&FlagHashed == 0 { + return nil, fmt.Errorf("Flags of successfully created IPVS service should be >= %d since every service is hashed into the service table", FlagHashed) + } + // Sub Flags to 0x2 + // 011 -> 001, 010 -> 000 + vs.Flags = ServiceFlags(svc.Flags &^ uint32(FlagHashed)) + if vs.Address == nil { if svc.AddressFamily == syscall.AF_INET { vs.Address = net.IPv4zero diff --git a/pkg/util/ipvs/ipvs_linux_test.go b/pkg/util/ipvs/ipvs_linux_test.go index 59142c59e5..1f5549035a 100644 --- a/pkg/util/ipvs/ipvs_linux_test.go +++ b/pkg/util/ipvs/ipvs_linux_test.go @@ -19,6 +19,7 @@ limitations under the License. package ipvs import ( + "fmt" "net" "reflect" "syscall" @@ -117,18 +118,36 @@ func TestUnbindVirtualServerAddress(t *testing.T) { } } -func Test_toFrontendService(t *testing.T) { +func Test_toVirtualServer(t *testing.T) { Tests := []struct { ipvsService ipvs.Service virtualServer VirtualServer + expectError bool + reason string }{ + { + ipvs.Service{ + Flags: 0x0, + }, + VirtualServer{}, + true, + fmt.Sprintf("IPVS Service Flags should be >= %d, got 0x0", FlagHashed), + }, + { + ipvs.Service{ + Flags: 0x1, + }, + VirtualServer{}, + true, + fmt.Sprintf("IPVS Service Flags should be >= %d, got 0x1", FlagHashed), + }, { ipvs.Service{ Protocol: syscall.IPPROTO_TCP, Port: 80, FWMark: 0, SchedName: "", - Flags: 0, + Flags: uint32(FlagPersistent + FlagHashed), Timeout: 0, Netmask: 0xffffffff, AddressFamily: syscall.AF_INET, @@ -140,9 +159,11 @@ func Test_toFrontendService(t *testing.T) { Protocol: "TCP", Port: 80, Scheduler: "", - Flags: 0, + Flags: ServiceFlags(FlagPersistent), Timeout: 0, }, + false, + "", }, { ipvs.Service{ @@ -150,7 +171,7 @@ func Test_toFrontendService(t *testing.T) { Port: 33434, FWMark: 0, SchedName: "wlc", - Flags: 1234, + Flags: uint32(0 + FlagHashed), Timeout: 100, Netmask: 128, AddressFamily: syscall.AF_INET6, @@ -162,9 +183,11 @@ func Test_toFrontendService(t *testing.T) { Protocol: "UDP", Port: 33434, Scheduler: "wlc", - Flags: 1234, + Flags: ServiceFlags(0), Timeout: 100, }, + false, + "", }, { ipvs.Service{ @@ -172,7 +195,7 @@ func Test_toFrontendService(t *testing.T) { Port: 0, FWMark: 0, SchedName: "lc", - Flags: 0, + Flags: uint32(0 + FlagHashed), Timeout: 0, Netmask: 0xffffffff, AddressFamily: syscall.AF_INET, @@ -184,9 +207,11 @@ func Test_toFrontendService(t *testing.T) { Protocol: "", Port: 0, Scheduler: "lc", - Flags: 0, + Flags: ServiceFlags(0), Timeout: 0, }, + false, + "", }, { ipvs.Service{ @@ -194,7 +219,7 @@ func Test_toFrontendService(t *testing.T) { Port: 0, FWMark: 0, SchedName: "wrr", - Flags: 0, + Flags: uint32(FlagPersistent + FlagHashed), Timeout: 0, Netmask: 128, AddressFamily: syscall.AF_INET6, @@ -206,19 +231,26 @@ func Test_toFrontendService(t *testing.T) { Protocol: "", Port: 0, Scheduler: "wrr", - Flags: 0, + Flags: ServiceFlags(FlagPersistent), Timeout: 0, }, + false, + "", }, } for i := range Tests { got, err := toVirtualServer(&Tests[i].ipvsService) - if err != nil { + if Tests[i].expectError && err == nil { + t.Errorf("case: %d, expected error: %s, got nil", i, Tests[i].reason) + } + if !Tests[i].expectError && err != nil { t.Errorf("case: %d, unexpected error: %v", i, err) } - if !reflect.DeepEqual(*got, Tests[i].virtualServer) { - t.Errorf("case: %d, got %#v, want %#v", i, *got, Tests[i].virtualServer) + if got != nil && &Tests[i].virtualServer != nil { + if !reflect.DeepEqual(*got, Tests[i].virtualServer) { + t.Errorf("case: %d, got %#v, want %#v", i, *got, Tests[i].virtualServer) + } } } }