diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-09-20 11:07:15 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-09-21 18:16:26 +0200 |
commit | e8e9048fee2fb1df1eb995f7ee0439c4ce27a783 (patch) | |
tree | 43fe68817723b3d5a61196db372cfd822d3d2e43 /src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c | |
parent | c6b401581a756067d68bf637315503e32842721b (diff) | |
download | strongswan-e8e9048fee2fb1df1eb995f7ee0439c4ce27a783.tar.bz2 strongswan-e8e9048fee2fb1df1eb995f7ee0439c4ce27a783.tar.xz |
Added an option to configure the interface on which virtual IP addresses are installed
Diffstat (limited to 'src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c')
-rw-r--r-- | src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c index fb3899ec6..e4a880ab9 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c @@ -76,7 +76,7 @@ struct addr_entry_t { /** scope of the address */ u_char scope; - /** number of times this IP is used, if virtual (> 0 IP is managed by us) */ + /** number of times this IP is used, if virtual (i.e. managed by us) */ u_int refcount; /** TRUE once it is installed, if virtual */ @@ -418,6 +418,11 @@ struct private_kernel_netlink_net_t { bool install_virtual_ip; /** + * the name of the interface virtual IP addresses are installed on + */ + char *install_virtual_ip_on; + + /** * whether preferred source addresses can be specified for IPv6 routes */ bool rta_prefsrc_for_ipv6; @@ -725,7 +730,7 @@ static bool is_interface_up_and_usable(private_kernel_netlink_net_t *this, * * this->mutex must be locked when calling this function */ -static void unregister_addr_entry(addr_entry_t *addr, iface_entry_t *iface, +static void addr_entry_unregister(addr_entry_t *addr, iface_entry_t *iface, private_kernel_netlink_net_t *this) { if (addr->refcount) @@ -817,7 +822,7 @@ static void process_link(private_kernel_netlink_net_t *this, * another interface? */ this->ifaces->remove_at(this->ifaces, enumerator); current->addrs->invoke_function(current->addrs, - (void*)unregister_addr_entry, current, this); + (void*)addr_entry_unregister, current, this); iface_entry_destroy(current); break; } @@ -1649,14 +1654,13 @@ METHOD(kernel_net_t, add_ip, status_t, addr_map_entry_t *entry, lookup = { .ip = virtual_ip, }; - iface_entry_t *iface; + iface_entry_t *iface = NULL; if (!this->install_virtual_ip) { /* disabled by config */ return SUCCESS; } - DBG2(DBG_KNL, "adding virtual IP %H", virtual_ip); this->mutex->lock(this->mutex); /* the virtual IP might actually be installed as regular IP, in which case * we don't track it as virtual IP */ @@ -1671,8 +1675,8 @@ METHOD(kernel_net_t, add_ip, status_t, * ready, 2) just added by another thread, but not yet confirmed to * be installed by the kernel, 3) just deleted, but not yet gone. * Then while we wait below, several things could happen (as we - * release the mutex). For instance, the interface could disappear. - * Or the IP is finally deleted, and it reappears on a different + * release the mutex). For instance, the interface could disappear, + * or the IP is finally deleted, and it reappears on a different * interface. All these cases are handled by the call below. */ while (!is_vip_installed_or_gone(this, virtual_ip, &entry)) { @@ -1691,21 +1695,23 @@ METHOD(kernel_net_t, add_ip, status_t, this->mutex->unlock(this->mutex); return SUCCESS; } - /* try to find the target interface */ - lookup.ip = iface_ip; - entry = this->addrs->get_match(this->addrs, &lookup, - (void*)addr_map_entry_match); - if (!entry) - { /* if we don't find the requested interface we just use the first */ - if (this->ifaces->get_first(this->ifaces, (void**)&iface) != SUCCESS) + /* try to find the target interface, either by config or via src ip */ + if (!this->install_virtual_ip_on || + this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, + (void**)&iface, this->install_virtual_ip_on) != SUCCESS) + { + lookup.ip = iface_ip; + entry = this->addrs->get_match(this->addrs, &lookup, + (void*)addr_map_entry_match); + if (!entry) + { /* if we don't find the requested interface we just use the first */ + this->ifaces->get_first(this->ifaces, (void**)&iface); + } + else { - iface = NULL; + iface = entry->iface; } } - else - { - iface = entry->iface; - } if (iface) { addr_entry_t *addr; @@ -1726,6 +1732,8 @@ METHOD(kernel_net_t, add_ip, status_t, } if (entry) { /* we fail if the interface got deleted in the meantime */ + DBG2(DBG_KNL, "virtual IP %H installed on %s", virtual_ip, + entry->iface->ifname); this->mutex->unlock(this->mutex); return SUCCESS; } @@ -2186,6 +2194,8 @@ kernel_netlink_net_t *kernel_netlink_net_create() "%s.process_route", TRUE, hydra->daemon), .install_virtual_ip = lib->settings->get_bool(lib->settings, "%s.install_virtual_ip", TRUE, hydra->daemon), + .install_virtual_ip_on = lib->settings->get_str(lib->settings, + "%s.install_virtual_ip_on", NULL, hydra->daemon), ); timerclear(&this->last_route_reinstall); timerclear(&this->last_roam); |