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