Signed-off-by: Heiko Hund <heiko.h...@sophos.com>
---
 init.c    |    1 +
 openvpn.8 |    6 ++++++
 options.c |   14 ++++++++++++++
 options.h |    3 +++
 socket.c  |   13 +++++++++++++
 socket.h  |    1 +
 6 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/init.c b/init.c
index 0530b10..e8c9aab 100644
--- a/init.c
+++ b/init.c
@@ -2640,6 +2640,7 @@ do_init_socket_1 (struct context *c, const int mode)
                           c->options.mtu_discover_type,
                           c->options.rcvbuf,
                           c->options.sndbuf,
+                          c->options.mark,
                           sockflags);
 }

diff --git a/openvpn.8 b/openvpn.8
index dc76464..55a9b80 100644
--- a/openvpn.8
+++ b/openvpn.8
@@ -1371,6 +1371,12 @@ Set the TCP/UDP socket receive buffer size.
 Currently defaults to 65536 bytes.
 .\"*********************************************************
 .TP
+.B \-\-mark value
+Mark encrypted packets being sent with value. The mark value can be
+matched in policy routing and packetfilter rules. This option is
+only supported in Linux and does nothing on other operating systems.
+.\"*********************************************************
+.TP
 .B \-\-socket-flags flags...
 Apply the given flags to the OpenVPN transport socket.
 Currently, only
diff --git a/options.c b/options.c
index a6230de..d410782 100644
--- a/options.c
+++ b/options.c
@@ -280,6 +280,10 @@ static const char usage_message[] =
   "                  or --fragment max value, whichever is lower.\n"
   "--sndbuf size   : Set the TCP/UDP send buffer size.\n"
   "--rcvbuf size   : Set the TCP/UDP receive buffer size.\n"
+#ifdef TARGET_LINUX
+  "--mark value    : Mark encrypted packets being sent with value. The mark 
value\n"
+  "                  can be matched in policy routing and packetfilter 
rules.\n"
+#endif
   "--txqueuelen n  : Set the tun/tap TX queue length to n (Linux only).\n"
   "--mlock         : Disable Paging -- ensures key material and tunnel\n"
   "                  data will never be written to disk.\n"
@@ -1473,6 +1477,9 @@ show_settings (const struct options *o)
 #endif
   SHOW_INT (rcvbuf);
   SHOW_INT (sndbuf);
+#ifdef TARGET_LINUX
+  SHOW_INT (mark);
+#endif
   SHOW_INT (sockflags);

   SHOW_BOOL (fast_io);
@@ -4520,6 +4527,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_SOCKBUF);
       options->sndbuf = positive_atoi (p[1]);
     }
+  else if (streq (p[0], "mark") && p[1])
+    {
+#ifdef TARGET_LINUX
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->mark = atoi(p[1]);
+#endif
+    }
   else if (streq (p[0], "socket-flags"))
     {
       int j;
diff --git a/options.h b/options.h
index e723b66..d792872 100644
--- a/options.h
+++ b/options.h
@@ -342,6 +342,9 @@ struct options
   int rcvbuf;
   int sndbuf;

+  /* mark value */
+  int mark;
+
   /* socket flags */
   unsigned int sockflags;

diff --git a/socket.c b/socket.c
index 76c760c..a2f9511 100644
--- a/socket.c
+++ b/socket.c
@@ -779,6 +779,15 @@ socket_set_tcp_nodelay (int sd, int state)
 #endif
 }

+static void
+socket_set_mark (int sd, int mark)
+{
+#ifdef TARGET_LINUX
+  if (mark && setsockopt (sd, SOL_SOCKET, SO_MARK, &mark, sizeof (mark)) != 0)
+    msg (M_WARN, "NOTE: setsockopt SO_MARK=%d failed", mark);
+#endif
+}
+
 static bool
 socket_set_flags (int sd, unsigned int sockflags)
 {
@@ -1599,6 +1608,7 @@ link_socket_init_phase1 (struct link_socket *sock,
                         int mtu_discover_type,
                         int rcvbuf,
                         int sndbuf,
+                        int mark,
                         unsigned int sockflags)
 {
   ASSERT (sock);
@@ -1716,6 +1726,9 @@ link_socket_init_phase1 (struct link_socket *sock,
       /* set socket buffers based on --sndbuf and --rcvbuf options */
       socket_set_buffers (sock->sd, &sock->socket_buffer_sizes);

+      /* set socket to --mark packets with given value */
+      socket_set_mark (sock->sd, mark);
+
       resolve_bind_local (sock);
       resolve_remote (sock, 1, NULL, NULL);
     }
diff --git a/socket.h b/socket.h
index b385fb2..a9a29c5 100644
--- a/socket.h
+++ b/socket.h
@@ -324,6 +324,7 @@ link_socket_init_phase1 (struct link_socket *sock,
                         int mtu_discover_type,
                         int rcvbuf,
                         int sndbuf,
+                        int mark,
                         unsigned int sockflags);

 void link_socket_init_phase2 (struct link_socket *sock,
-- 
1.7.4.1


Reply via email to