]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libcharon / plugins / kernel_pfroute / kernel_pfroute_net.c
1 /*
2 * Copyright (C) 2009-2016 Tobias Brunner
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
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>.
10 *
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
14 * for more details.
15 */
16
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <sys/sysctl.h>
20 #include <net/if.h>
21 #include <net/if_dl.h>
22 #include <ifaddrs.h>
23 #include <net/route.h>
24 #include <unistd.h>
25 #include <errno.h>
26
27 #include "kernel_pfroute_net.h"
28
29 #include <daemon.h>
30 #include <utils/debug.h>
31 #include <networking/host.h>
32 #include <networking/tun_device.h>
33 #include <threading/thread.h>
34 #include <threading/mutex.h>
35 #include <threading/condvar.h>
36 #include <threading/rwlock.h>
37 #include <threading/spinlock.h>
38 #include <collections/hashtable.h>
39 #include <collections/linked_list.h>
40 #include <processing/jobs/callback_job.h>
41
42 #ifndef HAVE_STRUCT_SOCKADDR_SA_LEN
43 #error Cannot compile this plugin on systems where 'struct sockaddr' has no sa_len member.
44 #endif
45
46 /** properly align sockaddrs */
47 #ifdef __APPLE__
48 /* Apple always uses 4 bytes */
49 #define SA_ALIGN 4
50 #else
51 /* while on other platforms like FreeBSD it depends on the architecture */
52 #define SA_ALIGN sizeof(long)
53 #endif
54 #define SA_LEN(len) ((len) > 0 ? (((len)+SA_ALIGN-1) & ~(SA_ALIGN-1)) : SA_ALIGN)
55
56 /** delay before firing roam events (ms) */
57 #define ROAM_DELAY 100
58
59 /** delay before reinstalling routes (ms) */
60 #define ROUTE_DELAY 100
61
62 /** default MTU for TUN devices */
63 #define TUN_DEFAULT_MTU 1400
64
65 typedef struct addr_entry_t addr_entry_t;
66
67 /**
68 * IP address in an inface_entry_t
69 */
70 struct addr_entry_t {
71
72 /** The ip address */
73 host_t *ip;
74
75 /** virtual IP managed by us */
76 bool virtual;
77 };
78
79 /**
80 * destroy a addr_entry_t object
81 */
82 static void addr_entry_destroy(addr_entry_t *this)
83 {
84 this->ip->destroy(this->ip);
85 free(this);
86 }
87
88 typedef struct iface_entry_t iface_entry_t;
89
90 /**
91 * A network interface on this system, containing addr_entry_t's
92 */
93 struct iface_entry_t {
94
95 /** interface index */
96 int ifindex;
97
98 /** name of the interface */
99 char ifname[IFNAMSIZ];
100
101 /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
102 u_int flags;
103
104 /** list of addresses as host_t */
105 linked_list_t *addrs;
106
107 /** TRUE if usable by config */
108 bool usable;
109 };
110
111 /**
112 * destroy an interface entry
113 */
114 static void iface_entry_destroy(iface_entry_t *this)
115 {
116 this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy);
117 free(this);
118 }
119
120 /**
121 * check if an interface is up
122 */
123 static inline bool iface_entry_up(iface_entry_t *iface)
124 {
125 return (iface->flags & IFF_UP) == IFF_UP;
126 }
127
128 /**
129 * check if an interface is up and usable
130 */
131 static inline bool iface_entry_up_and_usable(iface_entry_t *iface)
132 {
133 return iface->usable && iface_entry_up(iface);
134 }
135
136 typedef struct addr_map_entry_t addr_map_entry_t;
137
138 /**
139 * Entry that maps an IP address to an interface entry
140 */
141 struct addr_map_entry_t {
142 /** The IP address */
143 host_t *ip;
144
145 /** The address entry for this IP address */
146 addr_entry_t *addr;
147
148 /** The interface this address is installed on */
149 iface_entry_t *iface;
150 };
151
152 /**
153 * Hash a addr_map_entry_t object, all entries with the same IP address
154 * are stored in the same bucket
155 */
156 static u_int addr_map_entry_hash(addr_map_entry_t *this)
157 {
158 return chunk_hash(this->ip->get_address(this->ip));
159 }
160
161 /**
162 * Compare two addr_map_entry_t objects, two entries are equal if they are
163 * installed on the same interface
164 */
165 static bool addr_map_entry_equals(addr_map_entry_t *a, addr_map_entry_t *b)
166 {
167 return a->iface->ifindex == b->iface->ifindex &&
168 a->ip->ip_equals(a->ip, b->ip);
169 }
170
171 /**
172 * Used with get_match this finds an address entry if it is installed on
173 * an up and usable interface
174 */
175 static bool addr_map_entry_match_up_and_usable(addr_map_entry_t *a,
176 addr_map_entry_t *b)
177 {
178 return !b->addr->virtual && iface_entry_up_and_usable(b->iface) &&
179 a->ip->ip_equals(a->ip, b->ip);
180 }
181
182 /**
183 * Used with get_match this finds an address entry if it is installed as virtual
184 * IP address
185 */
186 static bool addr_map_entry_match_virtual(addr_map_entry_t *a, addr_map_entry_t *b)
187 {
188 return b->addr->virtual && a->ip->ip_equals(a->ip, b->ip);
189 }
190
191 /**
192 * Used with get_match this finds an address entry if it is installed on
193 * any active local interface
194 */
195 static bool addr_map_entry_match_up(addr_map_entry_t *a, addr_map_entry_t *b)
196 {
197 return !b->addr->virtual && iface_entry_up(b->iface) &&
198 a->ip->ip_equals(a->ip, b->ip);
199 }
200
201 typedef struct route_entry_t route_entry_t;
202
203 /**
204 * Installed routing entry
205 */
206 struct route_entry_t {
207 /** Name of the interface the route is bound to */
208 char *if_name;
209
210 /** Gateway for this route */
211 host_t *gateway;
212
213 /** Destination net */
214 chunk_t dst_net;
215
216 /** Destination net prefixlen */
217 uint8_t prefixlen;
218 };
219
220 /**
221 * Clone a route_entry_t object.
222 */
223 static route_entry_t *route_entry_clone(route_entry_t *this)
224 {
225 route_entry_t *route;
226
227 INIT(route,
228 .if_name = strdup(this->if_name),
229 .gateway = this->gateway ? this->gateway->clone(this->gateway) : NULL,
230 .dst_net = chunk_clone(this->dst_net),
231 .prefixlen = this->prefixlen,
232 );
233 return route;
234 }
235
236 /**
237 * Destroy a route_entry_t object
238 */
239 static void route_entry_destroy(route_entry_t *this)
240 {
241 free(this->if_name);
242 DESTROY_IF(this->gateway);
243 chunk_free(&this->dst_net);
244 free(this);
245 }
246
247 /**
248 * Hash a route_entry_t object
249 */
250 static u_int route_entry_hash(route_entry_t *this)
251 {
252 return chunk_hash_inc(chunk_from_thing(this->prefixlen),
253 chunk_hash(this->dst_net));
254 }
255
256 /**
257 * Compare two route_entry_t objects
258 */
259 static bool route_entry_equals(route_entry_t *a, route_entry_t *b)
260 {
261 if (a->if_name && b->if_name && streq(a->if_name, b->if_name) &&
262 chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen)
263 {
264 return (!a->gateway && !b->gateway) || (a->gateway && b->gateway &&
265 a->gateway->ip_equals(a->gateway, b->gateway));
266 }
267 return FALSE;
268 }
269
270 typedef struct net_change_t net_change_t;
271
272 /**
273 * Queued network changes
274 */
275 struct net_change_t {
276 /** Name of the interface that got activated (or an IP appeared on) */
277 char *if_name;
278 };
279
280 /**
281 * Destroy a net_change_t object
282 */
283 static void net_change_destroy(net_change_t *this)
284 {
285 free(this->if_name);
286 free(this);
287 }
288
289 /**
290 * Hash a net_change_t object
291 */
292 static u_int net_change_hash(net_change_t *this)
293 {
294 return chunk_hash(chunk_create(this->if_name, strlen(this->if_name)));
295 }
296
297 /**
298 * Compare two net_change_t objects
299 */
300 static bool net_change_equals(net_change_t *a, net_change_t *b)
301 {
302 return streq(a->if_name, b->if_name);
303 }
304
305 typedef struct private_kernel_pfroute_net_t private_kernel_pfroute_net_t;
306
307 /**
308 * Private variables and functions of kernel_pfroute class.
309 */
310 struct private_kernel_pfroute_net_t
311 {
312 /**
313 * Public part of the kernel_pfroute_t object.
314 */
315 kernel_pfroute_net_t public;
316
317 /**
318 * lock to access lists and maps
319 */
320 rwlock_t *lock;
321
322 /**
323 * Cached list of interfaces and their addresses (iface_entry_t)
324 */
325 linked_list_t *ifaces;
326
327 /**
328 * Map for IP addresses to iface_entry_t objects (addr_map_entry_t)
329 */
330 hashlist_t *addrs;
331
332 /**
333 * List of tun devices we installed for virtual IPs
334 */
335 linked_list_t *tuns;
336
337 /**
338 * mutex to communicate exclusively with PF_KEY
339 */
340 mutex_t *mutex;
341
342 /**
343 * condvar to signal if PF_KEY query got a response
344 */
345 condvar_t *condvar;
346
347 /**
348 * installed routes
349 */
350 hashtable_t *routes;
351
352 /**
353 * mutex for routes
354 */
355 mutex_t *routes_lock;
356
357 /**
358 * interface changes which may trigger route reinstallation
359 */
360 hashtable_t *net_changes;
361
362 /**
363 * mutex for route reinstallation triggers
364 */
365 mutex_t *net_changes_lock;
366
367 /**
368 * time of last route reinstallation
369 */
370 timeval_t last_route_reinstall;
371
372 /**
373 * pid to send PF_ROUTE messages with
374 */
375 pid_t pid;
376
377 /**
378 * PF_ROUTE socket to communicate with the kernel
379 */
380 int socket;
381
382 /**
383 * sequence number for messages sent to the kernel
384 */
385 int seq;
386
387 /**
388 * Sequence number a query is waiting for
389 */
390 int waiting_seq;
391
392 /**
393 * Allocated reply message from kernel
394 */
395 struct rt_msghdr *reply;
396
397 /**
398 * earliest time of the next roam event
399 */
400 timeval_t next_roam;
401
402 /**
403 * roam event due to address change
404 */
405 bool roam_address;
406
407 /**
408 * lock to check and update roam event time
409 */
410 spinlock_t *roam_lock;
411
412 /**
413 * Time in ms to wait for IP addresses to appear/disappear
414 */
415 int vip_wait;
416
417 /**
418 * MTU to set on TUN devices
419 */
420 uint32_t mtu;
421
422 /**
423 * whether to actually install virtual IPs
424 */
425 bool install_virtual_ip;
426 };
427
428
429 /**
430 * Forward declaration
431 */
432 static status_t manage_route(private_kernel_pfroute_net_t *this, int op,
433 chunk_t dst_net, uint8_t prefixlen,
434 host_t *gateway, char *if_name);
435
436 /**
437 * Clear the queued network changes.
438 */
439 static void net_changes_clear(private_kernel_pfroute_net_t *this)
440 {
441 enumerator_t *enumerator;
442 net_change_t *change;
443
444 enumerator = this->net_changes->create_enumerator(this->net_changes);
445 while (enumerator->enumerate(enumerator, NULL, (void**)&change))
446 {
447 this->net_changes->remove_at(this->net_changes, enumerator);
448 net_change_destroy(change);
449 }
450 enumerator->destroy(enumerator);
451 }
452
453 /**
454 * Act upon queued network changes.
455 */
456 static job_requeue_t reinstall_routes(private_kernel_pfroute_net_t *this)
457 {
458 enumerator_t *enumerator;
459 route_entry_t *route;
460
461 this->net_changes_lock->lock(this->net_changes_lock);
462 this->routes_lock->lock(this->routes_lock);
463
464 enumerator = this->routes->create_enumerator(this->routes);
465 while (enumerator->enumerate(enumerator, NULL, (void**)&route))
466 {
467 net_change_t *change, lookup = {
468 .if_name = route->if_name,
469 };
470 /* check if a change for the outgoing interface is queued */
471 change = this->net_changes->get(this->net_changes, &lookup);
472 if (change)
473 {
474 manage_route(this, RTM_ADD, route->dst_net, route->prefixlen,
475 route->gateway, route->if_name);
476 }
477 }
478 enumerator->destroy(enumerator);
479 this->routes_lock->unlock(this->routes_lock);
480
481 net_changes_clear(this);
482 this->net_changes_lock->unlock(this->net_changes_lock);
483 return JOB_REQUEUE_NONE;
484 }
485
486 /**
487 * Queue route reinstallation caused by network changes for a given interface.
488 *
489 * The route reinstallation is delayed for a while and only done once for
490 * several calls during this delay, in order to avoid doing it too often.
491 * The interface name is freed.
492 */
493 static void queue_route_reinstall(private_kernel_pfroute_net_t *this,
494 char *if_name)
495 {
496 net_change_t *update, *found;
497 timeval_t now;
498 job_t *job;
499
500 INIT(update,
501 .if_name = if_name
502 );
503
504 this->net_changes_lock->lock(this->net_changes_lock);
505 found = this->net_changes->put(this->net_changes, update, update);
506 if (found)
507 {
508 net_change_destroy(found);
509 }
510 time_monotonic(&now);
511 if (timercmp(&now, &this->last_route_reinstall, >))
512 {
513 timeval_add_ms(&now, ROUTE_DELAY);
514 this->last_route_reinstall = now;
515
516 job = (job_t*)callback_job_create((callback_job_cb_t)reinstall_routes,
517 this, NULL, NULL);
518 lib->scheduler->schedule_job_ms(lib->scheduler, job, ROUTE_DELAY);
519 }
520 this->net_changes_lock->unlock(this->net_changes_lock);
521 }
522
523 /**
524 * Add an address map entry
525 */
526 static void addr_map_entry_add(private_kernel_pfroute_net_t *this,
527 addr_entry_t *addr, iface_entry_t *iface)
528 {
529 addr_map_entry_t *entry;
530
531 INIT(entry,
532 .ip = addr->ip,
533 .addr = addr,
534 .iface = iface,
535 );
536 entry = this->addrs->ht.put(&this->addrs->ht, entry, entry);
537 free(entry);
538 }
539
540 /**
541 * Remove an address map entry (the argument order is a bit strange because
542 * it is also used with linked_list_t.invoke_function)
543 */
544 static void addr_map_entry_remove(addr_entry_t *addr, iface_entry_t *iface,
545 private_kernel_pfroute_net_t *this)
546 {
547 addr_map_entry_t *entry, lookup = {
548 .ip = addr->ip,
549 .addr = addr,
550 .iface = iface,
551 };
552
553 entry = this->addrs->ht.remove(&this->addrs->ht, &lookup);
554 free(entry);
555 }
556
557 /**
558 * callback function that raises the delayed roam event
559 */
560 static job_requeue_t roam_event(private_kernel_pfroute_net_t *this)
561 {
562 bool address;
563
564 this->roam_lock->lock(this->roam_lock);
565 address = this->roam_address;
566 this->roam_address = FALSE;
567 this->roam_lock->unlock(this->roam_lock);
568 charon->kernel->roam(charon->kernel, address);
569 return JOB_REQUEUE_NONE;
570 }
571
572 /**
573 * fire a roaming event. we delay it for a bit and fire only one event
574 * for multiple calls. otherwise we would create too many events.
575 */
576 static void fire_roam_event(private_kernel_pfroute_net_t *this, bool address)
577 {
578 timeval_t now;
579 job_t *job;
580
581 time_monotonic(&now);
582 this->roam_lock->lock(this->roam_lock);
583 this->roam_address |= address;
584 if (!timercmp(&now, &this->next_roam, >))
585 {
586 this->roam_lock->unlock(this->roam_lock);
587 return;
588 }
589 timeval_add_ms(&now, ROAM_DELAY);
590 this->next_roam = now;
591 this->roam_lock->unlock(this->roam_lock);
592
593 job = (job_t*)callback_job_create((callback_job_cb_t)roam_event,
594 this, NULL, NULL);
595 lib->scheduler->schedule_job_ms(lib->scheduler, job, ROAM_DELAY);
596 }
597
598 /**
599 * Data for enumerator over rtmsg sockaddrs
600 */
601 typedef struct {
602 /** implements enumerator */
603 enumerator_t public;
604 /** copy of attribute bitfield */
605 int types;
606 /** bytes remaining in buffer */
607 int remaining;
608 /** next sockaddr to enumerate */
609 struct sockaddr *addr;
610 } rt_enumerator_t;
611
612 METHOD(enumerator_t, rt_enumerate, bool,
613 rt_enumerator_t *this, va_list args)
614 {
615 struct sockaddr **addr;
616 int i, type, *xtype;
617
618 VA_ARGS_VGET(args, xtype, addr);
619
620 if (this->remaining < sizeof(this->addr->sa_len) ||
621 this->remaining < this->addr->sa_len)
622 {
623 return FALSE;
624 }
625 for (i = 0; i < RTAX_MAX; i++)
626 {
627 type = (1 << i);
628 if (this->types & type)
629 {
630 this->types &= ~type;
631 *addr = this->addr;
632 *xtype = i;
633 this->remaining -= SA_LEN(this->addr->sa_len);
634 this->addr = (struct sockaddr*)((char*)this->addr +
635 SA_LEN(this->addr->sa_len));
636 return TRUE;
637 }
638 }
639 return FALSE;
640 }
641
642 /**
643 * Create an enumerator over sockaddrs in rt/if messages
644 */
645 static enumerator_t *create_rt_enumerator(int types, int remaining,
646 struct sockaddr *addr)
647 {
648 rt_enumerator_t *this;
649
650 INIT(this,
651 .public = {
652 .enumerate = enumerator_enumerate_default,
653 .venumerate = _rt_enumerate,
654 .destroy = (void*)free,
655 },
656 .types = types,
657 .remaining = remaining,
658 .addr = addr,
659 );
660 return &this->public;
661 }
662
663 /**
664 * Create a safe enumerator over sockaddrs in rt_msghdr
665 */
666 static enumerator_t *create_rtmsg_enumerator(struct rt_msghdr *hdr)
667 {
668 return create_rt_enumerator(hdr->rtm_addrs, hdr->rtm_msglen - sizeof(*hdr),
669 (struct sockaddr *)(hdr + 1));
670 }
671
672 /**
673 * Create a safe enumerator over sockaddrs in ifa_msghdr
674 */
675 static enumerator_t *create_ifamsg_enumerator(struct ifa_msghdr *hdr)
676 {
677 return create_rt_enumerator(hdr->ifam_addrs, hdr->ifam_msglen - sizeof(*hdr),
678 (struct sockaddr *)(hdr + 1));
679 }
680
681 /**
682 * Process an RTM_*ADDR message from the kernel
683 */
684 static void process_addr(private_kernel_pfroute_net_t *this,
685 struct ifa_msghdr *ifa)
686 {
687 struct sockaddr *sockaddr;
688 host_t *host = NULL;
689 enumerator_t *ifaces, *addrs;
690 iface_entry_t *iface;
691 addr_entry_t *addr;
692 bool found = FALSE, changed = FALSE, roam = FALSE;
693 enumerator_t *enumerator;
694 char *ifname = NULL;
695 int type;
696
697 enumerator = create_ifamsg_enumerator(ifa);
698 while (enumerator->enumerate(enumerator, &type, &sockaddr))
699 {
700 if (type == RTAX_IFA)
701 {
702 host = host_create_from_sockaddr(sockaddr);
703 break;
704 }
705 }
706 enumerator->destroy(enumerator);
707
708 if (!host || host->is_anyaddr(host))
709 {
710 DESTROY_IF(host);
711 return;
712 }
713
714 this->lock->write_lock(this->lock);
715 ifaces = this->ifaces->create_enumerator(this->ifaces);
716 while (ifaces->enumerate(ifaces, &iface))
717 {
718 if (iface->ifindex == ifa->ifam_index)
719 {
720 addrs = iface->addrs->create_enumerator(iface->addrs);
721 while (addrs->enumerate(addrs, &addr))
722 {
723 if (host->ip_equals(host, addr->ip))
724 {
725 found = TRUE;
726 if (ifa->ifam_type == RTM_DELADDR)
727 {
728 iface->addrs->remove_at(iface->addrs, addrs);
729 if (!addr->virtual && iface->usable)
730 {
731 changed = TRUE;
732 DBG1(DBG_KNL, "%H disappeared from %s",
733 host, iface->ifname);
734 }
735 addr_map_entry_remove(addr, iface, this);
736 addr_entry_destroy(addr);
737 }
738 }
739 }
740 addrs->destroy(addrs);
741
742 if (!found && ifa->ifam_type == RTM_NEWADDR)
743 {
744 INIT(addr,
745 .ip = host->clone(host),
746 );
747 changed = TRUE;
748 ifname = strdup(iface->ifname);
749 iface->addrs->insert_last(iface->addrs, addr);
750 addr_map_entry_add(this, addr, iface);
751 if (iface->usable)
752 {
753 DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname);
754 }
755 }
756
757 if (changed && iface_entry_up_and_usable(iface))
758 {
759 roam = TRUE;
760 }
761 break;
762 }
763 }
764 ifaces->destroy(ifaces);
765 this->lock->unlock(this->lock);
766 host->destroy(host);
767
768 if (roam && ifname)
769 {
770 queue_route_reinstall(this, ifname);
771 }
772 else
773 {
774 free(ifname);
775 }
776
777 if (roam)
778 {
779 fire_roam_event(this, TRUE);
780 }
781 }
782
783 /**
784 * Re-initialize address list of an interface if it changes state
785 */
786 static void repopulate_iface(private_kernel_pfroute_net_t *this,
787 iface_entry_t *iface)
788 {
789 struct ifaddrs *ifap, *ifa;
790 addr_entry_t *addr;
791
792 while (iface->addrs->remove_last(iface->addrs, (void**)&addr) == SUCCESS)
793 {
794 addr_map_entry_remove(addr, iface, this);
795 addr_entry_destroy(addr);
796 }
797
798 if (getifaddrs(&ifap) == 0)
799 {
800 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
801 {
802 if (ifa->ifa_addr && streq(ifa->ifa_name, iface->ifname))
803 {
804 switch (ifa->ifa_addr->sa_family)
805 {
806 case AF_INET:
807 case AF_INET6:
808 INIT(addr,
809 .ip = host_create_from_sockaddr(ifa->ifa_addr),
810 );
811 iface->addrs->insert_last(iface->addrs, addr);
812 addr_map_entry_add(this, addr, iface);
813 break;
814 default:
815 break;
816 }
817 }
818 }
819 freeifaddrs(ifap);
820 }
821 }
822
823 /**
824 * Process an RTM_IFINFO message from the kernel
825 */
826 static void process_link(private_kernel_pfroute_net_t *this,
827 struct if_msghdr *msg)
828 {
829 enumerator_t *enumerator;
830 iface_entry_t *iface;
831 bool roam = FALSE, found = FALSE, update_routes = FALSE;
832
833 this->lock->write_lock(this->lock);
834 enumerator = this->ifaces->create_enumerator(this->ifaces);
835 while (enumerator->enumerate(enumerator, &iface))
836 {
837 if (iface->ifindex == msg->ifm_index)
838 {
839 if (iface->usable)
840 {
841 if (!(iface->flags & IFF_UP) && (msg->ifm_flags & IFF_UP))
842 {
843 roam = update_routes = TRUE;
844 DBG1(DBG_KNL, "interface %s activated", iface->ifname);
845 }
846 else if ((iface->flags & IFF_UP) && !(msg->ifm_flags & IFF_UP))
847 {
848 roam = TRUE;
849 DBG1(DBG_KNL, "interface %s deactivated", iface->ifname);
850 }
851 }
852 #ifdef __APPLE__
853 /* There seems to be a race condition on 10.10, where we get
854 * the RTM_IFINFO, but getifaddrs() does not return the virtual
855 * IP installed on a tun device, but we also don't get a
856 * RTM_NEWADDR. We therefore could miss the new address, letting
857 * virtual IP installation fail. Delaying getifaddrs() helps,
858 * but is obviously not a clean fix. */
859 usleep(50000);
860 #endif
861 iface->flags = msg->ifm_flags;
862 repopulate_iface(this, iface);
863 found = TRUE;
864 break;
865 }
866 }
867 enumerator->destroy(enumerator);
868
869 if (!found)
870 {
871 INIT(iface,
872 .ifindex = msg->ifm_index,
873 .flags = msg->ifm_flags,
874 .addrs = linked_list_create(),
875 );
876 #ifdef __APPLE__
877 /* Similar to the issue described above, on 10.13 we need this delay as
878 * we might otherwise not be able to convert the index to a name yet. */
879 usleep(50000);
880 #endif
881 if (if_indextoname(iface->ifindex, iface->ifname))
882 {
883 DBG1(DBG_KNL, "interface %s appeared", iface->ifname);
884 iface->usable = charon->kernel->is_interface_usable(charon->kernel,
885 iface->ifname);
886 repopulate_iface(this, iface);
887 this->ifaces->insert_last(this->ifaces, iface);
888 if (iface->usable)
889 {
890 roam = update_routes = TRUE;
891 }
892 }
893 else
894 {
895 free(iface);
896 }
897 }
898 this->lock->unlock(this->lock);
899
900 if (update_routes)
901 {
902 queue_route_reinstall(this, strdup(iface->ifname));
903 }
904
905 if (roam)
906 {
907 fire_roam_event(this, TRUE);
908 }
909 }
910
911 #ifdef HAVE_RTM_IFANNOUNCE
912
913 /**
914 * Process an RTM_IFANNOUNCE message from the kernel
915 */
916 static void process_announce(private_kernel_pfroute_net_t *this,
917 struct if_announcemsghdr *msg)
918 {
919 enumerator_t *enumerator;
920 iface_entry_t *iface;
921
922 if (msg->ifan_what != IFAN_DEPARTURE)
923 {
924 /* we handle new interfaces in process_link() */
925 return;
926 }
927
928 this->lock->write_lock(this->lock);
929 enumerator = this->ifaces->create_enumerator(this->ifaces);
930 while (enumerator->enumerate(enumerator, &iface))
931 {
932 if (iface->ifindex == msg->ifan_index)
933 {
934 DBG1(DBG_KNL, "interface %s disappeared", iface->ifname);
935 this->ifaces->remove_at(this->ifaces, enumerator);
936 iface_entry_destroy(iface);
937 break;
938 }
939 }
940 enumerator->destroy(enumerator);
941 this->lock->unlock(this->lock);
942 }
943
944 #endif /* HAVE_RTM_IFANNOUNCE */
945
946 /**
947 * Process an RTM_*ROUTE message from the kernel
948 */
949 static void process_route(private_kernel_pfroute_net_t *this,
950 struct rt_msghdr *msg)
951 {
952
953 }
954
955 /**
956 * Receives PF_ROUTE messages from kernel
957 */
958 static bool receive_events(private_kernel_pfroute_net_t *this, int fd,
959 watcher_event_t event)
960 {
961 struct {
962 union {
963 struct rt_msghdr rtm;
964 struct if_msghdr ifm;
965 struct ifa_msghdr ifam;
966 #ifdef HAVE_RTM_IFANNOUNCE
967 struct if_announcemsghdr ifanm;
968 #endif
969 };
970 char buf[sizeof(struct sockaddr_storage) * RTAX_MAX];
971 } msg;
972 int len, hdrlen;
973
974 len = recv(this->socket, &msg, sizeof(msg), MSG_DONTWAIT);
975 if (len < 0)
976 {
977 switch (errno)
978 {
979 case EINTR:
980 case EAGAIN:
981 return TRUE;
982 default:
983 DBG1(DBG_KNL, "unable to receive from PF_ROUTE event socket");
984 sleep(1);
985 return TRUE;
986 }
987 }
988
989 if (len < offsetof(struct rt_msghdr, rtm_flags) || len < msg.rtm.rtm_msglen)
990 {
991 DBG1(DBG_KNL, "received invalid PF_ROUTE message");
992 return TRUE;
993 }
994 if (msg.rtm.rtm_version != RTM_VERSION)
995 {
996 DBG1(DBG_KNL, "received PF_ROUTE message with unsupported version: %d",
997 msg.rtm.rtm_version);
998 return TRUE;
999 }
1000 switch (msg.rtm.rtm_type)
1001 {
1002 case RTM_NEWADDR:
1003 case RTM_DELADDR:
1004 hdrlen = sizeof(msg.ifam);
1005 break;
1006 case RTM_IFINFO:
1007 hdrlen = sizeof(msg.ifm);
1008 break;
1009 #ifdef HAVE_RTM_IFANNOUNCE
1010 case RTM_IFANNOUNCE:
1011 hdrlen = sizeof(msg.ifanm);
1012 break;
1013 #endif /* HAVE_RTM_IFANNOUNCE */
1014 case RTM_ADD:
1015 case RTM_DELETE:
1016 case RTM_GET:
1017 hdrlen = sizeof(msg.rtm);
1018 break;
1019 default:
1020 return TRUE;
1021 }
1022 if (msg.rtm.rtm_msglen < hdrlen)
1023 {
1024 DBG1(DBG_KNL, "ignoring short PF_ROUTE message");
1025 return TRUE;
1026 }
1027 switch (msg.rtm.rtm_type)
1028 {
1029 case RTM_NEWADDR:
1030 case RTM_DELADDR:
1031 process_addr(this, &msg.ifam);
1032 break;
1033 case RTM_IFINFO:
1034 process_link(this, &msg.ifm);
1035 break;
1036 #ifdef HAVE_RTM_IFANNOUNCE
1037 case RTM_IFANNOUNCE:
1038 process_announce(this, &msg.ifanm);
1039 break;
1040 #endif /* HAVE_RTM_IFANNOUNCE */
1041 case RTM_ADD:
1042 case RTM_DELETE:
1043 process_route(this, &msg.rtm);
1044 break;
1045 default:
1046 break;
1047 }
1048
1049 this->mutex->lock(this->mutex);
1050 if (msg.rtm.rtm_pid == this->pid && msg.rtm.rtm_seq == this->waiting_seq)
1051 {
1052 /* seems like the message someone is waiting for, deliver */
1053 this->reply = realloc(this->reply, msg.rtm.rtm_msglen);
1054 memcpy(this->reply, &msg, msg.rtm.rtm_msglen);
1055 }
1056 /* signal on any event, add_ip()/del_ip() might wait for it */
1057 this->condvar->broadcast(this->condvar);
1058 this->mutex->unlock(this->mutex);
1059
1060 return TRUE;
1061 }
1062
1063
1064 /** enumerator over addresses */
1065 typedef struct {
1066 private_kernel_pfroute_net_t* this;
1067 /** which addresses to enumerate */
1068 kernel_address_type_t which;
1069 } address_enumerator_t;
1070
1071 CALLBACK(address_enumerator_destroy, void,
1072 address_enumerator_t *data)
1073 {
1074 data->this->lock->unlock(data->this->lock);
1075 free(data);
1076 }
1077
1078 CALLBACK(filter_addresses, bool,
1079 address_enumerator_t *data, enumerator_t *orig, va_list args)
1080 {
1081 addr_entry_t *addr;
1082 host_t *ip, **out;
1083 struct sockaddr_in6 *sin6;
1084
1085 VA_ARGS_VGET(args, out);
1086
1087 while (orig->enumerate(orig, &addr))
1088 {
1089 if (!(data->which & ADDR_TYPE_VIRTUAL) && addr->virtual)
1090 { /* skip virtual interfaces added by us */
1091 continue;
1092 }
1093 if (!(data->which & ADDR_TYPE_REGULAR) && !addr->virtual)
1094 { /* address is regular, but not requested */
1095 continue;
1096 }
1097 ip = addr->ip;
1098 if (ip->get_family(ip) == AF_INET6)
1099 {
1100 sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip);
1101 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
1102 { /* skip addresses with a unusable scope */
1103 continue;
1104 }
1105 }
1106 *out = ip;
1107 return TRUE;
1108 }
1109 return FALSE;
1110 }
1111
1112 /**
1113 * enumerator constructor for interfaces
1114 */
1115 static enumerator_t *create_iface_enumerator(iface_entry_t *iface,
1116 address_enumerator_t *data)
1117 {
1118 return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs),
1119 filter_addresses, data, NULL);
1120 }
1121
1122 CALLBACK(filter_interfaces, bool,
1123 address_enumerator_t *data, enumerator_t *orig, va_list args)
1124 {
1125 iface_entry_t *iface, **out;
1126
1127 VA_ARGS_VGET(args, out);
1128
1129 while (orig->enumerate(orig, &iface))
1130 {
1131 if (!(data->which & ADDR_TYPE_IGNORED) && !iface->usable)
1132 { /* skip interfaces excluded by config */
1133 continue;
1134 }
1135 if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK))
1136 { /* ignore loopback devices */
1137 continue;
1138 }
1139 if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP))
1140 { /* skip interfaces not up */
1141 continue;
1142 }
1143 *out = iface;
1144 return TRUE;
1145 }
1146 return FALSE;
1147 }
1148
1149 METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
1150 private_kernel_pfroute_net_t *this, kernel_address_type_t which)
1151 {
1152 address_enumerator_t *data;
1153
1154 INIT(data,
1155 .this = this,
1156 .which = which,
1157 );
1158
1159 this->lock->read_lock(this->lock);
1160 return enumerator_create_nested(
1161 enumerator_create_filter(
1162 this->ifaces->create_enumerator(this->ifaces),
1163 filter_interfaces, data, NULL),
1164 (void*)create_iface_enumerator, data,
1165 address_enumerator_destroy);
1166 }
1167
1168 METHOD(kernel_net_t, get_features, kernel_feature_t,
1169 private_kernel_pfroute_net_t *this)
1170 {
1171 return KERNEL_REQUIRE_EXCLUDE_ROUTE;
1172 }
1173
1174 METHOD(kernel_net_t, get_interface_name, bool,
1175 private_kernel_pfroute_net_t *this, host_t* ip, char **name)
1176 {
1177 addr_map_entry_t *entry, lookup = {
1178 .ip = ip,
1179 };
1180
1181 if (ip->is_anyaddr(ip))
1182 {
1183 return FALSE;
1184 }
1185 this->lock->read_lock(this->lock);
1186 /* first try to find it on an up and usable interface */
1187 entry = this->addrs->get_match(this->addrs, &lookup,
1188 (void*)addr_map_entry_match_up_and_usable);
1189 if (entry)
1190 {
1191 if (name)
1192 {
1193 *name = strdup(entry->iface->ifname);
1194 DBG2(DBG_KNL, "%H is on interface %s", ip, *name);
1195 }
1196 this->lock->unlock(this->lock);
1197 return TRUE;
1198 }
1199 /* check if it is a virtual IP */
1200 entry = this->addrs->get_match(this->addrs, &lookup,
1201 (void*)addr_map_entry_match_virtual);
1202 if (entry)
1203 {
1204 if (name)
1205 {
1206 *name = strdup(entry->iface->ifname);
1207 DBG2(DBG_KNL, "virtual IP %H is on interface %s", ip, *name);
1208 }
1209 this->lock->unlock(this->lock);
1210 return TRUE;
1211 }
1212 /* maybe it is installed on an ignored interface */
1213 entry = this->addrs->get_match(this->addrs, &lookup,
1214 (void*)addr_map_entry_match_up);
1215 if (!entry)
1216 { /* the address does not exist, is on a down interface */
1217 DBG2(DBG_KNL, "%H is not a local address or the interface is down", ip);
1218 }
1219 this->lock->unlock(this->lock);
1220 return FALSE;
1221 }
1222
1223 METHOD(kernel_net_t, add_ip, status_t,
1224 private_kernel_pfroute_net_t *this, host_t *vip, int prefix,
1225 char *ifname)
1226 {
1227 enumerator_t *ifaces, *addrs;
1228 iface_entry_t *iface;
1229 addr_entry_t *addr;
1230 tun_device_t *tun;
1231 bool timeout = FALSE;
1232
1233 if (!this->install_virtual_ip)
1234 { /* disabled by config */
1235 return SUCCESS;
1236 }
1237
1238 tun = tun_device_create(NULL);
1239 if (!tun)
1240 {
1241 return FAILED;
1242 }
1243 if (prefix == -1)
1244 {
1245 prefix = vip->get_address(vip).len * 8;
1246 }
1247 if (!tun->up(tun) || !tun->set_address(tun, vip, prefix) ||
1248 !tun->set_mtu(tun, this->mtu))
1249 {
1250 tun->destroy(tun);
1251 return FAILED;
1252 }
1253
1254 /* wait until address appears */
1255 this->mutex->lock(this->mutex);
1256 while (!timeout && !get_interface_name(this, vip, NULL))
1257 {
1258 timeout = this->condvar->timed_wait(this->condvar, this->mutex,
1259 this->vip_wait);
1260 }
1261 this->mutex->unlock(this->mutex);
1262 if (timeout)
1263 {
1264 DBG1(DBG_KNL, "virtual IP %H did not appear on %s",
1265 vip, tun->get_name(tun));
1266 tun->destroy(tun);
1267 return FAILED;
1268 }
1269
1270 this->lock->write_lock(this->lock);
1271 this->tuns->insert_last(this->tuns, tun);
1272
1273 ifaces = this->ifaces->create_enumerator(this->ifaces);
1274 while (ifaces->enumerate(ifaces, &iface))
1275 {
1276 if (streq(iface->ifname, tun->get_name(tun)))
1277 {
1278 addrs = iface->addrs->create_enumerator(iface->addrs);
1279 while (addrs->enumerate(addrs, &addr))
1280 {
1281 if (addr->ip->ip_equals(addr->ip, vip))
1282 {
1283 addr->virtual = TRUE;
1284 }
1285 }
1286 addrs->destroy(addrs);
1287 /* during IKEv1 reauthentication, children get moved from
1288 * old the new SA before the virtual IP is available. This
1289 * kills the route for our virtual IP, reinstall. */
1290 queue_route_reinstall(this, strdup(iface->ifname));
1291 break;
1292 }
1293 }
1294 ifaces->destroy(ifaces);
1295 /* lets do this while holding the lock, thus preventing another thread
1296 * from deleting the TUN device concurrently, hopefully listeners are quick
1297 * and cause no deadlocks */
1298 charon->kernel->tun(charon->kernel, tun, TRUE);
1299 this->lock->unlock(this->lock);
1300
1301 return SUCCESS;
1302 }
1303
1304 METHOD(kernel_net_t, del_ip, status_t,
1305 private_kernel_pfroute_net_t *this, host_t *vip, int prefix,
1306 bool wait)
1307 {
1308 enumerator_t *enumerator;
1309 tun_device_t *tun;
1310 host_t *addr;
1311 bool timeout = FALSE, found = FALSE;
1312
1313 if (!this->install_virtual_ip)
1314 { /* disabled by config */
1315 return SUCCESS;
1316 }
1317
1318 this->lock->write_lock(this->lock);
1319 enumerator = this->tuns->create_enumerator(this->tuns);
1320 while (enumerator->enumerate(enumerator, &tun))
1321 {
1322 addr = tun->get_address(tun, NULL);
1323 if (addr && addr->ip_equals(addr, vip))
1324 {
1325 this->tuns->remove_at(this->tuns, enumerator);
1326 charon->kernel->tun(charon->kernel, tun, FALSE);
1327 tun->destroy(tun);
1328 found = TRUE;
1329 break;
1330 }
1331 }
1332 enumerator->destroy(enumerator);
1333 this->lock->unlock(this->lock);
1334
1335 if (!found)
1336 {
1337 return NOT_FOUND;
1338 }
1339 /* wait until address disappears */
1340 if (wait)
1341 {
1342 this->mutex->lock(this->mutex);
1343 while (!timeout && get_interface_name(this, vip, NULL))
1344 {
1345 timeout = this->condvar->timed_wait(this->condvar, this->mutex,
1346 this->vip_wait);
1347 }
1348 this->mutex->unlock(this->mutex);
1349 if (timeout)
1350 {
1351 DBG1(DBG_KNL, "virtual IP %H did not disappear from tun", vip);
1352 return FAILED;
1353 }
1354 }
1355 return SUCCESS;
1356 }
1357
1358 /**
1359 * Append a sockaddr_in/in6 of given type to routing message
1360 */
1361 static void add_rt_addr(struct rt_msghdr *hdr, int type, host_t *addr)
1362 {
1363 if (addr)
1364 {
1365 int len;
1366
1367 len = *addr->get_sockaddr_len(addr);
1368 memcpy((char*)hdr + hdr->rtm_msglen, addr->get_sockaddr(addr), len);
1369 hdr->rtm_msglen += SA_LEN(len);
1370 hdr->rtm_addrs |= type;
1371 }
1372 }
1373
1374 /**
1375 * Append a subnet mask sockaddr using the given prefix to routing message
1376 */
1377 static void add_rt_mask(struct rt_msghdr *hdr, int type, int family, int prefix)
1378 {
1379 host_t *mask;
1380
1381 mask = host_create_netmask(family, prefix);
1382 if (mask)
1383 {
1384 add_rt_addr(hdr, type, mask);
1385 mask->destroy(mask);
1386 }
1387 }
1388
1389 /**
1390 * Append an interface name sockaddr_dl to routing message
1391 */
1392 static void add_rt_ifname(struct rt_msghdr *hdr, int type, char *name)
1393 {
1394 struct sockaddr_dl sdl = {
1395 .sdl_len = sizeof(struct sockaddr_dl),
1396 .sdl_family = AF_LINK,
1397 .sdl_nlen = strlen(name),
1398 };
1399
1400 if (strlen(name) <= sizeof(sdl.sdl_data))
1401 {
1402 memcpy(sdl.sdl_data, name, sdl.sdl_nlen);
1403 memcpy((char*)hdr + hdr->rtm_msglen, &sdl, sdl.sdl_len);
1404 hdr->rtm_msglen += SA_LEN(sdl.sdl_len);
1405 hdr->rtm_addrs |= type;
1406 }
1407 }
1408
1409 /**
1410 * Add or remove a route
1411 */
1412 static status_t manage_route(private_kernel_pfroute_net_t *this, int op,
1413 chunk_t dst_net, uint8_t prefixlen,
1414 host_t *gateway, char *if_name)
1415 {
1416 struct {
1417 struct rt_msghdr hdr;
1418 char buf[sizeof(struct sockaddr_storage) * RTAX_MAX];
1419 } msg = {
1420 .hdr = {
1421 .rtm_version = RTM_VERSION,
1422 .rtm_type = op,
1423 .rtm_flags = RTF_UP | RTF_STATIC,
1424 .rtm_pid = this->pid,
1425 .rtm_seq = ref_get(&this->seq),
1426 },
1427 };
1428 host_t *dst;
1429 int type;
1430
1431 if (prefixlen == 0 && dst_net.len)
1432 {
1433 status_t status;
1434 chunk_t half;
1435
1436 half = chunk_clonea(dst_net);
1437 half.ptr[0] |= 0x80;
1438 prefixlen = 1;
1439 status = manage_route(this, op, half, prefixlen, gateway, if_name);
1440 if (status != SUCCESS)
1441 {
1442 return status;
1443 }
1444 }
1445
1446 dst = host_create_from_chunk(AF_UNSPEC, dst_net, 0);
1447 if (!dst)
1448 {
1449 return FAILED;
1450 }
1451
1452 if ((dst->get_family(dst) == AF_INET && prefixlen == 32) ||
1453 (dst->get_family(dst) == AF_INET6 && prefixlen == 128))
1454 {
1455 msg.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY;
1456 }
1457
1458 msg.hdr.rtm_msglen = sizeof(struct rt_msghdr);
1459 for (type = 0; type < RTAX_MAX; type++)
1460 {
1461 switch (type)
1462 {
1463 case RTAX_DST:
1464 add_rt_addr(&msg.hdr, RTA_DST, dst);
1465 break;
1466 case RTAX_NETMASK:
1467 if (!(msg.hdr.rtm_flags & RTF_HOST))
1468 {
1469 add_rt_mask(&msg.hdr, RTA_NETMASK,
1470 dst->get_family(dst), prefixlen);
1471 }
1472 break;
1473 case RTAX_IFP:
1474 if (if_name)
1475 {
1476 add_rt_ifname(&msg.hdr, RTA_IFP, if_name);
1477 }
1478 break;
1479 case RTAX_GATEWAY:
1480 if (gateway &&
1481 gateway->get_family(gateway) == dst->get_family(dst))
1482 {
1483 add_rt_addr(&msg.hdr, RTA_GATEWAY, gateway);
1484 }
1485 break;
1486 default:
1487 break;
1488 }
1489 }
1490 dst->destroy(dst);
1491
1492 if (send(this->socket, &msg, msg.hdr.rtm_msglen, 0) != msg.hdr.rtm_msglen)
1493 {
1494 if (errno == EEXIST)
1495 {
1496 return ALREADY_DONE;
1497 }
1498 DBG1(DBG_KNL, "%s PF_ROUTE route failed: %s",
1499 op == RTM_ADD ? "adding" : "deleting", strerror(errno));
1500 return FAILED;
1501 }
1502 return SUCCESS;
1503 }
1504
1505 METHOD(kernel_net_t, add_route, status_t,
1506 private_kernel_pfroute_net_t *this, chunk_t dst_net, uint8_t prefixlen,
1507 host_t *gateway, host_t *src_ip, char *if_name, bool pass)
1508 {
1509 status_t status;
1510 route_entry_t *found, route = {
1511 .dst_net = dst_net,
1512 .prefixlen = prefixlen,
1513 .gateway = gateway,
1514 .if_name = if_name,
1515 };
1516
1517 this->routes_lock->lock(this->routes_lock);
1518 found = this->routes->get(this->routes, &route);
1519 if (found)
1520 {
1521 this->routes_lock->unlock(this->routes_lock);
1522 return ALREADY_DONE;
1523 }
1524 status = manage_route(this, RTM_ADD, dst_net, prefixlen, gateway, if_name);
1525 if (status == SUCCESS)
1526 {
1527 found = route_entry_clone(&route);
1528 this->routes->put(this->routes, found, found);
1529 }
1530 this->routes_lock->unlock(this->routes_lock);
1531 return status;
1532 }
1533
1534 METHOD(kernel_net_t, del_route, status_t,
1535 private_kernel_pfroute_net_t *this, chunk_t dst_net, uint8_t prefixlen,
1536 host_t *gateway, host_t *src_ip, char *if_name, bool pass)
1537 {
1538 status_t status;
1539 route_entry_t *found, route = {
1540 .dst_net = dst_net,
1541 .prefixlen = prefixlen,
1542 .gateway = gateway,
1543 .if_name = if_name,
1544 };
1545
1546 this->routes_lock->lock(this->routes_lock);
1547 found = this->routes->get(this->routes, &route);
1548 if (!found)
1549 {
1550 this->routes_lock->unlock(this->routes_lock);
1551 return NOT_FOUND;
1552 }
1553 this->routes->remove(this->routes, found);
1554 route_entry_destroy(found);
1555 status = manage_route(this, RTM_DELETE, dst_net, prefixlen, gateway,
1556 if_name);
1557 this->routes_lock->unlock(this->routes_lock);
1558 return status;
1559 }
1560
1561 /**
1562 * Do a route lookup for dest and return either the nexthop or the source
1563 * address.
1564 */
1565 static host_t *get_route(private_kernel_pfroute_net_t *this, bool nexthop,
1566 host_t *dest, host_t *src, char **iface)
1567 {
1568 struct {
1569 struct rt_msghdr hdr;
1570 char buf[sizeof(struct sockaddr_storage) * RTAX_MAX];
1571 } msg = {
1572 .hdr = {
1573 .rtm_version = RTM_VERSION,
1574 .rtm_type = RTM_GET,
1575 .rtm_pid = this->pid,
1576 .rtm_seq = ref_get(&this->seq),
1577 },
1578 };
1579 host_t *host = NULL;
1580 enumerator_t *enumerator;
1581 struct sockaddr *addr;
1582 bool failed = FALSE;
1583 int type;
1584
1585 retry:
1586 msg.hdr.rtm_msglen = sizeof(struct rt_msghdr);
1587 for (type = 0; type < RTAX_MAX; type++)
1588 {
1589 switch (type)
1590 {
1591 case RTAX_DST:
1592 add_rt_addr(&msg.hdr, RTA_DST, dest);
1593 break;
1594 case RTAX_IFA:
1595 add_rt_addr(&msg.hdr, RTA_IFA, src);
1596 break;
1597 case RTAX_IFP:
1598 if (!nexthop)
1599 { /* add an empty IFP to ensure we get a source address */
1600 add_rt_ifname(&msg.hdr, RTA_IFP, "");
1601 }
1602 break;
1603 default:
1604 break;
1605 }
1606 }
1607 this->mutex->lock(this->mutex);
1608
1609 while (this->waiting_seq)
1610 {
1611 this->condvar->wait(this->condvar, this->mutex);
1612 }
1613 this->waiting_seq = msg.hdr.rtm_seq;
1614 if (send(this->socket, &msg, msg.hdr.rtm_msglen, 0) == msg.hdr.rtm_msglen)
1615 {
1616 while (TRUE)
1617 {
1618 if (this->condvar->timed_wait(this->condvar, this->mutex, 1000))
1619 { /* timed out? */
1620 break;
1621 }
1622 if (!this->reply)
1623 {
1624 continue;
1625 }
1626 enumerator = create_rtmsg_enumerator(this->reply);
1627 while (enumerator->enumerate(enumerator, &type, &addr))
1628 {
1629 if (nexthop)
1630 {
1631 if (type == RTAX_DST && this->reply->rtm_flags & RTF_HOST)
1632 { /* probably a cloned/cached direct route, only use that
1633 * as fallback if no gateway is found */
1634 host = host ?: host_create_from_sockaddr(addr);
1635 }
1636 if (type == RTAX_GATEWAY)
1637 { /* could actually be a MAC address */
1638 host_t *gtw = host_create_from_sockaddr(addr);
1639 if (gtw)
1640 {
1641 DESTROY_IF(host);
1642 host = gtw;
1643 }
1644 }
1645 if (type == RTAX_IFP && addr->sa_family == AF_LINK)
1646 {
1647 struct sockaddr_dl *sdl = (struct sockaddr_dl*)addr;
1648 if (iface)
1649 {
1650 free(*iface);
1651 *iface = strndup(sdl->sdl_data, sdl->sdl_nlen);
1652 }
1653 }
1654 }
1655 else
1656 {
1657 if (type == RTAX_IFA)
1658 {
1659 host = host_create_from_sockaddr(addr);
1660 }
1661 }
1662 }
1663 enumerator->destroy(enumerator);
1664 break;
1665 }
1666 }
1667 else
1668 {
1669 failed = TRUE;
1670 }
1671 free(this->reply);
1672 this->reply = NULL;
1673 /* signal completion of query to a waiting thread */
1674 this->waiting_seq = 0;
1675 this->condvar->signal(this->condvar);
1676 this->mutex->unlock(this->mutex);
1677
1678 if (failed)
1679 {
1680 if (src)
1681 { /* the given source address might be gone, try again without */
1682 src = NULL;
1683 msg.hdr.rtm_seq = ref_get(&this->seq);
1684 msg.hdr.rtm_addrs = 0;
1685 memset(msg.buf, 0, sizeof(msg.buf));
1686 goto retry;
1687 }
1688 DBG1(DBG_KNL, "PF_ROUTE lookup failed: %s", strerror(errno));
1689 }
1690 if (nexthop)
1691 {
1692 host = host ?: dest->clone(dest);
1693 }
1694 else
1695 { /* make sure the source address is not virtual and usable */
1696 addr_entry_t *entry, lookup = {
1697 .ip = host,
1698 };
1699
1700 if (!host)
1701 {
1702 return NULL;
1703 }
1704 this->lock->read_lock(this->lock);
1705 entry = this->addrs->get_match(this->addrs, &lookup,
1706 (void*)addr_map_entry_match_up_and_usable);
1707 this->lock->unlock(this->lock);
1708 if (!entry)
1709 {
1710 host->destroy(host);
1711 return NULL;
1712 }
1713 }
1714 DBG2(DBG_KNL, "using %H as %s to reach %H", host,
1715 nexthop ? "nexthop" : "address", dest);
1716 return host;
1717 }
1718
1719 METHOD(kernel_net_t, get_source_addr, host_t*,
1720 private_kernel_pfroute_net_t *this, host_t *dest, host_t *src)
1721 {
1722 return get_route(this, FALSE, dest, src, NULL);
1723 }
1724
1725 METHOD(kernel_net_t, get_nexthop, host_t*,
1726 private_kernel_pfroute_net_t *this, host_t *dest, int prefix, host_t *src,
1727 char **iface)
1728 {
1729 if (iface)
1730 {
1731 *iface = NULL;
1732 }
1733 return get_route(this, TRUE, dest, src, iface);
1734 }
1735
1736 /**
1737 * Get the number of set bits in the given netmask
1738 */
1739 static uint8_t sockaddr_to_netmask(sockaddr_t *sockaddr, host_t *dst)
1740 {
1741 uint8_t len = 0, i, byte, mask = 0;
1742 struct sockaddr_storage ss;
1743 char *addr;
1744
1745 /* at least some older FreeBSD versions send us shorter sockaddrs
1746 * with the family set to -1 (255) */
1747 if (sockaddr->sa_family == 255)
1748 {
1749 memset(&ss, 0, sizeof(ss));
1750 memcpy(&ss, sockaddr, sockaddr->sa_len);
1751 /* use the address family and length of the destination as hint */
1752 ss.ss_len = *dst->get_sockaddr_len(dst);
1753 ss.ss_family = dst->get_family(dst);
1754 sockaddr = (sockaddr_t*)&ss;
1755 }
1756
1757 switch (sockaddr->sa_family)
1758 {
1759 case AF_INET:
1760 len = 4;
1761 addr = (char*)&((struct sockaddr_in*)sockaddr)->sin_addr;
1762 break;
1763 case AF_INET6:
1764 len = 16;
1765 addr = (char*)&((struct sockaddr_in6*)sockaddr)->sin6_addr;
1766 break;
1767 default:
1768 break;
1769 }
1770
1771 for (i = 0; i < len; i++)
1772 {
1773 byte = addr[i];
1774
1775 if (byte == 0x00)
1776 {
1777 break;
1778 }
1779 if (byte == 0xff)
1780 {
1781 mask += 8;
1782 }
1783 else
1784 {
1785 while (byte & 0x80)
1786 {
1787 mask++;
1788 byte <<= 1;
1789 }
1790 }
1791 }
1792 return mask;
1793 }
1794
1795 /** enumerator over subnets */
1796 typedef struct {
1797 enumerator_t public;
1798 /** sysctl result */
1799 char *buf;
1800 /** length of the complete result */
1801 size_t len;
1802 /** start of the current route entry */
1803 char *current;
1804 /** last subnet enumerated */
1805 host_t *net;
1806 /** interface of current net */
1807 char *ifname;
1808 } subnet_enumerator_t;
1809
1810 METHOD(enumerator_t, destroy_subnet_enumerator, void,
1811 subnet_enumerator_t *this)
1812 {
1813 DESTROY_IF(this->net);
1814 free(this->ifname);
1815 free(this->buf);
1816 free(this);
1817 }
1818
1819 METHOD(enumerator_t, enumerate_subnets, bool,
1820 subnet_enumerator_t *this, va_list args)
1821 {
1822 enumerator_t *enumerator;
1823 host_t **net;
1824 struct rt_msghdr *rtm;
1825 struct sockaddr *addr;
1826 uint8_t *mask;
1827 char **ifname;
1828 int type;
1829
1830 VA_ARGS_VGET(args, net, mask, ifname);
1831
1832 if (!this->current)
1833 {
1834 this->current = this->buf;
1835 }
1836 else
1837 {
1838 rtm = (struct rt_msghdr*)this->current;
1839 this->current += rtm->rtm_msglen;
1840 DESTROY_IF(this->net);
1841 this->net = NULL;
1842 free(this->ifname);
1843 this->ifname = NULL;
1844 }
1845
1846 for (; this->current < this->buf + this->len;
1847 this->current += rtm->rtm_msglen)
1848 {
1849 struct sockaddr *netmask = NULL;
1850 uint8_t netbits = 0;
1851
1852 rtm = (struct rt_msghdr*)this->current;
1853
1854 if (rtm->rtm_version != RTM_VERSION)
1855 {
1856 continue;
1857 }
1858 if (rtm->rtm_flags & RTF_GATEWAY ||
1859 rtm->rtm_flags & RTF_HOST ||
1860 rtm->rtm_flags & RTF_REJECT)
1861 {
1862 continue;
1863 }
1864 enumerator = create_rtmsg_enumerator(rtm);
1865 while (enumerator->enumerate(enumerator, &type, &addr))
1866 {
1867 if (type == RTAX_DST)
1868 {
1869 this->net = this->net ?: host_create_from_sockaddr(addr);
1870 }
1871 if (type == RTAX_NETMASK)
1872 {
1873 netmask = addr;
1874 }
1875 if (type == RTAX_IFP && addr->sa_family == AF_LINK)
1876 {
1877 struct sockaddr_dl *sdl = (struct sockaddr_dl*)addr;
1878 free(this->ifname);
1879 this->ifname = strndup(sdl->sdl_data, sdl->sdl_nlen);
1880 }
1881 }
1882 if (this->net && netmask)
1883 {
1884 netbits = sockaddr_to_netmask(netmask, this->net);
1885 }
1886 enumerator->destroy(enumerator);
1887
1888 if (this->net && this->ifname)
1889 {
1890 *net = this->net;
1891 *mask = netbits ?: this->net->get_address(this->net).len * 8;
1892 *ifname = this->ifname;
1893 return TRUE;
1894 }
1895 }
1896 return FALSE;
1897 }
1898
1899 METHOD(kernel_net_t, create_local_subnet_enumerator, enumerator_t*,
1900 private_kernel_pfroute_net_t *this)
1901 {
1902 subnet_enumerator_t *enumerator;
1903 char *buf;
1904 size_t len;
1905 int mib[7] = {
1906 CTL_NET, PF_ROUTE, 0, AF_UNSPEC, NET_RT_DUMP, 0, 0
1907 };
1908
1909 if (sysctl(mib, countof(mib), NULL, &len, NULL, 0) < 0)
1910 {
1911 DBG2(DBG_KNL, "enumerating local subnets failed");
1912 return enumerator_create_empty();
1913 }
1914 buf = malloc(len);
1915 if (sysctl(mib, countof(mib), buf, &len, NULL, 0) < 0)
1916 {
1917 DBG2(DBG_KNL, "enumerating local subnets failed");
1918 free(buf);
1919 return enumerator_create_empty();
1920 }
1921
1922 INIT(enumerator,
1923 .public = {
1924 .enumerate = enumerator_enumerate_default,
1925 .venumerate = _enumerate_subnets,
1926 .destroy = _destroy_subnet_enumerator,
1927 },
1928 .buf = buf,
1929 .len = len,
1930 );
1931 return &enumerator->public;
1932 }
1933
1934 /**
1935 * Initialize a list of local addresses.
1936 */
1937 static status_t init_address_list(private_kernel_pfroute_net_t *this)
1938 {
1939 struct ifaddrs *ifap, *ifa;
1940 iface_entry_t *iface, *current;
1941 addr_entry_t *addr;
1942 enumerator_t *ifaces, *addrs;
1943
1944 DBG2(DBG_KNL, "known interfaces and IP addresses:");
1945
1946 if (getifaddrs(&ifap) < 0)
1947 {
1948 DBG1(DBG_KNL, " failed to get interfaces!");
1949 return FAILED;
1950 }
1951
1952 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
1953 {
1954 if (ifa->ifa_addr == NULL)
1955 {
1956 continue;
1957 }
1958 switch(ifa->ifa_addr->sa_family)
1959 {
1960 case AF_LINK:
1961 case AF_INET:
1962 case AF_INET6:
1963 {
1964 iface = NULL;
1965 ifaces = this->ifaces->create_enumerator(this->ifaces);
1966 while (ifaces->enumerate(ifaces, &current))
1967 {
1968 if (streq(current->ifname, ifa->ifa_name))
1969 {
1970 iface = current;
1971 break;
1972 }
1973 }
1974 ifaces->destroy(ifaces);
1975
1976 if (!iface)
1977 {
1978 INIT(iface,
1979 .ifindex = if_nametoindex(ifa->ifa_name),
1980 .flags = ifa->ifa_flags,
1981 .addrs = linked_list_create(),
1982 .usable = charon->kernel->is_interface_usable(
1983 charon->kernel, ifa->ifa_name),
1984 );
1985 memcpy(iface->ifname, ifa->ifa_name, IFNAMSIZ);
1986 this->ifaces->insert_last(this->ifaces, iface);
1987 }
1988
1989 if (ifa->ifa_addr->sa_family != AF_LINK)
1990 {
1991 INIT(addr,
1992 .ip = host_create_from_sockaddr(ifa->ifa_addr),
1993 );
1994 iface->addrs->insert_last(iface->addrs, addr);
1995 addr_map_entry_add(this, addr, iface);
1996 }
1997 }
1998 }
1999 }
2000 freeifaddrs(ifap);
2001
2002 ifaces = this->ifaces->create_enumerator(this->ifaces);
2003 while (ifaces->enumerate(ifaces, &iface))
2004 {
2005 if (iface->usable && iface->flags & IFF_UP)
2006 {
2007 DBG2(DBG_KNL, " %s", iface->ifname);
2008 addrs = iface->addrs->create_enumerator(iface->addrs);
2009 while (addrs->enumerate(addrs, (void**)&addr))
2010 {
2011 DBG2(DBG_KNL, " %H", addr->ip);
2012 }
2013 addrs->destroy(addrs);
2014 }
2015 }
2016 ifaces->destroy(ifaces);
2017
2018 return SUCCESS;
2019 }
2020
2021 METHOD(kernel_net_t, destroy, void,
2022 private_kernel_pfroute_net_t *this)
2023 {
2024 enumerator_t *enumerator;
2025 route_entry_t *route;
2026
2027 enumerator = this->routes->create_enumerator(this->routes);
2028 while (enumerator->enumerate(enumerator, NULL, (void**)&route))
2029 {
2030 manage_route(this, RTM_DELETE, route->dst_net, route->prefixlen,
2031 route->gateway, route->if_name);
2032 route_entry_destroy(route);
2033 }
2034 enumerator->destroy(enumerator);
2035 this->routes->destroy(this->routes);
2036 this->routes_lock->destroy(this->routes_lock);
2037
2038 if (this->socket != -1)
2039 {
2040 lib->watcher->remove(lib->watcher, this->socket);
2041 close(this->socket);
2042 }
2043
2044 net_changes_clear(this);
2045 this->net_changes->destroy(this->net_changes);
2046 this->net_changes_lock->destroy(this->net_changes_lock);
2047
2048 this->addrs->ht.destroy_function(&this->addrs->ht, (void*)free);
2049 this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy);
2050 this->tuns->destroy(this->tuns);
2051 this->lock->destroy(this->lock);
2052 this->mutex->destroy(this->mutex);
2053 this->condvar->destroy(this->condvar);
2054 this->roam_lock->destroy(this->roam_lock);
2055 free(this->reply);
2056 free(this);
2057 }
2058
2059 /*
2060 * Described in header.
2061 */
2062 kernel_pfroute_net_t *kernel_pfroute_net_create()
2063 {
2064 private_kernel_pfroute_net_t *this;
2065
2066 INIT(this,
2067 .public = {
2068 .interface = {
2069 .get_features = _get_features,
2070 .get_interface = _get_interface_name,
2071 .create_address_enumerator = _create_address_enumerator,
2072 .create_local_subnet_enumerator = _create_local_subnet_enumerator,
2073 .get_source_addr = _get_source_addr,
2074 .get_nexthop = _get_nexthop,
2075 .add_ip = _add_ip,
2076 .del_ip = _del_ip,
2077 .add_route = _add_route,
2078 .del_route = _del_route,
2079 .destroy = _destroy,
2080 },
2081 },
2082 .pid = getpid(),
2083 .ifaces = linked_list_create(),
2084 .addrs = hashlist_create(
2085 (hashtable_hash_t)addr_map_entry_hash,
2086 (hashtable_equals_t)addr_map_entry_equals, 16),
2087 .routes = hashtable_create((hashtable_hash_t)route_entry_hash,
2088 (hashtable_equals_t)route_entry_equals, 16),
2089 .net_changes = hashtable_create(
2090 (hashtable_hash_t)net_change_hash,
2091 (hashtable_equals_t)net_change_equals, 16),
2092 .tuns = linked_list_create(),
2093 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
2094 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
2095 .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
2096 .routes_lock = mutex_create(MUTEX_TYPE_DEFAULT),
2097 .net_changes_lock = mutex_create(MUTEX_TYPE_DEFAULT),
2098 .roam_lock = spinlock_create(),
2099 .vip_wait = lib->settings->get_int(lib->settings,
2100 "%s.plugins.kernel-pfroute.vip_wait", 1000, lib->ns),
2101 .mtu = lib->settings->get_int(lib->settings,
2102 "%s.plugins.kernel-pfroute.mtu", TUN_DEFAULT_MTU, lib->ns),
2103 .install_virtual_ip = lib->settings->get_bool(lib->settings,
2104 "%s.install_virtual_ip", TRUE, lib->ns),
2105 );
2106 timerclear(&this->last_route_reinstall);
2107 timerclear(&this->next_roam);
2108
2109 /* create a PF_ROUTE socket to communicate with the kernel */
2110 this->socket = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
2111 if (this->socket == -1)
2112 {
2113 DBG1(DBG_KNL, "unable to create PF_ROUTE socket");
2114 destroy(this);
2115 return NULL;
2116 }
2117
2118 if (streq(lib->ns, "starter"))
2119 {
2120 /* starter has no threads, so we do not register for kernel events */
2121 if (shutdown(this->socket, SHUT_RD) != 0)
2122 {
2123 DBG1(DBG_KNL, "closing read end of PF_ROUTE socket failed: %s",
2124 strerror(errno));
2125 }
2126 }
2127 else
2128 {
2129 lib->watcher->add(lib->watcher, this->socket, WATCHER_READ,
2130 (watcher_cb_t)receive_events, this);
2131 }
2132 if (init_address_list(this) != SUCCESS)
2133 {
2134 DBG1(DBG_KNL, "unable to get interface list");
2135 destroy(this);
2136 return NULL;
2137 }
2138
2139 return &this->public;
2140 }