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 <linux/netlink.h>
42 #include <linux/rtnetlink.h>
47 #include "kernel_netlink_net.h"
48 #include "kernel_netlink_shared.h"
52 #include <threading/thread.h>
53 #include <threading/condvar.h>
54 #include <threading/mutex.h>
55 #include <utils/hashtable.h>
56 #include <utils/linked_list.h>
57 #include <processing/jobs/callback_job.h>
59 /** delay before firing roam events (ms) */
60 #define ROAM_DELAY 100
62 /** delay before reinstalling routes (ms) */
63 #define ROUTE_DELAY 100
65 typedef struct addr_entry_t addr_entry_t
;
68 * IP address in an inface_entry_t
75 /** virtual IP managed by us */
78 /** scope of the address */
81 /** Number of times this IP is used, if virtual */
86 * destroy a addr_entry_t object
88 static void addr_entry_destroy(addr_entry_t
*this)
90 this->ip
->destroy(this->ip
);
94 typedef struct iface_entry_t iface_entry_t
;
97 * A network interface on this system, containing addr_entry_t's
99 struct iface_entry_t
{
101 /** interface index */
104 /** name of the interface */
105 char ifname
[IFNAMSIZ
];
107 /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
110 /** list of addresses as host_t */
111 linked_list_t
*addrs
;
115 * destroy an interface entry
117 static void iface_entry_destroy(iface_entry_t
*this)
119 this->addrs
->destroy_function(this->addrs
, (void*)addr_entry_destroy
);
123 typedef struct route_entry_t route_entry_t
;
126 * Installed routing entry
128 struct route_entry_t
{
129 /** Name of the interface the route is bound to */
132 /** Source ip of the route */
135 /** Gateway for this route */
138 /** Destination net */
141 /** Destination net prefixlen */
146 * Clone a route_entry_t object.
148 static route_entry_t
*route_entry_clone(route_entry_t
*this)
150 route_entry_t
*route
;
153 .if_name
= strdup(this->if_name
),
154 .src_ip
= this->src_ip
->clone(this->src_ip
),
155 .gateway
= this->gateway
->clone(this->gateway
),
156 .dst_net
= chunk_clone(this->dst_net
),
157 .prefixlen
= this->prefixlen
,
163 * Destroy a route_entry_t object
165 static void route_entry_destroy(route_entry_t
*this)
168 DESTROY_IF(this->src_ip
);
169 DESTROY_IF(this->gateway
);
170 chunk_free(&this->dst_net
);
175 * Hash a route_entry_t object
177 static u_int
route_entry_hash(route_entry_t
*this)
179 return chunk_hash_inc(chunk_from_thing(this->prefixlen
),
180 chunk_hash(this->dst_net
));
184 * Compare two route_entry_t objects
186 static bool route_entry_equals(route_entry_t
*a
, route_entry_t
*b
)
188 return a
->if_name
&& b
->if_name
&& streq(a
->if_name
, b
->if_name
) &&
189 a
->src_ip
->ip_equals(a
->src_ip
, b
->src_ip
) &&
190 a
->gateway
->ip_equals(a
->gateway
, b
->gateway
) &&
191 chunk_equals(a
->dst_net
, b
->dst_net
) && a
->prefixlen
== b
->prefixlen
;
194 typedef struct net_change_t net_change_t
;
197 * Queued network changes
199 struct net_change_t
{
200 /** Name of the interface that got activated (or an IP appeared on) */
205 * Destroy a net_change_t object
207 static void net_change_destroy(net_change_t
*this)
214 * Hash a net_change_t object
216 static u_int
net_change_hash(net_change_t
*this)
218 return chunk_hash(chunk_create(this->if_name
, strlen(this->if_name
)));
222 * Compare two net_change_t objects
224 static bool net_change_equals(net_change_t
*a
, net_change_t
*b
)
226 return streq(a
->if_name
, b
->if_name
);
229 typedef struct private_kernel_netlink_net_t private_kernel_netlink_net_t
;
232 * Private variables and functions of kernel_netlink_net class.
234 struct private_kernel_netlink_net_t
{
236 * Public part of the kernel_netlink_net_t object.
238 kernel_netlink_net_t
public;
241 * mutex to lock access to various lists
246 * condition variable to signal virtual IP add/removal
251 * Cached list of interfaces and its addresses (iface_entry_t)
253 linked_list_t
*ifaces
;
256 * job receiving netlink events
261 * netlink rt socket (routing)
263 netlink_socket_t
*socket
;
266 * Netlink rt socket to receive address change events
271 * time of the last roam event
276 * routing table to install routes
281 * priority of used routing table
283 int routing_table_prio
;
291 * interface changes which may trigger route reinstallation
293 hashtable_t
*net_changes
;
296 * mutex for route reinstallation triggers
298 mutex_t
*net_changes_lock
;
301 * time of last route reinstallation
303 timeval_t last_route_reinstall
;
306 * whether to react to RTM_NEWROUTE or RTM_DELROUTE events
311 * whether to actually install virtual IPs
313 bool install_virtual_ip
;
316 * list with routing tables to be excluded from route lookup
318 linked_list_t
*rt_exclude
;
322 * Forward declaration
324 static status_t
manage_srcroute(private_kernel_netlink_net_t
*this,
325 int nlmsg_type
, int flags
, chunk_t dst_net
,
326 u_int8_t prefixlen
, host_t
*gateway
,
327 host_t
*src_ip
, char *if_name
);
330 * Clear the queued network changes.
332 static void net_changes_clear(private_kernel_netlink_net_t
*this)
334 enumerator_t
*enumerator
;
335 net_change_t
*change
;
337 enumerator
= this->net_changes
->create_enumerator(this->net_changes
);
338 while (enumerator
->enumerate(enumerator
, NULL
, (void**)&change
))
340 this->net_changes
->remove_at(this->net_changes
, enumerator
);
341 net_change_destroy(change
);
343 enumerator
->destroy(enumerator
);
347 * Act upon queued network changes.
349 static job_requeue_t
reinstall_routes(private_kernel_netlink_net_t
*this)
351 enumerator_t
*enumerator
;
352 route_entry_t
*route
;
354 this->net_changes_lock
->lock(this->net_changes_lock
);
355 this->mutex
->lock(this->mutex
);
357 enumerator
= this->routes
->create_enumerator(this->routes
);
358 while (enumerator
->enumerate(enumerator
, NULL
, (void**)&route
))
360 net_change_t
*change
, lookup
= {
361 .if_name
= route
->if_name
,
363 /* check if a change for the outgoing interface is queued */
364 change
= this->net_changes
->get(this->net_changes
, &lookup
);
366 { /* in case src_ip is not on the outgoing interface */
367 lookup
.if_name
= this->public.interface
.get_interface(
368 &this->public.interface
, route
->src_ip
);
369 if (lookup
.if_name
&& !streq(lookup
.if_name
, route
->if_name
))
371 change
= this->net_changes
->get(this->net_changes
, &lookup
);
373 free(lookup
.if_name
);
377 manage_srcroute(this, RTM_NEWROUTE
, NLM_F_CREATE
| NLM_F_EXCL
,
378 route
->dst_net
, route
->prefixlen
, route
->gateway
,
379 route
->src_ip
, route
->if_name
);
382 enumerator
->destroy(enumerator
);
383 this->mutex
->unlock(this->mutex
);
385 net_changes_clear(this);
386 this->net_changes_lock
->unlock(this->net_changes_lock
);
387 return JOB_REQUEUE_NONE
;
391 * Queue route reinstallation caused by network changes for a given interface.
393 * The route reinstallation is delayed for a while and only done once for
394 * several calls during this delay, in order to avoid doing it too often.
395 * The interface name is freed.
397 static void queue_route_reinstall(private_kernel_netlink_net_t
*this,
400 net_change_t
*update
, *found
;
408 this->net_changes_lock
->lock(this->net_changes_lock
);
409 found
= this->net_changes
->put(this->net_changes
, update
, update
);
412 net_change_destroy(found
);
414 time_monotonic(&now
);
415 if (timercmp(&now
, &this->last_route_reinstall
, >))
417 now
.tv_usec
+= ROUTE_DELAY
* 1000;
418 while (now
.tv_usec
> 1000000)
421 now
.tv_usec
-= 1000000;
423 this->last_route_reinstall
= now
;
425 job
= (job_t
*)callback_job_create((callback_job_cb_t
)reinstall_routes
,
427 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, job
, ROUTE_DELAY
);
429 this->net_changes_lock
->unlock(this->net_changes_lock
);
433 * get the refcount of a virtual ip
435 static int get_vip_refcount(private_kernel_netlink_net_t
*this, host_t
* ip
)
437 enumerator_t
*ifaces
, *addrs
;
438 iface_entry_t
*iface
;
442 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
443 while (ifaces
->enumerate(ifaces
, (void**)&iface
))
445 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
446 while (addrs
->enumerate(addrs
, (void**)&addr
))
448 if (addr
->virtual && (iface
->flags
& IFF_UP
) &&
449 ip
->ip_equals(ip
, addr
->ip
))
451 refcount
= addr
->refcount
;
455 addrs
->destroy(addrs
);
461 ifaces
->destroy(ifaces
);
467 * get the first non-virtual ip address on the given interface.
468 * returned host is a clone, has to be freed by caller.
470 static host_t
*get_interface_address(private_kernel_netlink_net_t
*this,
471 int ifindex
, int family
)
473 enumerator_t
*ifaces
, *addrs
;
474 iface_entry_t
*iface
;
478 this->mutex
->lock(this->mutex
);
479 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
480 while (ifaces
->enumerate(ifaces
, &iface
))
482 if (iface
->ifindex
== ifindex
)
484 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
485 while (addrs
->enumerate(addrs
, &addr
))
487 if (!addr
->virtual && addr
->ip
->get_family(addr
->ip
) == family
)
489 ip
= addr
->ip
->clone(addr
->ip
);
493 addrs
->destroy(addrs
);
497 ifaces
->destroy(ifaces
);
498 this->mutex
->unlock(this->mutex
);
503 * callback function that raises the delayed roam event
505 static job_requeue_t
roam_event(uintptr_t address
)
507 hydra
->kernel_interface
->roam(hydra
->kernel_interface
, address
!= 0);
508 return JOB_REQUEUE_NONE
;
512 * fire a roaming event. we delay it for a bit and fire only one event
513 * for multiple calls. otherwise we would create too many events.
515 static void fire_roam_event(private_kernel_netlink_net_t
*this, bool address
)
520 time_monotonic(&now
);
521 if (timercmp(&now
, &this->last_roam
, >))
523 now
.tv_usec
+= ROAM_DELAY
* 1000;
524 while (now
.tv_usec
> 1000000)
527 now
.tv_usec
-= 1000000;
529 this->last_roam
= now
;
531 job
= (job_t
*)callback_job_create((callback_job_cb_t
)roam_event
,
532 (void*)(uintptr_t)(address ?
1 : 0),
534 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, job
, ROAM_DELAY
);
539 * process RTM_NEWLINK/RTM_DELLINK from kernel
541 static void process_link(private_kernel_netlink_net_t
*this,
542 struct nlmsghdr
*hdr
, bool event
)
544 struct ifinfomsg
* msg
= (struct ifinfomsg
*)(NLMSG_DATA(hdr
));
545 struct rtattr
*rta
= IFLA_RTA(msg
);
546 size_t rtasize
= IFLA_PAYLOAD (hdr
);
547 enumerator_t
*enumerator
;
548 iface_entry_t
*current
, *entry
= NULL
;
550 bool update
= FALSE
, update_routes
= FALSE
;
552 while (RTA_OK(rta
, rtasize
))
554 switch (rta
->rta_type
)
557 name
= RTA_DATA(rta
);
560 rta
= RTA_NEXT(rta
, rtasize
);
567 this->mutex
->lock(this->mutex
);
568 switch (hdr
->nlmsg_type
)
572 if (msg
->ifi_flags
& IFF_LOOPBACK
)
573 { /* ignore loopback interfaces */
576 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
577 while (enumerator
->enumerate(enumerator
, ¤t
))
579 if (current
->ifindex
== msg
->ifi_index
)
585 enumerator
->destroy(enumerator
);
588 entry
= malloc_thing(iface_entry_t
);
589 entry
->ifindex
= msg
->ifi_index
;
591 entry
->addrs
= linked_list_create();
592 this->ifaces
->insert_last(this->ifaces
, entry
);
594 strncpy(entry
->ifname
, name
, IFNAMSIZ
);
595 entry
->ifname
[IFNAMSIZ
-1] = '\0';
598 if (!(entry
->flags
& IFF_UP
) && (msg
->ifi_flags
& IFF_UP
))
600 update
= update_routes
= TRUE
;
601 DBG1(DBG_KNL
, "interface %s activated", name
);
603 if ((entry
->flags
& IFF_UP
) && !(msg
->ifi_flags
& IFF_UP
))
606 DBG1(DBG_KNL
, "interface %s deactivated", name
);
609 entry
->flags
= msg
->ifi_flags
;
614 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
615 while (enumerator
->enumerate(enumerator
, ¤t
))
617 if (current
->ifindex
== msg
->ifi_index
)
622 DBG1(DBG_KNL
, "interface %s deleted", current
->ifname
);
624 this->ifaces
->remove_at(this->ifaces
, enumerator
);
625 iface_entry_destroy(current
);
629 enumerator
->destroy(enumerator
);
633 this->mutex
->unlock(this->mutex
);
635 if (update_routes
&& event
)
637 queue_route_reinstall(this, strdup(name
));
640 /* send an update to all IKE_SAs */
643 fire_roam_event(this, TRUE
);
648 * process RTM_NEWADDR/RTM_DELADDR from kernel
650 static void process_addr(private_kernel_netlink_net_t
*this,
651 struct nlmsghdr
*hdr
, bool event
)
653 struct ifaddrmsg
* msg
= (struct ifaddrmsg
*)(NLMSG_DATA(hdr
));
654 struct rtattr
*rta
= IFA_RTA(msg
);
655 size_t rtasize
= IFA_PAYLOAD (hdr
);
657 enumerator_t
*ifaces
, *addrs
;
658 iface_entry_t
*iface
;
660 chunk_t local
= chunk_empty
, address
= chunk_empty
;
661 char *route_ifname
= NULL
;
662 bool update
= FALSE
, found
= FALSE
, changed
= FALSE
;
664 while (RTA_OK(rta
, rtasize
))
666 switch (rta
->rta_type
)
669 local
.ptr
= RTA_DATA(rta
);
670 local
.len
= RTA_PAYLOAD(rta
);
673 address
.ptr
= RTA_DATA(rta
);
674 address
.len
= RTA_PAYLOAD(rta
);
677 rta
= RTA_NEXT(rta
, rtasize
);
680 /* For PPP interfaces, we need the IFA_LOCAL address,
681 * IFA_ADDRESS is the peers address. But IFA_LOCAL is
682 * not included in all cases (IPv6?), so fallback to IFA_ADDRESS. */
685 host
= host_create_from_chunk(msg
->ifa_family
, local
, 0);
687 else if (address
.ptr
)
689 host
= host_create_from_chunk(msg
->ifa_family
, address
, 0);
697 this->mutex
->lock(this->mutex
);
698 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
699 while (ifaces
->enumerate(ifaces
, &iface
))
701 if (iface
->ifindex
== msg
->ifa_index
)
703 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
704 while (addrs
->enumerate(addrs
, &addr
))
706 if (host
->ip_equals(host
, addr
->ip
))
709 if (hdr
->nlmsg_type
== RTM_DELADDR
)
711 iface
->addrs
->remove_at(iface
->addrs
, addrs
);
715 DBG1(DBG_KNL
, "%H disappeared from %s",
716 host
, iface
->ifname
);
718 addr_entry_destroy(addr
);
720 else if (hdr
->nlmsg_type
== RTM_NEWADDR
&& addr
->virtual)
726 addrs
->destroy(addrs
);
728 if (hdr
->nlmsg_type
== RTM_NEWADDR
)
734 route_ifname
= strdup(iface
->ifname
);
735 addr
= malloc_thing(addr_entry_t
);
736 addr
->ip
= host
->clone(host
);
737 addr
->virtual = FALSE
;
739 addr
->scope
= msg
->ifa_scope
;
741 iface
->addrs
->insert_last(iface
->addrs
, addr
);
744 DBG1(DBG_KNL
, "%H appeared on %s", host
, iface
->ifname
);
748 if (found
&& (iface
->flags
& IFF_UP
))
755 ifaces
->destroy(ifaces
);
756 this->mutex
->unlock(this->mutex
);
758 if (update
&& event
&& route_ifname
)
760 queue_route_reinstall(this, route_ifname
);
768 /* send an update to all IKE_SAs */
769 if (update
&& event
&& changed
)
771 fire_roam_event(this, TRUE
);
776 * process RTM_NEWROUTE and RTM_DELROUTE from kernel
778 static void process_route(private_kernel_netlink_net_t
*this, struct nlmsghdr
*hdr
)
780 struct rtmsg
* msg
= (struct rtmsg
*)(NLMSG_DATA(hdr
));
781 struct rtattr
*rta
= RTM_RTA(msg
);
782 size_t rtasize
= RTM_PAYLOAD(hdr
);
783 u_int32_t rta_oif
= 0;
786 /* ignore routes added by us or in the local routing table (local addrs) */
787 if (msg
->rtm_table
&& (msg
->rtm_table
== this->routing_table
||
788 msg
->rtm_table
== RT_TABLE_LOCAL
))
793 while (RTA_OK(rta
, rtasize
))
795 switch (rta
->rta_type
)
799 host
= host_create_from_chunk(msg
->rtm_family
,
800 chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
)), 0);
803 if (RTA_PAYLOAD(rta
) == sizeof(rta_oif
))
805 rta_oif
= *(u_int32_t
*)RTA_DATA(rta
);
809 rta
= RTA_NEXT(rta
, rtasize
);
811 if (!host
&& rta_oif
)
813 host
= get_interface_address(this, rta_oif
, msg
->rtm_family
);
817 this->mutex
->lock(this->mutex
);
818 if (!get_vip_refcount(this, host
))
819 { /* ignore routes added for virtual IPs */
820 fire_roam_event(this, FALSE
);
822 this->mutex
->unlock(this->mutex
);
828 * Receives events from kernel
830 static job_requeue_t
receive_events(private_kernel_netlink_net_t
*this)
833 struct nlmsghdr
*hdr
= (struct nlmsghdr
*)response
;
834 struct sockaddr_nl addr
;
835 socklen_t addr_len
= sizeof(addr
);
839 oldstate
= thread_cancelability(TRUE
);
840 len
= recvfrom(this->socket_events
, response
, sizeof(response
), 0,
841 (struct sockaddr
*)&addr
, &addr_len
);
842 thread_cancelability(oldstate
);
849 /* interrupted, try again */
850 return JOB_REQUEUE_DIRECT
;
852 /* no data ready, select again */
853 return JOB_REQUEUE_DIRECT
;
855 DBG1(DBG_KNL
, "unable to receive from rt event socket");
857 return JOB_REQUEUE_FAIR
;
861 if (addr
.nl_pid
!= 0)
862 { /* not from kernel. not interested, try another one */
863 return JOB_REQUEUE_DIRECT
;
866 while (NLMSG_OK(hdr
, len
))
868 /* looks good so far, dispatch netlink message */
869 switch (hdr
->nlmsg_type
)
873 process_addr(this, hdr
, TRUE
);
874 this->condvar
->broadcast(this->condvar
);
878 process_link(this, hdr
, TRUE
);
879 this->condvar
->broadcast(this->condvar
);
883 if (this->process_route
)
885 process_route(this, hdr
);
891 hdr
= NLMSG_NEXT(hdr
, len
);
893 return JOB_REQUEUE_DIRECT
;
896 /** enumerator over addresses */
898 private_kernel_netlink_net_t
* this;
899 /** whether to enumerate down interfaces */
900 bool include_down_ifaces
;
901 /** whether to enumerate virtual ip addresses */
902 bool include_virtual_ips
;
903 } address_enumerator_t
;
906 * cleanup function for address enumerator
908 static void address_enumerator_destroy(address_enumerator_t
*data
)
910 data
->this->mutex
->unlock(data
->this->mutex
);
915 * filter for addresses
917 static bool filter_addresses(address_enumerator_t
*data
,
918 addr_entry_t
** in
, host_t
** out
)
920 if (!data
->include_virtual_ips
&& (*in
)->virtual)
921 { /* skip virtual interfaces added by us */
924 if ((*in
)->scope
>= RT_SCOPE_LINK
)
925 { /* skip addresses with a unusable scope */
933 * enumerator constructor for interfaces
935 static enumerator_t
*create_iface_enumerator(iface_entry_t
*iface
,
936 address_enumerator_t
*data
)
938 return enumerator_create_filter(
939 iface
->addrs
->create_enumerator(iface
->addrs
),
940 (void*)filter_addresses
, data
, NULL
);
944 * filter for interfaces
946 static bool filter_interfaces(address_enumerator_t
*data
, iface_entry_t
** in
,
949 if (!data
->include_down_ifaces
&& !((*in
)->flags
& IFF_UP
))
950 { /* skip interfaces not up */
957 METHOD(kernel_net_t
, create_address_enumerator
, enumerator_t
*,
958 private_kernel_netlink_net_t
*this,
959 bool include_down_ifaces
, bool include_virtual_ips
)
961 address_enumerator_t
*data
= malloc_thing(address_enumerator_t
);
963 data
->include_down_ifaces
= include_down_ifaces
;
964 data
->include_virtual_ips
= include_virtual_ips
;
966 this->mutex
->lock(this->mutex
);
967 return enumerator_create_nested(
968 enumerator_create_filter(
969 this->ifaces
->create_enumerator(this->ifaces
),
970 (void*)filter_interfaces
, data
, NULL
),
971 (void*)create_iface_enumerator
, data
,
972 (void*)address_enumerator_destroy
);
975 METHOD(kernel_net_t
, get_interface_name
, char*,
976 private_kernel_netlink_net_t
*this, host_t
* ip
)
978 enumerator_t
*ifaces
, *addrs
;
979 iface_entry_t
*iface
;
983 DBG2(DBG_KNL
, "getting interface name for %H", ip
);
985 this->mutex
->lock(this->mutex
);
986 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
987 while (ifaces
->enumerate(ifaces
, &iface
))
989 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
990 while (addrs
->enumerate(addrs
, &addr
))
992 if (ip
->ip_equals(ip
, addr
->ip
))
994 name
= strdup(iface
->ifname
);
998 addrs
->destroy(addrs
);
1004 ifaces
->destroy(ifaces
);
1005 this->mutex
->unlock(this->mutex
);
1009 DBG2(DBG_KNL
, "%H is on interface %s", ip
, name
);
1013 DBG2(DBG_KNL
, "%H is not a local address", ip
);
1019 * get the index of an interface by name
1021 static int get_interface_index(private_kernel_netlink_net_t
*this, char* name
)
1023 enumerator_t
*ifaces
;
1024 iface_entry_t
*iface
;
1027 DBG2(DBG_KNL
, "getting iface index for %s", name
);
1029 this->mutex
->lock(this->mutex
);
1030 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1031 while (ifaces
->enumerate(ifaces
, &iface
))
1033 if (streq(name
, iface
->ifname
))
1035 ifindex
= iface
->ifindex
;
1039 ifaces
->destroy(ifaces
);
1040 this->mutex
->unlock(this->mutex
);
1044 DBG1(DBG_KNL
, "unable to get interface index for %s", name
);
1050 * Check if an interface with a given index is up
1052 static bool is_interface_up(private_kernel_netlink_net_t
*this, int index
)
1054 enumerator_t
*ifaces
;
1055 iface_entry_t
*iface
;
1056 /* default to TRUE for interface we do not monitor (e.g. lo) */
1059 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1060 while (ifaces
->enumerate(ifaces
, &iface
))
1062 if (iface
->ifindex
== index
)
1064 up
= iface
->flags
& IFF_UP
;
1068 ifaces
->destroy(ifaces
);
1073 * check if an address (chunk) addr is in subnet (net with net_len net bits)
1075 static bool addr_in_subnet(chunk_t addr
, chunk_t net
, int net_len
)
1077 static const u_char mask
[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
1081 { /* any address matches a /0 network */
1084 if (addr
.len
!= net
.len
|| net_len
> 8 * net
.len
)
1088 /* scan through all bytes in network order */
1093 return (mask
[net_len
] & addr
.ptr
[byte
]) == (mask
[net_len
] & net
.ptr
[byte
]);
1097 if (addr
.ptr
[byte
] != net
.ptr
[byte
])
1109 * Get a route: If "nexthop", the nexthop is returned. source addr otherwise.
1111 static host_t
*get_route(private_kernel_netlink_net_t
*this, host_t
*dest
,
1112 bool nexthop
, host_t
*candidate
)
1114 netlink_buf_t request
;
1115 struct nlmsghdr
*hdr
, *out
, *current
;
1120 enumerator_t
*enumerator
;
1121 host_t
*src
= NULL
, *gtw
= NULL
;
1123 DBG2(DBG_KNL
, "getting address to reach %H", dest
);
1125 memset(&request
, 0, sizeof(request
));
1127 hdr
= (struct nlmsghdr
*)request
;
1128 hdr
->nlmsg_flags
= NLM_F_REQUEST
;
1129 if (dest
->get_family(dest
) == AF_INET
)
1131 /* We dump all addresses for IPv4, as we want to ignore IPsec specific
1132 * routes installed by us. But the kernel does not return source
1133 * addresses in a IPv6 dump, so fall back to get() for v6 routes. */
1134 hdr
->nlmsg_flags
|= NLM_F_ROOT
| NLM_F_DUMP
;
1136 hdr
->nlmsg_type
= RTM_GETROUTE
;
1137 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1139 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1140 msg
->rtm_family
= dest
->get_family(dest
);
1143 chunk
= candidate
->get_address(candidate
);
1144 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
1146 chunk
= dest
->get_address(dest
);
1147 netlink_add_attribute(hdr
, RTA_DST
, chunk
, sizeof(request
));
1149 if (this->socket
->send(this->socket
, hdr
, &out
, &len
) != SUCCESS
)
1151 DBG1(DBG_KNL
, "getting address to %H failed", dest
);
1154 this->mutex
->lock(this->mutex
);
1156 for (current
= out
; NLMSG_OK(current
, len
);
1157 current
= NLMSG_NEXT(current
, len
))
1159 switch (current
->nlmsg_type
)
1167 chunk_t rta_gtw
, rta_src
, rta_dst
;
1168 u_int32_t rta_oif
= 0, rta_table
;
1169 host_t
*new_src
, *new_gtw
;
1173 rta_gtw
= rta_src
= rta_dst
= chunk_empty
;
1174 msg
= (struct rtmsg
*)(NLMSG_DATA(current
));
1176 rtasize
= RTM_PAYLOAD(current
);
1177 rta_table
= msg
->rtm_table
;
1178 while (RTA_OK(rta
, rtasize
))
1180 switch (rta
->rta_type
)
1183 rta_src
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
1186 rta_gtw
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
1189 rta_dst
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
1192 if (RTA_PAYLOAD(rta
) == sizeof(rta_oif
))
1194 rta_oif
= *(u_int32_t
*)RTA_DATA(rta
);
1197 #ifdef HAVE_RTA_TABLE
1199 if (RTA_PAYLOAD(rta
) == sizeof(rta_table
))
1201 rta_table
= *(u_int32_t
*)RTA_DATA(rta
);
1204 #endif /* HAVE_RTA_TABLE*/
1206 rta
= RTA_NEXT(rta
, rtasize
);
1208 if (msg
->rtm_dst_len
<= best
)
1209 { /* not better than a previous one */
1212 enumerator
= this->rt_exclude
->create_enumerator(this->rt_exclude
);
1213 while (enumerator
->enumerate(enumerator
, &table
))
1215 if (table
== rta_table
)
1221 enumerator
->destroy(enumerator
);
1226 if (this->routing_table
!= 0 &&
1227 rta_table
== this->routing_table
)
1228 { /* route is from our own ipsec routing table */
1231 if (rta_oif
&& !is_interface_up(this, rta_oif
))
1232 { /* interface is down */
1235 if (!addr_in_subnet(chunk
, rta_dst
, msg
->rtm_dst_len
))
1236 { /* route destination does not contain dest */
1242 /* nexthop lookup, return gateway if any */
1244 gtw
= host_create_from_chunk(msg
->rtm_family
, rta_gtw
, 0);
1245 best
= msg
->rtm_dst_len
;
1249 { /* got a source address */
1250 new_src
= host_create_from_chunk(msg
->rtm_family
, rta_src
, 0);
1253 if (get_vip_refcount(this, new_src
))
1254 { /* skip source address if it is installed by us */
1255 new_src
->destroy(new_src
);
1261 best
= msg
->rtm_dst_len
;
1267 { /* no src or gtw, but an interface. Get address from it. */
1268 new_src
= get_interface_address(this, rta_oif
,
1274 best
= msg
->rtm_dst_len
;
1279 { /* no source, but a gateway. Lookup source to reach gtw. */
1280 new_gtw
= host_create_from_chunk(msg
->rtm_family
, rta_gtw
, 0);
1281 new_src
= get_route(this, new_gtw
, FALSE
, candidate
);
1282 new_gtw
->destroy(new_gtw
);
1287 best
= msg
->rtm_dst_len
;
1299 this->mutex
->unlock(this->mutex
);
1307 return dest
->clone(dest
);
1312 METHOD(kernel_net_t
, get_source_addr
, host_t
*,
1313 private_kernel_netlink_net_t
*this, host_t
*dest
, host_t
*src
)
1315 return get_route(this, dest
, FALSE
, src
);
1318 METHOD(kernel_net_t
, get_nexthop
, host_t
*,
1319 private_kernel_netlink_net_t
*this, host_t
*dest
)
1321 return get_route(this, dest
, TRUE
, NULL
);
1325 * Manages the creation and deletion of ip addresses on an interface.
1326 * By setting the appropriate nlmsg_type, the ip will be set or unset.
1328 static status_t
manage_ipaddr(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1329 int flags
, int if_index
, host_t
*ip
)
1331 netlink_buf_t request
;
1332 struct nlmsghdr
*hdr
;
1333 struct ifaddrmsg
*msg
;
1336 memset(&request
, 0, sizeof(request
));
1338 chunk
= ip
->get_address(ip
);
1340 hdr
= (struct nlmsghdr
*)request
;
1341 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1342 hdr
->nlmsg_type
= nlmsg_type
;
1343 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1345 msg
= (struct ifaddrmsg
*)NLMSG_DATA(hdr
);
1346 msg
->ifa_family
= ip
->get_family(ip
);
1348 msg
->ifa_prefixlen
= 8 * chunk
.len
;
1349 msg
->ifa_scope
= RT_SCOPE_UNIVERSE
;
1350 msg
->ifa_index
= if_index
;
1352 netlink_add_attribute(hdr
, IFA_LOCAL
, chunk
, sizeof(request
));
1354 return this->socket
->send_ack(this->socket
, hdr
);
1357 METHOD(kernel_net_t
, add_ip
, status_t
,
1358 private_kernel_netlink_net_t
*this, host_t
*virtual_ip
, host_t
*iface_ip
)
1360 iface_entry_t
*iface
;
1362 enumerator_t
*addrs
, *ifaces
;
1365 if (!this->install_virtual_ip
)
1366 { /* disabled by config */
1370 DBG2(DBG_KNL
, "adding virtual IP %H", virtual_ip
);
1372 this->mutex
->lock(this->mutex
);
1373 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1374 while (ifaces
->enumerate(ifaces
, &iface
))
1376 bool iface_found
= FALSE
;
1378 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1379 while (addrs
->enumerate(addrs
, &addr
))
1381 if (iface_ip
->ip_equals(iface_ip
, addr
->ip
))
1385 else if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1388 DBG2(DBG_KNL
, "virtual IP %H already installed on %s",
1389 virtual_ip
, iface
->ifname
);
1390 addrs
->destroy(addrs
);
1391 ifaces
->destroy(ifaces
);
1392 this->mutex
->unlock(this->mutex
);
1396 addrs
->destroy(addrs
);
1400 ifindex
= iface
->ifindex
;
1401 addr
= malloc_thing(addr_entry_t
);
1402 addr
->ip
= virtual_ip
->clone(virtual_ip
);
1404 addr
->virtual = TRUE
;
1405 addr
->scope
= RT_SCOPE_UNIVERSE
;
1406 iface
->addrs
->insert_last(iface
->addrs
, addr
);
1408 if (manage_ipaddr(this, RTM_NEWADDR
, NLM_F_CREATE
| NLM_F_EXCL
,
1409 ifindex
, virtual_ip
) == SUCCESS
)
1411 while (get_vip_refcount(this, virtual_ip
) == 0)
1412 { /* wait until address appears */
1413 this->condvar
->wait(this->condvar
, this->mutex
);
1415 ifaces
->destroy(ifaces
);
1416 this->mutex
->unlock(this->mutex
);
1419 ifaces
->destroy(ifaces
);
1420 this->mutex
->unlock(this->mutex
);
1421 DBG1(DBG_KNL
, "adding virtual IP %H failed", virtual_ip
);
1425 ifaces
->destroy(ifaces
);
1426 this->mutex
->unlock(this->mutex
);
1428 DBG1(DBG_KNL
, "interface address %H not found, unable to install"
1429 "virtual IP %H", iface_ip
, virtual_ip
);
1433 METHOD(kernel_net_t
, del_ip
, status_t
,
1434 private_kernel_netlink_net_t
*this, host_t
*virtual_ip
)
1436 iface_entry_t
*iface
;
1438 enumerator_t
*addrs
, *ifaces
;
1442 if (!this->install_virtual_ip
)
1443 { /* disabled by config */
1447 DBG2(DBG_KNL
, "deleting virtual IP %H", virtual_ip
);
1449 this->mutex
->lock(this->mutex
);
1450 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1451 while (ifaces
->enumerate(ifaces
, &iface
))
1453 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1454 while (addrs
->enumerate(addrs
, &addr
))
1456 if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1458 ifindex
= iface
->ifindex
;
1459 if (addr
->refcount
== 1)
1461 status
= manage_ipaddr(this, RTM_DELADDR
, 0,
1462 ifindex
, virtual_ip
);
1463 if (status
== SUCCESS
)
1464 { /* wait until the address is really gone */
1465 while (get_vip_refcount(this, virtual_ip
) > 0)
1467 this->condvar
->wait(this->condvar
, this->mutex
);
1470 addrs
->destroy(addrs
);
1471 ifaces
->destroy(ifaces
);
1472 this->mutex
->unlock(this->mutex
);
1479 DBG2(DBG_KNL
, "virtual IP %H used by other SAs, not deleting",
1481 addrs
->destroy(addrs
);
1482 ifaces
->destroy(ifaces
);
1483 this->mutex
->unlock(this->mutex
);
1487 addrs
->destroy(addrs
);
1489 ifaces
->destroy(ifaces
);
1490 this->mutex
->unlock(this->mutex
);
1492 DBG2(DBG_KNL
, "virtual IP %H not cached, unable to delete", virtual_ip
);
1497 * Manages source routes in the routing table.
1498 * By setting the appropriate nlmsg_type, the route gets added or removed.
1500 static status_t
manage_srcroute(private_kernel_netlink_net_t
*this,
1501 int nlmsg_type
, int flags
, chunk_t dst_net
,
1502 u_int8_t prefixlen
, host_t
*gateway
,
1503 host_t
*src_ip
, char *if_name
)
1505 netlink_buf_t request
;
1506 struct nlmsghdr
*hdr
;
1511 /* if route is 0.0.0.0/0, we can't install it, as it would
1512 * overwrite the default route. Instead, we add two routes:
1513 * 0.0.0.0/1 and 128.0.0.0/1 */
1514 if (this->routing_table
== 0 && prefixlen
== 0)
1517 u_int8_t half_prefixlen
;
1520 half_net
= chunk_alloca(dst_net
.len
);
1521 memset(half_net
.ptr
, 0, half_net
.len
);
1524 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1525 gateway
, src_ip
, if_name
);
1526 half_net
.ptr
[0] |= 0x80;
1527 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1528 gateway
, src_ip
, if_name
);
1532 memset(&request
, 0, sizeof(request
));
1534 hdr
= (struct nlmsghdr
*)request
;
1535 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1536 hdr
->nlmsg_type
= nlmsg_type
;
1537 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1539 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1540 msg
->rtm_family
= src_ip
->get_family(src_ip
);
1541 msg
->rtm_dst_len
= prefixlen
;
1542 msg
->rtm_table
= this->routing_table
;
1543 msg
->rtm_protocol
= RTPROT_STATIC
;
1544 msg
->rtm_type
= RTN_UNICAST
;
1545 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1547 netlink_add_attribute(hdr
, RTA_DST
, dst_net
, sizeof(request
));
1548 chunk
= src_ip
->get_address(src_ip
);
1549 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
1550 if (gateway
&& gateway
->get_family(gateway
) == src_ip
->get_family(src_ip
))
1552 chunk
= gateway
->get_address(gateway
);
1553 netlink_add_attribute(hdr
, RTA_GATEWAY
, chunk
, sizeof(request
));
1555 ifindex
= get_interface_index(this, if_name
);
1556 chunk
.ptr
= (char*)&ifindex
;
1557 chunk
.len
= sizeof(ifindex
);
1558 netlink_add_attribute(hdr
, RTA_OIF
, chunk
, sizeof(request
));
1560 return this->socket
->send_ack(this->socket
, hdr
);
1563 METHOD(kernel_net_t
, add_route
, status_t
,
1564 private_kernel_netlink_net_t
*this, chunk_t dst_net
, u_int8_t prefixlen
,
1565 host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1568 route_entry_t
*found
, route
= {
1570 .prefixlen
= prefixlen
,
1576 this->mutex
->lock(this->mutex
);
1577 found
= this->routes
->get(this->routes
, &route
);
1580 this->mutex
->unlock(this->mutex
);
1581 return ALREADY_DONE
;
1583 found
= route_entry_clone(&route
);
1584 this->routes
->put(this->routes
, found
, found
);
1585 status
= manage_srcroute(this, RTM_NEWROUTE
, NLM_F_CREATE
| NLM_F_EXCL
,
1586 dst_net
, prefixlen
, gateway
, src_ip
, if_name
);
1587 this->mutex
->unlock(this->mutex
);
1591 METHOD(kernel_net_t
, del_route
, status_t
,
1592 private_kernel_netlink_net_t
*this, chunk_t dst_net
, u_int8_t prefixlen
,
1593 host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1596 route_entry_t
*found
, route
= {
1598 .prefixlen
= prefixlen
,
1604 this->mutex
->lock(this->mutex
);
1605 found
= this->routes
->get(this->routes
, &route
);
1608 this->mutex
->unlock(this->mutex
);
1611 this->routes
->remove(this->routes
, found
);
1612 route_entry_destroy(found
);
1613 status
= manage_srcroute(this, RTM_DELROUTE
, 0, dst_net
, prefixlen
,
1614 gateway
, src_ip
, if_name
);
1615 this->mutex
->unlock(this->mutex
);
1620 * Initialize a list of local addresses.
1622 static status_t
init_address_list(private_kernel_netlink_net_t
*this)
1624 netlink_buf_t request
;
1625 struct nlmsghdr
*out
, *current
, *in
;
1626 struct rtgenmsg
*msg
;
1628 enumerator_t
*ifaces
, *addrs
;
1629 iface_entry_t
*iface
;
1632 DBG1(DBG_KNL
, "listening on interfaces:");
1634 memset(&request
, 0, sizeof(request
));
1636 in
= (struct nlmsghdr
*)&request
;
1637 in
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtgenmsg
));
1638 in
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_MATCH
| NLM_F_ROOT
;
1639 msg
= (struct rtgenmsg
*)NLMSG_DATA(in
);
1640 msg
->rtgen_family
= AF_UNSPEC
;
1643 in
->nlmsg_type
= RTM_GETLINK
;
1644 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1649 while (NLMSG_OK(current
, len
))
1651 switch (current
->nlmsg_type
)
1656 process_link(this, current
, FALSE
);
1659 current
= NLMSG_NEXT(current
, len
);
1666 /* get all interface addresses */
1667 in
->nlmsg_type
= RTM_GETADDR
;
1668 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1673 while (NLMSG_OK(current
, len
))
1675 switch (current
->nlmsg_type
)
1680 process_addr(this, current
, FALSE
);
1683 current
= NLMSG_NEXT(current
, len
);
1690 this->mutex
->lock(this->mutex
);
1691 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1692 while (ifaces
->enumerate(ifaces
, &iface
))
1694 if (iface
->flags
& IFF_UP
)
1696 DBG1(DBG_KNL
, " %s", iface
->ifname
);
1697 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1698 while (addrs
->enumerate(addrs
, (void**)&addr
))
1700 DBG1(DBG_KNL
, " %H", addr
->ip
);
1702 addrs
->destroy(addrs
);
1705 ifaces
->destroy(ifaces
);
1706 this->mutex
->unlock(this->mutex
);
1711 * create or delete a rule to use our routing table
1713 static status_t
manage_rule(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1714 int family
, u_int32_t table
, u_int32_t prio
)
1716 netlink_buf_t request
;
1717 struct nlmsghdr
*hdr
;
1721 memset(&request
, 0, sizeof(request
));
1722 hdr
= (struct nlmsghdr
*)request
;
1723 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1724 hdr
->nlmsg_type
= nlmsg_type
;
1725 if (nlmsg_type
== RTM_NEWRULE
)
1727 hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
1729 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1731 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1732 msg
->rtm_table
= table
;
1733 msg
->rtm_family
= family
;
1734 msg
->rtm_protocol
= RTPROT_BOOT
;
1735 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1736 msg
->rtm_type
= RTN_UNICAST
;
1738 chunk
= chunk_from_thing(prio
);
1739 netlink_add_attribute(hdr
, RTA_PRIORITY
, chunk
, sizeof(request
));
1741 return this->socket
->send_ack(this->socket
, hdr
);
1744 METHOD(kernel_net_t
, destroy
, void,
1745 private_kernel_netlink_net_t
*this)
1747 enumerator_t
*enumerator
;
1748 route_entry_t
*route
;
1750 if (this->routing_table
)
1752 manage_rule(this, RTM_DELRULE
, AF_INET
, this->routing_table
,
1753 this->routing_table_prio
);
1754 manage_rule(this, RTM_DELRULE
, AF_INET6
, this->routing_table
,
1755 this->routing_table_prio
);
1759 this->job
->cancel(this->job
);
1761 if (this->socket_events
> 0)
1763 close(this->socket_events
);
1765 enumerator
= this->routes
->create_enumerator(this->routes
);
1766 while (enumerator
->enumerate(enumerator
, NULL
, (void**)&route
))
1768 manage_srcroute(this, RTM_DELROUTE
, 0, route
->dst_net
, route
->prefixlen
,
1769 route
->gateway
, route
->src_ip
, route
->if_name
);
1770 route_entry_destroy(route
);
1772 enumerator
->destroy(enumerator
);
1773 this->routes
->destroy(this->routes
);
1774 DESTROY_IF(this->socket
);
1776 net_changes_clear(this);
1777 this->net_changes
->destroy(this->net_changes
);
1778 this->net_changes_lock
->destroy(this->net_changes_lock
);
1780 this->ifaces
->destroy_function(this->ifaces
, (void*)iface_entry_destroy
);
1781 this->rt_exclude
->destroy(this->rt_exclude
);
1782 this->condvar
->destroy(this->condvar
);
1783 this->mutex
->destroy(this->mutex
);
1788 * Described in header.
1790 kernel_netlink_net_t
*kernel_netlink_net_create()
1792 private_kernel_netlink_net_t
*this;
1793 enumerator_t
*enumerator
;
1794 bool register_for_events
= TRUE
;
1800 .get_interface
= _get_interface_name
,
1801 .create_address_enumerator
= _create_address_enumerator
,
1802 .get_source_addr
= _get_source_addr
,
1803 .get_nexthop
= _get_nexthop
,
1806 .add_route
= _add_route
,
1807 .del_route
= _del_route
,
1808 .destroy
= _destroy
,
1811 .socket
= netlink_socket_create(NETLINK_ROUTE
),
1812 .rt_exclude
= linked_list_create(),
1813 .routes
= hashtable_create((hashtable_hash_t
)route_entry_hash
,
1814 (hashtable_equals_t
)route_entry_equals
, 16),
1815 .net_changes
= hashtable_create(
1816 (hashtable_hash_t
)net_change_hash
,
1817 (hashtable_equals_t
)net_change_equals
, 16),
1818 .net_changes_lock
= mutex_create(MUTEX_TYPE_DEFAULT
),
1819 .ifaces
= linked_list_create(),
1820 .mutex
= mutex_create(MUTEX_TYPE_RECURSIVE
),
1821 .condvar
= condvar_create(CONDVAR_TYPE_DEFAULT
),
1822 .routing_table
= lib
->settings
->get_int(lib
->settings
,
1823 "%s.routing_table", ROUTING_TABLE
, hydra
->daemon
),
1824 .routing_table_prio
= lib
->settings
->get_int(lib
->settings
,
1825 "%s.routing_table_prio", ROUTING_TABLE_PRIO
, hydra
->daemon
),
1826 .process_route
= lib
->settings
->get_bool(lib
->settings
,
1827 "%s.process_route", TRUE
, hydra
->daemon
),
1828 .install_virtual_ip
= lib
->settings
->get_bool(lib
->settings
,
1829 "%s.install_virtual_ip", TRUE
, hydra
->daemon
),
1831 timerclear(&this->last_route_reinstall
);
1832 timerclear(&this->last_roam
);
1834 if (streq(hydra
->daemon
, "starter"))
1835 { /* starter has no threads, so we do not register for kernel events */
1836 register_for_events
= FALSE
;
1839 exclude
= lib
->settings
->get_str(lib
->settings
,
1840 "%s.ignore_routing_tables", NULL
, hydra
->daemon
);
1846 enumerator
= enumerator_create_token(exclude
, " ", " ");
1847 while (enumerator
->enumerate(enumerator
, &token
))
1850 table
= strtoul(token
, NULL
, 10);
1854 this->rt_exclude
->insert_last(this->rt_exclude
, (void*)table
);
1857 enumerator
->destroy(enumerator
);
1860 if (register_for_events
)
1862 struct sockaddr_nl addr
;
1864 memset(&addr
, 0, sizeof(addr
));
1865 addr
.nl_family
= AF_NETLINK
;
1867 /* create and bind RT socket for events (address/interface/route changes) */
1868 this->socket_events
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
1869 if (this->socket_events
< 0)
1871 DBG1(DBG_KNL
, "unable to create RT event socket");
1875 addr
.nl_groups
= RTMGRP_IPV4_IFADDR
| RTMGRP_IPV6_IFADDR
|
1876 RTMGRP_IPV4_ROUTE
| RTMGRP_IPV6_ROUTE
| RTMGRP_LINK
;
1877 if (bind(this->socket_events
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1879 DBG1(DBG_KNL
, "unable to bind RT event socket");
1884 this->job
= callback_job_create_with_prio((callback_job_cb_t
)receive_events
,
1885 this, NULL
, NULL
, JOB_PRIO_CRITICAL
);
1886 lib
->processor
->queue_job(lib
->processor
, (job_t
*)this->job
);
1889 if (init_address_list(this) != SUCCESS
)
1891 DBG1(DBG_KNL
, "unable to get interface list");
1896 if (this->routing_table
)
1898 if (manage_rule(this, RTM_NEWRULE
, AF_INET
, this->routing_table
,
1899 this->routing_table_prio
) != SUCCESS
)
1901 DBG1(DBG_KNL
, "unable to create IPv4 routing table rule");
1903 if (manage_rule(this, RTM_NEWRULE
, AF_INET6
, this->routing_table
,
1904 this->routing_table_prio
) != SUCCESS
)
1906 DBG1(DBG_KNL
, "unable to create IPv6 routing table rule");
1910 return &this->public;