2d0e252ac7e5a3c1738ad402e7257105e51d4fea
[strongswan.git] / src / libhydra / plugins / kernel_pfroute / kernel_pfroute_net.c
1 /*
2 * Copyright (C) 2009-2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <net/if.h>
19 #include <net/if_dl.h>
20 #include <ifaddrs.h>
21 #include <net/route.h>
22 #include <unistd.h>
23 #include <errno.h>
24
25 #include "kernel_pfroute_net.h"
26
27 #include <hydra.h>
28 #include <utils/debug.h>
29 #include <networking/host.h>
30 #include <networking/tun_device.h>
31 #include <threading/thread.h>
32 #include <threading/mutex.h>
33 #include <threading/condvar.h>
34 #include <threading/rwlock.h>
35 #include <collections/hashtable.h>
36 #include <collections/linked_list.h>
37 #include <processing/jobs/callback_job.h>
38
39 #ifndef HAVE_STRUCT_SOCKADDR_SA_LEN
40 #error Cannot compile this plugin on systems where 'struct sockaddr' has no sa_len member.
41 #endif
42
43 /** properly align sockaddrs */
44 #ifdef __APPLE__
45 /* Apple always uses 4 bytes */
46 #define SA_ALIGN 4
47 #else
48 /* while on other platforms like FreeBSD it depends on the architecture */
49 #define SA_ALIGN sizeof(long)
50 #endif
51 #define SA_LEN(len) ((len) > 0 ? (((len)+SA_ALIGN-1) & ~(SA_ALIGN-1)) : SA_ALIGN)
52
53 /** delay before firing roam events (ms) */
54 #define ROAM_DELAY 100
55
56 typedef struct addr_entry_t addr_entry_t;
57
58 /**
59 * IP address in an inface_entry_t
60 */
61 struct addr_entry_t {
62
63 /** The ip address */
64 host_t *ip;
65
66 /** virtual IP managed by us */
67 bool virtual;
68 };
69
70 /**
71 * destroy a addr_entry_t object
72 */
73 static void addr_entry_destroy(addr_entry_t *this)
74 {
75 this->ip->destroy(this->ip);
76 free(this);
77 }
78
79 typedef struct iface_entry_t iface_entry_t;
80
81 /**
82 * A network interface on this system, containing addr_entry_t's
83 */
84 struct iface_entry_t {
85
86 /** interface index */
87 int ifindex;
88
89 /** name of the interface */
90 char ifname[IFNAMSIZ];
91
92 /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
93 u_int flags;
94
95 /** list of addresses as host_t */
96 linked_list_t *addrs;
97
98 /** TRUE if usable by config */
99 bool usable;
100 };
101
102 /**
103 * destroy an interface entry
104 */
105 static void iface_entry_destroy(iface_entry_t *this)
106 {
107 this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy);
108 free(this);
109 }
110
111 /**
112 * check if an interface is up
113 */
114 static inline bool iface_entry_up(iface_entry_t *iface)
115 {
116 return (iface->flags & IFF_UP) == IFF_UP;
117 }
118
119 /**
120 * check if an interface is up and usable
121 */
122 static inline bool iface_entry_up_and_usable(iface_entry_t *iface)
123 {
124 return iface->usable && iface_entry_up(iface);
125 }
126
127 typedef struct addr_map_entry_t addr_map_entry_t;
128
129 /**
130 * Entry that maps an IP address to an interface entry
131 */
132 struct addr_map_entry_t {
133 /** The IP address */
134 host_t *ip;
135
136 /** The interface this address is installed on */
137 iface_entry_t *iface;
138 };
139
140 /**
141 * Hash a addr_map_entry_t object, all entries with the same IP address
142 * are stored in the same bucket
143 */
144 static u_int addr_map_entry_hash(addr_map_entry_t *this)
145 {
146 return chunk_hash(this->ip->get_address(this->ip));
147 }
148
149 /**
150 * Compare two addr_map_entry_t objects, two entries are equal if they are
151 * installed on the same interface
152 */
153 static bool addr_map_entry_equals(addr_map_entry_t *a, addr_map_entry_t *b)
154 {
155 return a->iface->ifindex == b->iface->ifindex &&
156 a->ip->ip_equals(a->ip, b->ip);
157 }
158
159 /**
160 * Used with get_match this finds an address entry if it is installed on
161 * an up and usable interface
162 */
163 static bool addr_map_entry_match_up_and_usable(addr_map_entry_t *a,
164 addr_map_entry_t *b)
165 {
166 return iface_entry_up_and_usable(b->iface) &&
167 a->ip->ip_equals(a->ip, b->ip);
168 }
169
170 /**
171 * Used with get_match this finds an address entry if it is installed on
172 * any active local interface
173 */
174 static bool addr_map_entry_match_up(addr_map_entry_t *a, addr_map_entry_t *b)
175 {
176 return iface_entry_up(b->iface) && a->ip->ip_equals(a->ip, b->ip);
177 }
178
179 typedef struct private_kernel_pfroute_net_t private_kernel_pfroute_net_t;
180
181 /**
182 * Private variables and functions of kernel_pfroute class.
183 */
184 struct private_kernel_pfroute_net_t
185 {
186 /**
187 * Public part of the kernel_pfroute_t object.
188 */
189 kernel_pfroute_net_t public;
190
191 /**
192 * lock to access lists and maps
193 */
194 rwlock_t *lock;
195
196 /**
197 * Cached list of interfaces and their addresses (iface_entry_t)
198 */
199 linked_list_t *ifaces;
200
201 /**
202 * Map for IP addresses to iface_entry_t objects (addr_map_entry_t)
203 */
204 hashtable_t *addrs;
205
206 /**
207 * List of tun devices we installed for virtual IPs
208 */
209 linked_list_t *tuns;
210
211 /**
212 * mutex to communicate exclusively with PF_KEY
213 */
214 mutex_t *mutex;
215
216 /**
217 * condvar to signal if PF_KEY query got a response
218 */
219 condvar_t *condvar;
220
221 /**
222 * pid to send PF_ROUTE messages with
223 */
224 pid_t pid;
225
226 /**
227 * PF_ROUTE socket to communicate with the kernel
228 */
229 int socket;
230
231 /**
232 * sequence number for messages sent to the kernel
233 */
234 int seq;
235
236 /**
237 * Sequence number a query is waiting for
238 */
239 int waiting_seq;
240
241 /**
242 * Allocated reply message from kernel
243 */
244 struct rt_msghdr *reply;
245
246 /**
247 * time of last roam event
248 */
249 timeval_t last_roam;
250 };
251
252 /**
253 * Add an address map entry
254 */
255 static void addr_map_entry_add(private_kernel_pfroute_net_t *this,
256 addr_entry_t *addr, iface_entry_t *iface)
257 {
258 addr_map_entry_t *entry;
259
260 if (addr->virtual)
261 { /* don't map virtual IPs */
262 return;
263 }
264
265 INIT(entry,
266 .ip = addr->ip,
267 .iface = iface,
268 );
269 entry = this->addrs->put(this->addrs, entry, entry);
270 free(entry);
271 }
272
273 /**
274 * Remove an address map entry (the argument order is a bit strange because
275 * it is also used with linked_list_t.invoke_function)
276 */
277 static void addr_map_entry_remove(addr_entry_t *addr, iface_entry_t *iface,
278 private_kernel_pfroute_net_t *this)
279 {
280 addr_map_entry_t *entry, lookup = {
281 .ip = addr->ip,
282 .iface = iface,
283 };
284
285 if (addr->virtual)
286 { /* these are never mapped, but this check avoid problems if a virtual IP
287 * equals a regular one */
288 return;
289 }
290 entry = this->addrs->remove(this->addrs, &lookup);
291 free(entry);
292 }
293
294 /**
295 * callback function that raises the delayed roam event
296 */
297 static job_requeue_t roam_event(uintptr_t address)
298 {
299 hydra->kernel_interface->roam(hydra->kernel_interface, address != 0);
300 return JOB_REQUEUE_NONE;
301 }
302
303 /**
304 * fire a roaming event. we delay it for a bit and fire only one event
305 * for multiple calls. otherwise we would create too many events.
306 */
307 static void fire_roam_event(private_kernel_pfroute_net_t *this, bool address)
308 {
309 timeval_t now;
310 job_t *job;
311
312 time_monotonic(&now);
313 if (timercmp(&now, &this->last_roam, >))
314 {
315 timeval_add_ms(&now, ROAM_DELAY);
316 this->last_roam = now;
317
318 job = (job_t*)callback_job_create((callback_job_cb_t)roam_event,
319 (void*)(uintptr_t)(address ? 1 : 0),
320 NULL, NULL);
321 lib->scheduler->schedule_job_ms(lib->scheduler, job, ROAM_DELAY);
322 }
323 }
324
325 /**
326 * Data for enumerator over rtmsg sockaddrs
327 */
328 typedef struct {
329 /** implements enumerator */
330 enumerator_t public;
331 /** copy of attribute bitfield */
332 int types;
333 /** bytes remaining in buffer */
334 int remaining;
335 /** next sockaddr to enumerate */
336 struct sockaddr *addr;
337 } rt_enumerator_t;
338
339 METHOD(enumerator_t, rt_enumerate, bool,
340 rt_enumerator_t *this, int *xtype, struct sockaddr **addr)
341 {
342 int i, type;
343
344 if (this->remaining < sizeof(this->addr->sa_len) ||
345 this->remaining < this->addr->sa_len)
346 {
347 return FALSE;
348 }
349 for (i = 0; i < RTAX_MAX; i++)
350 {
351 type = (1 << i);
352 if (this->types & type)
353 {
354 this->types &= ~type;
355 *addr = this->addr;
356 *xtype = i;
357 this->remaining -= SA_LEN(this->addr->sa_len);
358 this->addr = (struct sockaddr*)((char*)this->addr +
359 SA_LEN(this->addr->sa_len));
360 return TRUE;
361 }
362 }
363 return FALSE;
364 }
365
366 /**
367 * Create a safe enumerator over sockaddrs in ifa/ifam/rt_msg
368 */
369 static enumerator_t *create_rtmsg_enumerator(void *hdr, size_t hdrlen)
370 {
371 struct rt_msghdr *rthdr = hdr;
372 rt_enumerator_t *this;
373
374 INIT(this,
375 .public = {
376 .enumerate = (void*)_rt_enumerate,
377 .destroy = (void*)free,
378 },
379 .types = rthdr->rtm_addrs,
380 .remaining = rthdr->rtm_msglen - hdrlen,
381 .addr = hdr + hdrlen,
382 );
383 return &this->public;
384 }
385
386 /**
387 * Process an RTM_*ADDR message from the kernel
388 */
389 static void process_addr(private_kernel_pfroute_net_t *this,
390 struct ifa_msghdr *ifa)
391 {
392 struct sockaddr *sockaddr;
393 host_t *host = NULL;
394 enumerator_t *ifaces, *addrs;
395 iface_entry_t *iface;
396 addr_entry_t *addr;
397 bool found = FALSE, changed = FALSE, roam = FALSE;
398 enumerator_t *enumerator;
399 int type;
400
401 enumerator = create_rtmsg_enumerator(ifa, sizeof(*ifa));
402 while (enumerator->enumerate(enumerator, &type, &sockaddr))
403 {
404 if (type == RTAX_IFA)
405 {
406 host = host_create_from_sockaddr(sockaddr);
407 break;
408 }
409 }
410 enumerator->destroy(enumerator);
411
412 if (!host)
413 {
414 return;
415 }
416
417 this->lock->write_lock(this->lock);
418 ifaces = this->ifaces->create_enumerator(this->ifaces);
419 while (ifaces->enumerate(ifaces, &iface))
420 {
421 if (iface->ifindex == ifa->ifam_index)
422 {
423 addrs = iface->addrs->create_enumerator(iface->addrs);
424 while (addrs->enumerate(addrs, &addr))
425 {
426 if (host->ip_equals(host, addr->ip))
427 {
428 found = TRUE;
429 if (ifa->ifam_type == RTM_DELADDR)
430 {
431 iface->addrs->remove_at(iface->addrs, addrs);
432 if (!addr->virtual && iface->usable)
433 {
434 changed = TRUE;
435 DBG1(DBG_KNL, "%H disappeared from %s",
436 host, iface->ifname);
437 }
438 addr_map_entry_remove(addr, iface, this);
439 addr_entry_destroy(addr);
440 }
441 }
442 }
443 addrs->destroy(addrs);
444
445 if (!found && ifa->ifam_type == RTM_NEWADDR)
446 {
447 INIT(addr,
448 .ip = host->clone(host),
449 );
450 changed = TRUE;
451 iface->addrs->insert_last(iface->addrs, addr);
452 addr_map_entry_add(this, addr, iface);
453 if (iface->usable)
454 {
455 DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname);
456 }
457 }
458
459 if (changed && iface_entry_up_and_usable(iface))
460 {
461 roam = TRUE;
462 }
463 break;
464 }
465 }
466 ifaces->destroy(ifaces);
467 this->lock->unlock(this->lock);
468 host->destroy(host);
469
470 if (roam)
471 {
472 fire_roam_event(this, TRUE);
473 }
474 }
475
476 /**
477 * Re-initialize address list of an interface if it changes state
478 */
479 static void repopulate_iface(private_kernel_pfroute_net_t *this,
480 iface_entry_t *iface)
481 {
482 struct ifaddrs *ifap, *ifa;
483 addr_entry_t *addr;
484
485 while (iface->addrs->remove_last(iface->addrs, (void**)&addr) == SUCCESS)
486 {
487 addr_map_entry_remove(addr, iface, this);
488 addr_entry_destroy(addr);
489 }
490
491 if (getifaddrs(&ifap) == 0)
492 {
493 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
494 {
495 if (ifa->ifa_addr && streq(ifa->ifa_name, iface->ifname))
496 {
497 switch (ifa->ifa_addr->sa_family)
498 {
499 case AF_INET:
500 case AF_INET6:
501 INIT(addr,
502 .ip = host_create_from_sockaddr(ifa->ifa_addr),
503 );
504 iface->addrs->insert_last(iface->addrs, addr);
505 addr_map_entry_add(this, addr, iface);
506 break;
507 default:
508 break;
509 }
510 }
511 }
512 freeifaddrs(ifap);
513 }
514 }
515
516 /**
517 * Process an RTM_IFINFO message from the kernel
518 */
519 static void process_link(private_kernel_pfroute_net_t *this,
520 struct if_msghdr *msg)
521 {
522 enumerator_t *enumerator;
523 iface_entry_t *iface;
524 bool roam = FALSE, found = FALSE;
525
526 this->lock->write_lock(this->lock);
527 enumerator = this->ifaces->create_enumerator(this->ifaces);
528 while (enumerator->enumerate(enumerator, &iface))
529 {
530 if (iface->ifindex == msg->ifm_index)
531 {
532 if (iface->usable)
533 {
534 if (!(iface->flags & IFF_UP) && (msg->ifm_flags & IFF_UP))
535 {
536 roam = TRUE;
537 DBG1(DBG_KNL, "interface %s activated", iface->ifname);
538 }
539 else if ((iface->flags & IFF_UP) && !(msg->ifm_flags & IFF_UP))
540 {
541 roam = TRUE;
542 DBG1(DBG_KNL, "interface %s deactivated", iface->ifname);
543 }
544 }
545 iface->flags = msg->ifm_flags;
546 repopulate_iface(this, iface);
547 found = TRUE;
548 break;
549 }
550 }
551 enumerator->destroy(enumerator);
552
553 if (!found)
554 {
555 INIT(iface,
556 .ifindex = msg->ifm_index,
557 .flags = msg->ifm_flags,
558 .addrs = linked_list_create(),
559 );
560 if (if_indextoname(iface->ifindex, iface->ifname))
561 {
562 DBG1(DBG_KNL, "interface %s appeared", iface->ifname);
563 iface->usable = hydra->kernel_interface->is_interface_usable(
564 hydra->kernel_interface, iface->ifname);
565 repopulate_iface(this, iface);
566 this->ifaces->insert_last(this->ifaces, iface);
567 }
568 else
569 {
570 free(iface);
571 }
572 }
573 this->lock->unlock(this->lock);
574
575 if (roam)
576 {
577 fire_roam_event(this, TRUE);
578 }
579 }
580
581 /**
582 * Process an RTM_*ROUTE message from the kernel
583 */
584 static void process_route(private_kernel_pfroute_net_t *this,
585 struct rt_msghdr *msg)
586 {
587
588 }
589
590 /**
591 * Receives PF_ROUTE messages from kernel
592 */
593 static job_requeue_t receive_events(private_kernel_pfroute_net_t *this)
594 {
595 struct {
596 union {
597 struct rt_msghdr rtm;
598 struct if_msghdr ifm;
599 struct ifa_msghdr ifam;
600 };
601 char buf[sizeof(struct sockaddr_storage) * RTAX_MAX];
602 } msg;
603 int len, hdrlen;
604 bool oldstate;
605
606 oldstate = thread_cancelability(TRUE);
607 len = recv(this->socket, &msg, sizeof(msg), 0);
608 thread_cancelability(oldstate);
609
610 if (len < 0)
611 {
612 switch (errno)
613 {
614 case EINTR:
615 case EAGAIN:
616 return JOB_REQUEUE_DIRECT;
617 default:
618 DBG1(DBG_KNL, "unable to receive from PF_ROUTE event socket");
619 sleep(1);
620 return JOB_REQUEUE_FAIR;
621 }
622 }
623
624 if (len < offsetof(struct rt_msghdr, rtm_flags) || len < msg.rtm.rtm_msglen)
625 {
626 DBG1(DBG_KNL, "received invalid PF_ROUTE message");
627 return JOB_REQUEUE_DIRECT;
628 }
629 if (msg.rtm.rtm_version != RTM_VERSION)
630 {
631 DBG1(DBG_KNL, "received PF_ROUTE message with unsupported version: %d",
632 msg.rtm.rtm_version);
633 return JOB_REQUEUE_DIRECT;
634 }
635 switch (msg.rtm.rtm_type)
636 {
637 case RTM_NEWADDR:
638 case RTM_DELADDR:
639 hdrlen = sizeof(msg.ifam);
640 break;
641 case RTM_IFINFO:
642 hdrlen = sizeof(msg.ifm);
643 break;
644 case RTM_ADD:
645 case RTM_DELETE:
646 case RTM_GET:
647 hdrlen = sizeof(msg.rtm);
648 break;
649 default:
650 return JOB_REQUEUE_DIRECT;
651 }
652 if (msg.rtm.rtm_msglen < hdrlen)
653 {
654 DBG1(DBG_KNL, "ignoring short PF_ROUTE message");
655 return JOB_REQUEUE_DIRECT;
656 }
657 switch (msg.rtm.rtm_type)
658 {
659 case RTM_NEWADDR:
660 case RTM_DELADDR:
661 process_addr(this, &msg.ifam);
662 break;
663 case RTM_IFINFO:
664 process_link(this, &msg.ifm);
665 break;
666 case RTM_ADD:
667 case RTM_DELETE:
668 process_route(this, &msg.rtm);
669 break;
670 default:
671 break;
672 }
673
674 this->mutex->lock(this->mutex);
675 if (msg.rtm.rtm_pid == this->pid && msg.rtm.rtm_seq == this->waiting_seq)
676 {
677 /* seems like the message someone is waiting for, deliver */
678 this->reply = realloc(this->reply, msg.rtm.rtm_msglen);
679 memcpy(this->reply, &msg, msg.rtm.rtm_msglen);
680 }
681 /* signal on any event, add_ip()/del_ip() might wait for it */
682 this->condvar->broadcast(this->condvar);
683 this->mutex->unlock(this->mutex);
684
685 return JOB_REQUEUE_DIRECT;
686 }
687
688
689 /** enumerator over addresses */
690 typedef struct {
691 private_kernel_pfroute_net_t* this;
692 /** which addresses to enumerate */
693 kernel_address_type_t which;
694 } address_enumerator_t;
695
696 /**
697 * cleanup function for address enumerator
698 */
699 static void address_enumerator_destroy(address_enumerator_t *data)
700 {
701 data->this->lock->unlock(data->this->lock);
702 free(data);
703 }
704
705 /**
706 * filter for addresses
707 */
708 static bool filter_addresses(address_enumerator_t *data,
709 addr_entry_t** in, host_t** out)
710 {
711 host_t *ip;
712 if (!(data->which & ADDR_TYPE_VIRTUAL) && (*in)->virtual)
713 { /* skip virtual interfaces added by us */
714 return FALSE;
715 }
716 if (!(data->which & ADDR_TYPE_REGULAR) && !(*in)->virtual)
717 { /* address is regular, but not requested */
718 return FALSE;
719 }
720 ip = (*in)->ip;
721 if (ip->get_family(ip) == AF_INET6)
722 {
723 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip);
724 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
725 { /* skip addresses with a unusable scope */
726 return FALSE;
727 }
728 }
729 *out = ip;
730 return TRUE;
731 }
732
733 /**
734 * enumerator constructor for interfaces
735 */
736 static enumerator_t *create_iface_enumerator(iface_entry_t *iface,
737 address_enumerator_t *data)
738 {
739 return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs),
740 (void*)filter_addresses, data, NULL);
741 }
742
743 /**
744 * filter for interfaces
745 */
746 static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in,
747 iface_entry_t** out)
748 {
749 if (!(data->which & ADDR_TYPE_IGNORED) && !(*in)->usable)
750 { /* skip interfaces excluded by config */
751 return FALSE;
752 }
753 if (!(data->which & ADDR_TYPE_LOOPBACK) && ((*in)->flags & IFF_LOOPBACK))
754 { /* ignore loopback devices */
755 return FALSE;
756 }
757 if (!(data->which & ADDR_TYPE_DOWN) && !((*in)->flags & IFF_UP))
758 { /* skip interfaces not up */
759 return FALSE;
760 }
761 *out = *in;
762 return TRUE;
763 }
764
765 METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
766 private_kernel_pfroute_net_t *this, kernel_address_type_t which)
767 {
768 address_enumerator_t *data;
769
770 INIT(data,
771 .this = this,
772 .which = which,
773 );
774
775 this->lock->read_lock(this->lock);
776 return enumerator_create_nested(
777 enumerator_create_filter(
778 this->ifaces->create_enumerator(this->ifaces),
779 (void*)filter_interfaces, data, NULL),
780 (void*)create_iface_enumerator, data,
781 (void*)address_enumerator_destroy);
782 }
783
784 METHOD(kernel_net_t, get_features, kernel_feature_t,
785 private_kernel_pfroute_net_t *this)
786 {
787 return KERNEL_REQUIRE_EXCLUDE_ROUTE;
788 }
789
790 METHOD(kernel_net_t, get_interface_name, bool,
791 private_kernel_pfroute_net_t *this, host_t* ip, char **name)
792 {
793 addr_map_entry_t *entry, lookup = {
794 .ip = ip,
795 };
796
797 if (ip->is_anyaddr(ip))
798 {
799 return FALSE;
800 }
801 this->lock->read_lock(this->lock);
802 /* first try to find it on an up and usable interface */
803 entry = this->addrs->get_match(this->addrs, &lookup,
804 (void*)addr_map_entry_match_up_and_usable);
805 if (entry)
806 {
807 if (name)
808 {
809 *name = strdup(entry->iface->ifname);
810 DBG2(DBG_KNL, "%H is on interface %s", ip, *name);
811 }
812 this->lock->unlock(this->lock);
813 return TRUE;
814 }
815 /* maybe it is installed on an ignored interface */
816 entry = this->addrs->get_match(this->addrs, &lookup,
817 (void*)addr_map_entry_match_up);
818 if (!entry)
819 { /* the address does not exist, is on a down interface */
820 DBG2(DBG_KNL, "%H is not a local address or the interface is down", ip);
821 }
822 this->lock->unlock(this->lock);
823 return FALSE;
824 }
825
826 METHOD(kernel_net_t, add_ip, status_t,
827 private_kernel_pfroute_net_t *this, host_t *vip, int prefix,
828 char *ifname)
829 {
830 enumerator_t *ifaces, *addrs;
831 iface_entry_t *iface;
832 addr_entry_t *addr;
833 tun_device_t *tun;
834 bool timeout = FALSE;
835
836 tun = tun_device_create(NULL);
837 if (!tun)
838 {
839 return FAILED;
840 }
841 if (prefix == -1)
842 {
843 prefix = vip->get_address(vip).len * 8;
844 }
845 if (!tun->up(tun) || !tun->set_address(tun, vip, prefix))
846 {
847 tun->destroy(tun);
848 return FAILED;
849 }
850
851 /* wait until address appears */
852 this->mutex->lock(this->mutex);
853 while (!timeout && !get_interface_name(this, vip, NULL))
854 {
855 timeout = this->condvar->timed_wait(this->condvar, this->mutex, 1000);
856 }
857 this->mutex->unlock(this->mutex);
858 if (timeout)
859 {
860 DBG1(DBG_KNL, "virtual IP %H did not appear on %s",
861 vip, tun->get_name(tun));
862 tun->destroy(tun);
863 return FAILED;
864 }
865
866 this->lock->write_lock(this->lock);
867 this->tuns->insert_last(this->tuns, tun);
868
869 ifaces = this->ifaces->create_enumerator(this->ifaces);
870 while (ifaces->enumerate(ifaces, &iface))
871 {
872 if (streq(iface->ifname, tun->get_name(tun)))
873 {
874 addrs = iface->addrs->create_enumerator(iface->addrs);
875 while (addrs->enumerate(addrs, &addr))
876 {
877 if (addr->ip->ip_equals(addr->ip, vip))
878 {
879 addr->virtual = TRUE;
880 }
881 }
882 addrs->destroy(addrs);
883 }
884 }
885 ifaces->destroy(ifaces);
886 /* lets do this while holding the lock, thus preventing another thread
887 * from deleting the TUN device concurrently, hopefully listeneres are quick
888 * and cause no deadlocks */
889 hydra->kernel_interface->tun(hydra->kernel_interface, tun, TRUE);
890 this->lock->unlock(this->lock);
891
892 return SUCCESS;
893 }
894
895 METHOD(kernel_net_t, del_ip, status_t,
896 private_kernel_pfroute_net_t *this, host_t *vip, int prefix,
897 bool wait)
898 {
899 enumerator_t *enumerator;
900 tun_device_t *tun;
901 host_t *addr;
902 bool timeout = FALSE, found = FALSE;
903
904 this->lock->write_lock(this->lock);
905 enumerator = this->tuns->create_enumerator(this->tuns);
906 while (enumerator->enumerate(enumerator, &tun))
907 {
908 addr = tun->get_address(tun, NULL);
909 if (addr && addr->ip_equals(addr, vip))
910 {
911 this->tuns->remove_at(this->tuns, enumerator);
912 hydra->kernel_interface->tun(hydra->kernel_interface, tun,
913 FALSE);
914 tun->destroy(tun);
915 found = TRUE;
916 break;
917 }
918 }
919 enumerator->destroy(enumerator);
920 this->lock->unlock(this->lock);
921
922 if (!found)
923 {
924 return NOT_FOUND;
925 }
926 /* wait until address disappears */
927 if (wait)
928 {
929 this->mutex->lock(this->mutex);
930 while (!timeout && get_interface_name(this, vip, NULL))
931 {
932 timeout = this->condvar->timed_wait(this->condvar, this->mutex, 1000);
933 }
934 this->mutex->unlock(this->mutex);
935 if (timeout)
936 {
937 DBG1(DBG_KNL, "virtual IP %H did not disappear from tun", vip);
938 return FAILED;
939 }
940 }
941 return SUCCESS;
942 }
943
944 /**
945 * Append a sockaddr_in/in6 of given type to routing message
946 */
947 static void add_rt_addr(struct rt_msghdr *hdr, int type, host_t *addr)
948 {
949 if (addr)
950 {
951 int len;
952
953 len = *addr->get_sockaddr_len(addr);
954 memcpy((char*)hdr + hdr->rtm_msglen, addr->get_sockaddr(addr), len);
955 hdr->rtm_msglen += SA_LEN(len);
956 hdr->rtm_addrs |= type;
957 }
958 }
959
960 /**
961 * Append a subnet mask sockaddr using the given prefix to routing message
962 */
963 static void add_rt_mask(struct rt_msghdr *hdr, int type, int family, int prefix)
964 {
965 host_t *mask;
966
967 mask = host_create_netmask(family, prefix);
968 if (mask)
969 {
970 add_rt_addr(hdr, type, mask);
971 mask->destroy(mask);
972 }
973 }
974
975 /**
976 * Append an interface name sockaddr_dl to routing message
977 */
978 static void add_rt_ifname(struct rt_msghdr *hdr, int type, char *name)
979 {
980 struct sockaddr_dl sdl = {
981 .sdl_len = sizeof(struct sockaddr_dl),
982 .sdl_family = AF_LINK,
983 .sdl_nlen = strlen(name),
984 };
985
986 if (strlen(name) <= sizeof(sdl.sdl_data))
987 {
988 memcpy(sdl.sdl_data, name, sdl.sdl_nlen);
989 memcpy((char*)hdr + hdr->rtm_msglen, &sdl, sdl.sdl_len);
990 hdr->rtm_msglen += SA_LEN(sdl.sdl_len);
991 hdr->rtm_addrs |= type;
992 }
993 }
994
995 /**
996 * Add or remove a route
997 */
998 static status_t manage_route(private_kernel_pfroute_net_t *this, int op,
999 chunk_t dst_net, u_int8_t prefixlen,
1000 host_t *gateway, char *if_name)
1001 {
1002 struct {
1003 struct rt_msghdr hdr;
1004 char buf[sizeof(struct sockaddr_storage) * RTAX_MAX];
1005 } msg = {
1006 .hdr = {
1007 .rtm_version = RTM_VERSION,
1008 .rtm_type = op,
1009 .rtm_flags = RTF_UP | RTF_STATIC,
1010 .rtm_pid = this->pid,
1011 .rtm_seq = ++this->seq,
1012 },
1013 };
1014 host_t *dst;
1015 int type;
1016
1017 if (prefixlen == 0 && dst_net.len)
1018 {
1019 status_t status;
1020 chunk_t half;
1021
1022 half = chunk_clonea(dst_net);
1023 half.ptr[0] |= 0x80;
1024 prefixlen = 1;
1025 status = manage_route(this, op, half, prefixlen, gateway, if_name);
1026 if (status != SUCCESS)
1027 {
1028 return status;
1029 }
1030 }
1031
1032 dst = host_create_from_chunk(AF_UNSPEC, dst_net, 0);
1033 if (!dst)
1034 {
1035 return FAILED;
1036 }
1037
1038 if ((dst->get_family(dst) == AF_INET && prefixlen == 32) ||
1039 (dst->get_family(dst) == AF_INET6 && prefixlen == 128))
1040 {
1041 msg.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY;
1042 }
1043
1044 msg.hdr.rtm_msglen = sizeof(struct rt_msghdr);
1045 for (type = 0; type < RTAX_MAX; type++)
1046 {
1047 switch (type)
1048 {
1049 case RTAX_DST:
1050 add_rt_addr(&msg.hdr, RTA_DST, dst);
1051 break;
1052 case RTAX_NETMASK:
1053 if (!(msg.hdr.rtm_flags & RTF_HOST))
1054 {
1055 add_rt_mask(&msg.hdr, RTA_NETMASK,
1056 dst->get_family(dst), prefixlen);
1057 }
1058 break;
1059 case RTAX_IFP:
1060 if (if_name)
1061 {
1062 add_rt_ifname(&msg.hdr, RTA_IFP, if_name);
1063 }
1064 break;
1065 case RTAX_GATEWAY:
1066 if (gateway)
1067 {
1068 add_rt_addr(&msg.hdr, RTA_GATEWAY, gateway);
1069 }
1070 break;
1071 default:
1072 break;
1073 }
1074 }
1075 dst->destroy(dst);
1076
1077 if (send(this->socket, &msg, msg.hdr.rtm_msglen, 0) != msg.hdr.rtm_msglen)
1078 {
1079 DBG1(DBG_KNL, "%s PF_ROUTE route failed: %s",
1080 op == RTM_ADD ? "adding" : "deleting", strerror(errno));
1081 return FAILED;
1082 }
1083 return SUCCESS;
1084 }
1085
1086 METHOD(kernel_net_t, add_route, status_t,
1087 private_kernel_pfroute_net_t *this, chunk_t dst_net, u_int8_t prefixlen,
1088 host_t *gateway, host_t *src_ip, char *if_name)
1089 {
1090 return manage_route(this, RTM_ADD, dst_net, prefixlen, gateway, if_name);
1091 }
1092
1093 METHOD(kernel_net_t, del_route, status_t,
1094 private_kernel_pfroute_net_t *this, chunk_t dst_net, u_int8_t prefixlen,
1095 host_t *gateway, host_t *src_ip, char *if_name)
1096 {
1097 return manage_route(this, RTM_DELETE, dst_net, prefixlen, gateway, if_name);
1098 }
1099
1100 /**
1101 * Do a route lookup for dest and return either the nexthop or the source
1102 * address.
1103 */
1104 static host_t *get_route(private_kernel_pfroute_net_t *this, bool nexthop,
1105 host_t *dest, host_t *src)
1106 {
1107 struct {
1108 struct rt_msghdr hdr;
1109 char buf[sizeof(struct sockaddr_storage) * RTAX_MAX];
1110 } msg = {
1111 .hdr = {
1112 .rtm_version = RTM_VERSION,
1113 .rtm_type = RTM_GET,
1114 .rtm_pid = this->pid,
1115 .rtm_seq = ++this->seq,
1116 },
1117 };
1118 host_t *host = NULL;
1119 enumerator_t *enumerator;
1120 struct sockaddr *addr;
1121 bool failed = FALSE;
1122 int type;
1123
1124 retry:
1125 msg.hdr.rtm_msglen = sizeof(struct rt_msghdr);
1126 for (type = 0; type < RTAX_MAX; type++)
1127 {
1128 switch (type)
1129 {
1130 case RTAX_DST:
1131 add_rt_addr(&msg.hdr, RTA_DST, dest);
1132 break;
1133 case RTAX_IFA:
1134 add_rt_addr(&msg.hdr, RTA_IFA, src);
1135 break;
1136 case RTAX_IFP:
1137 if (!nexthop)
1138 { /* add an empty IFP to ensure we get a source address */
1139 add_rt_ifname(&msg.hdr, RTA_IFP, "");
1140 }
1141 break;
1142 default:
1143 break;
1144 }
1145 }
1146 this->mutex->lock(this->mutex);
1147
1148 while (this->waiting_seq)
1149 {
1150 this->condvar->wait(this->condvar, this->mutex);
1151 }
1152 this->waiting_seq = msg.hdr.rtm_seq;
1153 if (send(this->socket, &msg, msg.hdr.rtm_msglen, 0) == msg.hdr.rtm_msglen)
1154 {
1155 while (TRUE)
1156 {
1157 if (this->condvar->timed_wait(this->condvar, this->mutex, 1000))
1158 { /* timed out? */
1159 break;
1160 }
1161 if (this->reply->rtm_msglen < sizeof(*this->reply) ||
1162 msg.hdr.rtm_seq != this->reply->rtm_seq)
1163 {
1164 continue;
1165 }
1166 enumerator = create_rtmsg_enumerator(this->reply,
1167 sizeof(*this->reply));
1168 while (enumerator->enumerate(enumerator, &type, &addr))
1169 {
1170 if (nexthop)
1171 {
1172 if (type == RTAX_DST && this->reply->rtm_flags & RTF_HOST)
1173 { /* probably a cloned/cached direct route, only use that
1174 * as fallback if no gateway is found */
1175 host = host ?: host_create_from_sockaddr(addr);
1176 }
1177 if (type == RTAX_GATEWAY)
1178 { /* could actually be a MAC address */
1179 host_t *gtw = host_create_from_sockaddr(addr);
1180 if (gtw)
1181 {
1182 DESTROY_IF(host);
1183 host = gtw;
1184 }
1185 }
1186 }
1187 else
1188 {
1189 if (type == RTAX_IFA)
1190 {
1191 host = host_create_from_sockaddr(addr);
1192 }
1193 }
1194 }
1195 enumerator->destroy(enumerator);
1196 break;
1197 }
1198 }
1199 else
1200 {
1201 failed = TRUE;
1202 }
1203 /* signal completion of query to a waiting thread */
1204 this->waiting_seq = 0;
1205 this->condvar->signal(this->condvar);
1206 this->mutex->unlock(this->mutex);
1207
1208 if (failed)
1209 {
1210 if (src)
1211 { /* the given source address might be gone, try again without */
1212 src = NULL;
1213 msg.hdr.rtm_seq = ++this->seq;
1214 msg.hdr.rtm_addrs = 0;
1215 memset(msg.buf, sizeof(msg.buf), 0);
1216 goto retry;
1217 }
1218 DBG1(DBG_KNL, "PF_ROUTE lookup failed: %s", strerror(errno));
1219 }
1220
1221 if (host)
1222 {
1223 DBG2(DBG_KNL, "using %H as %s to reach %H", host,
1224 nexthop ? "nexthop" : "address", dest);
1225 }
1226 return host;
1227 }
1228
1229 METHOD(kernel_net_t, get_source_addr, host_t*,
1230 private_kernel_pfroute_net_t *this, host_t *dest, host_t *src)
1231 {
1232 return get_route(this, FALSE, dest, src);
1233 }
1234
1235 METHOD(kernel_net_t, get_nexthop, host_t*,
1236 private_kernel_pfroute_net_t *this, host_t *dest, host_t *src)
1237 {
1238 return get_route(this, TRUE, dest, src);
1239 }
1240
1241 /**
1242 * Initialize a list of local addresses.
1243 */
1244 static status_t init_address_list(private_kernel_pfroute_net_t *this)
1245 {
1246 struct ifaddrs *ifap, *ifa;
1247 iface_entry_t *iface, *current;
1248 addr_entry_t *addr;
1249 enumerator_t *ifaces, *addrs;
1250
1251 DBG2(DBG_KNL, "known interfaces and IP addresses:");
1252
1253 if (getifaddrs(&ifap) < 0)
1254 {
1255 DBG1(DBG_KNL, " failed to get interfaces!");
1256 return FAILED;
1257 }
1258
1259 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
1260 {
1261 if (ifa->ifa_addr == NULL)
1262 {
1263 continue;
1264 }
1265 switch(ifa->ifa_addr->sa_family)
1266 {
1267 case AF_LINK:
1268 case AF_INET:
1269 case AF_INET6:
1270 {
1271 iface = NULL;
1272 ifaces = this->ifaces->create_enumerator(this->ifaces);
1273 while (ifaces->enumerate(ifaces, &current))
1274 {
1275 if (streq(current->ifname, ifa->ifa_name))
1276 {
1277 iface = current;
1278 break;
1279 }
1280 }
1281 ifaces->destroy(ifaces);
1282
1283 if (!iface)
1284 {
1285 INIT(iface,
1286 .ifindex = if_nametoindex(ifa->ifa_name),
1287 .flags = ifa->ifa_flags,
1288 .addrs = linked_list_create(),
1289 .usable = hydra->kernel_interface->is_interface_usable(
1290 hydra->kernel_interface, ifa->ifa_name),
1291 );
1292 memcpy(iface->ifname, ifa->ifa_name, IFNAMSIZ);
1293 this->ifaces->insert_last(this->ifaces, iface);
1294 }
1295
1296 if (ifa->ifa_addr->sa_family != AF_LINK)
1297 {
1298 INIT(addr,
1299 .ip = host_create_from_sockaddr(ifa->ifa_addr),
1300 );
1301 iface->addrs->insert_last(iface->addrs, addr);
1302 addr_map_entry_add(this, addr, iface);
1303 }
1304 }
1305 }
1306 }
1307 freeifaddrs(ifap);
1308
1309 ifaces = this->ifaces->create_enumerator(this->ifaces);
1310 while (ifaces->enumerate(ifaces, &iface))
1311 {
1312 if (iface->usable && iface->flags & IFF_UP)
1313 {
1314 DBG2(DBG_KNL, " %s", iface->ifname);
1315 addrs = iface->addrs->create_enumerator(iface->addrs);
1316 while (addrs->enumerate(addrs, (void**)&addr))
1317 {
1318 DBG2(DBG_KNL, " %H", addr->ip);
1319 }
1320 addrs->destroy(addrs);
1321 }
1322 }
1323 ifaces->destroy(ifaces);
1324
1325 return SUCCESS;
1326 }
1327
1328 METHOD(kernel_net_t, destroy, void,
1329 private_kernel_pfroute_net_t *this)
1330 {
1331 enumerator_t *enumerator;
1332 addr_entry_t *addr;
1333
1334 if (this->socket != -1)
1335 {
1336 close(this->socket);
1337 }
1338 enumerator = this->addrs->create_enumerator(this->addrs);
1339 while (enumerator->enumerate(enumerator, NULL, (void**)&addr))
1340 {
1341 free(addr);
1342 }
1343 enumerator->destroy(enumerator);
1344 this->addrs->destroy(this->addrs);
1345 this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy);
1346 this->tuns->destroy(this->tuns);
1347 this->lock->destroy(this->lock);
1348 this->mutex->destroy(this->mutex);
1349 this->condvar->destroy(this->condvar);
1350 free(this->reply);
1351 free(this);
1352 }
1353
1354 /*
1355 * Described in header.
1356 */
1357 kernel_pfroute_net_t *kernel_pfroute_net_create()
1358 {
1359 private_kernel_pfroute_net_t *this;
1360
1361 INIT(this,
1362 .public = {
1363 .interface = {
1364 .get_features = _get_features,
1365 .get_interface = _get_interface_name,
1366 .create_address_enumerator = _create_address_enumerator,
1367 .get_source_addr = _get_source_addr,
1368 .get_nexthop = _get_nexthop,
1369 .add_ip = _add_ip,
1370 .del_ip = _del_ip,
1371 .add_route = _add_route,
1372 .del_route = _del_route,
1373 .destroy = _destroy,
1374 },
1375 },
1376 .pid = getpid(),
1377 .ifaces = linked_list_create(),
1378 .addrs = hashtable_create(
1379 (hashtable_hash_t)addr_map_entry_hash,
1380 (hashtable_equals_t)addr_map_entry_equals, 16),
1381 .tuns = linked_list_create(),
1382 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
1383 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
1384 .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
1385 );
1386
1387 /* create a PF_ROUTE socket to communicate with the kernel */
1388 this->socket = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
1389 if (this->socket == -1)
1390 {
1391 DBG1(DBG_KNL, "unable to create PF_ROUTE socket");
1392 destroy(this);
1393 return NULL;
1394 }
1395
1396 if (streq(hydra->daemon, "starter"))
1397 {
1398 /* starter has no threads, so we do not register for kernel events */
1399 if (shutdown(this->socket, SHUT_RD) != 0)
1400 {
1401 DBG1(DBG_KNL, "closing read end of PF_ROUTE socket failed: %s",
1402 strerror(errno));
1403 }
1404 }
1405 else
1406 {
1407 lib->processor->queue_job(lib->processor,
1408 (job_t*)callback_job_create_with_prio(
1409 (callback_job_cb_t)receive_events, this, NULL,
1410 (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
1411 }
1412 if (init_address_list(this) != SUCCESS)
1413 {
1414 DBG1(DBG_KNL, "unable to get interface list");
1415 destroy(this);
1416 return NULL;
1417 }
1418
1419 return &this->public;
1420 }