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