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