summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/udp
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tcpip/transport/udp')
-rw-r--r--pkg/tcpip/transport/udp/endpoint.go24
-rw-r--r--pkg/tcpip/transport/udp/udp_state_autogen.go47
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)
}