aboutsummaryrefslogtreecommitdiffstats
path: root/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-05-07 11:24:07 +0200
committerTobias Brunner <tobias@strongswan.org>2012-05-07 19:00:47 +0200
commitc732e220190b77ee9882a9ca5360280748c12cc9 (patch)
tree6fb22d27d7cbeb9a2d58c2f7ae2647904d73b8fa /src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
parent5de5b04ce411ed8bb2edc3b8721cf81f0406ff98 (diff)
downloadstrongswan-c732e220190b77ee9882a9ca5360280748c12cc9.tar.bz2
strongswan-c732e220190b77ee9882a9ca5360280748c12cc9.tar.xz
Fix route reinstallation if preferred source IP is not on outgoing interface.
Diffstat (limited to 'src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c')
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c48
1 files changed, 18 insertions, 30 deletions
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
index 4432bec9f..8a5eaa0f7 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
@@ -199,9 +199,6 @@ typedef struct net_change_t net_change_t;
struct net_change_t {
/** Name of the interface that got activated (or an IP appeared on) */
char *if_name;
-
- /** IP that appeared, if any */
- host_t *ip;
};
/**
@@ -209,7 +206,6 @@ struct net_change_t {
*/
static void net_change_destroy(net_change_t *this)
{
- DESTROY_IF(this->ip);
free(this->if_name);
free(this);
}
@@ -219,12 +215,6 @@ static void net_change_destroy(net_change_t *this)
*/
static u_int net_change_hash(net_change_t *this)
{
- if (this->ip)
- {
- return chunk_hash_inc(this->ip->get_address(this->ip),
- chunk_hash(chunk_create(this->if_name,
- strlen(this->if_name))));
- }
return chunk_hash(chunk_create(this->if_name, strlen(this->if_name)));
}
@@ -233,8 +223,7 @@ static u_int net_change_hash(net_change_t *this)
*/
static bool net_change_equals(net_change_t *a, net_change_t *b)
{
- return streq(a->if_name, b->if_name) && ((!a->ip && !b->ip) ||
- (a->ip && b->ip && a->ip->equals(a->ip, b->ip)));
+ return streq(a->if_name, b->if_name);
}
typedef struct private_kernel_netlink_net_t private_kernel_netlink_net_t;
@@ -299,7 +288,7 @@ struct private_kernel_netlink_net_t {
hashtable_t *routes;
/**
- * interface and IP address changes which may trigger route reinstallation
+ * interface changes which may trigger route reinstallation
*/
hashtable_t *net_changes;
@@ -371,12 +360,17 @@ static job_requeue_t reinstall_routes(private_kernel_netlink_net_t *this)
net_change_t *change, lookup = {
.if_name = route->if_name,
};
- /* check if a generic change for this interface is queued */
+ /* check if a change for the outgoing interface is queued */
change = this->net_changes->get(this->net_changes, &lookup);
if (!change)
- { /* check if a specific update for this IP is queued */
- lookup.ip = route->src_ip;
- change = this->net_changes->get(this->net_changes, &lookup);
+ { /* in case src_ip is not on the outgoing interface */
+ lookup.if_name = this->public.interface.get_interface(
+ &this->public.interface, route->src_ip);
+ if (lookup.if_name && !streq(lookup.if_name, route->if_name))
+ {
+ change = this->net_changes->get(this->net_changes, &lookup);
+ }
+ free(lookup.if_name);
}
if (change)
{
@@ -395,33 +389,27 @@ static job_requeue_t reinstall_routes(private_kernel_netlink_net_t *this)
/**
* Queue route reinstallation caused by network changes for a given interface.
- * Provide the IP address if the update is caused by an IP address change.
*
* The route reinstallation is delayed for a while and only done once for
* several calls during this delay, in order to avoid doing it too often.
- * The interface name and IP address are freed.
+ * The interface name is freed.
*/
static void queue_route_reinstall(private_kernel_netlink_net_t *this,
- char *if_name, host_t *ip)
+ char *if_name)
{
net_change_t *update, *found;
timeval_t now;
job_t *job;
INIT(update,
- .if_name = if_name,
- .ip = ip
+ .if_name = if_name
);
this->net_changes_lock->lock(this->net_changes_lock);
- found = this->net_changes->get(this->net_changes, update);
+ found = this->net_changes->put(this->net_changes, update, update);
if (found)
{
- net_change_destroy(update);
- }
- else
- {
- this->net_changes->put(this->net_changes, update, update);
+ net_change_destroy(found);
}
time_monotonic(&now);
if (timercmp(&now, &this->last_route_reinstall, >))
@@ -646,7 +634,7 @@ static void process_link(private_kernel_netlink_net_t *this,
if (update_routes && event)
{
- queue_route_reinstall(this, strdup(name), NULL);
+ queue_route_reinstall(this, strdup(name));
}
/* send an update to all IKE_SAs */
@@ -769,7 +757,7 @@ static void process_addr(private_kernel_netlink_net_t *this,
if (update && event && route_ifname)
{
- queue_route_reinstall(this, route_ifname, host->clone(host));
+ queue_route_reinstall(this, route_ifname);
}
else
{