瀏覽代碼

add so_mark sockopt support (#1331)

jampe 4 月之前
父節點
當前提交
1d3c85338c
共有 2 個文件被更改,包括 29 次插入0 次删除
  1. 5 0
      examples/config.yml
  2. 24 0
      udp/udp_linux.go

+ 5 - 0
examples/config.yml

@@ -144,6 +144,11 @@ listen:
   # valid values: always, never, private
   # This setting is reloadable.
   #send_recv_error: always
+  # The so_sock option is a Linux-specific feature that allows all outgoing Nebula packets to be tagged with a specific identifier.
+  # This tagging enables IP rule-based filtering. For example, it supports 0.0.0.0/0 unsafe_routes,
+  # allowing for more precise routing decisions based on the packet tags. Default is 0 meaning no mark is set.
+  # This setting is reloadable.
+  #so_mark: 0
 
 # Routines is the number of thread pairs to run that consume from the tun and UDP queues.
 # Currently, this defaults to 1 which means we have 1 tun queue reader and 1

+ 24 - 0
udp/udp_linux.go

@@ -84,6 +84,10 @@ func (u *StdConn) SetSendBuffer(n int) error {
 	return unix.SetsockoptInt(u.sysFd, unix.SOL_SOCKET, unix.SO_SNDBUFFORCE, n)
 }
 
+func (u *StdConn) SetSoMark(mark int) error {
+	return unix.SetsockoptInt(u.sysFd, unix.SOL_SOCKET, unix.SO_MARK, mark)
+}
+
 func (u *StdConn) GetRecvBuffer() (int, error) {
 	return unix.GetsockoptInt(int(u.sysFd), unix.SOL_SOCKET, unix.SO_RCVBUF)
 }
@@ -92,6 +96,10 @@ func (u *StdConn) GetSendBuffer() (int, error) {
 	return unix.GetsockoptInt(int(u.sysFd), unix.SOL_SOCKET, unix.SO_SNDBUF)
 }
 
+func (u *StdConn) GetSoMark() (int, error) {
+	return unix.GetsockoptInt(int(u.sysFd), unix.SOL_SOCKET, unix.SO_MARK)
+}
+
 func (u *StdConn) LocalAddr() (netip.AddrPort, error) {
 	sa, err := unix.Getsockname(u.sysFd)
 	if err != nil {
@@ -270,6 +278,22 @@ func (u *StdConn) ReloadConfig(c *config.C) {
 			u.l.WithError(err).Error("Failed to set listen.write_buffer")
 		}
 	}
+
+	b = c.GetInt("listen.so_mark", 0)
+	s, err := u.GetSoMark()
+	if b > 0 || (err == nil && s != 0) {
+		err := u.SetSoMark(b)
+		if err == nil {
+			s, err := u.GetSoMark()
+			if err == nil {
+				u.l.WithField("mark", s).Info("listen.so_mark was set")
+			} else {
+				u.l.WithError(err).Warn("Failed to get listen.so_mark")
+			}
+		} else {
+			u.l.WithError(err).Error("Failed to set listen.so_mark")
+		}
+	}
 }
 
 func (u *StdConn) getMemInfo(meminfo *[unix.SK_MEMINFO_VARS]uint32) error {