Merge release-20210125.0-25-gd6a39734c (automated)
This commit is contained in:
commit
f2280a58b6
|
@ -309,25 +309,47 @@ func (n *NIC) WritePacket(r *Route, gso *GSO, protocol tcpip.NetworkProtocolNumb
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *NIC) writePacketBuffer(r RouteInfo, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt pendingPacketBuffer) (int, tcpip.Error) {
|
||||||
|
switch pkt := pkt.(type) {
|
||||||
|
case *PacketBuffer:
|
||||||
|
if err := n.writePacket(r, gso, protocol, pkt); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return 1, nil
|
||||||
|
case *PacketBufferList:
|
||||||
|
return n.writePackets(r, gso, protocol, *pkt)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unrecognized pending packet buffer type = %T", pkt))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (n *NIC) enqueuePacketBuffer(r *Route, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt pendingPacketBuffer) (int, tcpip.Error) {
|
func (n *NIC) enqueuePacketBuffer(r *Route, gso *GSO, protocol tcpip.NetworkProtocolNumber, pkt pendingPacketBuffer) (int, tcpip.Error) {
|
||||||
// As per relevant RFCs, we should queue packets while we wait for link
|
routeInfo, _, err := r.resolvedFields(nil)
|
||||||
// resolution to complete.
|
switch err.(type) {
|
||||||
//
|
case nil:
|
||||||
// RFC 1122 section 2.3.2.2 (for IPv4):
|
return n.writePacketBuffer(routeInfo, gso, protocol, pkt)
|
||||||
// The link layer SHOULD save (rather than discard) at least
|
case *tcpip.ErrWouldBlock:
|
||||||
// one (the latest) packet of each set of packets destined to
|
// As per relevant RFCs, we should queue packets while we wait for link
|
||||||
// the same unresolved IP address, and transmit the saved
|
// resolution to complete.
|
||||||
// packet when the address has been resolved.
|
//
|
||||||
//
|
// RFC 1122 section 2.3.2.2 (for IPv4):
|
||||||
// RFC 4861 section 7.2.2 (for IPv6):
|
// The link layer SHOULD save (rather than discard) at least
|
||||||
// While waiting for address resolution to complete, the sender MUST, for
|
// one (the latest) packet of each set of packets destined to
|
||||||
// each neighbor, retain a small queue of packets waiting for address
|
// the same unresolved IP address, and transmit the saved
|
||||||
// resolution to complete. The queue MUST hold at least one packet, and MAY
|
// packet when the address has been resolved.
|
||||||
// contain more. However, the number of queued packets per neighbor SHOULD
|
//
|
||||||
// be limited to some small value. When a queue overflows, the new arrival
|
// RFC 4861 section 7.2.2 (for IPv6):
|
||||||
// SHOULD replace the oldest entry. Once address resolution completes, the
|
// While waiting for address resolution to complete, the sender MUST, for
|
||||||
// node transmits any queued packets.
|
// each neighbor, retain a small queue of packets waiting for address
|
||||||
return n.linkResQueue.enqueue(r, gso, protocol, pkt)
|
// resolution to complete. The queue MUST hold at least one packet, and
|
||||||
|
// MAY contain more. However, the number of queued packets per neighbor
|
||||||
|
// SHOULD be limited to some small value. When a queue overflows, the new
|
||||||
|
// arrival SHOULD replace the oldest entry. Once address resolution
|
||||||
|
// completes, the node transmits any queued packets.
|
||||||
|
return n.linkResQueue.enqueue(r, gso, protocol, pkt)
|
||||||
|
default:
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WritePacketToRemote implements NetworkInterface.
|
// WritePacketToRemote implements NetworkInterface.
|
||||||
|
|
|
@ -114,20 +114,6 @@ func (f *packetsPendingLinkResolution) dequeue(ch <-chan struct{}, linkAddr tcpi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *packetsPendingLinkResolution) writePacketBuffer(r RouteInfo, gso *GSO, proto tcpip.NetworkProtocolNumber, pkt pendingPacketBuffer) (int, tcpip.Error) {
|
|
||||||
switch pkt := pkt.(type) {
|
|
||||||
case *PacketBuffer:
|
|
||||||
if err := f.nic.writePacket(r, gso, proto, pkt); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return 1, nil
|
|
||||||
case *PacketBufferList:
|
|
||||||
return f.nic.writePackets(r, gso, proto, *pkt)
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unrecognized pending packet buffer type = %T", pkt))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// enqueue a packet to be sent once link resolution completes.
|
// enqueue a packet to be sent once link resolution completes.
|
||||||
//
|
//
|
||||||
// If the maximum number of pending resolutions is reached, the packets
|
// If the maximum number of pending resolutions is reached, the packets
|
||||||
|
@ -151,7 +137,7 @@ func (f *packetsPendingLinkResolution) enqueue(r *Route, gso *GSO, proto tcpip.N
|
||||||
// The route resolved immediately, so we don't need to wait for link
|
// The route resolved immediately, so we don't need to wait for link
|
||||||
// resolution to send the packet.
|
// resolution to send the packet.
|
||||||
f.mu.Unlock()
|
f.mu.Unlock()
|
||||||
return f.writePacketBuffer(routeInfo, gso, proto, pkt)
|
return f.nic.writePacketBuffer(routeInfo, gso, proto, pkt)
|
||||||
case *tcpip.ErrWouldBlock:
|
case *tcpip.ErrWouldBlock:
|
||||||
// We need to wait for link resolution to complete.
|
// We need to wait for link resolution to complete.
|
||||||
default:
|
default:
|
||||||
|
@ -225,7 +211,7 @@ func (f *packetsPendingLinkResolution) dequeuePackets(packets []pendingPacket, l
|
||||||
for _, p := range packets {
|
for _, p := range packets {
|
||||||
if success {
|
if success {
|
||||||
p.routeInfo.RemoteLinkAddress = linkAddr
|
p.routeInfo.RemoteLinkAddress = linkAddr
|
||||||
_, _ = f.writePacketBuffer(p.routeInfo, p.gso, p.proto, p.pkt)
|
_, _ = f.nic.writePacketBuffer(p.routeInfo, p.gso, p.proto, p.pkt)
|
||||||
} else {
|
} else {
|
||||||
f.incrementOutgoingPacketErrors(p.proto, p.pkt)
|
f.incrementOutgoingPacketErrors(p.proto, p.pkt)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue