Annotation of embedaddon/strongswan/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008-2019 Tobias Brunner
                      3:  * Copyright (C) 2005-2008 Martin Willi
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2 of the License, or (at your
                      9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:  * for more details.
                     15:  */
                     16: 
                     17: /*
                     18:  * Copyright (C) 2010 secunet Security Networks AG
                     19:  * Copyright (C) 2010 Thomas Egerer
                     20:  *
                     21:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                     22:  * of this software and associated documentation files (the "Software"), to deal
                     23:  * in the Software without restriction, including without limitation the rights
                     24:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     25:  * copies of the Software, and to permit persons to whom the Software is
                     26:  * furnished to do so, subject to the following conditions:
                     27:  *
                     28:  * The above copyright notice and this permission notice shall be included in
                     29:  * all copies or substantial portions of the Software.
                     30:  *
                     31:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     32:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     33:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     34:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     35:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     36:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     37:  * THE SOFTWARE.
                     38:  */
                     39: 
                     40: #include <sys/socket.h>
                     41: #include <sys/utsname.h>
                     42: #include <linux/netlink.h>
                     43: #include <linux/rtnetlink.h>
                     44: #include <linux/if_addrlabel.h>
                     45: #include <unistd.h>
                     46: #include <errno.h>
                     47: #include <net/if.h>
                     48: #ifdef HAVE_LINUX_FIB_RULES_H
                     49: #include <linux/fib_rules.h>
                     50: #endif
                     51: 
                     52: #include "kernel_netlink_net.h"
                     53: #include "kernel_netlink_shared.h"
                     54: 
                     55: #include <daemon.h>
                     56: #include <utils/debug.h>
                     57: #include <threading/mutex.h>
                     58: #include <threading/rwlock.h>
                     59: #include <threading/rwlock_condvar.h>
                     60: #include <threading/spinlock.h>
                     61: #include <collections/hashtable.h>
                     62: #include <collections/linked_list.h>
                     63: #include <processing/jobs/callback_job.h>
                     64: 
                     65: /** delay before firing roam events (ms) */
                     66: #define ROAM_DELAY 100
                     67: 
                     68: /** delay before reinstalling routes (ms) */
                     69: #define ROUTE_DELAY 100
                     70: 
                     71: /** maximum recursion when searching for addresses in get_route() */
                     72: #define MAX_ROUTE_RECURSION 2
                     73: 
                     74: #ifndef ROUTING_TABLE
                     75: #define ROUTING_TABLE 0
                     76: #endif
                     77: 
                     78: #ifndef ROUTING_TABLE_PRIO
                     79: #define ROUTING_TABLE_PRIO 0
                     80: #endif
                     81: 
                     82: /** multicast groups (for groups > 31 setsockopt has to be used) */
                     83: #define nl_group(group) (1 << (group - 1))
                     84: 
                     85: ENUM(rt_msg_names, RTM_NEWLINK, RTM_GETRULE,
                     86:        "RTM_NEWLINK",
                     87:        "RTM_DELLINK",
                     88:        "RTM_GETLINK",
                     89:        "RTM_SETLINK",
                     90:        "RTM_NEWADDR",
                     91:        "RTM_DELADDR",
                     92:        "RTM_GETADDR",
                     93:        "23",
                     94:        "RTM_NEWROUTE",
                     95:        "RTM_DELROUTE",
                     96:        "RTM_GETROUTE",
                     97:        "27",
                     98:        "RTM_NEWNEIGH",
                     99:        "RTM_DELNEIGH",
                    100:        "RTM_GETNEIGH",
                    101:        "31",
                    102:        "RTM_NEWRULE",
                    103:        "RTM_DELRULE",
                    104:        "RTM_GETRULE",
                    105: );
                    106: 
                    107: typedef struct addr_entry_t addr_entry_t;
                    108: 
                    109: /**
                    110:  * IP address in an iface_entry_t
                    111:  */
                    112: struct addr_entry_t {
                    113: 
                    114:        /** the ip address */
                    115:        host_t *ip;
                    116: 
                    117:        /** address flags */
                    118:        u_char flags;
                    119: 
                    120:        /** scope of the address */
                    121:        u_char scope;
                    122: 
                    123:        /** number of times this IP is used, if virtual (i.e. managed by us) */
                    124:        u_int refcount;
                    125: 
                    126:        /** TRUE once it is installed, if virtual */
                    127:        bool installed;
                    128: };
                    129: 
                    130: /**
                    131:  * destroy a addr_entry_t object
                    132:  */
                    133: static void addr_entry_destroy(addr_entry_t *this)
                    134: {
                    135:        this->ip->destroy(this->ip);
                    136:        free(this);
                    137: }
                    138: 
                    139: typedef struct iface_entry_t iface_entry_t;
                    140: 
                    141: /**
                    142:  * A network interface on this system, containing addr_entry_t's
                    143:  */
                    144: struct iface_entry_t {
                    145: 
                    146:        /** interface index */
                    147:        int ifindex;
                    148: 
                    149:        /** name of the interface */
                    150:        char ifname[IFNAMSIZ];
                    151: 
                    152:        /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
                    153:        u_int flags;
                    154: 
                    155:        /** list of addresses as host_t */
                    156:        linked_list_t *addrs;
                    157: 
                    158:        /** TRUE if usable by config */
                    159:        bool usable;
                    160: };
                    161: 
                    162: /**
                    163:  * destroy an interface entry
                    164:  */
                    165: static void iface_entry_destroy(iface_entry_t *this)
                    166: {
                    167:        this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy);
                    168:        free(this);
                    169: }
                    170: 
                    171: CALLBACK(iface_entry_by_index, bool,
                    172:        iface_entry_t *this, va_list args)
                    173: {
                    174:        int ifindex;
                    175: 
                    176:        VA_ARGS_VGET(args, ifindex);
                    177:        return this->ifindex == ifindex;
                    178: }
                    179: 
                    180: CALLBACK(iface_entry_by_name, bool,
                    181:        iface_entry_t *this, va_list args)
                    182: {
                    183:        char *ifname;
                    184: 
                    185:        VA_ARGS_VGET(args, ifname);
                    186:        return streq(this->ifname, ifname);
                    187: }
                    188: 
                    189: /**
                    190:  * check if an interface is up
                    191:  */
                    192: static inline bool iface_entry_up(iface_entry_t *iface)
                    193: {
                    194:        return (iface->flags & IFF_UP) == IFF_UP;
                    195: }
                    196: 
                    197: /**
                    198:  * check if an interface is up and usable
                    199:  */
                    200: static inline bool iface_entry_up_and_usable(iface_entry_t *iface)
                    201: {
                    202:        return iface->usable && iface_entry_up(iface);
                    203: }
                    204: 
                    205: typedef struct addr_map_entry_t addr_map_entry_t;
                    206: 
                    207: /**
                    208:  * Entry that maps an IP address to an interface entry
                    209:  */
                    210: struct addr_map_entry_t {
                    211:        /** The IP address */
                    212:        host_t *ip;
                    213: 
                    214:        /** The address entry for this IP address */
                    215:        addr_entry_t *addr;
                    216: 
                    217:        /** The interface this address is installed on */
                    218:        iface_entry_t *iface;
                    219: };
                    220: 
                    221: /**
                    222:  * Hash a addr_map_entry_t object, all entries with the same IP address
                    223:  * are stored in the same bucket
                    224:  */
                    225: static u_int addr_map_entry_hash(addr_map_entry_t *this)
                    226: {
                    227:        return chunk_hash(this->ip->get_address(this->ip));
                    228: }
                    229: 
                    230: /**
                    231:  * Compare two addr_map_entry_t objects, two entries are equal if they are
                    232:  * installed on the same interface
                    233:  */
                    234: static bool addr_map_entry_equals(addr_map_entry_t *a, addr_map_entry_t *b)
                    235: {
                    236:        return a->iface->ifindex == b->iface->ifindex &&
                    237:                   a->ip->ip_equals(a->ip, b->ip);
                    238: }
                    239: 
                    240: /**
                    241:  * Used with get_match this finds an address entry if it is installed on
                    242:  * an up and usable interface
                    243:  */
                    244: static bool addr_map_entry_match_up_and_usable(addr_map_entry_t *a,
                    245:                                                                                           addr_map_entry_t *b)
                    246: {
                    247:        return iface_entry_up_and_usable(b->iface) &&
                    248:                   a->ip->ip_equals(a->ip, b->ip);
                    249: }
                    250: 
                    251: /**
                    252:  * Used with get_match this finds an address entry if it is installed on
                    253:  * any active local interface
                    254:  */
                    255: static bool addr_map_entry_match_up(addr_map_entry_t *a, addr_map_entry_t *b)
                    256: {
                    257:        return iface_entry_up(b->iface) && a->ip->ip_equals(a->ip, b->ip);
                    258: }
                    259: 
                    260: /**
                    261:  * Used with get_match this finds an address entry if it is installed on
                    262:  * any local interface
                    263:  */
                    264: static bool addr_map_entry_match(addr_map_entry_t *a, addr_map_entry_t *b)
                    265: {
                    266:        return a->ip->ip_equals(a->ip, b->ip);
                    267: }
                    268: 
                    269: typedef struct net_change_t net_change_t;
                    270: 
                    271: /**
                    272:  * Queued network changes
                    273:  */
                    274: struct net_change_t {
                    275:        /** Name of the interface that got activated (or an IP appeared on) */
                    276:        char *if_name;
                    277: };
                    278: 
                    279: /**
                    280:  * Destroy a net_change_t object
                    281:  */
                    282: static void net_change_destroy(net_change_t *this)
                    283: {
                    284:        free(this->if_name);
                    285:        free(this);
                    286: }
                    287: 
                    288: /**
                    289:  * Hash a net_change_t object
                    290:  */
                    291: static u_int net_change_hash(net_change_t *this)
                    292: {
                    293:        return chunk_hash(chunk_create(this->if_name, strlen(this->if_name)));
                    294: }
                    295: 
                    296: /**
                    297:  * Compare two net_change_t objects
                    298:  */
                    299: static bool net_change_equals(net_change_t *a, net_change_t *b)
                    300: {
                    301:        return streq(a->if_name, b->if_name);
                    302: }
                    303: 
                    304: typedef struct private_kernel_netlink_net_t private_kernel_netlink_net_t;
                    305: 
                    306: /**
                    307:  * Private variables and functions of kernel_netlink_net class.
                    308:  */
                    309: struct private_kernel_netlink_net_t {
                    310:        /**
                    311:         * Public part of the kernel_netlink_net_t object.
                    312:         */
                    313:        kernel_netlink_net_t public;
                    314: 
                    315:        /**
                    316:         * lock to access various lists and maps
                    317:         */
                    318:        rwlock_t *lock;
                    319: 
                    320:        /**
                    321:         * condition variable to signal virtual IP add/removal
                    322:         */
                    323:        rwlock_condvar_t *condvar;
                    324: 
                    325:        /**
                    326:         * Cached list of interfaces and its addresses (iface_entry_t)
                    327:         */
                    328:        linked_list_t *ifaces;
                    329: 
                    330:        /**
                    331:         * Map for IP addresses to iface_entry_t objects (addr_map_entry_t)
                    332:         */
                    333:        hashtable_t *addrs;
                    334: 
                    335:        /**
                    336:         * Map for virtual IP addresses to iface_entry_t objects (addr_map_entry_t)
                    337:         */
                    338:        hashtable_t *vips;
                    339: 
                    340:        /**
                    341:         * netlink rt socket (routing)
                    342:         */
                    343:        netlink_socket_t *socket;
                    344: 
                    345:        /**
                    346:         * Netlink rt socket to receive address change events
                    347:         */
                    348:        int socket_events;
                    349: 
                    350:        /**
                    351:         * earliest time of the next roam event
                    352:         */
                    353:        timeval_t next_roam;
                    354: 
                    355:        /**
                    356:         * roam event due to address change
                    357:         */
                    358:        bool roam_address;
                    359: 
                    360:        /**
                    361:         * lock to check and update roam event time
                    362:         */
                    363:        spinlock_t *roam_lock;
                    364: 
                    365:        /**
                    366:         * routing table to install routes
                    367:         */
                    368:        uint32_t routing_table;
                    369: 
                    370:        /**
                    371:         * priority of used routing table
                    372:         */
                    373:        uint32_t routing_table_prio;
                    374: 
                    375:        /**
                    376:         * installed routes
                    377:         */
                    378:        hashtable_t *routes;
                    379: 
                    380:        /**
                    381:         * mutex for routes
                    382:         */
                    383:        mutex_t *routes_lock;
                    384: 
                    385:        /**
                    386:         * interface changes which may trigger route reinstallation
                    387:         */
                    388:        hashtable_t *net_changes;
                    389: 
                    390:        /**
                    391:         * mutex for route reinstallation triggers
                    392:         */
                    393:        mutex_t *net_changes_lock;
                    394: 
                    395:        /**
                    396:         * time of last route reinstallation
                    397:         */
                    398:        timeval_t last_route_reinstall;
                    399: 
                    400:        /**
                    401:         * whether to react to RTM_NEWROUTE or RTM_DELROUTE events
                    402:         */
                    403:        bool process_route;
                    404: 
                    405:        /**
                    406:         * whether to react to RTM_NEWRULE or RTM_DELRULE events
                    407:         */
                    408:        bool process_rules;
                    409: 
                    410:        /**
                    411:         * whether to trigger roam events
                    412:         */
                    413:        bool roam_events;
                    414: 
                    415:        /**
                    416:         * whether to install IPsec policy routes
                    417:         */
                    418:        bool install_routes;
                    419: 
                    420:        /**
                    421:         * whether to actually install virtual IPs
                    422:         */
                    423:        bool install_virtual_ip;
                    424: 
                    425:        /**
                    426:         * the name of the interface virtual IP addresses are installed on
                    427:         */
                    428:        char *install_virtual_ip_on;
                    429: 
                    430:        /**
                    431:         * whether preferred source addresses can be specified for IPv6 routes
                    432:         */
                    433:        bool rta_prefsrc_for_ipv6;
                    434: 
                    435:        /**
                    436:         * whether marks can be used in route lookups
                    437:         */
                    438:        bool rta_mark;
                    439: 
                    440:        /**
                    441:         * the mark excluded from the routing rule used for virtual IPs
                    442:         */
                    443:        mark_t routing_mark;
                    444: 
                    445:        /**
                    446:         * whether to prefer temporary IPv6 addresses over public ones
                    447:         */
                    448:        bool prefer_temporary_addrs;
                    449: 
                    450:        /**
                    451:         * list with routing tables to be excluded from route lookup
                    452:         */
                    453:        linked_list_t *rt_exclude;
                    454: 
                    455:        /**
                    456:         * MTU to set on installed routes
                    457:         */
                    458:        uint32_t mtu;
                    459: 
                    460:        /**
                    461:         * MSS to set on installed routes
                    462:         */
                    463:        uint32_t mss;
                    464: };
                    465: 
                    466: /**
                    467:  * Forward declaration
                    468:  */
                    469: static status_t manage_srcroute(private_kernel_netlink_net_t *this,
                    470:                                                                int nlmsg_type, int flags, chunk_t dst_net,
                    471:                                                                uint8_t prefixlen, host_t *gateway,
                    472:                                                                host_t *src_ip, char *if_name, bool pass);
                    473: 
                    474: /**
                    475:  * Clear the queued network changes.
                    476:  */
                    477: static void net_changes_clear(private_kernel_netlink_net_t *this)
                    478: {
                    479:        enumerator_t *enumerator;
                    480:        net_change_t *change;
                    481: 
                    482:        enumerator = this->net_changes->create_enumerator(this->net_changes);
                    483:        while (enumerator->enumerate(enumerator, NULL, (void**)&change))
                    484:        {
                    485:                this->net_changes->remove_at(this->net_changes, enumerator);
                    486:                net_change_destroy(change);
                    487:        }
                    488:        enumerator->destroy(enumerator);
                    489: }
                    490: 
                    491: /**
                    492:  * Act upon queued network changes.
                    493:  */
                    494: static job_requeue_t reinstall_routes(private_kernel_netlink_net_t *this)
                    495: {
                    496:        enumerator_t *enumerator;
                    497:        route_entry_t *route;
                    498: 
                    499:        this->net_changes_lock->lock(this->net_changes_lock);
                    500:        this->routes_lock->lock(this->routes_lock);
                    501: 
                    502:        enumerator = this->routes->create_enumerator(this->routes);
                    503:        while (enumerator->enumerate(enumerator, NULL, (void**)&route))
                    504:        {
                    505:                net_change_t *change, lookup = {
                    506:                        .if_name = route->if_name,
                    507:                };
                    508:                if (route->pass || !route->if_name)
                    509:                {       /* no need to reinstall these, they don't reference interfaces */
                    510:                        continue;
                    511:                }
                    512:                /* check if a change for the outgoing interface is queued */
                    513:                change = this->net_changes->get(this->net_changes, &lookup);
                    514:                if (!change)
                    515:                {       /* in case src_ip is not on the outgoing interface */
                    516:                        if (this->public.interface.get_interface(&this->public.interface,
                    517:                                                                                                route->src_ip, &lookup.if_name))
                    518:                        {
                    519:                                if (!streq(lookup.if_name, route->if_name))
                    520:                                {
                    521:                                        change = this->net_changes->get(this->net_changes, &lookup);
                    522:                                }
                    523:                                free(lookup.if_name);
                    524:                        }
                    525:                }
                    526:                if (change)
                    527:                {
                    528:                        manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL,
                    529:                                                        route->dst_net, route->prefixlen, route->gateway,
                    530:                                                        route->src_ip, route->if_name, route->pass);
                    531:                }
                    532:        }
                    533:        enumerator->destroy(enumerator);
                    534:        this->routes_lock->unlock(this->routes_lock);
                    535: 
                    536:        net_changes_clear(this);
                    537:        this->net_changes_lock->unlock(this->net_changes_lock);
                    538:        return JOB_REQUEUE_NONE;
                    539: }
                    540: 
                    541: /**
                    542:  * Queue route reinstallation caused by network changes for a given interface.
                    543:  *
                    544:  * The route reinstallation is delayed for a while and only done once for
                    545:  * several calls during this delay, in order to avoid doing it too often.
                    546:  * The interface name is freed.
                    547:  */
                    548: static void queue_route_reinstall(private_kernel_netlink_net_t *this,
                    549:                                                                  char *if_name)
                    550: {
                    551:        net_change_t *update, *found;
                    552:        timeval_t now;
                    553:        job_t *job;
                    554: 
                    555:        INIT(update,
                    556:                .if_name = if_name
                    557:        );
                    558: 
                    559:        this->net_changes_lock->lock(this->net_changes_lock);
                    560:        found = this->net_changes->put(this->net_changes, update, update);
                    561:        if (found)
                    562:        {
                    563:                net_change_destroy(found);
                    564:        }
                    565:        time_monotonic(&now);
                    566:        if (timercmp(&now, &this->last_route_reinstall, >))
                    567:        {
                    568:                timeval_add_ms(&now, ROUTE_DELAY);
                    569:                this->last_route_reinstall = now;
                    570: 
                    571:                job = (job_t*)callback_job_create((callback_job_cb_t)reinstall_routes,
                    572:                                                                                  this, NULL, NULL);
                    573:                lib->scheduler->schedule_job_ms(lib->scheduler, job, ROUTE_DELAY);
                    574:        }
                    575:        this->net_changes_lock->unlock(this->net_changes_lock);
                    576: }
                    577: 
                    578: /**
                    579:  * check if the given IP is known as virtual IP and currently installed
                    580:  *
                    581:  * this function will also return TRUE if the virtual IP entry disappeared.
                    582:  * in that case the returned entry will be NULL.
                    583:  *
                    584:  * this->lock must be held when calling this function
                    585:  */
                    586: static bool is_vip_installed_or_gone(private_kernel_netlink_net_t *this,
                    587:                                                                         host_t *ip, addr_map_entry_t **entry)
                    588: {
                    589:        addr_map_entry_t lookup = {
                    590:                .ip = ip,
                    591:        };
                    592: 
                    593:        *entry = this->vips->get_match(this->vips, &lookup,
                    594:                                                                  (void*)addr_map_entry_match);
                    595:        if (*entry == NULL)
                    596:        {       /* the virtual IP disappeared */
                    597:                return TRUE;
                    598:        }
                    599:        return (*entry)->addr->installed;
                    600: }
                    601: 
                    602: /**
                    603:  * check if the given IP is known as virtual IP
                    604:  *
                    605:  * this->lock must be held when calling this function
                    606:  */
                    607: static bool is_known_vip(private_kernel_netlink_net_t *this, host_t *ip)
                    608: {
                    609:        addr_map_entry_t lookup = {
                    610:                .ip = ip,
                    611:        };
                    612: 
                    613:        return this->vips->get_match(this->vips, &lookup,
                    614:                                                                (void*)addr_map_entry_match) != NULL;
                    615: }
                    616: 
                    617: /**
                    618:  * Add an address map entry
                    619:  */
                    620: static void addr_map_entry_add(hashtable_t *map, addr_entry_t *addr,
                    621:                                                           iface_entry_t *iface)
                    622: {
                    623:        addr_map_entry_t *entry;
                    624: 
                    625:        INIT(entry,
                    626:                .ip = addr->ip,
                    627:                .addr = addr,
                    628:                .iface = iface,
                    629:        );
                    630:        entry = map->put(map, entry, entry);
                    631:        free(entry);
                    632: }
                    633: 
                    634: /**
                    635:  * Remove an address map entry
                    636:  */
                    637: static void addr_map_entry_remove(hashtable_t *map, addr_entry_t *addr,
                    638:                                                                  iface_entry_t *iface)
                    639: {
                    640:        addr_map_entry_t *entry, lookup = {
                    641:                .ip = addr->ip,
                    642:                .addr = addr,
                    643:                .iface = iface,
                    644:        };
                    645: 
                    646:        entry = map->remove(map, &lookup);
                    647:        free(entry);
                    648: }
                    649: 
                    650: /**
                    651:  * Check if an address or net (addr with prefix net bits) is in
                    652:  * subnet (net with net_len net bits)
                    653:  */
                    654: static bool addr_in_subnet(chunk_t addr, int prefix, chunk_t net, int net_len)
                    655: {
                    656:        static const u_char mask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
                    657:        int byte = 0;
                    658: 
                    659:        if (net_len == 0)
                    660:        {       /* any address matches a /0 network */
                    661:                return TRUE;
                    662:        }
                    663:        if (addr.len != net.len || net_len > 8 * net.len || prefix < net_len)
                    664:        {
                    665:                return FALSE;
                    666:        }
                    667:        /* scan through all bytes in network order */
                    668:        while (net_len > 0)
                    669:        {
                    670:                if (net_len < 8)
                    671:                {
                    672:                        return (mask[net_len] & addr.ptr[byte]) == (mask[net_len] & net.ptr[byte]);
                    673:                }
                    674:                else
                    675:                {
                    676:                        if (addr.ptr[byte] != net.ptr[byte])
                    677:                        {
                    678:                                return FALSE;
                    679:                        }
                    680:                        byte++;
                    681:                        net_len -= 8;
                    682:                }
                    683:        }
                    684:        return TRUE;
                    685: }
                    686: 
                    687: /**
                    688:  * Check if the given address is in subnet (net with net_len net bits)
                    689:  */
                    690: static bool host_in_subnet(host_t *host, chunk_t net, int net_len)
                    691: {
                    692:        chunk_t addr;
                    693: 
                    694:        addr = host->get_address(host);
                    695:        return addr_in_subnet(addr, addr.len * 8, net, net_len);
                    696: }
                    697: 
                    698: /**
                    699:  * Determine the type or scope of the given unicast IP address.  This is not
                    700:  * the same thing returned in rtm_scope/ifa_scope.
                    701:  *
                    702:  * We use return values as defined in RFC 6724 (referring to RFC 4291).
                    703:  */
                    704: static u_char get_scope(host_t *ip)
                    705: {
                    706:        chunk_t addr;
                    707: 
                    708:        addr = ip->get_address(ip);
                    709:        switch (addr.len)
                    710:        {
                    711:                case 4:
                    712:                        /* we use the mapping defined in RFC 6724, 3.2 */
                    713:                        if (addr.ptr[0] == 127)
                    714:                        {       /* link-local, same as the IPv6 loopback address */
                    715:                                return 2;
                    716:                        }
                    717:                        if (addr.ptr[0] == 169 && addr.ptr[1] == 254)
                    718:                        {       /* link-local */
                    719:                                return 2;
                    720:                        }
                    721:                        break;
                    722:                case 16:
                    723:                        if (IN6_IS_ADDR_LOOPBACK((struct in6_addr*)addr.ptr))
                    724:                        {       /* link-local, according to RFC 4291, 2.5.3 */
                    725:                                return 2;
                    726:                        }
                    727:                        if (IN6_IS_ADDR_LINKLOCAL((struct in6_addr*)addr.ptr))
                    728:                        {
                    729:                                return 2;
                    730:                        }
                    731:                        if (IN6_IS_ADDR_SITELOCAL((struct in6_addr*)addr.ptr))
                    732:                        {       /* deprecated, according to RFC 4291, 2.5.7 */
                    733:                                return 5;
                    734:                        }
                    735:                        break;
                    736:                default:
                    737:                        break;
                    738:        }
                    739:        /* global */
                    740:        return 14;
                    741: }
                    742: 
                    743: /**
                    744:  * Determine the label of the given unicast IP address.
                    745:  *
                    746:  * We currently only support the default table given in RFC 6724:
                    747:  *
                    748:  *  Prefix        Precedence Label
                    749:  *  ::1/128               50     0
                    750:  *  ::/0                  40     1
                    751:  *  ::ffff:0:0/96         35     4
                    752:  *  2002::/16             30     2
                    753:  *  2001::/32              5     5
                    754:  *  fc00::/7               3    13
                    755:  *  ::/96                  1     3
                    756:  *  fec0::/10              1    11
                    757:  *  3ffe::/16              1    12
                    758:  */
                    759: static u_char get_label(host_t *ip)
                    760: {
                    761:        struct {
                    762:                chunk_t net;
                    763:                u_char prefix;
                    764:                u_char label;
                    765:        } priorities[] = {
                    766:                /* priority table ordered by prefix */
                    767:                /* ::1/128 */
                    768:                { chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    769:                                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), 128, 0 },
                    770:                /* ::ffff:0:0/96 */
                    771:                { chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    772:                                                   0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00), 96, 4 },
                    773:                /* ::/96 */
                    774:                { chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    775:                                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), 96, 3 },
                    776:                /* 2001::/32 */
                    777:                { chunk_from_chars(0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    778:                                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), 32, 5 },
                    779:                /* 2002::/16 */
                    780:                { chunk_from_chars(0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    781:                                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), 16, 2 },
                    782:                /* 3ffe::/16 */
                    783:                { chunk_from_chars(0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    784:                                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), 16, 12 },
                    785:                /* fec0::/10 */
                    786:                { chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    787:                                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), 10, 11 },
                    788:                /* fc00::/7 */
                    789:                { chunk_from_chars(0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    790:                                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), 7, 13 },
                    791:        };
                    792:        int i;
                    793: 
                    794:        for (i = 0; i < countof(priorities); i++)
                    795:        {
                    796:                if (host_in_subnet(ip, priorities[i].net, priorities[i].prefix))
                    797:                {
                    798:                        return priorities[i].label;
                    799:                }
                    800:        }
                    801:        /* ::/0 */
                    802:        return 1;
                    803: }
                    804: 
                    805: /**
                    806:  * Returns the length of the common prefix in bits up to the length of a's
                    807:  * prefix, defined by RFC 6724 as the portion of the address not including the
                    808:  * interface ID, which is 64-bit for most unicast addresses (see RFC 4291).
                    809:  */
                    810: static u_char common_prefix(host_t *a, host_t *b)
                    811: {
                    812:        chunk_t aa, ba;
                    813:        u_char byte, bits = 0, match;
                    814: 
                    815:        aa = a->get_address(a);
                    816:        ba = b->get_address(b);
                    817:        for (byte = 0; byte < 8; byte++)
                    818:        {
                    819:                if (aa.ptr[byte] != ba.ptr[byte])
                    820:                {
                    821:                        match = aa.ptr[byte] ^ ba.ptr[byte];
                    822:                        for (bits = 8; match; match >>= 1)
                    823:                        {
                    824:                                bits--;
                    825:                        }
                    826:                        break;
                    827:                }
                    828:        }
                    829:        return byte * 8 + bits;
                    830: }
                    831: 
                    832: /**
                    833:  * Compare two IP addresses and return TRUE if the second address is the better
                    834:  * choice of the two to reach the destination.
                    835:  * For IPv6 we approximately follow RFC 6724.
                    836:  */
                    837: static bool is_address_better(private_kernel_netlink_net_t *this,
                    838:                                                          addr_entry_t *a, addr_entry_t *b, host_t *d)
                    839: {
                    840:        u_char sa, sb, sd, la, lb, ld, pa, pb;
                    841: 
                    842:        /* rule 2: prefer appropriate scope */
                    843:        if (d)
                    844:        {
                    845:                sa = get_scope(a->ip);
                    846:                sb = get_scope(b->ip);
                    847:                sd = get_scope(d);
                    848:                if (sa < sb)
                    849:                {
                    850:                        return sa < sd;
                    851:                }
                    852:                else if (sb < sa)
                    853:                {
                    854:                        return sb >= sd;
                    855:                }
                    856:        }
                    857:        if (a->ip->get_family(a->ip) == AF_INET)
                    858:        {       /* stop here for IPv4, default to addresses found earlier */
                    859:                return FALSE;
                    860:        }
                    861:        /* rule 3: avoid deprecated addresses (RFC 4862) */
                    862:        if ((a->flags & IFA_F_DEPRECATED) != (b->flags & IFA_F_DEPRECATED))
                    863:        {
                    864:                return a->flags & IFA_F_DEPRECATED;
                    865:        }
                    866:        /* rule 4 is not applicable as we don't know if an address is a home or
                    867:         * care-of addresses.
                    868:         * rule 5 does not apply as we only compare addresses from one interface
                    869:         */
                    870:        /* rule 6: prefer matching label */
                    871:        if (d)
                    872:        {
                    873:                la = get_label(a->ip);
                    874:                lb = get_label(b->ip);
                    875:                ld = get_label(d);
                    876:                if (la == ld && lb != ld)
                    877:                {
                    878:                        return FALSE;
                    879:                }
                    880:                else if (lb == ld && la != ld)
                    881:                {
                    882:                        return TRUE;
                    883:                }
                    884:        }
                    885:        /* rule 7: prefer temporary addresses (WE REVERSE THIS BY DEFAULT!) */
                    886:        if ((a->flags & IFA_F_TEMPORARY) != (b->flags & IFA_F_TEMPORARY))
                    887:        {
                    888:                if (this->prefer_temporary_addrs)
                    889:                {
                    890:                        return b->flags & IFA_F_TEMPORARY;
                    891:                }
                    892:                return a->flags & IFA_F_TEMPORARY;
                    893:        }
                    894:        /* rule 8: use longest matching prefix */
                    895:        if (d)
                    896:        {
                    897:                pa = common_prefix(a->ip, d);
                    898:                pb = common_prefix(b->ip, d);
                    899:                if (pa != pb)
                    900:                {
                    901:                        return pb > pa;
                    902:                }
                    903:        }
                    904:        /* default to addresses found earlier */
                    905:        return FALSE;
                    906: }
                    907: 
                    908: /**
                    909:  * Get a non-virtual IP address on the given interfaces and optionally in a
                    910:  * given subnet.
                    911:  *
                    912:  * If a candidate address is given, we first search for that address and if not
                    913:  * found return the address as above.
                    914:  * Returned host is a clone, has to be freed by caller.
                    915:  *
                    916:  * this->lock must be held when calling this function.
                    917:  */
                    918: static host_t *get_matching_address(private_kernel_netlink_net_t *this,
                    919:                                                                        int *ifindex, int family, chunk_t net,
                    920:                                                                        uint8_t mask, host_t *dest,
                    921:                                                                        host_t *candidate)
                    922: {
                    923:        enumerator_t *ifaces, *addrs;
                    924:        iface_entry_t *iface;
                    925:        addr_entry_t *addr, *best = NULL;
                    926:        bool candidate_matched = FALSE;
                    927: 
                    928:        ifaces = this->ifaces->create_enumerator(this->ifaces);
                    929:        while (ifaces->enumerate(ifaces, &iface))
                    930:        {
                    931:                if (iface->usable && (!ifindex || iface->ifindex == *ifindex))
                    932:                {       /* only use matching interfaces not excluded by config */
                    933:                        addrs = iface->addrs->create_enumerator(iface->addrs);
                    934:                        while (addrs->enumerate(addrs, &addr))
                    935:                        {
                    936:                                if (addr->refcount ||
                    937:                                        addr->ip->get_family(addr->ip) != family)
                    938:                                {       /* ignore virtual IP addresses and ensure family matches */
                    939:                                        continue;
                    940:                                }
                    941:                                if (net.ptr && !host_in_subnet(addr->ip, net, mask))
                    942:                                {       /* optionally match a subnet */
                    943:                                        continue;
                    944:                                }
                    945:                                if (candidate && candidate->ip_equals(candidate, addr->ip))
                    946:                                {       /* stop if we find the candidate */
                    947:                                        best = addr;
                    948:                                        candidate_matched = TRUE;
                    949:                                        break;
                    950:                                }
                    951:                                else if (!best || is_address_better(this, best, addr, dest))
                    952:                                {
                    953:                                        best = addr;
                    954:                                }
                    955:                        }
                    956:                        addrs->destroy(addrs);
                    957:                        if (ifindex || candidate_matched)
                    958:                        {
                    959:                                break;
                    960:                        }
                    961:                }
                    962:        }
                    963:        ifaces->destroy(ifaces);
                    964:        return best ? best->ip->clone(best->ip) : NULL;
                    965: }
                    966: 
                    967: /**
                    968:  * Get a non-virtual IP address on the given interface.
                    969:  *
                    970:  * If a candidate address is given, we first search for that address and if not
                    971:  * found return the address as above.
                    972:  * Returned host is a clone, has to be freed by caller.
                    973:  *
                    974:  * this->lock must be held when calling this function.
                    975:  */
                    976: static host_t *get_interface_address(private_kernel_netlink_net_t *this,
                    977:                                                                         int ifindex, int family, host_t *dest,
                    978:                                                                         host_t *candidate)
                    979: {
                    980:        return get_matching_address(this, &ifindex, family, chunk_empty, 0, dest,
                    981:                                                                candidate);
                    982: }
                    983: 
                    984: /**
                    985:  * Get a non-virtual IP address in the given subnet.
                    986:  *
                    987:  * If a candidate address is given, we first search for that address and if not
                    988:  * found return the address as above.
                    989:  * Returned host is a clone, has to be freed by caller.
                    990:  *
                    991:  * this->lock must be held when calling this function.
                    992:  */
                    993: static host_t *get_subnet_address(private_kernel_netlink_net_t *this,
                    994:                                                                  int family, chunk_t net, uint8_t mask,
                    995:                                                                  host_t *dest, host_t *candidate)
                    996: {
                    997:        return get_matching_address(this, NULL, family, net, mask, dest, candidate);
                    998: }
                    999: 
                   1000: /**
                   1001:  * callback function that raises the delayed roam event
                   1002:  */
                   1003: static job_requeue_t roam_event(private_kernel_netlink_net_t *this)
                   1004: {
                   1005:        bool address;
                   1006: 
                   1007:        this->roam_lock->lock(this->roam_lock);
                   1008:        address = this->roam_address;
                   1009:        this->roam_address = FALSE;
                   1010:        this->roam_lock->unlock(this->roam_lock);
                   1011:        charon->kernel->roam(charon->kernel, address);
                   1012:        return JOB_REQUEUE_NONE;
                   1013: }
                   1014: 
                   1015: /**
                   1016:  * fire a roaming event. we delay it for a bit and fire only one event
                   1017:  * for multiple calls. otherwise we would create too many events.
                   1018:  */
                   1019: static void fire_roam_event(private_kernel_netlink_net_t *this, bool address)
                   1020: {
                   1021:        timeval_t now;
                   1022:        job_t *job;
                   1023: 
                   1024:        if (!this->roam_events)
                   1025:        {
                   1026:                return;
                   1027:        }
                   1028: 
                   1029:        time_monotonic(&now);
                   1030:        this->roam_lock->lock(this->roam_lock);
                   1031:        this->roam_address |= address;
                   1032:        if (!timercmp(&now, &this->next_roam, >))
                   1033:        {
                   1034:                this->roam_lock->unlock(this->roam_lock);
                   1035:                return;
                   1036:        }
                   1037:        timeval_add_ms(&now, ROAM_DELAY);
                   1038:        this->next_roam = now;
                   1039:        this->roam_lock->unlock(this->roam_lock);
                   1040: 
                   1041:        job = (job_t*)callback_job_create((callback_job_cb_t)roam_event,
                   1042:                                                                          this, NULL, NULL);
                   1043:        lib->scheduler->schedule_job_ms(lib->scheduler, job, ROAM_DELAY);
                   1044: }
                   1045: 
                   1046: /**
                   1047:  * check if an interface with a given index is up and usable
                   1048:  *
                   1049:  * this->lock must be locked when calling this function
                   1050:  */
                   1051: static bool is_interface_up_and_usable(private_kernel_netlink_net_t *this,
                   1052:                                                                           int index)
                   1053: {
                   1054:        iface_entry_t *iface;
                   1055: 
                   1056:        if (this->ifaces->find_first(this->ifaces, iface_entry_by_index,
                   1057:                                                                 (void**)&iface, index))
                   1058:        {
                   1059:                return iface_entry_up_and_usable(iface);
                   1060:        }
                   1061:        return FALSE;
                   1062: }
                   1063: 
                   1064: /**
                   1065:  * unregister the current addr_entry_t from the hashtable it is stored in
                   1066:  *
                   1067:  * this->lock must be locked when calling this function
                   1068:  */
                   1069: CALLBACK(addr_entry_unregister, void,
                   1070:        addr_entry_t *addr, va_list args)
                   1071: {
                   1072:        private_kernel_netlink_net_t *this;
                   1073:        iface_entry_t *iface;
                   1074: 
                   1075:        VA_ARGS_VGET(args, iface, this);
                   1076:        if (addr->refcount)
                   1077:        {
                   1078:                addr_map_entry_remove(this->vips, addr, iface);
                   1079:                this->condvar->broadcast(this->condvar);
                   1080:                return;
                   1081:        }
                   1082:        addr_map_entry_remove(this->addrs, addr, iface);
                   1083: }
                   1084: 
                   1085: /**
                   1086:  * process RTM_NEWLINK/RTM_DELLINK from kernel
                   1087:  */
                   1088: static void process_link(private_kernel_netlink_net_t *this,
                   1089:                                                 struct nlmsghdr *hdr, bool event)
                   1090: {
                   1091:        struct ifinfomsg* msg = NLMSG_DATA(hdr);
                   1092:        struct rtattr *rta = IFLA_RTA(msg);
                   1093:        size_t rtasize = IFLA_PAYLOAD (hdr);
                   1094:        enumerator_t *enumerator;
                   1095:        iface_entry_t *current, *entry = NULL;
                   1096:        char *name = NULL;
                   1097:        bool update = FALSE, update_routes = FALSE;
                   1098: 
                   1099:        while (RTA_OK(rta, rtasize))
                   1100:        {
                   1101:                switch (rta->rta_type)
                   1102:                {
                   1103:                        case IFLA_IFNAME:
                   1104:                                name = RTA_DATA(rta);
                   1105:                                break;
                   1106:                }
                   1107:                rta = RTA_NEXT(rta, rtasize);
                   1108:        }
                   1109:        if (!name)
                   1110:        {
                   1111:                name = "(unknown)";
                   1112:        }
                   1113: 
                   1114:        this->lock->write_lock(this->lock);
                   1115:        switch (hdr->nlmsg_type)
                   1116:        {
                   1117:                case RTM_NEWLINK:
                   1118:                {
                   1119:                        if (!this->ifaces->find_first(this->ifaces, iface_entry_by_index,
                   1120:                                                                                 (void**)&entry, msg->ifi_index))
                   1121:                        {
                   1122:                                INIT(entry,
                   1123:                                        .ifindex = msg->ifi_index,
                   1124:                                        .addrs = linked_list_create(),
                   1125:                                );
                   1126:                                this->ifaces->insert_last(this->ifaces, entry);
                   1127:                        }
                   1128:                        strncpy(entry->ifname, name, IFNAMSIZ);
                   1129:                        entry->ifname[IFNAMSIZ-1] = '\0';
                   1130:                        entry->usable = charon->kernel->is_interface_usable(charon->kernel,
                   1131:                                                                                                                                name);
                   1132:                        if (event && entry->usable)
                   1133:                        {
                   1134:                                if (!(entry->flags & IFF_UP) && (msg->ifi_flags & IFF_UP))
                   1135:                                {
                   1136:                                        update = update_routes = TRUE;
                   1137:                                        DBG1(DBG_KNL, "interface %s activated", name);
                   1138:                                }
                   1139:                                if ((entry->flags & IFF_UP) && !(msg->ifi_flags & IFF_UP))
                   1140:                                {
                   1141:                                        update = TRUE;
                   1142:                                        DBG1(DBG_KNL, "interface %s deactivated", name);
                   1143:                                }
                   1144:                        }
                   1145:                        entry->flags = msg->ifi_flags;
                   1146:                        break;
                   1147:                }
                   1148:                case RTM_DELLINK:
                   1149:                {
                   1150:                        enumerator = this->ifaces->create_enumerator(this->ifaces);
                   1151:                        while (enumerator->enumerate(enumerator, &current))
                   1152:                        {
                   1153:                                if (current->ifindex == msg->ifi_index)
                   1154:                                {
                   1155:                                        if (event && current->usable)
                   1156:                                        {
                   1157:                                                update = TRUE;
                   1158:                                                DBG1(DBG_KNL, "interface %s deleted", current->ifname);
                   1159:                                        }
                   1160:                                        /* TODO: move virtual IPs installed on this interface to
                   1161:                                         * another interface? */
                   1162:                                        this->ifaces->remove_at(this->ifaces, enumerator);
                   1163:                                        current->addrs->invoke_function(current->addrs,
                   1164:                                                                                addr_entry_unregister, current, this);
                   1165:                                        iface_entry_destroy(current);
                   1166:                                        break;
                   1167:                                }
                   1168:                        }
                   1169:                        enumerator->destroy(enumerator);
                   1170:                        break;
                   1171:                }
                   1172:        }
                   1173:        this->lock->unlock(this->lock);
                   1174: 
                   1175:        if (update_routes && event)
                   1176:        {
                   1177:                queue_route_reinstall(this, strdup(name));
                   1178:        }
                   1179: 
                   1180:        if (update && event)
                   1181:        {
                   1182:                fire_roam_event(this, TRUE);
                   1183:        }
                   1184: }
                   1185: 
                   1186: /**
                   1187:  * process RTM_NEWADDR/RTM_DELADDR from kernel
                   1188:  */
                   1189: static void process_addr(private_kernel_netlink_net_t *this,
                   1190:                                                 struct nlmsghdr *hdr, bool event)
                   1191: {
                   1192:        struct ifaddrmsg* msg = NLMSG_DATA(hdr);
                   1193:        struct rtattr *rta = IFA_RTA(msg);
                   1194:        size_t rtasize = IFA_PAYLOAD (hdr);
                   1195:        host_t *host = NULL;
                   1196:        iface_entry_t *iface;
                   1197:        chunk_t local = chunk_empty, address = chunk_empty;
                   1198:        char *route_ifname = NULL;
                   1199:        bool update = FALSE, found = FALSE, changed = FALSE;
                   1200: 
                   1201:        while (RTA_OK(rta, rtasize))
                   1202:        {
                   1203:                switch (rta->rta_type)
                   1204:                {
                   1205:                        case IFA_LOCAL:
                   1206:                                local.ptr = RTA_DATA(rta);
                   1207:                                local.len = RTA_PAYLOAD(rta);
                   1208:                                break;
                   1209:                        case IFA_ADDRESS:
                   1210:                                address.ptr = RTA_DATA(rta);
                   1211:                                address.len = RTA_PAYLOAD(rta);
                   1212:                                break;
                   1213:                }
                   1214:                rta = RTA_NEXT(rta, rtasize);
                   1215:        }
                   1216: 
                   1217:        /* For PPP interfaces, we need the IFA_LOCAL address,
                   1218:         * IFA_ADDRESS is the peers address. But IFA_LOCAL is
                   1219:         * not included in all cases (IPv6?), so fallback to IFA_ADDRESS. */
                   1220:        if (local.ptr)
                   1221:        {
                   1222:                host = host_create_from_chunk(msg->ifa_family, local, 0);
                   1223:        }
                   1224:        else if (address.ptr)
                   1225:        {
                   1226:                host = host_create_from_chunk(msg->ifa_family, address, 0);
                   1227:        }
                   1228: 
                   1229:        if (host == NULL)
                   1230:        {       /* bad family? */
                   1231:                return;
                   1232:        }
                   1233: 
                   1234:        this->lock->write_lock(this->lock);
                   1235:        if (this->ifaces->find_first(this->ifaces, iface_entry_by_index,
                   1236:                                                                 (void**)&iface, msg->ifa_index))
                   1237:        {
                   1238:                addr_map_entry_t *entry, lookup = {
                   1239:                        .ip = host,
                   1240:                        .iface = iface,
                   1241:                };
                   1242:                addr_entry_t *addr;
                   1243: 
                   1244:                entry = this->vips->get(this->vips, &lookup);
                   1245:                if (entry)
                   1246:                {
                   1247:                        if (hdr->nlmsg_type == RTM_NEWADDR)
                   1248:                        {       /* mark as installed and signal waiting threads */
                   1249:                                entry->addr->installed = TRUE;
                   1250:                        }
                   1251:                        else
                   1252:                        {       /* the address was already marked as uninstalled */
                   1253:                                addr = entry->addr;
                   1254:                                iface->addrs->remove(iface->addrs, addr, NULL);
                   1255:                                addr_map_entry_remove(this->vips, addr, iface);
                   1256:                                addr_entry_destroy(addr);
                   1257:                        }
                   1258:                        /* no roam events etc. for virtual IPs */
                   1259:                        this->condvar->broadcast(this->condvar);
                   1260:                        this->lock->unlock(this->lock);
                   1261:                        host->destroy(host);
                   1262:                        return;
                   1263:                }
                   1264:                entry = this->addrs->get(this->addrs, &lookup);
                   1265:                if (entry)
                   1266:                {
                   1267:                        if (hdr->nlmsg_type == RTM_DELADDR)
                   1268:                        {
                   1269:                                found = TRUE;
                   1270:                                addr = entry->addr;
                   1271:                                iface->addrs->remove(iface->addrs, addr, NULL);
                   1272:                                if (iface->usable)
                   1273:                                {
                   1274:                                        changed = TRUE;
                   1275:                                        DBG1(DBG_KNL, "%H disappeared from %s", host,
                   1276:                                                 iface->ifname);
                   1277:                                }
                   1278:                                addr_map_entry_remove(this->addrs, addr, iface);
                   1279:                                addr_entry_destroy(addr);
                   1280:                        }
                   1281:                }
                   1282:                else
                   1283:                {
                   1284:                        if (hdr->nlmsg_type == RTM_NEWADDR)
                   1285:                        {
                   1286:                                found = TRUE;
                   1287:                                changed = TRUE;
                   1288:                                route_ifname = strdup(iface->ifname);
                   1289:                                INIT(addr,
                   1290:                                        .ip = host->clone(host),
                   1291:                                        .flags = msg->ifa_flags,
                   1292:                                        .scope = msg->ifa_scope,
                   1293:                                );
                   1294:                                iface->addrs->insert_last(iface->addrs, addr);
                   1295:                                addr_map_entry_add(this->addrs, addr, iface);
                   1296:                                if (event && iface->usable)
                   1297:                                {
                   1298:                                        DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname);
                   1299:                                }
                   1300:                        }
                   1301:                }
                   1302:                if (found && (iface->flags & IFF_UP))
                   1303:                {
                   1304:                        update = TRUE;
                   1305:                }
                   1306:                if (!iface->usable)
                   1307:                {       /* ignore events for interfaces excluded by config */
                   1308:                        update = changed = FALSE;
                   1309:                }
                   1310:        }
                   1311:        this->lock->unlock(this->lock);
                   1312: 
                   1313:        if (update && event && route_ifname)
                   1314:        {
                   1315:                queue_route_reinstall(this, route_ifname);
                   1316:        }
                   1317:        else
                   1318:        {
                   1319:                free(route_ifname);
                   1320:        }
                   1321:        host->destroy(host);
                   1322: 
                   1323:        /* send an update to all IKE_SAs */
                   1324:        if (update && event && changed)
                   1325:        {
                   1326:                fire_roam_event(this, TRUE);
                   1327:        }
                   1328: }
                   1329: 
                   1330: /**
                   1331:  * process RTM_NEWROUTE and RTM_DELROUTE from kernel
                   1332:  */
                   1333: static void process_route(private_kernel_netlink_net_t *this,
                   1334:                                                  struct nlmsghdr *hdr)
                   1335: {
                   1336:        struct rtmsg* msg = NLMSG_DATA(hdr);
                   1337:        struct rtattr *rta = RTM_RTA(msg);
                   1338:        size_t rtasize = RTM_PAYLOAD(hdr);
                   1339:        uint32_t rta_oif = 0;
                   1340:        host_t *host = NULL;
                   1341: 
                   1342:        /* ignore routes added by us or in the local routing table (local addrs) */
                   1343:        if (msg->rtm_table && (msg->rtm_table == this->routing_table ||
                   1344:                                                   msg->rtm_table == RT_TABLE_LOCAL))
                   1345:        {
                   1346:                return;
                   1347:        }
                   1348:        else if (msg->rtm_flags & RTM_F_CLONED)
                   1349:        {       /* ignore cached routes, seem to be created a lot for IPv6 */
                   1350:                return;
                   1351:        }
                   1352: 
                   1353:        while (RTA_OK(rta, rtasize))
                   1354:        {
                   1355:                switch (rta->rta_type)
                   1356:                {
                   1357: #ifdef HAVE_RTA_TABLE
                   1358:                        case RTA_TABLE:
                   1359:                                /* also check against extended table ID */
                   1360:                                if (RTA_PAYLOAD(rta) == sizeof(uint32_t) &&
                   1361:                                        this->routing_table == *(uint32_t*)RTA_DATA(rta))
                   1362:                                {
                   1363:                                        return;
                   1364:                                }
                   1365:                                break;
                   1366: #endif /* HAVE_RTA_TABLE */
                   1367:                        case RTA_PREFSRC:
                   1368:                                DESTROY_IF(host);
                   1369:                                host = host_create_from_chunk(msg->rtm_family,
                   1370:                                                        chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)), 0);
                   1371:                                break;
                   1372:                        case RTA_OIF:
                   1373:                                if (RTA_PAYLOAD(rta) == sizeof(rta_oif))
                   1374:                                {
                   1375:                                        rta_oif = *(uint32_t*)RTA_DATA(rta);
                   1376:                                }
                   1377:                                break;
                   1378:                }
                   1379:                rta = RTA_NEXT(rta, rtasize);
                   1380:        }
                   1381:        this->lock->read_lock(this->lock);
                   1382:        if (rta_oif && !is_interface_up_and_usable(this, rta_oif))
                   1383:        {       /* ignore route changes for interfaces that are ignored or down */
                   1384:                this->lock->unlock(this->lock);
                   1385:                DESTROY_IF(host);
                   1386:                return;
                   1387:        }
                   1388:        if (!host && rta_oif)
                   1389:        {
                   1390:                host = get_interface_address(this, rta_oif, msg->rtm_family,
                   1391:                                                                         NULL, NULL);
                   1392:        }
                   1393:        if (!host || is_known_vip(this, host))
                   1394:        {       /* ignore routes added for virtual IPs */
                   1395:                this->lock->unlock(this->lock);
                   1396:                DESTROY_IF(host);
                   1397:                return;
                   1398:        }
                   1399:        this->lock->unlock(this->lock);
                   1400:        fire_roam_event(this, FALSE);
                   1401:        host->destroy(host);
                   1402: }
                   1403: 
                   1404: /**
                   1405:  * process RTM_NEW|DELRULE from kernel
                   1406:  */
                   1407: static void process_rule(private_kernel_netlink_net_t *this,
                   1408:                                                 struct nlmsghdr *hdr)
                   1409: {
                   1410: #ifdef HAVE_LINUX_FIB_RULES_H
                   1411:        struct rtmsg* msg = NLMSG_DATA(hdr);
                   1412:        struct rtattr *rta = RTM_RTA(msg);
                   1413:        size_t rtasize = RTM_PAYLOAD(hdr);
                   1414: 
                   1415:        /* ignore rules added by us or in the local routing table (local addrs) */
                   1416:        if (msg->rtm_table && (msg->rtm_table == this->routing_table ||
                   1417:                                                   msg->rtm_table == RT_TABLE_LOCAL))
                   1418:        {
                   1419:                return;
                   1420:        }
                   1421: 
                   1422:        while (RTA_OK(rta, rtasize))
                   1423:        {
                   1424:                switch (rta->rta_type)
                   1425:                {
                   1426:                        case FRA_TABLE:
                   1427:                                /* also check against extended table ID */
                   1428:                                if (RTA_PAYLOAD(rta) == sizeof(uint32_t) &&
                   1429:                                        this->routing_table == *(uint32_t*)RTA_DATA(rta))
                   1430:                                {
                   1431:                                        return;
                   1432:                                }
                   1433:                                break;
                   1434:                }
                   1435:                rta = RTA_NEXT(rta, rtasize);
                   1436:        }
                   1437:        fire_roam_event(this, FALSE);
                   1438: #endif
                   1439: }
                   1440: 
                   1441: /**
                   1442:  * Receives events from kernel
                   1443:  */
                   1444: static bool receive_events(private_kernel_netlink_net_t *this, int fd,
                   1445:                                                   watcher_event_t event)
                   1446: {
                   1447:        char response[netlink_get_buflen()];
                   1448:        struct nlmsghdr *hdr = (struct nlmsghdr*)response;
                   1449:        struct sockaddr_nl addr;
                   1450:        socklen_t addr_len = sizeof(addr);
                   1451:        int len;
                   1452: 
                   1453:        len = recvfrom(this->socket_events, response, sizeof(response),
                   1454:                                   MSG_DONTWAIT, (struct sockaddr*)&addr, &addr_len);
                   1455:        if (len < 0)
                   1456:        {
                   1457:                switch (errno)
                   1458:                {
                   1459:                        case EINTR:
                   1460:                                /* interrupted, try again */
                   1461:                                return TRUE;
                   1462:                        case EAGAIN:
                   1463:                                /* no data ready, select again */
                   1464:                                return TRUE;
                   1465:                        default:
                   1466:                                DBG1(DBG_KNL, "unable to receive from RT event socket %s (%d)",
                   1467:                                         strerror(errno), errno);
                   1468:                                sleep(1);
                   1469:                                return TRUE;
                   1470:                }
                   1471:        }
                   1472: 
                   1473:        if (addr.nl_pid != 0)
                   1474:        {       /* not from kernel. not interested, try another one */
                   1475:                return TRUE;
                   1476:        }
                   1477: 
                   1478:        while (NLMSG_OK(hdr, len))
                   1479:        {
                   1480:                /* looks good so far, dispatch netlink message */
                   1481:                switch (hdr->nlmsg_type)
                   1482:                {
                   1483:                        case RTM_NEWADDR:
                   1484:                        case RTM_DELADDR:
                   1485:                                process_addr(this, hdr, TRUE);
                   1486:                                break;
                   1487:                        case RTM_NEWLINK:
                   1488:                        case RTM_DELLINK:
                   1489:                                process_link(this, hdr, TRUE);
                   1490:                                break;
                   1491:                        case RTM_NEWROUTE:
                   1492:                        case RTM_DELROUTE:
                   1493:                                if (this->process_route)
                   1494:                                {
                   1495:                                        process_route(this, hdr);
                   1496:                                }
                   1497:                                break;
                   1498:                        case RTM_NEWRULE:
                   1499:                        case RTM_DELRULE:
                   1500:                                if (this->process_rules)
                   1501:                                {
                   1502:                                        process_rule(this, hdr);
                   1503:                                }
                   1504:                                break;
                   1505:                        default:
                   1506:                                break;
                   1507:                }
                   1508:                hdr = NLMSG_NEXT(hdr, len);
                   1509:        }
                   1510:        return TRUE;
                   1511: }
                   1512: 
                   1513: /** enumerator over addresses */
                   1514: typedef struct {
                   1515:        private_kernel_netlink_net_t* this;
                   1516:        /** which addresses to enumerate */
                   1517:        kernel_address_type_t which;
                   1518: } address_enumerator_t;
                   1519: 
                   1520: CALLBACK(address_enumerator_destroy, void,
                   1521:        address_enumerator_t *data)
                   1522: {
                   1523:        data->this->lock->unlock(data->this->lock);
                   1524:        free(data);
                   1525: }
                   1526: 
                   1527: CALLBACK(filter_addresses, bool,
                   1528:        address_enumerator_t *data, enumerator_t *orig, va_list args)
                   1529: {
                   1530:        addr_entry_t *addr;
                   1531:        host_t **out;
                   1532: 
                   1533:        VA_ARGS_VGET(args, out);
                   1534: 
                   1535:        while (orig->enumerate(orig, &addr))
                   1536:        {
                   1537:                if (!(data->which & ADDR_TYPE_VIRTUAL) && addr->refcount)
                   1538:                {       /* skip virtual interfaces added by us */
                   1539:                        continue;
                   1540:                }
                   1541:                if (!(data->which & ADDR_TYPE_REGULAR) && !addr->refcount)
                   1542:                {       /* address is regular, but not requested */
                   1543:                        continue;
                   1544:                }
                   1545:                if (addr->flags & IFA_F_DEPRECATED ||
                   1546:                        addr->scope >= RT_SCOPE_LINK)
                   1547:                {       /* skip deprecated addresses or those with an unusable scope */
                   1548:                        continue;
                   1549:                }
                   1550:                if (addr->ip->get_family(addr->ip) == AF_INET6)
                   1551:                {       /* handle temporary IPv6 addresses according to config */
                   1552:                        bool temporary = (addr->flags & IFA_F_TEMPORARY) == IFA_F_TEMPORARY;
                   1553:                        if (data->this->prefer_temporary_addrs != temporary)
                   1554:                        {
                   1555:                                continue;
                   1556:                        }
                   1557:                }
                   1558:                *out = addr->ip;
                   1559:                return TRUE;
                   1560:        }
                   1561:        return FALSE;
                   1562: }
                   1563: 
                   1564: /**
                   1565:  * enumerator constructor for interfaces
                   1566:  */
                   1567: static enumerator_t *create_iface_enumerator(iface_entry_t *iface,
                   1568:                                                                                         address_enumerator_t *data)
                   1569: {
                   1570:        return enumerator_create_filter(
                   1571:                                                iface->addrs->create_enumerator(iface->addrs),
                   1572:                                                filter_addresses, data, NULL);
                   1573: }
                   1574: 
                   1575: CALLBACK(filter_interfaces, bool,
                   1576:        address_enumerator_t *data, enumerator_t *orig, va_list args)
                   1577: {
                   1578:        iface_entry_t *iface, **out;
                   1579: 
                   1580:        VA_ARGS_VGET(args, out);
                   1581: 
                   1582:        while (orig->enumerate(orig, &iface))
                   1583:        {
                   1584:                if (!(data->which & ADDR_TYPE_IGNORED) && !iface->usable)
                   1585:                {       /* skip interfaces excluded by config */
                   1586:                        continue;
                   1587:                }
                   1588:                if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK))
                   1589:                {       /* ignore loopback devices */
                   1590:                        continue;
                   1591:                }
                   1592:                if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP))
                   1593:                {       /* skip interfaces not up */
                   1594:                        continue;
                   1595:                }
                   1596:                *out = iface;
                   1597:                return TRUE;
                   1598:        }
                   1599:        return FALSE;
                   1600: }
                   1601: 
                   1602: METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
                   1603:        private_kernel_netlink_net_t *this, kernel_address_type_t which)
                   1604: {
                   1605:        address_enumerator_t *data;
                   1606: 
                   1607:        INIT(data,
                   1608:                .this = this,
                   1609:                .which = which,
                   1610:        );
                   1611: 
                   1612:        this->lock->read_lock(this->lock);
                   1613:        return enumerator_create_nested(
                   1614:                                enumerator_create_filter(
                   1615:                                        this->ifaces->create_enumerator(this->ifaces),
                   1616:                                        filter_interfaces, data, NULL),
                   1617:                                (void*)create_iface_enumerator, data,
                   1618:                                address_enumerator_destroy);
                   1619: }
                   1620: 
                   1621: METHOD(kernel_net_t, get_interface_name, bool,
                   1622:        private_kernel_netlink_net_t *this, host_t* ip, char **name)
                   1623: {
                   1624:        addr_map_entry_t *entry, lookup = {
                   1625:                .ip = ip,
                   1626:        };
                   1627: 
                   1628:        if (ip->is_anyaddr(ip))
                   1629:        {
                   1630:                return FALSE;
                   1631:        }
                   1632:        this->lock->read_lock(this->lock);
                   1633:        /* first try to find it on an up and usable interface */
                   1634:        entry = this->addrs->get_match(this->addrs, &lookup,
                   1635:                                                                  (void*)addr_map_entry_match_up_and_usable);
                   1636:        if (entry)
                   1637:        {
                   1638:                if (name)
                   1639:                {
                   1640:                        *name = strdup(entry->iface->ifname);
                   1641:                        DBG2(DBG_KNL, "%H is on interface %s", ip, *name);
                   1642:                }
                   1643:                this->lock->unlock(this->lock);
                   1644:                return TRUE;
                   1645:        }
                   1646:        /* in a second step, consider virtual IPs installed by us */
                   1647:        entry = this->vips->get_match(this->vips, &lookup,
                   1648:                                                                  (void*)addr_map_entry_match_up_and_usable);
                   1649:        if (entry)
                   1650:        {
                   1651:                if (name)
                   1652:                {
                   1653:                        *name = strdup(entry->iface->ifname);
                   1654:                        DBG2(DBG_KNL, "virtual IP %H is on interface %s", ip, *name);
                   1655:                }
                   1656:                this->lock->unlock(this->lock);
                   1657:                return TRUE;
                   1658:        }
                   1659:        /* maybe it is installed on an ignored interface */
                   1660:        entry = this->addrs->get_match(this->addrs, &lookup,
                   1661:                                                                  (void*)addr_map_entry_match_up);
                   1662:        if (!entry)
                   1663:        {
                   1664:                DBG2(DBG_KNL, "%H is not a local address or the interface is down", ip);
                   1665:        }
                   1666:        this->lock->unlock(this->lock);
                   1667:        return FALSE;
                   1668: }
                   1669: 
                   1670: /**
                   1671:  * get the index of an interface by name
                   1672:  */
                   1673: static int get_interface_index(private_kernel_netlink_net_t *this, char* name)
                   1674: {
                   1675:        iface_entry_t *iface;
                   1676:        int ifindex = 0;
                   1677: 
                   1678:        DBG2(DBG_KNL, "getting iface index for %s", name);
                   1679: 
                   1680:        this->lock->read_lock(this->lock);
                   1681:        if (this->ifaces->find_first(this->ifaces, iface_entry_by_name,
                   1682:                                                                (void**)&iface, name))
                   1683:        {
                   1684:                ifindex = iface->ifindex;
                   1685:        }
                   1686:        this->lock->unlock(this->lock);
                   1687: 
                   1688:        if (ifindex == 0)
                   1689:        {
                   1690:                DBG1(DBG_KNL, "unable to get interface index for %s", name);
                   1691:        }
                   1692:        return ifindex;
                   1693: }
                   1694: 
                   1695: /**
                   1696:  * get the name of an interface by index (allocated)
                   1697:  */
                   1698: static char *get_interface_name_by_index(private_kernel_netlink_net_t *this,
                   1699:                                                                                 int index)
                   1700: {
                   1701:        iface_entry_t *iface;
                   1702:        char *name = NULL;
                   1703: 
                   1704:        DBG2(DBG_KNL, "getting iface name for index %d", index);
                   1705: 
                   1706:        this->lock->read_lock(this->lock);
                   1707:        if (this->ifaces->find_first(this->ifaces, iface_entry_by_index,
                   1708:                                                                (void**)&iface, index))
                   1709:        {
                   1710:                name = strdup(iface->ifname);
                   1711:        }
                   1712:        this->lock->unlock(this->lock);
                   1713: 
                   1714:        if (!name)
                   1715:        {
                   1716:                DBG1(DBG_KNL, "unable to get interface name for %d", index);
                   1717:        }
                   1718:        return name;
                   1719: }
                   1720: 
                   1721: /**
                   1722:  * Store information about a route retrieved via RTNETLINK
                   1723:  */
                   1724: typedef struct {
                   1725:        chunk_t gtw;
                   1726:        chunk_t pref_src;
                   1727:        chunk_t dst;
                   1728:        chunk_t src;
                   1729:        host_t *src_host;
                   1730:        uint8_t dst_len;
                   1731:        uint8_t src_len;
                   1732:        uint32_t table;
                   1733:        uint32_t oif;
                   1734:        uint32_t priority;
                   1735: } rt_entry_t;
                   1736: 
                   1737: /**
                   1738:  * Free a route entry
                   1739:  */
                   1740: static void rt_entry_destroy(rt_entry_t *this)
                   1741: {
                   1742:        DESTROY_IF(this->src_host);
                   1743:        free(this);
                   1744: }
                   1745: 
                   1746: /**
                   1747:  * Check if the route received with RTM_NEWROUTE is usable based on its type.
                   1748:  */
                   1749: static bool route_usable(struct nlmsghdr *hdr, bool allow_local)
                   1750: {
                   1751:        struct rtmsg *msg;
                   1752: 
                   1753:        msg = NLMSG_DATA(hdr);
                   1754:        switch (msg->rtm_type)
                   1755:        {
                   1756:                case RTN_BLACKHOLE:
                   1757:                case RTN_UNREACHABLE:
                   1758:                case RTN_PROHIBIT:
                   1759:                case RTN_THROW:
                   1760:                        return FALSE;
                   1761:                case RTN_LOCAL:
                   1762:                        return allow_local;
                   1763:                default:
                   1764:                        return TRUE;
                   1765:        }
                   1766: }
                   1767: 
                   1768: /**
                   1769:  * Parse route received with RTM_NEWROUTE. The given rt_entry_t object will be
                   1770:  * reused if not NULL.
                   1771:  *
                   1772:  * Returned chunks point to internal data of the Netlink message.
                   1773:  */
                   1774: static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route)
                   1775: {
                   1776:        struct rtattr *rta;
                   1777:        struct rtmsg *msg;
                   1778:        size_t rtasize;
                   1779: 
                   1780:        msg = NLMSG_DATA(hdr);
                   1781:        rta = RTM_RTA(msg);
                   1782:        rtasize = RTM_PAYLOAD(hdr);
                   1783: 
                   1784:        if (route)
                   1785:        {
                   1786:                *route = (rt_entry_t){
                   1787:                        .dst_len = msg->rtm_dst_len,
                   1788:                        .src_len = msg->rtm_src_len,
                   1789:                        .table = msg->rtm_table,
                   1790:                };
                   1791:        }
                   1792:        else
                   1793:        {
                   1794:                INIT(route,
                   1795:                        .dst_len = msg->rtm_dst_len,
                   1796:                        .src_len = msg->rtm_src_len,
                   1797:                        .table = msg->rtm_table,
                   1798:                );
                   1799:        }
                   1800: 
                   1801:        while (RTA_OK(rta, rtasize))
                   1802:        {
                   1803:                switch (rta->rta_type)
                   1804:                {
                   1805:                        case RTA_PREFSRC:
                   1806:                                route->pref_src = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta));
                   1807:                                break;
                   1808:                        case RTA_GATEWAY:
                   1809:                                route->gtw = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta));
                   1810:                                break;
                   1811:                        case RTA_DST:
                   1812:                                route->dst = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta));
                   1813:                                break;
                   1814:                        case RTA_SRC:
                   1815:                                route->src = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta));
                   1816:                                break;
                   1817:                        case RTA_OIF:
                   1818:                                if (RTA_PAYLOAD(rta) == sizeof(route->oif))
                   1819:                                {
                   1820:                                        route->oif = *(uint32_t*)RTA_DATA(rta);
                   1821:                                }
                   1822:                                break;
                   1823:                        case RTA_PRIORITY:
                   1824:                                if (RTA_PAYLOAD(rta) == sizeof(route->priority))
                   1825:                                {
                   1826:                                        route->priority = *(uint32_t*)RTA_DATA(rta);
                   1827:                                }
                   1828:                                break;
                   1829: #ifdef HAVE_RTA_TABLE
                   1830:                        case RTA_TABLE:
                   1831:                                if (RTA_PAYLOAD(rta) == sizeof(route->table))
                   1832:                                {
                   1833:                                        route->table = *(uint32_t*)RTA_DATA(rta);
                   1834:                                }
                   1835:                                break;
                   1836: #endif /* HAVE_RTA_TABLE*/
                   1837:                }
                   1838:                rta = RTA_NEXT(rta, rtasize);
                   1839:        }
                   1840:        return route;
                   1841: }
                   1842: 
                   1843: /**
                   1844:  * Get a route: If "nexthop", the nexthop is returned. source addr otherwise.
                   1845:  */
                   1846: static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
                   1847:                                                 int prefix, bool nexthop, host_t *candidate,
                   1848:                                                 char **iface, u_int recursion)
                   1849: {
                   1850:        netlink_buf_t request;
                   1851:        struct nlmsghdr *hdr, *out, *current;
                   1852:        struct rtmsg *msg;
                   1853:        chunk_t chunk;
                   1854:        size_t len;
                   1855:        linked_list_t *routes;
                   1856:        rt_entry_t *route = NULL, *best = NULL;
                   1857:        enumerator_t *enumerator;
                   1858:        host_t *addr = NULL;
                   1859:        bool match_net;
                   1860:        int family;
                   1861: 
                   1862:        if (recursion > MAX_ROUTE_RECURSION)
                   1863:        {
                   1864:                return NULL;
                   1865:        }
                   1866:        chunk = dest->get_address(dest);
                   1867:        len = chunk.len * 8;
                   1868:        prefix = prefix < 0 ? len : min(prefix, len);
                   1869:        match_net = prefix != len;
                   1870: 
                   1871:        memset(&request, 0, sizeof(request));
                   1872: 
                   1873:        family = dest->get_family(dest);
                   1874:        hdr = &request.hdr;
                   1875:        hdr->nlmsg_flags = NLM_F_REQUEST;
                   1876:        hdr->nlmsg_type = RTM_GETROUTE;
                   1877:        hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
                   1878: 
                   1879:        msg = NLMSG_DATA(hdr);
                   1880:        msg->rtm_family = family;
                   1881:        if (!match_net && this->rta_mark && this->routing_mark.value)
                   1882:        {
                   1883:                /* if our routing rule excludes packets with a certain mark we can
                   1884:                 * get the preferred route without having to dump all routes */
                   1885:                chunk = chunk_from_thing(this->routing_mark.value);
                   1886:                netlink_add_attribute(hdr, RTA_MARK, chunk, sizeof(request));
                   1887:        }
                   1888:        else if (family == AF_INET || this->rta_prefsrc_for_ipv6 ||
                   1889:                         this->routing_table || match_net)
                   1890:        {       /* kernels prior to 3.0 do not support RTA_PREFSRC for IPv6 routes.
                   1891:                 * as we want to ignore routes with virtual IPs we cannot use DUMP
                   1892:                 * if these routes are not installed in a separate table */
                   1893:                if (this->install_routes)
                   1894:                {
                   1895:                        hdr->nlmsg_flags |= NLM_F_DUMP;
                   1896:                }
                   1897:        }
                   1898:        if (candidate)
                   1899:        {
                   1900:                chunk = candidate->get_address(candidate);
                   1901:                if (hdr->nlmsg_flags & NLM_F_DUMP)
                   1902:                {
                   1903:                        netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request));
                   1904:                }
                   1905:                else
                   1906:                {
                   1907:                        netlink_add_attribute(hdr, RTA_SRC, chunk, sizeof(request));
                   1908:                }
                   1909:        }
                   1910:        /* we use this below to match against the routes */
                   1911:        chunk = dest->get_address(dest);
                   1912:        if (!match_net)
                   1913:        {
                   1914:                netlink_add_attribute(hdr, RTA_DST, chunk, sizeof(request));
                   1915:        }
                   1916: 
                   1917:        if (this->socket->send(this->socket, hdr, &out, &len) != SUCCESS)
                   1918:        {
                   1919:                DBG2(DBG_KNL, "getting %s to reach %H/%d failed",
                   1920:                         nexthop ? "nexthop" : "address", dest, prefix);
                   1921:                return NULL;
                   1922:        }
                   1923:        routes = linked_list_create();
                   1924:        this->lock->read_lock(this->lock);
                   1925: 
                   1926:        for (current = out; NLMSG_OK(current, len);
                   1927:                 current = NLMSG_NEXT(current, len))
                   1928:        {
                   1929:                switch (current->nlmsg_type)
                   1930:                {
                   1931:                        case NLMSG_DONE:
                   1932:                                break;
                   1933:                        case RTM_NEWROUTE:
                   1934:                        {
                   1935:                                rt_entry_t *other;
                   1936:                                uintptr_t table;
                   1937: 
                   1938:                                if (!route_usable(current, TRUE))
                   1939:                                {
                   1940:                                        continue;
                   1941:                                }
                   1942:                                route = parse_route(current, route);
                   1943: 
                   1944:                                table = (uintptr_t)route->table;
                   1945:                                if (this->rt_exclude->find_first(this->rt_exclude, NULL,
                   1946:                                                                                                 (void**)&table))
                   1947:                                {       /* route is from an excluded routing table */
                   1948:                                        continue;
                   1949:                                }
                   1950:                                if (this->routing_table != 0 &&
                   1951:                                        route->table == this->routing_table)
                   1952:                                {       /* route is from our own ipsec routing table */
                   1953:                                        continue;
                   1954:                                }
                   1955:                                if (route->oif && !is_interface_up_and_usable(this, route->oif))
                   1956:                                {       /* interface is down */
                   1957:                                        continue;
                   1958:                                }
                   1959:                                if (!addr_in_subnet(chunk, prefix, route->dst, route->dst_len))
                   1960:                                {       /* route destination does not contain dest */
                   1961:                                        continue;
                   1962:                                }
                   1963:                                if (route->pref_src.ptr)
                   1964:                                {       /* verify source address, if any */
                   1965:                                        host_t *src = host_create_from_chunk(msg->rtm_family,
                   1966:                                                                                                                 route->pref_src, 0);
                   1967:                                        if (src && is_known_vip(this, src))
                   1968:                                        {       /* ignore routes installed by us */
                   1969:                                                src->destroy(src);
                   1970:                                                continue;
                   1971:                                        }
                   1972:                                        route->src_host = src;
                   1973:                                }
                   1974:                                /* insert route, sorted by network prefix and priority */
                   1975:                                enumerator = routes->create_enumerator(routes);
                   1976:                                while (enumerator->enumerate(enumerator, &other))
                   1977:                                {
                   1978:                                        if (route->dst_len > other->dst_len)
                   1979:                                        {
                   1980:                                                break;
                   1981:                                        }
                   1982:                                        if (route->dst_len == other->dst_len &&
                   1983:                                                route->priority < other->priority)
                   1984:                                        {
                   1985:                                                break;
                   1986:                                        }
                   1987:                                }
                   1988:                                routes->insert_before(routes, enumerator, route);
                   1989:                                enumerator->destroy(enumerator);
                   1990:                                route = NULL;
                   1991:                                continue;
                   1992:                        }
                   1993:                        default:
                   1994:                                continue;
                   1995:                }
                   1996:                break;
                   1997:        }
                   1998:        if (route)
                   1999:        {
                   2000:                rt_entry_destroy(route);
                   2001:        }
                   2002: 
                   2003:        /* now we have a list of routes matching dest, sorted by net prefix.
                   2004:         * we will look for source addresses for these routes and select the one
                   2005:         * with the preferred source address, if possible */
                   2006:        enumerator = routes->create_enumerator(routes);
                   2007:        while (enumerator->enumerate(enumerator, &route))
                   2008:        {
                   2009:                if (route->src_host)
                   2010:                {       /* got a source address with the route, if no preferred source
                   2011:                         * is given or it matches we are done, as this is the best route */
                   2012:                        if (!candidate || candidate->ip_equals(candidate, route->src_host))
                   2013:                        {
                   2014:                                best = route;
                   2015:                                break;
                   2016:                        }
                   2017:                        else if (route->oif)
                   2018:                        {       /* no match yet, maybe it is assigned to the same interface */
                   2019:                                host_t *src = get_interface_address(this, route->oif,
                   2020:                                                                                        msg->rtm_family, dest, candidate);
                   2021:                                if (src && src->ip_equals(src, candidate))
                   2022:                                {
                   2023:                                        route->src_host->destroy(route->src_host);
                   2024:                                        route->src_host = src;
                   2025:                                        best = route;
                   2026:                                        break;
                   2027:                                }
                   2028:                                DESTROY_IF(src);
                   2029:                        }
                   2030:                        /* no luck yet with the source address. if this is the best (first)
                   2031:                         * route we store it as fallback in case we don't find a route with
                   2032:                         * the preferred source */
                   2033:                        best = best ?: route;
                   2034:                        continue;
                   2035:                }
                   2036:                if (route->src.ptr)
                   2037:                {       /* no src, but a source selector, try to find a matching address */
                   2038:                        route->src_host = get_subnet_address(this, msg->rtm_family,
                   2039:                                                                                        route->src, route->src_len, dest,
                   2040:                                                                                        candidate);
                   2041:                        if (route->src_host)
                   2042:                        {       /* we handle this address the same as the one above */
                   2043:                                if (!candidate ||
                   2044:                                         candidate->ip_equals(candidate, route->src_host))
                   2045:                                {
                   2046:                                        best = route;
                   2047:                                        break;
                   2048:                                }
                   2049:                                best = best ?: route;
                   2050:                                continue;
                   2051:                        }
                   2052:                }
                   2053:                if (route->oif)
                   2054:                {       /* no src, but an interface - get address from it */
                   2055:                        route->src_host = get_interface_address(this, route->oif,
                   2056:                                                                                        msg->rtm_family, dest, candidate);
                   2057:                        if (route->src_host)
                   2058:                        {       /* more of the same */
                   2059:                                if (!candidate ||
                   2060:                                         candidate->ip_equals(candidate, route->src_host))
                   2061:                                {
                   2062:                                        best = route;
                   2063:                                        break;
                   2064:                                }
                   2065:                                best = best ?: route;
                   2066:                                continue;
                   2067:                        }
                   2068:                }
                   2069:                if (route->gtw.ptr)
                   2070:                {       /* no src, no iface, but a gateway - lookup src to reach gtw */
                   2071:                        host_t *gtw;
                   2072: 
                   2073:                        gtw = host_create_from_chunk(msg->rtm_family, route->gtw, 0);
                   2074:                        if (gtw && !gtw->ip_equals(gtw, dest))
                   2075:                        {
                   2076:                                route->src_host = get_route(this, gtw, -1, FALSE, candidate,
                   2077:                                                                                        iface, recursion + 1);
                   2078:                        }
                   2079:                        DESTROY_IF(gtw);
                   2080:                        if (route->src_host)
                   2081:                        {       /* more of the same */
                   2082:                                if (!candidate ||
                   2083:                                         candidate->ip_equals(candidate, route->src_host))
                   2084:                                {
                   2085:                                        best = route;
                   2086:                                        break;
                   2087:                                }
                   2088:                                best = best ?: route;
                   2089:                        }
                   2090:                }
                   2091:        }
                   2092:        enumerator->destroy(enumerator);
                   2093: 
                   2094:        if (nexthop)
                   2095:        {       /* nexthop lookup, return gateway and oif if any */
                   2096:                if (iface)
                   2097:                {
                   2098:                        *iface = NULL;
                   2099:                }
                   2100:                if (best || routes->get_first(routes, (void**)&best) == SUCCESS)
                   2101:                {
                   2102:                        addr = host_create_from_chunk(msg->rtm_family, best->gtw, 0);
                   2103:                        if (iface && best->oif)
                   2104:                        {
                   2105:                                *iface = get_interface_name_by_index(this, best->oif);
                   2106:                        }
                   2107:                }
                   2108:                if (!addr && !match_net)
                   2109:                {       /* fallback to destination address */
                   2110:                        addr = dest->clone(dest);
                   2111:                }
                   2112:        }
                   2113:        else
                   2114:        {
                   2115:                if (best)
                   2116:                {
                   2117:                        addr = best->src_host->clone(best->src_host);
                   2118:                }
                   2119:        }
                   2120:        this->lock->unlock(this->lock);
                   2121:        routes->destroy_function(routes, (void*)rt_entry_destroy);
                   2122:        free(out);
                   2123: 
                   2124:        if (addr)
                   2125:        {
                   2126:                if (nexthop && iface && *iface)
                   2127:                {
                   2128:                        DBG2(DBG_KNL, "using %H as nexthop and %s as dev to reach %H/%d",
                   2129:                                 addr, *iface, dest, prefix);
                   2130:                }
                   2131:                else
                   2132:                {
                   2133:                        DBG2(DBG_KNL, "using %H as %s to reach %H/%d", addr,
                   2134:                                 nexthop ? "nexthop" : "address", dest, prefix);
                   2135:                }
                   2136:        }
                   2137:        else if (!recursion)
                   2138:        {
                   2139:                DBG2(DBG_KNL, "no %s found to reach %H/%d",
                   2140:                         nexthop ? "nexthop" : "address", dest, prefix);
                   2141:        }
                   2142:        return addr;
                   2143: }
                   2144: 
                   2145: METHOD(kernel_net_t, get_source_addr, host_t*,
                   2146:        private_kernel_netlink_net_t *this, host_t *dest, host_t *src)
                   2147: {
                   2148:        return get_route(this, dest, -1, FALSE, src, NULL, 0);
                   2149: }
                   2150: 
                   2151: METHOD(kernel_net_t, get_nexthop, host_t*,
                   2152:        private_kernel_netlink_net_t *this, host_t *dest, int prefix, host_t *src,
                   2153:        char **iface)
                   2154: {
                   2155:        return get_route(this, dest, prefix, TRUE, src, iface, 0);
                   2156: }
                   2157: 
                   2158: /** enumerator over subnets */
                   2159: typedef struct {
                   2160:        enumerator_t public;
                   2161:        private_kernel_netlink_net_t *private;
                   2162:        /** message from the kernel */
                   2163:        struct nlmsghdr *msg;
                   2164:        /** current message from the kernel */
                   2165:        struct nlmsghdr *current;
                   2166:        /** remaining length */
                   2167:        size_t len;
                   2168:        /** last subnet enumerated */
                   2169:        host_t *net;
                   2170:        /** interface of current net */
                   2171:        char ifname[IFNAMSIZ];
                   2172: } subnet_enumerator_t;
                   2173: 
                   2174: METHOD(enumerator_t, destroy_subnet_enumerator, void,
                   2175:        subnet_enumerator_t *this)
                   2176: {
                   2177:        DESTROY_IF(this->net);
                   2178:        free(this->msg);
                   2179:        free(this);
                   2180: }
                   2181: 
                   2182: METHOD(enumerator_t, enumerate_subnets, bool,
                   2183:        subnet_enumerator_t *this, va_list args)
                   2184: {
                   2185:        host_t **net;
                   2186:        uint8_t *mask;
                   2187:        char **ifname;
                   2188: 
                   2189:        VA_ARGS_VGET(args, net, mask, ifname);
                   2190: 
                   2191:        if (!this->current)
                   2192:        {
                   2193:                this->current = this->msg;
                   2194:        }
                   2195:        else
                   2196:        {
                   2197:                this->current = NLMSG_NEXT(this->current, this->len);
                   2198:                DESTROY_IF(this->net);
                   2199:                this->net = NULL;
                   2200:        }
                   2201: 
                   2202:        while (NLMSG_OK(this->current, this->len))
                   2203:        {
                   2204:                switch (this->current->nlmsg_type)
                   2205:                {
                   2206:                        case NLMSG_DONE:
                   2207:                                break;
                   2208:                        case RTM_NEWROUTE:
                   2209:                        {
                   2210:                                rt_entry_t route;
                   2211: 
                   2212:                                if (!route_usable(this->current, FALSE))
                   2213:                                {
                   2214:                                        break;
                   2215:                                }
                   2216:                                parse_route(this->current, &route);
                   2217: 
                   2218:                                if (route.table && (
                   2219:                                                        route.table == RT_TABLE_LOCAL ||
                   2220:                                                        route.table == this->private->routing_table))
                   2221:                                {       /* ignore our own and the local routing tables */
                   2222:                                        break;
                   2223:                                }
                   2224:                                else if (route.gtw.ptr)
                   2225:                                {       /* ignore routes via gateway/next hop */
                   2226:                                        break;
                   2227:                                }
                   2228: 
                   2229:                                if (route.dst.ptr && route.oif &&
                   2230:                                        if_indextoname(route.oif, this->ifname))
                   2231:                                {
                   2232:                                        this->net = host_create_from_chunk(AF_UNSPEC, route.dst, 0);
                   2233:                                        *net = this->net;
                   2234:                                        *mask = route.dst_len;
                   2235:                                        *ifname = this->ifname;
                   2236:                                        return TRUE;
                   2237:                                }
                   2238:                                break;
                   2239:                        }
                   2240:                        default:
                   2241:                                break;
                   2242:                }
                   2243:                this->current = NLMSG_NEXT(this->current, this->len);
                   2244:        }
                   2245:        return FALSE;
                   2246: }
                   2247: 
                   2248: METHOD(kernel_net_t, create_local_subnet_enumerator, enumerator_t*,
                   2249:        private_kernel_netlink_net_t *this)
                   2250: {
                   2251:        netlink_buf_t request;
                   2252:        struct nlmsghdr *hdr, *out;
                   2253:        struct rtmsg *msg;
                   2254:        size_t len;
                   2255:        subnet_enumerator_t *enumerator;
                   2256: 
                   2257:        memset(&request, 0, sizeof(request));
                   2258: 
                   2259:        hdr = &request.hdr;
                   2260:        hdr->nlmsg_flags = NLM_F_REQUEST;
                   2261:        hdr->nlmsg_type = RTM_GETROUTE;
                   2262:        hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
                   2263:        hdr->nlmsg_flags |= NLM_F_DUMP;
                   2264: 
                   2265:        msg = NLMSG_DATA(hdr);
                   2266:        msg->rtm_scope = RT_SCOPE_LINK;
                   2267: 
                   2268:        if (this->socket->send(this->socket, hdr, &out, &len) != SUCCESS)
                   2269:        {
                   2270:                DBG2(DBG_KNL, "enumerating local subnets failed");
                   2271:                return enumerator_create_empty();
                   2272:        }
                   2273: 
                   2274:        INIT(enumerator,
                   2275:                .public = {
                   2276:                        .enumerate = enumerator_enumerate_default,
                   2277:                        .venumerate = _enumerate_subnets,
                   2278:                        .destroy = _destroy_subnet_enumerator,
                   2279:                },
                   2280:                .private = this,
                   2281:                .msg = out,
                   2282:                .len = len,
                   2283:        );
                   2284:        return &enumerator->public;
                   2285: }
                   2286: 
                   2287: /**
                   2288:  * Manages the creation and deletion of IPv6 address labels for virtual IPs.
                   2289:  * By setting the appropriate nlmsg_type the label is either added or removed.
                   2290:  */
                   2291: static status_t manage_addrlabel(private_kernel_netlink_net_t *this,
                   2292:                                                                 int nlmsg_type, host_t *ip)
                   2293: {
                   2294:        netlink_buf_t request;
                   2295:        struct nlmsghdr *hdr;
                   2296:        struct ifaddrlblmsg *msg;
                   2297:        chunk_t chunk;
                   2298:        uint32_t label;
                   2299: 
                   2300:        memset(&request, 0, sizeof(request));
                   2301: 
                   2302:        chunk = ip->get_address(ip);
                   2303: 
                   2304:        hdr = &request.hdr;
                   2305:        hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
                   2306:        if (nlmsg_type == RTM_NEWADDRLABEL)
                   2307:        {
                   2308:                hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
                   2309:        }
                   2310:        hdr->nlmsg_type = nlmsg_type;
                   2311:        hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrlblmsg));
                   2312: 
                   2313:        msg = NLMSG_DATA(hdr);
                   2314:        msg->ifal_family = ip->get_family(ip);
                   2315:        msg->ifal_prefixlen = chunk.len * 8;
                   2316: 
                   2317:        netlink_add_attribute(hdr, IFAL_ADDRESS, chunk, sizeof(request));
                   2318:        /* doesn't really matter as default labels are < 20 but this makes it kinda
                   2319:         * recognizable */
                   2320:        label = 220;
                   2321:        netlink_add_attribute(hdr, IFAL_LABEL, chunk_from_thing(label),
                   2322:                                                  sizeof(request));
                   2323: 
                   2324:        return this->socket->send_ack(this->socket, hdr);
                   2325: }
                   2326: 
                   2327: /**
                   2328:  * Manages the creation and deletion of ip addresses on an interface.
                   2329:  * By setting the appropriate nlmsg_type, the ip will be set or unset.
                   2330:  */
                   2331: static status_t manage_ipaddr(private_kernel_netlink_net_t *this, int nlmsg_type,
                   2332:                                                          int flags, int if_index, host_t *ip, int prefix)
                   2333: {
                   2334:        netlink_buf_t request;
                   2335:        struct nlmsghdr *hdr;
                   2336:        struct ifaddrmsg *msg;
                   2337:        chunk_t chunk;
                   2338: 
                   2339:        memset(&request, 0, sizeof(request));
                   2340: 
                   2341:        chunk = ip->get_address(ip);
                   2342: 
                   2343:        hdr = &request.hdr;
                   2344:        hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
                   2345:        hdr->nlmsg_type = nlmsg_type;
                   2346:        hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
                   2347: 
                   2348:        msg = NLMSG_DATA(hdr);
                   2349:        msg->ifa_family = ip->get_family(ip);
                   2350:        msg->ifa_flags = 0;
                   2351:        msg->ifa_prefixlen = prefix < 0 ? chunk.len * 8 : prefix;
                   2352:        msg->ifa_scope = RT_SCOPE_UNIVERSE;
                   2353:        msg->ifa_index = if_index;
                   2354: 
                   2355:        netlink_add_attribute(hdr, IFA_LOCAL, chunk, sizeof(request));
                   2356: 
                   2357:        if (ip->get_family(ip) == AF_INET6)
                   2358:        {
                   2359: #ifdef IFA_F_NODAD
                   2360:                msg->ifa_flags |= IFA_F_NODAD;
                   2361: #endif
                   2362:                if (this->rta_prefsrc_for_ipv6)
                   2363:                {
                   2364:                        /* if source routes are possible we set a label for this virtual IP
                   2365:                         * so it gets only used if forced by our route, and not by the
                   2366:                         * default IPv6 address selection */
                   2367:                        int labelop = nlmsg_type == RTM_NEWADDR ? RTM_NEWADDRLABEL
                   2368:                                                                                                        : RTM_DELADDRLABEL;
                   2369:                        if (manage_addrlabel(this, labelop, ip) != SUCCESS)
                   2370:                        {
                   2371:                                /* if we can't use address labels we let the virtual IP get
                   2372:                                 * deprecated immediately (but mark it as valid forever), which
                   2373:                                 * should also avoid that it gets used by the default address
                   2374:                                 * selection */
                   2375:                                struct ifa_cacheinfo cache = {
                   2376:                                        .ifa_valid = 0xFFFFFFFF,
                   2377:                                        .ifa_prefered = 0,
                   2378:                                };
                   2379:                                netlink_add_attribute(hdr, IFA_CACHEINFO,
                   2380:                                                                          chunk_from_thing(cache), sizeof(request));
                   2381:                        }
                   2382:                }
                   2383:        }
                   2384:        return this->socket->send_ack(this->socket, hdr);
                   2385: }
                   2386: 
                   2387: METHOD(kernel_net_t, add_ip, status_t,
                   2388:        private_kernel_netlink_net_t *this, host_t *virtual_ip, int prefix,
                   2389:        char *iface_name)
                   2390: {
                   2391:        addr_map_entry_t *entry, lookup = {
                   2392:                .ip = virtual_ip,
                   2393:        };
                   2394:        iface_entry_t *iface = NULL;
                   2395: 
                   2396:        if (!this->install_virtual_ip)
                   2397:        {       /* disabled by config */
                   2398:                return SUCCESS;
                   2399:        }
                   2400: 
                   2401:        this->lock->write_lock(this->lock);
                   2402:        /* the virtual IP might actually be installed as regular IP, in which case
                   2403:         * we don't track it as virtual IP */
                   2404:        entry = this->addrs->get_match(this->addrs, &lookup,
                   2405:                                                                  (void*)addr_map_entry_match);
                   2406:        if (!entry)
                   2407:        {       /* otherwise it might already be installed as virtual IP */
                   2408:                entry = this->vips->get_match(this->vips, &lookup,
                   2409:                                                                         (void*)addr_map_entry_match);
                   2410:                if (entry)
                   2411:                {       /* the vip we found can be in one of three states: 1) installed and
                   2412:                         * ready, 2) just added by another thread, but not yet confirmed to
                   2413:                         * be installed by the kernel, 3) just deleted, but not yet gone.
                   2414:                         * Then while we wait below, several things could happen (as we
                   2415:                         * release the lock).  For instance, the interface could disappear,
                   2416:                         * or the IP is finally deleted, and it reappears on a different
                   2417:                         * interface. All these cases are handled by the call below. */
                   2418:                        while (!is_vip_installed_or_gone(this, virtual_ip, &entry))
                   2419:                        {
                   2420:                                this->condvar->wait(this->condvar, this->lock);
                   2421:                        }
                   2422:                        if (entry)
                   2423:                        {
                   2424:                                entry->addr->refcount++;
                   2425:                        }
                   2426:                }
                   2427:        }
                   2428:        if (entry)
                   2429:        {
                   2430:                DBG2(DBG_KNL, "virtual IP %H is already installed on %s", virtual_ip,
                   2431:                         entry->iface->ifname);
                   2432:                this->lock->unlock(this->lock);
                   2433:                return SUCCESS;
                   2434:        }
                   2435:        /* try to find the target interface, either by config or via src ip */
                   2436:        if (!this->install_virtual_ip_on ||
                   2437:                !this->ifaces->find_first(this->ifaces, iface_entry_by_name,
                   2438:                                                                 (void**)&iface, this->install_virtual_ip_on))
                   2439:        {
                   2440:                if (!this->ifaces->find_first(this->ifaces, iface_entry_by_name,
                   2441:                                                                         (void**)&iface, iface_name))
                   2442:                {       /* if we don't find the requested interface we just use the first */
                   2443:                        this->ifaces->get_first(this->ifaces, (void**)&iface);
                   2444:                }
                   2445:        }
                   2446:        if (iface)
                   2447:        {
                   2448:                addr_entry_t *addr;
                   2449:                char *ifname;
                   2450:                int ifi;
                   2451: 
                   2452:                INIT(addr,
                   2453:                        .ip = virtual_ip->clone(virtual_ip),
                   2454:                        .refcount = 1,
                   2455:                        .scope = RT_SCOPE_UNIVERSE,
                   2456:                );
                   2457:                iface->addrs->insert_last(iface->addrs, addr);
                   2458:                addr_map_entry_add(this->vips, addr, iface);
                   2459:                ifi = iface->ifindex;
                   2460:                this->lock->unlock(this->lock);
                   2461:                if (manage_ipaddr(this, RTM_NEWADDR, NLM_F_CREATE | NLM_F_EXCL,
                   2462:                                                  ifi, virtual_ip, prefix) == SUCCESS)
                   2463:                {
                   2464:                        this->lock->write_lock(this->lock);
                   2465:                        while (!is_vip_installed_or_gone(this, virtual_ip, &entry))
                   2466:                        {       /* wait until address appears */
                   2467:                                this->condvar->wait(this->condvar, this->lock);
                   2468:                        }
                   2469:                        if (entry)
                   2470:                        {       /* we fail if the interface got deleted in the meantime */
                   2471:                                ifname = strdup(entry->iface->ifname);
                   2472:                                this->lock->unlock(this->lock);
                   2473:                                DBG2(DBG_KNL, "virtual IP %H installed on %s",
                   2474:                                         virtual_ip, ifname);
                   2475:                                /* during IKEv1 reauthentication, children get moved from
                   2476:                                 * old the new SA before the virtual IP is available. This
                   2477:                                 * kills the route for our virtual IP, reinstall. */
                   2478:                                queue_route_reinstall(this, ifname);
                   2479:                                return SUCCESS;
                   2480:                        }
                   2481:                        this->lock->unlock(this->lock);
                   2482:                }
                   2483:                DBG1(DBG_KNL, "adding virtual IP %H failed", virtual_ip);
                   2484:                return FAILED;
                   2485:        }
                   2486:        this->lock->unlock(this->lock);
                   2487:        DBG1(DBG_KNL, "no interface available, unable to install virtual IP %H",
                   2488:                 virtual_ip);
                   2489:        return FAILED;
                   2490: }
                   2491: 
                   2492: METHOD(kernel_net_t, del_ip, status_t,
                   2493:        private_kernel_netlink_net_t *this, host_t *virtual_ip, int prefix,
                   2494:        bool wait)
                   2495: {
                   2496:        addr_map_entry_t *entry, lookup = {
                   2497:                .ip = virtual_ip,
                   2498:        };
                   2499: 
                   2500:        if (!this->install_virtual_ip)
                   2501:        {       /* disabled by config */
                   2502:                return SUCCESS;
                   2503:        }
                   2504: 
                   2505:        DBG2(DBG_KNL, "deleting virtual IP %H", virtual_ip);
                   2506: 
                   2507:        this->lock->write_lock(this->lock);
                   2508:        entry = this->vips->get_match(this->vips, &lookup,
                   2509:                                                                 (void*)addr_map_entry_match);
                   2510:        if (!entry)
                   2511:        {       /* we didn't install this IP as virtual IP */
                   2512:                entry = this->addrs->get_match(this->addrs, &lookup,
                   2513:                                                                          (void*)addr_map_entry_match);
                   2514:                if (entry)
                   2515:                {
                   2516:                        DBG2(DBG_KNL, "not deleting existing IP %H on %s", virtual_ip,
                   2517:                                 entry->iface->ifname);
                   2518:                        this->lock->unlock(this->lock);
                   2519:                        return SUCCESS;
                   2520:                }
                   2521:                DBG2(DBG_KNL, "virtual IP %H not cached, unable to delete", virtual_ip);
                   2522:                this->lock->unlock(this->lock);
                   2523:                return FAILED;
                   2524:        }
                   2525:        if (entry->addr->refcount == 1)
                   2526:        {
                   2527:                status_t status;
                   2528:                int ifi;
                   2529: 
                   2530:                /* we set this flag so that threads calling add_ip will block and wait
                   2531:                 * until the entry is gone, also so we can wait below */
                   2532:                entry->addr->installed = FALSE;
                   2533:                ifi = entry->iface->ifindex;
                   2534:                this->lock->unlock(this->lock);
                   2535:                status = manage_ipaddr(this, RTM_DELADDR, 0, ifi, virtual_ip, prefix);
                   2536:                if (status == SUCCESS && wait)
                   2537:                {       /* wait until the address is really gone */
                   2538:                        this->lock->write_lock(this->lock);
                   2539:                        while (is_known_vip(this, virtual_ip))
                   2540:                        {
                   2541:                                this->condvar->wait(this->condvar, this->lock);
                   2542:                        }
                   2543:                        this->lock->unlock(this->lock);
                   2544:                }
                   2545:                return status;
                   2546:        }
                   2547:        else
                   2548:        {
                   2549:                entry->addr->refcount--;
                   2550:        }
                   2551:        DBG2(DBG_KNL, "virtual IP %H used by other SAs, not deleting",
                   2552:                 virtual_ip);
                   2553:        this->lock->unlock(this->lock);
                   2554:        return SUCCESS;
                   2555: }
                   2556: 
                   2557: /**
                   2558:  * Manages source routes in the routing table.
                   2559:  * By setting the appropriate nlmsg_type, the route gets added or removed.
                   2560:  */
                   2561: static status_t manage_srcroute(private_kernel_netlink_net_t *this,
                   2562:                                                                int nlmsg_type, int flags, chunk_t dst_net,
                   2563:                                                                uint8_t prefixlen, host_t *gateway,
                   2564:                                                                host_t *src_ip, char *if_name, bool pass)
                   2565: {
                   2566:        netlink_buf_t request;
                   2567:        struct nlmsghdr *hdr;
                   2568:        struct rtmsg *msg;
                   2569:        struct rtattr *rta;
                   2570:        int ifindex;
                   2571:        chunk_t chunk;
                   2572: 
                   2573:        /* if route is 0.0.0.0/0, we can't install it, as it would
                   2574:         * overwrite the default route. Instead, we add two routes:
                   2575:         * 0.0.0.0/1 and 128.0.0.0/1 */
                   2576:        if (this->routing_table == 0 && prefixlen == 0)
                   2577:        {
                   2578:                chunk_t half_net;
                   2579:                uint8_t half_prefixlen;
                   2580:                status_t status;
                   2581: 
                   2582:                half_net = chunk_alloca(dst_net.len);
                   2583:                memset(half_net.ptr, 0, half_net.len);
                   2584:                half_prefixlen = 1;
                   2585:                /* no throw routes in the main table */
                   2586:                status = manage_srcroute(this, nlmsg_type, flags, half_net,
                   2587:                                                        half_prefixlen, gateway, src_ip, if_name, FALSE);
                   2588:                half_net.ptr[0] |= 0x80;
                   2589:                status |= manage_srcroute(this, nlmsg_type, flags, half_net,
                   2590:                                                        half_prefixlen, gateway, src_ip, if_name, FALSE);
                   2591:                return status;
                   2592:        }
                   2593: 
                   2594:        memset(&request, 0, sizeof(request));
                   2595: 
                   2596:        hdr = &request.hdr;
                   2597:        hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
                   2598:        hdr->nlmsg_type = nlmsg_type;
                   2599:        hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
                   2600: 
                   2601:        msg = NLMSG_DATA(hdr);
                   2602:        msg->rtm_family = (dst_net.len == 4) ? AF_INET : AF_INET6;
                   2603:        msg->rtm_dst_len = prefixlen;
                   2604:        msg->rtm_protocol = RTPROT_STATIC;
                   2605:        msg->rtm_type = pass ? RTN_THROW : RTN_UNICAST;
                   2606:        msg->rtm_scope = RT_SCOPE_UNIVERSE;
                   2607: 
                   2608:        if (this->routing_table < 256)
                   2609:        {
                   2610:                msg->rtm_table = this->routing_table;
                   2611:        }
                   2612:        else
                   2613:        {
                   2614: #ifdef HAVE_RTA_TABLE
                   2615:                chunk = chunk_from_thing(this->routing_table);
                   2616:                netlink_add_attribute(hdr, RTA_TABLE, chunk, sizeof(request));
                   2617: #else
                   2618:                DBG1(DBG_KNL, "routing table IDs > 255 are not supported");
                   2619:                return FAILED;
                   2620: #endif /* HAVE_RTA_TABLE */
                   2621:        }
                   2622:        netlink_add_attribute(hdr, RTA_DST, dst_net, sizeof(request));
                   2623: 
                   2624:        /* only when installing regular routes do we need all the parameters,
                   2625:         * deletes are done by destination net (except if metrics are used, which
                   2626:         * we don't support), for throw routes we don't need any of them either */
                   2627:        if (nlmsg_type == RTM_NEWROUTE && !pass)
                   2628:        {
                   2629:                chunk = src_ip->get_address(src_ip);
                   2630:                netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request));
                   2631:                if (gateway && gateway->get_family(gateway) == src_ip->get_family(src_ip))
                   2632:                {
                   2633:                        chunk = gateway->get_address(gateway);
                   2634:                        netlink_add_attribute(hdr, RTA_GATEWAY, chunk, sizeof(request));
                   2635:                }
                   2636:                ifindex = get_interface_index(this, if_name);
                   2637:                chunk.ptr = (char*)&ifindex;
                   2638:                chunk.len = sizeof(ifindex);
                   2639:                netlink_add_attribute(hdr, RTA_OIF, chunk, sizeof(request));
                   2640: 
                   2641:                if (this->mtu || this->mss)
                   2642:                {
                   2643:                        chunk = chunk_alloca(RTA_LENGTH((sizeof(struct rtattr) +
                   2644:                                                                                         sizeof(uint32_t)) * 2));
                   2645:                        chunk.len = 0;
                   2646:                        rta = (struct rtattr*)chunk.ptr;
                   2647:                        if (this->mtu)
                   2648:                        {
                   2649:                                rta->rta_type = RTAX_MTU;
                   2650:                                rta->rta_len = RTA_LENGTH(sizeof(uint32_t));
                   2651:                                memcpy(RTA_DATA(rta), &this->mtu, sizeof(uint32_t));
                   2652:                                chunk.len = rta->rta_len;
                   2653:                        }
                   2654:                        if (this->mss)
                   2655:                        {
                   2656:                                rta = (struct rtattr*)(chunk.ptr + RTA_ALIGN(chunk.len));
                   2657:                                rta->rta_type = RTAX_ADVMSS;
                   2658:                                rta->rta_len = RTA_LENGTH(sizeof(uint32_t));
                   2659:                                memcpy(RTA_DATA(rta), &this->mss, sizeof(uint32_t));
                   2660:                                chunk.len = RTA_ALIGN(chunk.len) + rta->rta_len;
                   2661:                        }
                   2662:                        netlink_add_attribute(hdr, RTA_METRICS, chunk, sizeof(request));
                   2663:                }
                   2664:        }
                   2665:        return this->socket->send_ack(this->socket, hdr);
                   2666: }
                   2667: 
                   2668: /**
                   2669:  * Helper struct used to check routes
                   2670:  */
                   2671: typedef struct {
                   2672:        /** the entry we look for */
                   2673:        route_entry_t route;
                   2674:        /** kernel interface */
                   2675:        private_kernel_netlink_net_t *this;
                   2676: } route_entry_lookup_t;
                   2677: 
                   2678: /**
                   2679:  * Check if a matching route entry has a VIP associated
                   2680:  */
                   2681: static bool route_with_vip(route_entry_lookup_t *a, route_entry_t *b)
                   2682: {
                   2683:        if (chunk_equals(a->route.dst_net, b->dst_net) &&
                   2684:                a->route.prefixlen == b->prefixlen &&
                   2685:                is_known_vip(a->this, b->src_ip))
                   2686:        {
                   2687:                return TRUE;
                   2688:        }
                   2689:        return FALSE;
                   2690: }
                   2691: 
                   2692: /**
                   2693:  * Check if there is any route entry with a matching destination
                   2694:  */
                   2695: static bool route_with_dst(route_entry_lookup_t *a, route_entry_t *b)
                   2696: {
                   2697:        if (chunk_equals(a->route.dst_net, b->dst_net) &&
                   2698:                a->route.prefixlen == b->prefixlen)
                   2699:        {
                   2700:                return TRUE;
                   2701:        }
                   2702:        return FALSE;
                   2703: }
                   2704: 
                   2705: METHOD(kernel_net_t, add_route, status_t,
                   2706:        private_kernel_netlink_net_t *this, chunk_t dst_net, uint8_t prefixlen,
                   2707:        host_t *gateway, host_t *src_ip, char *if_name, bool pass)
                   2708: {
                   2709:        status_t status;
                   2710:        route_entry_t *found;
                   2711:        route_entry_lookup_t lookup = {
                   2712:                .route = {
                   2713:                        .dst_net = dst_net,
                   2714:                        .prefixlen = prefixlen,
                   2715:                        .gateway = gateway,
                   2716:                        .src_ip = src_ip,
                   2717:                        .if_name = if_name,
                   2718:                        .pass = pass,
                   2719:                },
                   2720:                .this = this,
                   2721:        };
                   2722: 
                   2723:        if (!this->routing_table)
                   2724:        {       /* treat these as regular routes if installing in the main table */
                   2725:                pass = lookup.route.pass = FALSE;
                   2726:        }
                   2727: 
                   2728:        this->routes_lock->lock(this->routes_lock);
                   2729:        found = this->routes->get(this->routes, &lookup.route);
                   2730:        if (found)
                   2731:        {
                   2732:                this->routes_lock->unlock(this->routes_lock);
                   2733:                return ALREADY_DONE;
                   2734:        }
                   2735: 
                   2736:        /* don't replace the route if we already have one with a VIP installed,
                   2737:         * but keep track of it in case that other route is uninstalled */
                   2738:        this->lock->read_lock(this->lock);
                   2739:        if (!is_known_vip(this, src_ip))
                   2740:        {
                   2741:                found = this->routes->get_match(this->routes, &lookup,
                   2742:                                                                                (void*)route_with_vip);
                   2743:        }
                   2744:        this->lock->unlock(this->lock);
                   2745:        if (found)
                   2746:        {
                   2747:                status = SUCCESS;
                   2748:        }
                   2749:        else
                   2750:        {
                   2751:                status = manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE|NLM_F_REPLACE,
                   2752:                                                                 dst_net, prefixlen, gateway, src_ip, if_name,
                   2753:                                                                 pass);
                   2754:        }
                   2755:        if (status == SUCCESS)
                   2756:        {
                   2757:                found = route_entry_clone(&lookup.route);
                   2758:                this->routes->put(this->routes, found, found);
                   2759:        }
                   2760:        this->routes_lock->unlock(this->routes_lock);
                   2761:        return status;
                   2762: }
                   2763: 
                   2764: METHOD(kernel_net_t, del_route, status_t,
                   2765:        private_kernel_netlink_net_t *this, chunk_t dst_net, uint8_t prefixlen,
                   2766:        host_t *gateway, host_t *src_ip, char *if_name, bool pass)
                   2767: {
                   2768:        status_t status;
                   2769:        route_entry_t *found;
                   2770:        route_entry_lookup_t lookup = {
                   2771:                .route = {
                   2772:                        .dst_net = dst_net,
                   2773:                        .prefixlen = prefixlen,
                   2774:                        .gateway = gateway,
                   2775:                        .src_ip = src_ip,
                   2776:                        .if_name = if_name,
                   2777:                        .pass = pass,
                   2778:                },
                   2779:                .this = this,
                   2780:        };
                   2781: 
                   2782:        if (!this->routing_table)
                   2783:        {       /* treat these as regular routes if installing in the main table */
                   2784:                pass = lookup.route.pass = FALSE;
                   2785:        }
                   2786: 
                   2787:        this->routes_lock->lock(this->routes_lock);
                   2788:        found = this->routes->remove(this->routes, &lookup.route);
                   2789:        if (!found)
                   2790:        {
                   2791:                this->routes_lock->unlock(this->routes_lock);
                   2792:                return NOT_FOUND;
                   2793:        }
                   2794:        route_entry_destroy(found);
                   2795: 
                   2796:        /* check if there are any other routes for the same destination and if
                   2797:         * so update the route, otherwise uninstall it */
                   2798:        this->lock->read_lock(this->lock);
                   2799:        found = this->routes->get_match(this->routes, &lookup,
                   2800:                                                                        (void*)route_with_vip);
                   2801:        this->lock->unlock(this->lock);
                   2802:        if (!found)
                   2803:        {
                   2804:                found = this->routes->get_match(this->routes, &lookup,
                   2805:                                                                                (void*)route_with_dst);
                   2806:        }
                   2807:        if (found)
                   2808:        {
                   2809:                status = manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE|NLM_F_REPLACE,
                   2810:                                                        found->dst_net, found->prefixlen, found->gateway,
                   2811:                                                        found->src_ip, found->if_name, found->pass);
                   2812:        }
                   2813:        else
                   2814:        {
                   2815:                status = manage_srcroute(this, RTM_DELROUTE, 0, dst_net, prefixlen,
                   2816:                                                                 gateway, src_ip, if_name, pass);
                   2817:        }
                   2818:        this->routes_lock->unlock(this->routes_lock);
                   2819:        return status;
                   2820: }
                   2821: 
                   2822: /**
                   2823:  * Initialize a list of local addresses.
                   2824:  */
                   2825: static status_t init_address_list(private_kernel_netlink_net_t *this)
                   2826: {
                   2827:        netlink_buf_t request;
                   2828:        struct nlmsghdr *out, *current, *in;
                   2829:        struct rtgenmsg *msg;
                   2830:        size_t len;
                   2831:        enumerator_t *ifaces, *addrs;
                   2832:        iface_entry_t *iface;
                   2833:        addr_entry_t *addr;
                   2834: 
                   2835:        DBG2(DBG_KNL, "known interfaces and IP addresses:");
                   2836: 
                   2837:        memset(&request, 0, sizeof(request));
                   2838: 
                   2839:        in = &request.hdr;
                   2840:        in->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
                   2841:        in->nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT;
                   2842:        msg = NLMSG_DATA(in);
                   2843:        msg->rtgen_family = AF_UNSPEC;
                   2844: 
                   2845:        /* get all links */
                   2846:        in->nlmsg_type = RTM_GETLINK;
                   2847:        if (this->socket->send(this->socket, in, &out, &len) != SUCCESS)
                   2848:        {
                   2849:                return FAILED;
                   2850:        }
                   2851:        current = out;
                   2852:        while (NLMSG_OK(current, len))
                   2853:        {
                   2854:                switch (current->nlmsg_type)
                   2855:                {
                   2856:                        case NLMSG_DONE:
                   2857:                                break;
                   2858:                        case RTM_NEWLINK:
                   2859:                                process_link(this, current, FALSE);
                   2860:                                /* fall through */
                   2861:                        default:
                   2862:                                current = NLMSG_NEXT(current, len);
                   2863:                                continue;
                   2864:                }
                   2865:                break;
                   2866:        }
                   2867:        free(out);
                   2868: 
                   2869:        /* get all interface addresses */
                   2870:        in->nlmsg_type = RTM_GETADDR;
                   2871:        if (this->socket->send(this->socket, in, &out, &len) != SUCCESS)
                   2872:        {
                   2873:                return FAILED;
                   2874:        }
                   2875:        current = out;
                   2876:        while (NLMSG_OK(current, len))
                   2877:        {
                   2878:                switch (current->nlmsg_type)
                   2879:                {
                   2880:                        case NLMSG_DONE:
                   2881:                                break;
                   2882:                        case RTM_NEWADDR:
                   2883:                                process_addr(this, current, FALSE);
                   2884:                                /* fall through */
                   2885:                        default:
                   2886:                                current = NLMSG_NEXT(current, len);
                   2887:                                continue;
                   2888:                }
                   2889:                break;
                   2890:        }
                   2891:        free(out);
                   2892: 
                   2893:        this->lock->read_lock(this->lock);
                   2894:        ifaces = this->ifaces->create_enumerator(this->ifaces);
                   2895:        while (ifaces->enumerate(ifaces, &iface))
                   2896:        {
                   2897:                if (iface_entry_up_and_usable(iface))
                   2898:                {
                   2899:                        DBG2(DBG_KNL, "  %s", iface->ifname);
                   2900:                        addrs = iface->addrs->create_enumerator(iface->addrs);
                   2901:                        while (addrs->enumerate(addrs, (void**)&addr))
                   2902:                        {
                   2903:                                DBG2(DBG_KNL, "    %H", addr->ip);
                   2904:                        }
                   2905:                        addrs->destroy(addrs);
                   2906:                }
                   2907:        }
                   2908:        ifaces->destroy(ifaces);
                   2909:        this->lock->unlock(this->lock);
                   2910:        return SUCCESS;
                   2911: }
                   2912: 
                   2913: /**
                   2914:  * create or delete a rule to use our routing table
                   2915:  */
                   2916: static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type,
                   2917:                                                        int family, uint32_t table, uint32_t prio)
                   2918: {
                   2919:        netlink_buf_t request;
                   2920:        struct nlmsghdr *hdr;
                   2921:        struct rtmsg *msg;
                   2922:        chunk_t chunk;
                   2923:        char *fwmark;
                   2924: 
                   2925:        memset(&request, 0, sizeof(request));
                   2926:        hdr = &request.hdr;
                   2927:        hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
                   2928:        hdr->nlmsg_type = nlmsg_type;
                   2929:        if (nlmsg_type == RTM_NEWRULE)
                   2930:        {
                   2931:                hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
                   2932:        }
                   2933:        hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
                   2934: 
                   2935:        msg = NLMSG_DATA(hdr);
                   2936:        msg->rtm_family = family;
                   2937:        msg->rtm_protocol = RTPROT_BOOT;
                   2938:        msg->rtm_scope = RT_SCOPE_UNIVERSE;
                   2939:        msg->rtm_type = RTN_UNICAST;
                   2940: 
                   2941:        if (this->routing_table < 256)
                   2942:        {
                   2943:                msg->rtm_table = table;
                   2944:        }
                   2945:        else
                   2946:        {
                   2947: #ifdef HAVE_LINUX_FIB_RULES_H
                   2948:                chunk = chunk_from_thing(table);
                   2949:                netlink_add_attribute(hdr, FRA_TABLE, chunk, sizeof(request));
                   2950: #else
                   2951:                DBG1(DBG_KNL, "routing table IDs > 255 are not supported");
                   2952:                return FAILED;
                   2953: #endif /* HAVE_LINUX_FIB_RULES_H */
                   2954:        }
                   2955:        chunk = chunk_from_thing(prio);
                   2956:        netlink_add_attribute(hdr, RTA_PRIORITY, chunk, sizeof(request));
                   2957: 
                   2958:        fwmark = lib->settings->get_str(lib->settings,
                   2959:                                                        "%s.plugins.kernel-netlink.fwmark", NULL, lib->ns);
                   2960:        if (fwmark)
                   2961:        {
                   2962: #ifdef HAVE_LINUX_FIB_RULES_H
                   2963:                mark_t mark;
                   2964: 
                   2965:                if (fwmark[0] == '!')
                   2966:                {
                   2967:                        msg->rtm_flags |= FIB_RULE_INVERT;
                   2968:                        fwmark++;
                   2969:                }
                   2970:                if (mark_from_string(fwmark, MARK_OP_NONE, &mark))
                   2971:                {
                   2972:                        chunk = chunk_from_thing(mark.value);
                   2973:                        netlink_add_attribute(hdr, FRA_FWMARK, chunk, sizeof(request));
                   2974:                        chunk = chunk_from_thing(mark.mask);
                   2975:                        netlink_add_attribute(hdr, FRA_FWMASK, chunk, sizeof(request));
                   2976:                        if (msg->rtm_flags & FIB_RULE_INVERT)
                   2977:                        {
                   2978:                                this->routing_mark = mark;
                   2979:                        }
                   2980:                }
                   2981: #else
                   2982:                DBG1(DBG_KNL, "setting firewall mark on routing rule is not supported");
                   2983: #endif /* HAVE_LINUX_FIB_RULES_H */
                   2984:        }
                   2985:        return this->socket->send_ack(this->socket, hdr);
                   2986: }
                   2987: 
                   2988: /**
                   2989:  * check for kernel features (currently only via version number)
                   2990:  */
                   2991: static void check_kernel_features(private_kernel_netlink_net_t *this)
                   2992: {
                   2993:        struct utsname utsname;
                   2994:        int a, b, c;
                   2995: 
                   2996:        if (uname(&utsname) == 0)
                   2997:        {
                   2998:                switch(sscanf(utsname.release, "%d.%d.%d", &a, &b, &c))
                   2999:                {
                   3000:                        case 3:
                   3001:                                if (a == 2)
                   3002:                                {
                   3003:                                        if (b == 6 && c >= 36)
                   3004:                                        {
                   3005:                                                this->rta_mark = TRUE;
                   3006:                                        }
                   3007:                                        DBG2(DBG_KNL, "detected Linux %d.%d.%d, no support for "
                   3008:                                                 "RTA_PREFSRC for IPv6 routes", a, b, c);
                   3009:                                        break;
                   3010:                                }
                   3011:                                /* fall-through */
                   3012:                        case 2:
                   3013:                                /* only 3.x+ uses two part version numbers */
                   3014:                                this->rta_prefsrc_for_ipv6 = TRUE;
                   3015:                                this->rta_mark = TRUE;
                   3016:                                break;
                   3017:                        default:
                   3018:                                break;
                   3019:                }
                   3020:        }
                   3021: }
                   3022: 
                   3023: /**
                   3024:  * Destroy an address to iface map
                   3025:  */
                   3026: static void addr_map_destroy(hashtable_t *map)
                   3027: {
                   3028:        enumerator_t *enumerator;
                   3029:        addr_map_entry_t *addr;
                   3030: 
                   3031:        enumerator = map->create_enumerator(map);
                   3032:        while (enumerator->enumerate(enumerator, NULL, (void**)&addr))
                   3033:        {
                   3034:                free(addr);
                   3035:        }
                   3036:        enumerator->destroy(enumerator);
                   3037:        map->destroy(map);
                   3038: }
                   3039: 
                   3040: METHOD(kernel_net_t, destroy, void,
                   3041:        private_kernel_netlink_net_t *this)
                   3042: {
                   3043:        enumerator_t *enumerator;
                   3044:        route_entry_t *route;
                   3045: 
                   3046:        if (this->routing_table)
                   3047:        {
                   3048:                manage_rule(this, RTM_DELRULE, AF_INET, this->routing_table,
                   3049:                                        this->routing_table_prio);
                   3050:                manage_rule(this, RTM_DELRULE, AF_INET6, this->routing_table,
                   3051:                                        this->routing_table_prio);
                   3052:        }
                   3053:        if (this->socket_events > 0)
                   3054:        {
                   3055:                lib->watcher->remove(lib->watcher, this->socket_events);
                   3056:                close(this->socket_events);
                   3057:        }
                   3058:        enumerator = this->routes->create_enumerator(this->routes);
                   3059:        while (enumerator->enumerate(enumerator, NULL, (void**)&route))
                   3060:        {
                   3061:                manage_srcroute(this, RTM_DELROUTE, 0, route->dst_net, route->prefixlen,
                   3062:                                                route->gateway, route->src_ip, route->if_name,
                   3063:                                                route->pass);
                   3064:                route_entry_destroy(route);
                   3065:        }
                   3066:        enumerator->destroy(enumerator);
                   3067:        this->routes->destroy(this->routes);
                   3068:        this->routes_lock->destroy(this->routes_lock);
                   3069:        DESTROY_IF(this->socket);
                   3070: 
                   3071:        net_changes_clear(this);
                   3072:        this->net_changes->destroy(this->net_changes);
                   3073:        this->net_changes_lock->destroy(this->net_changes_lock);
                   3074: 
                   3075:        addr_map_destroy(this->addrs);
                   3076:        addr_map_destroy(this->vips);
                   3077: 
                   3078:        this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy);
                   3079:        this->rt_exclude->destroy(this->rt_exclude);
                   3080:        this->roam_lock->destroy(this->roam_lock);
                   3081:        this->condvar->destroy(this->condvar);
                   3082:        this->lock->destroy(this->lock);
                   3083:        free(this);
                   3084: }
                   3085: 
                   3086: /*
                   3087:  * Described in header.
                   3088:  */
                   3089: kernel_netlink_net_t *kernel_netlink_net_create()
                   3090: {
                   3091:        private_kernel_netlink_net_t *this;
                   3092:        enumerator_t *enumerator;
                   3093:        bool register_for_events = TRUE;
                   3094:        char *exclude;
                   3095: 
                   3096:        INIT(this,
                   3097:                .public = {
                   3098:                        .interface = {
                   3099:                                .get_interface = _get_interface_name,
                   3100:                                .create_address_enumerator = _create_address_enumerator,
                   3101:                                .create_local_subnet_enumerator = _create_local_subnet_enumerator,
                   3102:                                .get_source_addr = _get_source_addr,
                   3103:                                .get_nexthop = _get_nexthop,
                   3104:                                .add_ip = _add_ip,
                   3105:                                .del_ip = _del_ip,
                   3106:                                .add_route = _add_route,
                   3107:                                .del_route = _del_route,
                   3108:                                .destroy = _destroy,
                   3109:                        },
                   3110:                },
                   3111:                .socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names,
                   3112:                        lib->settings->get_bool(lib->settings,
                   3113:                                "%s.plugins.kernel-netlink.parallel_route", FALSE, lib->ns)),
                   3114:                .rt_exclude = linked_list_create(),
                   3115:                .routes = hashtable_create((hashtable_hash_t)route_entry_hash,
                   3116:                                                                   (hashtable_equals_t)route_entry_equals, 16),
                   3117:                .net_changes = hashtable_create(
                   3118:                                                                   (hashtable_hash_t)net_change_hash,
                   3119:                                                                   (hashtable_equals_t)net_change_equals, 16),
                   3120:                .addrs = hashtable_create(
                   3121:                                                                (hashtable_hash_t)addr_map_entry_hash,
                   3122:                                                                (hashtable_equals_t)addr_map_entry_equals, 16),
                   3123:                .vips = hashtable_create((hashtable_hash_t)addr_map_entry_hash,
                   3124:                                                                 (hashtable_equals_t)addr_map_entry_equals, 16),
                   3125:                .routes_lock = mutex_create(MUTEX_TYPE_DEFAULT),
                   3126:                .net_changes_lock = mutex_create(MUTEX_TYPE_DEFAULT),
                   3127:                .ifaces = linked_list_create(),
                   3128:                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
                   3129:                .condvar = rwlock_condvar_create(),
                   3130:                .roam_lock = spinlock_create(),
                   3131:                .routing_table = lib->settings->get_int(lib->settings,
                   3132:                                                "%s.routing_table", ROUTING_TABLE, lib->ns),
                   3133:                .routing_table_prio = lib->settings->get_int(lib->settings,
                   3134:                                                "%s.routing_table_prio", ROUTING_TABLE_PRIO, lib->ns),
                   3135:                .process_route = lib->settings->get_bool(lib->settings,
                   3136:                                                "%s.process_route", TRUE, lib->ns),
                   3137:                .install_routes = lib->settings->get_bool(lib->settings,
                   3138:                                                "%s.install_routes", TRUE, lib->ns),
                   3139:                .install_virtual_ip = lib->settings->get_bool(lib->settings,
                   3140:                                                "%s.install_virtual_ip", TRUE, lib->ns),
                   3141:                .install_virtual_ip_on = lib->settings->get_str(lib->settings,
                   3142:                                                "%s.install_virtual_ip_on", NULL, lib->ns),
                   3143:                .prefer_temporary_addrs = lib->settings->get_bool(lib->settings,
                   3144:                                                "%s.prefer_temporary_addrs", FALSE, lib->ns),
                   3145:                .roam_events = lib->settings->get_bool(lib->settings,
                   3146:                                                "%s.plugins.kernel-netlink.roam_events", TRUE, lib->ns),
                   3147:                .process_rules = lib->settings->get_bool(lib->settings,
                   3148:                                                "%s.plugins.kernel-netlink.process_rules", FALSE, lib->ns),
                   3149:                .mtu = lib->settings->get_int(lib->settings,
                   3150:                                                "%s.plugins.kernel-netlink.mtu", 0, lib->ns),
                   3151:                .mss = lib->settings->get_int(lib->settings,
                   3152:                                                "%s.plugins.kernel-netlink.mss", 0, lib->ns),
                   3153:        );
                   3154:        timerclear(&this->last_route_reinstall);
                   3155:        timerclear(&this->next_roam);
                   3156: 
                   3157:        check_kernel_features(this);
                   3158: 
                   3159:        if (streq(lib->ns, "starter"))
                   3160:        {       /* starter has no threads, so we do not register for kernel events */
                   3161:                register_for_events = FALSE;
                   3162:        }
                   3163: 
                   3164:        exclude = lib->settings->get_str(lib->settings,
                   3165:                                                                         "%s.ignore_routing_tables", NULL, lib->ns);
                   3166:        if (exclude)
                   3167:        {
                   3168:                char *token;
                   3169:                uintptr_t table;
                   3170: 
                   3171:                enumerator = enumerator_create_token(exclude, " ", " ");
                   3172:                while (enumerator->enumerate(enumerator, &token))
                   3173:                {
                   3174:                        errno = 0;
                   3175:                        table = strtoul(token, NULL, 10);
                   3176: 
                   3177:                        if (errno == 0)
                   3178:                        {
                   3179:                                this->rt_exclude->insert_last(this->rt_exclude, (void*)table);
                   3180:                        }
                   3181:                }
                   3182:                enumerator->destroy(enumerator);
                   3183:        }
                   3184: 
                   3185:        if (register_for_events)
                   3186:        {
                   3187:                struct sockaddr_nl addr;
                   3188: 
                   3189:                memset(&addr, 0, sizeof(addr));
                   3190:                addr.nl_family = AF_NETLINK;
                   3191: 
                   3192:                /* create and bind RT socket for events (address/interface/route changes) */
                   3193:                this->socket_events = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
                   3194:                if (this->socket_events < 0)
                   3195:                {
                   3196:                        DBG1(DBG_KNL, "unable to create RT event socket: %s (%d)",
                   3197:                                 strerror(errno), errno);
                   3198:                        destroy(this);
                   3199:                        return NULL;
                   3200:                }
                   3201:                addr.nl_groups = nl_group(RTNLGRP_IPV4_IFADDR) |
                   3202:                                                 nl_group(RTNLGRP_IPV6_IFADDR) |
                   3203:                                                 nl_group(RTNLGRP_LINK);
                   3204:                if (this->process_route)
                   3205:                {
                   3206:                        addr.nl_groups |= nl_group(RTNLGRP_IPV4_ROUTE) |
                   3207:                                                          nl_group(RTNLGRP_IPV6_ROUTE);
                   3208:                }
                   3209:                if (this->process_rules)
                   3210:                {
                   3211:                        addr.nl_groups |= nl_group(RTNLGRP_IPV4_RULE) |
                   3212:                                                          nl_group(RTNLGRP_IPV6_RULE);
                   3213:                }
                   3214:                if (bind(this->socket_events, (struct sockaddr*)&addr, sizeof(addr)))
                   3215:                {
                   3216:                        DBG1(DBG_KNL, "unable to bind RT event socket: %s (%d)",
                   3217:                                 strerror(errno), errno);
                   3218:                        destroy(this);
                   3219:                        return NULL;
                   3220:                }
                   3221: 
                   3222:                lib->watcher->add(lib->watcher, this->socket_events, WATCHER_READ,
                   3223:                                                  (watcher_cb_t)receive_events, this);
                   3224:        }
                   3225: 
                   3226:        if (init_address_list(this) != SUCCESS)
                   3227:        {
                   3228:                DBG1(DBG_KNL, "unable to get interface list");
                   3229:                destroy(this);
                   3230:                return NULL;
                   3231:        }
                   3232: 
                   3233:        if (this->routing_table)
                   3234:        {
                   3235:                if (manage_rule(this, RTM_NEWRULE, AF_INET, this->routing_table,
                   3236:                                                this->routing_table_prio) != SUCCESS)
                   3237:                {
                   3238:                        DBG1(DBG_KNL, "unable to create IPv4 routing table rule");
                   3239:                }
                   3240:                if (manage_rule(this, RTM_NEWRULE, AF_INET6, this->routing_table,
                   3241:                                                this->routing_table_prio) != SUCCESS)
                   3242:                {
                   3243:                        DBG1(DBG_KNL, "unable to create IPv6 routing table rule");
                   3244:                }
                   3245:        }
                   3246: 
                   3247:        return &this->public;
                   3248: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>