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
19 #include <sys/socket.h>
20 #include <linux/netlink.h>
21 #include <linux/rtnetlink.h>
28 #include "kernel_netlink_net.h"
29 #include "kernel_netlink_shared.h"
32 #include <utils/mutex.h>
33 #include <utils/linked_list.h>
34 #include <processing/jobs/callback_job.h>
35 #include <processing/jobs/roam_job.h>
37 /** delay before firing roam jobs (ms) */
38 #define ROAM_DELAY 100
40 /** routing table for routes installed by us */
41 #ifndef IPSEC_ROUTING_TABLE
42 #define IPSEC_ROUTING_TABLE 100
44 #ifndef IPSEC_ROUTING_TABLE_PRIO
45 #define IPSEC_ROUTING_TABLE_PRIO 100
48 typedef struct addr_entry_t addr_entry_t
;
51 * IP address in an inface_entry_t
58 /** virtual IP managed by us */
61 /** scope of the address */
64 /** Number of times this IP is used, if virtual */
69 * destroy a addr_entry_t object
71 static void addr_entry_destroy(addr_entry_t
*this)
73 this->ip
->destroy(this->ip
);
77 typedef struct iface_entry_t iface_entry_t
;
80 * A network interface on this system, containing addr_entry_t's
82 struct iface_entry_t
{
84 /** interface index */
87 /** name of the interface */
88 char ifname
[IFNAMSIZ
];
90 /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
93 /** list of addresses as host_t */
98 * destroy an interface entry
100 static void iface_entry_destroy(iface_entry_t
*this)
102 this->addrs
->destroy_function(this->addrs
, (void*)addr_entry_destroy
);
106 typedef struct private_kernel_netlink_net_t private_kernel_netlink_net_t
;
109 * Private variables and functions of kernel_netlink_net class.
111 struct private_kernel_netlink_net_t
{
113 * Public part of the kernel_netlink_net_t object.
115 kernel_netlink_net_t
public;
118 * mutex to lock access to various lists
123 * condition variable to signal virtual IP add/removal
128 * Cached list of interfaces and its addresses (iface_entry_t)
130 linked_list_t
*ifaces
;
133 * job receiving netlink events
138 * netlink rt socket (routing)
140 netlink_socket_t
*socket
;
143 * Netlink rt socket to receive address change events
148 * time of the last roam_job
150 struct timeval last_roam
;
153 * routing table to install routes
158 * priority of used routing table
160 int routing_table_prio
;
163 * whether to react to RTM_NEWROUTE or RTM_DELROUTE events
170 * get the refcount of a virtual ip
172 static int get_vip_refcount(private_kernel_netlink_net_t
*this, host_t
* ip
)
174 iterator_t
*ifaces
, *addrs
;
175 iface_entry_t
*iface
;
179 ifaces
= this->ifaces
->create_iterator(this->ifaces
, TRUE
);
180 while (ifaces
->iterate(ifaces
, (void**)&iface
))
182 addrs
= iface
->addrs
->create_iterator(iface
->addrs
, TRUE
);
183 while (addrs
->iterate(addrs
, (void**)&addr
))
185 if (addr
->virtual && (iface
->flags
& IFF_UP
) &&
186 ip
->ip_equals(ip
, addr
->ip
))
188 refcount
= addr
->refcount
;
192 addrs
->destroy(addrs
);
198 ifaces
->destroy(ifaces
);
204 * start a roaming job. We delay it for a second and fire only one job
205 * for multiple events. Otherwise we would create two many jobs.
207 static void fire_roam_job(private_kernel_netlink_net_t
*this, bool address
)
211 if (gettimeofday(&now
, NULL
) == 0)
213 if (timercmp(&now
, &this->last_roam
, >))
215 now
.tv_usec
+= ROAM_DELAY
* 1000;
216 while (now
.tv_usec
> 1000000)
219 now
.tv_usec
-= 1000000;
221 this->last_roam
= now
;
222 charon
->scheduler
->schedule_job(charon
->scheduler
,
223 (job_t
*)roam_job_create(address
), ROAM_DELAY
);
229 * process RTM_NEWLINK/RTM_DELLINK from kernel
231 static void process_link(private_kernel_netlink_net_t
*this,
232 struct nlmsghdr
*hdr
, bool event
)
234 struct ifinfomsg
* msg
= (struct ifinfomsg
*)(NLMSG_DATA(hdr
));
235 struct rtattr
*rta
= IFLA_RTA(msg
);
236 size_t rtasize
= IFLA_PAYLOAD (hdr
);
237 enumerator_t
*enumerator
;
238 iface_entry_t
*current
, *entry
= NULL
;
242 while(RTA_OK(rta
, rtasize
))
244 switch (rta
->rta_type
)
247 name
= RTA_DATA(rta
);
250 rta
= RTA_NEXT(rta
, rtasize
);
257 this->mutex
->lock(this->mutex
);
258 switch (hdr
->nlmsg_type
)
262 if (msg
->ifi_flags
& IFF_LOOPBACK
)
263 { /* ignore loopback interfaces */
266 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
267 while (enumerator
->enumerate(enumerator
, ¤t
))
269 if (current
->ifindex
== msg
->ifi_index
)
275 enumerator
->destroy(enumerator
);
278 entry
= malloc_thing(iface_entry_t
);
279 entry
->ifindex
= msg
->ifi_index
;
281 entry
->addrs
= linked_list_create();
282 this->ifaces
->insert_last(this->ifaces
, entry
);
284 memcpy(entry
->ifname
, name
, IFNAMSIZ
);
285 entry
->ifname
[IFNAMSIZ
-1] = '\0';
288 if (!(entry
->flags
& IFF_UP
) && (msg
->ifi_flags
& IFF_UP
))
291 DBG1(DBG_KNL
, "interface %s activated", name
);
293 if ((entry
->flags
& IFF_UP
) && !(msg
->ifi_flags
& IFF_UP
))
296 DBG1(DBG_KNL
, "interface %s deactivated", name
);
299 entry
->flags
= msg
->ifi_flags
;
304 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
305 while (enumerator
->enumerate(enumerator
, ¤t
))
307 if (current
->ifindex
== msg
->ifi_index
)
309 /* we do not remove it, as an address may be added to a
310 * "down" interface and we wan't to know that. */
311 current
->flags
= msg
->ifi_flags
;
315 enumerator
->destroy(enumerator
);
319 this->mutex
->unlock(this->mutex
);
321 /* send an update to all IKE_SAs */
324 fire_roam_job(this, TRUE
);
329 * process RTM_NEWADDR/RTM_DELADDR from kernel
331 static void process_addr(private_kernel_netlink_net_t
*this,
332 struct nlmsghdr
*hdr
, bool event
)
334 struct ifaddrmsg
* msg
= (struct ifaddrmsg
*)(NLMSG_DATA(hdr
));
335 struct rtattr
*rta
= IFA_RTA(msg
);
336 size_t rtasize
= IFA_PAYLOAD (hdr
);
338 enumerator_t
*ifaces
, *addrs
;
339 iface_entry_t
*iface
;
341 chunk_t local
= chunk_empty
, address
= chunk_empty
;
342 bool update
= FALSE
, found
= FALSE
, changed
= FALSE
;
344 while(RTA_OK(rta
, rtasize
))
346 switch (rta
->rta_type
)
349 local
.ptr
= RTA_DATA(rta
);
350 local
.len
= RTA_PAYLOAD(rta
);
353 address
.ptr
= RTA_DATA(rta
);
354 address
.len
= RTA_PAYLOAD(rta
);
357 rta
= RTA_NEXT(rta
, rtasize
);
360 /* For PPP interfaces, we need the IFA_LOCAL address,
361 * IFA_ADDRESS is the peers address. But IFA_LOCAL is
362 * not included in all cases (IPv6?), so fallback to IFA_ADDRESS. */
365 host
= host_create_from_chunk(msg
->ifa_family
, local
, 0);
367 else if (address
.ptr
)
369 host
= host_create_from_chunk(msg
->ifa_family
, address
, 0);
377 this->mutex
->lock(this->mutex
);
378 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
379 while (ifaces
->enumerate(ifaces
, &iface
))
381 if (iface
->ifindex
== msg
->ifa_index
)
383 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
384 while (addrs
->enumerate(addrs
, &addr
))
386 if (host
->ip_equals(host
, addr
->ip
))
389 if (hdr
->nlmsg_type
== RTM_DELADDR
)
391 iface
->addrs
->remove_at(iface
->addrs
, addrs
);
395 DBG1(DBG_KNL
, "%H disappeared from %s",
396 host
, iface
->ifname
);
398 addr_entry_destroy(addr
);
400 else if (hdr
->nlmsg_type
== RTM_NEWADDR
&& addr
->virtual)
406 addrs
->destroy(addrs
);
408 if (hdr
->nlmsg_type
== RTM_NEWADDR
)
414 addr
= malloc_thing(addr_entry_t
);
415 addr
->ip
= host
->clone(host
);
416 addr
->virtual = FALSE
;
418 addr
->scope
= msg
->ifa_scope
;
420 iface
->addrs
->insert_last(iface
->addrs
, addr
);
423 DBG1(DBG_KNL
, "%H appeared on %s", host
, iface
->ifname
);
427 if (found
&& (iface
->flags
& IFF_UP
))
434 ifaces
->destroy(ifaces
);
435 this->mutex
->unlock(this->mutex
);
438 /* send an update to all IKE_SAs */
439 if (update
&& event
&& changed
)
441 fire_roam_job(this, TRUE
);
446 * process RTM_NEWROUTE and RTM_DELROUTE from kernel
448 static void process_route(private_kernel_netlink_net_t
*this, struct nlmsghdr
*hdr
)
450 struct rtmsg
* msg
= (struct rtmsg
*)(NLMSG_DATA(hdr
));
451 struct rtattr
*rta
= RTM_RTA(msg
);
452 size_t rtasize
= RTM_PAYLOAD(hdr
);
455 /* ignore routes added by us */
456 if (msg
->rtm_table
&& msg
->rtm_table
== this->routing_table
)
461 while (RTA_OK(rta
, rtasize
))
463 switch (rta
->rta_type
)
466 host
= host_create_from_chunk(msg
->rtm_family
,
467 chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
)), 0);
470 rta
= RTA_NEXT(rta
, rtasize
);
474 this->mutex
->lock(this->mutex
);
475 if (!get_vip_refcount(this, host
))
476 { /* ignore routes added for virtual IPs */
477 fire_roam_job(this, FALSE
);
479 this->mutex
->unlock(this->mutex
);
485 * Receives events from kernel
487 static job_requeue_t
receive_events(private_kernel_netlink_net_t
*this)
490 struct nlmsghdr
*hdr
= (struct nlmsghdr
*)response
;
491 struct sockaddr_nl addr
;
492 socklen_t addr_len
= sizeof(addr
);
495 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, &oldstate
);
496 len
= recvfrom(this->socket_events
, response
, sizeof(response
), 0,
497 (struct sockaddr
*)&addr
, &addr_len
);
498 pthread_setcancelstate(oldstate
, NULL
);
505 /* interrupted, try again */
506 return JOB_REQUEUE_DIRECT
;
508 /* no data ready, select again */
509 return JOB_REQUEUE_DIRECT
;
511 DBG1(DBG_KNL
, "unable to receive from rt event socket");
513 return JOB_REQUEUE_FAIR
;
517 if (addr
.nl_pid
!= 0)
518 { /* not from kernel. not interested, try another one */
519 return JOB_REQUEUE_DIRECT
;
522 while (NLMSG_OK(hdr
, len
))
524 /* looks good so far, dispatch netlink message */
525 switch (hdr
->nlmsg_type
)
529 process_addr(this, hdr
, TRUE
);
530 this->condvar
->broadcast(this->condvar
);
534 process_link(this, hdr
, TRUE
);
535 this->condvar
->broadcast(this->condvar
);
539 if (this->process_route
)
541 process_route(this, hdr
);
547 hdr
= NLMSG_NEXT(hdr
, len
);
549 return JOB_REQUEUE_DIRECT
;
552 /** enumerator over addresses */
554 private_kernel_netlink_net_t
* this;
555 /** whether to enumerate down interfaces */
556 bool include_down_ifaces
;
557 /** whether to enumerate virtual ip addresses */
558 bool include_virtual_ips
;
559 } address_enumerator_t
;
562 * cleanup function for address enumerator
564 static void address_enumerator_destroy(address_enumerator_t
*data
)
566 data
->this->mutex
->unlock(data
->this->mutex
);
571 * filter for addresses
573 static bool filter_addresses(address_enumerator_t
*data
, addr_entry_t
** in
, host_t
** out
)
575 if (!data
->include_virtual_ips
&& (*in
)->virtual)
576 { /* skip virtual interfaces added by us */
579 if ((*in
)->scope
>= RT_SCOPE_LINK
)
580 { /* skip addresses with a unusable scope */
588 * enumerator constructor for interfaces
590 static enumerator_t
*create_iface_enumerator(iface_entry_t
*iface
, address_enumerator_t
*data
)
592 return enumerator_create_filter(iface
->addrs
->create_enumerator(iface
->addrs
),
593 (void*)filter_addresses
, data
, NULL
);
597 * filter for interfaces
599 static bool filter_interfaces(address_enumerator_t
*data
, iface_entry_t
** in
, iface_entry_t
** out
)
601 if (!data
->include_down_ifaces
&& !((*in
)->flags
& IFF_UP
))
602 { /* skip interfaces not up */
610 * implementation of kernel_net_t.create_address_enumerator
612 static enumerator_t
*create_address_enumerator(private_kernel_netlink_net_t
*this,
613 bool include_down_ifaces
, bool include_virtual_ips
)
615 address_enumerator_t
*data
= malloc_thing(address_enumerator_t
);
617 data
->include_down_ifaces
= include_down_ifaces
;
618 data
->include_virtual_ips
= include_virtual_ips
;
620 this->mutex
->lock(this->mutex
);
621 return enumerator_create_nested(
622 enumerator_create_filter(this->ifaces
->create_enumerator(this->ifaces
),
623 (void*)filter_interfaces
, data
, NULL
),
624 (void*)create_iface_enumerator
, data
, (void*)address_enumerator_destroy
);
628 * implementation of kernel_net_t.get_interface_name
630 static char *get_interface_name(private_kernel_netlink_net_t
*this, host_t
* ip
)
632 enumerator_t
*ifaces
, *addrs
;
633 iface_entry_t
*iface
;
637 DBG2(DBG_KNL
, "getting interface name for %H", ip
);
639 this->mutex
->lock(this->mutex
);
640 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
641 while (ifaces
->enumerate(ifaces
, &iface
))
643 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
644 while (addrs
->enumerate(addrs
, &addr
))
646 if (ip
->ip_equals(ip
, addr
->ip
))
648 name
= strdup(iface
->ifname
);
652 addrs
->destroy(addrs
);
658 ifaces
->destroy(ifaces
);
659 this->mutex
->unlock(this->mutex
);
663 DBG2(DBG_KNL
, "%H is on interface %s", ip
, name
);
667 DBG2(DBG_KNL
, "%H is not a local address", ip
);
673 * get the index of an interface by name
675 static int get_interface_index(private_kernel_netlink_net_t
*this, char* name
)
677 enumerator_t
*ifaces
;
678 iface_entry_t
*iface
;
681 DBG2(DBG_KNL
, "getting iface index for %s", name
);
683 this->mutex
->lock(this->mutex
);
684 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
685 while (ifaces
->enumerate(ifaces
, &iface
))
687 if (streq(name
, iface
->ifname
))
689 ifindex
= iface
->ifindex
;
693 ifaces
->destroy(ifaces
);
694 this->mutex
->unlock(this->mutex
);
698 DBG1(DBG_KNL
, "unable to get interface index for %s", name
);
704 * Check if an interface with a given index is up
706 static bool is_interface_up(private_kernel_netlink_net_t
*this, int index
)
708 enumerator_t
*ifaces
;
709 iface_entry_t
*iface
;
712 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
713 while (ifaces
->enumerate(ifaces
, &iface
))
715 if (iface
->ifindex
== index
)
717 up
= iface
->flags
& IFF_UP
;
721 ifaces
->destroy(ifaces
);
726 * check if an address (chunk) addr is in subnet (net with net_len net bits)
728 static bool addr_in_subnet(chunk_t addr
, chunk_t net
, int net_len
)
730 static const u_char mask
[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
733 if (addr
.len
!= net
.len
|| net_len
> 8 * net
.len
)
738 /* scan through all bytes in network order */
743 return (mask
[net_len
] & addr
.ptr
[byte
]) == (mask
[net_len
] & net
.ptr
[byte
]);
747 if (addr
.ptr
[byte
] != net
.ptr
[byte
])
759 * Get a route: If "nexthop", the nexthop is returned. source addr otherwise.
761 static host_t
*get_route(private_kernel_netlink_net_t
*this, host_t
*dest
,
762 bool nexthop
, host_t
*candidate
)
764 unsigned char request
[NETLINK_BUFFER_SIZE
];
765 struct nlmsghdr
*hdr
, *out
, *current
;
770 host_t
*src
= NULL
, *gtw
= NULL
;
772 DBG2(DBG_KNL
, "getting address to reach %H", dest
);
774 memset(&request
, 0, sizeof(request
));
776 hdr
= (struct nlmsghdr
*)request
;
777 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_DUMP
| NLM_F_ROOT
;
778 hdr
->nlmsg_type
= RTM_GETROUTE
;
779 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
781 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
782 msg
->rtm_family
= dest
->get_family(dest
);
784 chunk
= dest
->get_address(dest
);
785 netlink_add_attribute(hdr
, RTA_DST
, chunk
, sizeof(request
));
788 chunk
= candidate
->get_address(candidate
);
789 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
792 if (this->socket
->send(this->socket
, hdr
, &out
, &len
) != SUCCESS
)
794 DBG1(DBG_KNL
, "getting address to %H failed", dest
);
797 this->mutex
->lock(this->mutex
);
799 while (NLMSG_OK(current
, len
))
801 switch (current
->nlmsg_type
)
809 chunk_t rta_gtw
, rta_src
, rta_dst
;
810 u_int32_t rta_oif
= 0;
811 enumerator_t
*ifaces
, *addrs
;
812 iface_entry_t
*iface
;
815 rta_gtw
= rta_src
= rta_dst
= chunk_empty
;
816 msg
= (struct rtmsg
*)(NLMSG_DATA(current
));
818 rtasize
= RTM_PAYLOAD(current
);
819 while (RTA_OK(rta
, rtasize
))
821 switch (rta
->rta_type
)
824 rta_src
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
827 rta_gtw
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
830 rta_dst
= chunk_create(RTA_DATA(rta
), RTA_PAYLOAD(rta
));
833 if (RTA_PAYLOAD(rta
) == sizeof(rta_oif
))
835 rta_oif
= *(u_int32_t
*)RTA_DATA(rta
);
839 rta
= RTA_NEXT(rta
, rtasize
);
841 if (rta_oif
&& !is_interface_up(this, rta_oif
))
842 { /* interface is down */
845 if (this->routing_table
!= 0 &&
846 msg
->rtm_table
== this->routing_table
)
847 { /* route is from our own ipsec routing table */
850 if (msg
->rtm_dst_len
<= best
)
851 { /* not better than a previous one */
854 if (msg
->rtm_dst_len
!= 0 &&
856 !addr_in_subnet(chunk
, rta_dst
, msg
->rtm_dst_len
)))
857 { /* is not the default route and not contained in our dst */
861 best
= msg
->rtm_dst_len
;
865 gtw
= host_create_from_chunk(msg
->rtm_family
, rta_gtw
, 0);
871 src
= host_create_from_chunk(msg
->rtm_family
, rta_src
, 0);
872 if (get_vip_refcount(this, src
))
873 { /* skip source address if it is installed by us */
879 /* no source addr, get one from the interfaces */
880 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
881 while (ifaces
->enumerate(ifaces
, &iface
))
883 if (iface
->ifindex
== rta_oif
&&
884 iface
->flags
& IFF_UP
)
886 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
887 while (addrs
->enumerate(addrs
, &addr
))
889 chunk_t ip
= addr
->ip
->get_address(addr
->ip
);
890 if ((msg
->rtm_dst_len
== 0 &&
891 addr
->ip
->get_family(addr
->ip
) ==
892 dest
->get_family(dest
)) ||
893 addr_in_subnet(ip
, rta_dst
, msg
->rtm_dst_len
))
896 src
= addr
->ip
->clone(addr
->ip
);
900 addrs
->destroy(addrs
);
903 ifaces
->destroy(ifaces
);
908 current
= NLMSG_NEXT(current
, len
);
914 this->mutex
->unlock(this->mutex
);
922 return dest
->clone(dest
);
928 * Implementation of kernel_net_t.get_source_addr.
930 static host_t
* get_source_addr(private_kernel_netlink_net_t
*this,
931 host_t
*dest
, host_t
*src
)
933 return get_route(this, dest
, FALSE
, src
);
937 * Implementation of kernel_net_t.get_nexthop.
939 static host_t
* get_nexthop(private_kernel_netlink_net_t
*this, host_t
*dest
)
941 return get_route(this, dest
, TRUE
, NULL
);
945 * Manages the creation and deletion of ip addresses on an interface.
946 * By setting the appropriate nlmsg_type, the ip will be set or unset.
948 static status_t
manage_ipaddr(private_kernel_netlink_net_t
*this, int nlmsg_type
,
949 int flags
, int if_index
, host_t
*ip
)
951 unsigned char request
[NETLINK_BUFFER_SIZE
];
952 struct nlmsghdr
*hdr
;
953 struct ifaddrmsg
*msg
;
956 memset(&request
, 0, sizeof(request
));
958 chunk
= ip
->get_address(ip
);
960 hdr
= (struct nlmsghdr
*)request
;
961 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
962 hdr
->nlmsg_type
= nlmsg_type
;
963 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
965 msg
= (struct ifaddrmsg
*)NLMSG_DATA(hdr
);
966 msg
->ifa_family
= ip
->get_family(ip
);
968 msg
->ifa_prefixlen
= 8 * chunk
.len
;
969 msg
->ifa_scope
= RT_SCOPE_UNIVERSE
;
970 msg
->ifa_index
= if_index
;
972 netlink_add_attribute(hdr
, IFA_LOCAL
, chunk
, sizeof(request
));
974 return this->socket
->send_ack(this->socket
, hdr
);
978 * Implementation of kernel_net_t.add_ip.
980 static status_t
add_ip(private_kernel_netlink_net_t
*this,
981 host_t
*virtual_ip
, host_t
*iface_ip
)
983 iface_entry_t
*iface
;
985 enumerator_t
*addrs
, *ifaces
;
988 DBG2(DBG_KNL
, "adding virtual IP %H", virtual_ip
);
990 this->mutex
->lock(this->mutex
);
991 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
992 while (ifaces
->enumerate(ifaces
, &iface
))
994 bool iface_found
= FALSE
;
996 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
997 while (addrs
->enumerate(addrs
, &addr
))
999 if (iface_ip
->ip_equals(iface_ip
, addr
->ip
))
1003 else if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1006 DBG2(DBG_KNL
, "virtual IP %H already installed on %s",
1007 virtual_ip
, iface
->ifname
);
1008 addrs
->destroy(addrs
);
1009 ifaces
->destroy(ifaces
);
1010 this->mutex
->unlock(this->mutex
);
1014 addrs
->destroy(addrs
);
1018 ifindex
= iface
->ifindex
;
1019 addr
= malloc_thing(addr_entry_t
);
1020 addr
->ip
= virtual_ip
->clone(virtual_ip
);
1022 addr
->virtual = TRUE
;
1023 addr
->scope
= RT_SCOPE_UNIVERSE
;
1024 iface
->addrs
->insert_last(iface
->addrs
, addr
);
1026 if (manage_ipaddr(this, RTM_NEWADDR
, NLM_F_CREATE
| NLM_F_EXCL
,
1027 ifindex
, virtual_ip
) == SUCCESS
)
1029 while (get_vip_refcount(this, virtual_ip
) == 0)
1030 { /* wait until address appears */
1031 this->condvar
->wait(this->condvar
, this->mutex
);
1033 ifaces
->destroy(ifaces
);
1034 this->mutex
->unlock(this->mutex
);
1037 ifaces
->destroy(ifaces
);
1038 this->mutex
->unlock(this->mutex
);
1039 DBG1(DBG_KNL
, "adding virtual IP %H failed", virtual_ip
);
1043 ifaces
->destroy(ifaces
);
1044 this->mutex
->unlock(this->mutex
);
1046 DBG1(DBG_KNL
, "interface address %H not found, unable to install"
1047 "virtual IP %H", iface_ip
, virtual_ip
);
1052 * Implementation of kernel_net_t.del_ip.
1054 static status_t
del_ip(private_kernel_netlink_net_t
*this, host_t
*virtual_ip
)
1056 iface_entry_t
*iface
;
1058 enumerator_t
*addrs
, *ifaces
;
1062 DBG2(DBG_KNL
, "deleting virtual IP %H", virtual_ip
);
1064 this->mutex
->lock(this->mutex
);
1065 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1066 while (ifaces
->enumerate(ifaces
, &iface
))
1068 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1069 while (addrs
->enumerate(addrs
, &addr
))
1071 if (virtual_ip
->ip_equals(virtual_ip
, addr
->ip
))
1073 ifindex
= iface
->ifindex
;
1074 if (addr
->refcount
== 1)
1076 status
= manage_ipaddr(this, RTM_DELADDR
, 0,
1077 ifindex
, virtual_ip
);
1078 if (status
== SUCCESS
)
1079 { /* wait until the address is really gone */
1080 while (get_vip_refcount(this, virtual_ip
) > 0)
1082 this->condvar
->wait(this->condvar
, this->mutex
);
1085 addrs
->destroy(addrs
);
1086 ifaces
->destroy(ifaces
);
1087 this->mutex
->unlock(this->mutex
);
1094 DBG2(DBG_KNL
, "virtual IP %H used by other SAs, not deleting",
1096 addrs
->destroy(addrs
);
1097 ifaces
->destroy(ifaces
);
1098 this->mutex
->unlock(this->mutex
);
1102 addrs
->destroy(addrs
);
1104 ifaces
->destroy(ifaces
);
1105 this->mutex
->unlock(this->mutex
);
1107 DBG2(DBG_KNL
, "virtual IP %H not cached, unable to delete", virtual_ip
);
1112 * Manages source routes in the routing table.
1113 * By setting the appropriate nlmsg_type, the route gets added or removed.
1115 static status_t
manage_srcroute(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1116 int flags
, chunk_t dst_net
, u_int8_t prefixlen
,
1117 host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1119 unsigned char request
[NETLINK_BUFFER_SIZE
];
1120 struct nlmsghdr
*hdr
;
1125 /* if route is 0.0.0.0/0, we can't install it, as it would
1126 * overwrite the default route. Instead, we add two routes:
1127 * 0.0.0.0/1 and 128.0.0.0/1 */
1128 if (this->routing_table
== 0 && prefixlen
== 0)
1131 u_int8_t half_prefixlen
;
1134 half_net
= chunk_alloca(dst_net
.len
);
1135 memset(half_net
.ptr
, 0, half_net
.len
);
1138 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1139 gateway
, src_ip
, if_name
);
1140 half_net
.ptr
[0] |= 0x80;
1141 status
= manage_srcroute(this, nlmsg_type
, flags
, half_net
, half_prefixlen
,
1142 gateway
, src_ip
, if_name
);
1146 memset(&request
, 0, sizeof(request
));
1148 hdr
= (struct nlmsghdr
*)request
;
1149 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
| flags
;
1150 hdr
->nlmsg_type
= nlmsg_type
;
1151 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1153 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1154 msg
->rtm_family
= src_ip
->get_family(src_ip
);
1155 msg
->rtm_dst_len
= prefixlen
;
1156 msg
->rtm_table
= this->routing_table
;
1157 msg
->rtm_protocol
= RTPROT_STATIC
;
1158 msg
->rtm_type
= RTN_UNICAST
;
1159 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1161 netlink_add_attribute(hdr
, RTA_DST
, dst_net
, sizeof(request
));
1162 chunk
= src_ip
->get_address(src_ip
);
1163 netlink_add_attribute(hdr
, RTA_PREFSRC
, chunk
, sizeof(request
));
1164 chunk
= gateway
->get_address(gateway
);
1165 netlink_add_attribute(hdr
, RTA_GATEWAY
, chunk
, sizeof(request
));
1166 ifindex
= get_interface_index(this, if_name
);
1167 chunk
.ptr
= (char*)&ifindex
;
1168 chunk
.len
= sizeof(ifindex
);
1169 netlink_add_attribute(hdr
, RTA_OIF
, chunk
, sizeof(request
));
1171 return this->socket
->send_ack(this->socket
, hdr
);
1175 * Implementation of kernel_net_t.add_route.
1177 status_t
add_route(private_kernel_netlink_net_t
*this, chunk_t dst_net
,
1178 u_int8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1180 return manage_srcroute(this, RTM_NEWROUTE
, NLM_F_CREATE
| NLM_F_EXCL
,
1181 dst_net
, prefixlen
, gateway
, src_ip
, if_name
);
1185 * Implementation of kernel_net_t.del_route.
1187 status_t
del_route(private_kernel_netlink_net_t
*this, chunk_t dst_net
,
1188 u_int8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
, char *if_name
)
1190 return manage_srcroute(this, RTM_DELROUTE
, 0, dst_net
, prefixlen
,
1191 gateway
, src_ip
, if_name
);
1195 * Initialize a list of local addresses.
1197 static status_t
init_address_list(private_kernel_netlink_net_t
*this)
1199 char request
[NETLINK_BUFFER_SIZE
];
1200 struct nlmsghdr
*out
, *current
, *in
;
1201 struct rtgenmsg
*msg
;
1203 enumerator_t
*ifaces
, *addrs
;
1204 iface_entry_t
*iface
;
1207 DBG1(DBG_KNL
, "listening on interfaces:");
1209 memset(&request
, 0, sizeof(request
));
1211 in
= (struct nlmsghdr
*)&request
;
1212 in
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtgenmsg
));
1213 in
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_MATCH
| NLM_F_ROOT
;
1214 msg
= (struct rtgenmsg
*)NLMSG_DATA(in
);
1215 msg
->rtgen_family
= AF_UNSPEC
;
1218 in
->nlmsg_type
= RTM_GETLINK
;
1219 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1224 while (NLMSG_OK(current
, len
))
1226 switch (current
->nlmsg_type
)
1231 process_link(this, current
, FALSE
);
1234 current
= NLMSG_NEXT(current
, len
);
1241 /* get all interface addresses */
1242 in
->nlmsg_type
= RTM_GETADDR
;
1243 if (this->socket
->send(this->socket
, in
, &out
, &len
) != SUCCESS
)
1248 while (NLMSG_OK(current
, len
))
1250 switch (current
->nlmsg_type
)
1255 process_addr(this, current
, FALSE
);
1258 current
= NLMSG_NEXT(current
, len
);
1265 this->mutex
->lock(this->mutex
);
1266 ifaces
= this->ifaces
->create_enumerator(this->ifaces
);
1267 while (ifaces
->enumerate(ifaces
, &iface
))
1269 if (iface
->flags
& IFF_UP
)
1271 DBG1(DBG_KNL
, " %s", iface
->ifname
);
1272 addrs
= iface
->addrs
->create_enumerator(iface
->addrs
);
1273 while (addrs
->enumerate(addrs
, (void**)&addr
))
1275 DBG1(DBG_KNL
, " %H", addr
->ip
);
1277 addrs
->destroy(addrs
);
1280 ifaces
->destroy(ifaces
);
1281 this->mutex
->unlock(this->mutex
);
1286 * create or delete a rule to use our routing table
1288 static status_t
manage_rule(private_kernel_netlink_net_t
*this, int nlmsg_type
,
1289 u_int32_t table
, u_int32_t prio
)
1291 unsigned char request
[NETLINK_BUFFER_SIZE
];
1292 struct nlmsghdr
*hdr
;
1296 memset(&request
, 0, sizeof(request
));
1297 hdr
= (struct nlmsghdr
*)request
;
1298 hdr
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
1299 hdr
->nlmsg_type
= nlmsg_type
;
1300 if (nlmsg_type
== RTM_NEWRULE
)
1302 hdr
->nlmsg_flags
|= NLM_F_CREATE
| NLM_F_EXCL
;
1304 hdr
->nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1306 msg
= (struct rtmsg
*)NLMSG_DATA(hdr
);
1307 msg
->rtm_table
= table
;
1308 msg
->rtm_family
= AF_INET
;
1309 msg
->rtm_protocol
= RTPROT_BOOT
;
1310 msg
->rtm_scope
= RT_SCOPE_UNIVERSE
;
1311 msg
->rtm_type
= RTN_UNICAST
;
1313 chunk
= chunk_from_thing(prio
);
1314 netlink_add_attribute(hdr
, RTA_PRIORITY
, chunk
, sizeof(request
));
1316 return this->socket
->send_ack(this->socket
, hdr
);
1320 * Implementation of kernel_netlink_net_t.destroy.
1322 static void destroy(private_kernel_netlink_net_t
*this)
1324 if (this->routing_table
)
1326 manage_rule(this, RTM_DELRULE
, this->routing_table
,
1327 this->routing_table_prio
);
1330 this->job
->cancel(this->job
);
1331 close(this->socket_events
);
1332 this->socket
->destroy(this->socket
);
1333 this->ifaces
->destroy_function(this->ifaces
, (void*)iface_entry_destroy
);
1334 this->condvar
->destroy(this->condvar
);
1335 this->mutex
->destroy(this->mutex
);
1340 * Described in header.
1342 kernel_netlink_net_t
*kernel_netlink_net_create()
1344 private_kernel_netlink_net_t
*this = malloc_thing(private_kernel_netlink_net_t
);
1345 struct sockaddr_nl addr
;
1347 /* public functions */
1348 this->public.interface
.get_interface
= (char*(*)(kernel_net_t
*,host_t
*))get_interface_name
;
1349 this->public.interface
.create_address_enumerator
= (enumerator_t
*(*)(kernel_net_t
*,bool,bool))create_address_enumerator
;
1350 this->public.interface
.get_source_addr
= (host_t
*(*)(kernel_net_t
*, host_t
*dest
, host_t
*src
))get_source_addr
;
1351 this->public.interface
.get_nexthop
= (host_t
*(*)(kernel_net_t
*, host_t
*dest
))get_nexthop
;
1352 this->public.interface
.add_ip
= (status_t(*)(kernel_net_t
*,host_t
*,host_t
*)) add_ip
;
1353 this->public.interface
.del_ip
= (status_t(*)(kernel_net_t
*,host_t
*)) del_ip
;
1354 this->public.interface
.add_route
= (status_t(*)(kernel_net_t
*,chunk_t
,u_int8_t
,host_t
*,host_t
*,char*)) add_route
;
1355 this->public.interface
.del_route
= (status_t(*)(kernel_net_t
*,chunk_t
,u_int8_t
,host_t
*,host_t
*,char*)) del_route
;
1356 this->public.interface
.destroy
= (void(*)(kernel_net_t
*)) destroy
;
1358 /* private members */
1359 this->ifaces
= linked_list_create();
1360 this->mutex
= mutex_create(MUTEX_DEFAULT
);
1361 this->condvar
= condvar_create(CONDVAR_DEFAULT
);
1362 timerclear(&this->last_roam
);
1363 this->routing_table
= lib
->settings
->get_int(lib
->settings
,
1364 "charon.routing_table", IPSEC_ROUTING_TABLE
);
1365 this->routing_table_prio
= lib
->settings
->get_int(lib
->settings
,
1366 "charon.routing_table_prio", IPSEC_ROUTING_TABLE_PRIO
);
1367 this->process_route
= lib
->settings
->get_bool(lib
->settings
,
1368 "charon.process_route", TRUE
);
1370 this->socket
= netlink_socket_create(NETLINK_ROUTE
);
1372 memset(&addr
, 0, sizeof(addr
));
1373 addr
.nl_family
= AF_NETLINK
;
1375 /* create and bind RT socket for events (address/interface/route changes) */
1376 this->socket_events
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
1377 if (this->socket_events
<= 0)
1379 charon
->kill(charon
, "unable to create RT event socket");
1381 addr
.nl_groups
= RTMGRP_IPV4_IFADDR
| RTMGRP_IPV6_IFADDR
|
1382 RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_ROUTE
| RTMGRP_LINK
;
1383 if (bind(this->socket_events
, (struct sockaddr
*)&addr
, sizeof(addr
)))
1385 charon
->kill(charon
, "unable to bind RT event socket");
1388 this->job
= callback_job_create((callback_job_cb_t
)receive_events
,
1390 charon
->processor
->queue_job(charon
->processor
, (job_t
*)this->job
);
1392 if (init_address_list(this) != SUCCESS
)
1394 charon
->kill(charon
, "unable to get interface list");
1397 if (this->routing_table
)
1399 if (manage_rule(this, RTM_NEWRULE
, this->routing_table
,
1400 this->routing_table_prio
) != SUCCESS
)
1402 DBG1(DBG_KNL
, "unable to create routing table rule");
1406 return &this->public;