Base Code merged to SPIN 2.4
[platform/upstream/connman.git] / src / rtnl.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2013  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.h"
44
45 #ifndef ARPHDR_PHONET_PIPE
46 #define ARPHDR_PHONET_PIPE (821)
47 #endif
48
49 #if defined TIZEN_EXT
50 #ifndef ARPHDR_RMNET
51 #define ARPHDR_RMNET (530)
52 #endif
53 #endif
54
55 #define print(arg...) do { if (0) connman_info(arg); } while (0)
56 //#define print(arg...) connman_info(arg)
57
58 struct watch_data {
59         unsigned int id;
60         int index;
61         connman_rtnl_link_cb_t newlink;
62         void *user_data;
63 };
64
65 static GSList *watch_list = NULL;
66 static unsigned int watch_id = 0;
67
68 static GSList *update_list = NULL;
69 static guint update_interval = G_MAXUINT;
70 static guint update_timeout = 0;
71
72 struct interface_data {
73         int index;
74         char *ident;
75         enum connman_service_type service_type;
76         enum connman_device_type device_type;
77 };
78
79 static GHashTable *interface_list = NULL;
80
81 static void free_interface(gpointer data)
82 {
83         struct interface_data *interface = data;
84
85         __connman_technology_remove_interface(interface->service_type,
86                         interface->index, interface->ident);
87
88         g_free(interface->ident);
89         g_free(interface);
90 }
91
92 static bool ether_blacklisted(const char *name)
93 {
94         if (!name)
95                 return true;
96
97         if (__connman_device_isfiltered(name))
98                 return true;
99
100         return false;
101 }
102
103 static bool wext_interface(char *ifname)
104 {
105         struct iwreq wrq;
106         int fd, err;
107
108         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
109         if (fd < 0)
110                 return false;
111
112         memset(&wrq, 0, sizeof(wrq));
113         strncpy(wrq.ifr_name, ifname, sizeof(wrq.ifr_name) - 1);
114
115         err = ioctl(fd, SIOCGIWNAME, &wrq);
116
117         close(fd);
118
119         if (err < 0)
120                 return false;
121
122         return true;
123 }
124
125 #if defined TIZEN_EXT
126 static bool __connman_rtnl_is_cellular_device(const char *name)
127 {
128         char **pattern;
129         char **cellular_interfaces;
130
131         cellular_interfaces =
132                         connman_setting_get_string_list(
133                                         "NetworkCellularInterfaceList");
134         if (!cellular_interfaces)
135                 return false;
136
137         for (pattern = cellular_interfaces; *pattern; pattern++) {
138                 if (g_str_has_prefix(name, *pattern)) {
139                         DBG("Cellular interface: %s", name);
140                         return true;
141                 }
142         }
143
144         return false;
145 }
146 #endif
147
148 static void read_uevent(struct interface_data *interface)
149 {
150         char *filename, *name, line[128];
151         bool found_devtype;
152         FILE *f;
153
154         name = connman_inet_ifname(interface->index);
155
156 #if defined TIZEN_EXT
157         if (__connman_rtnl_is_cellular_device(name)) {
158                 interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
159                 interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
160                 return;
161         }
162 #endif
163
164         if (ether_blacklisted(name)) {
165                 interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
166                 interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
167         } else {
168                 interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
169                 interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
170         }
171
172         filename = g_strdup_printf("/sys/class/net/%s/uevent", name);
173
174         f = fopen(filename, "re");
175
176         g_free(filename);
177
178         if (!f) {
179                 interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
180                 interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
181                 goto out;
182         }
183
184         found_devtype = false;
185         while (fgets(line, sizeof(line), f)) {
186                 char *pos;
187
188                 pos = strchr(line, '\n');
189                 if (!pos)
190                         continue;
191                 pos[0] = '\0';
192
193                 if (strncmp(line, "DEVTYPE=", 8) != 0)
194                         continue;
195
196                 found_devtype = true;
197
198                 if (strcmp(line + 8, "wlan") == 0) {
199                         interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
200                         interface->device_type = CONNMAN_DEVICE_TYPE_WIFI;
201                 } else if (strcmp(line + 8, "wwan") == 0) {
202                         interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
203                         interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
204                 } else if (strcmp(line + 8, "bluetooth") == 0) {
205                         interface->service_type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
206                         interface->device_type = CONNMAN_DEVICE_TYPE_BLUETOOTH;
207                 } else if (strcmp(line + 8, "gadget") == 0) {
208                         interface->service_type = CONNMAN_SERVICE_TYPE_GADGET;
209                         interface->device_type = CONNMAN_DEVICE_TYPE_GADGET;
210                 } else if (strcmp(line + 8, "vlan") == 0) {
211                         interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
212                         interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
213
214                 } else {
215                         interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
216                         interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
217                 }
218         }
219
220         fclose(f);
221
222         if (found_devtype)
223                 goto out;
224
225         /* We haven't got a DEVTYPE, let's check if it's a wireless device */
226         if (wext_interface(name)) {
227                 interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
228                 interface->device_type = CONNMAN_DEVICE_TYPE_WIFI;
229
230                 connman_error("%s runs an unsupported 802.11 driver", name);
231         }
232
233 out:
234         g_free(name);
235 }
236
237 enum connman_device_type __connman_rtnl_get_device_type(int index)
238 {
239         struct interface_data *interface;
240
241         interface = g_hash_table_lookup(interface_list,
242                                         GINT_TO_POINTER(index));
243         if (!interface)
244                 return CONNMAN_DEVICE_TYPE_UNKNOWN;
245
246         return interface->device_type;
247 }
248
249 /**
250  * connman_rtnl_add_newlink_watch:
251  * @index: network device index
252  * @callback: callback function
253  * @user_data: callback data;
254  *
255  * Add a new RTNL watch for newlink events
256  *
257  * Returns: %0 on failure and a unique id on success
258  */
259 unsigned int connman_rtnl_add_newlink_watch(int index,
260                         connman_rtnl_link_cb_t callback, void *user_data)
261 {
262         struct watch_data *watch;
263
264         watch = g_try_new0(struct watch_data, 1);
265         if (!watch)
266                 return 0;
267
268         watch->id = ++watch_id;
269         watch->index = index;
270
271         watch->newlink = callback;
272         watch->user_data = user_data;
273
274         watch_list = g_slist_prepend(watch_list, watch);
275
276         DBG("id %d", watch->id);
277
278         if (callback) {
279                 unsigned int flags = __connman_ipconfig_get_flags_from_index(index);
280
281                 if (flags > 0)
282                         callback(flags, 0, user_data);
283         }
284
285         return watch->id;
286 }
287
288 /**
289  * connman_rtnl_remove_watch:
290  * @id: watch identifier
291  *
292  * Remove the RTNL watch for the identifier
293  */
294 void connman_rtnl_remove_watch(unsigned int id)
295 {
296         GSList *list;
297
298         DBG("id %d", id);
299
300         if (id == 0)
301                 return;
302
303         for (list = watch_list; list; list = list->next) {
304                 struct watch_data *watch = list->data;
305
306                 if (watch->id  == id) {
307                         watch_list = g_slist_remove(watch_list, watch);
308                         g_free(watch);
309                         break;
310                 }
311         }
312 }
313
314 static void trigger_rtnl(int index, void *user_data)
315 {
316         struct connman_rtnl *rtnl = user_data;
317
318         if (rtnl->newlink) {
319                 unsigned short type = __connman_ipconfig_get_type_from_index(index);
320                 unsigned int flags = __connman_ipconfig_get_flags_from_index(index);
321
322                 rtnl->newlink(type, index, flags, 0);
323         }
324
325         if (rtnl->newgateway) {
326                 const char *gateway =
327                         __connman_ipconfig_get_gateway_from_index(index,
328                                         CONNMAN_IPCONFIG_TYPE_ALL);
329
330                 if (gateway)
331                         rtnl->newgateway(index, gateway);
332         }
333 }
334
335 static GSList *rtnl_list = NULL;
336
337 static gint compare_priority(gconstpointer a, gconstpointer b)
338 {
339         const struct connman_rtnl *rtnl1 = a;
340         const struct connman_rtnl *rtnl2 = b;
341
342         return rtnl2->priority - rtnl1->priority;
343 }
344
345 /**
346  * connman_rtnl_register:
347  * @rtnl: RTNL module
348  *
349  * Register a new RTNL module
350  *
351  * Returns: %0 on success
352  */
353 int connman_rtnl_register(struct connman_rtnl *rtnl)
354 {
355         DBG("rtnl %p name %s", rtnl, rtnl->name);
356
357         rtnl_list = g_slist_insert_sorted(rtnl_list, rtnl,
358                                                         compare_priority);
359
360         __connman_ipconfig_foreach(trigger_rtnl, rtnl);
361
362         return 0;
363 }
364
365 /**
366  * connman_rtnl_unregister:
367  * @rtnl: RTNL module
368  *
369  * Remove a previously registered RTNL module
370  */
371 void connman_rtnl_unregister(struct connman_rtnl *rtnl)
372 {
373         DBG("rtnl %p name %s", rtnl, rtnl->name);
374
375         rtnl_list = g_slist_remove(rtnl_list, rtnl);
376 }
377
378 static const char *operstate2str(unsigned char operstate)
379 {
380         switch (operstate) {
381         case IF_OPER_UNKNOWN:
382                 return "UNKNOWN";
383         case IF_OPER_NOTPRESENT:
384                 return "NOT-PRESENT";
385         case IF_OPER_DOWN:
386                 return "DOWN";
387         case IF_OPER_LOWERLAYERDOWN:
388                 return "LOWER-LAYER-DOWN";
389         case IF_OPER_TESTING:
390                 return "TESTING";
391         case IF_OPER_DORMANT:
392                 return "DORMANT";
393         case IF_OPER_UP:
394                 return "UP";
395         }
396
397         return "";
398 }
399
400 static bool extract_link(struct ifinfomsg *msg, int bytes,
401                                 struct ether_addr *address, const char **ifname,
402                                 unsigned int *mtu, unsigned char *operstate,
403                                 struct rtnl_link_stats *stats)
404 {
405         struct rtattr *attr;
406
407         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
408                                         attr = RTA_NEXT(attr, bytes)) {
409                 switch (attr->rta_type) {
410                 case IFLA_ADDRESS:
411                         if (address)
412                                 memcpy(address, RTA_DATA(attr), ETH_ALEN);
413                         break;
414                 case IFLA_IFNAME:
415                         if (ifname)
416                                 *ifname = RTA_DATA(attr);
417                         break;
418                 case IFLA_MTU:
419                         if (mtu)
420                                 *mtu = *((unsigned int *) RTA_DATA(attr));
421                         break;
422                 case IFLA_STATS:
423                         if (stats)
424                                 memcpy(stats, RTA_DATA(attr),
425                                         sizeof(struct rtnl_link_stats));
426                         break;
427                 case IFLA_OPERSTATE:
428                         if (operstate)
429                                 *operstate = *((unsigned char *) RTA_DATA(attr));
430                         break;
431                 case IFLA_LINKMODE:
432                         break;
433                 case IFLA_WIRELESS:
434                         return false;
435                 }
436         }
437
438         return true;
439 }
440
441 static void process_newlink(unsigned short type, int index, unsigned flags,
442                         unsigned change, struct ifinfomsg *msg, int bytes)
443 {
444         struct ether_addr address = {{ 0, 0, 0, 0, 0, 0 }};
445         struct rtnl_link_stats stats;
446         unsigned char operstate = 0xff;
447         struct interface_data *interface;
448         const char *ifname = NULL;
449         unsigned int mtu = 0;
450         char ident[13], str[18];
451         GSList *list;
452
453         memset(&stats, 0, sizeof(stats));
454         if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats))
455                 return;
456
457 #if defined TIZEN_EXT
458         /* Do not accept Wi-Fi P2P interface */
459         if (g_strrstr(ifname, "p2p") != NULL) {
460                 DBG("Newlink event for Wi-Fi P2P interface ignored");
461                 return;
462         }
463 #endif
464
465         snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
466                                                 address.ether_addr_octet[0],
467                                                 address.ether_addr_octet[1],
468                                                 address.ether_addr_octet[2],
469                                                 address.ether_addr_octet[3],
470                                                 address.ether_addr_octet[4],
471                                                 address.ether_addr_octet[5]);
472
473         snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
474                                                 address.ether_addr_octet[0],
475                                                 address.ether_addr_octet[1],
476                                                 address.ether_addr_octet[2],
477                                                 address.ether_addr_octet[3],
478                                                 address.ether_addr_octet[4],
479                                                 address.ether_addr_octet[5]);
480
481         if (flags & IFF_SLAVE) {
482                 connman_info("%s {newlink} ignoring slave, index %d address %s",
483                                                 ifname, index, str);
484                 return;
485         }
486
487 #if defined TIZEN_TV_EXT
488         if (g_strcmp0(ident, "eeeeeeeeeeee") == 0) {
489                 DBG("Newlink event with Dummy MAC. Ignored!");
490                 return;
491         }
492 #endif
493
494         switch (type) {
495         case ARPHRD_ETHER:
496         case ARPHRD_LOOPBACK:
497         case ARPHDR_PHONET_PIPE:
498         case ARPHRD_PPP:
499         case ARPHRD_NONE:
500 #if defined TIZEN_EXT
501 /*
502  * Description: ARPHDR_RMNET for QC modem using QMI
503  */
504         case ARPHDR_RMNET:
505 #endif
506                 __connman_ipconfig_newlink(index, type, flags,
507                                                         str, mtu, &stats);
508                 break;
509         }
510
511         connman_info("%s {newlink} index %d address %s mtu %u",
512                                         ifname, index, str, mtu);
513
514         if (operstate != 0xff)
515                 connman_info("%s {newlink} index %d operstate %u <%s>",
516                                                 ifname, index, operstate,
517                                                 operstate2str(operstate));
518
519         interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index));
520         if (!interface) {
521                 interface = g_new0(struct interface_data, 1);
522                 interface->index = index;
523                 interface->ident = g_strdup(ident);
524
525                 g_hash_table_insert(interface_list,
526                                         GINT_TO_POINTER(index), interface);
527
528                 if (type == ARPHRD_ETHER)
529                         read_uevent(interface);
530 #if defined TIZEN_EXT
531                 if (type == ARPHRD_PPP || type == ARPHDR_RMNET)
532                         read_uevent(interface);
533
534         } else if (g_strcmp0(interface->ident, ident) != 0) {
535                 /* If an original address is built-in physical device,
536                  * it's hardly get an address at a initial creation
537                  */
538                 __connman_technology_remove_interface(interface->service_type,
539                                 interface->index, interface->ident);
540
541                 g_free(interface->ident);
542                 interface->ident = g_strdup(ident);
543
544                 __connman_technology_add_interface(interface->service_type,
545                                 interface->index, interface->ident);
546
547                 interface = NULL;
548 #endif
549         } else
550                 interface = NULL;
551
552         for (list = rtnl_list; list; list = list->next) {
553                 struct connman_rtnl *rtnl = list->data;
554
555                 if (rtnl->newlink)
556                         rtnl->newlink(type, index, flags, change);
557         }
558
559         /*
560          * The interface needs to be added after the newlink call.
561          * The newlink will create the technology when needed and
562          * __connman_technology_add_interface() expects the
563          * technology to be there already.
564          */
565         if (interface)
566                 __connman_technology_add_interface(interface->service_type,
567                         interface->index, interface->ident);
568
569         for (list = watch_list; list; list = list->next) {
570                 struct watch_data *watch = list->data;
571
572                 if (watch->index != index)
573                         continue;
574
575                 if (watch->newlink)
576                         watch->newlink(flags, change, watch->user_data);
577         }
578 }
579
580 static void process_dellink(unsigned short type, int index, unsigned flags,
581                         unsigned change, struct ifinfomsg *msg, int bytes)
582 {
583         struct rtnl_link_stats stats;
584         unsigned char operstate = 0xff;
585         const char *ifname = NULL;
586         GSList *list;
587
588         memset(&stats, 0, sizeof(stats));
589         if (!extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats))
590                 return;
591
592         if (operstate != 0xff)
593                 connman_info("%s {dellink} index %d operstate %u <%s>",
594                                                 ifname, index, operstate,
595                                                 operstate2str(operstate));
596
597         for (list = rtnl_list; list; list = list->next) {
598                 struct connman_rtnl *rtnl = list->data;
599
600                 if (rtnl->dellink)
601                         rtnl->dellink(type, index, flags, change);
602         }
603
604         switch (type) {
605         case ARPHRD_ETHER:
606         case ARPHRD_LOOPBACK:
607         case ARPHDR_PHONET_PIPE:
608         case ARPHRD_PPP:
609         case ARPHRD_NONE:
610 #if defined TIZEN_EXT
611         /*
612          * Description: SLP requires ARPHRD_PPP for PPP type device
613          *              ARPHDR_RMNET for QC modem using QMI
614          */
615         case ARPHDR_RMNET:
616 #endif
617                 __connman_ipconfig_dellink(index, &stats);
618                 break;
619         }
620
621         g_hash_table_remove(interface_list, GINT_TO_POINTER(index));
622 }
623
624 static void extract_ipv4_addr(struct ifaddrmsg *msg, int bytes,
625                                                 const char **label,
626                                                 struct in_addr *local,
627                                                 struct in_addr *address,
628                                                 struct in_addr *broadcast)
629 {
630         struct rtattr *attr;
631
632         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
633                                         attr = RTA_NEXT(attr, bytes)) {
634                 switch (attr->rta_type) {
635                 case IFA_ADDRESS:
636                         if (address)
637                                 *address = *((struct in_addr *) RTA_DATA(attr));
638                         break;
639                 case IFA_LOCAL:
640                         if (local)
641                                 *local = *((struct in_addr *) RTA_DATA(attr));
642                         break;
643                 case IFA_BROADCAST:
644                         if (broadcast)
645                                 *broadcast = *((struct in_addr *) RTA_DATA(attr));
646                         break;
647                 case IFA_LABEL:
648                         if (label)
649                                 *label = RTA_DATA(attr);
650                         break;
651                 }
652         }
653 }
654
655 static void extract_ipv6_addr(struct ifaddrmsg *msg, int bytes,
656                                                 struct in6_addr *addr,
657                                                 struct in6_addr *local)
658 {
659         struct rtattr *attr;
660
661         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
662                                         attr = RTA_NEXT(attr, bytes)) {
663                 switch (attr->rta_type) {
664                 case IFA_ADDRESS:
665                         if (addr)
666                                 *addr = *((struct in6_addr *) RTA_DATA(attr));
667                         break;
668                 case IFA_LOCAL:
669                         if (local)
670                                 *local = *((struct in6_addr *) RTA_DATA(attr));
671                         break;
672                 }
673         }
674 }
675
676 static void process_newaddr(unsigned char family, unsigned char prefixlen,
677                                 int index, struct ifaddrmsg *msg, int bytes)
678 {
679         struct in_addr ipv4_addr = { INADDR_ANY };
680         struct in6_addr ipv6_address, ipv6_local;
681         const char *label = NULL;
682         void *src;
683         char ip_string[INET6_ADDRSTRLEN];
684
685         if (family == AF_INET) {
686
687                 extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
688                 src = &ipv4_addr;
689         } else if (family == AF_INET6) {
690                 extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
691                 if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
692                         return;
693
694                 src = &ipv6_address;
695         } else {
696                 return;
697         }
698
699         if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
700                 return;
701
702         if (__connman_ipconfig_newaddr(index, family, label,
703                                         prefixlen, ip_string) >= 0) {
704                 if (family == AF_INET6) {
705                         /*
706                          * Re-create RDNSS configured servers if there
707                          * are any for this interface. This is done
708                          * because we might have now properly
709                          * configured interface with proper
710                          * autoconfigured address.
711                          */
712                         __connman_resolver_redo_servers(index);
713                 }
714         }
715 }
716
717 static void process_deladdr(unsigned char family, unsigned char prefixlen,
718                                 int index, struct ifaddrmsg *msg, int bytes)
719 {
720         struct in_addr ipv4_addr = { INADDR_ANY };
721         struct in6_addr ipv6_address, ipv6_local;
722         const char *label = NULL;
723         void *src;
724         char ip_string[INET6_ADDRSTRLEN];
725
726         if (family == AF_INET) {
727                 extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
728                 src = &ipv4_addr;
729         } else if (family == AF_INET6) {
730                 extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
731                 if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
732                         return;
733
734                 src = &ipv6_address;
735         } else {
736                 return;
737         }
738
739         if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
740                 return;
741
742         __connman_ipconfig_deladdr(index, family, label,
743                                         prefixlen, ip_string);
744 }
745
746 static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index,
747                                                 struct in_addr *dst,
748                                                 struct in_addr *gateway)
749 {
750         struct rtattr *attr;
751
752         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
753                                         attr = RTA_NEXT(attr, bytes)) {
754                 switch (attr->rta_type) {
755                 case RTA_DST:
756                         if (dst)
757                                 *dst = *((struct in_addr *) RTA_DATA(attr));
758                         break;
759                 case RTA_GATEWAY:
760                         if (gateway)
761                                 *gateway = *((struct in_addr *) RTA_DATA(attr));
762                         break;
763                 case RTA_OIF:
764                         if (index)
765                                 *index = *((int *) RTA_DATA(attr));
766                         break;
767                 }
768         }
769 }
770
771 static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index,
772                                                 struct in6_addr *dst,
773                                                 struct in6_addr *gateway)
774 {
775         struct rtattr *attr;
776
777         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
778                                         attr = RTA_NEXT(attr, bytes)) {
779                 switch (attr->rta_type) {
780                 case RTA_DST:
781                         if (dst)
782                                 *dst = *((struct in6_addr *) RTA_DATA(attr));
783                         break;
784                 case RTA_GATEWAY:
785                         if (gateway)
786                                 *gateway =
787                                         *((struct in6_addr *) RTA_DATA(attr));
788                         break;
789                 case RTA_OIF:
790                         if (index)
791                                 *index = *((int *) RTA_DATA(attr));
792                         break;
793                 }
794         }
795 }
796
797 static void process_newroute(unsigned char family, unsigned char scope,
798                                                 struct rtmsg *msg, int bytes)
799 {
800         GSList *list;
801         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
802         int index = -1;
803
804         if (family == AF_INET) {
805                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
806
807                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
808
809                 inet_ntop(family, &dst, dststr, sizeof(dststr));
810                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
811
812                 __connman_ipconfig_newroute(index, family, scope, dststr,
813                                                                 gatewaystr);
814
815                 /* skip host specific routes */
816                 if (scope != RT_SCOPE_UNIVERSE &&
817                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
818                         return;
819
820                 if (dst.s_addr != INADDR_ANY)
821                         return;
822
823         } else if (family == AF_INET6) {
824                 struct in6_addr dst = IN6ADDR_ANY_INIT,
825                                 gateway = IN6ADDR_ANY_INIT;
826
827                 extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
828
829                 inet_ntop(family, &dst, dststr, sizeof(dststr));
830                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
831
832                 __connman_ipconfig_newroute(index, family, scope, dststr,
833                                                                 gatewaystr);
834
835                 /* skip host specific routes */
836                 if (scope != RT_SCOPE_UNIVERSE &&
837                         !(scope == RT_SCOPE_LINK &&
838                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
839                         return;
840
841                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
842                         return;
843         } else
844                 return;
845
846         for (list = rtnl_list; list; list = list->next) {
847                 struct connman_rtnl *rtnl = list->data;
848
849                 if (rtnl->newgateway)
850                         rtnl->newgateway(index, gatewaystr);
851         }
852 }
853
854 static void process_delroute(unsigned char family, unsigned char scope,
855                                                 struct rtmsg *msg, int bytes)
856 {
857         GSList *list;
858         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
859         int index = -1;
860
861         if (family == AF_INET) {
862                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
863
864                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
865
866                 inet_ntop(family, &dst, dststr, sizeof(dststr));
867                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
868
869                 __connman_ipconfig_delroute(index, family, scope, dststr,
870                                                                 gatewaystr);
871
872                 /* skip host specific routes */
873                 if (scope != RT_SCOPE_UNIVERSE &&
874                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
875                         return;
876
877                 if (dst.s_addr != INADDR_ANY)
878                         return;
879
880         }  else if (family == AF_INET6) {
881                 struct in6_addr dst = IN6ADDR_ANY_INIT,
882                                 gateway = IN6ADDR_ANY_INIT;
883
884                 extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
885
886                 inet_ntop(family, &dst, dststr, sizeof(dststr));
887                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
888
889                 __connman_ipconfig_delroute(index, family, scope, dststr,
890                                                 gatewaystr);
891
892                 /* skip host specific routes */
893                 if (scope != RT_SCOPE_UNIVERSE &&
894                         !(scope == RT_SCOPE_LINK &&
895                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
896                         return;
897
898                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
899                         return;
900         } else
901                 return;
902
903         for (list = rtnl_list; list; list = list->next) {
904                 struct connman_rtnl *rtnl = list->data;
905
906                 if (rtnl->delgateway)
907                         rtnl->delgateway(index, gatewaystr);
908         }
909 }
910
911 static inline void print_ether(struct rtattr *attr, const char *name)
912 {
913         int len = (int) RTA_PAYLOAD(attr);
914
915         if (len == ETH_ALEN) {
916                 struct ether_addr eth;
917                 memcpy(&eth, RTA_DATA(attr), ETH_ALEN);
918                 print("  attr %s (len %d) %s\n", name, len, ether_ntoa(&eth));
919         } else
920                 print("  attr %s (len %d)\n", name, len);
921 }
922
923 static inline void print_inet(struct rtattr *attr, const char *name,
924                                                         unsigned char family)
925 {
926         int len = (int) RTA_PAYLOAD(attr);
927
928         if (family == AF_INET && len == sizeof(struct in_addr)) {
929                 struct in_addr addr;
930                 addr = *((struct in_addr *) RTA_DATA(attr));
931                 print("  attr %s (len %d) %s\n", name, len, inet_ntoa(addr));
932         } else
933                 print("  attr %s (len %d)\n", name, len);
934 }
935
936 static inline void print_string(struct rtattr *attr, const char *name)
937 {
938         print("  attr %s (len %d) %s\n", name, (int) RTA_PAYLOAD(attr),
939                                                 (char *) RTA_DATA(attr));
940 }
941
942 static inline void print_byte(struct rtattr *attr, const char *name)
943 {
944         print("  attr %s (len %d) 0x%02x\n", name, (int) RTA_PAYLOAD(attr),
945                                         *((unsigned char *) RTA_DATA(attr)));
946 }
947
948 static inline void print_integer(struct rtattr *attr, const char *name)
949 {
950         print("  attr %s (len %d) %d\n", name, (int) RTA_PAYLOAD(attr),
951                                                 *((int *) RTA_DATA(attr)));
952 }
953
954 static inline void print_attr(struct rtattr *attr, const char *name)
955 {
956         int len = (int) RTA_PAYLOAD(attr);
957
958         if (name && len > 0)
959                 print("  attr %s (len %d)\n", name, len);
960         else
961                 print("  attr %d (len %d)\n", attr->rta_type, len);
962 }
963
964 static void rtnl_link(struct nlmsghdr *hdr)
965 {
966         struct ifinfomsg *msg;
967         struct rtattr *attr;
968         int bytes;
969
970         msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
971         bytes = IFLA_PAYLOAD(hdr);
972
973         print("ifi_index %d ifi_flags 0x%04x", msg->ifi_index, msg->ifi_flags);
974
975         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
976                                         attr = RTA_NEXT(attr, bytes)) {
977                 switch (attr->rta_type) {
978                 case IFLA_ADDRESS:
979                         print_ether(attr, "address");
980                         break;
981                 case IFLA_BROADCAST:
982                         print_ether(attr, "broadcast");
983                         break;
984                 case IFLA_IFNAME:
985                         print_string(attr, "ifname");
986                         break;
987                 case IFLA_MTU:
988                         print_integer(attr, "mtu");
989                         break;
990                 case IFLA_LINK:
991                         print_attr(attr, "link");
992                         break;
993                 case IFLA_QDISC:
994                         print_attr(attr, "qdisc");
995                         break;
996                 case IFLA_STATS:
997                         print_attr(attr, "stats");
998                         break;
999                 case IFLA_COST:
1000                         print_attr(attr, "cost");
1001                         break;
1002                 case IFLA_PRIORITY:
1003                         print_attr(attr, "priority");
1004                         break;
1005                 case IFLA_MASTER:
1006                         print_attr(attr, "master");
1007                         break;
1008                 case IFLA_WIRELESS:
1009                         print_attr(attr, "wireless");
1010                         break;
1011                 case IFLA_PROTINFO:
1012                         print_attr(attr, "protinfo");
1013                         break;
1014                 case IFLA_TXQLEN:
1015                         print_integer(attr, "txqlen");
1016                         break;
1017                 case IFLA_MAP:
1018                         print_attr(attr, "map");
1019                         break;
1020                 case IFLA_WEIGHT:
1021                         print_attr(attr, "weight");
1022                         break;
1023                 case IFLA_OPERSTATE:
1024                         print_byte(attr, "operstate");
1025                         break;
1026                 case IFLA_LINKMODE:
1027                         print_byte(attr, "linkmode");
1028                         break;
1029                 default:
1030                         print_attr(attr, NULL);
1031                         break;
1032                 }
1033         }
1034 }
1035
1036 static void rtnl_newlink(struct nlmsghdr *hdr)
1037 {
1038         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
1039
1040         rtnl_link(hdr);
1041
1042         if (hdr->nlmsg_type == IFLA_WIRELESS)
1043                 connman_warn_once("Obsolete WEXT WiFi driver detected");
1044
1045         process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
1046                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
1047 }
1048
1049 static void rtnl_dellink(struct nlmsghdr *hdr)
1050 {
1051         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
1052
1053         rtnl_link(hdr);
1054
1055         process_dellink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
1056                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
1057 }
1058
1059 static void rtnl_addr(struct nlmsghdr *hdr)
1060 {
1061         struct ifaddrmsg *msg;
1062         struct rtattr *attr;
1063         int bytes;
1064
1065         msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
1066         bytes = IFA_PAYLOAD(hdr);
1067
1068         print("ifa_family %d ifa_index %d", msg->ifa_family, msg->ifa_index);
1069
1070         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
1071                                         attr = RTA_NEXT(attr, bytes)) {
1072                 switch (attr->rta_type) {
1073                 case IFA_ADDRESS:
1074                         print_inet(attr, "address", msg->ifa_family);
1075                         break;
1076                 case IFA_LOCAL:
1077                         print_inet(attr, "local", msg->ifa_family);
1078                         break;
1079                 case IFA_LABEL:
1080                         print_string(attr, "label");
1081                         break;
1082                 case IFA_BROADCAST:
1083                         print_inet(attr, "broadcast", msg->ifa_family);
1084                         break;
1085                 case IFA_ANYCAST:
1086                         print_attr(attr, "anycast");
1087                         break;
1088                 case IFA_CACHEINFO:
1089                         print_attr(attr, "cacheinfo");
1090                         break;
1091                 case IFA_MULTICAST:
1092                         print_attr(attr, "multicast");
1093                         break;
1094                 default:
1095                         print_attr(attr, NULL);
1096                         break;
1097                 }
1098         }
1099 }
1100
1101 static void rtnl_newaddr(struct nlmsghdr *hdr)
1102 {
1103         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
1104
1105         rtnl_addr(hdr);
1106
1107         process_newaddr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
1108                                                 msg, IFA_PAYLOAD(hdr));
1109 }
1110
1111 static void rtnl_deladdr(struct nlmsghdr *hdr)
1112 {
1113         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
1114
1115         rtnl_addr(hdr);
1116
1117         process_deladdr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
1118                                                 msg, IFA_PAYLOAD(hdr));
1119 }
1120
1121 static void rtnl_route(struct nlmsghdr *hdr)
1122 {
1123         struct rtmsg *msg;
1124         struct rtattr *attr;
1125         int bytes;
1126
1127         msg = (struct rtmsg *) NLMSG_DATA(hdr);
1128         bytes = RTM_PAYLOAD(hdr);
1129
1130         print("rtm_family %d rtm_table %d rtm_protocol %d",
1131                         msg->rtm_family, msg->rtm_table, msg->rtm_protocol);
1132         print("rtm_scope %d rtm_type %d rtm_flags 0x%04x",
1133                                 msg->rtm_scope, msg->rtm_type, msg->rtm_flags);
1134
1135         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
1136                                         attr = RTA_NEXT(attr, bytes)) {
1137                 switch (attr->rta_type) {
1138                 case RTA_DST:
1139                         print_inet(attr, "dst", msg->rtm_family);
1140                         break;
1141                 case RTA_SRC:
1142                         print_inet(attr, "src", msg->rtm_family);
1143                         break;
1144                 case RTA_IIF:
1145                         print_string(attr, "iif");
1146                         break;
1147                 case RTA_OIF:
1148                         print_integer(attr, "oif");
1149                         break;
1150                 case RTA_GATEWAY:
1151                         print_inet(attr, "gateway", msg->rtm_family);
1152                         break;
1153                 case RTA_PRIORITY:
1154                         print_attr(attr, "priority");
1155                         break;
1156                 case RTA_PREFSRC:
1157                         print_inet(attr, "prefsrc", msg->rtm_family);
1158                         break;
1159                 case RTA_METRICS:
1160                         print_attr(attr, "metrics");
1161                         break;
1162                 case RTA_TABLE:
1163                         print_integer(attr, "table");
1164                         break;
1165                 default:
1166                         print_attr(attr, NULL);
1167                         break;
1168                 }
1169         }
1170 }
1171
1172 static bool is_route_rtmsg(struct rtmsg *msg)
1173 {
1174         if (msg->rtm_flags & RTM_F_CLONED)
1175                 return false;
1176
1177         if (msg->rtm_table != RT_TABLE_MAIN)
1178                 return false;
1179
1180         if (msg->rtm_protocol != RTPROT_BOOT &&
1181                         msg->rtm_protocol != RTPROT_KERNEL)
1182                 return false;
1183
1184         if (msg->rtm_type != RTN_UNICAST)
1185                 return false;
1186
1187         return true;
1188 }
1189
1190 static void rtnl_newroute(struct nlmsghdr *hdr)
1191 {
1192         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
1193
1194         rtnl_route(hdr);
1195
1196         if (is_route_rtmsg(msg))
1197                 process_newroute(msg->rtm_family, msg->rtm_scope,
1198                                                 msg, RTM_PAYLOAD(hdr));
1199 }
1200
1201 static void rtnl_delroute(struct nlmsghdr *hdr)
1202 {
1203         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
1204
1205         rtnl_route(hdr);
1206
1207         if (is_route_rtmsg(msg))
1208                 process_delroute(msg->rtm_family, msg->rtm_scope,
1209                                                 msg, RTM_PAYLOAD(hdr));
1210 }
1211
1212 static void *rtnl_nd_opt_rdnss(struct nd_opt_hdr *opt, guint32 *lifetime,
1213                                int *nr_servers)
1214 {
1215         guint32 *optint = (void *)opt;
1216
1217         if (opt->nd_opt_len < 3)
1218                 return NULL;
1219
1220         if (*lifetime > ntohl(optint[1]))
1221                 *lifetime = ntohl(optint[1]);
1222
1223         /* nd_opt_len is in units of 8 bytes. The header is 1 unit (8 bytes)
1224            and each address is another 2 units (16 bytes).
1225            So the number of addresses (given rounding) is nd_opt_len/2 */
1226         *nr_servers = opt->nd_opt_len / 2;
1227
1228         /* And they start 8 bytes into the packet, or two guint32s in. */
1229         return optint + 2;
1230 }
1231
1232 static const char **rtnl_nd_opt_dnssl(struct nd_opt_hdr *opt, guint32 *lifetime)
1233 {
1234         const char **domains = NULL;
1235         guint32 *optint = (void *)opt;
1236         unsigned char *optc = (void *)&optint[2];
1237         int data_len = (opt->nd_opt_len * 8) - 8;
1238         int nr_domains = 0;
1239         int i, tmp;
1240
1241         if (*lifetime > ntohl(optint[1]))
1242                 *lifetime = ntohl(optint[1]);
1243
1244         /* Turn it into normal strings by converting the length bytes into '.',
1245            and count how many search domains there are while we're at it. */
1246         i = 0;
1247         while (i < data_len) {
1248                 if (optc[i] > 0x3f) {
1249                         DBG("DNSSL contains compressed elements in violation of RFC6106");
1250                         return NULL;
1251                 }
1252
1253                 if (optc[i] == 0) {
1254                         nr_domains++;
1255                         i++;
1256                         /* Check for double zero */
1257                         if (i < data_len && optc[i] == 0)
1258                                 break;
1259                         continue;
1260                 }
1261
1262                 tmp = i;
1263                 i += optc[i] + 1;
1264
1265                 if (i >= data_len) {
1266                         DBG("DNSSL data overflows option length");
1267                         return NULL;
1268                 }
1269
1270                 optc[tmp] = '.';
1271         }
1272
1273         domains = g_try_new0(const char *, nr_domains + 1);
1274         if (!domains)
1275                 return NULL;
1276
1277         /* Now point to the normal strings, missing out the leading '.' that
1278            each of them will have now. */
1279         for (i = 0; i < nr_domains; i++) {
1280                 domains[i] = (char *)optc + 1;
1281                 optc += strlen((char *)optc) + 1;
1282         }
1283
1284         return domains;
1285 }
1286
1287 static void rtnl_newnduseropt(struct nlmsghdr *hdr)
1288 {
1289         struct nduseroptmsg *msg = (struct nduseroptmsg *) NLMSG_DATA(hdr);
1290         struct nd_opt_hdr *opt;
1291         guint32 lifetime = -1;
1292         const char **domains = NULL;
1293         struct in6_addr *servers = NULL;
1294         int i, nr_servers = 0;
1295         int msglen = msg->nduseropt_opts_len;
1296         int index;
1297
1298         DBG("family %d index %d len %d type %d code %d",
1299                 msg->nduseropt_family, msg->nduseropt_ifindex,
1300                 msg->nduseropt_opts_len, msg->nduseropt_icmp_type,
1301                 msg->nduseropt_icmp_code);
1302
1303         if (msg->nduseropt_family != AF_INET6 ||
1304                         msg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
1305                         msg->nduseropt_icmp_code != 0)
1306                 return;
1307
1308         index = msg->nduseropt_ifindex;
1309         if (index < 0)
1310                 return;
1311
1312         for (opt = (void *)&msg[1];
1313                         msglen > 0;
1314                         msglen -= opt->nd_opt_len * 8,
1315                         opt = ((void *)opt) + opt->nd_opt_len*8) {
1316
1317                 DBG("remaining %d nd opt type %d len %d\n",
1318                         msglen, opt->nd_opt_type, opt->nd_opt_len);
1319
1320                 if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */
1321                         char buf[40];
1322
1323                         servers = rtnl_nd_opt_rdnss(opt, &lifetime,
1324                                                                 &nr_servers);
1325                         for (i = 0; i < nr_servers; i++) {
1326                                 if (!inet_ntop(AF_INET6, servers + i, buf,
1327                                                                 sizeof(buf)))
1328                                         continue;
1329
1330                                 connman_resolver_append_lifetime(index,
1331                                                         NULL, buf, lifetime);
1332                         }
1333
1334                 } else if (opt->nd_opt_type == 31) { /* ND_OPT_DNSSL */
1335                         g_free(domains);
1336
1337                         domains = rtnl_nd_opt_dnssl(opt, &lifetime);
1338                         for (i = 0; domains && domains[i]; i++)
1339                                 connman_resolver_append_lifetime(index,
1340                                                 domains[i], NULL, lifetime);
1341                 }
1342         }
1343
1344         g_free(domains);
1345 }
1346
1347 static const char *type2string(uint16_t type)
1348 {
1349         switch (type) {
1350         case NLMSG_NOOP:
1351                 return "NOOP";
1352         case NLMSG_ERROR:
1353                 return "ERROR";
1354         case NLMSG_DONE:
1355                 return "DONE";
1356         case NLMSG_OVERRUN:
1357                 return "OVERRUN";
1358         case RTM_GETLINK:
1359                 return "GETLINK";
1360         case RTM_NEWLINK:
1361                 return "NEWLINK";
1362         case RTM_DELLINK:
1363                 return "DELLINK";
1364         case RTM_GETADDR:
1365                 return "GETADDR";
1366         case RTM_NEWADDR:
1367                 return "NEWADDR";
1368         case RTM_DELADDR:
1369                 return "DELADDR";
1370         case RTM_GETROUTE:
1371                 return "GETROUTE";
1372         case RTM_NEWROUTE:
1373                 return "NEWROUTE";
1374         case RTM_DELROUTE:
1375                 return "DELROUTE";
1376         case RTM_NEWNDUSEROPT:
1377                 return "NEWNDUSEROPT";
1378         default:
1379                 return "UNKNOWN";
1380         }
1381 }
1382
1383 static GIOChannel *channel = NULL;
1384 static guint channel_watch = 0;
1385
1386 struct rtnl_request {
1387         struct nlmsghdr hdr;
1388         struct rtgenmsg msg;
1389 };
1390 #define RTNL_REQUEST_SIZE  (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))
1391
1392 static GSList *request_list = NULL;
1393 static guint32 request_seq = 0;
1394
1395 static struct rtnl_request *find_request(guint32 seq)
1396 {
1397         GSList *list;
1398
1399         for (list = request_list; list; list = list->next) {
1400                 struct rtnl_request *req = list->data;
1401
1402                 if (req->hdr.nlmsg_seq == seq)
1403                         return req;
1404         }
1405
1406         return NULL;
1407 }
1408
1409 static int send_request(struct rtnl_request *req)
1410 {
1411         struct sockaddr_nl addr;
1412         int sk;
1413
1414         DBG("%s len %d type %d flags 0x%04x seq %d",
1415                                 type2string(req->hdr.nlmsg_type),
1416                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1417                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1418
1419         sk = g_io_channel_unix_get_fd(channel);
1420
1421         memset(&addr, 0, sizeof(addr));
1422         addr.nl_family = AF_NETLINK;
1423
1424         return sendto(sk, req, req->hdr.nlmsg_len, 0,
1425                                 (struct sockaddr *) &addr, sizeof(addr));
1426 }
1427
1428 static int queue_request(struct rtnl_request *req)
1429 {
1430         request_list = g_slist_append(request_list, req);
1431
1432         if (g_slist_length(request_list) > 1)
1433                 return 0;
1434
1435         return send_request(req);
1436 }
1437
1438 static int process_response(guint32 seq)
1439 {
1440         struct rtnl_request *req;
1441
1442         DBG("seq %d", seq);
1443
1444         req = find_request(seq);
1445         if (req) {
1446                 request_list = g_slist_remove(request_list, req);
1447                 g_free(req);
1448         }
1449
1450         req = g_slist_nth_data(request_list, 0);
1451         if (!req)
1452                 return 0;
1453
1454         return send_request(req);
1455 }
1456
1457 static void rtnl_message(void *buf, size_t len)
1458 {
1459         DBG("buf %p len %zd", buf, len);
1460
1461         while (len > 0) {
1462                 struct nlmsghdr *hdr = buf;
1463                 struct nlmsgerr *err;
1464
1465                 if (!NLMSG_OK(hdr, len))
1466                         break;
1467
1468                 DBG("%s len %d type %d flags 0x%04x seq %d pid %d",
1469                                         type2string(hdr->nlmsg_type),
1470                                         hdr->nlmsg_len, hdr->nlmsg_type,
1471                                         hdr->nlmsg_flags, hdr->nlmsg_seq,
1472                                         hdr->nlmsg_pid);
1473
1474                 switch (hdr->nlmsg_type) {
1475                 case NLMSG_NOOP:
1476                 case NLMSG_OVERRUN:
1477                         return;
1478                 case NLMSG_DONE:
1479                         process_response(hdr->nlmsg_seq);
1480                         return;
1481                 case NLMSG_ERROR:
1482                         err = NLMSG_DATA(hdr);
1483                         DBG("error %d (%s)", -err->error,
1484                                                 strerror(-err->error));
1485                         return;
1486                 case RTM_NEWLINK:
1487                         rtnl_newlink(hdr);
1488                         break;
1489                 case RTM_DELLINK:
1490                         rtnl_dellink(hdr);
1491                         break;
1492                 case RTM_NEWADDR:
1493                         rtnl_newaddr(hdr);
1494                         break;
1495                 case RTM_DELADDR:
1496                         rtnl_deladdr(hdr);
1497                         break;
1498                 case RTM_NEWROUTE:
1499                         rtnl_newroute(hdr);
1500                         break;
1501                 case RTM_DELROUTE:
1502                         rtnl_delroute(hdr);
1503                         break;
1504                 case RTM_NEWNDUSEROPT:
1505                         rtnl_newnduseropt(hdr);
1506                         break;
1507                 }
1508
1509                 len -= hdr->nlmsg_len;
1510                 buf += hdr->nlmsg_len;
1511         }
1512 }
1513
1514 static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1515 {
1516         unsigned char buf[4096];
1517         struct sockaddr_nl nladdr;
1518         socklen_t addr_len = sizeof(nladdr);
1519         ssize_t status;
1520         int fd;
1521
1522         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1523                 return FALSE;
1524
1525         memset(buf, 0, sizeof(buf));
1526         memset(&nladdr, 0, sizeof(nladdr));
1527
1528         fd = g_io_channel_unix_get_fd(chan);
1529
1530         status = recvfrom(fd, buf, sizeof(buf), 0,
1531                        (struct sockaddr *) &nladdr, &addr_len);
1532         if (status < 0) {
1533                 if (errno == EINTR || errno == EAGAIN)
1534                         return TRUE;
1535
1536                 return FALSE;
1537         }
1538
1539         if (status == 0)
1540                 return FALSE;
1541
1542         if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
1543                 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
1544                 return TRUE;
1545         }
1546
1547         rtnl_message(buf, status);
1548
1549         return TRUE;
1550 }
1551
1552 static int send_getlink(void)
1553 {
1554         struct rtnl_request *req;
1555
1556         DBG("");
1557
1558         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1559         if (!req)
1560                 return -ENOMEM;
1561
1562         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1563         req->hdr.nlmsg_type = RTM_GETLINK;
1564         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1565         req->hdr.nlmsg_pid = 0;
1566         req->hdr.nlmsg_seq = request_seq++;
1567         req->msg.rtgen_family = AF_INET;
1568
1569         return queue_request(req);
1570 }
1571
1572 static int send_getaddr(void)
1573 {
1574         struct rtnl_request *req;
1575
1576         DBG("");
1577
1578         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1579         if (!req)
1580                 return -ENOMEM;
1581
1582         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1583         req->hdr.nlmsg_type = RTM_GETADDR;
1584         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1585         req->hdr.nlmsg_pid = 0;
1586         req->hdr.nlmsg_seq = request_seq++;
1587         req->msg.rtgen_family = AF_INET;
1588
1589         return queue_request(req);
1590 }
1591
1592 static int send_getroute(void)
1593 {
1594         struct rtnl_request *req;
1595
1596         DBG("");
1597
1598         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1599         if (!req)
1600                 return -ENOMEM;
1601
1602         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1603         req->hdr.nlmsg_type = RTM_GETROUTE;
1604         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1605         req->hdr.nlmsg_pid = 0;
1606         req->hdr.nlmsg_seq = request_seq++;
1607         req->msg.rtgen_family = AF_INET;
1608
1609         return queue_request(req);
1610 }
1611
1612 static gboolean update_timeout_cb(gpointer user_data)
1613 {
1614         __connman_rtnl_request_update();
1615
1616         return TRUE;
1617 }
1618
1619 static void update_interval_callback(guint min)
1620 {
1621         if (update_timeout > 0)
1622                 g_source_remove(update_timeout);
1623
1624         if (min < G_MAXUINT) {
1625                 update_interval = min;
1626                 update_timeout = g_timeout_add_seconds(update_interval,
1627                                                 update_timeout_cb, NULL);
1628         } else {
1629                 update_timeout = 0;
1630                 update_interval = G_MAXUINT;
1631         }
1632 }
1633
1634 static gint compare_interval(gconstpointer a, gconstpointer b)
1635 {
1636         guint val_a = GPOINTER_TO_UINT(a);
1637         guint val_b = GPOINTER_TO_UINT(b);
1638
1639         return val_a - val_b;
1640 }
1641
1642 unsigned int __connman_rtnl_update_interval_add(unsigned int interval)
1643 {
1644         guint min;
1645
1646         if (interval == 0)
1647                 return 0;
1648
1649         update_list = g_slist_insert_sorted(update_list,
1650                         GUINT_TO_POINTER(interval), compare_interval);
1651
1652         min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1653         if (min < update_interval) {
1654                 update_interval_callback(min);
1655                 __connman_rtnl_request_update();
1656         }
1657
1658         return update_interval;
1659 }
1660
1661 unsigned int __connman_rtnl_update_interval_remove(unsigned int interval)
1662 {
1663         guint min = G_MAXUINT;
1664
1665         if (interval == 0)
1666                 return 0;
1667
1668         update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval));
1669
1670         if (update_list)
1671                 min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1672
1673         if (min > update_interval)
1674                 update_interval_callback(min);
1675
1676         return min;
1677 }
1678
1679 int __connman_rtnl_request_update(void)
1680 {
1681         return send_getlink();
1682 }
1683
1684 int __connman_rtnl_init(void)
1685 {
1686         struct sockaddr_nl addr;
1687         int sk;
1688
1689         DBG("");
1690
1691         interface_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1692                                                         NULL, free_interface);
1693
1694         sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
1695         if (sk < 0)
1696                 return -1;
1697
1698         memset(&addr, 0, sizeof(addr));
1699         addr.nl_family = AF_NETLINK;
1700         addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
1701                                 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE |
1702                                 (1<<(RTNLGRP_ND_USEROPT-1));
1703
1704         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1705                 close(sk);
1706                 return -1;
1707         }
1708
1709         channel = g_io_channel_unix_new(sk);
1710         g_io_channel_set_close_on_unref(channel, TRUE);
1711
1712         g_io_channel_set_encoding(channel, NULL, NULL);
1713         g_io_channel_set_buffered(channel, FALSE);
1714
1715         channel_watch = g_io_add_watch(channel,
1716                                 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1717                                 netlink_event, NULL);
1718
1719         return 0;
1720 }
1721
1722 void __connman_rtnl_start(void)
1723 {
1724         DBG("");
1725
1726         send_getlink();
1727         send_getaddr();
1728         send_getroute();
1729 }
1730
1731 void __connman_rtnl_cleanup(void)
1732 {
1733         GSList *list;
1734
1735         DBG("");
1736
1737         for (list = watch_list; list; list = list->next) {
1738                 struct watch_data *watch = list->data;
1739
1740                 DBG("removing watch %d", watch->id);
1741
1742                 g_free(watch);
1743                 list->data = NULL;
1744         }
1745
1746         g_slist_free(watch_list);
1747         watch_list = NULL;
1748
1749         g_slist_free(update_list);
1750         update_list = NULL;
1751
1752         for (list = request_list; list; list = list->next) {
1753                 struct rtnl_request *req = list->data;
1754
1755                 DBG("%s len %d type %d flags 0x%04x seq %d",
1756                                 type2string(req->hdr.nlmsg_type),
1757                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1758                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1759
1760                 g_free(req);
1761                 list->data = NULL;
1762         }
1763
1764         g_slist_free(request_list);
1765         request_list = NULL;
1766
1767         if (channel_watch) {
1768                 g_source_remove(channel_watch);
1769                 channel_watch = 0;
1770         }
1771
1772         g_io_channel_shutdown(channel, TRUE, NULL);
1773         g_io_channel_unref(channel);
1774
1775         channel = NULL;
1776
1777         g_hash_table_destroy(interface_list);
1778 }