+
+ /* apply the route if:
+ * - it is not from our own ipsec routing table
+ * - its destination net contains our destination
+ * - is better than a previous one
+ */
+ if (msg->rtm_table != IPSEC_ROUTING_TABLE && rta_dst.ptr &&
+ addr_in_subnet(chunk, rta_dst, msg->rtm_dst_len) &&
+ msg->rtm_dst_len > best)
+ {
+ iterator_t *ifaces, *addrs;
+ iface_entry_t *iface;
+ addr_entry_t *addr;
+
+ best = msg->rtm_dst_len;
+ if (nexthop)
+ {
+ DESTROY_IF(gtw);
+ gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0);
+ }
+ else if (rta_src.ptr)
+ {
+ DESTROY_IF(src);
+ src = host_create_from_chunk(msg->rtm_family, rta_src, 0);
+ }
+ else
+ {
+ /* no source addr, get one from the interfaces */
+ ifaces = this->ifaces->create_iterator_locked(
+ this->ifaces, &this->mutex);
+ while (ifaces->iterate(ifaces, (void**)&iface))
+ {
+ if (iface->ifindex == rta_oif)
+ {
+ addrs = iface->addrs->create_iterator(
+ iface->addrs, TRUE);
+ while (addrs->iterate(addrs, (void**)&addr))
+ {
+ chunk_t ip = addr->ip->get_address(addr->ip);
+ if (addr_in_subnet(ip, rta_dst,
+ msg->rtm_dst_len))
+ {
+ DESTROY_IF(src);
+ src = addr->ip->clone(addr->ip);
+ best = msg->rtm_dst_len;
+ break;
+ }
+ }
+ addrs->destroy(addrs);
+ }
+ }
+ ifaces->destroy(ifaces);
+ }
+ }
+ /* FALL through */