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 enumerator_t
*ifaces
, *addrs
;
197 iface_entry_t
*iface
;
201 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
202 while (ifaces
->enumerate(ifaces
, (void**)&iface
))
204 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
205 while (addrs
->enumerate(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 strncpy(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
)
538 host
= host_create_from_chunk(msg
->rtm_family
,
539 chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
)), 0);
542 if (RTA_PAYLOAD(rta
) == sizeof(rta_oif
))
544 rta_oif
= *(u_int32_t
*)RTA_DATA(rta
);
548 rta
= RTA_NEXT(rta
, rtasize
);
550 if (!host
&& rta_oif
)
552 host
= get_interface_address(this, rta_oif
, msg
->rtm_family
);
556 this->mutex
->lock(this->mutex
);
557 if (!get_vip_refcount(this, host
))
558 { /* ignore routes added for virtual IPs */
559 fire_roam_event(this, FALSE
);
561 this->mutex
->unlock(this->mutex
);
567 * Receives events from kernel
569 static job_requeue_t
receive_events(private_kernel_netlink_net_t
*this)
572 struct nlmsghdr
*hdr
= (struct nlmsghdr
*)response
;
573 struct sockaddr_nl addr
;
574 socklen_t addr_len
= sizeof(addr
);
578 oldstate
= thread_cancelability(TRUE
);
579 len
= recvfrom(this->socket_events
, response
, sizeof(response
), 0,
580 (struct sockaddr
*)&addr
, &addr_len
);
581 thread_cancelability(oldstate
);
588 /* interrupted, try again */
589 return JOB_REQUEUE_DIRECT
;
591 /* no data ready, select again */
592 return JOB_REQUEUE_DIRECT
;
594 DBG1(DBG_KNL
, "unable to receive from rt event socket");
596 return JOB_REQUEUE_FAIR
;
600 if (addr
.nl_pid
!= 0)
601 { /* not from kernel. not interested, try another one */
602 return JOB_REQUEUE_DIRECT
;
605 while (NLMSG_OK(hdr
, len
))
607 /* looks good so far, dispatch netlink message */
608 switch (hdr
->nlmsg_type
)
612 process_addr(this, hdr
, TRUE
);
613 this->condvar
->broadcast(this->condvar
);
617 process_link(this, hdr
, TRUE
);
618 this->condvar
->broadcast(this->condvar
);
622 if (this->process_route
)
624 process_route(this, hdr
);
630 hdr
= NLMSG_NEXT(hdr
, len
);
632 return JOB_REQUEUE_DIRECT
;
635 /** enumerator over addresses */
637 private_kernel_netlink_net_t
* this;
638 /** whether to enumerate down interfaces */
639 bool include_down_ifaces
;
640 /** whether to enumerate virtual ip addresses */
641 bool include_virtual_ips
;
642 } address_enumerator_t
;
645 * cleanup function for address enumerator
647 static void address_enumerator_destroy(address_enumerator_t
*data
)
649 data
->this->mutex
->unlock(data
->this->mutex
);
654 * filter for addresses
656 static bool filter_addresses(address_enumerator_t
*data
,
657 addr_entry_t
** in
, host_t
** out
)
659 if (!data
->include_virtual_ips
&& (*in
)->virtual)
660 { /* skip virtual interfaces added by us */
663 if ((*in
)->scope
>= RT_SCOPE_LINK
)
664 { /* skip addresses with a unusable scope */
672 * enumerator constructor for interfaces
674 static enumerator_t
*create_iface_enumerator(iface_entry_t
*iface
,
675 address_enumerator_t
*data
)
677 return enumerator_create_filter(
678 iface
->addrs
->create_enumerator(iface
->addrs
),
679 (void*)filter_addresses
, data
, NULL
);
683 * filter for interfaces
685 static bool filter_interfaces(address_enumerator_t
*data
, iface_entry_t
** in
,
688 if (!data
->include_down_ifaces
&& !((*in
)->flags
& IFF_UP
))
689 { /* skip interfaces not up */
696 METHOD(kernel_net_t
, create_address_enumerator
, enumerator_t
*,
697 private_kernel_netlink_net_t
*this,
698 bool include_down_ifaces
, bool include_virtual_ips
)
700 address_enumerator_t
*data
= malloc_thing(address_enumerator_t
);
702 data
->include_down_ifaces
= include_down_ifaces
;
703 data
->include_virtual_ips
= include_virtual_ips
;
705 this->mutex
->lock(this->mutex
);
706 return enumerator_create_nested(
707 enumerator_create_filter(
708 this->ifaces
->create_enumerator(this->ifaces
),
709 (void*)filter_interfaces
, data
, NULL
),
710 (void*)create_iface_enumerator
, data
,
711 (void*)address_enumerator_destroy
);
714 METHOD(kernel_net_t
, get_interface_name
, char*,
715 private_kernel_netlink_net_t
*this, host_t
* ip
)
717 enumerator_t
*ifaces
, *addrs
;
718 iface_entry_t
*iface
;
722 DBG2(DBG_KNL
, "getting interface name for %H", ip
);
724 this->mutex
->lock(this->mutex
);
725 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
726 while (ifaces
->enumerate(ifaces
, &iface
))
728 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
729 while (addrs
->enumerate(addrs
, &addr
))
731 if (ip
->ip_equals(ip
, addr
->ip
))
733 name
= strdup(iface
->ifname
);
737 addrs
->destroy(addrs
);
743 ifaces
->destroy(ifaces
);
744 this->mutex
->unlock(this->mutex
);
748 DBG2(DBG_KNL
, "%H is on interface %s", ip
, name
);
752 DBG2(DBG_KNL
, "%H is not a local address", ip
);
758 * get the index of an interface by name
760 static int get_interface_index(private_kernel_netlink_net_t
*this, char* name
)
762 enumerator_t
*ifaces
;
763 iface_entry_t
*iface
;
766 DBG2(DBG_KNL
, "getting iface index for %s", name
);
768 this->mutex
->lock(this->mutex
);
769 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
770 while (ifaces
->enumerate(ifaces
, &iface
))
772 if (streq(name
, iface
->ifname
))
774 ifindex
= iface
->ifindex
;
778 ifaces
->destroy(ifaces
);
779 this->mutex
->unlock(this->mutex
);
783 DBG1(DBG_KNL
, "unable to get interface index for %s", name
);
789 * Check if an interface with a given index is up
791 static bool is_interface_up(private_kernel_netlink_net_t
*this, int index
)
793 enumerator_t
*ifaces
;
794 iface_entry_t
*iface
;
795 /* default to TRUE for interface we do not monitor (e.g. lo) */
798 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
799 while (ifaces
->enumerate(ifaces
, &iface
))
801 if (iface
->ifindex
== index
)
803 up
= iface
->flags
& IFF_UP
;
807 ifaces
->destroy(ifaces
);
812 * check if an address (chunk) addr is in subnet (net with net_len net bits)
814 static bool addr_in_subnet(chunk_t addr
, chunk_t net
, int net_len
)
816 static const u_char mask
[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
820 { /* any address matches a /0 network */
823 if (addr
.len
!= net
.len
|| net_len
> 8 * net
.len
)
827 /* scan through all bytes in network order */
832 return (mask
[net_len
] & addr
.ptr
[byte
]) == (mask
[net_len
] & net
.ptr
[byte
]);
836 if (addr
.ptr
[byte
] != net
.ptr
[byte
])
848 * Get a route: If "nexthop", the nexthop is returned. source addr otherwise.
850 static host_t
*get_route(private_kernel_netlink_net_t
*this, host_t
*dest
,
851 bool nexthop
, host_t
*candidate
)
853 netlink_buf_t request
;
854 struct nlmsghdr
*hdr
, *out
, *current
;
859 enumerator_t
*enumerator
;
860 host_t
*src
= NULL
, *gtw
= NULL
;
862 DBG2(DBG_KNL
, "getting address to reach %H", dest
);
864 memset(&request
, 0, sizeof(request
));
866 hdr
= (struct nlmsghdr
*)request
;
867 hdr
->nlmsg_flags
= NLM_F_REQUEST
;
868 if (dest
->get_family(dest
) == AF_INET
)
870 /* We dump all addresses for IPv4, as we want to ignore IPsec specific
871 * routes installed by us. But the kernel does not return source
872 * addresses in a IPv6 dump, so fall back to get() for v6 routes. */
873 hdr
->nlmsg_flags
|= NLM_F_ROOT
| NLM_F_DUMP
;
875 hdr
->nlmsg_type
= RTM_GETROUTE
;
876 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
878 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
879 msg
->rtm_family
= dest
->get_family(dest
);
882 chunk
= candidate
->get_address(candidate
);
883 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
885 chunk
= dest
->get_address(dest
);
886 netlink_add_attribute(hdr
, RTA_DST
, chunk
, sizeof(request
));
888 if (this->socket
->send(this->socket
, hdr
, &out
, &len
) != SUCCESS
)
890 DBG1(DBG_KNL
, "getting address to %H failed", dest
);
893 this->mutex
->lock(this->mutex
);
895 for (current
= out
; NLMSG_OK(current
, len
);
896 current
= NLMSG_NEXT(current
, len
))
898 switch (current
->nlmsg_type
)
906 chunk_t rta_gtw
, rta_src
, rta_dst
;
907 u_int32_t rta_oif
= 0, rta_table
;
908 host_t
*new_src
, *new_gtw
;
912 rta_gtw
= rta_src
= rta_dst
= chunk_empty
;
913 msg
= (struct rtmsg
*)(NLMSG_DATA(current
));
915 rtasize
= RTM_PAYLOAD(current
);
916 rta_table
= msg
->rtm_table
;
917 while (RTA_OK(rta
, rtasize
))
919 switch (rta
->rta_type
)
922 rta_src
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
925 rta_gtw
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
928 rta_dst
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
931 if (RTA_PAYLOAD(rta
) == sizeof(rta_oif
))
933 rta_oif
= *(u_int32_t
*)RTA_DATA(rta
);
937 if (RTA_PAYLOAD(rta
) == sizeof(rta_table
))
939 rta_table
= *(u_int32_t
*)RTA_DATA(rta
);
943 rta
= RTA_NEXT(rta
, rtasize
);
945 if (msg
->rtm_dst_len
<= best
)
946 { /* not better than a previous one */
949 enumerator
= this->rt_exclude
->create_enumerator(this->rt_exclude
);
950 while (enumerator
->enumerate(enumerator
, &table
))
952 if (table
== rta_table
)
958 enumerator
->destroy(enumerator
);
963 if (this->routing_table
!= 0 &&
964 rta_table
== this->routing_table
)
965 { /* route is from our own ipsec routing table */
968 if (rta_oif
&& !is_interface_up(this, rta_oif
))
969 { /* interface is down */
972 if (!addr_in_subnet(chunk
, rta_dst
, msg
->rtm_dst_len
))
973 { /* route destination does not contain dest */
979 /* nexthop lookup, return gateway if any */
981 gtw
= host_create_from_chunk(msg
->rtm_family
, rta_gtw
, 0);
982 best
= msg
->rtm_dst_len
;
986 { /* got a source address */
987 new_src
= host_create_from_chunk(msg
->rtm_family
, rta_src
, 0);
990 if (get_vip_refcount(this, new_src
))
991 { /* skip source address if it is installed by us */
992 new_src
->destroy(new_src
);
998 best
= msg
->rtm_dst_len
;
1004 { /* no src or gtw, but an interface. Get address from it. */
1005 new_src
= get_interface_address(this, rta_oif
,
1011 best
= msg
->rtm_dst_len
;
1016 { /* no source, but a gateway. Lookup source to reach gtw. */
1017 new_gtw
= host_create_from_chunk(msg
->rtm_family
, rta_gtw
, 0);
1018 new_src
= get_route(this, new_gtw
, FALSE
, candidate
);
1019 new_gtw
->destroy(new_gtw
);
1024 best
= msg
->rtm_dst_len
;
1036 this->mutex
->unlock(this->mutex
);
1044 return dest
->clone(dest
);
1049 METHOD(kernel_net_t
, get_source_addr
, host_t
*,
1050 private_kernel_netlink_net_t
*this, host_t
*dest
, host_t
*src
)
1052 return get_route(this, dest
, FALSE
, src
);
1055 METHOD(kernel_net_t
, get_nexthop
, host_t
*,
1056 private_kernel_netlink_net_t
*this, host_t
*dest
)
1058 return get_route(this, dest
, TRUE
, NULL
);
1062 * Manages the creation and deletion of ip addresses on an interface.
1063 * By setting the appropriate nlmsg_type, the ip will be set or unset.
1065 static status_t
manage_ipaddr(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1066 int flags
, int if_index
, host_t
*ip
)
1068 netlink_buf_t request
;
1069 struct nlmsghdr
*hdr
;
1070 struct ifaddrmsg
*msg
;
1073 memset(&request
, 0, sizeof(request
));
1075 chunk
= ip
->get_address(ip
);
1077 hdr
= (struct nlmsghdr
*)request
;
1078 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1079 hdr
->nlmsg_type
= nlmsg_type
;
1080 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1082 msg
= (struct ifaddrmsg
*)NLMSG_DATA(hdr
);
1083 msg
->ifa_family
= ip
->get_family(ip
);
1085 msg
->ifa_prefixlen
= 8 * chunk
.len
;
1086 msg
->ifa_scope
= RT_SCOPE_UNIVERSE
;
1087 msg
->ifa_index
= if_index
;
1089 netlink_add_attribute(hdr
, IFA_LOCAL
, chunk
, sizeof(request
));
1091 return this->socket
->send_ack(this->socket
, hdr
);
1094 METHOD(kernel_net_t
, add_ip
, status_t
,
1095 private_kernel_netlink_net_t
*this, host_t
*virtual_ip
, host_t
*iface_ip
)
1097 iface_entry_t
*iface
;
1099 enumerator_t
*addrs
, *ifaces
;
1102 if (!this->install_virtual_ip
)
1103 { /* disabled by config */
1107 DBG2(DBG_KNL
, "adding virtual IP %H", virtual_ip
);
1109 this->mutex
->lock(this->mutex
);
1110 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1111 while (ifaces
->enumerate(ifaces
, &iface
))
1113 bool iface_found
= FALSE
;
1115 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1116 while (addrs
->enumerate(addrs
, &addr
))
1118 if (iface_ip
->ip_equals(iface_ip
, addr
->ip
))
1122 else if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1125 DBG2(DBG_KNL
, "virtual IP %H already installed on %s",
1126 virtual_ip
, iface
->ifname
);
1127 addrs
->destroy(addrs
);
1128 ifaces
->destroy(ifaces
);
1129 this->mutex
->unlock(this->mutex
);
1133 addrs
->destroy(addrs
);
1137 ifindex
= iface
->ifindex
;
1138 addr
= malloc_thing(addr_entry_t
);
1139 addr
->ip
= virtual_ip
->clone(virtual_ip
);
1141 addr
->virtual = TRUE
;
1142 addr
->scope
= RT_SCOPE_UNIVERSE
;
1143 iface
->addrs
->insert_last(iface
->addrs
, addr
);
1145 if (manage_ipaddr(this, RTM_NEWADDR
, NLM_F_CREATE
| NLM_F_EXCL
,
1146 ifindex
, virtual_ip
) == SUCCESS
)
1148 while (get_vip_refcount(this, virtual_ip
) == 0)
1149 { /* wait until address appears */
1150 this->condvar
->wait(this->condvar
, this->mutex
);
1152 ifaces
->destroy(ifaces
);
1153 this->mutex
->unlock(this->mutex
);
1156 ifaces
->destroy(ifaces
);
1157 this->mutex
->unlock(this->mutex
);
1158 DBG1(DBG_KNL
, "adding virtual IP %H failed", virtual_ip
);
1162 ifaces
->destroy(ifaces
);
1163 this->mutex
->unlock(this->mutex
);
1165 DBG1(DBG_KNL
, "interface address %H not found, unable to install"
1166 "virtual IP %H", iface_ip
, virtual_ip
);
1170 METHOD(kernel_net_t
, del_ip
, status_t
,
1171 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
);
1299 METHOD(kernel_net_t
, add_route
, status_t
,
1300 private_kernel_netlink_net_t
*this, chunk_t dst_net
, u_int8_t prefixlen
,
1301 host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1303 return manage_srcroute(this, RTM_NEWROUTE
, NLM_F_CREATE
| NLM_F_EXCL
,
1304 dst_net
, prefixlen
, gateway
, src_ip
, if_name
);
1307 METHOD(kernel_net_t
, del_route
, status_t
,
1308 private_kernel_netlink_net_t
*this, chunk_t dst_net
, u_int8_t prefixlen
,
1309 host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1311 return manage_srcroute(this, RTM_DELROUTE
, 0, dst_net
, prefixlen
,
1312 gateway
, src_ip
, if_name
);
1316 * Initialize a list of local addresses.
1318 static status_t
init_address_list(private_kernel_netlink_net_t
*this)
1320 netlink_buf_t request
;
1321 struct nlmsghdr
*out
, *current
, *in
;
1322 struct rtgenmsg
*msg
;
1324 enumerator_t
*ifaces
, *addrs
;
1325 iface_entry_t
*iface
;
1328 DBG1(DBG_KNL
, "listening on interfaces:");
1330 memset(&request
, 0, sizeof(request
));
1332 in
= (struct nlmsghdr
*)&request
;
1333 in
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtgenmsg
));
1334 in
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_MATCH
| NLM_F_ROOT
;
1335 msg
= (struct rtgenmsg
*)NLMSG_DATA(in
);
1336 msg
->rtgen_family
= AF_UNSPEC
;
1339 in
->nlmsg_type
= RTM_GETLINK
;
1340 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1345 while (NLMSG_OK(current
, len
))
1347 switch (current
->nlmsg_type
)
1352 process_link(this, current
, FALSE
);
1355 current
= NLMSG_NEXT(current
, len
);
1362 /* get all interface addresses */
1363 in
->nlmsg_type
= RTM_GETADDR
;
1364 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1369 while (NLMSG_OK(current
, len
))
1371 switch (current
->nlmsg_type
)
1376 process_addr(this, current
, FALSE
);
1379 current
= NLMSG_NEXT(current
, len
);
1386 this->mutex
->lock(this->mutex
);
1387 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1388 while (ifaces
->enumerate(ifaces
, &iface
))
1390 if (iface
->flags
& IFF_UP
)
1392 DBG1(DBG_KNL
, " %s", iface
->ifname
);
1393 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1394 while (addrs
->enumerate(addrs
, (void**)&addr
))
1396 DBG1(DBG_KNL
, " %H", addr
->ip
);
1398 addrs
->destroy(addrs
);
1401 ifaces
->destroy(ifaces
);
1402 this->mutex
->unlock(this->mutex
);
1407 * create or delete a rule to use our routing table
1409 static status_t
manage_rule(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1410 int family
, u_int32_t table
, u_int32_t prio
)
1412 netlink_buf_t request
;
1413 struct nlmsghdr
*hdr
;
1417 memset(&request
, 0, sizeof(request
));
1418 hdr
= (struct nlmsghdr
*)request
;
1419 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1420 hdr
->nlmsg_type
= nlmsg_type
;
1421 if (nlmsg_type
== RTM_NEWRULE
)
1423 hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
1425 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1427 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1428 msg
->rtm_table
= table
;
1429 msg
->rtm_family
= family
;
1430 msg
->rtm_protocol
= RTPROT_BOOT
;
1431 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1432 msg
->rtm_type
= RTN_UNICAST
;
1434 chunk
= chunk_from_thing(prio
);
1435 netlink_add_attribute(hdr
, RTA_PRIORITY
, chunk
, sizeof(request
));
1437 return this->socket
->send_ack(this->socket
, hdr
);
1440 METHOD(kernel_net_t
, destroy
, void,
1441 private_kernel_netlink_net_t
*this)
1443 if (this->routing_table
)
1445 manage_rule(this, RTM_DELRULE
, AF_INET
, this->routing_table
,
1446 this->routing_table_prio
);
1447 manage_rule(this, RTM_DELRULE
, AF_INET6
, this->routing_table
,
1448 this->routing_table_prio
);
1452 this->job
->cancel(this->job
);
1454 if (this->socket_events
> 0)
1456 close(this->socket_events
);
1458 DESTROY_IF(this->socket
);
1459 this->ifaces
->destroy_function(this->ifaces
, (void*)iface_entry_destroy
);
1460 this->rt_exclude
->destroy(this->rt_exclude
);
1461 this->condvar
->destroy(this->condvar
);
1462 this->mutex
->destroy(this->mutex
);
1467 * Described in header.
1469 kernel_netlink_net_t
*kernel_netlink_net_create()
1471 private_kernel_netlink_net_t
*this;
1472 struct sockaddr_nl addr
;
1473 enumerator_t
*enumerator
;
1479 .get_interface
= _get_interface_name
,
1480 .create_address_enumerator
= _create_address_enumerator
,
1481 .get_source_addr
= _get_source_addr
,
1482 .get_nexthop
= _get_nexthop
,
1485 .add_route
= _add_route
,
1486 .del_route
= _del_route
,
1487 .destroy
= _destroy
,
1490 .socket
= netlink_socket_create(NETLINK_ROUTE
),
1491 .rt_exclude
= linked_list_create(),
1492 .ifaces
= linked_list_create(),
1493 .mutex
= mutex_create(MUTEX_TYPE_RECURSIVE
),
1494 .condvar
= condvar_create(CONDVAR_TYPE_DEFAULT
),
1495 .routing_table
= lib
->settings
->get_int(lib
->settings
,
1496 "%s.routing_table", ROUTING_TABLE
, hydra
->daemon
),
1497 .routing_table_prio
= lib
->settings
->get_int(lib
->settings
,
1498 "%s.routing_table_prio", ROUTING_TABLE_PRIO
, hydra
->daemon
),
1499 .process_route
= lib
->settings
->get_bool(lib
->settings
,
1500 "%s.process_route", TRUE
, hydra
->daemon
),
1501 .install_virtual_ip
= lib
->settings
->get_bool(lib
->settings
,
1502 "%s.install_virtual_ip", TRUE
, hydra
->daemon
),
1504 timerclear(&this->last_roam
);
1506 exclude
= lib
->settings
->get_str(lib
->settings
,
1507 "%s.ignore_routing_tables", NULL
, hydra
->daemon
);
1513 enumerator
= enumerator_create_token(exclude
, " ", " ");
1514 while (enumerator
->enumerate(enumerator
, &token
))
1517 table
= strtoul(token
, NULL
, 10);
1521 this->rt_exclude
->insert_last(this->rt_exclude
, (void*)table
);
1524 enumerator
->destroy(enumerator
);
1527 memset(&addr
, 0, sizeof(addr
));
1528 addr
.nl_family
= AF_NETLINK
;
1530 /* create and bind RT socket for events (address/interface/route changes) */
1531 this->socket_events
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
1532 if (this->socket_events
< 0)
1534 DBG1(DBG_KNL
, "unable to create RT event socket");
1538 addr
.nl_groups
= RTMGRP_IPV4_IFADDR
| RTMGRP_IPV6_IFADDR
|
1539 RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_ROUTE
| RTMGRP_LINK
;
1540 if (bind(this->socket_events
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1542 DBG1(DBG_KNL
, "unable to bind RT event socket");
1547 this->job
= callback_job_create_with_prio((callback_job_cb_t
)receive_events
,
1548 this, NULL
, NULL
, JOB_PRIO_CRITICAL
);
1549 lib
->processor
->queue_job(lib
->processor
, (job_t
*)this->job
);
1551 if (init_address_list(this) != SUCCESS
)
1553 DBG1(DBG_KNL
, "unable to get interface list");
1558 if (this->routing_table
)
1560 if (manage_rule(this, RTM_NEWRULE
, AF_INET
, this->routing_table
,
1561 this->routing_table_prio
) != SUCCESS
)
1563 DBG1(DBG_KNL
, "unable to create IPv4 routing table rule");
1565 if (manage_rule(this, RTM_NEWRULE
, AF_INET6
, this->routing_table
,
1566 this->routing_table_prio
) != SUCCESS
)
1568 DBG1(DBG_KNL
, "unable to create IPv6 routing table rule");
1572 return &this->public;