Make it easy to check if an address is locally usable via changed get_interface() method
This commit is contained in:
@@ -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;
|
stroke_end_t tmp_end;
|
||||||
ike_cfg_t *ike_cfg;
|
ike_cfg_t *ike_cfg;
|
||||||
char *interface;
|
|
||||||
host_t *host;
|
host_t *host;
|
||||||
u_int16_t ikeport;
|
u_int16_t ikeport;
|
||||||
|
|
||||||
host = host_create_from_dns(msg->add_conn.other.address, 0, 0);
|
host = host_create_from_dns(msg->add_conn.other.address, 0, 0);
|
||||||
if (host)
|
if (host)
|
||||||
{
|
{
|
||||||
interface = hydra->kernel_interface->get_interface(
|
if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
|
||||||
hydra->kernel_interface, host);
|
host, NULL))
|
||||||
host->destroy(host);
|
|
||||||
if (interface)
|
|
||||||
{
|
{
|
||||||
DBG2(DBG_CFG, "left is other host, swapping ends");
|
DBG2(DBG_CFG, "left is other host, swapping ends");
|
||||||
tmp_end = msg->add_conn.me;
|
tmp_end = msg->add_conn.me;
|
||||||
msg->add_conn.me = msg->add_conn.other;
|
msg->add_conn.me = msg->add_conn.other;
|
||||||
msg->add_conn.other = tmp_end;
|
msg->add_conn.other = tmp_end;
|
||||||
free(interface);
|
host->destroy(host);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
host->destroy(host);
|
||||||
host = host_create_from_dns(msg->add_conn.me.address, 0, 0);
|
host = host_create_from_dns(msg->add_conn.me.address, 0, 0);
|
||||||
if (host)
|
if (host)
|
||||||
{
|
{
|
||||||
interface = hydra->kernel_interface->get_interface(
|
if (!hydra->kernel_interface->get_interface(
|
||||||
hydra->kernel_interface, host);
|
hydra->kernel_interface, host, NULL))
|
||||||
host->destroy(host);
|
|
||||||
if (!interface)
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "left nor right host is our side, "
|
DBG1(DBG_CFG, "left nor right host is our side, "
|
||||||
"assuming left=local");
|
"assuming left=local");
|
||||||
}
|
}
|
||||||
else
|
host->destroy(host);
|
||||||
{
|
|
||||||
free(interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -267,9 +267,8 @@ METHOD(listener_t, child_updown, bool,
|
|||||||
|
|
||||||
if (up)
|
if (up)
|
||||||
{
|
{
|
||||||
iface = hydra->kernel_interface->get_interface(
|
if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
|
||||||
hydra->kernel_interface, me);
|
me, &iface))
|
||||||
if (iface)
|
|
||||||
{
|
{
|
||||||
cache_iface(this, child_sa->get_reqid(child_sa), iface);
|
cache_iface(this, child_sa->get_reqid(child_sa), iface);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,14 +291,14 @@ METHOD(kernel_interface_t, get_nexthop, host_t*,
|
|||||||
return this->net->get_nexthop(this->net, dest, src);
|
return this->net->get_nexthop(this->net, dest, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kernel_interface_t, get_interface, char*,
|
METHOD(kernel_interface_t, get_interface, bool,
|
||||||
private_kernel_interface_t *this, host_t *host)
|
private_kernel_interface_t *this, host_t *host, char **name)
|
||||||
{
|
{
|
||||||
if (!this->net)
|
if (!this->net)
|
||||||
{
|
{
|
||||||
return NULL;
|
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*,
|
METHOD(kernel_interface_t, create_address_enumerator, enumerator_t*,
|
||||||
|
|||||||
@@ -308,9 +308,10 @@ struct kernel_interface_t {
|
|||||||
* Get the interface name of a local address.
|
* Get the interface name of a local address.
|
||||||
*
|
*
|
||||||
* @param host address to get interface name from
|
* @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.
|
* Creates an enumerator over all local addresses.
|
||||||
|
|||||||
@@ -68,9 +68,10 @@ struct kernel_net_t {
|
|||||||
* Get the interface name of a local address.
|
* Get the interface name of a local address.
|
||||||
*
|
*
|
||||||
* @param host address to get interface name from
|
* @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.
|
* Creates an enumerator over all local addresses.
|
||||||
|
|||||||
@@ -2108,7 +2108,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||||||
*/
|
*/
|
||||||
if (policy->route == NULL && direction == POLICY_OUT)
|
if (policy->route == NULL && direction == POLICY_OUT)
|
||||||
{
|
{
|
||||||
char *iface;
|
char *iface = NULL;
|
||||||
ipsec_dev_t *dev;
|
ipsec_dev_t *dev;
|
||||||
route_entry_t *route = malloc_thing(route_entry_t);
|
route_entry_t *route = malloc_thing(route_entry_t);
|
||||||
route->src_ip = NULL;
|
route->src_ip = NULL;
|
||||||
@@ -2126,8 +2126,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* find the virtual interface */
|
/* find the virtual interface */
|
||||||
iface = hydra->kernel_interface->get_interface(hydra->kernel_interface,
|
hydra->kernel_interface->get_interface(hydra->kernel_interface,
|
||||||
src);
|
src, &iface);
|
||||||
if (find_ipsec_dev(this, iface, &dev) == SUCCESS)
|
if (find_ipsec_dev(this, iface, &dev) == SUCCESS)
|
||||||
{
|
{
|
||||||
/* above, we got either the name of a virtual or a physical
|
/* above, we got either the name of a virtual or a physical
|
||||||
|
|||||||
@@ -2169,14 +2169,13 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
|
|||||||
route->gateway = hydra->kernel_interface->get_nexthop(
|
route->gateway = hydra->kernel_interface->get_nexthop(
|
||||||
hydra->kernel_interface, ipsec->src,
|
hydra->kernel_interface, ipsec->src,
|
||||||
ipsec->dst);
|
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);
|
route->dst_net = chunk_alloc(policy->sel.family == AF_INET ? 4 : 16);
|
||||||
memcpy(route->dst_net.ptr, &policy->sel.saddr, route->dst_net.len);
|
memcpy(route->dst_net.ptr, &policy->sel.saddr, route->dst_net.len);
|
||||||
route->prefixlen = policy->sel.prefixlen_s;
|
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);
|
this->mutex->unlock(this->mutex);
|
||||||
route_entry_destroy(route);
|
route_entry_destroy(route);
|
||||||
|
|||||||
@@ -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);
|
change = this->net_changes->get(this->net_changes, &lookup);
|
||||||
if (!change)
|
if (!change)
|
||||||
{ /* in case src_ip is not on the outgoing interface */
|
{ /* in case src_ip is not on the outgoing interface */
|
||||||
lookup.if_name = this->public.interface.get_interface(
|
if (this->public.interface.get_interface(&this->public.interface,
|
||||||
&this->public.interface, route->src_ip);
|
route->src_ip, &lookup.if_name))
|
||||||
if (lookup.if_name && !streq(lookup.if_name, route->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)
|
if (change)
|
||||||
{
|
{
|
||||||
@@ -999,15 +1001,13 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
|
|||||||
(void*)address_enumerator_destroy);
|
(void*)address_enumerator_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kernel_net_t, get_interface_name, char*,
|
METHOD(kernel_net_t, get_interface_name, bool,
|
||||||
private_kernel_netlink_net_t *this, host_t* ip)
|
private_kernel_netlink_net_t *this, host_t* ip, char **name)
|
||||||
{
|
{
|
||||||
enumerator_t *ifaces, *addrs;
|
enumerator_t *ifaces, *addrs;
|
||||||
iface_entry_t *iface;
|
iface_entry_t *iface;
|
||||||
addr_entry_t *addr;
|
addr_entry_t *addr;
|
||||||
char *name = NULL;
|
bool found = FALSE;
|
||||||
|
|
||||||
DBG2(DBG_KNL, "getting interface name for %H", ip);
|
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
this->mutex->lock(this->mutex);
|
||||||
ifaces = this->ifaces->create_enumerator(this->ifaces);
|
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))
|
if (ip->ip_equals(ip, addr->ip))
|
||||||
{
|
{
|
||||||
name = strdup(iface->ifname);
|
found = TRUE;
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
*name = strdup(iface->ifname);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addrs->destroy(addrs);
|
addrs->destroy(addrs);
|
||||||
if (name)
|
if (found)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1031,15 +1035,15 @@ METHOD(kernel_net_t, get_interface_name, char*,
|
|||||||
ifaces->destroy(ifaces);
|
ifaces->destroy(ifaces);
|
||||||
this->mutex->unlock(this->mutex);
|
this->mutex->unlock(this->mutex);
|
||||||
|
|
||||||
if (name)
|
if (!found)
|
||||||
{
|
|
||||||
DBG2(DBG_KNL, "%H is on interface %s", ip, name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
DBG2(DBG_KNL, "%H is not a local address", ip);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2028,14 +2028,13 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this,
|
|||||||
route->gateway = hydra->kernel_interface->get_nexthop(
|
route->gateway = hydra->kernel_interface->get_nexthop(
|
||||||
hydra->kernel_interface, ipsec->src,
|
hydra->kernel_interface, ipsec->src,
|
||||||
ipsec->dst);
|
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(
|
route->dst_net = chunk_clone(policy->src.net->get_address(
|
||||||
policy->src.net));
|
policy->src.net));
|
||||||
route->prefixlen = policy->src.mask;
|
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);
|
this->mutex->unlock(this->mutex);
|
||||||
route_entry_destroy(route);
|
route_entry_destroy(route);
|
||||||
|
|||||||
@@ -472,15 +472,13 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
|
|||||||
(void*)address_enumerator_destroy);
|
(void*)address_enumerator_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kernel_net_t, get_interface_name, char*,
|
METHOD(kernel_net_t, get_interface_name, bool,
|
||||||
private_kernel_pfroute_net_t *this, host_t* ip)
|
private_kernel_pfroute_net_t *this, host_t* ip, char **name)
|
||||||
{
|
{
|
||||||
enumerator_t *ifaces, *addrs;
|
enumerator_t *ifaces, *addrs;
|
||||||
iface_entry_t *iface;
|
iface_entry_t *iface;
|
||||||
addr_entry_t *addr;
|
addr_entry_t *addr;
|
||||||
char *name = NULL;
|
bool found = FALSE;
|
||||||
|
|
||||||
DBG2(DBG_KNL, "getting interface name for %H", ip);
|
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
this->mutex->lock(this->mutex);
|
||||||
ifaces = this->ifaces->create_enumerator(this->ifaces);
|
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))
|
if (ip->ip_equals(ip, addr->ip))
|
||||||
{
|
{
|
||||||
name = strdup(iface->ifname);
|
found = TRUE;
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
*name = strdup(iface->ifname);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addrs->destroy(addrs);
|
addrs->destroy(addrs);
|
||||||
if (name)
|
if (found)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -504,15 +506,15 @@ METHOD(kernel_net_t, get_interface_name, char*,
|
|||||||
ifaces->destroy(ifaces);
|
ifaces->destroy(ifaces);
|
||||||
this->mutex->unlock(this->mutex);
|
this->mutex->unlock(this->mutex);
|
||||||
|
|
||||||
if (name)
|
if (!found)
|
||||||
{
|
|
||||||
DBG2(DBG_KNL, "%H is on interface %s", ip, name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
DBG2(DBG_KNL, "%H is not a local address", ip);
|
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*,
|
METHOD(kernel_net_t, get_source_addr, host_t*,
|
||||||
|
|||||||
Reference in New Issue
Block a user