diff options
author | Ghanan Gowripalan <ghanan@google.com> | 2021-01-15 16:46:51 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-01-15 16:49:15 -0800 |
commit | fd5b52c87ff8fbabf2b293fc95ec9f9f04e5621c (patch) | |
tree | 9c557488caa1cce91986edc3f70f39b96e494c97 /pkg/tcpip/stack | |
parent | 12d9790833cc2f6a9b197066a5ecbeb434f74164 (diff) |
Only pass stack.Route's fields to LinkEndpoints
stack.Route is used to send network packets and resolve link addresses.
A LinkEndpoint does not need to do either of these and only needs the
route's fields at the time of the packet write request.
Since LinkEndpoints only need the route's fields when writing packets,
pass a stack.RouteInfo instead.
PiperOrigin-RevId: 352108405
Diffstat (limited to 'pkg/tcpip/stack')
-rw-r--r-- | pkg/tcpip/stack/forwarding_test.go | 6 | ||||
-rw-r--r-- | pkg/tcpip/stack/nic.go | 17 | ||||
-rw-r--r-- | pkg/tcpip/stack/packet_buffer.go | 2 | ||||
-rw-r--r-- | pkg/tcpip/stack/pending_packets.go | 2 | ||||
-rw-r--r-- | pkg/tcpip/stack/registration.go | 55 | ||||
-rw-r--r-- | pkg/tcpip/stack/route.go | 4 |
6 files changed, 51 insertions, 35 deletions
diff --git a/pkg/tcpip/stack/forwarding_test.go b/pkg/tcpip/stack/forwarding_test.go index 93e8e1c51..4908848e9 100644 --- a/pkg/tcpip/stack/forwarding_test.go +++ b/pkg/tcpip/stack/forwarding_test.go @@ -307,9 +307,9 @@ func (e *fwdTestLinkEndpoint) LinkAddress() tcpip.LinkAddress { return e.linkAddr } -func (e fwdTestLinkEndpoint) WritePacket(r *Route, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) *tcpip.Error { +func (e fwdTestLinkEndpoint) WritePacket(r RouteInfo, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) *tcpip.Error { p := fwdTestPacketInfo{ - RemoteLinkAddress: r.RemoteLinkAddress(), + RemoteLinkAddress: r.RemoteLinkAddress, LocalLinkAddress: r.LocalLinkAddress, Pkt: pkt, } @@ -323,7 +323,7 @@ func (e fwdTestLinkEndpoint) WritePacket(r *Route, gso *GSO, protocol tcpip.Netw } // WritePackets stores outbound packets into the channel. -func (e *fwdTestLinkEndpoint) WritePackets(r *Route, gso *GSO, pkts PacketBufferList, protocol tcpip.NetworkProtocolNumber) (int, *tcpip.Error) { +func (e *fwdTestLinkEndpoint) WritePackets(r RouteInfo, gso *GSO, pkts PacketBufferList, protocol tcpip.NetworkProtocolNumber) (int, *tcpip.Error) { n := 0 for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() { e.WritePacket(r, gso, protocol, pkt) diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 8a946b4fa..c8d0323cb 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -321,21 +321,18 @@ func (n *NIC) WritePacket(r *Route, gso *GSO, protocol tcpip.NetworkProtocolNumb return err } - return n.writePacket(r, gso, protocol, pkt) + return n.writePacket(r.Fields(), gso, protocol, pkt) } // WritePacketToRemote implements NetworkInterface. func (n *NIC) WritePacketToRemote(remoteLinkAddr tcpip.LinkAddress, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) *tcpip.Error { - r := Route{ - routeInfo: routeInfo{ - NetProto: protocol, - }, - } - r.ResolveWith(remoteLinkAddr) - return n.writePacket(&r, gso, protocol, pkt) + var r RouteInfo + r.NetProto = protocol + r.RemoteLinkAddress = remoteLinkAddr + return n.writePacket(r, gso, protocol, pkt) } -func (n *NIC) writePacket(r *Route, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) *tcpip.Error { +func (n *NIC) writePacket(r RouteInfo, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) *tcpip.Error { // WritePacket takes ownership of pkt, calculate numBytes first. numBytes := pkt.Size() @@ -352,7 +349,7 @@ func (n *NIC) writePacket(r *Route, gso *GSO, protocol tcpip.NetworkProtocolNumb func (n *NIC) WritePackets(r *Route, gso *GSO, pkts PacketBufferList, protocol tcpip.NetworkProtocolNumber) (int, *tcpip.Error) { // TODO(gvisor.dev/issue/4458): Queue packets whie link address resolution // is being peformed like WritePacket. - writtenPackets, err := n.LinkEndpoint.WritePackets(r, gso, pkts, protocol) + writtenPackets, err := n.LinkEndpoint.WritePackets(r.Fields(), gso, pkts, protocol) n.stats.Tx.Packets.IncrementBy(uint64(writtenPackets)) writtenBytes := 0 for i, pb := 0, pkts.Front(); i < writtenPackets && pb != nil; i, pb = i+1, pb.Next() { diff --git a/pkg/tcpip/stack/packet_buffer.go b/pkg/tcpip/stack/packet_buffer.go index 5f216ca21..9d4fc3e48 100644 --- a/pkg/tcpip/stack/packet_buffer.go +++ b/pkg/tcpip/stack/packet_buffer.go @@ -102,7 +102,7 @@ type PacketBuffer struct { // The following fields are only set by the qdisc layer when the packet // is added to a queue. - EgressRoute *Route + EgressRoute RouteInfo GSOOptions *GSO // NatDone indicates if the packet has been manipulated as per NAT diff --git a/pkg/tcpip/stack/pending_packets.go b/pkg/tcpip/stack/pending_packets.go index bded8814e..41529ffd5 100644 --- a/pkg/tcpip/stack/pending_packets.go +++ b/pkg/tcpip/stack/pending_packets.go @@ -108,7 +108,7 @@ func (f *packetsPendingLinkResolution) enqueue(ch <-chan struct{}, r *Route, pro linkResolvableEP.HandleLinkResolutionFailure(pkt) } } else { - p.route.outgoingNIC.writePacket(p.route, nil /* gso */, p.proto, p.pkt) + p.route.outgoingNIC.writePacket(p.route.Fields(), nil /* gso */, p.proto, p.pkt) } p.route.Release() } diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 924790779..0f6ec92c9 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -513,6 +513,23 @@ type NetworkInterface interface { // WritePacketToRemote writes the packet to the given remote link address. WritePacketToRemote(tcpip.LinkAddress, *GSO, tcpip.NetworkProtocolNumber, *PacketBuffer) *tcpip.Error + + // WritePacket writes a packet with the given protocol through the given + // route. + // + // WritePacket takes ownership of the packet buffer. The packet buffer's + // network and transport header must be set. + WritePacket(*Route, *GSO, tcpip.NetworkProtocolNumber, *PacketBuffer) *tcpip.Error + + // WritePackets writes packets with the given protocol through the given + // route. Must not be called with an empty list of packet buffers. + // + // WritePackets takes ownership of the packet buffers. + // + // Right now, WritePackets is used only when the software segmentation + // offload is enabled. If it will be used for something else, syscall filters + // may need to be updated. + WritePackets(*Route, *GSO, PacketBufferList, tcpip.NetworkProtocolNumber) (int, *tcpip.Error) } // LinkResolvableNetworkEndpoint handles link resolution events. @@ -708,24 +725,6 @@ type NetworkLinkEndpoint interface { // LinkAddress returns the link address (typically a MAC) of the // endpoint. LinkAddress() tcpip.LinkAddress - - // WritePacket writes a packet with the given protocol through the - // given route. It takes ownership of pkt. pkt.NetworkHeader and - // pkt.TransportHeader must have already been set. - // - // To participate in transparent bridging, a LinkEndpoint implementation - // should call eth.Encode with header.EthernetFields.SrcAddr set to - // r.LocalLinkAddress if it is provided. - WritePacket(r *Route, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) *tcpip.Error - - // WritePackets writes packets with the given protocol through the - // given route. pkts must not be zero length. It takes ownership of pkts and - // underlying packets. - // - // Right now, WritePackets is used only when the software segmentation - // offload is enabled. If it will be used for something else, it may - // require to change syscall filters. - WritePackets(r *Route, gso *GSO, pkts PacketBufferList, protocol tcpip.NetworkProtocolNumber) (int, *tcpip.Error) } // LinkEndpoint is the interface implemented by data link layer protocols (e.g., @@ -768,6 +767,26 @@ type LinkEndpoint interface { // AddHeader adds a link layer header to pkt if required. AddHeader(local, remote tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt *PacketBuffer) + + // WritePacket writes a packet with the given protocol and route. + // + // WritePacket takes ownership of the packet buffer. The packet buffer's + // network and transport header must be set. + // + // To participate in transparent bridging, a LinkEndpoint implementation + // should call eth.Encode with header.EthernetFields.SrcAddr set to + // r.LocalLinkAddress if it is provided. + WritePacket(RouteInfo, *GSO, tcpip.NetworkProtocolNumber, *PacketBuffer) *tcpip.Error + + // WritePackets writes packets with the given protocol and route. Must not be + // called with an empty list of packet buffers. + // + // WritePackets takes ownership of the packet buffers. + // + // Right now, WritePackets is used only when the software segmentation + // offload is enabled. If it will be used for something else, syscall filters + // may need to be updated. + WritePackets(RouteInfo, *GSO, PacketBufferList, tcpip.NetworkProtocolNumber) (int, *tcpip.Error) } // InjectableLinkEndpoint is a LinkEndpoint where inbound packets are diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index b0251d0b4..ac163904c 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -90,9 +90,9 @@ type RouteInfo struct { RemoteLinkAddress tcpip.LinkAddress } -// GetFields returns a RouteInfo with all of r's exported fields. This allows +// Fields returns a RouteInfo with all of r's exported fields. This allows // callers to store the route's fields without retaining a reference to it. -func (r *Route) GetFields() RouteInfo { +func (r *Route) Fields() RouteInfo { return RouteInfo{ routeInfo: r.routeInfo, RemoteLinkAddress: r.RemoteLinkAddress(), |