diff --git a/pkg/tcpip/link/ethernet/ethernet.go b/pkg/tcpip/link/ethernet/ethernet.go index 82b815677..60c592c12 100644 --- a/pkg/tcpip/link/ethernet/ethernet.go +++ b/pkg/tcpip/link/ethernet/ethernet.go @@ -91,7 +91,7 @@ func (e *Endpoint) WritePackets(r stack.RouteInfo, pkts stack.PacketBufferList, linkAddr := e.LinkAddress() for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() { - e.AddHeader(linkAddr, r.RemoteLinkAddress, proto, pkt) + e.AddHeader(linkAddr, pkt.EgressRoute.RemoteLinkAddress, pkt.NetworkProtocolNumber, pkt) } return e.Endpoint.WritePackets(r, pkts, proto) diff --git a/pkg/tcpip/link/ethernet/ethernet_test.go b/pkg/tcpip/link/ethernet/ethernet_test.go index 16b183a61..4361fe034 100644 --- a/pkg/tcpip/link/ethernet/ethernet_test.go +++ b/pkg/tcpip/link/ethernet/ethernet_test.go @@ -119,3 +119,49 @@ func TestMTU(t *testing.T) { }) } } + +func TestWritePacketsAddHeader(t *testing.T) { + const ( + localLinkAddr = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x06") + remoteLinkAddr = tcpip.LinkAddress("\x02\x02\x03\x04\x05\x07") + + netProto = 55 + ) + + c := channel.New(1, header.EthernetMinimumSize, localLinkAddr) + e := ethernet.New(c) + + { + pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ + ReserveHeaderBytes: int(e.MaxHeaderLength()), + }) + pkt.NetworkProtocolNumber = netProto + pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr + + var pkts stack.PacketBufferList + pkts.PushFront(pkt) + if n, err := e.WritePackets(stack.RouteInfo{}, pkts, 0 /* protocol */); err != nil { + t.Fatalf("e.WritePackets({}, _, 0): %s", err) + } else if n != 1 { + t.Fatalf("got e.WritePackets({}, _, 0) = %d, want = 1", n) + } + } + + { + pkt := c.Read() + if pkt == nil { + t.Fatal("expected to read a packet") + } + + eth := header.Ethernet(pkt.LinkHeader().View()) + if got := eth.SourceAddress(); got != localLinkAddr { + t.Errorf("got eth.SourceAddress() = %s, want = %s", got, localLinkAddr) + } + if got := eth.DestinationAddress(); got != remoteLinkAddr { + t.Errorf("got eth.DestinationAddress() = %s, want = %s", got, remoteLinkAddr) + } + if got := eth.Type(); got != netProto { + t.Errorf("got eth.Type() = %d, want = %d", got, netProto) + } + } +}