2 * Copyright (C) 2008 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/linked_list.h>
56 #include <processing/jobs/callback_job.h>
58 /** delay before firing roam events (ms) */
59 #define ROAM_DELAY 100
61 typedef struct addr_entry_t addr_entry_t
;
64 * IP address in an inface_entry_t
71 /** virtual IP managed by us */
74 /** scope of the address */
77 /** Number of times this IP is used, if virtual */
82 * destroy a addr_entry_t object
84 static void addr_entry_destroy(addr_entry_t
*this)
86 this->ip
->destroy(this->ip
);
90 typedef struct iface_entry_t iface_entry_t
;
93 * A network interface on this system, containing addr_entry_t's
95 struct iface_entry_t
{
97 /** interface index */
100 /** name of the interface */
101 char ifname
[IFNAMSIZ
];
103 /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
106 /** list of addresses as host_t */
107 linked_list_t
*addrs
;
111 * destroy an interface entry
113 static void iface_entry_destroy(iface_entry_t
*this)
115 this->addrs
->destroy_function(this->addrs
, (void*)addr_entry_destroy
);
119 typedef struct private_kernel_netlink_net_t private_kernel_netlink_net_t
;
122 * Private variables and functions of kernel_netlink_net class.
124 struct private_kernel_netlink_net_t
{
126 * Public part of the kernel_netlink_net_t object.
128 kernel_netlink_net_t
public;
131 * mutex to lock access to various lists
136 * condition variable to signal virtual IP add/removal
141 * Cached list of interfaces and its addresses (iface_entry_t)
143 linked_list_t
*ifaces
;
146 * job receiving netlink events
151 * netlink rt socket (routing)
153 netlink_socket_t
*socket
;
156 * Netlink rt socket to receive address change events
161 * time of the last roam event
166 * routing table to install routes
171 * priority of used routing table
173 int routing_table_prio
;
176 * whether to react to RTM_NEWROUTE or RTM_DELROUTE events
181 * whether to actually install virtual IPs
183 bool install_virtual_ip
;
186 * list with routing tables to be excluded from route lookup
188 linked_list_t
*rt_exclude
;
192 * get the refcount of a virtual ip
194 static int get_vip_refcount(private_kernel_netlink_net_t
*this, host_t
* ip
)
196 iterator_t
*ifaces
, *addrs
;
197 iface_entry_t
*iface
;
201 ifaces
= this->ifaces
->create_iterator(this->ifaces
, TRUE
);
202 while (ifaces
->iterate(ifaces
, (void**)&iface
))
204 addrs
= iface
->addrs
->create_iterator(iface
->addrs
, TRUE
);
205 while (addrs
->iterate(addrs
, (void**)&addr
))
207 if (addr
->virtual && (iface
->flags
& IFF_UP
) &&
208 ip
->ip_equals(ip
, addr
->ip
))
210 refcount
= addr
->refcount
;
214 addrs
->destroy(addrs
);
220 ifaces
->destroy(ifaces
);
226 * callback function that raises the delayed roam event
228 static job_requeue_t
roam_event(uintptr_t address
)
230 hydra
->kernel_interface
->roam(hydra
->kernel_interface
, address
!= 0);
231 return JOB_REQUEUE_NONE
;
235 * fire a roaming event. we delay it for a bit and fire only one event
236 * for multiple calls. otherwise we would create too many events.
238 static void fire_roam_event(private_kernel_netlink_net_t
*this, bool address
)
243 time_monotonic(&now
);
244 if (timercmp(&now
, &this->last_roam
, >))
246 now
.tv_usec
+= ROAM_DELAY
* 1000;
247 while (now
.tv_usec
> 1000000)
250 now
.tv_usec
-= 1000000;
252 this->last_roam
= now
;
254 job
= (job_t
*)callback_job_create((callback_job_cb_t
)roam_event
,
255 (void*)(uintptr_t)(address ?
1 : 0),
257 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, job
, ROAM_DELAY
);
262 * process RTM_NEWLINK/RTM_DELLINK from kernel
264 static void process_link(private_kernel_netlink_net_t
*this,
265 struct nlmsghdr
*hdr
, bool event
)
267 struct ifinfomsg
* msg
= (struct ifinfomsg
*)(NLMSG_DATA(hdr
));
268 struct rtattr
*rta
= IFLA_RTA(msg
);
269 size_t rtasize
= IFLA_PAYLOAD (hdr
);
270 enumerator_t
*enumerator
;
271 iface_entry_t
*current
, *entry
= NULL
;
275 while(RTA_OK(rta
, rtasize
))
277 switch (rta
->rta_type
)
280 name
= RTA_DATA(rta
);
283 rta
= RTA_NEXT(rta
, rtasize
);
290 this->mutex
->lock(this->mutex
);
291 switch (hdr
->nlmsg_type
)
295 if (msg
->ifi_flags
& IFF_LOOPBACK
)
296 { /* ignore loopback interfaces */
299 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
300 while (enumerator
->enumerate(enumerator
, ¤t
))
302 if (current
->ifindex
== msg
->ifi_index
)
308 enumerator
->destroy(enumerator
);
311 entry
= malloc_thing(iface_entry_t
);
312 entry
->ifindex
= msg
->ifi_index
;
314 entry
->addrs
= linked_list_create();
315 this->ifaces
->insert_last(this->ifaces
, entry
);
317 memcpy(entry
->ifname
, name
, IFNAMSIZ
);
318 entry
->ifname
[IFNAMSIZ
-1] = '\0';
321 if (!(entry
->flags
& IFF_UP
) && (msg
->ifi_flags
& IFF_UP
))
324 DBG1(DBG_KNL
, "interface %s activated", name
);
326 if ((entry
->flags
& IFF_UP
) && !(msg
->ifi_flags
& IFF_UP
))
329 DBG1(DBG_KNL
, "interface %s deactivated", name
);
332 entry
->flags
= msg
->ifi_flags
;
337 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
338 while (enumerator
->enumerate(enumerator
, ¤t
))
340 if (current
->ifindex
== msg
->ifi_index
)
342 /* we do not remove it, as an address may be added to a
343 * "down" interface and we wan't to know that. */
344 current
->flags
= msg
->ifi_flags
;
348 enumerator
->destroy(enumerator
);
352 this->mutex
->unlock(this->mutex
);
354 /* send an update to all IKE_SAs */
357 fire_roam_event(this, TRUE
);
362 * process RTM_NEWADDR/RTM_DELADDR from kernel
364 static void process_addr(private_kernel_netlink_net_t
*this,
365 struct nlmsghdr
*hdr
, bool event
)
367 struct ifaddrmsg
* msg
= (struct ifaddrmsg
*)(NLMSG_DATA(hdr
));
368 struct rtattr
*rta
= IFA_RTA(msg
);
369 size_t rtasize
= IFA_PAYLOAD (hdr
);
371 enumerator_t
*ifaces
, *addrs
;
372 iface_entry_t
*iface
;
374 chunk_t local
= chunk_empty
, address
= chunk_empty
;
375 bool update
= FALSE
, found
= FALSE
, changed
= FALSE
;
377 while(RTA_OK(rta
, rtasize
))
379 switch (rta
->rta_type
)
382 local
.ptr
= RTA_DATA(rta
);
383 local
.len
= RTA_PAYLOAD(rta
);
386 address
.ptr
= RTA_DATA(rta
);
387 address
.len
= RTA_PAYLOAD(rta
);
390 rta
= RTA_NEXT(rta
, rtasize
);
393 /* For PPP interfaces, we need the IFA_LOCAL address,
394 * IFA_ADDRESS is the peers address. But IFA_LOCAL is
395 * not included in all cases (IPv6?), so fallback to IFA_ADDRESS. */
398 host
= host_create_from_chunk(msg
->ifa_family
, local
, 0);
400 else if (address
.ptr
)
402 host
= host_create_from_chunk(msg
->ifa_family
, address
, 0);
410 this->mutex
->lock(this->mutex
);
411 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
412 while (ifaces
->enumerate(ifaces
, &iface
))
414 if (iface
->ifindex
== msg
->ifa_index
)
416 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
417 while (addrs
->enumerate(addrs
, &addr
))
419 if (host
->ip_equals(host
, addr
->ip
))
422 if (hdr
->nlmsg_type
== RTM_DELADDR
)
424 iface
->addrs
->remove_at(iface
->addrs
, addrs
);
428 DBG1(DBG_KNL
, "%H disappeared from %s",
429 host
, iface
->ifname
);
431 addr_entry_destroy(addr
);
433 else if (hdr
->nlmsg_type
== RTM_NEWADDR
&& addr
->virtual)
439 addrs
->destroy(addrs
);
441 if (hdr
->nlmsg_type
== RTM_NEWADDR
)
447 addr
= malloc_thing(addr_entry_t
);
448 addr
->ip
= host
->clone(host
);
449 addr
->virtual = FALSE
;
451 addr
->scope
= msg
->ifa_scope
;
453 iface
->addrs
->insert_last(iface
->addrs
, addr
);
456 DBG1(DBG_KNL
, "%H appeared on %s", host
, iface
->ifname
);
460 if (found
&& (iface
->flags
& IFF_UP
))
467 ifaces
->destroy(ifaces
);
468 this->mutex
->unlock(this->mutex
);
471 /* send an update to all IKE_SAs */
472 if (update
&& event
&& changed
)
474 fire_roam_event(this, TRUE
);
479 * process RTM_NEWROUTE and RTM_DELROUTE from kernel
481 static void process_route(private_kernel_netlink_net_t
*this, struct nlmsghdr
*hdr
)
483 struct rtmsg
* msg
= (struct rtmsg
*)(NLMSG_DATA(hdr
));
484 struct rtattr
*rta
= RTM_RTA(msg
);
485 size_t rtasize
= RTM_PAYLOAD(hdr
);
488 /* ignore routes added by us */
489 if (msg
->rtm_table
&& msg
->rtm_table
== this->routing_table
)
494 while (RTA_OK(rta
, rtasize
))
496 switch (rta
->rta_type
)
499 host
= host_create_from_chunk(msg
->rtm_family
,
500 chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
)), 0);
503 rta
= RTA_NEXT(rta
, rtasize
);
507 this->mutex
->lock(this->mutex
);
508 if (!get_vip_refcount(this, host
))
509 { /* ignore routes added for virtual IPs */
510 fire_roam_event(this, FALSE
);
512 this->mutex
->unlock(this->mutex
);
518 * Receives events from kernel
520 static job_requeue_t
receive_events(private_kernel_netlink_net_t
*this)
523 struct nlmsghdr
*hdr
= (struct nlmsghdr
*)response
;
524 struct sockaddr_nl addr
;
525 socklen_t addr_len
= sizeof(addr
);
529 oldstate
= thread_cancelability(TRUE
);
530 len
= recvfrom(this->socket_events
, response
, sizeof(response
), 0,
531 (struct sockaddr
*)&addr
, &addr_len
);
532 thread_cancelability(oldstate
);
539 /* interrupted, try again */
540 return JOB_REQUEUE_DIRECT
;
542 /* no data ready, select again */
543 return JOB_REQUEUE_DIRECT
;
545 DBG1(DBG_KNL
, "unable to receive from rt event socket");
547 return JOB_REQUEUE_FAIR
;
551 if (addr
.nl_pid
!= 0)
552 { /* not from kernel. not interested, try another one */
553 return JOB_REQUEUE_DIRECT
;
556 while (NLMSG_OK(hdr
, len
))
558 /* looks good so far, dispatch netlink message */
559 switch (hdr
->nlmsg_type
)
563 process_addr(this, hdr
, TRUE
);
564 this->condvar
->broadcast(this->condvar
);
568 process_link(this, hdr
, TRUE
);
569 this->condvar
->broadcast(this->condvar
);
573 if (this->process_route
)
575 process_route(this, hdr
);
581 hdr
= NLMSG_NEXT(hdr
, len
);
583 return JOB_REQUEUE_DIRECT
;
586 /** enumerator over addresses */
588 private_kernel_netlink_net_t
* this;
589 /** whether to enumerate down interfaces */
590 bool include_down_ifaces
;
591 /** whether to enumerate virtual ip addresses */
592 bool include_virtual_ips
;
593 } address_enumerator_t
;
596 * cleanup function for address enumerator
598 static void address_enumerator_destroy(address_enumerator_t
*data
)
600 data
->this->mutex
->unlock(data
->this->mutex
);
605 * filter for addresses
607 static bool filter_addresses(address_enumerator_t
*data
, addr_entry_t
** in
, host_t
** out
)
609 if (!data
->include_virtual_ips
&& (*in
)->virtual)
610 { /* skip virtual interfaces added by us */
613 if ((*in
)->scope
>= RT_SCOPE_LINK
)
614 { /* skip addresses with a unusable scope */
622 * enumerator constructor for interfaces
624 static enumerator_t
*create_iface_enumerator(iface_entry_t
*iface
, address_enumerator_t
*data
)
626 return enumerator_create_filter(iface
->addrs
->create_enumerator(iface
->addrs
),
627 (void*)filter_addresses
, data
, NULL
);
631 * filter for interfaces
633 static bool filter_interfaces(address_enumerator_t
*data
, iface_entry_t
** in
, iface_entry_t
** out
)
635 if (!data
->include_down_ifaces
&& !((*in
)->flags
& IFF_UP
))
636 { /* skip interfaces not up */
644 * implementation of kernel_net_t.create_address_enumerator
646 static enumerator_t
*create_address_enumerator(private_kernel_netlink_net_t
*this,
647 bool include_down_ifaces
, bool include_virtual_ips
)
649 address_enumerator_t
*data
= malloc_thing(address_enumerator_t
);
651 data
->include_down_ifaces
= include_down_ifaces
;
652 data
->include_virtual_ips
= include_virtual_ips
;
654 this->mutex
->lock(this->mutex
);
655 return enumerator_create_nested(
656 enumerator_create_filter(this->ifaces
->create_enumerator(this->ifaces
),
657 (void*)filter_interfaces
, data
, NULL
),
658 (void*)create_iface_enumerator
, data
, (void*)address_enumerator_destroy
);
662 * implementation of kernel_net_t.get_interface_name
664 static char *get_interface_name(private_kernel_netlink_net_t
*this, host_t
* ip
)
666 enumerator_t
*ifaces
, *addrs
;
667 iface_entry_t
*iface
;
671 DBG2(DBG_KNL
, "getting interface name for %H", ip
);
673 this->mutex
->lock(this->mutex
);
674 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
675 while (ifaces
->enumerate(ifaces
, &iface
))
677 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
678 while (addrs
->enumerate(addrs
, &addr
))
680 if (ip
->ip_equals(ip
, addr
->ip
))
682 name
= strdup(iface
->ifname
);
686 addrs
->destroy(addrs
);
692 ifaces
->destroy(ifaces
);
693 this->mutex
->unlock(this->mutex
);
697 DBG2(DBG_KNL
, "%H is on interface %s", ip
, name
);
701 DBG2(DBG_KNL
, "%H is not a local address", ip
);
707 * get the index of an interface by name
709 static int get_interface_index(private_kernel_netlink_net_t
*this, char* name
)
711 enumerator_t
*ifaces
;
712 iface_entry_t
*iface
;
715 DBG2(DBG_KNL
, "getting iface index for %s", name
);
717 this->mutex
->lock(this->mutex
);
718 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
719 while (ifaces
->enumerate(ifaces
, &iface
))
721 if (streq(name
, iface
->ifname
))
723 ifindex
= iface
->ifindex
;
727 ifaces
->destroy(ifaces
);
728 this->mutex
->unlock(this->mutex
);
732 DBG1(DBG_KNL
, "unable to get interface index for %s", name
);
738 * Check if an interface with a given index is up
740 static bool is_interface_up(private_kernel_netlink_net_t
*this, int index
)
742 enumerator_t
*ifaces
;
743 iface_entry_t
*iface
;
744 /* default to TRUE for interface we do not monitor (e.g. lo) */
747 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
748 while (ifaces
->enumerate(ifaces
, &iface
))
750 if (iface
->ifindex
== index
)
752 up
= iface
->flags
& IFF_UP
;
756 ifaces
->destroy(ifaces
);
761 * check if an address (chunk) addr is in subnet (net with net_len net bits)
763 static bool addr_in_subnet(chunk_t addr
, chunk_t net
, int net_len
)
765 static const u_char mask
[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
769 { /* any address matches a /0 network */
772 if (addr
.len
!= net
.len
|| net_len
> 8 * net
.len
)
776 /* scan through all bytes in network order */
781 return (mask
[net_len
] & addr
.ptr
[byte
]) == (mask
[net_len
] & net
.ptr
[byte
]);
785 if (addr
.ptr
[byte
] != net
.ptr
[byte
])
797 * Get a route: If "nexthop", the nexthop is returned. source addr otherwise.
799 static host_t
*get_route(private_kernel_netlink_net_t
*this, host_t
*dest
,
800 bool nexthop
, host_t
*candidate
)
802 netlink_buf_t request
;
803 struct nlmsghdr
*hdr
, *out
, *current
;
808 enumerator_t
*enumerator
;
809 host_t
*src
= NULL
, *gtw
= NULL
;
811 DBG2(DBG_KNL
, "getting address to reach %H", dest
);
813 memset(&request
, 0, sizeof(request
));
815 hdr
= (struct nlmsghdr
*)request
;
816 hdr
->nlmsg_flags
= NLM_F_REQUEST
;
817 if (dest
->get_family(dest
) == AF_INET
)
819 /* We dump all addresses for IPv4, as we want to ignore IPsec specific
820 * routes installed by us. But the kernel does not return source
821 * addresses in a IPv6 dump, so fall back to get() for v6 routes. */
822 hdr
->nlmsg_flags
|= NLM_F_ROOT
| NLM_F_DUMP
;
824 hdr
->nlmsg_type
= RTM_GETROUTE
;
825 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
827 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
828 msg
->rtm_family
= dest
->get_family(dest
);
831 chunk
= candidate
->get_address(candidate
);
832 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
834 chunk
= dest
->get_address(dest
);
835 netlink_add_attribute(hdr
, RTA_DST
, chunk
, sizeof(request
));
837 if (this->socket
->send(this->socket
, hdr
, &out
, &len
) != SUCCESS
)
839 DBG1(DBG_KNL
, "getting address to %H failed", dest
);
842 this->mutex
->lock(this->mutex
);
844 for (current
= out
; NLMSG_OK(current
, len
);
845 current
= NLMSG_NEXT(current
, len
))
847 switch (current
->nlmsg_type
)
855 chunk_t rta_gtw
, rta_src
, rta_dst
;
856 u_int32_t rta_oif
= 0;
857 host_t
*new_src
, *new_gtw
;
861 rta_gtw
= rta_src
= rta_dst
= chunk_empty
;
862 msg
= (struct rtmsg
*)(NLMSG_DATA(current
));
864 rtasize
= RTM_PAYLOAD(current
);
865 while (RTA_OK(rta
, rtasize
))
867 switch (rta
->rta_type
)
870 rta_src
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
873 rta_gtw
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
876 rta_dst
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
879 if (RTA_PAYLOAD(rta
) == sizeof(rta_oif
))
881 rta_oif
= *(u_int32_t
*)RTA_DATA(rta
);
885 rta
= RTA_NEXT(rta
, rtasize
);
887 if (msg
->rtm_dst_len
<= best
)
888 { /* not better than a previous one */
891 enumerator
= this->rt_exclude
->create_enumerator(this->rt_exclude
);
892 while (enumerator
->enumerate(enumerator
, &table
))
894 if (table
== msg
->rtm_table
)
900 enumerator
->destroy(enumerator
);
905 if (this->routing_table
!= 0 &&
906 msg
->rtm_table
== this->routing_table
)
907 { /* route is from our own ipsec routing table */
910 if (rta_oif
&& !is_interface_up(this, rta_oif
))
911 { /* interface is down */
914 if (!addr_in_subnet(chunk
, rta_dst
, msg
->rtm_dst_len
))
915 { /* route destination does not contain dest */
921 /* nexthop lookup, return gateway if any */
923 gtw
= host_create_from_chunk(msg
->rtm_family
, rta_gtw
, 0);
924 best
= msg
->rtm_dst_len
;
929 /* got a source address */
930 new_src
= host_create_from_chunk(msg
->rtm_family
, rta_src
, 0);
933 if (get_vip_refcount(this, new_src
))
934 { /* skip source address if it is installed by us */
935 new_src
->destroy(new_src
);
941 best
= msg
->rtm_dst_len
;
947 { /* no source, but a gateway. Lookup source to reach gtw. */
948 new_gtw
= host_create_from_chunk(msg
->rtm_family
, rta_gtw
, 0);
949 new_src
= get_route(this, new_gtw
, FALSE
, candidate
);
950 new_gtw
->destroy(new_gtw
);
955 best
= msg
->rtm_dst_len
;
967 this->mutex
->unlock(this->mutex
);
975 return dest
->clone(dest
);
981 * Implementation of kernel_net_t.get_source_addr.
983 static host_t
* get_source_addr(private_kernel_netlink_net_t
*this,
984 host_t
*dest
, host_t
*src
)
986 return get_route(this, dest
, FALSE
, src
);
990 * Implementation of kernel_net_t.get_nexthop.
992 static host_t
* get_nexthop(private_kernel_netlink_net_t
*this, host_t
*dest
)
994 return get_route(this, dest
, TRUE
, NULL
);
998 * Manages the creation and deletion of ip addresses on an interface.
999 * By setting the appropriate nlmsg_type, the ip will be set or unset.
1001 static status_t
manage_ipaddr(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1002 int flags
, int if_index
, host_t
*ip
)
1004 netlink_buf_t request
;
1005 struct nlmsghdr
*hdr
;
1006 struct ifaddrmsg
*msg
;
1009 memset(&request
, 0, sizeof(request
));
1011 chunk
= ip
->get_address(ip
);
1013 hdr
= (struct nlmsghdr
*)request
;
1014 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1015 hdr
->nlmsg_type
= nlmsg_type
;
1016 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1018 msg
= (struct ifaddrmsg
*)NLMSG_DATA(hdr
);
1019 msg
->ifa_family
= ip
->get_family(ip
);
1021 msg
->ifa_prefixlen
= 8 * chunk
.len
;
1022 msg
->ifa_scope
= RT_SCOPE_UNIVERSE
;
1023 msg
->ifa_index
= if_index
;
1025 netlink_add_attribute(hdr
, IFA_LOCAL
, chunk
, sizeof(request
));
1027 return this->socket
->send_ack(this->socket
, hdr
);
1031 * Implementation of kernel_net_t.add_ip.
1033 static status_t
add_ip(private_kernel_netlink_net_t
*this,
1034 host_t
*virtual_ip
, host_t
*iface_ip
)
1036 iface_entry_t
*iface
;
1038 enumerator_t
*addrs
, *ifaces
;
1041 if (!this->install_virtual_ip
)
1042 { /* disabled by config */
1046 DBG2(DBG_KNL
, "adding virtual IP %H", virtual_ip
);
1048 this->mutex
->lock(this->mutex
);
1049 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1050 while (ifaces
->enumerate(ifaces
, &iface
))
1052 bool iface_found
= FALSE
;
1054 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1055 while (addrs
->enumerate(addrs
, &addr
))
1057 if (iface_ip
->ip_equals(iface_ip
, addr
->ip
))
1061 else if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1064 DBG2(DBG_KNL
, "virtual IP %H already installed on %s",
1065 virtual_ip
, iface
->ifname
);
1066 addrs
->destroy(addrs
);
1067 ifaces
->destroy(ifaces
);
1068 this->mutex
->unlock(this->mutex
);
1072 addrs
->destroy(addrs
);
1076 ifindex
= iface
->ifindex
;
1077 addr
= malloc_thing(addr_entry_t
);
1078 addr
->ip
= virtual_ip
->clone(virtual_ip
);
1080 addr
->virtual = TRUE
;
1081 addr
->scope
= RT_SCOPE_UNIVERSE
;
1082 iface
->addrs
->insert_last(iface
->addrs
, addr
);
1084 if (manage_ipaddr(this, RTM_NEWADDR
, NLM_F_CREATE
| NLM_F_EXCL
,
1085 ifindex
, virtual_ip
) == SUCCESS
)
1087 while (get_vip_refcount(this, virtual_ip
) == 0)
1088 { /* wait until address appears */
1089 this->condvar
->wait(this->condvar
, this->mutex
);
1091 ifaces
->destroy(ifaces
);
1092 this->mutex
->unlock(this->mutex
);
1095 ifaces
->destroy(ifaces
);
1096 this->mutex
->unlock(this->mutex
);
1097 DBG1(DBG_KNL
, "adding virtual IP %H failed", virtual_ip
);
1101 ifaces
->destroy(ifaces
);
1102 this->mutex
->unlock(this->mutex
);
1104 DBG1(DBG_KNL
, "interface address %H not found, unable to install"
1105 "virtual IP %H", iface_ip
, virtual_ip
);
1110 * Implementation of kernel_net_t.del_ip.
1112 static status_t
del_ip(private_kernel_netlink_net_t
*this, host_t
*virtual_ip
)
1114 iface_entry_t
*iface
;
1116 enumerator_t
*addrs
, *ifaces
;
1120 if (!this->install_virtual_ip
)
1121 { /* disabled by config */
1125 DBG2(DBG_KNL
, "deleting virtual IP %H", virtual_ip
);
1127 this->mutex
->lock(this->mutex
);
1128 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1129 while (ifaces
->enumerate(ifaces
, &iface
))
1131 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1132 while (addrs
->enumerate(addrs
, &addr
))
1134 if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1136 ifindex
= iface
->ifindex
;
1137 if (addr
->refcount
== 1)
1139 status
= manage_ipaddr(this, RTM_DELADDR
, 0,
1140 ifindex
, virtual_ip
);
1141 if (status
== SUCCESS
)
1142 { /* wait until the address is really gone */
1143 while (get_vip_refcount(this, virtual_ip
) > 0)
1145 this->condvar
->wait(this->condvar
, this->mutex
);
1148 addrs
->destroy(addrs
);
1149 ifaces
->destroy(ifaces
);
1150 this->mutex
->unlock(this->mutex
);
1157 DBG2(DBG_KNL
, "virtual IP %H used by other SAs, not deleting",
1159 addrs
->destroy(addrs
);
1160 ifaces
->destroy(ifaces
);
1161 this->mutex
->unlock(this->mutex
);
1165 addrs
->destroy(addrs
);
1167 ifaces
->destroy(ifaces
);
1168 this->mutex
->unlock(this->mutex
);
1170 DBG2(DBG_KNL
, "virtual IP %H not cached, unable to delete", virtual_ip
);
1175 * Manages source routes in the routing table.
1176 * By setting the appropriate nlmsg_type, the route gets added or removed.
1178 static status_t
manage_srcroute(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1179 int flags
, chunk_t dst_net
, u_int8_t prefixlen
,
1180 host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1182 netlink_buf_t request
;
1183 struct nlmsghdr
*hdr
;
1188 /* if route is 0.0.0.0/0, we can't install it, as it would
1189 * overwrite the default route. Instead, we add two routes:
1190 * 0.0.0.0/1 and 128.0.0.0/1 */
1191 if (this->routing_table
== 0 && prefixlen
== 0)
1194 u_int8_t half_prefixlen
;
1197 half_net
= chunk_alloca(dst_net
.len
);
1198 memset(half_net
.ptr
, 0, half_net
.len
);
1201 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1202 gateway
, src_ip
, if_name
);
1203 half_net
.ptr
[0] |= 0x80;
1204 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1205 gateway
, src_ip
, if_name
);
1209 memset(&request
, 0, sizeof(request
));
1211 hdr
= (struct nlmsghdr
*)request
;
1212 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1213 hdr
->nlmsg_type
= nlmsg_type
;
1214 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1216 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1217 msg
->rtm_family
= src_ip
->get_family(src_ip
);
1218 msg
->rtm_dst_len
= prefixlen
;
1219 msg
->rtm_table
= this->routing_table
;
1220 msg
->rtm_protocol
= RTPROT_STATIC
;
1221 msg
->rtm_type
= RTN_UNICAST
;
1222 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1224 netlink_add_attribute(hdr
, RTA_DST
, dst_net
, sizeof(request
));
1225 chunk
= src_ip
->get_address(src_ip
);
1226 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
1227 if (gateway
&& gateway
->get_family(gateway
) == src_ip
->get_family(src_ip
))
1229 chunk
= gateway
->get_address(gateway
);
1230 netlink_add_attribute(hdr
, RTA_GATEWAY
, chunk
, sizeof(request
));
1232 ifindex
= get_interface_index(this, if_name
);
1233 chunk
.ptr
= (char*)&ifindex
;
1234 chunk
.len
= sizeof(ifindex
);
1235 netlink_add_attribute(hdr
, RTA_OIF
, chunk
, sizeof(request
));
1237 return this->socket
->send_ack(this->socket
, hdr
);
1241 * Implementation of kernel_net_t.add_route.
1243 static status_t
add_route(private_kernel_netlink_net_t
*this, chunk_t dst_net
,
1244 u_int8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1246 return manage_srcroute(this, RTM_NEWROUTE
, NLM_F_CREATE
| NLM_F_EXCL
,
1247 dst_net
, prefixlen
, gateway
, src_ip
, if_name
);
1251 * Implementation of kernel_net_t.del_route.
1253 static status_t
del_route(private_kernel_netlink_net_t
*this, chunk_t dst_net
,
1254 u_int8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1256 return manage_srcroute(this, RTM_DELROUTE
, 0, dst_net
, prefixlen
,
1257 gateway
, src_ip
, if_name
);
1261 * Initialize a list of local addresses.
1263 static status_t
init_address_list(private_kernel_netlink_net_t
*this)
1265 netlink_buf_t request
;
1266 struct nlmsghdr
*out
, *current
, *in
;
1267 struct rtgenmsg
*msg
;
1269 enumerator_t
*ifaces
, *addrs
;
1270 iface_entry_t
*iface
;
1273 DBG1(DBG_KNL
, "listening on interfaces:");
1275 memset(&request
, 0, sizeof(request
));
1277 in
= (struct nlmsghdr
*)&request
;
1278 in
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtgenmsg
));
1279 in
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_MATCH
| NLM_F_ROOT
;
1280 msg
= (struct rtgenmsg
*)NLMSG_DATA(in
);
1281 msg
->rtgen_family
= AF_UNSPEC
;
1284 in
->nlmsg_type
= RTM_GETLINK
;
1285 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1290 while (NLMSG_OK(current
, len
))
1292 switch (current
->nlmsg_type
)
1297 process_link(this, current
, FALSE
);
1300 current
= NLMSG_NEXT(current
, len
);
1307 /* get all interface addresses */
1308 in
->nlmsg_type
= RTM_GETADDR
;
1309 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1314 while (NLMSG_OK(current
, len
))
1316 switch (current
->nlmsg_type
)
1321 process_addr(this, current
, FALSE
);
1324 current
= NLMSG_NEXT(current
, len
);
1331 this->mutex
->lock(this->mutex
);
1332 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1333 while (ifaces
->enumerate(ifaces
, &iface
))
1335 if (iface
->flags
& IFF_UP
)
1337 DBG1(DBG_KNL
, " %s", iface
->ifname
);
1338 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1339 while (addrs
->enumerate(addrs
, (void**)&addr
))
1341 DBG1(DBG_KNL
, " %H", addr
->ip
);
1343 addrs
->destroy(addrs
);
1346 ifaces
->destroy(ifaces
);
1347 this->mutex
->unlock(this->mutex
);
1352 * create or delete a rule to use our routing table
1354 static status_t
manage_rule(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1355 int family
, u_int32_t table
, u_int32_t prio
)
1357 netlink_buf_t request
;
1358 struct nlmsghdr
*hdr
;
1362 memset(&request
, 0, sizeof(request
));
1363 hdr
= (struct nlmsghdr
*)request
;
1364 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1365 hdr
->nlmsg_type
= nlmsg_type
;
1366 if (nlmsg_type
== RTM_NEWRULE
)
1368 hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
1370 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1372 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1373 msg
->rtm_table
= table
;
1374 msg
->rtm_family
= family
;
1375 msg
->rtm_protocol
= RTPROT_BOOT
;
1376 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1377 msg
->rtm_type
= RTN_UNICAST
;
1379 chunk
= chunk_from_thing(prio
);
1380 netlink_add_attribute(hdr
, RTA_PRIORITY
, chunk
, sizeof(request
));
1382 return this->socket
->send_ack(this->socket
, hdr
);
1386 * Implementation of kernel_netlink_net_t.destroy.
1388 static void destroy(private_kernel_netlink_net_t
*this)
1390 if (this->routing_table
)
1392 manage_rule(this, RTM_DELRULE
, AF_INET
, this->routing_table
,
1393 this->routing_table_prio
);
1394 manage_rule(this, RTM_DELRULE
, AF_INET6
, this->routing_table
,
1395 this->routing_table_prio
);
1399 this->job
->cancel(this->job
);
1401 if (this->socket_events
> 0)
1403 close(this->socket_events
);
1405 DESTROY_IF(this->socket
);
1406 this->ifaces
->destroy_function(this->ifaces
, (void*)iface_entry_destroy
);
1407 this->rt_exclude
->destroy(this->rt_exclude
);
1408 this->condvar
->destroy(this->condvar
);
1409 this->mutex
->destroy(this->mutex
);
1414 * Described in header.
1416 kernel_netlink_net_t
*kernel_netlink_net_create()
1418 private_kernel_netlink_net_t
*this = malloc_thing(private_kernel_netlink_net_t
);
1419 struct sockaddr_nl addr
;
1420 enumerator_t
*enumerator
;
1423 /* public functions */
1424 this->public.interface
.get_interface
= (char*(*)(kernel_net_t
*,host_t
*))get_interface_name
;
1425 this->public.interface
.create_address_enumerator
= (enumerator_t
*(*)(kernel_net_t
*,bool,bool))create_address_enumerator
;
1426 this->public.interface
.get_source_addr
= (host_t
*(*)(kernel_net_t
*, host_t
*dest
, host_t
*src
))get_source_addr
;
1427 this->public.interface
.get_nexthop
= (host_t
*(*)(kernel_net_t
*, host_t
*dest
))get_nexthop
;
1428 this->public.interface
.add_ip
= (status_t(*)(kernel_net_t
*,host_t
*,host_t
*)) add_ip
;
1429 this->public.interface
.del_ip
= (status_t(*)(kernel_net_t
*,host_t
*)) del_ip
;
1430 this->public.interface
.add_route
= (status_t(*)(kernel_net_t
*,chunk_t
,u_int8_t
,host_t
*,host_t
*,char*)) add_route
;
1431 this->public.interface
.del_route
= (status_t(*)(kernel_net_t
*,chunk_t
,u_int8_t
,host_t
*,host_t
*,char*)) del_route
;
1432 this->public.interface
.destroy
= (void(*)(kernel_net_t
*)) destroy
;
1434 /* private members */
1435 this->ifaces
= linked_list_create();
1436 this->mutex
= mutex_create(MUTEX_TYPE_RECURSIVE
);
1437 this->condvar
= condvar_create(CONDVAR_TYPE_DEFAULT
);
1438 timerclear(&this->last_roam
);
1439 this->routing_table
= lib
->settings
->get_int(lib
->settings
,
1440 "%s.routing_table", ROUTING_TABLE
, hydra
->daemon
);
1441 this->routing_table_prio
= lib
->settings
->get_int(lib
->settings
,
1442 "%s.routing_table_prio", ROUTING_TABLE_PRIO
, hydra
->daemon
);
1443 this->process_route
= lib
->settings
->get_bool(lib
->settings
,
1444 "%s.process_route", TRUE
, hydra
->daemon
);
1445 this->install_virtual_ip
= lib
->settings
->get_bool(lib
->settings
,
1446 "%s.install_virtual_ip", TRUE
, hydra
->daemon
);
1448 this->rt_exclude
= linked_list_create();
1449 exclude
= lib
->settings
->get_str(lib
->settings
,
1450 "%s.ignore_routing_tables", NULL
, hydra
->daemon
);
1456 enumerator
= enumerator_create_token(exclude
, " ", " ");
1457 while (enumerator
->enumerate(enumerator
, &token
))
1460 table
= strtoul(token
, NULL
, 10);
1464 this->rt_exclude
->insert_last(this->rt_exclude
, (void*)table
);
1467 enumerator
->destroy(enumerator
);
1470 this->socket
= netlink_socket_create(NETLINK_ROUTE
);
1473 memset(&addr
, 0, sizeof(addr
));
1474 addr
.nl_family
= AF_NETLINK
;
1476 /* create and bind RT socket for events (address/interface/route changes) */
1477 this->socket_events
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
1478 if (this->socket_events
< 0)
1480 DBG1(DBG_KNL
, "unable to create RT event socket");
1484 addr
.nl_groups
= RTMGRP_IPV4_IFADDR
| RTMGRP_IPV6_IFADDR
|
1485 RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_ROUTE
| RTMGRP_LINK
;
1486 if (bind(this->socket_events
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1488 DBG1(DBG_KNL
, "unable to bind RT event socket");
1493 this->job
= callback_job_create((callback_job_cb_t
)receive_events
,
1495 lib
->processor
->queue_job(lib
->processor
, (job_t
*)this->job
);
1497 if (init_address_list(this) != SUCCESS
)
1499 DBG1(DBG_KNL
, "unable to get interface list");
1504 if (this->routing_table
)
1506 if (manage_rule(this, RTM_NEWRULE
, AF_INET
, this->routing_table
,
1507 this->routing_table_prio
) != SUCCESS
)
1509 DBG1(DBG_KNL
, "unable to create IPv4 routing table rule");
1511 if (manage_rule(this, RTM_NEWRULE
, AF_INET6
, this->routing_table
,
1512 this->routing_table_prio
) != SUCCESS
)
1514 DBG1(DBG_KNL
, "unable to create IPv6 routing table rule");
1518 return &this->public;