diff options
author | Thomas Egerer <thomas.egerer@secunet.com> | 2010-03-12 09:37:51 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-03-17 10:08:02 +0100 |
commit | d266e8953e585a8e32910b653f86547acdcf9743 (patch) | |
tree | b025c069fb1d94df6e99831ec747a967171d30ea /src/charon/plugins/kernel_netlink/kernel_netlink_net.c | |
parent | 7b1fc2f7cfd40147d1d74601a41ea6df34131a3b (diff) | |
download | strongswan-d266e8953e585a8e32910b653f86547acdcf9743.tar.bz2 strongswan-d266e8953e585a8e32910b653f86547acdcf9743.tar.xz |
lookup exclusion for several arbitrary routing tables
Diffstat (limited to 'src/charon/plugins/kernel_netlink/kernel_netlink_net.c')
-rw-r--r-- | src/charon/plugins/kernel_netlink/kernel_netlink_net.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_net.c b/src/charon/plugins/kernel_netlink/kernel_netlink_net.c index e1ba4a859..6750458cf 100644 --- a/src/charon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/charon/plugins/kernel_netlink/kernel_netlink_net.c @@ -14,6 +14,29 @@ * for more details. */ +/* + * Copyright (C) 2010 secunet Security Networks AG + * Copyright (C) 2010 Thomas Egerer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <sys/socket.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> @@ -158,6 +181,11 @@ struct private_kernel_netlink_net_t { * whether to actually install virtual IPs */ bool install_virtual_ip; + + /** + * list with routing tables to be excluded from route lookup + */ + linked_list_t *rt_exclude; }; /** @@ -764,6 +792,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, chunk_t chunk; size_t len; int best = -1; + enumerator_t *enumerator; host_t *src = NULL, *gtw = NULL; DBG2(DBG_KNL, "getting address to reach %H", dest); @@ -813,6 +842,8 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, chunk_t rta_gtw, rta_src, rta_dst; u_int32_t rta_oif = 0; host_t *new_src, *new_gtw; + bool cont = FALSE; + uintptr_t table; rta_gtw = rta_src = rta_dst = chunk_empty; msg = (struct rtmsg*)(NLMSG_DATA(current)); @@ -844,6 +875,20 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, { /* not better than a previous one */ continue; } + enumerator = this->rt_exclude->create_enumerator(this->rt_exclude); + while (enumerator->enumerate(enumerator, &table)) + { + if (table == msg->rtm_table) + { + cont = TRUE; + break; + } + } + enumerator->destroy(enumerator); + if (cont) + { + continue; + } if (this->routing_table != 0 && msg->rtm_table == this->routing_table) { /* route is from our own ipsec routing table */ @@ -1346,6 +1391,7 @@ static void destroy(private_kernel_netlink_net_t *this) } DESTROY_IF(this->socket); this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy); + this->rt_exclude->destroy(this->rt_exclude); this->condvar->destroy(this->condvar); this->mutex->destroy(this->mutex); free(this); @@ -1358,6 +1404,8 @@ kernel_netlink_net_t *kernel_netlink_net_create() { private_kernel_netlink_net_t *this = malloc_thing(private_kernel_netlink_net_t); struct sockaddr_nl addr; + enumerator_t *enumerator; + char *exclude; /* public functions */ this->public.interface.get_interface = (char*(*)(kernel_net_t*,host_t*))get_interface_name; @@ -1384,6 +1432,28 @@ kernel_netlink_net_t *kernel_netlink_net_create() this->install_virtual_ip = lib->settings->get_bool(lib->settings, "charon.install_virtual_ip", TRUE); + this->rt_exclude = linked_list_create(); + exclude = lib->settings->get_str(lib->settings, + "charon.ignore_routing_tables", NULL); + if (exclude) + { + char *token; + uintptr_t table; + + enumerator = enumerator_create_token(exclude, " ", " "); + while (enumerator->enumerate(enumerator, &token)) + { + errno = 0; + table = strtoul(token, NULL, 10); + + if (errno == 0) + { + this->rt_exclude->insert_last(this->rt_exclude, (void*)table); + } + } + enumerator->destroy(enumerator); + } + this->socket = netlink_socket_create(NETLINK_ROUTE); this->job = NULL; |