Skip to content

Commit

Permalink
fix(dest): encode tunnel port in network order
Browse files Browse the repository at this point in the history
The tunnel port needs to be encoded in the network byte order, rather
than netlink's standard native byte order.
  • Loading branch information
terinjokes committed Apr 5, 2023
1 parent 32922b5 commit 2146fc9
Show file tree
Hide file tree
Showing 2 changed files with 358 additions and 1 deletion.
1 change: 0 additions & 1 deletion client_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,6 @@ func packDest(dest Destination) func() ([]byte, error) {
ae.Uint32(cipvs.DestAttrLThresh, dest.LowerThreshold)
ae.Uint8(cipvs.DestAttrTunType, uint8(dest.TunnelType))
ae.Do(cipvs.DestAttrTunPort, packPort(dest.TunnelPort))
ae.Uint16(cipvs.DestAttrTunPort, dest.TunnelPort)
ae.Uint16(cipvs.DestAttrTunFlags, uint16(dest.TunnelFlags))

return ae.Encode()
Expand Down
358 changes: 358 additions & 0 deletions client_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,364 @@ func TestServices(t *testing.T) {
}
}

func TestDestinations_Pack(t *testing.T) {
type testCase struct {
name string
destination Destination
expected genetlink.Message
}

run := func(t *testing.T, tc testCase) {
fn := func(gerq genetlink.Message, _ netlink.Message) ([]genetlink.Message, error) {
assert.DeepEqual(t, gerq, tc.expected)
return []genetlink.Message{{}}, nil
}

client := testClient(t, genltest.CheckRequest(familyID, cipvs.CmdNewDest, netlink.Request|netlink.Acknowledge, fn))
defer client.Close()

err := client.CreateDestination(Service{}, tc.destination)
assert.NilError(t, err)
}

testCases := []testCase{
{
name: "direct destination",
destination: Destination{
Address: NewIP(net.ParseIP("127.0.1.1")),
FwdMethod: DirectRoute,
Weight: 1,
Port: 80,
Family: INET,
},
expected: genetlink.Message{
Header: genetlink.Header{
Command: cipvs.CmdNewDest,
Version: 1,
},
Data: nltest.MustMarshalAttributes([]netlink.Attribute{
{
Type: cipvs.CmdAttrService,
Data: nltest.MustMarshalAttributes([]netlink.Attribute{
{
Type: cipvs.SvcAttrAf,
Data: []byte{0x00, 0x00},
},
{
Type: cipvs.SvcAttrSchedName,
Data: []byte{0x00},
},
{
Type: cipvs.SvcAttrFlags,
Data: []byte{0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
},
{
Type: cipvs.SvcAttrTimeout,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.SvcAttrNetmask,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.SvcAttrProtocol,
Data: []byte{0x00, 0x00},
},
{
Type: cipvs.SvcAttrAddr,
Data: []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
{
Type: cipvs.SvcAttrPort,
Data: []byte{
0x00, 0x00,
},
},
}),
},
{
Type: cipvs.CmdAttrDest,
Data: nltest.MustMarshalAttributes([]netlink.Attribute{
{
Type: cipvs.DestAttrAddrFamily,
Data: []byte{0x02, 0x00},
},
{
Type: cipvs.DestAttrAddr,
Data: []byte{
0x7F, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
{
Type: cipvs.DestAttrPort,
Data: []byte{0x00, 0x50},
},
{
Type: cipvs.DestAttrFwdMethod,
Data: []byte{0x03, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrWeight,
Data: []byte{0x01, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrUThresh,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrLThresh,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrTunType,
Data: []byte{0x00},
},
{
Type: cipvs.DestAttrTunPort,
Data: []byte{0x00, 0x00},
},
{
Type: cipvs.DestAttrTunFlags,
Data: []byte{0x00, 0x00},
},
}),
},
}),
},
},
{
name: "direct IPv6 destination",
destination: Destination{
Address: NewIP(net.ParseIP("2004:db8::3")),
FwdMethod: DirectRoute,
Weight: 1,
Port: 80,
Family: INET6,
},
expected: genetlink.Message{
Header: genetlink.Header{
Command: cipvs.CmdNewDest,
Version: 1,
},
Data: nltest.MustMarshalAttributes([]netlink.Attribute{
{
Type: cipvs.CmdAttrService,
Data: nltest.MustMarshalAttributes([]netlink.Attribute{
{
Type: cipvs.SvcAttrAf,
Data: []byte{0x00, 0x00},
},
{
Type: cipvs.SvcAttrSchedName,
Data: []byte{0x00},
},
{
Type: cipvs.SvcAttrFlags,
Data: []byte{0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
},
{
Type: cipvs.SvcAttrTimeout,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.SvcAttrNetmask,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.SvcAttrProtocol,
Data: []byte{0x00, 0x00},
},
{
Type: cipvs.SvcAttrAddr,
Data: []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
{
Type: cipvs.SvcAttrPort,
Data: []byte{
0x00, 0x00,
},
},
}),
},
{
Type: cipvs.CmdAttrDest,
Data: nltest.MustMarshalAttributes([]netlink.Attribute{
{
Type: cipvs.DestAttrAddrFamily,
Data: []byte{0x0A, 0x00},
},
{
Type: cipvs.DestAttrAddr,
Data: []byte{
0x20, 0x04, 0x0D, 0xB8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
},
},
{
Type: cipvs.DestAttrPort,
Data: []byte{0x00, 0x50},
},
{
Type: cipvs.DestAttrFwdMethod,
Data: []byte{0x03, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrWeight,
Data: []byte{0x01, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrUThresh,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrLThresh,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrTunType,
Data: []byte{0x00},
},
{
Type: cipvs.DestAttrTunPort,
Data: []byte{0x00, 0x00},
},
{
Type: cipvs.DestAttrTunFlags,
Data: []byte{0x00, 0x00},
},
}),
},
}),
},
},
{
name: "GUE tunnel destination",
destination: Destination{
Address: NewIP(net.ParseIP("127.0.1.1")),
FwdMethod: Tunnel,
Weight: 1,
Port: 80,
Family: INET,
TunnelType: GUE,
TunnelPort: 5580,
TunnelFlags: TunnelEncapRemoteChecksum,
},
expected: genetlink.Message{
Header: genetlink.Header{
Command: cipvs.CmdNewDest,
Version: 1,
},
Data: nltest.MustMarshalAttributes([]netlink.Attribute{
{
Type: cipvs.CmdAttrService,
Data: nltest.MustMarshalAttributes([]netlink.Attribute{
{
Type: cipvs.SvcAttrAf,
Data: []byte{0x00, 0x00},
},
{
Type: cipvs.SvcAttrSchedName,
Data: []byte{0x00},
},
{
Type: cipvs.SvcAttrFlags,
Data: []byte{0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
},
{
Type: cipvs.SvcAttrTimeout,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.SvcAttrNetmask,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.SvcAttrProtocol,
Data: []byte{0x00, 0x00},
},
{
Type: cipvs.SvcAttrAddr,
Data: []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
{
Type: cipvs.SvcAttrPort,
Data: []byte{
0x00, 0x00,
},
},
}),
},
{
Type: cipvs.CmdAttrDest,
Data: nltest.MustMarshalAttributes([]netlink.Attribute{
{
Type: cipvs.DestAttrAddrFamily,
Data: []byte{0x02, 0x00},
},
{
Type: cipvs.DestAttrAddr,
Data: []byte{
0x7F, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
{
Type: cipvs.DestAttrPort,
Data: []byte{0x00, 0x50},
},
{
Type: cipvs.DestAttrFwdMethod,
Data: []byte{0x02, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrWeight,
Data: []byte{0x01, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrUThresh,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrLThresh,
Data: []byte{0x00, 0x00, 0x00, 0x00},
},
{
Type: cipvs.DestAttrTunType,
Data: []byte{0x01},
},
{
Type: cipvs.DestAttrTunPort,
Data: []byte{0x15, 0xCC},
},
{
Type: cipvs.DestAttrTunFlags,
Data: []byte{0x02, 0x00},
},
}),
},
}),
},
},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
run(t, tc)
})
}
}

func TestDestinations_Unpack(t *testing.T) {
type testCase struct {
name string
Expand Down

0 comments on commit 2146fc9

Please sign in to comment.