2 * Copyright (C) 2008-2012 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
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>.
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
18 * Copyright (C) 2010 secunet Security Networks AG
19 * Copyright (C) 2010 Thomas Egerer
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:
28 * The above copyright notice and this permission notice shall be included in
29 * all copies or substantial portions of the Software.
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
40 #include <sys/socket.h>
41 #include <sys/utsname.h>
42 #include <linux/netlink.h>
43 #include <linux/rtnetlink.h>
48 #include "kernel_netlink_net.h"
49 #include "kernel_netlink_shared.h"
53 #include <threading/thread.h>
54 #include <threading/condvar.h>
55 #include <threading/mutex.h>
56 #include <utils/hashtable.h>
57 #include <utils/linked_list.h>
58 #include <processing/jobs/callback_job.h>
60 /** delay before firing roam events (ms) */
61 #define ROAM_DELAY 100
63 /** delay before reinstalling routes (ms) */
64 #define ROUTE_DELAY 100
66 typedef struct addr_entry_t addr_entry_t
;
69 * IP address in an inface_entry_t
76 /** virtual IP managed by us */
79 /** scope of the address */
82 /** Number of times this IP is used, if virtual */
87 * destroy a addr_entry_t object
89 static void addr_entry_destroy(addr_entry_t
*this)
91 this->ip
->destroy(this->ip
);
95 typedef struct iface_entry_t iface_entry_t
;
98 * A network interface on this system, containing addr_entry_t's
100 struct iface_entry_t
{
102 /** interface index */
105 /** name of the interface */
106 char ifname
[IFNAMSIZ
];
108 /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
111 /** list of addresses as host_t */
112 linked_list_t
*addrs
;
114 /** TRUE if usable by config */
119 * destroy an interface entry
121 static void iface_entry_destroy(iface_entry_t
*this)
123 this->addrs
->destroy_function(this->addrs
, (void*)addr_entry_destroy
);
128 * find an interface entry by index
130 static bool iface_entry_by_index(iface_entry_t
*this, int *ifindex
)
132 return this->ifindex
== *ifindex
;
136 * check if an interface is up and usable
138 static inline bool iface_entry_up_and_usable(iface_entry_t
*iface
)
140 return iface
->usable
&& (iface
->flags
& IFF_UP
) == IFF_UP
;
143 typedef struct route_entry_t route_entry_t
;
146 * Installed routing entry
148 struct route_entry_t
{
149 /** Name of the interface the route is bound to */
152 /** Source ip of the route */
155 /** Gateway for this route */
158 /** Destination net */
161 /** Destination net prefixlen */
166 * Clone a route_entry_t object.
168 static route_entry_t
*route_entry_clone(route_entry_t
*this)
170 route_entry_t
*route
;
173 .if_name
= strdup(this->if_name
),
174 .src_ip
= this->src_ip
->clone(this->src_ip
),
175 .gateway
= this->gateway
->clone(this->gateway
),
176 .dst_net
= chunk_clone(this->dst_net
),
177 .prefixlen
= this->prefixlen
,
183 * Destroy a route_entry_t object
185 static void route_entry_destroy(route_entry_t
*this)
188 DESTROY_IF(this->src_ip
);
189 DESTROY_IF(this->gateway
);
190 chunk_free(&this->dst_net
);
195 * Hash a route_entry_t object
197 static u_int
route_entry_hash(route_entry_t
*this)
199 return chunk_hash_inc(chunk_from_thing(this->prefixlen
),
200 chunk_hash(this->dst_net
));
204 * Compare two route_entry_t objects
206 static bool route_entry_equals(route_entry_t
*a
, route_entry_t
*b
)
208 return a
->if_name
&& b
->if_name
&& streq(a
->if_name
, b
->if_name
) &&
209 a
->src_ip
->ip_equals(a
->src_ip
, b
->src_ip
) &&
210 a
->gateway
->ip_equals(a
->gateway
, b
->gateway
) &&
211 chunk_equals(a
->dst_net
, b
->dst_net
) && a
->prefixlen
== b
->prefixlen
;
214 typedef struct net_change_t net_change_t
;
217 * Queued network changes
219 struct net_change_t
{
220 /** Name of the interface that got activated (or an IP appeared on) */
225 * Destroy a net_change_t object
227 static void net_change_destroy(net_change_t
*this)
234 * Hash a net_change_t object
236 static u_int
net_change_hash(net_change_t
*this)
238 return chunk_hash(chunk_create(this->if_name
, strlen(this->if_name
)));
242 * Compare two net_change_t objects
244 static bool net_change_equals(net_change_t
*a
, net_change_t
*b
)
246 return streq(a
->if_name
, b
->if_name
);
249 typedef struct private_kernel_netlink_net_t private_kernel_netlink_net_t
;
252 * Private variables and functions of kernel_netlink_net class.
254 struct private_kernel_netlink_net_t
{
256 * Public part of the kernel_netlink_net_t object.
258 kernel_netlink_net_t
public;
261 * mutex to lock access to various lists
266 * condition variable to signal virtual IP add/removal
271 * Cached list of interfaces and its addresses (iface_entry_t)
273 linked_list_t
*ifaces
;
276 * netlink rt socket (routing)
278 netlink_socket_t
*socket
;
281 * Netlink rt socket to receive address change events
286 * time of the last roam event
291 * routing table to install routes
296 * priority of used routing table
298 int routing_table_prio
;
306 * interface changes which may trigger route reinstallation
308 hashtable_t
*net_changes
;
311 * mutex for route reinstallation triggers
313 mutex_t
*net_changes_lock
;
316 * time of last route reinstallation
318 timeval_t last_route_reinstall
;
321 * whether to react to RTM_NEWROUTE or RTM_DELROUTE events
326 * whether to actually install virtual IPs
328 bool install_virtual_ip
;
331 * whether preferred source addresses can be specified for IPv6 routes
333 bool rta_prefsrc_for_ipv6
;
336 * list with routing tables to be excluded from route lookup
338 linked_list_t
*rt_exclude
;
342 * Forward declaration
344 static status_t
manage_srcroute(private_kernel_netlink_net_t
*this,
345 int nlmsg_type
, int flags
, chunk_t dst_net
,
346 u_int8_t prefixlen
, host_t
*gateway
,
347 host_t
*src_ip
, char *if_name
);
350 * Clear the queued network changes.
352 static void net_changes_clear(private_kernel_netlink_net_t
*this)
354 enumerator_t
*enumerator
;
355 net_change_t
*change
;
357 enumerator
= this->net_changes
->create_enumerator(this->net_changes
);
358 while (enumerator
->enumerate(enumerator
, NULL
, (void**)&change
))
360 this->net_changes
->remove_at(this->net_changes
, enumerator
);
361 net_change_destroy(change
);
363 enumerator
->destroy(enumerator
);
367 * Act upon queued network changes.
369 static job_requeue_t
reinstall_routes(private_kernel_netlink_net_t
*this)
371 enumerator_t
*enumerator
;
372 route_entry_t
*route
;
374 this->net_changes_lock
->lock(this->net_changes_lock
);
375 this->mutex
->lock(this->mutex
);
377 enumerator
= this->routes
->create_enumerator(this->routes
);
378 while (enumerator
->enumerate(enumerator
, NULL
, (void**)&route
))
380 net_change_t
*change
, lookup
= {
381 .if_name
= route
->if_name
,
383 /* check if a change for the outgoing interface is queued */
384 change
= this->net_changes
->get(this->net_changes
, &lookup
);
386 { /* in case src_ip is not on the outgoing interface */
387 if (this->public.interface
.get_interface(&this->public.interface
,
388 route
->src_ip
, &lookup
.if_name
))
390 if (!streq(lookup
.if_name
, route
->if_name
))
392 change
= this->net_changes
->get(this->net_changes
, &lookup
);
394 free(lookup
.if_name
);
399 manage_srcroute(this, RTM_NEWROUTE
, NLM_F_CREATE
| NLM_F_EXCL
,
400 route
->dst_net
, route
->prefixlen
, route
->gateway
,
401 route
->src_ip
, route
->if_name
);
404 enumerator
->destroy(enumerator
);
405 this->mutex
->unlock(this->mutex
);
407 net_changes_clear(this);
408 this->net_changes_lock
->unlock(this->net_changes_lock
);
409 return JOB_REQUEUE_NONE
;
413 * Queue route reinstallation caused by network changes for a given interface.
415 * The route reinstallation is delayed for a while and only done once for
416 * several calls during this delay, in order to avoid doing it too often.
417 * The interface name is freed.
419 static void queue_route_reinstall(private_kernel_netlink_net_t
*this,
422 net_change_t
*update
, *found
;
430 this->net_changes_lock
->lock(this->net_changes_lock
);
431 found
= this->net_changes
->put(this->net_changes
, update
, update
);
434 net_change_destroy(found
);
436 time_monotonic(&now
);
437 if (timercmp(&now
, &this->last_route_reinstall
, >))
439 now
.tv_usec
+= ROUTE_DELAY
* 1000;
440 while (now
.tv_usec
> 1000000)
443 now
.tv_usec
-= 1000000;
445 this->last_route_reinstall
= now
;
447 job
= (job_t
*)callback_job_create((callback_job_cb_t
)reinstall_routes
,
449 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, job
, ROUTE_DELAY
);
451 this->net_changes_lock
->unlock(this->net_changes_lock
);
455 * get the refcount of a virtual ip
457 static int get_vip_refcount(private_kernel_netlink_net_t
*this, host_t
* ip
)
459 enumerator_t
*ifaces
, *addrs
;
460 iface_entry_t
*iface
;
464 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
465 while (ifaces
->enumerate(ifaces
, (void**)&iface
))
467 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
468 while (addrs
->enumerate(addrs
, (void**)&addr
))
470 if (addr
->virtual && (iface
->flags
& IFF_UP
) &&
471 ip
->ip_equals(ip
, addr
->ip
))
473 refcount
= addr
->refcount
;
477 addrs
->destroy(addrs
);
483 ifaces
->destroy(ifaces
);
489 * get the first non-virtual ip address on the given interface.
490 * if a candidate address is given, we first search for that address and if not
491 * found return the address as above.
492 * returned host is a clone, has to be freed by caller.
494 static host_t
*get_interface_address(private_kernel_netlink_net_t
*this,
495 int ifindex
, int family
, host_t
*candidate
)
497 enumerator_t
*ifaces
, *addrs
;
498 iface_entry_t
*iface
;
502 this->mutex
->lock(this->mutex
);
503 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
504 while (ifaces
->enumerate(ifaces
, &iface
))
506 if (iface
->ifindex
== ifindex
)
509 { /* ignore interfaces excluded by config */
512 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
513 while (addrs
->enumerate(addrs
, &addr
))
519 if (addr
->ip
->get_family(addr
->ip
) == family
)
521 if (!candidate
|| candidate
->ip_equals(candidate
, addr
->ip
))
522 { /* stop at the first address if we don't search for a
523 * candidate or if the candidate matches */
528 { /* store the first address as fallback if candidate is
534 addrs
->destroy(addrs
);
538 ifaces
->destroy(ifaces
);
543 this->mutex
->unlock(this->mutex
);
548 * callback function that raises the delayed roam event
550 static job_requeue_t
roam_event(uintptr_t address
)
552 hydra
->kernel_interface
->roam(hydra
->kernel_interface
, address
!= 0);
553 return JOB_REQUEUE_NONE
;
557 * fire a roaming event. we delay it for a bit and fire only one event
558 * for multiple calls. otherwise we would create too many events.
560 static void fire_roam_event(private_kernel_netlink_net_t
*this, bool address
)
565 time_monotonic(&now
);
566 if (timercmp(&now
, &this->last_roam
, >))
568 now
.tv_usec
+= ROAM_DELAY
* 1000;
569 while (now
.tv_usec
> 1000000)
572 now
.tv_usec
-= 1000000;
574 this->last_roam
= now
;
576 job
= (job_t
*)callback_job_create((callback_job_cb_t
)roam_event
,
577 (void*)(uintptr_t)(address ?
1 : 0),
579 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, job
, ROAM_DELAY
);
584 * check if an interface with a given index is up and usable
586 static bool is_interface_up_and_usable(private_kernel_netlink_net_t
*this,
589 iface_entry_t
*iface
;
591 if (this->ifaces
->find_first(this->ifaces
, (void*)iface_entry_by_index
,
592 (void**)&iface
, &index
) == SUCCESS
)
594 return iface_entry_up_and_usable(iface
);
600 * process RTM_NEWLINK/RTM_DELLINK from kernel
602 static void process_link(private_kernel_netlink_net_t
*this,
603 struct nlmsghdr
*hdr
, bool event
)
605 struct ifinfomsg
* msg
= (struct ifinfomsg
*)(NLMSG_DATA(hdr
));
606 struct rtattr
*rta
= IFLA_RTA(msg
);
607 size_t rtasize
= IFLA_PAYLOAD (hdr
);
608 enumerator_t
*enumerator
;
609 iface_entry_t
*current
, *entry
= NULL
;
611 bool update
= FALSE
, update_routes
= FALSE
;
613 while (RTA_OK(rta
, rtasize
))
615 switch (rta
->rta_type
)
618 name
= RTA_DATA(rta
);
621 rta
= RTA_NEXT(rta
, rtasize
);
628 this->mutex
->lock(this->mutex
);
629 switch (hdr
->nlmsg_type
)
633 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
634 while (enumerator
->enumerate(enumerator
, ¤t
))
636 if (current
->ifindex
== msg
->ifi_index
)
642 enumerator
->destroy(enumerator
);
645 entry
= malloc_thing(iface_entry_t
);
646 entry
->ifindex
= msg
->ifi_index
;
648 entry
->usable
= hydra
->kernel_interface
->is_interface_usable(
649 hydra
->kernel_interface
, name
);
650 entry
->addrs
= linked_list_create();
651 this->ifaces
->insert_last(this->ifaces
, entry
);
653 strncpy(entry
->ifname
, name
, IFNAMSIZ
);
654 entry
->ifname
[IFNAMSIZ
-1] = '\0';
655 if (event
&& entry
->usable
)
657 if (!(entry
->flags
& IFF_UP
) && (msg
->ifi_flags
& IFF_UP
))
659 update
= update_routes
= TRUE
;
660 DBG1(DBG_KNL
, "interface %s activated", name
);
662 if ((entry
->flags
& IFF_UP
) && !(msg
->ifi_flags
& IFF_UP
))
665 DBG1(DBG_KNL
, "interface %s deactivated", name
);
668 entry
->flags
= msg
->ifi_flags
;
673 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
674 while (enumerator
->enumerate(enumerator
, ¤t
))
676 if (current
->ifindex
== msg
->ifi_index
)
678 if (event
&& current
->usable
)
681 DBG1(DBG_KNL
, "interface %s deleted", current
->ifname
);
683 this->ifaces
->remove_at(this->ifaces
, enumerator
);
684 iface_entry_destroy(current
);
688 enumerator
->destroy(enumerator
);
692 this->mutex
->unlock(this->mutex
);
694 if (update_routes
&& event
)
696 queue_route_reinstall(this, strdup(name
));
699 /* send an update to all IKE_SAs */
702 fire_roam_event(this, TRUE
);
707 * process RTM_NEWADDR/RTM_DELADDR from kernel
709 static void process_addr(private_kernel_netlink_net_t
*this,
710 struct nlmsghdr
*hdr
, bool event
)
712 struct ifaddrmsg
* msg
= (struct ifaddrmsg
*)(NLMSG_DATA(hdr
));
713 struct rtattr
*rta
= IFA_RTA(msg
);
714 size_t rtasize
= IFA_PAYLOAD (hdr
);
716 enumerator_t
*ifaces
, *addrs
;
717 iface_entry_t
*iface
;
719 chunk_t local
= chunk_empty
, address
= chunk_empty
;
720 char *route_ifname
= NULL
;
721 bool update
= FALSE
, found
= FALSE
, changed
= FALSE
;
723 while (RTA_OK(rta
, rtasize
))
725 switch (rta
->rta_type
)
728 local
.ptr
= RTA_DATA(rta
);
729 local
.len
= RTA_PAYLOAD(rta
);
732 address
.ptr
= RTA_DATA(rta
);
733 address
.len
= RTA_PAYLOAD(rta
);
736 rta
= RTA_NEXT(rta
, rtasize
);
739 /* For PPP interfaces, we need the IFA_LOCAL address,
740 * IFA_ADDRESS is the peers address. But IFA_LOCAL is
741 * not included in all cases (IPv6?), so fallback to IFA_ADDRESS. */
744 host
= host_create_from_chunk(msg
->ifa_family
, local
, 0);
746 else if (address
.ptr
)
748 host
= host_create_from_chunk(msg
->ifa_family
, address
, 0);
756 this->mutex
->lock(this->mutex
);
757 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
758 while (ifaces
->enumerate(ifaces
, &iface
))
760 if (iface
->ifindex
== msg
->ifa_index
)
762 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
763 while (addrs
->enumerate(addrs
, &addr
))
765 if (host
->ip_equals(host
, addr
->ip
))
768 if (hdr
->nlmsg_type
== RTM_DELADDR
)
770 iface
->addrs
->remove_at(iface
->addrs
, addrs
);
771 if (!addr
->virtual && iface
->usable
)
774 DBG1(DBG_KNL
, "%H disappeared from %s",
775 host
, iface
->ifname
);
777 addr_entry_destroy(addr
);
779 else if (hdr
->nlmsg_type
== RTM_NEWADDR
&& addr
->virtual)
785 addrs
->destroy(addrs
);
787 if (hdr
->nlmsg_type
== RTM_NEWADDR
)
793 route_ifname
= strdup(iface
->ifname
);
794 addr
= malloc_thing(addr_entry_t
);
795 addr
->ip
= host
->clone(host
);
796 addr
->virtual = FALSE
;
798 addr
->scope
= msg
->ifa_scope
;
800 iface
->addrs
->insert_last(iface
->addrs
, addr
);
801 if (event
&& iface
->usable
)
803 DBG1(DBG_KNL
, "%H appeared on %s", host
, iface
->ifname
);
807 if (found
&& (iface
->flags
& IFF_UP
))
812 { /* ignore events for interfaces excluded by config */
813 update
= changed
= FALSE
;
818 ifaces
->destroy(ifaces
);
819 this->mutex
->unlock(this->mutex
);
821 if (update
&& event
&& route_ifname
)
823 queue_route_reinstall(this, route_ifname
);
831 /* send an update to all IKE_SAs */
832 if (update
&& event
&& changed
)
834 fire_roam_event(this, TRUE
);
839 * process RTM_NEWROUTE and RTM_DELROUTE from kernel
841 static void process_route(private_kernel_netlink_net_t
*this, struct nlmsghdr
*hdr
)
843 struct rtmsg
* msg
= (struct rtmsg
*)(NLMSG_DATA(hdr
));
844 struct rtattr
*rta
= RTM_RTA(msg
);
845 size_t rtasize
= RTM_PAYLOAD(hdr
);
846 u_int32_t rta_oif
= 0;
849 /* ignore routes added by us or in the local routing table (local addrs) */
850 if (msg
->rtm_table
&& (msg
->rtm_table
== this->routing_table
||
851 msg
->rtm_table
== RT_TABLE_LOCAL
))
855 else if (msg
->rtm_flags
& RTM_F_CLONED
)
856 { /* ignore cached routes, seem to be created a lot for IPv6 */
860 while (RTA_OK(rta
, rtasize
))
862 switch (rta
->rta_type
)
866 host
= host_create_from_chunk(msg
->rtm_family
,
867 chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
)), 0);
870 if (RTA_PAYLOAD(rta
) == sizeof(rta_oif
))
872 rta_oif
= *(u_int32_t
*)RTA_DATA(rta
);
876 rta
= RTA_NEXT(rta
, rtasize
);
878 this->mutex
->lock(this->mutex
);
879 if (rta_oif
&& !is_interface_up_and_usable(this, rta_oif
))
880 { /* ignore route changes for interfaces that are ignored or down */
881 this->mutex
->unlock(this->mutex
);
885 if (!host
&& rta_oif
)
887 host
= get_interface_address(this, rta_oif
, msg
->rtm_family
, NULL
);
891 if (!get_vip_refcount(this, host
))
892 { /* ignore routes added for virtual IPs */
893 fire_roam_event(this, FALSE
);
897 this->mutex
->unlock(this->mutex
);
901 * Receives events from kernel
903 static job_requeue_t
receive_events(private_kernel_netlink_net_t
*this)
906 struct nlmsghdr
*hdr
= (struct nlmsghdr
*)response
;
907 struct sockaddr_nl addr
;
908 socklen_t addr_len
= sizeof(addr
);
912 oldstate
= thread_cancelability(TRUE
);
913 len
= recvfrom(this->socket_events
, response
, sizeof(response
), 0,
914 (struct sockaddr
*)&addr
, &addr_len
);
915 thread_cancelability(oldstate
);
922 /* interrupted, try again */
923 return JOB_REQUEUE_DIRECT
;
925 /* no data ready, select again */
926 return JOB_REQUEUE_DIRECT
;
928 DBG1(DBG_KNL
, "unable to receive from rt event socket");
930 return JOB_REQUEUE_FAIR
;
934 if (addr
.nl_pid
!= 0)
935 { /* not from kernel. not interested, try another one */
936 return JOB_REQUEUE_DIRECT
;
939 while (NLMSG_OK(hdr
, len
))
941 /* looks good so far, dispatch netlink message */
942 switch (hdr
->nlmsg_type
)
946 process_addr(this, hdr
, TRUE
);
947 this->condvar
->broadcast(this->condvar
);
951 process_link(this, hdr
, TRUE
);
952 this->condvar
->broadcast(this->condvar
);
956 if (this->process_route
)
958 process_route(this, hdr
);
964 hdr
= NLMSG_NEXT(hdr
, len
);
966 return JOB_REQUEUE_DIRECT
;
969 /** enumerator over addresses */
971 private_kernel_netlink_net_t
* this;
972 /** whether to enumerate down interfaces */
973 bool include_down_ifaces
;
974 /** whether to enumerate virtual ip addresses */
975 bool include_virtual_ips
;
976 /** whether to enumerate loopback interfaces */
977 bool include_loopback
;
978 } address_enumerator_t
;
981 * cleanup function for address enumerator
983 static void address_enumerator_destroy(address_enumerator_t
*data
)
985 data
->this->mutex
->unlock(data
->this->mutex
);
990 * filter for addresses
992 static bool filter_addresses(address_enumerator_t
*data
,
993 addr_entry_t
** in
, host_t
** out
)
995 if (!data
->include_virtual_ips
&& (*in
)->virtual)
996 { /* skip virtual interfaces added by us */
999 if ((*in
)->scope
>= RT_SCOPE_LINK
)
1000 { /* skip addresses with a unusable scope */
1008 * enumerator constructor for interfaces
1010 static enumerator_t
*create_iface_enumerator(iface_entry_t
*iface
,
1011 address_enumerator_t
*data
)
1013 return enumerator_create_filter(
1014 iface
->addrs
->create_enumerator(iface
->addrs
),
1015 (void*)filter_addresses
, data
, NULL
);
1019 * filter for interfaces
1021 static bool filter_interfaces(address_enumerator_t
*data
, iface_entry_t
** in
,
1022 iface_entry_t
** out
)
1025 { /* skip interfaces excluded by config */
1028 if (!data
->include_loopback
&& ((*in
)->flags
& IFF_LOOPBACK
))
1029 { /* ignore loopback devices */
1032 if (!data
->include_down_ifaces
&& !((*in
)->flags
& IFF_UP
))
1033 { /* skip interfaces not up */
1040 METHOD(kernel_net_t
, create_address_enumerator
, enumerator_t
*,
1041 private_kernel_netlink_net_t
*this,
1042 bool include_down_ifaces
, bool include_virtual_ips
, bool include_loopback
)
1044 address_enumerator_t
*data
= malloc_thing(address_enumerator_t
);
1046 data
->include_down_ifaces
= include_down_ifaces
;
1047 data
->include_virtual_ips
= include_virtual_ips
;
1048 data
->include_loopback
= include_loopback
;
1050 this->mutex
->lock(this->mutex
);
1051 return enumerator_create_nested(
1052 enumerator_create_filter(
1053 this->ifaces
->create_enumerator(this->ifaces
),
1054 (void*)filter_interfaces
, data
, NULL
),
1055 (void*)create_iface_enumerator
, data
,
1056 (void*)address_enumerator_destroy
);
1059 METHOD(kernel_net_t
, get_interface_name
, bool,
1060 private_kernel_netlink_net_t
*this, host_t
* ip
, char **name
)
1062 enumerator_t
*ifaces
, *addrs
;
1063 iface_entry_t
*iface
;
1065 bool found
= FALSE
, ignored
= FALSE
;
1067 if (ip
->is_anyaddr(ip
))
1072 this->mutex
->lock(this->mutex
);
1073 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1074 while (ifaces
->enumerate(ifaces
, &iface
))
1076 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1077 while (addrs
->enumerate(addrs
, &addr
))
1079 if (ip
->ip_equals(ip
, addr
->ip
))
1089 *name
= strdup(iface
->ifname
);
1094 addrs
->destroy(addrs
);
1100 ifaces
->destroy(ifaces
);
1101 this->mutex
->unlock(this->mutex
);
1107 DBG2(DBG_KNL
, "%H is not a local address", ip
);
1111 DBG2(DBG_KNL
, "%H is on interface %s", ip
, *name
);
1114 return found
&& !ignored
;
1118 * get the index of an interface by name
1120 static int get_interface_index(private_kernel_netlink_net_t
*this, char* name
)
1122 enumerator_t
*ifaces
;
1123 iface_entry_t
*iface
;
1126 DBG2(DBG_KNL
, "getting iface index for %s", name
);
1128 this->mutex
->lock(this->mutex
);
1129 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1130 while (ifaces
->enumerate(ifaces
, &iface
))
1132 if (streq(name
, iface
->ifname
))
1134 ifindex
= iface
->ifindex
;
1138 ifaces
->destroy(ifaces
);
1139 this->mutex
->unlock(this->mutex
);
1143 DBG1(DBG_KNL
, "unable to get interface index for %s", name
);
1149 * check if an address (chunk) addr is in subnet (net with net_len net bits)
1151 static bool addr_in_subnet(chunk_t addr
, chunk_t net
, int net_len
)
1153 static const u_char mask
[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
1157 { /* any address matches a /0 network */
1160 if (addr
.len
!= net
.len
|| net_len
> 8 * net
.len
)
1164 /* scan through all bytes in network order */
1169 return (mask
[net_len
] & addr
.ptr
[byte
]) == (mask
[net_len
] & net
.ptr
[byte
]);
1173 if (addr
.ptr
[byte
] != net
.ptr
[byte
])
1185 * Store information about a route retrieved via RTNETLINK
1198 * Free a route entry
1200 static void rt_entry_destroy(rt_entry_t
*this)
1202 DESTROY_IF(this->src_host
);
1207 * Parse route received with RTM_NEWROUTE. The given rt_entry_t object will be
1208 * reused if not NULL.
1210 * Returned chunks point to internal data of the Netlink message.
1212 static rt_entry_t
*parse_route(struct nlmsghdr
*hdr
, rt_entry_t
*route
)
1218 msg
= (struct rtmsg
*)(NLMSG_DATA(hdr
));
1220 rtasize
= RTM_PAYLOAD(hdr
);
1224 route
->gtw
= chunk_empty
;
1225 route
->src
= chunk_empty
;
1226 route
->dst
= chunk_empty
;
1227 route
->dst_len
= msg
->rtm_dst_len
;
1228 route
->table
= msg
->rtm_table
;
1234 .dst_len
= msg
->rtm_dst_len
,
1235 .table
= msg
->rtm_table
,
1239 while (RTA_OK(rta
, rtasize
))
1241 switch (rta
->rta_type
)
1244 route
->src
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
1247 route
->gtw
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
1250 route
->dst
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
1253 if (RTA_PAYLOAD(rta
) == sizeof(route
->oif
))
1255 route
->oif
= *(u_int32_t
*)RTA_DATA(rta
);
1258 #ifdef HAVE_RTA_TABLE
1260 if (RTA_PAYLOAD(rta
) == sizeof(route
->table
))
1262 route
->table
= *(u_int32_t
*)RTA_DATA(rta
);
1265 #endif /* HAVE_RTA_TABLE*/
1267 rta
= RTA_NEXT(rta
, rtasize
);
1273 * Get a route: If "nexthop", the nexthop is returned. source addr otherwise.
1275 static host_t
*get_route(private_kernel_netlink_net_t
*this, host_t
*dest
,
1276 bool nexthop
, host_t
*candidate
)
1278 netlink_buf_t request
;
1279 struct nlmsghdr
*hdr
, *out
, *current
;
1283 linked_list_t
*routes
;
1284 rt_entry_t
*route
= NULL
, *best
= NULL
;
1285 enumerator_t
*enumerator
;
1286 host_t
*addr
= NULL
;
1288 memset(&request
, 0, sizeof(request
));
1290 hdr
= (struct nlmsghdr
*)request
;
1291 hdr
->nlmsg_flags
= NLM_F_REQUEST
;
1292 if (dest
->get_family(dest
) == AF_INET
|| this->rta_prefsrc_for_ipv6
||
1293 this->routing_table
)
1294 { /* kernels prior to 3.0 do not support RTA_PREFSRC for IPv6 routes.
1295 * as we want to ignore routes with virtual IPs we cannot use DUMP
1296 * if these routes are not installed in a separate table */
1297 hdr
->nlmsg_flags
|= NLM_F_DUMP
;
1299 hdr
->nlmsg_type
= RTM_GETROUTE
;
1300 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1302 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1303 msg
->rtm_family
= dest
->get_family(dest
);
1306 chunk
= candidate
->get_address(candidate
);
1307 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
1309 chunk
= dest
->get_address(dest
);
1310 netlink_add_attribute(hdr
, RTA_DST
, chunk
, sizeof(request
));
1312 if (this->socket
->send(this->socket
, hdr
, &out
, &len
) != SUCCESS
)
1314 DBG2(DBG_KNL
, "getting %s to reach %H failed",
1315 nexthop ?
"nexthop" : "address", dest
);
1318 routes
= linked_list_create();
1319 this->mutex
->lock(this->mutex
);
1321 for (current
= out
; NLMSG_OK(current
, len
);
1322 current
= NLMSG_NEXT(current
, len
))
1324 switch (current
->nlmsg_type
)
1333 route
= parse_route(current
, route
);
1335 table
= (uintptr_t)route
->table
;
1336 if (this->rt_exclude
->find_first(this->rt_exclude
, NULL
,
1337 (void**)&table
) == SUCCESS
)
1338 { /* route is from an excluded routing table */
1341 if (this->routing_table
!= 0 &&
1342 route
->table
== this->routing_table
)
1343 { /* route is from our own ipsec routing table */
1346 if (route
->oif
&& !is_interface_up_and_usable(this, route
->oif
))
1347 { /* interface is down */
1350 if (!addr_in_subnet(chunk
, route
->dst
, route
->dst_len
))
1351 { /* route destination does not contain dest */
1355 { /* verify source address, if any */
1356 host_t
*src
= host_create_from_chunk(msg
->rtm_family
,
1358 if (src
&& get_vip_refcount(this, src
))
1359 { /* ignore routes installed by us */
1363 route
->src_host
= src
;
1365 /* insert route, sorted by decreasing network prefix */
1366 enumerator
= routes
->create_enumerator(routes
);
1367 while (enumerator
->enumerate(enumerator
, &other
))
1369 if (route
->dst_len
> other
->dst_len
)
1374 routes
->insert_before(routes
, enumerator
, route
);
1375 enumerator
->destroy(enumerator
);
1386 rt_entry_destroy(route
);
1389 /* now we have a list of routes matching dest, sorted by net prefix.
1390 * we will look for source addresses for these routes and select the one
1391 * with the preferred source address, if possible */
1392 enumerator
= routes
->create_enumerator(routes
);
1393 while (enumerator
->enumerate(enumerator
, &route
))
1395 if (route
->src_host
)
1396 { /* got a source address with the route, if no preferred source
1397 * is given or it matches we are done, as this is the best route */
1398 if (!candidate
|| candidate
->ip_equals(candidate
, route
->src_host
))
1403 else if (route
->oif
)
1404 { /* no match yet, maybe it is assigned to the same interface */
1405 host_t
*src
= get_interface_address(this, route
->oif
,
1406 msg
->rtm_family
, candidate
);
1407 if (src
&& src
->ip_equals(src
, candidate
))
1409 route
->src_host
->destroy(route
->src_host
);
1410 route
->src_host
= src
;
1416 /* no luck yet with the source address. if this is the best (first)
1417 * route we store it as fallback in case we don't find a route with
1418 * the preferred source */
1419 best
= best ?
: route
;
1423 { /* no src, but an interface - get address from it */
1424 route
->src_host
= get_interface_address(this, route
->oif
,
1425 msg
->rtm_family
, candidate
);
1426 if (route
->src_host
)
1427 { /* we handle this address the same as the one above */
1429 candidate
->ip_equals(candidate
, route
->src_host
))
1434 best
= best ?
: route
;
1439 { /* no src, no iface, but a gateway - lookup src to reach gtw */
1442 gtw
= host_create_from_chunk(msg
->rtm_family
, route
->gtw
, 0);
1443 route
->src_host
= get_route(this, gtw
, FALSE
, candidate
);
1445 if (route
->src_host
)
1446 { /* more of the same */
1448 candidate
->ip_equals(candidate
, route
->src_host
))
1453 best
= best ?
: route
;
1457 enumerator
->destroy(enumerator
);
1460 { /* nexthop lookup, return gateway if any */
1461 if (best
|| routes
->get_first(routes
, (void**)&best
) == SUCCESS
)
1463 addr
= host_create_from_chunk(msg
->rtm_family
, best
->gtw
, 0);
1465 addr
= addr ?
: dest
->clone(dest
);
1471 addr
= best
->src_host
->clone(best
->src_host
);
1474 this->mutex
->unlock(this->mutex
);
1475 routes
->destroy_function(routes
, (void*)rt_entry_destroy
);
1480 DBG2(DBG_KNL
, "using %H as %s to reach %H", addr
,
1481 nexthop ?
"nexthop" : "address", dest
);
1485 DBG2(DBG_KNL
, "no %s found to reach %H",
1486 nexthop ?
"nexthop" : "address", dest
);
1491 METHOD(kernel_net_t
, get_source_addr
, host_t
*,
1492 private_kernel_netlink_net_t
*this, host_t
*dest
, host_t
*src
)
1494 return get_route(this, dest
, FALSE
, src
);
1497 METHOD(kernel_net_t
, get_nexthop
, host_t
*,
1498 private_kernel_netlink_net_t
*this, host_t
*dest
, host_t
*src
)
1500 return get_route(this, dest
, TRUE
, src
);
1504 * Manages the creation and deletion of ip addresses on an interface.
1505 * By setting the appropriate nlmsg_type, the ip will be set or unset.
1507 static status_t
manage_ipaddr(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1508 int flags
, int if_index
, host_t
*ip
)
1510 netlink_buf_t request
;
1511 struct nlmsghdr
*hdr
;
1512 struct ifaddrmsg
*msg
;
1515 memset(&request
, 0, sizeof(request
));
1517 chunk
= ip
->get_address(ip
);
1519 hdr
= (struct nlmsghdr
*)request
;
1520 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1521 hdr
->nlmsg_type
= nlmsg_type
;
1522 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1524 msg
= (struct ifaddrmsg
*)NLMSG_DATA(hdr
);
1525 msg
->ifa_family
= ip
->get_family(ip
);
1527 msg
->ifa_prefixlen
= 8 * chunk
.len
;
1528 msg
->ifa_scope
= RT_SCOPE_UNIVERSE
;
1529 msg
->ifa_index
= if_index
;
1531 netlink_add_attribute(hdr
, IFA_LOCAL
, chunk
, sizeof(request
));
1533 return this->socket
->send_ack(this->socket
, hdr
);
1536 METHOD(kernel_net_t
, add_ip
, status_t
,
1537 private_kernel_netlink_net_t
*this, host_t
*virtual_ip
, host_t
*iface_ip
)
1539 iface_entry_t
*iface
;
1541 enumerator_t
*addrs
, *ifaces
;
1544 if (!this->install_virtual_ip
)
1545 { /* disabled by config */
1549 DBG2(DBG_KNL
, "adding virtual IP %H", virtual_ip
);
1551 this->mutex
->lock(this->mutex
);
1552 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1553 while (ifaces
->enumerate(ifaces
, &iface
))
1555 bool iface_found
= FALSE
;
1557 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1558 while (addrs
->enumerate(addrs
, &addr
))
1560 if (iface_ip
->ip_equals(iface_ip
, addr
->ip
))
1564 else if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1567 DBG2(DBG_KNL
, "virtual IP %H already installed on %s",
1568 virtual_ip
, iface
->ifname
);
1569 addrs
->destroy(addrs
);
1570 ifaces
->destroy(ifaces
);
1571 this->mutex
->unlock(this->mutex
);
1575 addrs
->destroy(addrs
);
1579 ifindex
= iface
->ifindex
;
1580 addr
= malloc_thing(addr_entry_t
);
1581 addr
->ip
= virtual_ip
->clone(virtual_ip
);
1583 addr
->virtual = TRUE
;
1584 addr
->scope
= RT_SCOPE_UNIVERSE
;
1585 iface
->addrs
->insert_last(iface
->addrs
, addr
);
1587 if (manage_ipaddr(this, RTM_NEWADDR
, NLM_F_CREATE
| NLM_F_EXCL
,
1588 ifindex
, virtual_ip
) == SUCCESS
)
1590 while (get_vip_refcount(this, virtual_ip
) == 0)
1591 { /* wait until address appears */
1592 this->condvar
->wait(this->condvar
, this->mutex
);
1594 ifaces
->destroy(ifaces
);
1595 this->mutex
->unlock(this->mutex
);
1598 ifaces
->destroy(ifaces
);
1599 this->mutex
->unlock(this->mutex
);
1600 DBG1(DBG_KNL
, "adding virtual IP %H failed", virtual_ip
);
1604 ifaces
->destroy(ifaces
);
1605 this->mutex
->unlock(this->mutex
);
1607 DBG1(DBG_KNL
, "interface address %H not found, unable to install"
1608 "virtual IP %H", iface_ip
, virtual_ip
);
1612 METHOD(kernel_net_t
, del_ip
, status_t
,
1613 private_kernel_netlink_net_t
*this, host_t
*virtual_ip
)
1615 iface_entry_t
*iface
;
1617 enumerator_t
*addrs
, *ifaces
;
1621 if (!this->install_virtual_ip
)
1622 { /* disabled by config */
1626 DBG2(DBG_KNL
, "deleting virtual IP %H", virtual_ip
);
1628 this->mutex
->lock(this->mutex
);
1629 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1630 while (ifaces
->enumerate(ifaces
, &iface
))
1632 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1633 while (addrs
->enumerate(addrs
, &addr
))
1635 if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1637 ifindex
= iface
->ifindex
;
1638 if (addr
->refcount
== 1)
1640 status
= manage_ipaddr(this, RTM_DELADDR
, 0,
1641 ifindex
, virtual_ip
);
1642 if (status
== SUCCESS
)
1643 { /* wait until the address is really gone */
1644 while (get_vip_refcount(this, virtual_ip
) > 0)
1646 this->condvar
->wait(this->condvar
, this->mutex
);
1649 addrs
->destroy(addrs
);
1650 ifaces
->destroy(ifaces
);
1651 this->mutex
->unlock(this->mutex
);
1658 DBG2(DBG_KNL
, "virtual IP %H used by other SAs, not deleting",
1660 addrs
->destroy(addrs
);
1661 ifaces
->destroy(ifaces
);
1662 this->mutex
->unlock(this->mutex
);
1666 addrs
->destroy(addrs
);
1668 ifaces
->destroy(ifaces
);
1669 this->mutex
->unlock(this->mutex
);
1671 DBG2(DBG_KNL
, "virtual IP %H not cached, unable to delete", virtual_ip
);
1676 * Manages source routes in the routing table.
1677 * By setting the appropriate nlmsg_type, the route gets added or removed.
1679 static status_t
manage_srcroute(private_kernel_netlink_net_t
*this,
1680 int nlmsg_type
, int flags
, chunk_t dst_net
,
1681 u_int8_t prefixlen
, host_t
*gateway
,
1682 host_t
*src_ip
, char *if_name
)
1684 netlink_buf_t request
;
1685 struct nlmsghdr
*hdr
;
1690 /* if route is 0.0.0.0/0, we can't install it, as it would
1691 * overwrite the default route. Instead, we add two routes:
1692 * 0.0.0.0/1 and 128.0.0.0/1 */
1693 if (this->routing_table
== 0 && prefixlen
== 0)
1696 u_int8_t half_prefixlen
;
1699 half_net
= chunk_alloca(dst_net
.len
);
1700 memset(half_net
.ptr
, 0, half_net
.len
);
1703 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1704 gateway
, src_ip
, if_name
);
1705 half_net
.ptr
[0] |= 0x80;
1706 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1707 gateway
, src_ip
, if_name
);
1711 memset(&request
, 0, sizeof(request
));
1713 hdr
= (struct nlmsghdr
*)request
;
1714 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1715 hdr
->nlmsg_type
= nlmsg_type
;
1716 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1718 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1719 msg
->rtm_family
= src_ip
->get_family(src_ip
);
1720 msg
->rtm_dst_len
= prefixlen
;
1721 msg
->rtm_table
= this->routing_table
;
1722 msg
->rtm_protocol
= RTPROT_STATIC
;
1723 msg
->rtm_type
= RTN_UNICAST
;
1724 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1726 netlink_add_attribute(hdr
, RTA_DST
, dst_net
, sizeof(request
));
1727 chunk
= src_ip
->get_address(src_ip
);
1728 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
1729 if (gateway
&& gateway
->get_family(gateway
) == src_ip
->get_family(src_ip
))
1731 chunk
= gateway
->get_address(gateway
);
1732 netlink_add_attribute(hdr
, RTA_GATEWAY
, chunk
, sizeof(request
));
1734 ifindex
= get_interface_index(this, if_name
);
1735 chunk
.ptr
= (char*)&ifindex
;
1736 chunk
.len
= sizeof(ifindex
);
1737 netlink_add_attribute(hdr
, RTA_OIF
, chunk
, sizeof(request
));
1739 return this->socket
->send_ack(this->socket
, hdr
);
1742 METHOD(kernel_net_t
, add_route
, status_t
,
1743 private_kernel_netlink_net_t
*this, chunk_t dst_net
, u_int8_t prefixlen
,
1744 host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1747 route_entry_t
*found
, route
= {
1749 .prefixlen
= prefixlen
,
1755 this->mutex
->lock(this->mutex
);
1756 found
= this->routes
->get(this->routes
, &route
);
1759 this->mutex
->unlock(this->mutex
);
1760 return ALREADY_DONE
;
1762 found
= route_entry_clone(&route
);
1763 this->routes
->put(this->routes
, found
, found
);
1764 status
= manage_srcroute(this, RTM_NEWROUTE
, NLM_F_CREATE
| NLM_F_EXCL
,
1765 dst_net
, prefixlen
, gateway
, src_ip
, if_name
);
1766 this->mutex
->unlock(this->mutex
);
1770 METHOD(kernel_net_t
, del_route
, status_t
,
1771 private_kernel_netlink_net_t
*this, chunk_t dst_net
, u_int8_t prefixlen
,
1772 host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1775 route_entry_t
*found
, route
= {
1777 .prefixlen
= prefixlen
,
1783 this->mutex
->lock(this->mutex
);
1784 found
= this->routes
->get(this->routes
, &route
);
1787 this->mutex
->unlock(this->mutex
);
1790 this->routes
->remove(this->routes
, found
);
1791 route_entry_destroy(found
);
1792 status
= manage_srcroute(this, RTM_DELROUTE
, 0, dst_net
, prefixlen
,
1793 gateway
, src_ip
, if_name
);
1794 this->mutex
->unlock(this->mutex
);
1799 * Initialize a list of local addresses.
1801 static status_t
init_address_list(private_kernel_netlink_net_t
*this)
1803 netlink_buf_t request
;
1804 struct nlmsghdr
*out
, *current
, *in
;
1805 struct rtgenmsg
*msg
;
1807 enumerator_t
*ifaces
, *addrs
;
1808 iface_entry_t
*iface
;
1811 DBG2(DBG_KNL
, "known interfaces and IP addresses:");
1813 memset(&request
, 0, sizeof(request
));
1815 in
= (struct nlmsghdr
*)&request
;
1816 in
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtgenmsg
));
1817 in
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_MATCH
| NLM_F_ROOT
;
1818 msg
= (struct rtgenmsg
*)NLMSG_DATA(in
);
1819 msg
->rtgen_family
= AF_UNSPEC
;
1822 in
->nlmsg_type
= RTM_GETLINK
;
1823 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1828 while (NLMSG_OK(current
, len
))
1830 switch (current
->nlmsg_type
)
1835 process_link(this, current
, FALSE
);
1838 current
= NLMSG_NEXT(current
, len
);
1845 /* get all interface addresses */
1846 in
->nlmsg_type
= RTM_GETADDR
;
1847 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1852 while (NLMSG_OK(current
, len
))
1854 switch (current
->nlmsg_type
)
1859 process_addr(this, current
, FALSE
);
1862 current
= NLMSG_NEXT(current
, len
);
1869 this->mutex
->lock(this->mutex
);
1870 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1871 while (ifaces
->enumerate(ifaces
, &iface
))
1873 if (iface_entry_up_and_usable(iface
))
1875 DBG2(DBG_KNL
, " %s", iface
->ifname
);
1876 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1877 while (addrs
->enumerate(addrs
, (void**)&addr
))
1879 DBG2(DBG_KNL
, " %H", addr
->ip
);
1881 addrs
->destroy(addrs
);
1884 ifaces
->destroy(ifaces
);
1885 this->mutex
->unlock(this->mutex
);
1890 * create or delete a rule to use our routing table
1892 static status_t
manage_rule(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1893 int family
, u_int32_t table
, u_int32_t prio
)
1895 netlink_buf_t request
;
1896 struct nlmsghdr
*hdr
;
1900 memset(&request
, 0, sizeof(request
));
1901 hdr
= (struct nlmsghdr
*)request
;
1902 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1903 hdr
->nlmsg_type
= nlmsg_type
;
1904 if (nlmsg_type
== RTM_NEWRULE
)
1906 hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
1908 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1910 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1911 msg
->rtm_table
= table
;
1912 msg
->rtm_family
= family
;
1913 msg
->rtm_protocol
= RTPROT_BOOT
;
1914 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1915 msg
->rtm_type
= RTN_UNICAST
;
1917 chunk
= chunk_from_thing(prio
);
1918 netlink_add_attribute(hdr
, RTA_PRIORITY
, chunk
, sizeof(request
));
1920 return this->socket
->send_ack(this->socket
, hdr
);
1924 * check for kernel features (currently only via version number)
1926 static void check_kernel_features(private_kernel_netlink_net_t
*this)
1928 struct utsname utsname
;
1931 if (uname(&utsname
) == 0)
1933 switch(sscanf(utsname
.release
, "%d.%d.%d", &a
, &b
, &c
))
1938 DBG2(DBG_KNL
, "detected Linux %d.%d.%d, no support for "
1939 "RTA_PREFSRC for IPv6 routes", a
, b
, c
);
1944 /* only 3.x+ uses two part version numbers */
1945 this->rta_prefsrc_for_ipv6
= TRUE
;
1953 METHOD(kernel_net_t
, destroy
, void,
1954 private_kernel_netlink_net_t
*this)
1956 enumerator_t
*enumerator
;
1957 route_entry_t
*route
;
1959 if (this->routing_table
)
1961 manage_rule(this, RTM_DELRULE
, AF_INET
, this->routing_table
,
1962 this->routing_table_prio
);
1963 manage_rule(this, RTM_DELRULE
, AF_INET6
, this->routing_table
,
1964 this->routing_table_prio
);
1966 if (this->socket_events
> 0)
1968 close(this->socket_events
);
1970 enumerator
= this->routes
->create_enumerator(this->routes
);
1971 while (enumerator
->enumerate(enumerator
, NULL
, (void**)&route
))
1973 manage_srcroute(this, RTM_DELROUTE
, 0, route
->dst_net
, route
->prefixlen
,
1974 route
->gateway
, route
->src_ip
, route
->if_name
);
1975 route_entry_destroy(route
);
1977 enumerator
->destroy(enumerator
);
1978 this->routes
->destroy(this->routes
);
1979 DESTROY_IF(this->socket
);
1981 net_changes_clear(this);
1982 this->net_changes
->destroy(this->net_changes
);
1983 this->net_changes_lock
->destroy(this->net_changes_lock
);
1985 this->ifaces
->destroy_function(this->ifaces
, (void*)iface_entry_destroy
);
1986 this->rt_exclude
->destroy(this->rt_exclude
);
1987 this->condvar
->destroy(this->condvar
);
1988 this->mutex
->destroy(this->mutex
);
1993 * Described in header.
1995 kernel_netlink_net_t
*kernel_netlink_net_create()
1997 private_kernel_netlink_net_t
*this;
1998 enumerator_t
*enumerator
;
1999 bool register_for_events
= TRUE
;
2005 .get_interface
= _get_interface_name
,
2006 .create_address_enumerator
= _create_address_enumerator
,
2007 .get_source_addr
= _get_source_addr
,
2008 .get_nexthop
= _get_nexthop
,
2011 .add_route
= _add_route
,
2012 .del_route
= _del_route
,
2013 .destroy
= _destroy
,
2016 .socket
= netlink_socket_create(NETLINK_ROUTE
),
2017 .rt_exclude
= linked_list_create(),
2018 .routes
= hashtable_create((hashtable_hash_t
)route_entry_hash
,
2019 (hashtable_equals_t
)route_entry_equals
, 16),
2020 .net_changes
= hashtable_create(
2021 (hashtable_hash_t
)net_change_hash
,
2022 (hashtable_equals_t
)net_change_equals
, 16),
2023 .net_changes_lock
= mutex_create(MUTEX_TYPE_DEFAULT
),
2024 .ifaces
= linked_list_create(),
2025 .mutex
= mutex_create(MUTEX_TYPE_RECURSIVE
),
2026 .condvar
= condvar_create(CONDVAR_TYPE_DEFAULT
),
2027 .routing_table
= lib
->settings
->get_int(lib
->settings
,
2028 "%s.routing_table", ROUTING_TABLE
, hydra
->daemon
),
2029 .routing_table_prio
= lib
->settings
->get_int(lib
->settings
,
2030 "%s.routing_table_prio", ROUTING_TABLE_PRIO
, hydra
->daemon
),
2031 .process_route
= lib
->settings
->get_bool(lib
->settings
,
2032 "%s.process_route", TRUE
, hydra
->daemon
),
2033 .install_virtual_ip
= lib
->settings
->get_bool(lib
->settings
,
2034 "%s.install_virtual_ip", TRUE
, hydra
->daemon
),
2036 timerclear(&this->last_route_reinstall
);
2037 timerclear(&this->last_roam
);
2039 check_kernel_features(this);
2041 if (streq(hydra
->daemon
, "starter"))
2042 { /* starter has no threads, so we do not register for kernel events */
2043 register_for_events
= FALSE
;
2046 exclude
= lib
->settings
->get_str(lib
->settings
,
2047 "%s.ignore_routing_tables", NULL
, hydra
->daemon
);
2053 enumerator
= enumerator_create_token(exclude
, " ", " ");
2054 while (enumerator
->enumerate(enumerator
, &token
))
2057 table
= strtoul(token
, NULL
, 10);
2061 this->rt_exclude
->insert_last(this->rt_exclude
, (void*)table
);
2064 enumerator
->destroy(enumerator
);
2067 if (register_for_events
)
2069 struct sockaddr_nl addr
;
2071 memset(&addr
, 0, sizeof(addr
));
2072 addr
.nl_family
= AF_NETLINK
;
2074 /* create and bind RT socket for events (address/interface/route changes) */
2075 this->socket_events
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
2076 if (this->socket_events
< 0)
2078 DBG1(DBG_KNL
, "unable to create RT event socket");
2082 addr
.nl_groups
= RTMGRP_IPV4_IFADDR
| RTMGRP_IPV6_IFADDR
|
2083 RTMGRP_IPV4_ROUTE
| RTMGRP_IPV6_ROUTE
| RTMGRP_LINK
;
2084 if (bind(this->socket_events
, (struct sockaddr
*)&addr
, sizeof(addr
)))
2086 DBG1(DBG_KNL
, "unable to bind RT event socket");
2091 lib
->processor
->queue_job(lib
->processor
,
2092 (job_t
*)callback_job_create_with_prio(
2093 (callback_job_cb_t
)receive_events
, this, NULL
,
2094 (callback_job_cancel_t
)return_false
, JOB_PRIO_CRITICAL
));
2097 if (init_address_list(this) != SUCCESS
)
2099 DBG1(DBG_KNL
, "unable to get interface list");
2104 if (this->routing_table
)
2106 if (manage_rule(this, RTM_NEWRULE
, AF_INET
, this->routing_table
,
2107 this->routing_table_prio
) != SUCCESS
)
2109 DBG1(DBG_KNL
, "unable to create IPv4 routing table rule");
2111 if (manage_rule(this, RTM_NEWRULE
, AF_INET6
, this->routing_table
,
2112 this->routing_table_prio
) != SUCCESS
)
2114 DBG1(DBG_KNL
, "unable to create IPv6 routing table rule");
2118 return &this->public;