5ce14e420e56b3778561b3ece1721a042955e6de
[platform/upstream/connman.git] / vpn / vpn-rtnl.c
1 /*
2  *
3  *  ConnMan VPN daemon
4  *
5  *  Copyright (C) 2012  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <errno.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <sys/socket.h>
31 #include <sys/ioctl.h>
32 #include <arpa/inet.h>
33 #include <netinet/ether.h>
34 #include <netinet/icmp6.h>
35 #include <net/if_arp.h>
36 #include <linux/if.h>
37 #include <linux/netlink.h>
38 #include <linux/rtnetlink.h>
39 #include <linux/wireless.h>
40
41 #include <glib.h>
42
43 #include <connman/log.h>
44
45 #include "vpn.h"
46
47 #include "vpn-rtnl.h"
48
49 #ifndef ARPHDR_PHONET_PIPE
50 #define ARPHDR_PHONET_PIPE (821)
51 #endif
52
53 #define print(arg...) do { if (0) connman_info(arg); } while (0)
54 #define debug(arg...) do { if (0) DBG(arg); } while (0)
55
56 struct watch_data {
57         unsigned int id;
58         int index;
59         vpn_rtnl_link_cb_t newlink;
60         void *user_data;
61 };
62
63 static GSList *watch_list = NULL;
64 static unsigned int watch_id = 0;
65
66 static GSList *update_list = NULL;
67 static guint update_interval = G_MAXUINT;
68 static guint update_timeout = 0;
69
70 struct interface_data {
71         int index;
72         char *name;
73         char *ident;
74 };
75
76 static GHashTable *interface_list = NULL;
77
78 static void free_interface(gpointer data)
79 {
80         struct interface_data *interface = data;
81
82         g_free(interface->ident);
83         g_free(interface->name);
84         g_free(interface);
85 }
86
87 /**
88  * vpn_rtnl_add_newlink_watch:
89  * @index: network device index
90  * @callback: callback function
91  * @user_data: callback data;
92  *
93  * Add a new RTNL watch for newlink events
94  *
95  * Returns: %0 on failure and a unique id on success
96  */
97 unsigned int vpn_rtnl_add_newlink_watch(int index,
98                         vpn_rtnl_link_cb_t callback, void *user_data)
99 {
100         struct watch_data *watch;
101
102         watch = g_try_new0(struct watch_data, 1);
103         if (watch == NULL)
104                 return 0;
105
106         watch->id = ++watch_id;
107         watch->index = index;
108
109         watch->newlink = callback;
110         watch->user_data = user_data;
111
112         watch_list = g_slist_prepend(watch_list, watch);
113
114         DBG("id %d", watch->id);
115
116         if (callback) {
117                 unsigned int flags = __vpn_ipconfig_get_flags_from_index(index);
118
119                 if (flags > 0)
120                         callback(flags, 0, user_data);
121         }
122
123         return watch->id;
124 }
125
126 /**
127  * vpn_rtnl_remove_watch:
128  * @id: watch identifier
129  *
130  * Remove the RTNL watch for the identifier
131  */
132 void vpn_rtnl_remove_watch(unsigned int id)
133 {
134         GSList *list;
135
136         DBG("id %d", id);
137
138         if (id == 0)
139                 return;
140
141         for (list = watch_list; list; list = list->next) {
142                 struct watch_data *watch = list->data;
143
144                 if (watch->id  == id) {
145                         watch_list = g_slist_remove(watch_list, watch);
146                         g_free(watch);
147                         break;
148                 }
149         }
150 }
151
152 static void trigger_rtnl(int index, void *user_data)
153 {
154         struct vpn_rtnl *rtnl = user_data;
155
156         if (rtnl->newlink) {
157                 unsigned short type = __vpn_ipconfig_get_type_from_index(index);
158                 unsigned int flags = __vpn_ipconfig_get_flags_from_index(index);
159
160                 rtnl->newlink(type, index, flags, 0);
161         }
162 }
163
164 static GSList *rtnl_list = NULL;
165
166 static gint compare_priority(gconstpointer a, gconstpointer b)
167 {
168         const struct vpn_rtnl *rtnl1 = a;
169         const struct vpn_rtnl *rtnl2 = b;
170
171         return rtnl2->priority - rtnl1->priority;
172 }
173
174 /**
175  * vpn_rtnl_register:
176  * @rtnl: RTNL module
177  *
178  * Register a new RTNL module
179  *
180  * Returns: %0 on success
181  */
182 int vpn_rtnl_register(struct vpn_rtnl *rtnl)
183 {
184         DBG("rtnl %p name %s", rtnl, rtnl->name);
185
186         rtnl_list = g_slist_insert_sorted(rtnl_list, rtnl,
187                                                         compare_priority);
188
189         __vpn_ipconfig_foreach(trigger_rtnl, rtnl);
190
191         return 0;
192 }
193
194 /**
195  * vpn_rtnl_unregister:
196  * @rtnl: RTNL module
197  *
198  * Remove a previously registered RTNL module
199  */
200 void vpn_rtnl_unregister(struct vpn_rtnl *rtnl)
201 {
202         DBG("rtnl %p name %s", rtnl, rtnl->name);
203
204         rtnl_list = g_slist_remove(rtnl_list, rtnl);
205 }
206
207 static const char *operstate2str(unsigned char operstate)
208 {
209         switch (operstate) {
210         case IF_OPER_UNKNOWN:
211                 return "UNKNOWN";
212         case IF_OPER_NOTPRESENT:
213                 return "NOT-PRESENT";
214         case IF_OPER_DOWN:
215                 return "DOWN";
216         case IF_OPER_LOWERLAYERDOWN:
217                 return "LOWER-LAYER-DOWN";
218         case IF_OPER_TESTING:
219                 return "TESTING";
220         case IF_OPER_DORMANT:
221                 return "DORMANT";
222         case IF_OPER_UP:
223                 return "UP";
224         }
225
226         return "";
227 }
228
229 static void extract_link(struct ifinfomsg *msg, int bytes,
230                                 struct ether_addr *address, const char **ifname,
231                                 unsigned int *mtu, unsigned char *operstate,
232                                                 struct rtnl_link_stats *stats)
233 {
234         struct rtattr *attr;
235
236         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
237                                         attr = RTA_NEXT(attr, bytes)) {
238                 switch (attr->rta_type) {
239                 case IFLA_ADDRESS:
240                         if (address != NULL)
241                                 memcpy(address, RTA_DATA(attr), ETH_ALEN);
242                         break;
243                 case IFLA_IFNAME:
244                         if (ifname != NULL)
245                                 *ifname = RTA_DATA(attr);
246                         break;
247                 case IFLA_MTU:
248                         if (mtu != NULL)
249                                 *mtu = *((unsigned int *) RTA_DATA(attr));
250                         break;
251                 case IFLA_STATS:
252                         if (stats != NULL)
253                                 memcpy(stats, RTA_DATA(attr),
254                                         sizeof(struct rtnl_link_stats));
255                         break;
256                 case IFLA_OPERSTATE:
257                         if (operstate != NULL)
258                                 *operstate = *((unsigned char *) RTA_DATA(attr));
259                         break;
260                 case IFLA_LINKMODE:
261                         break;
262                 }
263         }
264 }
265
266 static void process_newlink(unsigned short type, int index, unsigned flags,
267                         unsigned change, struct ifinfomsg *msg, int bytes)
268 {
269         struct ether_addr address = {{ 0, 0, 0, 0, 0, 0 }};
270         struct ether_addr compare = {{ 0, 0, 0, 0, 0, 0 }};
271         struct rtnl_link_stats stats;
272         unsigned char operstate = 0xff;
273         struct interface_data *interface;
274         const char *ifname = NULL;
275         unsigned int mtu = 0;
276         char ident[13], str[18];
277         GSList *list;
278
279         memset(&stats, 0, sizeof(stats));
280         extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats);
281
282         snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
283                                                 address.ether_addr_octet[0],
284                                                 address.ether_addr_octet[1],
285                                                 address.ether_addr_octet[2],
286                                                 address.ether_addr_octet[3],
287                                                 address.ether_addr_octet[4],
288                                                 address.ether_addr_octet[5]);
289
290         snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
291                                                 address.ether_addr_octet[0],
292                                                 address.ether_addr_octet[1],
293                                                 address.ether_addr_octet[2],
294                                                 address.ether_addr_octet[3],
295                                                 address.ether_addr_octet[4],
296                                                 address.ether_addr_octet[5]);
297
298         switch (type) {
299         case ARPHRD_ETHER:
300         case ARPHRD_LOOPBACK:
301         case ARPHDR_PHONET_PIPE:
302         case ARPHRD_NONE:
303                 __vpn_ipconfig_newlink(index, type, flags,
304                                                         str, mtu, &stats);
305                 break;
306         }
307
308         if (memcmp(&address, &compare, ETH_ALEN) != 0)
309                 connman_info("%s {newlink} index %d address %s mtu %u",
310                                                 ifname, index, str, mtu);
311
312         if (operstate != 0xff)
313                 connman_info("%s {newlink} index %d operstate %u <%s>",
314                                                 ifname, index, operstate,
315                                                 operstate2str(operstate));
316
317         interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index));
318         if (interface == NULL) {
319                 interface = g_new0(struct interface_data, 1);
320                 interface->index = index;
321                 interface->name = g_strdup(ifname);
322                 interface->ident = g_strdup(ident);
323
324                 g_hash_table_insert(interface_list,
325                                         GINT_TO_POINTER(index), interface);
326         }
327
328         for (list = rtnl_list; list; list = list->next) {
329                 struct vpn_rtnl *rtnl = list->data;
330
331                 if (rtnl->newlink)
332                         rtnl->newlink(type, index, flags, change);
333         }
334
335         for (list = watch_list; list; list = list->next) {
336                 struct watch_data *watch = list->data;
337
338                 if (watch->index != index)
339                         continue;
340
341                 if (watch->newlink)
342                         watch->newlink(flags, change, watch->user_data);
343         }
344 }
345
346 static void process_dellink(unsigned short type, int index, unsigned flags,
347                         unsigned change, struct ifinfomsg *msg, int bytes)
348 {
349         struct rtnl_link_stats stats;
350         unsigned char operstate = 0xff;
351         const char *ifname = NULL;
352         GSList *list;
353
354         memset(&stats, 0, sizeof(stats));
355         extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats);
356
357         if (operstate != 0xff)
358                 connman_info("%s {dellink} index %d operstate %u <%s>",
359                                                 ifname, index, operstate,
360                                                 operstate2str(operstate));
361
362         for (list = rtnl_list; list; list = list->next) {
363                 struct vpn_rtnl *rtnl = list->data;
364
365                 if (rtnl->dellink)
366                         rtnl->dellink(type, index, flags, change);
367         }
368
369         switch (type) {
370         case ARPHRD_ETHER:
371         case ARPHRD_LOOPBACK:
372         case ARPHRD_NONE:
373                 __vpn_ipconfig_dellink(index, &stats);
374                 break;
375         }
376
377         g_hash_table_remove(interface_list, GINT_TO_POINTER(index));
378 }
379
380 static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index,
381                                                 struct in_addr *dst,
382                                                 struct in_addr *gateway)
383 {
384         struct rtattr *attr;
385
386         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
387                                         attr = RTA_NEXT(attr, bytes)) {
388                 switch (attr->rta_type) {
389                 case RTA_DST:
390                         if (dst != NULL)
391                                 *dst = *((struct in_addr *) RTA_DATA(attr));
392                         break;
393                 case RTA_GATEWAY:
394                         if (gateway != NULL)
395                                 *gateway = *((struct in_addr *) RTA_DATA(attr));
396                         break;
397                 case RTA_OIF:
398                         if (index != NULL)
399                                 *index = *((int *) RTA_DATA(attr));
400                         break;
401                 }
402         }
403 }
404
405 static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index,
406                                                 struct in6_addr *dst,
407                                                 struct in6_addr *gateway)
408 {
409         struct rtattr *attr;
410
411         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
412                                         attr = RTA_NEXT(attr, bytes)) {
413                 switch (attr->rta_type) {
414                 case RTA_DST:
415                         if (dst != NULL)
416                                 *dst = *((struct in6_addr *) RTA_DATA(attr));
417                         break;
418                 case RTA_GATEWAY:
419                         if (gateway != NULL)
420                                 *gateway =
421                                         *((struct in6_addr *) RTA_DATA(attr));
422                         break;
423                 case RTA_OIF:
424                         if (index != NULL)
425                                 *index = *((int *) RTA_DATA(attr));
426                         break;
427                 }
428         }
429 }
430
431 static void process_newroute(unsigned char family, unsigned char scope,
432                                                 struct rtmsg *msg, int bytes)
433 {
434         GSList *list;
435         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
436         int index = -1;
437
438         if (family == AF_INET) {
439                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
440
441                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
442
443                 inet_ntop(family, &dst, dststr, sizeof(dststr));
444                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
445
446                 /* skip host specific routes */
447                 if (scope != RT_SCOPE_UNIVERSE &&
448                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
449                         return;
450
451                 if (dst.s_addr != INADDR_ANY)
452                         return;
453
454         } else if (family == AF_INET6) {
455                 struct in6_addr dst = IN6ADDR_ANY_INIT,
456                                 gateway = IN6ADDR_ANY_INIT;
457
458                 extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
459
460                 inet_ntop(family, &dst, dststr, sizeof(dststr));
461                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
462
463                 /* skip host specific routes */
464                 if (scope != RT_SCOPE_UNIVERSE &&
465                         !(scope == RT_SCOPE_LINK &&
466                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
467                         return;
468
469                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
470                         return;
471         } else
472                 return;
473
474         for (list = rtnl_list; list; list = list->next) {
475                 struct vpn_rtnl *rtnl = list->data;
476
477                 if (rtnl->newgateway)
478                         rtnl->newgateway(index, gatewaystr);
479         }
480 }
481
482 static void process_delroute(unsigned char family, unsigned char scope,
483                                                 struct rtmsg *msg, int bytes)
484 {
485         GSList *list;
486         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
487         int index = -1;
488
489         if (family == AF_INET) {
490                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
491
492                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
493
494                 inet_ntop(family, &dst, dststr, sizeof(dststr));
495                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
496
497                 /* skip host specific routes */
498                 if (scope != RT_SCOPE_UNIVERSE &&
499                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
500                         return;
501
502                 if (dst.s_addr != INADDR_ANY)
503                         return;
504
505         }  else if (family == AF_INET6) {
506                 struct in6_addr dst = IN6ADDR_ANY_INIT,
507                                 gateway = IN6ADDR_ANY_INIT;
508
509                 extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
510
511                 inet_ntop(family, &dst, dststr, sizeof(dststr));
512                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
513
514                 /* skip host specific routes */
515                 if (scope != RT_SCOPE_UNIVERSE &&
516                         !(scope == RT_SCOPE_LINK &&
517                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
518                         return;
519
520                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
521                         return;
522         } else
523                 return;
524
525         for (list = rtnl_list; list; list = list->next) {
526                 struct vpn_rtnl *rtnl = list->data;
527
528                 if (rtnl->delgateway)
529                         rtnl->delgateway(index, gatewaystr);
530         }
531 }
532
533 static inline void print_ether(struct rtattr *attr, const char *name)
534 {
535         int len = (int) RTA_PAYLOAD(attr);
536
537         if (len == ETH_ALEN) {
538                 struct ether_addr eth;
539                 memcpy(&eth, RTA_DATA(attr), ETH_ALEN);
540                 print("  attr %s (len %d) %s\n", name, len, ether_ntoa(&eth));
541         } else
542                 print("  attr %s (len %d)\n", name, len);
543 }
544
545 static inline void print_inet(struct rtattr *attr, const char *name,
546                                                         unsigned char family)
547 {
548         int len = (int) RTA_PAYLOAD(attr);
549
550         if (family == AF_INET && len == sizeof(struct in_addr)) {
551                 struct in_addr addr;
552                 addr = *((struct in_addr *) RTA_DATA(attr));
553                 print("  attr %s (len %d) %s\n", name, len, inet_ntoa(addr));
554         } else
555                 print("  attr %s (len %d)\n", name, len);
556 }
557
558 static inline void print_string(struct rtattr *attr, const char *name)
559 {
560         print("  attr %s (len %d) %s\n", name, (int) RTA_PAYLOAD(attr),
561                                                 (char *) RTA_DATA(attr));
562 }
563
564 static inline void print_byte(struct rtattr *attr, const char *name)
565 {
566         print("  attr %s (len %d) 0x%02x\n", name, (int) RTA_PAYLOAD(attr),
567                                         *((unsigned char *) RTA_DATA(attr)));
568 }
569
570 static inline void print_integer(struct rtattr *attr, const char *name)
571 {
572         print("  attr %s (len %d) %d\n", name, (int) RTA_PAYLOAD(attr),
573                                                 *((int *) RTA_DATA(attr)));
574 }
575
576 static inline void print_attr(struct rtattr *attr, const char *name)
577 {
578         int len = (int) RTA_PAYLOAD(attr);
579
580         if (name && len > 0)
581                 print("  attr %s (len %d)\n", name, len);
582         else
583                 print("  attr %d (len %d)\n", attr->rta_type, len);
584 }
585
586 static void rtnl_link(struct nlmsghdr *hdr)
587 {
588         struct ifinfomsg *msg;
589         struct rtattr *attr;
590         int bytes;
591
592         msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
593         bytes = IFLA_PAYLOAD(hdr);
594
595         print("ifi_index %d ifi_flags 0x%04x", msg->ifi_index, msg->ifi_flags);
596
597         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
598                                         attr = RTA_NEXT(attr, bytes)) {
599                 switch (attr->rta_type) {
600                 case IFLA_ADDRESS:
601                         print_ether(attr, "address");
602                         break;
603                 case IFLA_BROADCAST:
604                         print_ether(attr, "broadcast");
605                         break;
606                 case IFLA_IFNAME:
607                         print_string(attr, "ifname");
608                         break;
609                 case IFLA_MTU:
610                         print_integer(attr, "mtu");
611                         break;
612                 case IFLA_LINK:
613                         print_attr(attr, "link");
614                         break;
615                 case IFLA_QDISC:
616                         print_attr(attr, "qdisc");
617                         break;
618                 case IFLA_STATS:
619                         print_attr(attr, "stats");
620                         break;
621                 case IFLA_COST:
622                         print_attr(attr, "cost");
623                         break;
624                 case IFLA_PRIORITY:
625                         print_attr(attr, "priority");
626                         break;
627                 case IFLA_MASTER:
628                         print_attr(attr, "master");
629                         break;
630                 case IFLA_WIRELESS:
631                         print_attr(attr, "wireless");
632                         break;
633                 case IFLA_PROTINFO:
634                         print_attr(attr, "protinfo");
635                         break;
636                 case IFLA_TXQLEN:
637                         print_integer(attr, "txqlen");
638                         break;
639                 case IFLA_MAP:
640                         print_attr(attr, "map");
641                         break;
642                 case IFLA_WEIGHT:
643                         print_attr(attr, "weight");
644                         break;
645                 case IFLA_OPERSTATE:
646                         print_byte(attr, "operstate");
647                         break;
648                 case IFLA_LINKMODE:
649                         print_byte(attr, "linkmode");
650                         break;
651                 default:
652                         print_attr(attr, NULL);
653                         break;
654                 }
655         }
656 }
657
658 static void rtnl_newlink(struct nlmsghdr *hdr)
659 {
660         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
661
662         rtnl_link(hdr);
663
664         process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
665                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
666 }
667
668 static void rtnl_dellink(struct nlmsghdr *hdr)
669 {
670         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
671
672         rtnl_link(hdr);
673
674         process_dellink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
675                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
676 }
677
678 static void rtnl_route(struct nlmsghdr *hdr)
679 {
680         struct rtmsg *msg;
681         struct rtattr *attr;
682         int bytes;
683
684         msg = (struct rtmsg *) NLMSG_DATA(hdr);
685         bytes = RTM_PAYLOAD(hdr);
686
687         print("rtm_family %d rtm_table %d rtm_protocol %d",
688                         msg->rtm_family, msg->rtm_table, msg->rtm_protocol);
689         print("rtm_scope %d rtm_type %d rtm_flags 0x%04x",
690                                 msg->rtm_scope, msg->rtm_type, msg->rtm_flags);
691
692         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
693                                         attr = RTA_NEXT(attr, bytes)) {
694                 switch (attr->rta_type) {
695                 case RTA_DST:
696                         print_inet(attr, "dst", msg->rtm_family);
697                         break;
698                 case RTA_SRC:
699                         print_inet(attr, "src", msg->rtm_family);
700                         break;
701                 case RTA_IIF:
702                         print_string(attr, "iif");
703                         break;
704                 case RTA_OIF:
705                         print_integer(attr, "oif");
706                         break;
707                 case RTA_GATEWAY:
708                         print_inet(attr, "gateway", msg->rtm_family);
709                         break;
710                 case RTA_PRIORITY:
711                         print_attr(attr, "priority");
712                         break;
713                 case RTA_PREFSRC:
714                         print_inet(attr, "prefsrc", msg->rtm_family);
715                         break;
716                 case RTA_METRICS:
717                         print_attr(attr, "metrics");
718                         break;
719                 case RTA_TABLE:
720                         print_integer(attr, "table");
721                         break;
722                 default:
723                         print_attr(attr, NULL);
724                         break;
725                 }
726         }
727 }
728
729 static connman_bool_t is_route_rtmsg(struct rtmsg *msg)
730 {
731
732         if (msg->rtm_table != RT_TABLE_MAIN)
733                 return FALSE;
734
735         if (msg->rtm_protocol != RTPROT_BOOT &&
736                         msg->rtm_protocol != RTPROT_KERNEL)
737                 return FALSE;
738
739         if (msg->rtm_type != RTN_UNICAST)
740                 return FALSE;
741
742         return TRUE;
743 }
744
745 static void rtnl_newroute(struct nlmsghdr *hdr)
746 {
747         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
748
749         rtnl_route(hdr);
750
751         if (is_route_rtmsg(msg))
752                 process_newroute(msg->rtm_family, msg->rtm_scope,
753                                                 msg, RTM_PAYLOAD(hdr));
754 }
755
756 static void rtnl_delroute(struct nlmsghdr *hdr)
757 {
758         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
759
760         rtnl_route(hdr);
761
762         if (is_route_rtmsg(msg))
763                 process_delroute(msg->rtm_family, msg->rtm_scope,
764                                                 msg, RTM_PAYLOAD(hdr));
765 }
766
767 static const char *type2string(uint16_t type)
768 {
769         switch (type) {
770         case NLMSG_NOOP:
771                 return "NOOP";
772         case NLMSG_ERROR:
773                 return "ERROR";
774         case NLMSG_DONE:
775                 return "DONE";
776         case NLMSG_OVERRUN:
777                 return "OVERRUN";
778         case RTM_GETLINK:
779                 return "GETLINK";
780         case RTM_NEWLINK:
781                 return "NEWLINK";
782         case RTM_DELLINK:
783                 return "DELLINK";
784         case RTM_NEWADDR:
785                 return "NEWADDR";
786         case RTM_DELADDR:
787                 return "DELADDR";
788         case RTM_GETROUTE:
789                 return "GETROUTE";
790         case RTM_NEWROUTE:
791                 return "NEWROUTE";
792         case RTM_DELROUTE:
793                 return "DELROUTE";
794         case RTM_NEWNDUSEROPT:
795                 return "NEWNDUSEROPT";
796         default:
797                 return "UNKNOWN";
798         }
799 }
800
801 static GIOChannel *channel = NULL;
802
803 struct rtnl_request {
804         struct nlmsghdr hdr;
805         struct rtgenmsg msg;
806 };
807 #define RTNL_REQUEST_SIZE  (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))
808
809 static GSList *request_list = NULL;
810 static guint32 request_seq = 0;
811
812 static struct rtnl_request *find_request(guint32 seq)
813 {
814         GSList *list;
815
816         for (list = request_list; list; list = list->next) {
817                 struct rtnl_request *req = list->data;
818
819                 if (req->hdr.nlmsg_seq == seq)
820                         return req;
821         }
822
823         return NULL;
824 }
825
826 static int send_request(struct rtnl_request *req)
827 {
828         struct sockaddr_nl addr;
829         int sk;
830
831         debug("%s len %d type %d flags 0x%04x seq %d",
832                                 type2string(req->hdr.nlmsg_type),
833                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
834                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
835
836         sk = g_io_channel_unix_get_fd(channel);
837
838         memset(&addr, 0, sizeof(addr));
839         addr.nl_family = AF_NETLINK;
840
841         return sendto(sk, req, req->hdr.nlmsg_len, 0,
842                                 (struct sockaddr *) &addr, sizeof(addr));
843 }
844
845 static int queue_request(struct rtnl_request *req)
846 {
847         request_list = g_slist_append(request_list, req);
848
849         if (g_slist_length(request_list) > 1)
850                 return 0;
851
852         return send_request(req);
853 }
854
855 static int process_response(guint32 seq)
856 {
857         struct rtnl_request *req;
858
859         debug("seq %d", seq);
860
861         req = find_request(seq);
862         if (req != NULL) {
863                 request_list = g_slist_remove(request_list, req);
864                 g_free(req);
865         }
866
867         req = g_slist_nth_data(request_list, 0);
868         if (req == NULL)
869                 return 0;
870
871         return send_request(req);
872 }
873
874 static void rtnl_message(void *buf, size_t len)
875 {
876         debug("buf %p len %zd", buf, len);
877
878         while (len > 0) {
879                 struct nlmsghdr *hdr = buf;
880                 struct nlmsgerr *err;
881
882                 if (!NLMSG_OK(hdr, len))
883                         break;
884
885                 debug("%s len %d type %d flags 0x%04x seq %d pid %d",
886                                         type2string(hdr->nlmsg_type),
887                                         hdr->nlmsg_len, hdr->nlmsg_type,
888                                         hdr->nlmsg_flags, hdr->nlmsg_seq,
889                                         hdr->nlmsg_pid);
890
891                 switch (hdr->nlmsg_type) {
892                 case NLMSG_NOOP:
893                 case NLMSG_OVERRUN:
894                         return;
895                 case NLMSG_DONE:
896                         process_response(hdr->nlmsg_seq);
897                         return;
898                 case NLMSG_ERROR:
899                         err = NLMSG_DATA(hdr);
900                         DBG("error %d (%s)", -err->error,
901                                                 strerror(-err->error));
902                         return;
903                 case RTM_NEWLINK:
904                         rtnl_newlink(hdr);
905                         break;
906                 case RTM_DELLINK:
907                         rtnl_dellink(hdr);
908                         break;
909                 case RTM_NEWADDR:
910                         break;
911                 case RTM_DELADDR:
912                         break;
913                 case RTM_NEWROUTE:
914                         rtnl_newroute(hdr);
915                         break;
916                 case RTM_DELROUTE:
917                         rtnl_delroute(hdr);
918                         break;
919                 }
920
921                 len -= hdr->nlmsg_len;
922                 buf += hdr->nlmsg_len;
923         }
924 }
925
926 static gboolean netlink_event(GIOChannel *chan,
927                                 GIOCondition cond, gpointer data)
928 {
929         unsigned char buf[4096];
930         struct sockaddr_nl nladdr;
931         socklen_t addr_len = sizeof(nladdr);
932         ssize_t status;
933         int fd;
934
935         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
936                 return FALSE;
937
938         memset(buf, 0, sizeof(buf));
939         memset(&nladdr, 0, sizeof(nladdr));
940
941         fd = g_io_channel_unix_get_fd(chan);
942
943         status = recvfrom(fd, buf, sizeof(buf), 0,
944                        (struct sockaddr *) &nladdr, &addr_len);
945         if (status < 0) {
946                 if (errno == EINTR || errno == EAGAIN)
947                         return TRUE;
948
949                 return FALSE;
950         }
951
952         if (status == 0)
953                 return FALSE;
954
955         if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
956                 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
957                 return TRUE;
958         }
959
960         rtnl_message(buf, status);
961
962         return TRUE;
963 }
964
965 static int send_getlink(void)
966 {
967         struct rtnl_request *req;
968
969         debug("");
970
971         req = g_try_malloc0(RTNL_REQUEST_SIZE);
972         if (req == NULL)
973                 return -ENOMEM;
974
975         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
976         req->hdr.nlmsg_type = RTM_GETLINK;
977         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
978         req->hdr.nlmsg_pid = 0;
979         req->hdr.nlmsg_seq = request_seq++;
980         req->msg.rtgen_family = AF_INET;
981
982         return queue_request(req);
983 }
984
985 static int send_getaddr(void)
986 {
987         struct rtnl_request *req;
988
989         debug("");
990
991         req = g_try_malloc0(RTNL_REQUEST_SIZE);
992         if (req == NULL)
993                 return -ENOMEM;
994
995         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
996         req->hdr.nlmsg_type = RTM_GETADDR;
997         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
998         req->hdr.nlmsg_pid = 0;
999         req->hdr.nlmsg_seq = request_seq++;
1000         req->msg.rtgen_family = AF_INET;
1001
1002         return queue_request(req);
1003 }
1004
1005 static int send_getroute(void)
1006 {
1007         struct rtnl_request *req;
1008
1009         debug("");
1010
1011         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1012         if (req == NULL)
1013                 return -ENOMEM;
1014
1015         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1016         req->hdr.nlmsg_type = RTM_GETROUTE;
1017         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1018         req->hdr.nlmsg_pid = 0;
1019         req->hdr.nlmsg_seq = request_seq++;
1020         req->msg.rtgen_family = AF_INET;
1021
1022         return queue_request(req);
1023 }
1024
1025 static gboolean update_timeout_cb(gpointer user_data)
1026 {
1027         __vpn_rtnl_request_update();
1028
1029         return TRUE;
1030 }
1031
1032 static void update_interval_callback(guint min)
1033 {
1034         if (update_timeout > 0)
1035                 g_source_remove(update_timeout);
1036
1037         if (min < G_MAXUINT) {
1038                 update_interval = min;
1039                 update_timeout = g_timeout_add_seconds(update_interval,
1040                                                 update_timeout_cb, NULL);
1041         } else {
1042                 update_timeout = 0;
1043                 update_interval = G_MAXUINT;
1044         }
1045 }
1046
1047 static gint compare_interval(gconstpointer a, gconstpointer b)
1048 {
1049         guint val_a = GPOINTER_TO_UINT(a);
1050         guint val_b = GPOINTER_TO_UINT(b);
1051
1052         return val_a - val_b;
1053 }
1054
1055 unsigned int __vpn_rtnl_update_interval_add(unsigned int interval)
1056 {
1057         guint min;
1058
1059         if (interval == 0)
1060                 return 0;
1061
1062         update_list = g_slist_insert_sorted(update_list,
1063                         GUINT_TO_POINTER(interval), compare_interval);
1064
1065         min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1066         if (min < update_interval) {
1067                 update_interval_callback(min);
1068                 __vpn_rtnl_request_update();
1069         }
1070
1071         return update_interval;
1072 }
1073
1074 unsigned int __vpn_rtnl_update_interval_remove(unsigned int interval)
1075 {
1076         guint min = G_MAXUINT;
1077
1078         if (interval == 0)
1079                 return 0;
1080
1081         update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval));
1082
1083         if (update_list != NULL)
1084                 min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1085
1086         if (min > update_interval)
1087                 update_interval_callback(min);
1088
1089         return min;
1090 }
1091
1092 int __vpn_rtnl_request_update(void)
1093 {
1094         return send_getlink();
1095 }
1096
1097 int __vpn_rtnl_init(void)
1098 {
1099         struct sockaddr_nl addr;
1100         int sk;
1101
1102         DBG("");
1103
1104         interface_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1105                                                         NULL, free_interface);
1106
1107         sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
1108         if (sk < 0)
1109                 return -1;
1110
1111         memset(&addr, 0, sizeof(addr));
1112         addr.nl_family = AF_NETLINK;
1113         addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
1114                                 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE |
1115                                 (1<<(RTNLGRP_ND_USEROPT-1));
1116
1117         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1118                 close(sk);
1119                 return -1;
1120         }
1121
1122         channel = g_io_channel_unix_new(sk);
1123         g_io_channel_set_close_on_unref(channel, TRUE);
1124
1125         g_io_channel_set_encoding(channel, NULL, NULL);
1126         g_io_channel_set_buffered(channel, FALSE);
1127
1128         g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1129                                                         netlink_event, NULL);
1130
1131         return 0;
1132 }
1133
1134 void __vpn_rtnl_start(void)
1135 {
1136         DBG("");
1137
1138         send_getlink();
1139         send_getaddr();
1140         send_getroute();
1141 }
1142
1143 void __vpn_rtnl_cleanup(void)
1144 {
1145         GSList *list;
1146
1147         DBG("");
1148
1149         for (list = watch_list; list; list = list->next) {
1150                 struct watch_data *watch = list->data;
1151
1152                 DBG("removing watch %d", watch->id);
1153
1154                 g_free(watch);
1155                 list->data = NULL;
1156         }
1157
1158         g_slist_free(watch_list);
1159         watch_list = NULL;
1160
1161         g_slist_free(update_list);
1162         update_list = NULL;
1163
1164         for (list = request_list; list; list = list->next) {
1165                 struct rtnl_request *req = list->data;
1166
1167                 debug("%s len %d type %d flags 0x%04x seq %d",
1168                                 type2string(req->hdr.nlmsg_type),
1169                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1170                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1171
1172                 g_free(req);
1173                 list->data = NULL;
1174         }
1175
1176         g_slist_free(request_list);
1177         request_list = NULL;
1178
1179         g_io_channel_shutdown(channel, TRUE, NULL);
1180         g_io_channel_unref(channel);
1181
1182         channel = NULL;
1183
1184         g_hash_table_destroy(interface_list);
1185 }