2017-07-16 05:35:55 +00:00
|
|
|
// +build linux
|
|
|
|
|
|
|
|
/*
|
|
|
|
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 ipvs
|
|
|
|
|
|
|
|
import (
|
2017-09-12 09:25:30 +00:00
|
|
|
"fmt"
|
2017-07-16 05:35:55 +00:00
|
|
|
"net"
|
|
|
|
"reflect"
|
|
|
|
"syscall"
|
|
|
|
"testing"
|
|
|
|
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs "github.com/docker/libnetwork/ipvs"
|
2017-07-16 05:35:55 +00:00
|
|
|
)
|
|
|
|
|
2017-09-12 09:25:30 +00:00
|
|
|
func Test_toVirtualServer(t *testing.T) {
|
2017-07-16 05:35:55 +00:00
|
|
|
Tests := []struct {
|
2018-02-06 16:26:17 +00:00
|
|
|
ipvsService libipvs.Service
|
2017-07-16 05:35:55 +00:00
|
|
|
virtualServer VirtualServer
|
2017-09-12 09:25:30 +00:00
|
|
|
expectError bool
|
|
|
|
reason string
|
2017-07-16 05:35:55 +00:00
|
|
|
}{
|
2017-09-12 09:25:30 +00:00
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: 0x0,
|
|
|
|
},
|
|
|
|
VirtualServer{},
|
|
|
|
true,
|
|
|
|
fmt.Sprintf("IPVS Service Flags should be >= %d, got 0x0", FlagHashed),
|
|
|
|
},
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: 0x1,
|
|
|
|
},
|
|
|
|
VirtualServer{},
|
|
|
|
true,
|
|
|
|
fmt.Sprintf("IPVS Service Flags should be >= %d, got 0x1", FlagHashed),
|
|
|
|
},
|
2017-07-16 05:35:55 +00:00
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-07-16 05:35:55 +00:00
|
|
|
Protocol: syscall.IPPROTO_TCP,
|
|
|
|
Port: 80,
|
|
|
|
FWMark: 0,
|
|
|
|
SchedName: "",
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: uint32(FlagPersistent + FlagHashed),
|
2017-07-16 05:35:55 +00:00
|
|
|
Timeout: 0,
|
|
|
|
Netmask: 0xffffffff,
|
|
|
|
AddressFamily: syscall.AF_INET,
|
|
|
|
Address: nil,
|
|
|
|
PEName: "",
|
|
|
|
},
|
|
|
|
VirtualServer{
|
|
|
|
Address: net.ParseIP("0.0.0.0"),
|
|
|
|
Protocol: "TCP",
|
|
|
|
Port: 80,
|
|
|
|
Scheduler: "",
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: ServiceFlags(FlagPersistent),
|
2017-07-16 05:35:55 +00:00
|
|
|
Timeout: 0,
|
|
|
|
},
|
2017-09-12 09:25:30 +00:00
|
|
|
false,
|
|
|
|
"",
|
2017-07-16 05:35:55 +00:00
|
|
|
},
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-07-16 05:35:55 +00:00
|
|
|
Protocol: syscall.IPPROTO_UDP,
|
|
|
|
Port: 33434,
|
|
|
|
FWMark: 0,
|
|
|
|
SchedName: "wlc",
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: uint32(0 + FlagHashed),
|
2017-07-16 05:35:55 +00:00
|
|
|
Timeout: 100,
|
|
|
|
Netmask: 128,
|
|
|
|
AddressFamily: syscall.AF_INET6,
|
|
|
|
Address: net.ParseIP("2012::beef"),
|
|
|
|
PEName: "",
|
|
|
|
},
|
|
|
|
VirtualServer{
|
|
|
|
Address: net.ParseIP("2012::beef"),
|
|
|
|
Protocol: "UDP",
|
|
|
|
Port: 33434,
|
|
|
|
Scheduler: "wlc",
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: ServiceFlags(0),
|
2017-07-16 05:35:55 +00:00
|
|
|
Timeout: 100,
|
|
|
|
},
|
2017-09-12 09:25:30 +00:00
|
|
|
false,
|
|
|
|
"",
|
2017-07-16 05:35:55 +00:00
|
|
|
},
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-07-16 05:35:55 +00:00
|
|
|
Protocol: 0,
|
|
|
|
Port: 0,
|
|
|
|
FWMark: 0,
|
|
|
|
SchedName: "lc",
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: uint32(0 + FlagHashed),
|
2017-07-16 05:35:55 +00:00
|
|
|
Timeout: 0,
|
|
|
|
Netmask: 0xffffffff,
|
|
|
|
AddressFamily: syscall.AF_INET,
|
|
|
|
Address: net.ParseIP("1.2.3.4"),
|
|
|
|
PEName: "",
|
|
|
|
},
|
|
|
|
VirtualServer{
|
|
|
|
Address: net.ParseIP("1.2.3.4"),
|
|
|
|
Protocol: "",
|
|
|
|
Port: 0,
|
|
|
|
Scheduler: "lc",
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: ServiceFlags(0),
|
2017-07-16 05:35:55 +00:00
|
|
|
Timeout: 0,
|
|
|
|
},
|
2017-09-12 09:25:30 +00:00
|
|
|
false,
|
|
|
|
"",
|
2017-07-16 05:35:55 +00:00
|
|
|
},
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-07-16 05:35:55 +00:00
|
|
|
Protocol: 0,
|
|
|
|
Port: 0,
|
|
|
|
FWMark: 0,
|
|
|
|
SchedName: "wrr",
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: uint32(FlagPersistent + FlagHashed),
|
2017-07-16 05:35:55 +00:00
|
|
|
Timeout: 0,
|
|
|
|
Netmask: 128,
|
|
|
|
AddressFamily: syscall.AF_INET6,
|
|
|
|
Address: nil,
|
|
|
|
PEName: "",
|
|
|
|
},
|
|
|
|
VirtualServer{
|
|
|
|
Address: net.ParseIP("::0"),
|
|
|
|
Protocol: "",
|
|
|
|
Port: 0,
|
|
|
|
Scheduler: "wrr",
|
2017-09-12 09:25:30 +00:00
|
|
|
Flags: ServiceFlags(FlagPersistent),
|
2017-07-16 05:35:55 +00:00
|
|
|
Timeout: 0,
|
|
|
|
},
|
2017-09-12 09:25:30 +00:00
|
|
|
false,
|
|
|
|
"",
|
2017-07-16 05:35:55 +00:00
|
|
|
},
|
2018-06-11 11:25:18 +00:00
|
|
|
{
|
|
|
|
libipvs.Service{
|
|
|
|
Protocol: syscall.IPPROTO_SCTP,
|
|
|
|
Port: 80,
|
|
|
|
FWMark: 0,
|
|
|
|
SchedName: "",
|
|
|
|
Flags: uint32(FlagPersistent + FlagHashed),
|
|
|
|
Timeout: 0,
|
|
|
|
Netmask: 0xffffffff,
|
|
|
|
AddressFamily: syscall.AF_INET,
|
|
|
|
Address: nil,
|
|
|
|
PEName: "",
|
|
|
|
},
|
|
|
|
VirtualServer{
|
|
|
|
Address: net.ParseIP("0.0.0.0"),
|
|
|
|
Protocol: "SCTP",
|
|
|
|
Port: 80,
|
|
|
|
Scheduler: "",
|
|
|
|
Flags: ServiceFlags(FlagPersistent),
|
|
|
|
Timeout: 0,
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
"",
|
|
|
|
},
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for i := range Tests {
|
|
|
|
got, err := toVirtualServer(&Tests[i].ipvsService)
|
2017-09-12 09:25:30 +00:00
|
|
|
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 {
|
2017-07-16 05:35:55 +00:00
|
|
|
t.Errorf("case: %d, unexpected error: %v", i, err)
|
|
|
|
}
|
2017-09-12 09:25:30 +00:00
|
|
|
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)
|
|
|
|
}
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-06 16:26:17 +00:00
|
|
|
func Test_toIPVSService(t *testing.T) {
|
2017-07-16 05:35:55 +00:00
|
|
|
Tests := []struct {
|
2018-02-06 16:26:17 +00:00
|
|
|
ipvsService libipvs.Service
|
2017-07-16 05:35:55 +00:00
|
|
|
virtualServer VirtualServer
|
|
|
|
}{
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-07-16 05:35:55 +00:00
|
|
|
Protocol: syscall.IPPROTO_TCP,
|
|
|
|
Port: 80,
|
|
|
|
FWMark: 0,
|
|
|
|
SchedName: "",
|
|
|
|
Flags: 0,
|
|
|
|
Timeout: 0,
|
|
|
|
Netmask: 0xffffffff,
|
|
|
|
AddressFamily: syscall.AF_INET,
|
|
|
|
Address: net.ParseIP("0.0.0.0"),
|
|
|
|
PEName: "",
|
|
|
|
},
|
|
|
|
VirtualServer{
|
|
|
|
Address: net.ParseIP("0.0.0.0"),
|
|
|
|
Protocol: "TCP",
|
|
|
|
Port: 80,
|
|
|
|
Scheduler: "",
|
|
|
|
Flags: 0,
|
|
|
|
Timeout: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-07-16 05:35:55 +00:00
|
|
|
Protocol: syscall.IPPROTO_UDP,
|
|
|
|
Port: 33434,
|
|
|
|
FWMark: 0,
|
|
|
|
SchedName: "wlc",
|
|
|
|
Flags: 1234,
|
|
|
|
Timeout: 100,
|
|
|
|
Netmask: 128,
|
|
|
|
AddressFamily: syscall.AF_INET6,
|
|
|
|
Address: net.ParseIP("2012::beef"),
|
|
|
|
PEName: "",
|
|
|
|
},
|
|
|
|
VirtualServer{
|
|
|
|
Address: net.ParseIP("2012::beef"),
|
|
|
|
Protocol: "UDP",
|
|
|
|
Port: 33434,
|
|
|
|
Scheduler: "wlc",
|
|
|
|
Flags: 1234,
|
|
|
|
Timeout: 100,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-07-16 05:35:55 +00:00
|
|
|
Protocol: 0,
|
|
|
|
Port: 0,
|
|
|
|
FWMark: 0,
|
|
|
|
SchedName: "lc",
|
|
|
|
Flags: 0,
|
|
|
|
Timeout: 0,
|
|
|
|
Netmask: 0xffffffff,
|
|
|
|
AddressFamily: syscall.AF_INET,
|
|
|
|
Address: net.ParseIP("1.2.3.4"),
|
|
|
|
PEName: "",
|
|
|
|
},
|
|
|
|
VirtualServer{
|
|
|
|
Address: net.ParseIP("1.2.3.4"),
|
|
|
|
Protocol: "",
|
|
|
|
Port: 0,
|
|
|
|
Scheduler: "lc",
|
|
|
|
Flags: 0,
|
|
|
|
Timeout: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Service{
|
2017-07-16 05:35:55 +00:00
|
|
|
Protocol: 0,
|
|
|
|
Port: 0,
|
|
|
|
FWMark: 0,
|
|
|
|
SchedName: "wrr",
|
|
|
|
Flags: 0,
|
|
|
|
Timeout: 0,
|
|
|
|
Netmask: 128,
|
|
|
|
AddressFamily: syscall.AF_INET6,
|
|
|
|
Address: net.ParseIP("::0"),
|
|
|
|
PEName: "",
|
|
|
|
},
|
|
|
|
VirtualServer{
|
|
|
|
Address: net.ParseIP("::0"),
|
|
|
|
Protocol: "",
|
|
|
|
Port: 0,
|
|
|
|
Scheduler: "wrr",
|
|
|
|
Flags: 0,
|
|
|
|
Timeout: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range Tests {
|
2018-02-06 16:26:17 +00:00
|
|
|
got, err := toIPVSService(&Tests[i].virtualServer)
|
2017-07-16 05:35:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("case: %d, unexpected error: %v", i, err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(*got, Tests[i].ipvsService) {
|
|
|
|
t.Errorf("case: %d - got %#v, want %#v", i, *got, Tests[i].ipvsService)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-06 16:26:17 +00:00
|
|
|
func Test_toRealServer(t *testing.T) {
|
2017-07-16 05:35:55 +00:00
|
|
|
Tests := []struct {
|
2018-02-06 16:26:17 +00:00
|
|
|
ipvsDestination libipvs.Destination
|
2017-07-16 05:35:55 +00:00
|
|
|
realServer RealServer
|
|
|
|
}{
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Destination{
|
2017-07-16 05:35:55 +00:00
|
|
|
Port: 54321,
|
|
|
|
ConnectionFlags: 0,
|
|
|
|
Weight: 1,
|
|
|
|
Address: net.ParseIP("1.2.3.4"),
|
|
|
|
},
|
|
|
|
RealServer{
|
|
|
|
Address: net.ParseIP("1.2.3.4"),
|
|
|
|
Port: 54321,
|
|
|
|
Weight: 1,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Destination{
|
2017-07-16 05:35:55 +00:00
|
|
|
Port: 53,
|
|
|
|
ConnectionFlags: 0,
|
|
|
|
Weight: 1,
|
|
|
|
Address: net.ParseIP("2002::cafe"),
|
|
|
|
},
|
|
|
|
RealServer{
|
|
|
|
Address: net.ParseIP("2002::cafe"),
|
|
|
|
Port: 53,
|
|
|
|
Weight: 1,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for i := range Tests {
|
|
|
|
got, err := toRealServer(&Tests[i].ipvsDestination)
|
|
|
|
if err != nil {
|
2018-04-08 08:56:06 +00:00
|
|
|
t.Errorf("case %d unexpected error: %v", i, err)
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(*got, Tests[i].realServer) {
|
|
|
|
t.Errorf("case %d Failed to translate Destination - got %#v, want %#v", i, *got, Tests[i].realServer)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-06 16:26:17 +00:00
|
|
|
func Test_toIPVSDestination(t *testing.T) {
|
2017-07-16 05:35:55 +00:00
|
|
|
Tests := []struct {
|
|
|
|
realServer RealServer
|
2018-02-06 16:26:17 +00:00
|
|
|
ipvsDestination libipvs.Destination
|
2017-07-16 05:35:55 +00:00
|
|
|
}{
|
|
|
|
{
|
|
|
|
RealServer{
|
|
|
|
Address: net.ParseIP("1.2.3.4"),
|
|
|
|
Port: 54321,
|
|
|
|
Weight: 1,
|
|
|
|
},
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Destination{
|
2017-07-16 05:35:55 +00:00
|
|
|
Port: 54321,
|
|
|
|
ConnectionFlags: 0,
|
|
|
|
Weight: 1,
|
|
|
|
Address: net.ParseIP("1.2.3.4"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
RealServer{
|
|
|
|
Address: net.ParseIP("2002::cafe"),
|
|
|
|
Port: 53,
|
|
|
|
Weight: 1,
|
|
|
|
},
|
2018-02-06 16:26:17 +00:00
|
|
|
libipvs.Destination{
|
2017-07-16 05:35:55 +00:00
|
|
|
Port: 53,
|
|
|
|
ConnectionFlags: 0,
|
|
|
|
Weight: 1,
|
|
|
|
Address: net.ParseIP("2002::cafe"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for i := range Tests {
|
2018-02-06 16:26:17 +00:00
|
|
|
got, err := toIPVSDestination(&Tests[i].realServer)
|
2017-07-16 05:35:55 +00:00
|
|
|
if err != nil {
|
2018-04-08 08:56:06 +00:00
|
|
|
t.Errorf("case %d unexpected error: %v", i, err)
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(*got, Tests[i].ipvsDestination) {
|
2018-02-06 16:26:17 +00:00
|
|
|
t.Errorf("case %d failed to translate Destination - got %#v, want %#v", i, *got, Tests[i].ipvsDestination)
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-06 16:26:17 +00:00
|
|
|
func Test_stringToProtocol(t *testing.T) {
|
2017-07-16 05:35:55 +00:00
|
|
|
tests := []string{
|
2018-06-11 11:25:18 +00:00
|
|
|
"TCP", "UDP", "ICMP", "SCTP",
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
2018-02-06 16:26:17 +00:00
|
|
|
expected := []uint16{
|
2018-06-11 11:25:18 +00:00
|
|
|
uint16(syscall.IPPROTO_TCP), uint16(syscall.IPPROTO_UDP), uint16(0), uint16(syscall.IPPROTO_SCTP),
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
|
|
|
for i := range tests {
|
2018-02-06 16:26:17 +00:00
|
|
|
got := stringToProtocol(tests[i])
|
|
|
|
if got != expected[i] {
|
|
|
|
t.Errorf("stringToProtocol() failed - got %#v, want %#v",
|
|
|
|
got, expected[i])
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-06 16:26:17 +00:00
|
|
|
func Test_protocolToString(t *testing.T) {
|
|
|
|
tests := []Protocol{
|
2018-06-11 11:25:18 +00:00
|
|
|
syscall.IPPROTO_TCP, syscall.IPPROTO_UDP, Protocol(0), syscall.IPPROTO_SCTP,
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
2018-02-06 16:26:17 +00:00
|
|
|
expected := []string{
|
2018-06-11 11:25:18 +00:00
|
|
|
"TCP", "UDP", "", "SCTP",
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
|
|
|
for i := range tests {
|
2018-02-06 16:26:17 +00:00
|
|
|
got := protocolToString(tests[i])
|
|
|
|
if got != expected[i] {
|
|
|
|
t.Errorf("protocolToString() failed - got %#v, want %#v",
|
|
|
|
got, expected[i])
|
2017-07-16 05:35:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|