228 lines
7.5 KiB
Go
228 lines
7.5 KiB
Go
// Copyright 2020 The gVisor 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 netdevs
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
)
|
|
|
|
func mustParseMAC(s string) net.HardwareAddr {
|
|
mac, err := net.ParseMAC(s)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("failed to parse test MAC %q: %s", s, err))
|
|
}
|
|
return mac
|
|
}
|
|
|
|
func TestParseDevices(t *testing.T) {
|
|
for _, v := range []struct {
|
|
desc string
|
|
cmdOutput string
|
|
want map[string]DeviceInfo
|
|
}{
|
|
{
|
|
desc: "v4 and v6",
|
|
cmdOutput: `
|
|
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
|
|
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
|
inet 127.0.0.1/8 scope host lo
|
|
valid_lft forever preferred_lft forever
|
|
inet6 ::1/128 scope host
|
|
valid_lft forever preferred_lft forever
|
|
2613: eth0@if2614: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
|
link/ether 02:42:c0:a8:09:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
|
inet 192.168.9.2/24 brd 192.168.9.255 scope global eth0
|
|
valid_lft forever preferred_lft forever
|
|
inet6 fe80::42:c0ff:fea8:902/64 scope link tentative
|
|
valid_lft forever preferred_lft forever
|
|
2615: eth2@if2616: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
|
link/ether 02:42:df:f5:e1:0a brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
|
inet 223.245.225.10/24 brd 223.245.225.255 scope global eth2
|
|
valid_lft forever preferred_lft forever
|
|
inet6 fe80::42:dfff:fef5:e10a/64 scope link tentative
|
|
valid_lft forever preferred_lft forever
|
|
2617: eth1@if2618: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
|
link/ether 02:42:da:33:13:0a brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
|
inet 218.51.19.10/24 brd 218.51.19.255 scope global eth1
|
|
valid_lft forever preferred_lft forever
|
|
inet6 fe80::42:daff:fe33:130a/64 scope link tentative
|
|
valid_lft forever preferred_lft forever`,
|
|
want: map[string]DeviceInfo{
|
|
"lo": DeviceInfo{
|
|
ID: 1,
|
|
MAC: mustParseMAC("00:00:00:00:00:00"),
|
|
IPv4Addr: net.IPv4(127, 0, 0, 1),
|
|
IPv4Net: &net.IPNet{
|
|
IP: net.IPv4(127, 0, 0, 0),
|
|
Mask: net.CIDRMask(8, 32),
|
|
},
|
|
IPv6Addr: net.ParseIP("::1"),
|
|
IPv6Net: &net.IPNet{
|
|
IP: net.ParseIP("::1"),
|
|
Mask: net.CIDRMask(128, 128),
|
|
},
|
|
},
|
|
"eth0": DeviceInfo{
|
|
ID: 2613,
|
|
MAC: mustParseMAC("02:42:c0:a8:09:02"),
|
|
IPv4Addr: net.IPv4(192, 168, 9, 2),
|
|
IPv4Net: &net.IPNet{
|
|
IP: net.IPv4(192, 168, 9, 0),
|
|
Mask: net.CIDRMask(24, 32),
|
|
},
|
|
IPv6Addr: net.ParseIP("fe80::42:c0ff:fea8:902"),
|
|
IPv6Net: &net.IPNet{
|
|
IP: net.ParseIP("fe80::"),
|
|
Mask: net.CIDRMask(64, 128),
|
|
},
|
|
},
|
|
"eth1": DeviceInfo{
|
|
ID: 2617,
|
|
MAC: mustParseMAC("02:42:da:33:13:0a"),
|
|
IPv4Addr: net.IPv4(218, 51, 19, 10),
|
|
IPv4Net: &net.IPNet{
|
|
IP: net.IPv4(218, 51, 19, 0),
|
|
Mask: net.CIDRMask(24, 32),
|
|
},
|
|
IPv6Addr: net.ParseIP("fe80::42:daff:fe33:130a"),
|
|
IPv6Net: &net.IPNet{
|
|
IP: net.ParseIP("fe80::"),
|
|
Mask: net.CIDRMask(64, 128),
|
|
},
|
|
},
|
|
"eth2": DeviceInfo{
|
|
ID: 2615,
|
|
MAC: mustParseMAC("02:42:df:f5:e1:0a"),
|
|
IPv4Addr: net.IPv4(223, 245, 225, 10),
|
|
IPv4Net: &net.IPNet{
|
|
IP: net.IPv4(223, 245, 225, 0),
|
|
Mask: net.CIDRMask(24, 32),
|
|
},
|
|
IPv6Addr: net.ParseIP("fe80::42:dfff:fef5:e10a"),
|
|
IPv6Net: &net.IPNet{
|
|
IP: net.ParseIP("fe80::"),
|
|
Mask: net.CIDRMask(64, 128),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "v4 only",
|
|
cmdOutput: `
|
|
2613: eth0@if2614: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
|
link/ether 02:42:c0:a8:09:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
|
inet 192.168.9.2/24 brd 192.168.9.255 scope global eth0
|
|
valid_lft forever preferred_lft forever`,
|
|
want: map[string]DeviceInfo{
|
|
"eth0": DeviceInfo{
|
|
ID: 2613,
|
|
MAC: mustParseMAC("02:42:c0:a8:09:02"),
|
|
IPv4Addr: net.IPv4(192, 168, 9, 2),
|
|
IPv4Net: &net.IPNet{
|
|
IP: net.IPv4(192, 168, 9, 0),
|
|
Mask: net.CIDRMask(24, 32),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
desc: "v6 only",
|
|
cmdOutput: `
|
|
2615: eth2@if2616: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
|
link/ether 02:42:df:f5:e1:0a brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
|
inet6 fe80::42:dfff:fef5:e10a/64 scope link tentative
|
|
valid_lft forever preferred_lft forever`,
|
|
want: map[string]DeviceInfo{
|
|
"eth2": DeviceInfo{
|
|
ID: 2615,
|
|
MAC: mustParseMAC("02:42:df:f5:e1:0a"),
|
|
IPv6Addr: net.ParseIP("fe80::42:dfff:fef5:e10a"),
|
|
IPv6Net: &net.IPNet{
|
|
IP: net.ParseIP("fe80::"),
|
|
Mask: net.CIDRMask(64, 128),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
} {
|
|
t.Run(v.desc, func(t *testing.T) {
|
|
got, err := ParseDevices(v.cmdOutput)
|
|
if err != nil {
|
|
t.Errorf("ParseDevices(\n%s\n) got unexpected error: %s", v.cmdOutput, err)
|
|
}
|
|
if diff := cmp.Diff(v.want, got); diff != "" {
|
|
t.Errorf("ParseDevices(\n%s\n) got output diff (-want, +got):\n%s", v.cmdOutput, diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseDevicesErrors(t *testing.T) {
|
|
for _, v := range []struct {
|
|
desc string
|
|
cmdOutput string
|
|
}{
|
|
{
|
|
desc: "invalid MAC addr",
|
|
cmdOutput: `
|
|
2617: eth1@if2618: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
|
link/ether 02:42:da:33:13:0a:ffffffff brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
|
inet 218.51.19.10/24 brd 218.51.19.255 scope global eth1
|
|
valid_lft forever preferred_lft forever
|
|
inet6 fe80::42:daff:fe33:130a/64 scope link tentative
|
|
valid_lft forever preferred_lft forever`,
|
|
},
|
|
{
|
|
desc: "invalid v4 addr",
|
|
cmdOutput: `
|
|
2617: eth1@if2618: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
|
link/ether 02:42:da:33:13:0a brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
|
inet 1234.4321.424242.0/24 brd 218.51.19.255 scope global eth1
|
|
valid_lft forever preferred_lft forever
|
|
inet6 fe80::42:daff:fe33:130a/64 scope link tentative
|
|
valid_lft forever preferred_lft forever`,
|
|
},
|
|
{
|
|
desc: "invalid v6 addr",
|
|
cmdOutput: `
|
|
2617: eth1@if2618: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
|
link/ether 02:42:da:33:13:0a brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
|
inet 218.51.19.10/24 brd 218.51.19.255 scope global eth1
|
|
valid_lft forever preferred_lft forever
|
|
inet6 fe80:ffffffff::42:daff:fe33:130a/64 scope link tentative
|
|
valid_lft forever preferred_lft forever`,
|
|
},
|
|
{
|
|
desc: "invalid CIDR missing prefixlen",
|
|
cmdOutput: `
|
|
2617: eth1@if2618: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
|
link/ether 02:42:da:33:13:0a brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
|
inet 218.51.19.10 brd 218.51.19.255 scope global eth1
|
|
valid_lft forever preferred_lft forever
|
|
inet6 fe80::42:daff:fe33:130a scope link tentative
|
|
valid_lft forever preferred_lft forever`,
|
|
},
|
|
} {
|
|
t.Run(v.desc, func(t *testing.T) {
|
|
if _, err := ParseDevices(v.cmdOutput); err == nil {
|
|
t.Errorf("ParseDevices(\n%s\n) succeeded unexpectedly, want error", v.cmdOutput)
|
|
}
|
|
})
|
|
}
|
|
}
|