kernel-netlink: Allow setting firewall marks on routing rule
authorTobias Brunner <tobias@strongswan.org>
Tue, 13 Aug 2013 14:53:06 +0000 (16:53 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 11 Oct 2013 13:32:44 +0000 (15:32 +0200)
man/strongswan.conf.5.in
src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c

index 1df58a7..2af6e73 100644 (file)
@@ -623,6 +623,11 @@ Number of ipsecN devices
 .BR charon.plugins.kernel-klips.ipsec_dev_mtu " [0]"
 Set MTU of ipsecN device
 .TP
+.BR charon.plugins.kernel-netlink.fwmark
+Firewall mark to set on the routing rule that directs traffic to our own routing
+table. The format is [!]mark[/mask], where the optional exclamation mark inverts
+the meaning (i.e. the rule only applies to packets that don't match the mark).
+.TP
 .BR charon.plugins.kernel-netlink.roam_events " [yes]"
 Whether to trigger roam events when interfaces, addresses or routes change
 .TP
index 1b9e0f0..04dc22c 100644 (file)
@@ -44,6 +44,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <net/if.h>
+#include <linux/fib_rules.h>
 
 #include "kernel_netlink_net.h"
 #include "kernel_netlink_shared.h"
@@ -2096,6 +2097,8 @@ static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type,
        struct nlmsghdr *hdr;
        struct rtmsg *msg;
        chunk_t chunk;
+       char *fwmark;
+       mark_t mark;
 
        memset(&request, 0, sizeof(request));
        hdr = (struct nlmsghdr*)request;
@@ -2117,6 +2120,23 @@ static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type,
        chunk = chunk_from_thing(prio);
        netlink_add_attribute(hdr, RTA_PRIORITY, chunk, sizeof(request));
 
+       fwmark = lib->settings->get_str(lib->settings,
+                                       "%s.plugins.kernel-netlink.fwmark", NULL, hydra->daemon);
+       if (fwmark)
+       {
+               if (fwmark[0] == '!')
+               {
+                       msg->rtm_flags |= FIB_RULE_INVERT;
+                       fwmark++;
+               }
+               if (mark_from_string(fwmark, &mark))
+               {
+                       chunk = chunk_from_thing(mark.value);
+                       netlink_add_attribute(hdr, FRA_FWMARK, chunk, sizeof(request));
+                       chunk = chunk_from_thing(mark.mask);
+                       netlink_add_attribute(hdr, FRA_FWMASK, chunk, sizeof(request));
+               }
+       }
        return this->socket->send_ack(this->socket, hdr);
 }