From: Heiko Hund Date: Wed, 31 Aug 2011 18:05:15 +0000 (+0200) Subject: add --mark option to set SO_MARK sockopt X-Git-Tag: v2.3-alpha1~186 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d90428d141102a646a20b1310de1716621e32bd6;p=thirdparty%2Fopenvpn.git add --mark option to set SO_MARK sockopt Signed-off-by: Heiko Hund Acked-by: David Sommerseth Signed-off-by: David Sommerseth --- diff --git a/init.c b/init.c index 0530b10a7..e8c9aab36 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 dc7646428..55a9b80c0 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 a6230de1a..d410782ac 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 e723b6677..d79287217 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 76c760cd7..a2f9511c1 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 b385fb27a..a9a29c5ba 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,