diff options
Diffstat (limited to 'test/packetimpact/netdevs')
-rw-r--r-- | test/packetimpact/netdevs/BUILD | 23 | ||||
-rw-r--r-- | test/packetimpact/netdevs/netdevs.go | 122 | ||||
-rw-r--r-- | test/packetimpact/netdevs/netdevs_test.go | 227 |
3 files changed, 0 insertions, 372 deletions
diff --git a/test/packetimpact/netdevs/BUILD b/test/packetimpact/netdevs/BUILD deleted file mode 100644 index 8d1193fed..000000000 --- a/test/packetimpact/netdevs/BUILD +++ /dev/null @@ -1,23 +0,0 @@ -load("//tools:defs.bzl", "go_library", "go_test") - -package( - licenses = ["notice"], -) - -go_library( - name = "netdevs", - srcs = ["netdevs.go"], - visibility = ["//test/packetimpact:__subpackages__"], - deps = [ - "//pkg/tcpip", - "//pkg/tcpip/header", - ], -) - -go_test( - name = "netdevs_test", - size = "small", - srcs = ["netdevs_test.go"], - library = ":netdevs", - deps = ["@com_github_google_go_cmp//cmp:go_default_library"], -) diff --git a/test/packetimpact/netdevs/netdevs.go b/test/packetimpact/netdevs/netdevs.go deleted file mode 100644 index 25dcfbf60..000000000 --- a/test/packetimpact/netdevs/netdevs.go +++ /dev/null @@ -1,122 +0,0 @@ -// 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 contains utilities for working with network devices. -package netdevs - -import ( - "fmt" - "net" - "regexp" - "strconv" - "strings" - - "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/header" -) - -// A DeviceInfo represents a network device. -type DeviceInfo struct { - ID uint32 - MAC net.HardwareAddr - IPv4Addr net.IP - IPv4Net *net.IPNet - IPv6Addr net.IP - IPv6Net *net.IPNet -} - -var ( - deviceLine = regexp.MustCompile(`^\s*(\d+): (\w+)`) - linkLine = regexp.MustCompile(`^\s*link/\w+ ([0-9a-fA-F:]+)`) - inetLine = regexp.MustCompile(`^\s*inet ([0-9./]+)`) - inet6Line = regexp.MustCompile(`^\s*inet6 ([0-9a-fA-F:/]+)`) -) - -// ParseDevicesWithRegex will parse the output with the given regexps to produce -// a map from device name to device information. It is assumed that deviceLine -// contains both a name and an ID. -func ParseDevicesWithRegex(cmdOutput string, deviceLine, linkLine, inetLine, inet6Line *regexp.Regexp) (map[string]DeviceInfo, error) { - var currentDevice string - var currentInfo DeviceInfo - deviceInfos := make(map[string]DeviceInfo) - for _, line := range strings.Split(cmdOutput, "\n") { - if m := deviceLine.FindStringSubmatch(line); m != nil { - if currentDevice != "" { - deviceInfos[currentDevice] = currentInfo - } - id, err := strconv.ParseUint(m[1], 10, 32) - if err != nil { - return nil, fmt.Errorf("parsing device ID %s: %w", m[1], err) - } - currentInfo = DeviceInfo{ID: uint32(id)} - currentDevice = m[2] - } else if m := linkLine.FindStringSubmatch(line); m != nil { - mac, err := net.ParseMAC(m[1]) - if err != nil { - return nil, err - } - currentInfo.MAC = mac - } else if m := inetLine.FindStringSubmatch(line); m != nil { - ipv4Addr, ipv4Net, err := net.ParseCIDR(m[1]) - if err != nil { - return nil, err - } - currentInfo.IPv4Addr = ipv4Addr - currentInfo.IPv4Net = ipv4Net - } else if m := inet6Line.FindStringSubmatch(line); m != nil { - ipv6Addr, ipv6Net, err := net.ParseCIDR(m[1]) - if err != nil { - return nil, err - } - currentInfo.IPv6Addr = ipv6Addr - currentInfo.IPv6Net = ipv6Net - } - } - if currentDevice != "" { - deviceInfos[currentDevice] = currentInfo - } - return deviceInfos, nil -} - -// ParseDevices parses the output from `ip addr show` into a map from device -// name to information about the device. -// -// Note: if multiple IPv6 addresses are assigned to a device, the last address -// displayed by `ip addr show` will be used. This is fine for packetimpact -// because we will always only have at most one IPv6 address assigned to each -// device. -func ParseDevices(cmdOutput string) (map[string]DeviceInfo, error) { - return ParseDevicesWithRegex(cmdOutput, deviceLine, linkLine, inetLine, inet6Line) -} - -// MACToIP converts the MAC address to an IPv6 link local address as described -// in RFC 4291 page 20: https://tools.ietf.org/html/rfc4291#page-20 -func MACToIP(mac net.HardwareAddr) net.IP { - addr := make([]byte, header.IPv6AddressSize) - addr[0] = 0xfe - addr[1] = 0x80 - header.EthernetAdddressToModifiedEUI64IntoBuf(tcpip.LinkAddress(mac), addr[8:]) - return net.IP(addr) -} - -// FindDeviceByIP finds a DeviceInfo and device name from an IP address in the -// output of ParseDevices. -func FindDeviceByIP(ip net.IP, devices map[string]DeviceInfo) (string, DeviceInfo, error) { - for dev, info := range devices { - if info.IPv4Addr.Equal(ip) { - return dev, info, nil - } - } - return "", DeviceInfo{}, fmt.Errorf("can't find %s on any interface", ip) -} diff --git a/test/packetimpact/netdevs/netdevs_test.go b/test/packetimpact/netdevs/netdevs_test.go deleted file mode 100644 index 379386980..000000000 --- a/test/packetimpact/netdevs/netdevs_test.go +++ /dev/null @@ -1,227 +0,0 @@ -// 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": { - 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": { - 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": { - 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": { - 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": { - 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": { - 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) - } - }) - } -} |