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 * get the first non-virtual ip address on the given interface.
227 * returned host is a clone, has to be freed by caller.
229 static host_t
*get_interface_address(private_kernel_netlink_net_t
*this,
230 int ifindex
, int family
)
232 enumerator_t
*ifaces
, *addrs
;
233 iface_entry_t
*iface
;
237 this->mutex
->lock(this->mutex
);
238 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
239 while (ifaces
->enumerate(ifaces
, &iface
))
241 if (iface
->ifindex
== ifindex
)
243 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
244 while (addrs
->enumerate(addrs
, &addr
))
246 if (!addr
->virtual && addr
->ip
->get_family(addr
->ip
) == family
)
248 ip
= addr
->ip
->clone(addr
->ip
);
252 addrs
->destroy(addrs
);
256 ifaces
->destroy(ifaces
);
257 this->mutex
->unlock(this->mutex
);
262 * callback function that raises the delayed roam event
264 static job_requeue_t
roam_event(uintptr_t address
)
266 hydra
->kernel_interface
->roam(hydra
->kernel_interface
, address
!= 0);
267 return JOB_REQUEUE_NONE
;
271 * fire a roaming event. we delay it for a bit and fire only one event
272 * for multiple calls. otherwise we would create too many events.
274 static void fire_roam_event(private_kernel_netlink_net_t
*this, bool address
)
279 time_monotonic(&now
);
280 if (timercmp(&now
, &this->last_roam
, >))
282 now
.tv_usec
+= ROAM_DELAY
* 1000;
283 while (now
.tv_usec
> 1000000)
286 now
.tv_usec
-= 1000000;
288 this->last_roam
= now
;
290 job
= (job_t
*)callback_job_create((callback_job_cb_t
)roam_event
,
291 (void*)(uintptr_t)(address ?
1 : 0),
293 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, job
, ROAM_DELAY
);
298 * process RTM_NEWLINK/RTM_DELLINK from kernel
300 static void process_link(private_kernel_netlink_net_t
*this,
301 struct nlmsghdr
*hdr
, bool event
)
303 struct ifinfomsg
* msg
= (struct ifinfomsg
*)(NLMSG_DATA(hdr
));
304 struct rtattr
*rta
= IFLA_RTA(msg
);
305 size_t rtasize
= IFLA_PAYLOAD (hdr
);
306 enumerator_t
*enumerator
;
307 iface_entry_t
*current
, *entry
= NULL
;
311 while(RTA_OK(rta
, rtasize
))
313 switch (rta
->rta_type
)
316 name
= RTA_DATA(rta
);
319 rta
= RTA_NEXT(rta
, rtasize
);
326 this->mutex
->lock(this->mutex
);
327 switch (hdr
->nlmsg_type
)
331 if (msg
->ifi_flags
& IFF_LOOPBACK
)
332 { /* ignore loopback interfaces */
335 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
336 while (enumerator
->enumerate(enumerator
, ¤t
))
338 if (current
->ifindex
== msg
->ifi_index
)
344 enumerator
->destroy(enumerator
);
347 entry
= malloc_thing(iface_entry_t
);
348 entry
->ifindex
= msg
->ifi_index
;
350 entry
->addrs
= linked_list_create();
351 this->ifaces
->insert_last(this->ifaces
, entry
);
353 memcpy(entry
->ifname
, name
, IFNAMSIZ
);
354 entry
->ifname
[IFNAMSIZ
-1] = '\0';
357 if (!(entry
->flags
& IFF_UP
) && (msg
->ifi_flags
& IFF_UP
))
360 DBG1(DBG_KNL
, "interface %s activated", name
);
362 if ((entry
->flags
& IFF_UP
) && !(msg
->ifi_flags
& IFF_UP
))
365 DBG1(DBG_KNL
, "interface %s deactivated", name
);
368 entry
->flags
= msg
->ifi_flags
;
373 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
374 while (enumerator
->enumerate(enumerator
, ¤t
))
376 if (current
->ifindex
== msg
->ifi_index
)
378 /* we do not remove it, as an address may be added to a
379 * "down" interface and we wan't to know that. */
380 current
->flags
= msg
->ifi_flags
;
384 enumerator
->destroy(enumerator
);
388 this->mutex
->unlock(this->mutex
);
390 /* send an update to all IKE_SAs */
393 fire_roam_event(this, TRUE
);
398 * process RTM_NEWADDR/RTM_DELADDR from kernel
400 static void process_addr(private_kernel_netlink_net_t
*this,
401 struct nlmsghdr
*hdr
, bool event
)
403 struct ifaddrmsg
* msg
= (struct ifaddrmsg
*)(NLMSG_DATA(hdr
));
404 struct rtattr
*rta
= IFA_RTA(msg
);
405 size_t rtasize
= IFA_PAYLOAD (hdr
);
407 enumerator_t
*ifaces
, *addrs
;
408 iface_entry_t
*iface
;
410 chunk_t local
= chunk_empty
, address
= chunk_empty
;
411 bool update
= FALSE
, found
= FALSE
, changed
= FALSE
;
413 while(RTA_OK(rta
, rtasize
))
415 switch (rta
->rta_type
)
418 local
.ptr
= RTA_DATA(rta
);
419 local
.len
= RTA_PAYLOAD(rta
);
422 address
.ptr
= RTA_DATA(rta
);
423 address
.len
= RTA_PAYLOAD(rta
);
426 rta
= RTA_NEXT(rta
, rtasize
);
429 /* For PPP interfaces, we need the IFA_LOCAL address,
430 * IFA_ADDRESS is the peers address. But IFA_LOCAL is
431 * not included in all cases (IPv6?), so fallback to IFA_ADDRESS. */
434 host
= host_create_from_chunk(msg
->ifa_family
, local
, 0);
436 else if (address
.ptr
)
438 host
= host_create_from_chunk(msg
->ifa_family
, address
, 0);
446 this->mutex
->lock(this->mutex
);
447 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
448 while (ifaces
->enumerate(ifaces
, &iface
))
450 if (iface
->ifindex
== msg
->ifa_index
)
452 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
453 while (addrs
->enumerate(addrs
, &addr
))
455 if (host
->ip_equals(host
, addr
->ip
))
458 if (hdr
->nlmsg_type
== RTM_DELADDR
)
460 iface
->addrs
->remove_at(iface
->addrs
, addrs
);
464 DBG1(DBG_KNL
, "%H disappeared from %s",
465 host
, iface
->ifname
);
467 addr_entry_destroy(addr
);
469 else if (hdr
->nlmsg_type
== RTM_NEWADDR
&& addr
->virtual)
475 addrs
->destroy(addrs
);
477 if (hdr
->nlmsg_type
== RTM_NEWADDR
)
483 addr
= malloc_thing(addr_entry_t
);
484 addr
->ip
= host
->clone(host
);
485 addr
->virtual = FALSE
;
487 addr
->scope
= msg
->ifa_scope
;
489 iface
->addrs
->insert_last(iface
->addrs
, addr
);
492 DBG1(DBG_KNL
, "%H appeared on %s", host
, iface
->ifname
);
496 if (found
&& (iface
->flags
& IFF_UP
))
503 ifaces
->destroy(ifaces
);
504 this->mutex
->unlock(this->mutex
);
507 /* send an update to all IKE_SAs */
508 if (update
&& event
&& changed
)
510 fire_roam_event(this, TRUE
);
515 * process RTM_NEWROUTE and RTM_DELROUTE from kernel
517 static void process_route(private_kernel_netlink_net_t
*this, struct nlmsghdr
*hdr
)
519 struct rtmsg
* msg
= (struct rtmsg
*)(NLMSG_DATA(hdr
));
520 struct rtattr
*rta
= RTM_RTA(msg
);
521 size_t rtasize
= RTM_PAYLOAD(hdr
);
522 u_int32_t rta_oif
= 0;
525 /* ignore routes added by us or in the local routing table (local addrs) */
526 if (msg
->rtm_table
&& (msg
->rtm_table
== this->routing_table
||
527 msg
->rtm_table
== RT_TABLE_LOCAL
))
532 while (RTA_OK(rta
, rtasize
))
534 switch (rta
->rta_type
)
537 host
= host_create_from_chunk(msg
->rtm_family
,
538 chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
)), 0);
541 if (RTA_PAYLOAD(rta
) == sizeof(rta_oif
))
543 rta_oif
= *(u_int32_t
*)RTA_DATA(rta
);
547 rta
= RTA_NEXT(rta
, rtasize
);
549 if (!host
&& rta_oif
)
551 host
= get_interface_address(this, rta_oif
, msg
->rtm_family
);
555 this->mutex
->lock(this->mutex
);
556 if (!get_vip_refcount(this, host
))
557 { /* ignore routes added for virtual IPs */
558 fire_roam_event(this, FALSE
);
560 this->mutex
->unlock(this->mutex
);
566 * Receives events from kernel
568 static job_requeue_t
receive_events(private_kernel_netlink_net_t
*this)
571 struct nlmsghdr
*hdr
= (struct nlmsghdr
*)response
;
572 struct sockaddr_nl addr
;
573 socklen_t addr_len
= sizeof(addr
);
577 oldstate
= thread_cancelability(TRUE
);
578 len
= recvfrom(this->socket_events
, response
, sizeof(response
), 0,
579 (struct sockaddr
*)&addr
, &addr_len
);
580 thread_cancelability(oldstate
);
587 /* interrupted, try again */
588 return JOB_REQUEUE_DIRECT
;
590 /* no data ready, select again */
591 return JOB_REQUEUE_DIRECT
;
593 DBG1(DBG_KNL
, "unable to receive from rt event socket");
595 return JOB_REQUEUE_FAIR
;
599 if (addr
.nl_pid
!= 0)
600 { /* not from kernel. not interested, try another one */
601 return JOB_REQUEUE_DIRECT
;
604 while (NLMSG_OK(hdr
, len
))
606 /* looks good so far, dispatch netlink message */
607 switch (hdr
->nlmsg_type
)
611 process_addr(this, hdr
, TRUE
);
612 this->condvar
->broadcast(this->condvar
);
616 process_link(this, hdr
, TRUE
);
617 this->condvar
->broadcast(this->condvar
);
621 if (this->process_route
)
623 process_route(this, hdr
);
629 hdr
= NLMSG_NEXT(hdr
, len
);
631 return JOB_REQUEUE_DIRECT
;
634 /** enumerator over addresses */
636 private_kernel_netlink_net_t
* this;
637 /** whether to enumerate down interfaces */
638 bool include_down_ifaces
;
639 /** whether to enumerate virtual ip addresses */
640 bool include_virtual_ips
;
641 } address_enumerator_t
;
644 * cleanup function for address enumerator
646 static void address_enumerator_destroy(address_enumerator_t
*data
)
648 data
->this->mutex
->unlock(data
->this->mutex
);
653 * filter for addresses
655 static bool filter_addresses(address_enumerator_t
*data
, addr_entry_t
** in
, host_t
** out
)
657 if (!data
->include_virtual_ips
&& (*in
)->virtual)
658 { /* skip virtual interfaces added by us */
661 if ((*in
)->scope
>= RT_SCOPE_LINK
)
662 { /* skip addresses with a unusable scope */
670 * enumerator constructor for interfaces
672 static enumerator_t
*create_iface_enumerator(iface_entry_t
*iface
, address_enumerator_t
*data
)
674 return enumerator_create_filter(iface
->addrs
->create_enumerator(iface
->addrs
),
675 (void*)filter_addresses
, data
, NULL
);
679 * filter for interfaces
681 static bool filter_interfaces(address_enumerator_t
*data
, iface_entry_t
** in
, iface_entry_t
** out
)
683 if (!data
->include_down_ifaces
&& !((*in
)->flags
& IFF_UP
))
684 { /* skip interfaces not up */
692 * implementation of kernel_net_t.create_address_enumerator
694 static enumerator_t
*create_address_enumerator(private_kernel_netlink_net_t
*this,
695 bool include_down_ifaces
, bool include_virtual_ips
)
697 address_enumerator_t
*data
= malloc_thing(address_enumerator_t
);
699 data
->include_down_ifaces
= include_down_ifaces
;
700 data
->include_virtual_ips
= include_virtual_ips
;
702 this->mutex
->lock(this->mutex
);
703 return enumerator_create_nested(
704 enumerator_create_filter(this->ifaces
->create_enumerator(this->ifaces
),
705 (void*)filter_interfaces
, data
, NULL
),
706 (void*)create_iface_enumerator
, data
, (void*)address_enumerator_destroy
);
710 * implementation of kernel_net_t.get_interface_name
712 static char *get_interface_name(private_kernel_netlink_net_t
*this, host_t
* ip
)
714 enumerator_t
*ifaces
, *addrs
;
715 iface_entry_t
*iface
;
719 DBG2(DBG_KNL
, "getting interface name for %H", ip
);
721 this->mutex
->lock(this->mutex
);
722 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
723 while (ifaces
->enumerate(ifaces
, &iface
))
725 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
726 while (addrs
->enumerate(addrs
, &addr
))
728 if (ip
->ip_equals(ip
, addr
->ip
))
730 name
= strdup(iface
->ifname
);
734 addrs
->destroy(addrs
);
740 ifaces
->destroy(ifaces
);
741 this->mutex
->unlock(this->mutex
);
745 DBG2(DBG_KNL
, "%H is on interface %s", ip
, name
);
749 DBG2(DBG_KNL
, "%H is not a local address", ip
);
755 * get the index of an interface by name
757 static int get_interface_index(private_kernel_netlink_net_t
*this, char* name
)
759 enumerator_t
*ifaces
;
760 iface_entry_t
*iface
;
763 DBG2(DBG_KNL
, "getting iface index for %s", name
);
765 this->mutex
->lock(this->mutex
);
766 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
767 while (ifaces
->enumerate(ifaces
, &iface
))
769 if (streq(name
, iface
->ifname
))
771 ifindex
= iface
->ifindex
;
775 ifaces
->destroy(ifaces
);
776 this->mutex
->unlock(this->mutex
);
780 DBG1(DBG_KNL
, "unable to get interface index for %s", name
);
786 * Check if an interface with a given index is up
788 static bool is_interface_up(private_kernel_netlink_net_t
*this, int index
)
790 enumerator_t
*ifaces
;
791 iface_entry_t
*iface
;
792 /* default to TRUE for interface we do not monitor (e.g. lo) */
795 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
796 while (ifaces
->enumerate(ifaces
, &iface
))
798 if (iface
->ifindex
== index
)
800 up
= iface
->flags
& IFF_UP
;
804 ifaces
->destroy(ifaces
);
809 * check if an address (chunk) addr is in subnet (net with net_len net bits)
811 static bool addr_in_subnet(chunk_t addr
, chunk_t net
, int net_len
)
813 static const u_char mask
[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
817 { /* any address matches a /0 network */
820 if (addr
.len
!= net
.len
|| net_len
> 8 * net
.len
)
824 /* scan through all bytes in network order */
829 return (mask
[net_len
] & addr
.ptr
[byte
]) == (mask
[net_len
] & net
.ptr
[byte
]);
833 if (addr
.ptr
[byte
] != net
.ptr
[byte
])
845 * Get a route: If "nexthop", the nexthop is returned. source addr otherwise.
847 static host_t
*get_route(private_kernel_netlink_net_t
*this, host_t
*dest
,
848 bool nexthop
, host_t
*candidate
)
850 netlink_buf_t request
;
851 struct nlmsghdr
*hdr
, *out
, *current
;
856 enumerator_t
*enumerator
;
857 host_t
*src
= NULL
, *gtw
= NULL
;
859 DBG2(DBG_KNL
, "getting address to reach %H", dest
);
861 memset(&request
, 0, sizeof(request
));
863 hdr
= (struct nlmsghdr
*)request
;
864 hdr
->nlmsg_flags
= NLM_F_REQUEST
;
865 if (dest
->get_family(dest
) == AF_INET
)
867 /* We dump all addresses for IPv4, as we want to ignore IPsec specific
868 * routes installed by us. But the kernel does not return source
869 * addresses in a IPv6 dump, so fall back to get() for v6 routes. */
870 hdr
->nlmsg_flags
|= NLM_F_ROOT
| NLM_F_DUMP
;
872 hdr
->nlmsg_type
= RTM_GETROUTE
;
873 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
875 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
876 msg
->rtm_family
= dest
->get_family(dest
);
879 chunk
= candidate
->get_address(candidate
);
880 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
882 chunk
= dest
->get_address(dest
);
883 netlink_add_attribute(hdr
, RTA_DST
, chunk
, sizeof(request
));
885 if (this->socket
->send(this->socket
, hdr
, &out
, &len
) != SUCCESS
)
887 DBG1(DBG_KNL
, "getting address to %H failed", dest
);
890 this->mutex
->lock(this->mutex
);
892 for (current
= out
; NLMSG_OK(current
, len
);
893 current
= NLMSG_NEXT(current
, len
))
895 switch (current
->nlmsg_type
)
903 chunk_t rta_gtw
, rta_src
, rta_dst
;
904 u_int32_t rta_oif
= 0;
905 host_t
*new_src
, *new_gtw
;
909 rta_gtw
= rta_src
= rta_dst
= chunk_empty
;
910 msg
= (struct rtmsg
*)(NLMSG_DATA(current
));
912 rtasize
= RTM_PAYLOAD(current
);
913 while (RTA_OK(rta
, rtasize
))
915 switch (rta
->rta_type
)
918 rta_src
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
921 rta_gtw
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
924 rta_dst
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
927 if (RTA_PAYLOAD(rta
) == sizeof(rta_oif
))
929 rta_oif
= *(u_int32_t
*)RTA_DATA(rta
);
933 rta
= RTA_NEXT(rta
, rtasize
);
935 if (msg
->rtm_dst_len
<= best
)
936 { /* not better than a previous one */
939 enumerator
= this->rt_exclude
->create_enumerator(this->rt_exclude
);
940 while (enumerator
->enumerate(enumerator
, &table
))
942 if (table
== msg
->rtm_table
)
948 enumerator
->destroy(enumerator
);
953 if (this->routing_table
!= 0 &&
954 msg
->rtm_table
== this->routing_table
)
955 { /* route is from our own ipsec routing table */
958 if (rta_oif
&& !is_interface_up(this, rta_oif
))
959 { /* interface is down */
962 if (!addr_in_subnet(chunk
, rta_dst
, msg
->rtm_dst_len
))
963 { /* route destination does not contain dest */
969 /* nexthop lookup, return gateway if any */
971 gtw
= host_create_from_chunk(msg
->rtm_family
, rta_gtw
, 0);
972 best
= msg
->rtm_dst_len
;
976 { /* got a source address */
977 new_src
= host_create_from_chunk(msg
->rtm_family
, rta_src
, 0);
980 if (get_vip_refcount(this, new_src
))
981 { /* skip source address if it is installed by us */
982 new_src
->destroy(new_src
);
988 best
= msg
->rtm_dst_len
;
994 { /* no src or gtw, but an interface. Get address from it. */
995 new_src
= get_interface_address(this, rta_oif
,
1001 best
= msg
->rtm_dst_len
;
1006 { /* no source, but a gateway. Lookup source to reach gtw. */
1007 new_gtw
= host_create_from_chunk(msg
->rtm_family
, rta_gtw
, 0);
1008 new_src
= get_route(this, new_gtw
, FALSE
, candidate
);
1009 new_gtw
->destroy(new_gtw
);
1014 best
= msg
->rtm_dst_len
;
1026 this->mutex
->unlock(this->mutex
);
1034 return dest
->clone(dest
);
1040 * Implementation of kernel_net_t.get_source_addr.
1042 static host_t
* get_source_addr(private_kernel_netlink_net_t
*this,
1043 host_t
*dest
, host_t
*src
)
1045 return get_route(this, dest
, FALSE
, src
);
1049 * Implementation of kernel_net_t.get_nexthop.
1051 static host_t
* get_nexthop(private_kernel_netlink_net_t
*this, host_t
*dest
)
1053 return get_route(this, dest
, TRUE
, NULL
);
1057 * Manages the creation and deletion of ip addresses on an interface.
1058 * By setting the appropriate nlmsg_type, the ip will be set or unset.
1060 static status_t
manage_ipaddr(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1061 int flags
, int if_index
, host_t
*ip
)
1063 netlink_buf_t request
;
1064 struct nlmsghdr
*hdr
;
1065 struct ifaddrmsg
*msg
;
1068 memset(&request
, 0, sizeof(request
));
1070 chunk
= ip
->get_address(ip
);
1072 hdr
= (struct nlmsghdr
*)request
;
1073 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1074 hdr
->nlmsg_type
= nlmsg_type
;
1075 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1077 msg
= (struct ifaddrmsg
*)NLMSG_DATA(hdr
);
1078 msg
->ifa_family
= ip
->get_family(ip
);
1080 msg
->ifa_prefixlen
= 8 * chunk
.len
;
1081 msg
->ifa_scope
= RT_SCOPE_UNIVERSE
;
1082 msg
->ifa_index
= if_index
;
1084 netlink_add_attribute(hdr
, IFA_LOCAL
, chunk
, sizeof(request
));
1086 return this->socket
->send_ack(this->socket
, hdr
);
1090 * Implementation of kernel_net_t.add_ip.
1092 static status_t
add_ip(private_kernel_netlink_net_t
*this,
1093 host_t
*virtual_ip
, host_t
*iface_ip
)
1095 iface_entry_t
*iface
;
1097 enumerator_t
*addrs
, *ifaces
;
1100 if (!this->install_virtual_ip
)
1101 { /* disabled by config */
1105 DBG2(DBG_KNL
, "adding virtual IP %H", virtual_ip
);
1107 this->mutex
->lock(this->mutex
);
1108 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1109 while (ifaces
->enumerate(ifaces
, &iface
))
1111 bool iface_found
= FALSE
;
1113 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1114 while (addrs
->enumerate(addrs
, &addr
))
1116 if (iface_ip
->ip_equals(iface_ip
, addr
->ip
))
1120 else if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1123 DBG2(DBG_KNL
, "virtual IP %H already installed on %s",
1124 virtual_ip
, iface
->ifname
);
1125 addrs
->destroy(addrs
);
1126 ifaces
->destroy(ifaces
);
1127 this->mutex
->unlock(this->mutex
);
1131 addrs
->destroy(addrs
);
1135 ifindex
= iface
->ifindex
;
1136 addr
= malloc_thing(addr_entry_t
);
1137 addr
->ip
= virtual_ip
->clone(virtual_ip
);
1139 addr
->virtual = TRUE
;
1140 addr
->scope
= RT_SCOPE_UNIVERSE
;
1141 iface
->addrs
->insert_last(iface
->addrs
, addr
);
1143 if (manage_ipaddr(this, RTM_NEWADDR
, NLM_F_CREATE
| NLM_F_EXCL
,
1144 ifindex
, virtual_ip
) == SUCCESS
)
1146 while (get_vip_refcount(this, virtual_ip
) == 0)
1147 { /* wait until address appears */
1148 this->condvar
->wait(this->condvar
, this->mutex
);
1150 ifaces
->destroy(ifaces
);
1151 this->mutex
->unlock(this->mutex
);
1154 ifaces
->destroy(ifaces
);
1155 this->mutex
->unlock(this->mutex
);
1156 DBG1(DBG_KNL
, "adding virtual IP %H failed", virtual_ip
);
1160 ifaces
->destroy(ifaces
);
1161 this->mutex
->unlock(this->mutex
);
1163 DBG1(DBG_KNL
, "interface address %H not found, unable to install"
1164 "virtual IP %H", iface_ip
, virtual_ip
);
1169 * Implementation of kernel_net_t.del_ip.
1171 static status_t
del_ip(private_kernel_netlink_net_t
*this, host_t
*virtual_ip
)
1173 iface_entry_t
*iface
;
1175 enumerator_t
*addrs
, *ifaces
;
1179 if (!this->install_virtual_ip
)
1180 { /* disabled by config */
1184 DBG2(DBG_KNL
, "deleting virtual IP %H", virtual_ip
);
1186 this->mutex
->lock(this->mutex
);
1187 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1188 while (ifaces
->enumerate(ifaces
, &iface
))
1190 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1191 while (addrs
->enumerate(addrs
, &addr
))
1193 if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1195 ifindex
= iface
->ifindex
;
1196 if (addr
->refcount
== 1)
1198 status
= manage_ipaddr(this, RTM_DELADDR
, 0,
1199 ifindex
, virtual_ip
);
1200 if (status
== SUCCESS
)
1201 { /* wait until the address is really gone */
1202 while (get_vip_refcount(this, virtual_ip
) > 0)
1204 this->condvar
->wait(this->condvar
, this->mutex
);
1207 addrs
->destroy(addrs
);
1208 ifaces
->destroy(ifaces
);
1209 this->mutex
->unlock(this->mutex
);
1216 DBG2(DBG_KNL
, "virtual IP %H used by other SAs, not deleting",
1218 addrs
->destroy(addrs
);
1219 ifaces
->destroy(ifaces
);
1220 this->mutex
->unlock(this->mutex
);
1224 addrs
->destroy(addrs
);
1226 ifaces
->destroy(ifaces
);
1227 this->mutex
->unlock(this->mutex
);
1229 DBG2(DBG_KNL
, "virtual IP %H not cached, unable to delete", virtual_ip
);
1234 * Manages source routes in the routing table.
1235 * By setting the appropriate nlmsg_type, the route gets added or removed.
1237 static status_t
manage_srcroute(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1238 int flags
, chunk_t dst_net
, u_int8_t prefixlen
,
1239 host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1241 netlink_buf_t request
;
1242 struct nlmsghdr
*hdr
;
1247 /* if route is 0.0.0.0/0, we can't install it, as it would
1248 * overwrite the default route. Instead, we add two routes:
1249 * 0.0.0.0/1 and 128.0.0.0/1 */
1250 if (this->routing_table
== 0 && prefixlen
== 0)
1253 u_int8_t half_prefixlen
;
1256 half_net
= chunk_alloca(dst_net
.len
);
1257 memset(half_net
.ptr
, 0, half_net
.len
);
1260 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1261 gateway
, src_ip
, if_name
);
1262 half_net
.ptr
[0] |= 0x80;
1263 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1264 gateway
, src_ip
, if_name
);
1268 memset(&request
, 0, sizeof(request
));
1270 hdr
= (struct nlmsghdr
*)request
;
1271 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1272 hdr
->nlmsg_type
= nlmsg_type
;
1273 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1275 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1276 msg
->rtm_family
= src_ip
->get_family(src_ip
);
1277 msg
->rtm_dst_len
= prefixlen
;
1278 msg
->rtm_table
= this->routing_table
;
1279 msg
->rtm_protocol
= RTPROT_STATIC
;
1280 msg
->rtm_type
= RTN_UNICAST
;
1281 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1283 netlink_add_attribute(hdr
, RTA_DST
, dst_net
, sizeof(request
));
1284 chunk
= src_ip
->get_address(src_ip
);
1285 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
1286 if (gateway
&& gateway
->get_family(gateway
) == src_ip
->get_family(src_ip
))
1288 chunk
= gateway
->get_address(gateway
);
1289 netlink_add_attribute(hdr
, RTA_GATEWAY
, chunk
, sizeof(request
));
1291 ifindex
= get_interface_index(this, if_name
);
1292 chunk
.ptr
= (char*)&ifindex
;
1293 chunk
.len
= sizeof(ifindex
);
1294 netlink_add_attribute(hdr
, RTA_OIF
, chunk
, sizeof(request
));
1296 return this->socket
->send_ack(this->socket
, hdr
);
1300 * Implementation of kernel_net_t.add_route.
1302 static status_t
add_route(private_kernel_netlink_net_t
*this, chunk_t dst_net
,
1303 u_int8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1305 return manage_srcroute(this, RTM_NEWROUTE
, NLM_F_CREATE
| NLM_F_EXCL
,
1306 dst_net
, prefixlen
, gateway
, src_ip
, if_name
);
1310 * Implementation of kernel_net_t.del_route.
1312 static status_t
del_route(private_kernel_netlink_net_t
*this, chunk_t dst_net
,
1313 u_int8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1315 return manage_srcroute(this, RTM_DELROUTE
, 0, dst_net
, prefixlen
,
1316 gateway
, src_ip
, if_name
);
1320 * Initialize a list of local addresses.
1322 static status_t
init_address_list(private_kernel_netlink_net_t
*this)
1324 netlink_buf_t request
;
1325 struct nlmsghdr
*out
, *current
, *in
;
1326 struct rtgenmsg
*msg
;
1328 enumerator_t
*ifaces
, *addrs
;
1329 iface_entry_t
*iface
;
1332 DBG1(DBG_KNL
, "listening on interfaces:");
1334 memset(&request
, 0, sizeof(request
));
1336 in
= (struct nlmsghdr
*)&request
;
1337 in
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtgenmsg
));
1338 in
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_MATCH
| NLM_F_ROOT
;
1339 msg
= (struct rtgenmsg
*)NLMSG_DATA(in
);
1340 msg
->rtgen_family
= AF_UNSPEC
;
1343 in
->nlmsg_type
= RTM_GETLINK
;
1344 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1349 while (NLMSG_OK(current
, len
))
1351 switch (current
->nlmsg_type
)
1356 process_link(this, current
, FALSE
);
1359 current
= NLMSG_NEXT(current
, len
);
1366 /* get all interface addresses */
1367 in
->nlmsg_type
= RTM_GETADDR
;
1368 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1373 while (NLMSG_OK(current
, len
))
1375 switch (current
->nlmsg_type
)
1380 process_addr(this, current
, FALSE
);
1383 current
= NLMSG_NEXT(current
, len
);
1390 this->mutex
->lock(this->mutex
);
1391 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1392 while (ifaces
->enumerate(ifaces
, &iface
))
1394 if (iface
->flags
& IFF_UP
)
1396 DBG1(DBG_KNL
, " %s", iface
->ifname
);
1397 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1398 while (addrs
->enumerate(addrs
, (void**)&addr
))
1400 DBG1(DBG_KNL
, " %H", addr
->ip
);
1402 addrs
->destroy(addrs
);
1405 ifaces
->destroy(ifaces
);
1406 this->mutex
->unlock(this->mutex
);
1411 * create or delete a rule to use our routing table
1413 static status_t
manage_rule(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1414 int family
, u_int32_t table
, u_int32_t prio
)
1416 netlink_buf_t request
;
1417 struct nlmsghdr
*hdr
;
1421 memset(&request
, 0, sizeof(request
));
1422 hdr
= (struct nlmsghdr
*)request
;
1423 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1424 hdr
->nlmsg_type
= nlmsg_type
;
1425 if (nlmsg_type
== RTM_NEWRULE
)
1427 hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
1429 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1431 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1432 msg
->rtm_table
= table
;
1433 msg
->rtm_family
= family
;
1434 msg
->rtm_protocol
= RTPROT_BOOT
;
1435 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1436 msg
->rtm_type
= RTN_UNICAST
;
1438 chunk
= chunk_from_thing(prio
);
1439 netlink_add_attribute(hdr
, RTA_PRIORITY
, chunk
, sizeof(request
));
1441 return this->socket
->send_ack(this->socket
, hdr
);
1445 * Implementation of kernel_netlink_net_t.destroy.
1447 static void destroy(private_kernel_netlink_net_t
*this)
1449 if (this->routing_table
)
1451 manage_rule(this, RTM_DELRULE
, AF_INET
, this->routing_table
,
1452 this->routing_table_prio
);
1453 manage_rule(this, RTM_DELRULE
, AF_INET6
, this->routing_table
,
1454 this->routing_table_prio
);
1458 this->job
->cancel(this->job
);
1460 if (this->socket_events
> 0)
1462 close(this->socket_events
);
1464 DESTROY_IF(this->socket
);
1465 this->ifaces
->destroy_function(this->ifaces
, (void*)iface_entry_destroy
);
1466 this->rt_exclude
->destroy(this->rt_exclude
);
1467 this->condvar
->destroy(this->condvar
);
1468 this->mutex
->destroy(this->mutex
);
1473 * Described in header.
1475 kernel_netlink_net_t
*kernel_netlink_net_create()
1477 private_kernel_netlink_net_t
*this = malloc_thing(private_kernel_netlink_net_t
);
1478 struct sockaddr_nl addr
;
1479 enumerator_t
*enumerator
;
1482 /* public functions */
1483 this->public.interface
.get_interface
= (char*(*)(kernel_net_t
*,host_t
*))get_interface_name
;
1484 this->public.interface
.create_address_enumerator
= (enumerator_t
*(*)(kernel_net_t
*,bool,bool))create_address_enumerator
;
1485 this->public.interface
.get_source_addr
= (host_t
*(*)(kernel_net_t
*, host_t
*dest
, host_t
*src
))get_source_addr
;
1486 this->public.interface
.get_nexthop
= (host_t
*(*)(kernel_net_t
*, host_t
*dest
))get_nexthop
;
1487 this->public.interface
.add_ip
= (status_t(*)(kernel_net_t
*,host_t
*,host_t
*)) add_ip
;
1488 this->public.interface
.del_ip
= (status_t(*)(kernel_net_t
*,host_t
*)) del_ip
;
1489 this->public.interface
.add_route
= (status_t(*)(kernel_net_t
*,chunk_t
,u_int8_t
,host_t
*,host_t
*,char*)) add_route
;
1490 this->public.interface
.del_route
= (status_t(*)(kernel_net_t
*,chunk_t
,u_int8_t
,host_t
*,host_t
*,char*)) del_route
;
1491 this->public.interface
.destroy
= (void(*)(kernel_net_t
*)) destroy
;
1493 /* private members */
1494 this->ifaces
= linked_list_create();
1495 this->mutex
= mutex_create(MUTEX_TYPE_RECURSIVE
);
1496 this->condvar
= condvar_create(CONDVAR_TYPE_DEFAULT
);
1497 timerclear(&this->last_roam
);
1498 this->routing_table
= lib
->settings
->get_int(lib
->settings
,
1499 "%s.routing_table", ROUTING_TABLE
, hydra
->daemon
);
1500 this->routing_table_prio
= lib
->settings
->get_int(lib
->settings
,
1501 "%s.routing_table_prio", ROUTING_TABLE_PRIO
, hydra
->daemon
);
1502 this->process_route
= lib
->settings
->get_bool(lib
->settings
,
1503 "%s.process_route", TRUE
, hydra
->daemon
);
1504 this->install_virtual_ip
= lib
->settings
->get_bool(lib
->settings
,
1505 "%s.install_virtual_ip", TRUE
, hydra
->daemon
);
1507 this->rt_exclude
= linked_list_create();
1508 exclude
= lib
->settings
->get_str(lib
->settings
,
1509 "%s.ignore_routing_tables", NULL
, hydra
->daemon
);
1515 enumerator
= enumerator_create_token(exclude
, " ", " ");
1516 while (enumerator
->enumerate(enumerator
, &token
))
1519 table
= strtoul(token
, NULL
, 10);
1523 this->rt_exclude
->insert_last(this->rt_exclude
, (void*)table
);
1526 enumerator
->destroy(enumerator
);
1529 this->socket
= netlink_socket_create(NETLINK_ROUTE
);
1532 memset(&addr
, 0, sizeof(addr
));
1533 addr
.nl_family
= AF_NETLINK
;
1535 /* create and bind RT socket for events (address/interface/route changes) */
1536 this->socket_events
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
1537 if (this->socket_events
< 0)
1539 DBG1(DBG_KNL
, "unable to create RT event socket");
1543 addr
.nl_groups
= RTMGRP_IPV4_IFADDR
| RTMGRP_IPV6_IFADDR
|
1544 RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_ROUTE
| RTMGRP_LINK
;
1545 if (bind(this->socket_events
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1547 DBG1(DBG_KNL
, "unable to bind RT event socket");
1552 this->job
= callback_job_create((callback_job_cb_t
)receive_events
,
1554 lib
->processor
->queue_job(lib
->processor
, (job_t
*)this->job
);
1556 if (init_address_list(this) != SUCCESS
)
1558 DBG1(DBG_KNL
, "unable to get interface list");
1563 if (this->routing_table
)
1565 if (manage_rule(this, RTM_NEWRULE
, AF_INET
, this->routing_table
,
1566 this->routing_table_prio
) != SUCCESS
)
1568 DBG1(DBG_KNL
, "unable to create IPv4 routing table rule");
1570 if (manage_rule(this, RTM_NEWRULE
, AF_INET6
, this->routing_table
,
1571 this->routing_table_prio
) != SUCCESS
)
1573 DBG1(DBG_KNL
, "unable to create IPv6 routing table rule");
1577 return &this->public;