11/* SPDX-License-Identifier: MIT
22 *
3- * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
3+ * Copyright (C) 2017-2025 WireGuard LLC. All Rights Reserved.
44 */
55
66package conn
@@ -13,6 +13,35 @@ import (
1313 "golang.org/x/sys/unix"
1414)
1515
16+ // Taken from go/src/internal/syscall/unix/kernel_version_linux.go
17+ func kernelVersion () (major , minor int ) {
18+ var uname unix.Utsname
19+ if err := unix .Uname (& uname ); err != nil {
20+ return
21+ }
22+
23+ var (
24+ values [2 ]int
25+ value , vi int
26+ )
27+ for _ , c := range uname .Release {
28+ if '0' <= c && c <= '9' {
29+ value = (value * 10 ) + int (c - '0' )
30+ } else {
31+ // Note that we're assuming N.N.N here.
32+ // If we see anything else, we are likely to mis-parse it.
33+ values [vi ] = value
34+ vi ++
35+ if vi >= len (values ) {
36+ break
37+ }
38+ value = 0
39+ }
40+ }
41+
42+ return values [0 ], values [1 ]
43+ }
44+
1645func init () {
1746 controlFns = append (controlFns ,
1847
@@ -57,5 +86,24 @@ func init() {
5786 }
5887 return err
5988 },
89+
90+ // Attempt to enable UDP_GRO
91+ func (network , address string , c syscall.RawConn ) error {
92+ // Kernels below 5.12 are missing 98184612aca0 ("net:
93+ // udp: Add support for getsockopt(..., ..., UDP_GRO,
94+ // ..., ...);"), which means we can't read this back
95+ // later. We could pipe the return value through to
96+ // the rest of the code, but UDP_GRO is kind of buggy
97+ // anyway, so just gate this here.
98+ major , minor := kernelVersion ()
99+ if major < 5 || (major == 5 && minor < 12 ) {
100+ return nil
101+ }
102+
103+ c .Control (func (fd uintptr ) {
104+ _ = unix .SetsockoptInt (int (fd ), unix .IPPROTO_UDP , unix .UDP_GRO , 1 )
105+ })
106+ return nil
107+ },
60108 )
61109}
0 commit comments