diff options
Diffstat (limited to 'pkg/tcpip/network/arp')
-rw-r--r-- | pkg/tcpip/network/arp/BUILD | 53 | ||||
-rw-r--r-- | pkg/tcpip/network/arp/arp_state_autogen.go | 3 | ||||
-rw-r--r-- | pkg/tcpip/network/arp/arp_test.go | 688 | ||||
-rw-r--r-- | pkg/tcpip/network/arp/stats_test.go | 51 |
4 files changed, 3 insertions, 792 deletions
diff --git a/pkg/tcpip/network/arp/BUILD b/pkg/tcpip/network/arp/BUILD deleted file mode 100644 index 6fa1aee18..000000000 --- a/pkg/tcpip/network/arp/BUILD +++ /dev/null @@ -1,53 +0,0 @@ -load("//tools:defs.bzl", "go_library", "go_test") - -package(licenses = ["notice"]) - -go_library( - name = "arp", - srcs = [ - "arp.go", - "stats.go", - ], - visibility = ["//visibility:public"], - deps = [ - "//pkg/sync", - "//pkg/tcpip", - "//pkg/tcpip/buffer", - "//pkg/tcpip/header", - "//pkg/tcpip/header/parse", - "//pkg/tcpip/network/internal/ip", - "//pkg/tcpip/stack", - ], -) - -go_test( - name = "arp_test", - size = "small", - srcs = ["arp_test.go"], - deps = [ - ":arp", - "//pkg/tcpip", - "//pkg/tcpip/buffer", - "//pkg/tcpip/faketime", - "//pkg/tcpip/header", - "//pkg/tcpip/link/channel", - "//pkg/tcpip/link/sniffer", - "//pkg/tcpip/network/ipv4", - "//pkg/tcpip/stack", - "//pkg/tcpip/testutil", - "@com_github_google_go_cmp//cmp:go_default_library", - "@com_github_google_go_cmp//cmp/cmpopts:go_default_library", - ], -) - -go_test( - name = "stats_test", - size = "small", - srcs = ["stats_test.go"], - library = ":arp", - deps = [ - "//pkg/tcpip", - "//pkg/tcpip/stack", - "//pkg/tcpip/testutil", - ], -) diff --git a/pkg/tcpip/network/arp/arp_state_autogen.go b/pkg/tcpip/network/arp/arp_state_autogen.go new file mode 100644 index 000000000..5cd8535e3 --- /dev/null +++ b/pkg/tcpip/network/arp/arp_state_autogen.go @@ -0,0 +1,3 @@ +// automatically generated by stateify. + +package arp diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go deleted file mode 100644 index 061cc35ae..000000000 --- a/pkg/tcpip/network/arp/arp_test.go +++ /dev/null @@ -1,688 +0,0 @@ -// Copyright 2018 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 arp_test - -import ( - "fmt" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" - "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/buffer" - "gvisor.dev/gvisor/pkg/tcpip/faketime" - "gvisor.dev/gvisor/pkg/tcpip/header" - "gvisor.dev/gvisor/pkg/tcpip/link/channel" - "gvisor.dev/gvisor/pkg/tcpip/link/sniffer" - "gvisor.dev/gvisor/pkg/tcpip/network/arp" - "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" - "gvisor.dev/gvisor/pkg/tcpip/stack" - "gvisor.dev/gvisor/pkg/tcpip/testutil" -) - -const ( - nicID = 1 - - stackLinkAddr = tcpip.LinkAddress("\x0a\x0a\x0b\x0b\x0c\x0c") - remoteLinkAddr = tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06") -) - -var ( - stackAddr = testutil.MustParse4("10.0.0.1") - remoteAddr = testutil.MustParse4("10.0.0.2") - unknownAddr = testutil.MustParse4("10.0.0.3") -) - -type eventType uint8 - -const ( - entryAdded eventType = iota - entryChanged - entryRemoved -) - -func (t eventType) String() string { - switch t { - case entryAdded: - return "add" - case entryChanged: - return "change" - case entryRemoved: - return "remove" - default: - return fmt.Sprintf("unknown (%d)", t) - } -} - -type eventInfo struct { - eventType eventType - nicID tcpip.NICID - entry stack.NeighborEntry -} - -func (e eventInfo) String() string { - return fmt.Sprintf("%s event for NIC #%d, %#v", e.eventType, e.nicID, e.entry) -} - -// arpDispatcher implements NUDDispatcher to validate the dispatching of -// events upon certain NUD state machine events. -type arpDispatcher struct { - // C is where events are queued - C chan eventInfo -} - -var _ stack.NUDDispatcher = (*arpDispatcher)(nil) - -func (d *arpDispatcher) OnNeighborAdded(nicID tcpip.NICID, entry stack.NeighborEntry) { - e := eventInfo{ - eventType: entryAdded, - nicID: nicID, - entry: entry, - } - d.C <- e -} - -func (d *arpDispatcher) OnNeighborChanged(nicID tcpip.NICID, entry stack.NeighborEntry) { - e := eventInfo{ - eventType: entryChanged, - nicID: nicID, - entry: entry, - } - d.C <- e -} - -func (d *arpDispatcher) OnNeighborRemoved(nicID tcpip.NICID, entry stack.NeighborEntry) { - e := eventInfo{ - eventType: entryRemoved, - nicID: nicID, - entry: entry, - } - d.C <- e -} - -func (d *arpDispatcher) nextEvent() (eventInfo, bool) { - select { - case event := <-d.C: - return event, true - default: - return eventInfo{}, false - } -} - -type testContext struct { - s *stack.Stack - linkEP *channel.Endpoint - nudDisp arpDispatcher -} - -func makeTestContext(t *testing.T, eventDepth int, packetDepth int) testContext { - t.Helper() - - tc := testContext{ - nudDisp: arpDispatcher{ - C: make(chan eventInfo, eventDepth), - }, - } - - tc.s = stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol}, - NUDDisp: &tc.nudDisp, - Clock: &faketime.NullClock{}, - }) - - tc.linkEP = channel.New(packetDepth, header.IPv4MinimumMTU, stackLinkAddr) - tc.linkEP.LinkEPCapabilities |= stack.CapabilityResolutionRequired - - wep := stack.LinkEndpoint(tc.linkEP) - if testing.Verbose() { - wep = sniffer.New(wep) - } - if err := tc.s.CreateNIC(nicID, wep); err != nil { - t.Fatalf("CreateNIC failed: %s", err) - } - - protocolAddr := tcpip.ProtocolAddress{ - Protocol: ipv4.ProtocolNumber, - AddressWithPrefix: stackAddr.WithPrefix(), - } - if err := tc.s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil { - t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err) - } - - tc.s.SetRouteTable([]tcpip.Route{{ - Destination: header.IPv4EmptySubnet, - NIC: nicID, - }}) - - return tc -} - -func (c *testContext) cleanup() { - c.linkEP.Close() -} - -func TestMalformedPacket(t *testing.T) { - c := makeTestContext(t, 0, 0) - defer c.cleanup() - - v := make(buffer.View, header.ARPSize) - pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: v.ToVectorisedView(), - }) - - c.linkEP.InjectInbound(arp.ProtocolNumber, pkt) - - if got := c.s.Stats().ARP.PacketsReceived.Value(); got != 1 { - t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got) - } - if got := c.s.Stats().ARP.MalformedPacketsReceived.Value(); got != 1 { - t.Errorf("got c.s.Stats().ARP.MalformedPacketsReceived.Value() = %d, want = 1", got) - } -} - -func TestDisabledEndpoint(t *testing.T) { - c := makeTestContext(t, 0, 0) - defer c.cleanup() - - ep, err := c.s.GetNetworkEndpoint(nicID, header.ARPProtocolNumber) - if err != nil { - t.Fatalf("GetNetworkEndpoint(%d, header.ARPProtocolNumber) failed: %s", nicID, err) - } - ep.Disable() - - v := make(buffer.View, header.ARPSize) - pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: v.ToVectorisedView(), - }) - - c.linkEP.InjectInbound(arp.ProtocolNumber, pkt) - - if got := c.s.Stats().ARP.PacketsReceived.Value(); got != 1 { - t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got) - } - if got := c.s.Stats().ARP.DisabledPacketsReceived.Value(); got != 1 { - t.Errorf("got c.s.Stats().ARP.DisabledPacketsReceived.Value() = %d, want = 1", got) - } -} - -func TestDirectReply(t *testing.T) { - c := makeTestContext(t, 0, 0) - defer c.cleanup() - - const senderMAC = "\x01\x02\x03\x04\x05\x06" - const senderIPv4 = "\x0a\x00\x00\x02" - - v := make(buffer.View, header.ARPSize) - h := header.ARP(v) - h.SetIPv4OverEthernet() - h.SetOp(header.ARPReply) - - copy(h.HardwareAddressSender(), senderMAC) - copy(h.ProtocolAddressSender(), senderIPv4) - copy(h.HardwareAddressTarget(), stackLinkAddr) - copy(h.ProtocolAddressTarget(), stackAddr) - - pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: v.ToVectorisedView(), - }) - - c.linkEP.InjectInbound(arp.ProtocolNumber, pkt) - - if got := c.s.Stats().ARP.PacketsReceived.Value(); got != 1 { - t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got) - } - if got := c.s.Stats().ARP.RepliesReceived.Value(); got != 1 { - t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got) - } -} - -func TestDirectRequest(t *testing.T) { - c := makeTestContext(t, 1, 1) - defer c.cleanup() - - tests := []struct { - name string - senderAddr tcpip.Address - senderLinkAddr tcpip.LinkAddress - targetAddr tcpip.Address - isValid bool - }{ - { - name: "Loopback", - senderAddr: stackAddr, - senderLinkAddr: stackLinkAddr, - targetAddr: stackAddr, - isValid: true, - }, - { - name: "Remote", - senderAddr: remoteAddr, - senderLinkAddr: remoteLinkAddr, - targetAddr: stackAddr, - isValid: true, - }, - { - name: "RemoteInvalidTarget", - senderAddr: remoteAddr, - senderLinkAddr: remoteLinkAddr, - targetAddr: unknownAddr, - isValid: false, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - packetsRecv := c.s.Stats().ARP.PacketsReceived.Value() - requestsRecv := c.s.Stats().ARP.RequestsReceived.Value() - requestsRecvUnknownAddr := c.s.Stats().ARP.RequestsReceivedUnknownTargetAddress.Value() - outgoingReplies := c.s.Stats().ARP.OutgoingRepliesSent.Value() - - // Inject an incoming ARP request. - v := make(buffer.View, header.ARPSize) - h := header.ARP(v) - h.SetIPv4OverEthernet() - h.SetOp(header.ARPRequest) - copy(h.HardwareAddressSender(), test.senderLinkAddr) - copy(h.ProtocolAddressSender(), test.senderAddr) - copy(h.ProtocolAddressTarget(), test.targetAddr) - c.linkEP.InjectInbound(arp.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: v.ToVectorisedView(), - })) - - if got, want := c.s.Stats().ARP.PacketsReceived.Value(), packetsRecv+1; got != want { - t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = %d", got, want) - } - if got, want := c.s.Stats().ARP.RequestsReceived.Value(), requestsRecv+1; got != want { - t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = %d", got, want) - } - - if !test.isValid { - // No packets should be sent after receiving an invalid ARP request. - // There is no need to perform a blocking read here, since packets are - // sent in the same function that handles ARP requests. - if pkt, ok := c.linkEP.Read(); ok { - t.Errorf("unexpected packet sent with network protocol number %d", pkt.Proto) - } - if got, want := c.s.Stats().ARP.RequestsReceivedUnknownTargetAddress.Value(), requestsRecvUnknownAddr+1; got != want { - t.Errorf("got c.s.Stats().ARP.RequestsReceivedUnknownTargetAddress.Value() = %d, want = %d", got, want) - } - if got, want := c.s.Stats().ARP.OutgoingRepliesSent.Value(), outgoingReplies; got != want { - t.Errorf("got c.s.Stats().ARP.OutgoingRepliesSent.Value() = %d, want = %d", got, want) - } - - return - } - - if got, want := c.s.Stats().ARP.OutgoingRepliesSent.Value(), outgoingReplies+1; got != want { - t.Errorf("got c.s.Stats().ARP.OutgoingRepliesSent.Value() = %d, want = %d", got, want) - } - - // Verify an ARP response was sent. - pi, ok := c.linkEP.Read() - if !ok { - t.Fatal("expected ARP response to be sent, got none") - } - - if pi.Proto != arp.ProtocolNumber { - t.Fatalf("expected ARP response, got network protocol number %d", pi.Proto) - } - rep := header.ARP(pi.Pkt.NetworkHeader().View()) - if !rep.IsValid() { - t.Fatalf("invalid ARP response: len = %d; response = %x", len(rep), rep) - } - if got, want := tcpip.LinkAddress(rep.HardwareAddressSender()), stackLinkAddr; got != want { - t.Errorf("got HardwareAddressSender() = %s, want = %s", got, want) - } - if got, want := tcpip.Address(rep.ProtocolAddressSender()), tcpip.Address(h.ProtocolAddressTarget()); got != want { - t.Errorf("got ProtocolAddressSender() = %s, want = %s", got, want) - } - if got, want := tcpip.LinkAddress(rep.HardwareAddressTarget()), tcpip.LinkAddress(h.HardwareAddressSender()); got != want { - t.Errorf("got HardwareAddressTarget() = %s, want = %s", got, want) - } - if got, want := tcpip.Address(rep.ProtocolAddressTarget()), tcpip.Address(h.ProtocolAddressSender()); got != want { - t.Errorf("got ProtocolAddressTarget() = %s, want = %s", got, want) - } - - // Verify the sender was saved in the neighbor cache. - if got, ok := c.nudDisp.nextEvent(); ok { - want := eventInfo{ - eventType: entryAdded, - nicID: nicID, - entry: stack.NeighborEntry{ - Addr: test.senderAddr, - LinkAddr: test.senderLinkAddr, - State: stack.Stale, - }, - } - if diff := cmp.Diff(want, got, cmp.AllowUnexported(eventInfo{}), cmpopts.IgnoreFields(stack.NeighborEntry{}, "UpdatedAt")); diff != "" { - t.Errorf("got invalid event (-want +got):\n%s", diff) - } - } else { - t.Fatal("event didn't arrive") - } - - neighbors, err := c.s.Neighbors(nicID, ipv4.ProtocolNumber) - if err != nil { - t.Fatalf("c.s.Neighbors(%d, %d): %s", nicID, ipv4.ProtocolNumber, err) - } - - neighborByAddr := make(map[tcpip.Address]stack.NeighborEntry) - for _, n := range neighbors { - if existing, ok := neighborByAddr[n.Addr]; ok { - if diff := cmp.Diff(existing, n); diff != "" { - t.Fatalf("duplicate neighbor entry found (-existing +got):\n%s", diff) - } - t.Fatalf("exact neighbor entry duplicate found for addr=%s", n.Addr) - } - neighborByAddr[n.Addr] = n - } - - neigh, ok := neighborByAddr[test.senderAddr] - if !ok { - t.Fatalf("expected neighbor entry with Addr = %s", test.senderAddr) - } - if got, want := neigh.LinkAddr, test.senderLinkAddr; got != want { - t.Errorf("got neighbor LinkAddr = %s, want = %s", got, want) - } - if got, want := neigh.State, stack.Stale; got != want { - t.Errorf("got neighbor State = %s, want = %s", got, want) - } - - // No more events should be dispatched - for { - event, ok := c.nudDisp.nextEvent() - if !ok { - break - } - t.Errorf("unexpected %s", event) - } - }) - } -} - -var _ stack.LinkEndpoint = (*testLinkEndpoint)(nil) - -type testLinkEndpoint struct { - stack.LinkEndpoint - - writeErr tcpip.Error -} - -func (t *testLinkEndpoint) WritePacket(r stack.RouteInfo, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) tcpip.Error { - if t.writeErr != nil { - return t.writeErr - } - - return t.LinkEndpoint.WritePacket(r, protocol, pkt) -} - -func TestLinkAddressRequest(t *testing.T) { - const nicID = 1 - - testAddr := tcpip.Address([]byte{1, 2, 3, 4}) - - tests := []struct { - name string - nicAddr tcpip.Address - localAddr tcpip.Address - remoteLinkAddr tcpip.LinkAddress - linkErr tcpip.Error - expectedErr tcpip.Error - expectedLocalAddr tcpip.Address - expectedRemoteLinkAddr tcpip.LinkAddress - expectedRequestsSent uint64 - expectedRequestBadLocalAddressErrors uint64 - expectedRequestInterfaceHasNoLocalAddressErrors uint64 - expectedRequestDroppedErrors uint64 - }{ - { - name: "Unicast", - nicAddr: stackAddr, - localAddr: stackAddr, - remoteLinkAddr: remoteLinkAddr, - expectedLocalAddr: stackAddr, - expectedRemoteLinkAddr: remoteLinkAddr, - expectedRequestsSent: 1, - expectedRequestBadLocalAddressErrors: 0, - expectedRequestInterfaceHasNoLocalAddressErrors: 0, - expectedRequestDroppedErrors: 0, - }, - { - name: "Multicast", - nicAddr: stackAddr, - localAddr: stackAddr, - remoteLinkAddr: "", - expectedLocalAddr: stackAddr, - expectedRemoteLinkAddr: header.EthernetBroadcastAddress, - expectedRequestsSent: 1, - expectedRequestBadLocalAddressErrors: 0, - expectedRequestInterfaceHasNoLocalAddressErrors: 0, - expectedRequestDroppedErrors: 0, - }, - { - name: "Unicast with unspecified source", - nicAddr: stackAddr, - localAddr: "", - remoteLinkAddr: remoteLinkAddr, - expectedLocalAddr: stackAddr, - expectedRemoteLinkAddr: remoteLinkAddr, - expectedRequestsSent: 1, - expectedRequestBadLocalAddressErrors: 0, - expectedRequestInterfaceHasNoLocalAddressErrors: 0, - expectedRequestDroppedErrors: 0, - }, - { - name: "Multicast with unspecified source", - nicAddr: stackAddr, - localAddr: "", - remoteLinkAddr: "", - expectedLocalAddr: stackAddr, - expectedRemoteLinkAddr: header.EthernetBroadcastAddress, - expectedRequestsSent: 1, - expectedRequestBadLocalAddressErrors: 0, - expectedRequestInterfaceHasNoLocalAddressErrors: 0, - expectedRequestDroppedErrors: 0, - }, - { - name: "Unicast with unassigned address", - nicAddr: stackAddr, - localAddr: testAddr, - remoteLinkAddr: remoteLinkAddr, - expectedErr: &tcpip.ErrBadLocalAddress{}, - expectedRequestsSent: 0, - expectedRequestBadLocalAddressErrors: 1, - expectedRequestInterfaceHasNoLocalAddressErrors: 0, - expectedRequestDroppedErrors: 0, - }, - { - name: "Multicast with unassigned address", - nicAddr: stackAddr, - localAddr: testAddr, - remoteLinkAddr: "", - expectedErr: &tcpip.ErrBadLocalAddress{}, - expectedRequestsSent: 0, - expectedRequestBadLocalAddressErrors: 1, - expectedRequestInterfaceHasNoLocalAddressErrors: 0, - expectedRequestDroppedErrors: 0, - }, - { - name: "Unicast with no local address available", - nicAddr: "", - localAddr: "", - remoteLinkAddr: remoteLinkAddr, - expectedErr: &tcpip.ErrNetworkUnreachable{}, - expectedRequestsSent: 0, - expectedRequestBadLocalAddressErrors: 0, - expectedRequestInterfaceHasNoLocalAddressErrors: 1, - expectedRequestDroppedErrors: 0, - }, - { - name: "Multicast with no local address available", - nicAddr: "", - localAddr: "", - remoteLinkAddr: "", - expectedErr: &tcpip.ErrNetworkUnreachable{}, - expectedRequestsSent: 0, - expectedRequestBadLocalAddressErrors: 0, - expectedRequestInterfaceHasNoLocalAddressErrors: 1, - expectedRequestDroppedErrors: 0, - }, - { - name: "Link error", - nicAddr: stackAddr, - localAddr: stackAddr, - remoteLinkAddr: remoteLinkAddr, - linkErr: &tcpip.ErrInvalidEndpointState{}, - expectedErr: &tcpip.ErrInvalidEndpointState{}, - expectedRequestsSent: 0, - expectedRequestBadLocalAddressErrors: 0, - expectedRequestInterfaceHasNoLocalAddressErrors: 0, - expectedRequestDroppedErrors: 1, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol}, - }) - linkEP := channel.New(1, header.IPv4MinimumMTU, stackLinkAddr) - if err := s.CreateNIC(nicID, &testLinkEndpoint{LinkEndpoint: linkEP, writeErr: test.linkErr}); err != nil { - t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err) - } - - ep, err := s.GetNetworkEndpoint(nicID, arp.ProtocolNumber) - if err != nil { - t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, arp.ProtocolNumber, err) - } - linkRes, ok := ep.(stack.LinkAddressResolver) - if !ok { - t.Fatalf("expected %T to implement stack.LinkAddressResolver", ep) - } - - if len(test.nicAddr) != 0 { - protocolAddr := tcpip.ProtocolAddress{ - Protocol: ipv4.ProtocolNumber, - AddressWithPrefix: test.nicAddr.WithPrefix(), - } - if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{}); err != nil { - t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protocolAddr, err) - } - } - - { - err := linkRes.LinkAddressRequest(remoteAddr, test.localAddr, test.remoteLinkAddr) - if diff := cmp.Diff(test.expectedErr, err); diff != "" { - t.Fatalf("unexpected error from p.LinkAddressRequest(%s, %s, %s, _), (-want, +got):\n%s", remoteAddr, test.localAddr, test.remoteLinkAddr, diff) - } - } - - if got := s.Stats().ARP.OutgoingRequestsSent.Value(); got != test.expectedRequestsSent { - t.Errorf("got s.Stats().ARP.OutgoingRequestsSent.Value() = %d, want = %d", got, test.expectedRequestsSent) - } - if got := s.Stats().ARP.OutgoingRequestInterfaceHasNoLocalAddressErrors.Value(); got != test.expectedRequestInterfaceHasNoLocalAddressErrors { - t.Errorf("got s.Stats().ARP.OutgoingRequestInterfaceHasNoLocalAddressErrors.Value() = %d, want = %d", got, test.expectedRequestInterfaceHasNoLocalAddressErrors) - } - if got := s.Stats().ARP.OutgoingRequestBadLocalAddressErrors.Value(); got != test.expectedRequestBadLocalAddressErrors { - t.Errorf("got s.Stats().ARP.OutgoingRequestBadLocalAddressErrors.Value() = %d, want = %d", got, test.expectedRequestBadLocalAddressErrors) - } - if got := s.Stats().ARP.OutgoingRequestsDropped.Value(); got != test.expectedRequestDroppedErrors { - t.Errorf("got s.Stats().ARP.OutgoingRequestsDropped.Value() = %d, want = %d", got, test.expectedRequestDroppedErrors) - } - - if test.expectedErr != nil { - return - } - - pkt, ok := linkEP.Read() - if !ok { - t.Fatal("expected to send a link address request") - } - - if pkt.Route.RemoteLinkAddress != test.expectedRemoteLinkAddr { - t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, test.expectedRemoteLinkAddr) - } - - rep := header.ARP(stack.PayloadSince(pkt.Pkt.NetworkHeader())) - if got := rep.Op(); got != header.ARPRequest { - t.Errorf("got Op = %d, want = %d", got, header.ARPRequest) - } - if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != stackLinkAddr { - t.Errorf("got HardwareAddressSender = %s, want = %s", got, stackLinkAddr) - } - if got := tcpip.Address(rep.ProtocolAddressSender()); got != test.expectedLocalAddr { - t.Errorf("got ProtocolAddressSender = %s, want = %s", got, test.expectedLocalAddr) - } - if got, want := tcpip.LinkAddress(rep.HardwareAddressTarget()), tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"); got != want { - t.Errorf("got HardwareAddressTarget = %s, want = %s", got, want) - } - if got := tcpip.Address(rep.ProtocolAddressTarget()); got != remoteAddr { - t.Errorf("got ProtocolAddressTarget = %s, want = %s", got, remoteAddr) - } - }) - } -} - -func TestDADARPRequestPacket(t *testing.T) { - clock := faketime.NewManualClock() - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocolWithOptions(arp.Options{ - DADConfigs: stack.DADConfigurations{ - DupAddrDetectTransmits: 1, - }, - }), ipv4.NewProtocol}, - Clock: clock, - }) - e := channel.New(1, header.IPv4MinimumMTU, stackLinkAddr) - if err := s.CreateNIC(nicID, e); err != nil { - t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err) - } - - if res, err := s.CheckDuplicateAddress(nicID, header.IPv4ProtocolNumber, remoteAddr, func(stack.DADResult) {}); err != nil { - t.Fatalf("s.CheckDuplicateAddress(%d, %d, %s, _): %s", nicID, header.IPv4ProtocolNumber, remoteAddr, err) - } else if res != stack.DADStarting { - t.Fatalf("got s.CheckDuplicateAddress(%d, %d, %s, _) = %d, want = %d", nicID, header.IPv4ProtocolNumber, remoteAddr, res, stack.DADStarting) - } - - clock.RunImmediatelyScheduledJobs() - pkt, ok := e.Read() - if !ok { - t.Fatal("expected to send an ARP request") - } - - if pkt.Route.RemoteLinkAddress != header.EthernetBroadcastAddress { - t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, header.EthernetBroadcastAddress) - } - - req := header.ARP(stack.PayloadSince(pkt.Pkt.NetworkHeader())) - if !req.IsValid() { - t.Errorf("got req.IsValid() = false, want = true") - } - if got := req.Op(); got != header.ARPRequest { - t.Errorf("got req.Op() = %d, want = %d", got, header.ARPRequest) - } - if got := tcpip.LinkAddress(req.HardwareAddressSender()); got != stackLinkAddr { - t.Errorf("got req.HardwareAddressSender() = %s, want = %s", got, stackLinkAddr) - } - if got := tcpip.Address(req.ProtocolAddressSender()); got != header.IPv4Any { - t.Errorf("got req.ProtocolAddressSender() = %s, want = %s", got, header.IPv4Any) - } - if got, want := tcpip.LinkAddress(req.HardwareAddressTarget()), tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"); got != want { - t.Errorf("got req.HardwareAddressTarget() = %s, want = %s", got, want) - } - if got := tcpip.Address(req.ProtocolAddressTarget()); got != remoteAddr { - t.Errorf("got req.ProtocolAddressTarget() = %s, want = %s", got, remoteAddr) - } -} diff --git a/pkg/tcpip/network/arp/stats_test.go b/pkg/tcpip/network/arp/stats_test.go deleted file mode 100644 index 0df39ae81..000000000 --- a/pkg/tcpip/network/arp/stats_test.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2021 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 arp - -import ( - "reflect" - "testing" - - "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/stack" - "gvisor.dev/gvisor/pkg/tcpip/testutil" -) - -var _ stack.NetworkInterface = (*testInterface)(nil) - -type testInterface struct { - stack.NetworkInterface - nicID tcpip.NICID -} - -func (t *testInterface) ID() tcpip.NICID { - return t.nicID -} - -func TestMultiCounterStatsInitialization(t *testing.T) { - s := stack.New(stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{NewProtocol}, - }) - proto := s.NetworkProtocolInstance(ProtocolNumber).(*protocol) - var nic testInterface - ep := proto.NewEndpoint(&nic, nil).(*endpoint) - // At this point, the Stack's stats and the NetworkEndpoint's stats are - // expected to be bound by a MultiCounterStat. - refStack := s.Stats() - refEP := ep.stats.localStats - if err := testutil.ValidateMultiCounterStats(reflect.ValueOf(&ep.stats.arp).Elem(), []reflect.Value{reflect.ValueOf(&refEP.ARP).Elem(), reflect.ValueOf(&refStack.ARP).Elem()}); err != nil { - t.Error(err) - } -} |