Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 120 additions & 112 deletions ipvs/ipvs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,49 +133,67 @@ func TestService(t *testing.T) {

for _, protocol := range protocols {
for _, schedMethod := range schedMethods {

s := Service{
AddressFamily: nl.FAMILY_V4,
SchedName: schedMethod,
}

switch protocol {
case "FWM":
s.FWMark = 1234
case "TCP":
s.Protocol = unix.IPPROTO_TCP
s.Port = 80
s.Address = net.ParseIP("1.2.3.4")
s.Netmask = 0xFFFFFFFF
case "UDP":
s.Protocol = unix.IPPROTO_UDP
s.Port = 53
s.Address = net.ParseIP("2.3.4.5")
testDatas := []struct {
AddressFamily uint16
IP string
Netmask uint32
}{
{
AddressFamily: nl.FAMILY_V4,
IP: "1.2.3.4",
Netmask: 0xFFFFFFFF,
}, {
AddressFamily: nl.FAMILY_V6,
IP: "2001:db8:3c4d:15::1a00",
Netmask: 128,
},
}
for _, td := range testDatas {
s := Service{
AddressFamily: td.AddressFamily,
SchedName: schedMethod,
}

err := i.NewService(&s)
assert.NilError(t, err)
checkService(t, i, &s, true)
for _, updateSchedMethod := range schedMethods {
if updateSchedMethod == schedMethod {
continue
switch protocol {
case "FWM":
s.FWMark = 1234
s.Netmask = td.Netmask
case "TCP":
s.Protocol = unix.IPPROTO_TCP
s.Port = 80
s.Address = net.ParseIP(td.IP)
s.Netmask = td.Netmask
case "UDP":
s.Protocol = unix.IPPROTO_UDP
s.Port = 53
s.Address = net.ParseIP(td.IP)
s.Netmask = td.Netmask
}

s.SchedName = updateSchedMethod
err = i.UpdateService(&s)
err := i.NewService(&s)
assert.NilError(t, err)
checkService(t, i, &s, true)
for _, updateSchedMethod := range schedMethods {
if updateSchedMethod == schedMethod {
continue
}

s.SchedName = updateSchedMethod
err = i.UpdateService(&s)
assert.NilError(t, err)
checkService(t, i, &s, true)

scopy, err := i.GetService(&s)
assert.NilError(t, err)
assert.Check(t, is.Equal((*scopy).Address.String(), s.Address.String()))
assert.Check(t, is.Equal((*scopy).Port, s.Port))
assert.Check(t, is.Equal((*scopy).Protocol, s.Protocol))
}

scopy, err := i.GetService(&s)
err = i.DelService(&s)
assert.NilError(t, err)
assert.Check(t, is.Equal((*scopy).Address.String(), s.Address.String()))
assert.Check(t, is.Equal((*scopy).Port, s.Port))
assert.Check(t, is.Equal((*scopy).Protocol, s.Protocol))
checkService(t, i, &s, false)
}

err = i.DelService(&s)
assert.NilError(t, err)
checkService(t, i, &s, false)
}
}

Expand Down Expand Up @@ -251,95 +269,85 @@ func TestDestination(t *testing.T) {
assert.NilError(t, err)

for _, protocol := range protocols {

s := Service{
AddressFamily: nl.FAMILY_V4,
SchedName: RoundRobin,
}

switch protocol {
case "FWM":
s.FWMark = 1234
case "TCP":
s.Protocol = unix.IPPROTO_TCP
s.Port = 80
s.Address = net.ParseIP("1.2.3.4")
s.Netmask = 0xFFFFFFFF
case "UDP":
s.Protocol = unix.IPPROTO_UDP
s.Port = 53
s.Address = net.ParseIP("2.3.4.5")
testDatas := []struct {
AddressFamily uint16
IP string
Netmask uint32
Destinations []string
}{
{
AddressFamily: nl.FAMILY_V4,
IP: "1.2.3.4",
Netmask: 0xFFFFFFFF,
Destinations: []string{"10.1.1.2", "10.1.1.3", "10.1.1.4"},
}, {
AddressFamily: nl.FAMILY_V6,
IP: "2001:db8:3c4d:15::1a00",
Netmask: 128,
Destinations: []string{"2001:db8:3c4d:15::1a2b", "2001:db8:3c4d:15::1a2c", "2001:db8:3c4d:15::1a2d"},
},
}

err := i.NewService(&s)
assert.NilError(t, err)
checkService(t, i, &s, true)

s.SchedName = ""
for _, fwdMethod := range fwdMethods {
d1 := Destination{
AddressFamily: nl.FAMILY_V4,
Address: net.ParseIP("10.1.1.2"),
Port: 5000,
Weight: 1,
ConnectionFlags: fwdMethod,
}

err := i.NewDestination(&s, &d1)
assert.NilError(t, err)
checkDestination(t, i, &s, &d1, true)
d2 := Destination{
AddressFamily: nl.FAMILY_V4,
Address: net.ParseIP("10.1.1.3"),
Port: 5000,
Weight: 1,
ConnectionFlags: fwdMethod,
for _, td := range testDatas {
s := Service{
AddressFamily: td.AddressFamily,
SchedName: RoundRobin,
}

err = i.NewDestination(&s, &d2)
assert.NilError(t, err)
checkDestination(t, i, &s, &d2, true)

d3 := Destination{
AddressFamily: nl.FAMILY_V4,
Address: net.ParseIP("10.1.1.4"),
Port: 5000,
Weight: 1,
ConnectionFlags: fwdMethod,
switch protocol {
case "FWM":
s.FWMark = 1234
s.Netmask = td.Netmask
case "TCP":
s.Protocol = unix.IPPROTO_TCP
s.Port = 80
s.Address = net.ParseIP(td.IP)
s.Netmask = td.Netmask
case "UDP":
s.Protocol = unix.IPPROTO_UDP
s.Port = 53
s.Address = net.ParseIP(td.IP)
s.Netmask = td.Netmask
}

err = i.NewDestination(&s, &d3)
err := i.NewService(&s)
assert.NilError(t, err)
checkDestination(t, i, &s, &d3, true)
checkService(t, i, &s, true)

for _, updateFwdMethod := range fwdMethods {
if updateFwdMethod == fwdMethod {
continue
s.SchedName = ""
for _, fwdMethod := range fwdMethods {
destinations := make([]Destination, 0)
for _, ip := range td.Destinations {
d := Destination{
AddressFamily: td.AddressFamily,
Address: net.ParseIP(ip),
Port: 5000,
Weight: 1,
ConnectionFlags: fwdMethod,
}
destinations = append(destinations, d)
err := i.NewDestination(&s, &d)
assert.NilError(t, err)
checkDestination(t, i, &s, &d, true)
}
d1.ConnectionFlags = updateFwdMethod
err = i.UpdateDestination(&s, &d1)
assert.NilError(t, err)
checkDestination(t, i, &s, &d1, true)

d2.ConnectionFlags = updateFwdMethod
err = i.UpdateDestination(&s, &d2)
assert.NilError(t, err)
checkDestination(t, i, &s, &d2, true)

d3.ConnectionFlags = updateFwdMethod
err = i.UpdateDestination(&s, &d3)
assert.NilError(t, err)
checkDestination(t, i, &s, &d3, true)
for _, updateFwdMethod := range fwdMethods {
if updateFwdMethod == fwdMethod {
continue
}
for _, d := range destinations {
d.ConnectionFlags = updateFwdMethod
err = i.UpdateDestination(&s, &d)
assert.NilError(t, err)
checkDestination(t, i, &s, &d, true)
}
}
for _, d := range destinations {
err = i.DelDestination(&s, &d)
assert.NilError(t, err)
checkDestination(t, i, &s, &d, false)
}
}

err = i.DelDestination(&s, &d1)
assert.NilError(t, err)
err = i.DelDestination(&s, &d2)
assert.NilError(t, err)
err = i.DelDestination(&s, &d3)
assert.NilError(t, err)
checkDestination(t, i, &s, &d3, false)

}
}
}
Expand Down
34 changes: 24 additions & 10 deletions ipvs/netlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ func assembleStats(msg []byte) (SvcStats, error) {
func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {

var s Service
var addressBytes []byte

for _, attr := range attrs {

Expand All @@ -327,11 +328,7 @@ func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {
case ipvsSvcAttrProtocol:
s.Protocol = native.Uint16(attr.Value)
case ipvsSvcAttrAddress:
ip, err := parseIP(attr.Value, s.AddressFamily)
if err != nil {
return nil, err
}
s.Address = ip
addressBytes = attr.Value
case ipvsSvcAttrPort:
s.Port = binary.BigEndian.Uint16(attr.Value)
case ipvsSvcAttrFWMark:
Expand All @@ -353,6 +350,16 @@ func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {
}

}

// parse Address after parse AddressFamily incase of parseIP error
if addressBytes != nil {
ip, err := parseIP(addressBytes, s.AddressFamily)
if err != nil {
return nil, err
}
s.Address = ip
}

return &s, nil
}

Expand Down Expand Up @@ -416,6 +423,7 @@ func (i *Handle) doCmdWithoutAttr(cmd uint8) ([][]byte, error) {
func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error) {

var d Destination
var addressBytes []byte

for _, attr := range attrs {

Expand All @@ -426,11 +434,7 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error)
case ipvsDestAttrAddressFamily:
d.AddressFamily = native.Uint16(attr.Value)
case ipvsDestAttrAddress:
ip, err := parseIP(attr.Value, d.AddressFamily)
if err != nil {
return nil, err
}
d.Address = ip
addressBytes = attr.Value
case ipvsDestAttrPort:
d.Port = binary.BigEndian.Uint16(attr.Value)
case ipvsDestAttrForwardingMethod:
Expand All @@ -453,6 +457,16 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error)
d.Stats = DstStats(stats)
}
}

// parse Address after parse AddressFamily incase of parseIP error
if addressBytes != nil {
ip, err := parseIP(addressBytes, d.AddressFamily)
if err != nil {
return nil, err
}
d.Address = ip
}

return &d, nil
}

Expand Down