mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Internal change.
PiperOrigin-RevId: 274700093
This commit is contained in:
@@ -1177,6 +1177,25 @@ func getSockOptIPv6(t *kernel.Task, ep commonEndpoint, name, outLen int) (interf
|
||||
case linux.IPV6_PATHMTU:
|
||||
t.Kernel().EmitUnimplementedEvent(t)
|
||||
|
||||
case linux.IPV6_TCLASS:
|
||||
// Length handling for parity with Linux.
|
||||
if outLen == 0 {
|
||||
return make([]byte, 0), nil
|
||||
}
|
||||
var v tcpip.IPv6TrafficClassOption
|
||||
if err := ep.GetSockOpt(&v); err != nil {
|
||||
return nil, syserr.TranslateNetstackError(err)
|
||||
}
|
||||
|
||||
uintv := uint32(v)
|
||||
// Linux truncates the output binary to outLen.
|
||||
ib := binary.Marshal(nil, usermem.ByteOrder, &uintv)
|
||||
// Handle cases where outLen is lesser than sizeOfInt32.
|
||||
if len(ib) > outLen {
|
||||
ib = ib[:outLen]
|
||||
}
|
||||
return ib, nil
|
||||
|
||||
default:
|
||||
emitUnimplementedEventIPv6(t, name)
|
||||
}
|
||||
@@ -1244,6 +1263,20 @@ func getSockOptIP(t *kernel.Task, ep commonEndpoint, name, outLen int, family in
|
||||
}
|
||||
return int32(0), nil
|
||||
|
||||
case linux.IP_TOS:
|
||||
// Length handling for parity with Linux.
|
||||
if outLen == 0 {
|
||||
return []byte(nil), nil
|
||||
}
|
||||
var v tcpip.IPv4TOSOption
|
||||
if err := ep.GetSockOpt(&v); err != nil {
|
||||
return nil, syserr.TranslateNetstackError(err)
|
||||
}
|
||||
if outLen < sizeOfInt32 {
|
||||
return uint8(v), nil
|
||||
}
|
||||
return int32(v), nil
|
||||
|
||||
default:
|
||||
emitUnimplementedEventIP(t, name)
|
||||
}
|
||||
@@ -1542,6 +1575,19 @@ func setSockOptIPv6(t *kernel.Task, ep commonEndpoint, name int, optVal []byte)
|
||||
|
||||
t.Kernel().EmitUnimplementedEvent(t)
|
||||
|
||||
case linux.IPV6_TCLASS:
|
||||
if len(optVal) < sizeOfInt32 {
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
v := int32(usermem.ByteOrder.Uint32(optVal))
|
||||
if v < -1 || v > 255 {
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
if v == -1 {
|
||||
v = 0
|
||||
}
|
||||
return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.IPv6TrafficClassOption(v)))
|
||||
|
||||
default:
|
||||
emitUnimplementedEventIPv6(t, name)
|
||||
}
|
||||
@@ -1687,6 +1733,16 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s
|
||||
}
|
||||
return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.TTLOption(v)))
|
||||
|
||||
case linux.IP_TOS:
|
||||
if len(optVal) == 0 {
|
||||
return nil
|
||||
}
|
||||
v, err := parseIntOrChar(optVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.IPv4TOSOption(v)))
|
||||
|
||||
case linux.IP_ADD_SOURCE_MEMBERSHIP,
|
||||
linux.IP_BIND_ADDRESS_NO_PORT,
|
||||
linux.IP_BLOCK_SOURCE,
|
||||
@@ -1710,7 +1766,6 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s
|
||||
linux.IP_RECVTOS,
|
||||
linux.IP_RECVTTL,
|
||||
linux.IP_RETOPTS,
|
||||
linux.IP_TOS,
|
||||
linux.IP_TRANSPARENT,
|
||||
linux.IP_UNBLOCK_SOURCE,
|
||||
linux.IP_UNICAST_IF,
|
||||
|
||||
@@ -79,7 +79,7 @@ func (e *endpoint) MaxHeaderLength() uint16 {
|
||||
|
||||
func (e *endpoint) Close() {}
|
||||
|
||||
func (e *endpoint) WritePacket(*stack.Route, *stack.GSO, buffer.Prependable, buffer.VectorisedView, tcpip.TransportProtocolNumber, uint8, stack.PacketLooping) *tcpip.Error {
|
||||
func (e *endpoint) WritePacket(*stack.Route, *stack.GSO, buffer.Prependable, buffer.VectorisedView, stack.NetworkHeaderParams, stack.PacketLooping) *tcpip.Error {
|
||||
return tcpip.ErrNotSupported
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ func TestIPv4Send(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("could not find route: %v", err)
|
||||
}
|
||||
if err := ep.WritePacket(&r, nil /* gso */, hdr, payload.ToVectorisedView(), 123, 123, stack.PacketOut); err != nil {
|
||||
if err := ep.WritePacket(&r, nil /* gso */, hdr, payload.ToVectorisedView(), stack.NetworkHeaderParams{Protocol: 123, TTL: 123, TOS: stack.DefaultTOS}, stack.PacketOut); err != nil {
|
||||
t.Fatalf("WritePacket failed: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -460,7 +460,7 @@ func TestIPv6Send(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("could not find route: %v", err)
|
||||
}
|
||||
if err := ep.WritePacket(&r, nil /* gso */, hdr, payload.ToVectorisedView(), 123, 123, stack.PacketOut); err != nil {
|
||||
if err := ep.WritePacket(&r, nil /* gso */, hdr, payload.ToVectorisedView(), stack.NetworkHeaderParams{Protocol: 123, TTL: 123, TOS: stack.DefaultTOS}, stack.PacketOut); err != nil {
|
||||
t.Fatalf("WritePacket failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
pkt.SetChecksum(0)
|
||||
pkt.SetChecksum(^header.Checksum(pkt, header.ChecksumVV(vv, 0)))
|
||||
sent := stats.ICMP.V4PacketsSent
|
||||
if err := r.WritePacket(nil /* gso */, hdr, vv, header.ICMPv4ProtocolNumber, 0, true /* useDefaultTTL */); err != nil {
|
||||
if err := r.WritePacket(nil /* gso */, hdr, vv, stack.NetworkHeaderParams{Protocol: header.ICMPv4ProtocolNumber, TTL: r.DefaultTTL(), TOS: stack.DefaultTOS}); err != nil {
|
||||
sent.Dropped.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -199,21 +199,22 @@ func (e *endpoint) writePacketFragments(r *stack.Route, gso *stack.GSO, hdr buff
|
||||
}
|
||||
|
||||
// WritePacket writes a packet to the given destination address and protocol.
|
||||
func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop stack.PacketLooping) *tcpip.Error {
|
||||
func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, params stack.NetworkHeaderParams, loop stack.PacketLooping) *tcpip.Error {
|
||||
ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize))
|
||||
length := uint16(hdr.UsedLength() + payload.Size())
|
||||
id := uint32(0)
|
||||
if length > header.IPv4MaximumHeaderSize+8 {
|
||||
// Packets of 68 bytes or less are required by RFC 791 to not be
|
||||
// fragmented, so we only assign ids to larger packets.
|
||||
id = atomic.AddUint32(&e.protocol.ids[hashRoute(r, protocol, e.protocol.hashIV)%buckets], 1)
|
||||
id = atomic.AddUint32(&e.protocol.ids[hashRoute(r, params.Protocol, e.protocol.hashIV)%buckets], 1)
|
||||
}
|
||||
ip.Encode(&header.IPv4Fields{
|
||||
IHL: header.IPv4MinimumSize,
|
||||
TotalLength: length,
|
||||
ID: uint16(id),
|
||||
TTL: ttl,
|
||||
Protocol: uint8(protocol),
|
||||
TTL: params.TTL,
|
||||
TOS: params.TOS,
|
||||
Protocol: uint8(params.Protocol),
|
||||
SrcAddr: r.LocalAddress,
|
||||
DstAddr: r.RemoteAddress,
|
||||
})
|
||||
|
||||
@@ -302,7 +302,7 @@ func TestFragmentation(t *testing.T) {
|
||||
Payload: payload.Clone([]buffer.View{}),
|
||||
}
|
||||
c := buildContext(t, nil, ft.mtu)
|
||||
err := c.Route.WritePacket(ft.gso, hdr, payload, tcp.ProtocolNumber, 42 /* ttl */, false /* useDefaultTTL */)
|
||||
err := c.Route.WritePacket(ft.gso, hdr, payload, stack.NetworkHeaderParams{Protocol: tcp.ProtocolNumber, TTL: 42, TOS: stack.DefaultTOS})
|
||||
if err != nil {
|
||||
t.Errorf("err got %v, want %v", err, nil)
|
||||
}
|
||||
@@ -349,7 +349,7 @@ func TestFragmentationErrors(t *testing.T) {
|
||||
t.Run(ft.description, func(t *testing.T) {
|
||||
hdr, payload := makeHdrAndPayload(ft.hdrLength, header.IPv4MinimumSize, ft.payloadViewsSizes)
|
||||
c := buildContext(t, ft.packetCollectorErrors, ft.mtu)
|
||||
err := c.Route.WritePacket(&stack.GSO{}, hdr, payload, tcp.ProtocolNumber, 42 /* ttl */, false /* useDefaultTTL */)
|
||||
err := c.Route.WritePacket(&stack.GSO{}, hdr, payload, stack.NetworkHeaderParams{Protocol: tcp.ProtocolNumber, TTL: 42, TOS: stack.DefaultTOS})
|
||||
for i := 0; i < len(ft.packetCollectorErrors)-1; i++ {
|
||||
if got, want := ft.packetCollectorErrors[i], (*tcpip.Error)(nil); got != want {
|
||||
t.Errorf("ft.packetCollectorErrors[%d] got %v, want %v", i, got, want)
|
||||
|
||||
@@ -154,7 +154,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
r.LocalAddress = targetAddr
|
||||
pkt.SetChecksum(header.ICMPv6Checksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{}))
|
||||
|
||||
if err := r.WritePacket(nil /* gso */, hdr, buffer.VectorisedView{}, header.ICMPv6ProtocolNumber, 0, true /* useDefaultTTL */); err != nil {
|
||||
if err := r.WritePacket(nil /* gso */, hdr, buffer.VectorisedView{}, stack.NetworkHeaderParams{Protocol: header.ICMPv6ProtocolNumber, TTL: r.DefaultTTL(), TOS: stack.DefaultTOS}); err != nil {
|
||||
sent.Dropped.Increment()
|
||||
return
|
||||
}
|
||||
@@ -185,7 +185,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
copy(pkt, h)
|
||||
pkt.SetType(header.ICMPv6EchoReply)
|
||||
pkt.SetChecksum(header.ICMPv6Checksum(pkt, r.LocalAddress, r.RemoteAddress, vv))
|
||||
if err := r.WritePacket(nil /* gso */, hdr, vv, header.ICMPv6ProtocolNumber, 0, true /* useDefaultTTL */); err != nil {
|
||||
if err := r.WritePacket(nil /* gso */, hdr, vv, stack.NetworkHeaderParams{Protocol: header.ICMPv6ProtocolNumber, TTL: r.DefaultTTL(), TOS: stack.DefaultTOS}); err != nil {
|
||||
sent.Dropped.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -98,13 +98,14 @@ func (e *endpoint) GSOMaxSize() uint32 {
|
||||
}
|
||||
|
||||
// WritePacket writes a packet to the given destination address and protocol.
|
||||
func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop stack.PacketLooping) *tcpip.Error {
|
||||
func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, params stack.NetworkHeaderParams, loop stack.PacketLooping) *tcpip.Error {
|
||||
length := uint16(hdr.UsedLength() + payload.Size())
|
||||
ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
|
||||
ip.Encode(&header.IPv6Fields{
|
||||
PayloadLength: length,
|
||||
NextHeader: uint8(protocol),
|
||||
HopLimit: ttl,
|
||||
NextHeader: uint8(params.Protocol),
|
||||
HopLimit: params.TTL,
|
||||
TrafficClass: params.TOS,
|
||||
SrcAddr: r.LocalAddress,
|
||||
DstAddr: r.RemoteAddress,
|
||||
})
|
||||
|
||||
@@ -64,7 +64,7 @@ func testReceiveICMP(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst
|
||||
}
|
||||
}
|
||||
|
||||
// testReceiveICMP tests receiving a UDP packet from src to dst. want is the
|
||||
// testReceiveUDP tests receiving a UDP packet from src to dst. want is the
|
||||
// expected UDP received count after receiving the packet.
|
||||
func testReceiveUDP(t *testing.T, s *stack.Stack, e *channel.Endpoint, src, dst tcpip.Address, want uint64) {
|
||||
t.Helper()
|
||||
|
||||
@@ -146,6 +146,19 @@ const (
|
||||
PacketLoop
|
||||
)
|
||||
|
||||
// NetworkHeaderParams are the header parameters given as input by the
|
||||
// transport endpoint to the network.
|
||||
type NetworkHeaderParams struct {
|
||||
// Protocol refers to the transport protocol number.
|
||||
Protocol tcpip.TransportProtocolNumber
|
||||
|
||||
// TTL refers to Time To Live field of the IP-header.
|
||||
TTL uint8
|
||||
|
||||
// TOS refers to TypeOfService or TrafficClass field of the IP-header.
|
||||
TOS uint8
|
||||
}
|
||||
|
||||
// NetworkEndpoint is the interface that needs to be implemented by endpoints
|
||||
// of network layer protocols (e.g., ipv4, ipv6).
|
||||
type NetworkEndpoint interface {
|
||||
@@ -170,7 +183,7 @@ type NetworkEndpoint interface {
|
||||
|
||||
// WritePacket writes a packet to the given destination address and
|
||||
// protocol.
|
||||
WritePacket(r *Route, gso *GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop PacketLooping) *tcpip.Error
|
||||
WritePacket(r *Route, gso *GSO, hdr buffer.Prependable, payload buffer.VectorisedView, params NetworkHeaderParams, loop PacketLooping) *tcpip.Error
|
||||
|
||||
// WriteHeaderIncludedPacket writes a packet that includes a network
|
||||
// header to the given destination address.
|
||||
|
||||
@@ -154,16 +154,12 @@ func (r *Route) IsResolutionRequired() bool {
|
||||
}
|
||||
|
||||
// WritePacket writes the packet through the given route.
|
||||
func (r *Route) WritePacket(gso *GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, useDefaultTTL bool) *tcpip.Error {
|
||||
func (r *Route) WritePacket(gso *GSO, hdr buffer.Prependable, payload buffer.VectorisedView, params NetworkHeaderParams) *tcpip.Error {
|
||||
if !r.ref.isValidForOutgoing() {
|
||||
return tcpip.ErrInvalidEndpointState
|
||||
}
|
||||
|
||||
if useDefaultTTL {
|
||||
ttl = r.DefaultTTL()
|
||||
}
|
||||
|
||||
err := r.ref.ep.WritePacket(r, gso, hdr, payload, protocol, ttl, r.loop)
|
||||
err := r.ref.ep.WritePacket(r, gso, hdr, payload, params, r.loop)
|
||||
if err != nil {
|
||||
r.Stats().IP.OutgoingPacketErrors.Increment()
|
||||
} else {
|
||||
|
||||
@@ -43,6 +43,9 @@ const (
|
||||
resolutionTimeout = 1 * time.Second
|
||||
// resolutionAttempts is set to the same ARP retries used in Linux.
|
||||
resolutionAttempts = 3
|
||||
|
||||
// DefaultTOS is the default type of service value for network endpoints.
|
||||
DefaultTOS = 0
|
||||
)
|
||||
|
||||
type transportProtocolState struct {
|
||||
@@ -394,7 +397,7 @@ type Stack struct {
|
||||
// portSeed is a one-time random value initialized at stack startup
|
||||
// and is used to seed the TCP port picking on active connections
|
||||
//
|
||||
// TODO(gvisor.dev/issues/940): S/R this field.
|
||||
// TODO(gvisor.dev/issue/940): S/R this field.
|
||||
portSeed uint32
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ func (f *fakeNetworkEndpoint) Capabilities() stack.LinkEndpointCapabilities {
|
||||
return f.ep.Capabilities()
|
||||
}
|
||||
|
||||
func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, _ uint8, loop stack.PacketLooping) *tcpip.Error {
|
||||
func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, params stack.NetworkHeaderParams, loop stack.PacketLooping) *tcpip.Error {
|
||||
// Increment the sent packet count in the protocol descriptor.
|
||||
f.proto.sendPacketCount[int(r.RemoteAddress[0])%len(f.proto.sendPacketCount)]++
|
||||
|
||||
@@ -128,7 +128,7 @@ func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr bu
|
||||
b := hdr.Prepend(fakeNetHeaderLen)
|
||||
b[0] = r.RemoteAddress[0]
|
||||
b[1] = f.id.LocalAddress[0]
|
||||
b[2] = byte(protocol)
|
||||
b[2] = byte(params.Protocol)
|
||||
|
||||
if loop&stack.PacketLoop != 0 {
|
||||
views := make([]buffer.View, 1, 1+len(payload.Views()))
|
||||
@@ -310,7 +310,7 @@ func sendTo(s *stack.Stack, addr tcpip.Address, payload buffer.View) *tcpip.Erro
|
||||
|
||||
func send(r stack.Route, payload buffer.View) *tcpip.Error {
|
||||
hdr := buffer.NewPrependable(int(r.MaxHeaderLength()))
|
||||
return r.WritePacket(nil /* gso */, hdr, payload.ToVectorisedView(), fakeTransNumber, 123 /* ttl */, false /* useDefaultTTL */)
|
||||
return r.WritePacket(nil /* gso */, hdr, payload.ToVectorisedView(), stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS})
|
||||
}
|
||||
|
||||
func testSendTo(t *testing.T, s *stack.Stack, addr tcpip.Address, ep *channel.Endpoint, payload buffer.View) {
|
||||
|
||||
@@ -82,7 +82,7 @@ func (f *fakeTransportEndpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if err := f.route.WritePacket(nil /* gso */, hdr, buffer.View(v).ToVectorisedView(), fakeTransNumber, 123 /* ttl */, false /* useDefaultTTL */); err != nil {
|
||||
if err := f.route.WritePacket(nil /* gso */, hdr, buffer.View(v).ToVectorisedView(), stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS}); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -624,6 +624,14 @@ type BroadcastOption int
|
||||
// a default TTL.
|
||||
type DefaultTTLOption uint8
|
||||
|
||||
// IPv4TOSOption is used by SetSockOpt/GetSockOpt to specify TOS
|
||||
// for all subsequent outgoing IPv4 packets from the endpoint.
|
||||
type IPv4TOSOption uint8
|
||||
|
||||
// IPv6TrafficClassOption is used by SetSockOpt/GetSockOpt to specify TOS
|
||||
// for all subsequent outgoing IPv6 packets from the endpoint.
|
||||
type IPv6TrafficClassOption uint8
|
||||
|
||||
// Route is a row in the routing table. It specifies through which NIC (and
|
||||
// gateway) sets of packets should be routed. A row is considered viable if the
|
||||
// masked target address matches the destination address in the row.
|
||||
|
||||
@@ -422,7 +422,10 @@ func send4(r *stack.Route, ident uint16, data buffer.View, ttl uint8) *tcpip.Err
|
||||
icmpv4.SetChecksum(0)
|
||||
icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0)))
|
||||
|
||||
return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, ttl, ttl == 0 /* useDefaultTTL */)
|
||||
if ttl == 0 {
|
||||
ttl = r.DefaultTTL()
|
||||
}
|
||||
return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), stack.NetworkHeaderParams{Protocol: header.ICMPv4ProtocolNumber, TTL: ttl, TOS: stack.DefaultTOS})
|
||||
}
|
||||
|
||||
func send6(r *stack.Route, ident uint16, data buffer.View, ttl uint8) *tcpip.Error {
|
||||
@@ -445,7 +448,10 @@ func send6(r *stack.Route, ident uint16, data buffer.View, ttl uint8) *tcpip.Err
|
||||
icmpv6.SetChecksum(0)
|
||||
icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0)))
|
||||
|
||||
return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), header.ICMPv6ProtocolNumber, ttl, ttl == 0 /* useDefaultTTL */)
|
||||
if ttl == 0 {
|
||||
ttl = r.DefaultTTL()
|
||||
}
|
||||
return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), stack.NetworkHeaderParams{Protocol: header.ICMPv6ProtocolNumber, TTL: ttl, TOS: stack.DefaultTOS})
|
||||
}
|
||||
|
||||
func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) {
|
||||
|
||||
@@ -350,7 +350,7 @@ func (e *endpoint) finishWrite(payloadBytes []byte, route *stack.Route) (int64,
|
||||
break
|
||||
}
|
||||
hdr := buffer.NewPrependable(len(payloadBytes) + int(route.MaxHeaderLength()))
|
||||
if err := route.WritePacket(nil /* gso */, hdr, buffer.View(payloadBytes).ToVectorisedView(), e.TransProto, 0, true /* useDefaultTTL */); err != nil {
|
||||
if err := route.WritePacket(nil /* gso */, hdr, buffer.View(payloadBytes).ToVectorisedView(), stack.NetworkHeaderParams{Protocol: e.TransProto, TTL: route.DefaultTTL(), TOS: stack.DefaultTOS}); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -441,7 +441,7 @@ func (e *endpoint) handleListenSegment(ctx *listenContext, s *segment) {
|
||||
TSEcr: opts.TSVal,
|
||||
MSS: uint16(mss),
|
||||
}
|
||||
e.sendSynTCP(&s.route, s.id, e.ttl, header.TCPFlagSyn|header.TCPFlagAck, cookie, s.sequenceNumber+1, ctx.rcvWnd, synOpts)
|
||||
e.sendSynTCP(&s.route, s.id, e.ttl, e.sendTOS, header.TCPFlagSyn|header.TCPFlagAck, cookie, s.sequenceNumber+1, ctx.rcvWnd, synOpts)
|
||||
e.stack.Stats().TCP.ListenOverflowSynCookieSent.Increment()
|
||||
}
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ func (h *handshake) synSentState(s *segment) *tcpip.Error {
|
||||
if ttl == 0 {
|
||||
ttl = s.route.DefaultTTL()
|
||||
}
|
||||
h.ep.sendSynTCP(&s.route, h.ep.ID, ttl, h.flags, h.iss, h.ackNum, h.rcvWnd, synOpts)
|
||||
h.ep.sendSynTCP(&s.route, h.ep.ID, ttl, h.ep.sendTOS, h.flags, h.iss, h.ackNum, h.rcvWnd, synOpts)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ func (h *handshake) synRcvdState(s *segment) *tcpip.Error {
|
||||
SACKPermitted: h.ep.sackPermitted,
|
||||
MSS: h.ep.amss,
|
||||
}
|
||||
h.ep.sendSynTCP(&s.route, h.ep.ID, h.ep.ttl, h.flags, h.iss, h.ackNum, h.rcvWnd, synOpts)
|
||||
h.ep.sendSynTCP(&s.route, h.ep.ID, h.ep.ttl, h.ep.sendTOS, h.flags, h.iss, h.ackNum, h.rcvWnd, synOpts)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -468,7 +468,8 @@ func (h *handshake) execute() *tcpip.Error {
|
||||
synOpts.WS = -1
|
||||
}
|
||||
}
|
||||
h.ep.sendSynTCP(&h.ep.route, h.ep.ID, h.ep.ttl, h.flags, h.iss, h.ackNum, h.rcvWnd, synOpts)
|
||||
h.ep.sendSynTCP(&h.ep.route, h.ep.ID, h.ep.ttl, h.ep.sendTOS, h.flags, h.iss, h.ackNum, h.rcvWnd, synOpts)
|
||||
|
||||
for h.state != handshakeCompleted {
|
||||
switch index, _ := s.Fetch(true); index {
|
||||
case wakerForResend:
|
||||
@@ -477,7 +478,7 @@ func (h *handshake) execute() *tcpip.Error {
|
||||
return tcpip.ErrTimeout
|
||||
}
|
||||
rt.Reset(timeOut)
|
||||
h.ep.sendSynTCP(&h.ep.route, h.ep.ID, h.ep.ttl, h.flags, h.iss, h.ackNum, h.rcvWnd, synOpts)
|
||||
h.ep.sendSynTCP(&h.ep.route, h.ep.ID, h.ep.ttl, h.ep.sendTOS, h.flags, h.iss, h.ackNum, h.rcvWnd, synOpts)
|
||||
|
||||
case wakerForNotification:
|
||||
n := h.ep.fetchNotifications()
|
||||
@@ -587,17 +588,18 @@ func makeSynOptions(opts header.TCPSynOptions) []byte {
|
||||
return options[:offset]
|
||||
}
|
||||
|
||||
func (e *endpoint) sendSynTCP(r *stack.Route, id stack.TransportEndpointID, ttl uint8, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts header.TCPSynOptions) {
|
||||
func (e *endpoint) sendSynTCP(r *stack.Route, id stack.TransportEndpointID, ttl, tos uint8, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts header.TCPSynOptions) *tcpip.Error {
|
||||
options := makeSynOptions(opts)
|
||||
// We ignore SYN send errors and let the callers re-attempt send.
|
||||
if err := e.sendTCP(r, id, buffer.VectorisedView{}, ttl, flags, seq, ack, rcvWnd, options, nil); err != nil {
|
||||
if err := e.sendTCP(r, id, buffer.VectorisedView{}, ttl, tos, flags, seq, ack, rcvWnd, options, nil); err != nil {
|
||||
e.stats.SendErrors.SynSendToNetworkFailed.Increment()
|
||||
}
|
||||
putOptions(options)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *endpoint) sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, ttl uint8, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte, gso *stack.GSO) *tcpip.Error {
|
||||
if err := sendTCP(r, id, data, ttl, flags, seq, ack, rcvWnd, opts, gso); err != nil {
|
||||
func (e *endpoint) sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, ttl, tos uint8, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte, gso *stack.GSO) *tcpip.Error {
|
||||
if err := sendTCP(r, id, data, ttl, tos, flags, seq, ack, rcvWnd, opts, gso); err != nil {
|
||||
e.stats.SendErrors.SegmentSendToNetworkFailed.Increment()
|
||||
return err
|
||||
}
|
||||
@@ -607,7 +609,7 @@ func (e *endpoint) sendTCP(r *stack.Route, id stack.TransportEndpointID, data bu
|
||||
|
||||
// sendTCP sends a TCP segment with the provided options via the provided
|
||||
// network endpoint and under the provided identity.
|
||||
func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, ttl uint8, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte, gso *stack.GSO) *tcpip.Error {
|
||||
func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, ttl, tos uint8, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte, gso *stack.GSO) *tcpip.Error {
|
||||
optLen := len(opts)
|
||||
// Allocate a buffer for the TCP header.
|
||||
hdr := buffer.NewPrependable(header.TCPMinimumSize + int(r.MaxHeaderLength()) + optLen)
|
||||
@@ -643,7 +645,10 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.Vectorise
|
||||
tcp.SetChecksum(^tcp.CalculateChecksum(xsum))
|
||||
}
|
||||
|
||||
if err := r.WritePacket(gso, hdr, data, ProtocolNumber, ttl, ttl == 0 /* useDefaultTTL */); err != nil {
|
||||
if ttl == 0 {
|
||||
ttl = r.DefaultTTL()
|
||||
}
|
||||
if err := r.WritePacket(gso, hdr, data, stack.NetworkHeaderParams{Protocol: ProtocolNumber, TTL: ttl, TOS: tos}); err != nil {
|
||||
r.Stats().TCP.SegmentSendErrors.Increment()
|
||||
return err
|
||||
}
|
||||
@@ -700,7 +705,7 @@ func (e *endpoint) sendRaw(data buffer.VectorisedView, flags byte, seq, ack seqn
|
||||
sackBlocks = e.sack.Blocks[:e.sack.NumBlocks]
|
||||
}
|
||||
options := e.makeOptions(sackBlocks)
|
||||
err := e.sendTCP(&e.route, e.ID, data, e.ttl, flags, seq, ack, rcvWnd, options, e.gso)
|
||||
err := e.sendTCP(&e.route, e.ID, data, e.ttl, e.sendTOS, flags, seq, ack, rcvWnd, options, e.gso)
|
||||
putOptions(options)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestV4MappedConnectOnV6Only(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testV4Connect(t *testing.T, c *context.Context) {
|
||||
func testV4Connect(t *testing.T, c *context.Context, checkers ...checker.NetworkChecker) {
|
||||
// Start connection attempt.
|
||||
we, ch := waiter.NewChannelEntry(nil)
|
||||
c.WQ.EventRegister(&we, waiter.EventOut)
|
||||
@@ -55,12 +55,11 @@ func testV4Connect(t *testing.T, c *context.Context) {
|
||||
|
||||
// Receive SYN packet.
|
||||
b := c.GetPacket()
|
||||
checker.IPv4(t, b,
|
||||
checker.TCP(
|
||||
checker.DstPort(context.TestPort),
|
||||
checker.TCPFlags(header.TCPFlagSyn),
|
||||
),
|
||||
)
|
||||
synCheckers := append(checkers, checker.TCP(
|
||||
checker.DstPort(context.TestPort),
|
||||
checker.TCPFlags(header.TCPFlagSyn),
|
||||
))
|
||||
checker.IPv4(t, b, synCheckers...)
|
||||
|
||||
tcp := header.TCP(header.IPv4(b).Payload())
|
||||
c.IRS = seqnum.Value(tcp.SequenceNumber())
|
||||
@@ -76,14 +75,13 @@ func testV4Connect(t *testing.T, c *context.Context) {
|
||||
})
|
||||
|
||||
// Receive ACK packet.
|
||||
checker.IPv4(t, c.GetPacket(),
|
||||
checker.TCP(
|
||||
checker.DstPort(context.TestPort),
|
||||
checker.TCPFlags(header.TCPFlagAck),
|
||||
checker.SeqNum(uint32(c.IRS)+1),
|
||||
checker.AckNum(uint32(iss)+1),
|
||||
),
|
||||
)
|
||||
ackCheckers := append(checkers, checker.TCP(
|
||||
checker.DstPort(context.TestPort),
|
||||
checker.TCPFlags(header.TCPFlagAck),
|
||||
checker.SeqNum(uint32(c.IRS)+1),
|
||||
checker.AckNum(uint32(iss)+1),
|
||||
))
|
||||
checker.IPv4(t, c.GetPacket(), ackCheckers...)
|
||||
|
||||
// Wait for connection to be established.
|
||||
select {
|
||||
@@ -152,7 +150,7 @@ func TestV4ConnectWhenBoundToV4Mapped(t *testing.T) {
|
||||
testV4Connect(t, c)
|
||||
}
|
||||
|
||||
func testV6Connect(t *testing.T, c *context.Context) {
|
||||
func testV6Connect(t *testing.T, c *context.Context, checkers ...checker.NetworkChecker) {
|
||||
// Start connection attempt to IPv6 address.
|
||||
we, ch := waiter.NewChannelEntry(nil)
|
||||
c.WQ.EventRegister(&we, waiter.EventOut)
|
||||
@@ -165,12 +163,11 @@ func testV6Connect(t *testing.T, c *context.Context) {
|
||||
|
||||
// Receive SYN packet.
|
||||
b := c.GetV6Packet()
|
||||
checker.IPv6(t, b,
|
||||
checker.TCP(
|
||||
checker.DstPort(context.TestPort),
|
||||
checker.TCPFlags(header.TCPFlagSyn),
|
||||
),
|
||||
)
|
||||
synCheckers := append(checkers, checker.TCP(
|
||||
checker.DstPort(context.TestPort),
|
||||
checker.TCPFlags(header.TCPFlagSyn),
|
||||
))
|
||||
checker.IPv6(t, b, synCheckers...)
|
||||
|
||||
tcp := header.TCP(header.IPv6(b).Payload())
|
||||
c.IRS = seqnum.Value(tcp.SequenceNumber())
|
||||
@@ -186,14 +183,13 @@ func testV6Connect(t *testing.T, c *context.Context) {
|
||||
})
|
||||
|
||||
// Receive ACK packet.
|
||||
checker.IPv6(t, c.GetV6Packet(),
|
||||
checker.TCP(
|
||||
checker.DstPort(context.TestPort),
|
||||
checker.TCPFlags(header.TCPFlagAck),
|
||||
checker.SeqNum(uint32(c.IRS)+1),
|
||||
checker.AckNum(uint32(iss)+1),
|
||||
),
|
||||
)
|
||||
ackCheckers := append(checkers, checker.TCP(
|
||||
checker.DstPort(context.TestPort),
|
||||
checker.TCPFlags(header.TCPFlagAck),
|
||||
checker.SeqNum(uint32(c.IRS)+1),
|
||||
checker.AckNum(uint32(iss)+1),
|
||||
))
|
||||
checker.IPv6(t, c.GetV6Packet(), ackCheckers...)
|
||||
|
||||
// Wait for connection to be established.
|
||||
select {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user