diff options
Diffstat (limited to 'pkg/tcpip/link/fdbased/endpoint.go')
-rw-r--r-- | pkg/tcpip/link/fdbased/endpoint.go | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 668514454..0c844c05b 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -45,10 +45,14 @@ type endpoint struct { // its end of the communication pipe. closed func(*tcpip.Error) - vv *buffer.VectorisedView - iovecs []syscall.Iovec - views []buffer.View - attached bool + vv *buffer.VectorisedView + iovecs []syscall.Iovec + views []buffer.View + dispatcher stack.NetworkDispatcher + + // egressLocal indicates whether packets destined to itself should be + // forwarded to the FD endpoint (true) or be sent back to netstack (false). + egressLocal bool } // Options specify the details about the fd-based endpoint to be created. @@ -59,6 +63,7 @@ type Options struct { ChecksumOffload bool ClosedFunc func(*tcpip.Error) Address tcpip.LinkAddress + EgressLocal bool } // New creates a new fd-based endpoint. @@ -80,14 +85,15 @@ func New(opts *Options) tcpip.LinkEndpointID { } e := &endpoint{ - fd: opts.FD, - mtu: opts.MTU, - caps: caps, - closed: opts.ClosedFunc, - addr: opts.Address, - hdrSize: hdrSize, - views: make([]buffer.View, len(BufConfig)), - iovecs: make([]syscall.Iovec, len(BufConfig)), + fd: opts.FD, + mtu: opts.MTU, + caps: caps, + closed: opts.ClosedFunc, + addr: opts.Address, + hdrSize: hdrSize, + views: make([]buffer.View, len(BufConfig)), + iovecs: make([]syscall.Iovec, len(BufConfig)), + egressLocal: opts.EgressLocal, } vv := buffer.NewVectorisedView(0, e.views) e.vv = &vv @@ -97,13 +103,13 @@ func New(opts *Options) tcpip.LinkEndpointID { // Attach launches the goroutine that reads packets from the file descriptor and // dispatches them via the provided dispatcher. func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { - e.attached = true - go e.dispatchLoop(dispatcher) // S/R-FIXME + e.dispatcher = dispatcher + go e.dispatchLoop() // S/R-FIXME } // IsAttached implements stack.LinkEndpoint.IsAttached. func (e *endpoint) IsAttached() bool { - return e.attached + return e.dispatcher != nil } // MTU implements stack.LinkEndpoint.MTU. It returns the value initialized @@ -130,6 +136,12 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { + if !e.egressLocal && r.LocalAddress != "" && r.LocalAddress == r.RemoteAddress { + hdrView := hdr.View() + vv := buffer.NewVectorisedView(len(hdrView)+len(payload), []buffer.View{hdrView, payload}) + e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, &vv) + return nil + } if e.hdrSize > 0 { // Add ethernet header if needed. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) @@ -142,7 +154,6 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload if len(payload) == 0 { return rawfile.NonBlockingWrite(e.fd, hdr.UsedBytes()) - } return rawfile.NonBlockingWrite2(e.fd, hdr.UsedBytes(), payload) @@ -175,7 +186,7 @@ func (e *endpoint) allocateViews(bufConfig []int) { } // dispatch reads one packet from the file descriptor and dispatches it. -func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool, *tcpip.Error) { +func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { e.allocateViews(BufConfig) n, err := rawfile.BlockingReadv(e.fd, e.iovecs) @@ -211,7 +222,7 @@ func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool e.vv.SetSize(n) e.vv.TrimFront(e.hdrSize) - d.DeliverNetworkPacket(e, addr, p, e.vv) + e.dispatcher.DeliverNetworkPacket(e, addr, p, e.vv) // Prepare e.views for another packet: release used views. for i := 0; i < used; i++ { @@ -223,10 +234,10 @@ func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool // dispatchLoop reads packets from the file descriptor in a loop and dispatches // them to the network stack. -func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) *tcpip.Error { +func (e *endpoint) dispatchLoop() *tcpip.Error { v := buffer.NewView(header.MaxIPPacketSize) for { - cont, err := e.dispatch(d, v) + cont, err := e.dispatch(v) if err != nil || !cont { if e.closed != nil { e.closed(err) |