mark_unix.go raw
1 //go:build linux || openbsd || freebsd
2
3 /* SPDX-License-Identifier: MIT
4 *
5 * Copyright (C) 2017-2025 WireGuard LLC. All Rights Reserved.
6 */
7
8 package conn
9
10 import (
11 "runtime"
12
13 "golang.org/x/sys/unix"
14 )
15
16 var fwmarkIoctl int
17
18 func init() {
19 switch runtime.GOOS {
20 case "linux", "android":
21 fwmarkIoctl = 36 /* unix.SO_MARK */
22 case "freebsd":
23 fwmarkIoctl = 0x1015 /* unix.SO_USER_COOKIE */
24 case "openbsd":
25 fwmarkIoctl = 0x1021 /* unix.SO_RTABLE */
26 }
27 }
28
29 func (s *StdNetBind) SetMark(mark uint32) error {
30 var operr error
31 if fwmarkIoctl == 0 {
32 return nil
33 }
34 if s.ipv4 != nil {
35 fd, err := s.ipv4.SyscallConn()
36 if err != nil {
37 return err
38 }
39 err = fd.Control(func(fd uintptr) {
40 operr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
41 })
42 if err == nil {
43 err = operr
44 }
45 if err != nil {
46 return err
47 }
48 }
49 if s.ipv6 != nil {
50 fd, err := s.ipv6.SyscallConn()
51 if err != nil {
52 return err
53 }
54 err = fd.Control(func(fd uintptr) {
55 operr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
56 })
57 if err == nil {
58 err = operr
59 }
60 if err != nil {
61 return err
62 }
63 }
64 return nil
65 }
66