]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
Add support for fwmark on linux
authorMathias Hall-Andersen <mathias@hall-andersen.dk>
Tue, 22 Aug 2017 15:22:45 +0000 (17:22 +0200)
committerMathias Hall-Andersen <mathias@hall-andersen.dk>
Tue, 22 Aug 2017 15:22:45 +0000 (17:22 +0200)
src/config.go
src/conn.go
src/device.go
src/tun.go

index 474134b933369fcf96f6ef7f078a84ab5406c6dd..871232cd24371d04fe925f71d259bd094af0dd64 100644 (file)
@@ -145,10 +145,10 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
                                        return &IPCError{Code: ipcErrorInvalid}
                                }
 
-                               netc := &device.net
-                               netc.mutex.Lock()
-                               netc.addr = addr
-                               netc.mutex.Unlock()
+                               device.net.mutex.Lock()
+                               device.net.addr = addr
+                               device.net.mutex.Unlock()
+
                                err = updateUDPConn(device)
                                if err != nil {
                                        logError.Println("Failed to set listen_port:", err)
@@ -158,7 +158,24 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
                                // TODO: Clear source address of all peers
 
                        case "fwmark":
-                               logError.Println("FWMark not handled yet")
+                               fwmark, err := strconv.ParseInt(value, 10, 32)
+                               if err != nil {
+                                       logError.Println("Invalid fwmark", err)
+                                       return &IPCError{Code: ipcErrorInvalid}
+                               }
+
+                               device.net.mutex.Lock()
+                               device.net.fwmark = int(fwmark)
+                               err = setMark(
+                                       device.net.conn,
+                                       device.net.fwmark,
+                               )
+                               device.net.mutex.Unlock()
+                               if err != nil {
+                                       logError.Println("Failed to set fwmark:", err)
+                                       return &IPCError{Code: ipcErrorIO}
+                               }
+
                                // TODO: Clear source address of all peers
 
                        case "public_key":
index e23b3506f25b552aeb1046c68a8a85899b6f687b..7b35829f83a0889b6689c9abef4fb892295980cd 100644 (file)
@@ -13,6 +13,7 @@ func updateUDPConn(device *Device) error {
 
        if netc.conn != nil {
                netc.conn.Close()
+               netc.conn = nil
        }
 
        // open new connection
@@ -26,11 +27,24 @@ func updateUDPConn(device *Device) error {
                        return err
                }
 
+               // set fwmark
+
+               err = setMark(netc.conn, netc.fwmark)
+               if err != nil {
+                       return err
+               }
+
                // retrieve port (may have been chosen by kernel)
 
                addr := conn.LocalAddr()
                netc.conn = conn
-               netc.addr, _ = net.ResolveUDPAddr(addr.Network(), addr.String())
+               netc.addr, _ = net.ResolveUDPAddr(
+                       addr.Network(),
+                       addr.String(),
+               )
+
+               // notify goroutines
+
                signalSend(device.signal.newUDPConn)
        }
 
index 2a0d0ca5881ab6170f90a50dae31ca80776010a3..2ead76895ca2ecafe86cb2d616947b1642d810fd 100644 (file)
@@ -21,9 +21,10 @@ type Device struct {
                messageBuffers sync.Pool
        }
        net struct {
-               mutex sync.RWMutex
-               addr  *net.UDPAddr // UDP source address
-               conn  *net.UDPConn // UDP "connection"
+               mutex  sync.RWMutex
+               addr   *net.UDPAddr // UDP source address
+               conn   *net.UDPConn // UDP "connection"
+               fwmark int
        }
        mutex        sync.RWMutex
        privateKey   NoisePrivateKey
index b4fbc62cba3a525167c586230e54b79da9d33bca..8e8c759ff1ec0050744d7d99b1655a3b96f80d7e 100644 (file)
@@ -34,28 +34,28 @@ func (device *Device) RoutineTUNEventReader() {
                        if err != nil {
                                logError.Println("Failed to load updated MTU of device:", err)
                        } else if int(old) != mtu {
-                               atomic.StoreInt32(&device.tun.mtu, int32(mtu))
                                if mtu+MessageTransportSize > MaxMessageSize {
                                        logInfo.Println("MTU updated:", mtu, "(too large)")
                                } else {
                                        logInfo.Println("MTU updated:", mtu)
                                }
+                               atomic.StoreInt32(&device.tun.mtu, int32(mtu))
                        }
                }
 
                if event&TUNEventUp != 0 {
                        if !device.tun.isUp.Get() {
+                               logInfo.Println("Interface set up")
                                device.tun.isUp.Set(true)
                                updateUDPConn(device)
-                               logInfo.Println("Interface set up")
                        }
                }
 
                if event&TUNEventDown != 0 {
                        if device.tun.isUp.Get() {
+                               logInfo.Println("Interface set down")
                                device.tun.isUp.Set(false)
                                closeUDPConn(device)
-                               logInfo.Println("Interface set down")
                        }
                }
        }