diff options
Diffstat (limited to 'pkg/tcpip/link/fdbased/endpoint.go')
-rw-r--r-- | pkg/tcpip/link/fdbased/endpoint.go | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 40a10eb9b..ee99ada07 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -164,17 +164,24 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b views[0] = hdr.View() views = append(views, payload.Views()...) vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) - e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, r.LocalLinkAddress, protocol, vv) return nil } if e.hdrSize > 0 { // Add ethernet header if needed. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) - eth.Encode(&header.EthernetFields{ + ethHdr := &header.EthernetFields{ DstAddr: r.RemoteLinkAddress, - SrcAddr: e.addr, Type: protocol, - }) + } + + // Preserve the src address if it's set in the route. + if r.LocalLinkAddress != "" { + ethHdr.SrcAddr = r.LocalLinkAddress + } else { + ethHdr.SrcAddr = e.addr + } + eth.Encode(ethHdr) } if payload.Size() == 0 { @@ -223,12 +230,15 @@ func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { return false, nil } - var p tcpip.NetworkProtocolNumber - var addr tcpip.LinkAddress + var ( + p tcpip.NetworkProtocolNumber + remoteLinkAddr, localLinkAddr tcpip.LinkAddress + ) if e.hdrSize > 0 { eth := header.Ethernet(e.views[0]) p = eth.Type() - addr = eth.SourceAddress() + remoteLinkAddr = eth.SourceAddress() + localLinkAddr = eth.DestinationAddress() } else { // We don't get any indication of what the packet is, so try to guess // if it's an IPv4 or IPv6 packet. @@ -246,7 +256,7 @@ func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { vv := buffer.NewVectorisedView(n, e.views[:used]) vv.TrimFront(e.hdrSize) - e.dispatcher.DeliverNetworkPacket(e, addr, p, vv) + e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, localLinkAddr, p, vv) // Prepare e.views for another packet: release used views. for i := 0; i < used; i++ { @@ -287,7 +297,7 @@ func (e *InjectableEndpoint) Attach(dispatcher stack.NetworkDispatcher) { // Inject injects an inbound packet. func (e *InjectableEndpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { - e.dispatcher.DeliverNetworkPacket(e, "", protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, "" /* remoteLinkAddr */, "" /* localLinkAddr */, protocol, vv) } // NewInjectable creates a new fd-based InjectableEndpoint. |