diff options
Diffstat (limited to 'pkg/tcpip/link/ethernet')
-rw-r--r-- | pkg/tcpip/link/ethernet/BUILD | 16 | ||||
-rw-r--r-- | pkg/tcpip/link/ethernet/ethernet.go | 10 | ||||
-rw-r--r-- | pkg/tcpip/link/ethernet/ethernet_test.go | 71 |
3 files changed, 91 insertions, 6 deletions
diff --git a/pkg/tcpip/link/ethernet/BUILD b/pkg/tcpip/link/ethernet/BUILD index ec92ed623..0ae0d201a 100644 --- a/pkg/tcpip/link/ethernet/BUILD +++ b/pkg/tcpip/link/ethernet/BUILD @@ -1,4 +1,4 @@ -load("//tools:defs.bzl", "go_library") +load("//tools:defs.bzl", "go_library", "go_test") package(licenses = ["notice"]) @@ -13,3 +13,17 @@ go_library( "//pkg/tcpip/stack", ], ) + +go_test( + name = "ethernet_test", + size = "small", + srcs = ["ethernet_test.go"], + deps = [ + ":ethernet", + "//pkg/tcpip", + "//pkg/tcpip/buffer", + "//pkg/tcpip/header", + "//pkg/tcpip/link/channel", + "//pkg/tcpip/stack", + ], +) diff --git a/pkg/tcpip/link/ethernet/ethernet.go b/pkg/tcpip/link/ethernet/ethernet.go index 3eef7cd56..89e3e6164 100644 --- a/pkg/tcpip/link/ethernet/ethernet.go +++ b/pkg/tcpip/link/ethernet/ethernet.go @@ -49,10 +49,10 @@ func (e *Endpoint) DeliverNetworkPacket(_, _ tcpip.LinkAddress, _ tcpip.NetworkP return } + // Note, there is no need to check the destination link address here since + // the ethernet hardware filters frames based on their destination addresses. eth := header.Ethernet(hdr) - if dst := eth.DestinationAddress(); dst == e.Endpoint.LinkAddress() || dst == header.EthernetBroadcastAddress || header.IsMulticastEthernetAddress(dst) { - e.Endpoint.DeliverNetworkPacket(eth.SourceAddress() /* remote */, dst /* local */, eth.Type() /* protocol */, pkt) - } + e.Endpoint.DeliverNetworkPacket(eth.SourceAddress() /* remote */, eth.DestinationAddress() /* local */, eth.Type() /* protocol */, pkt) } // Capabilities implements stack.LinkEndpoint. @@ -62,7 +62,7 @@ func (e *Endpoint) Capabilities() stack.LinkEndpointCapabilities { // WritePacket implements stack.LinkEndpoint. func (e *Endpoint) WritePacket(r *stack.Route, gso *stack.GSO, proto tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) *tcpip.Error { - e.AddHeader(e.Endpoint.LinkAddress(), r.RemoteLinkAddress, proto, pkt) + e.AddHeader(e.Endpoint.LinkAddress(), r.RemoteLinkAddress(), proto, pkt) return e.Endpoint.WritePacket(r, gso, proto, pkt) } @@ -71,7 +71,7 @@ func (e *Endpoint) WritePackets(r *stack.Route, gso *stack.GSO, pkts stack.Packe linkAddr := e.Endpoint.LinkAddress() for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() { - e.AddHeader(linkAddr, r.RemoteLinkAddress, proto, pkt) + e.AddHeader(linkAddr, r.RemoteLinkAddress(), proto, pkt) } return e.Endpoint.WritePackets(r, gso, pkts, proto) diff --git a/pkg/tcpip/link/ethernet/ethernet_test.go b/pkg/tcpip/link/ethernet/ethernet_test.go new file mode 100644 index 000000000..08a7f1ce1 --- /dev/null +++ b/pkg/tcpip/link/ethernet/ethernet_test.go @@ -0,0 +1,71 @@ +// 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 ethernet_test + +import ( + "testing" + + "gvisor.dev/gvisor/pkg/tcpip" + "gvisor.dev/gvisor/pkg/tcpip/buffer" + "gvisor.dev/gvisor/pkg/tcpip/header" + "gvisor.dev/gvisor/pkg/tcpip/link/channel" + "gvisor.dev/gvisor/pkg/tcpip/link/ethernet" + "gvisor.dev/gvisor/pkg/tcpip/stack" +) + +var _ stack.NetworkDispatcher = (*testNetworkDispatcher)(nil) + +type testNetworkDispatcher struct { + networkPackets int +} + +func (t *testNetworkDispatcher) DeliverNetworkPacket(_, _ tcpip.LinkAddress, _ tcpip.NetworkProtocolNumber, _ *stack.PacketBuffer) { + t.networkPackets++ +} + +func (*testNetworkDispatcher) DeliverOutboundPacket(_, _ tcpip.LinkAddress, _ tcpip.NetworkProtocolNumber, _ *stack.PacketBuffer) { +} + +func TestDeliverNetworkPacket(t *testing.T) { + const ( + linkAddr = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06") + otherLinkAddr1 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x07") + otherLinkAddr2 = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x08") + ) + + e := ethernet.New(channel.New(0, 0, linkAddr)) + var networkDispatcher testNetworkDispatcher + e.Attach(&networkDispatcher) + + if networkDispatcher.networkPackets != 0 { + t.Fatalf("got networkDispatcher.networkPackets = %d, want = 0", networkDispatcher.networkPackets) + } + + // An ethernet frame with a destination link address that is not assigned to + // our ethernet link endpoint should still be delivered to the network + // dispatcher since the ethernet endpoint is not expected to filter frames. + eth := buffer.NewView(header.EthernetMinimumSize) + header.Ethernet(eth).Encode(&header.EthernetFields{ + SrcAddr: otherLinkAddr1, + DstAddr: otherLinkAddr2, + Type: header.IPv4ProtocolNumber, + }) + e.DeliverNetworkPacket("", "", 0, stack.NewPacketBuffer(stack.PacketBufferOptions{ + Data: eth.ToVectorisedView(), + })) + if networkDispatcher.networkPackets != 1 { + t.Fatalf("got networkDispatcher.networkPackets = %d, want = 1", networkDispatcher.networkPackets) + } +} |