diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-05-07 11:24:07 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-05-07 19:00:47 +0200 |
commit | c732e220190b77ee9882a9ca5360280748c12cc9 (patch) | |
tree | 6fb22d27d7cbeb9a2d58c2f7ae2647904d73b8fa /src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c | |
parent | 5de5b04ce411ed8bb2edc3b8721cf81f0406ff98 (diff) | |
download | strongswan-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.c | 48 |
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 { |