diff options
Diffstat (limited to 'pkg/tcpip/transport/udp')
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 24 | ||||
-rw-r--r-- | pkg/tcpip/transport/udp/udp_state_autogen.go | 47 |
2 files changed, 45 insertions, 26 deletions
diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 8bdc1ee1f..cae29fbff 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -109,6 +109,7 @@ type endpoint struct { portFlags ports.Flags bindToDevice tcpip.NICID broadcast bool + noChecksum bool lastErrorMu sync.Mutex `state:"nosave"` lastError *tcpip.Error `state:".(string)"` @@ -529,7 +530,7 @@ func (e *endpoint) write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, <-c useDefaultTTL = false } - if err := sendUDP(route, buffer.View(v).ToVectorisedView(), e.ID.LocalPort, dstPort, ttl, useDefaultTTL, e.sendTOS, e.owner); err != nil { + if err := sendUDP(route, buffer.View(v).ToVectorisedView(), e.ID.LocalPort, dstPort, ttl, useDefaultTTL, e.sendTOS, e.owner, e.noChecksum); err != nil { return 0, nil, err } return int64(len(v)), nil, nil @@ -553,6 +554,11 @@ func (e *endpoint) SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error { e.multicastLoop = v e.mu.Unlock() + case tcpip.NoChecksumOption: + e.mu.Lock() + e.noChecksum = v + e.mu.Unlock() + case tcpip.ReceiveTOSOption: e.mu.Lock() e.receiveTOS = v @@ -825,6 +831,12 @@ func (e *endpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) { e.mu.RUnlock() return v, nil + case tcpip.NoChecksumOption: + e.mu.RLock() + v := e.noChecksum + e.mu.RUnlock() + return v, nil + case tcpip.ReceiveTOSOption: e.mu.RLock() v := e.receiveTOS @@ -959,7 +971,7 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { // sendUDP sends a UDP segment via the provided network endpoint and under the // provided identity. -func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, ttl uint8, useDefaultTTL bool, tos uint8, owner tcpip.PacketOwner) *tcpip.Error { +func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, ttl uint8, useDefaultTTL bool, tos uint8, owner tcpip.PacketOwner, noChecksum bool) *tcpip.Error { // Allocate a buffer for the UDP header. hdr := buffer.NewPrependable(header.UDPMinimumSize + int(r.MaxHeaderLength())) @@ -973,8 +985,12 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u Length: length, }) - // Only calculate the checksum if offloading isn't supported. - if r.Capabilities()&stack.CapabilityTXChecksumOffload == 0 { + // Set the checksum field unless TX checksum offload is enabled. + // On IPv4, UDP checksum is optional, and a zero value indicates the + // transmitter skipped the checksum generation (RFC768). + // On IPv6, UDP checksum is not optional (RFC2460 Section 8.1). + if r.Capabilities()&stack.CapabilityTXChecksumOffload == 0 && + (!noChecksum || r.NetProto == header.IPv6ProtocolNumber) { xsum := r.PseudoHeaderChecksum(ProtocolNumber, length) for _, v := range data.Views() { xsum = header.Checksum(v, xsum) diff --git a/pkg/tcpip/transport/udp/udp_state_autogen.go b/pkg/tcpip/transport/udp/udp_state_autogen.go index 943022c38..50fd0f186 100644 --- a/pkg/tcpip/transport/udp/udp_state_autogen.go +++ b/pkg/tcpip/transport/udp/udp_state_autogen.go @@ -73,6 +73,7 @@ func (x *endpoint) StateFields() []string { "portFlags", "bindToDevice", "broadcast", + "noChecksum", "lastError", "boundBindToDevice", "boundPortFlags", @@ -92,7 +93,7 @@ func (x *endpoint) StateSave(m state.Sink) { var rcvBufSizeMax int = x.saveRcvBufSizeMax() m.SaveValue(5, rcvBufSizeMax) var lastError string = x.saveLastError() - m.SaveValue(21, lastError) + m.SaveValue(22, lastError) m.Save(0, &x.TransportEndpointInfo) m.Save(1, &x.waiterQueue) m.Save(2, &x.uniqueID) @@ -113,16 +114,17 @@ func (x *endpoint) StateSave(m state.Sink) { m.Save(18, &x.portFlags) m.Save(19, &x.bindToDevice) m.Save(20, &x.broadcast) - m.Save(22, &x.boundBindToDevice) - m.Save(23, &x.boundPortFlags) - m.Save(24, &x.sendTOS) - m.Save(25, &x.receiveTOS) - m.Save(26, &x.receiveTClass) - m.Save(27, &x.receiveIPPacketInfo) - m.Save(28, &x.shutdownFlags) - m.Save(29, &x.multicastMemberships) - m.Save(30, &x.effectiveNetProtos) - m.Save(31, &x.owner) + m.Save(21, &x.noChecksum) + m.Save(23, &x.boundBindToDevice) + m.Save(24, &x.boundPortFlags) + m.Save(25, &x.sendTOS) + m.Save(26, &x.receiveTOS) + m.Save(27, &x.receiveTClass) + m.Save(28, &x.receiveIPPacketInfo) + m.Save(29, &x.shutdownFlags) + m.Save(30, &x.multicastMemberships) + m.Save(31, &x.effectiveNetProtos) + m.Save(32, &x.owner) } func (x *endpoint) StateLoad(m state.Source) { @@ -146,18 +148,19 @@ func (x *endpoint) StateLoad(m state.Source) { m.Load(18, &x.portFlags) m.Load(19, &x.bindToDevice) m.Load(20, &x.broadcast) - m.Load(22, &x.boundBindToDevice) - m.Load(23, &x.boundPortFlags) - m.Load(24, &x.sendTOS) - m.Load(25, &x.receiveTOS) - m.Load(26, &x.receiveTClass) - m.Load(27, &x.receiveIPPacketInfo) - m.Load(28, &x.shutdownFlags) - m.Load(29, &x.multicastMemberships) - m.Load(30, &x.effectiveNetProtos) - m.Load(31, &x.owner) + m.Load(21, &x.noChecksum) + m.Load(23, &x.boundBindToDevice) + m.Load(24, &x.boundPortFlags) + m.Load(25, &x.sendTOS) + m.Load(26, &x.receiveTOS) + m.Load(27, &x.receiveTClass) + m.Load(28, &x.receiveIPPacketInfo) + m.Load(29, &x.shutdownFlags) + m.Load(30, &x.multicastMemberships) + m.Load(31, &x.effectiveNetProtos) + m.Load(32, &x.owner) m.LoadValue(5, new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) - m.LoadValue(21, new(string), func(y interface{}) { x.loadLastError(y.(string)) }) + m.LoadValue(22, new(string), func(y interface{}) { x.loadLastError(y.(string)) }) m.AfterLoad(x.afterLoad) } |