}
/**
+ * get the first non-virtual ip address on the given interface.
+ * returned host is a clone, has to be freed by caller.
+ */
+static host_t *get_interface_address(private_kernel_netlink_net_t *this,
+ int ifindex, int family)
+{
+ enumerator_t *ifaces, *addrs;
+ iface_entry_t *iface;
+ addr_entry_t *addr;
+ host_t *ip = NULL;
+
+ this->mutex->lock(this->mutex);
+ ifaces = this->ifaces->create_enumerator(this->ifaces);
+ while (ifaces->enumerate(ifaces, &iface))
+ {
+ if (iface->ifindex == ifindex)
+ {
+ addrs = iface->addrs->create_enumerator(iface->addrs);
+ while (addrs->enumerate(addrs, &addr))
+ {
+ if (!addr->virtual && addr->ip->get_family(addr->ip) == family)
+ {
+ ip = addr->ip->clone(addr->ip);
+ break;
+ }
+ }
+ addrs->destroy(addrs);
+ break;
+ }
+ }
+ ifaces->destroy(ifaces);
+ this->mutex->unlock(this->mutex);
+ return ip;
+}
+
+/**
* Check if an interface with a given index is up
*/
static bool is_interface_up(private_kernel_netlink_net_t *this, int index)
continue;
}
if (rta_src.ptr)
- {
- /* got a source address */
+ { /* got a source address */
new_src = host_create_from_chunk(msg->rtm_family, rta_src, 0);
if (new_src)
{
}
continue;
}
+ if (rta_oif)
+ { /* no source, but an interface. Get address from it. */
+ new_src = get_interface_address(this, rta_oif,
+ msg->rtm_family);
+ if (new_src)
+ {
+ DESTROY_IF(src);
+ src = new_src;
+ best = msg->rtm_dst_len;
+ }
+ continue;
+ }
if (rta_gtw.ptr)
{ /* no source, but a gateway. Lookup source to reach gtw. */
new_gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0);