From 9ba36c0f7f68af814c9805ec8ac11d2f3ae2f5d7 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 14 Sep 2012 16:27:33 +0200 Subject: [PATCH] Make it easy to check if an address is locally usable via changed get_interface() method --- src/libcharon/plugins/stroke/stroke_config.c | 22 ++++------ .../plugins/updown/updown_listener.c | 5 +-- src/libhydra/kernel/kernel_interface.c | 6 +-- src/libhydra/kernel/kernel_interface.h | 5 ++- src/libhydra/kernel/kernel_net.h | 5 ++- .../plugins/kernel_klips/kernel_klips_ipsec.c | 6 +-- .../kernel_netlink/kernel_netlink_ipsec.c | 7 ++-- .../kernel_netlink/kernel_netlink_net.c | 40 ++++++++++--------- .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 7 ++-- .../kernel_pfroute/kernel_pfroute_net.c | 28 +++++++------ 10 files changed, 64 insertions(+), 67 deletions(-) diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index da3459b5e..e43672b18 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -191,42 +191,34 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg { stroke_end_t tmp_end; ike_cfg_t *ike_cfg; - char *interface; host_t *host; u_int16_t ikeport; host = host_create_from_dns(msg->add_conn.other.address, 0, 0); if (host) { - interface = hydra->kernel_interface->get_interface( - hydra->kernel_interface, host); - host->destroy(host); - if (interface) + if (hydra->kernel_interface->get_interface(hydra->kernel_interface, + host, NULL)) { DBG2(DBG_CFG, "left is other host, swapping ends"); tmp_end = msg->add_conn.me; msg->add_conn.me = msg->add_conn.other; msg->add_conn.other = tmp_end; - free(interface); + host->destroy(host); } else { + host->destroy(host); host = host_create_from_dns(msg->add_conn.me.address, 0, 0); if (host) { - interface = hydra->kernel_interface->get_interface( - hydra->kernel_interface, host); - host->destroy(host); - if (!interface) + if (!hydra->kernel_interface->get_interface( + hydra->kernel_interface, host, NULL)) { DBG1(DBG_CFG, "left nor right host is our side, " "assuming left=local"); } - else - { - free(interface); - } - + host->destroy(host); } } } diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c index 2f9f2ef91..8b2af05b6 100644 --- a/src/libcharon/plugins/updown/updown_listener.c +++ b/src/libcharon/plugins/updown/updown_listener.c @@ -267,9 +267,8 @@ METHOD(listener_t, child_updown, bool, if (up) { - iface = hydra->kernel_interface->get_interface( - hydra->kernel_interface, me); - if (iface) + if (hydra->kernel_interface->get_interface(hydra->kernel_interface, + me, &iface)) { cache_iface(this, child_sa->get_reqid(child_sa), iface); } diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c index 8e3f6a666..7bdc0bed8 100644 --- a/src/libhydra/kernel/kernel_interface.c +++ b/src/libhydra/kernel/kernel_interface.c @@ -291,14 +291,14 @@ METHOD(kernel_interface_t, get_nexthop, host_t*, return this->net->get_nexthop(this->net, dest, src); } -METHOD(kernel_interface_t, get_interface, char*, - private_kernel_interface_t *this, host_t *host) +METHOD(kernel_interface_t, get_interface, bool, + private_kernel_interface_t *this, host_t *host, char **name) { if (!this->net) { return NULL; } - return this->net->get_interface(this->net, host); + return this->net->get_interface(this->net, host, name); } METHOD(kernel_interface_t, create_address_enumerator, enumerator_t*, diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h index 5396dad99..842b51102 100644 --- a/src/libhydra/kernel/kernel_interface.h +++ b/src/libhydra/kernel/kernel_interface.h @@ -308,9 +308,10 @@ struct kernel_interface_t { * Get the interface name of a local address. * * @param host address to get interface name from - * @return allocated interface name, or NULL if not found + * @param name allocated interface name (optional) + * @return TRUE if interface found and usable */ - char* (*get_interface) (kernel_interface_t *this, host_t *host); + bool (*get_interface) (kernel_interface_t *this, host_t *host, char **name); /** * Creates an enumerator over all local addresses. diff --git a/src/libhydra/kernel/kernel_net.h b/src/libhydra/kernel/kernel_net.h index 772ccacd5..4edd8da04 100644 --- a/src/libhydra/kernel/kernel_net.h +++ b/src/libhydra/kernel/kernel_net.h @@ -68,9 +68,10 @@ struct kernel_net_t { * Get the interface name of a local address. * * @param host address to get interface name from - * @return allocated interface name, or NULL if not found + * @param name allocated interface name (optional) + * @return TRUE if interface found and usable */ - char* (*get_interface) (kernel_net_t *this, host_t *host); + bool (*get_interface) (kernel_net_t *this, host_t *host, char **name); /** * Creates an enumerator over all local addresses. diff --git a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c index ac1122d16..d875dab04 100644 --- a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c +++ b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c @@ -2108,7 +2108,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t, */ if (policy->route == NULL && direction == POLICY_OUT) { - char *iface; + char *iface = NULL; ipsec_dev_t *dev; route_entry_t *route = malloc_thing(route_entry_t); route->src_ip = NULL; @@ -2126,8 +2126,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t, } /* find the virtual interface */ - iface = hydra->kernel_interface->get_interface(hydra->kernel_interface, - src); + hydra->kernel_interface->get_interface(hydra->kernel_interface, + src, &iface); if (find_ipsec_dev(this, iface, &dev) == SUCCESS) { /* above, we got either the name of a virtual or a physical diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c index 31ca71718..cfd85a5e7 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -2169,14 +2169,13 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this, route->gateway = hydra->kernel_interface->get_nexthop( hydra->kernel_interface, ipsec->src, ipsec->dst); - /* install route via outgoing interface */ - route->if_name = hydra->kernel_interface->get_interface( - hydra->kernel_interface, ipsec->dst); route->dst_net = chunk_alloc(policy->sel.family == AF_INET ? 4 : 16); memcpy(route->dst_net.ptr, &policy->sel.saddr, route->dst_net.len); route->prefixlen = policy->sel.prefixlen_s; - if (!route->if_name) + /* install route via outgoing interface */ + if (!hydra->kernel_interface->get_interface(hydra->kernel_interface, + ipsec->dst, &route->if_name)) { this->mutex->unlock(this->mutex); route_entry_destroy(route); diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c index 52671a205..b4eabb2e9 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c @@ -365,13 +365,15 @@ static job_requeue_t reinstall_routes(private_kernel_netlink_net_t *this) change = this->net_changes->get(this->net_changes, &lookup); if (!change) { /* 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)) + if (this->public.interface.get_interface(&this->public.interface, + route->src_ip, &lookup.if_name)) { - change = this->net_changes->get(this->net_changes, &lookup); + if (!streq(lookup.if_name, route->if_name)) + { + change = this->net_changes->get(this->net_changes, &lookup); + } + free(lookup.if_name); } - free(lookup.if_name); } if (change) { @@ -999,15 +1001,13 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, (void*)address_enumerator_destroy); } -METHOD(kernel_net_t, get_interface_name, char*, - private_kernel_netlink_net_t *this, host_t* ip) +METHOD(kernel_net_t, get_interface_name, bool, + private_kernel_netlink_net_t *this, host_t* ip, char **name) { enumerator_t *ifaces, *addrs; iface_entry_t *iface; addr_entry_t *addr; - char *name = NULL; - - DBG2(DBG_KNL, "getting interface name for %H", ip); + bool found = FALSE; this->mutex->lock(this->mutex); ifaces = this->ifaces->create_enumerator(this->ifaces); @@ -1018,12 +1018,16 @@ METHOD(kernel_net_t, get_interface_name, char*, { if (ip->ip_equals(ip, addr->ip)) { - name = strdup(iface->ifname); + found = TRUE; + if (name) + { + *name = strdup(iface->ifname); + } break; } } addrs->destroy(addrs); - if (name) + if (found) { break; } @@ -1031,15 +1035,15 @@ METHOD(kernel_net_t, get_interface_name, char*, ifaces->destroy(ifaces); this->mutex->unlock(this->mutex); - if (name) - { - DBG2(DBG_KNL, "%H is on interface %s", ip, name); - } - else + if (!found) { DBG2(DBG_KNL, "%H is not a local address", ip); } - return name; + else if (name) + { + DBG2(DBG_KNL, "%H is on interface %s", ip, *name); + } + return found; } /** diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index 4ecb72731..14ca4c8cb 100644 --- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -2028,14 +2028,13 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this, route->gateway = hydra->kernel_interface->get_nexthop( hydra->kernel_interface, ipsec->src, ipsec->dst); - /* install route via outgoing interface */ - route->if_name = hydra->kernel_interface->get_interface( - hydra->kernel_interface, ipsec->dst); route->dst_net = chunk_clone(policy->src.net->get_address( policy->src.net)); route->prefixlen = policy->src.mask; - if (!route->if_name) + /* install route via outgoing interface */ + if (!hydra->kernel_interface->get_interface(hydra->kernel_interface, + ipsec->dst, &route->if_name)) { this->mutex->unlock(this->mutex); route_entry_destroy(route); diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c index 878573793..d24820caf 100644 --- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -472,15 +472,13 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, (void*)address_enumerator_destroy); } -METHOD(kernel_net_t, get_interface_name, char*, - private_kernel_pfroute_net_t *this, host_t* ip) +METHOD(kernel_net_t, get_interface_name, bool, + private_kernel_pfroute_net_t *this, host_t* ip, char **name) { enumerator_t *ifaces, *addrs; iface_entry_t *iface; addr_entry_t *addr; - char *name = NULL; - - DBG2(DBG_KNL, "getting interface name for %H", ip); + bool found = FALSE; this->mutex->lock(this->mutex); ifaces = this->ifaces->create_enumerator(this->ifaces); @@ -491,12 +489,16 @@ METHOD(kernel_net_t, get_interface_name, char*, { if (ip->ip_equals(ip, addr->ip)) { - name = strdup(iface->ifname); + found = TRUE; + if (name) + { + *name = strdup(iface->ifname); + } break; } } addrs->destroy(addrs); - if (name) + if (found) { break; } @@ -504,15 +506,15 @@ METHOD(kernel_net_t, get_interface_name, char*, ifaces->destroy(ifaces); this->mutex->unlock(this->mutex); - if (name) - { - DBG2(DBG_KNL, "%H is on interface %s", ip, name); - } - else + if (!found) { DBG2(DBG_KNL, "%H is not a local address", ip); } - return name; + else if (name) + { + DBG2(DBG_KNL, "%H is on interface %s", ip, *name); + } + return found; } METHOD(kernel_net_t, get_source_addr, host_t*,