chiark / gitweb /
sd-rtnl: message - fix memory leak
[elogind.git] / src / libsystemd / sd-rtnl / rtnl-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Tom Gundersen <teg@jklm.no>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <netinet/in.h>
23 #include <netinet/ether.h>
24 #include <stdbool.h>
25 #include <unistd.h>
26 #include <linux/veth.h>
27 #include <linux/if.h>
28 #include <linux/ip.h>
29 #include <linux/if_tunnel.h>
30 #include <linux/if_bridge.h>
31
32 #include "util.h"
33 #include "refcnt.h"
34 #include "missing.h"
35
36 #include "sd-rtnl.h"
37 #include "rtnl-util.h"
38 #include "rtnl-internal.h"
39
40 #define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->container_offsets[i]) : NULL)
41 #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
42
43 int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, size_t initial_size) {
44         sd_rtnl_message *m;
45
46         assert_return(ret, -EINVAL);
47         assert_return(initial_size >= sizeof(struct nlmsghdr), -EINVAL);
48
49         /* Note that 'rtnl' is curretly unused, if we start using it internally
50            we must take care to avoid problems due to mutual references between
51            busses and their queued messages. See sd-bus.
52          */
53
54         m = new0(sd_rtnl_message, 1);
55         if (!m)
56                 return -ENOMEM;
57
58         m->hdr = malloc0(initial_size);
59         if (!m->hdr) {
60                 free(m);
61                 return -ENOMEM;
62         }
63
64         m->n_ref = REFCNT_INIT;
65
66         m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
67         m->sealed = false;
68
69         *ret = m;
70
71         return 0;
72 }
73
74 int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
75         struct rtmsg *rtm;
76
77         assert_return(m, -EINVAL);
78         assert_return(m->hdr, -EINVAL);
79         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
80
81         rtm = NLMSG_DATA(m->hdr);
82
83         if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
84             (rtm->rtm_family == AF_INET6 && prefixlen > 128))
85                 return -ERANGE;
86
87         rtm->rtm_dst_len = prefixlen;
88
89         return 0;
90 }
91
92 int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
93         struct rtmsg *rtm;
94
95         assert_return(m, -EINVAL);
96         assert_return(m->hdr, -EINVAL);
97         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
98
99         rtm = NLMSG_DATA(m->hdr);
100
101         rtm->rtm_scope = scope;
102
103         return 0;
104 }
105
106 int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
107                               uint16_t nlmsg_type, unsigned char rtm_family) {
108         struct rtmsg *rtm;
109         int r;
110
111         assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL);
112         assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
113         assert_return(ret, -EINVAL);
114
115         r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct rtmsg)));
116         if (r < 0)
117                 return r;
118
119         (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
120         (*ret)->hdr->nlmsg_type = nlmsg_type;
121         if (nlmsg_type == RTM_NEWROUTE)
122                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
123
124         rtm = NLMSG_DATA((*ret)->hdr);
125
126         rtm->rtm_family = rtm_family;
127         rtm->rtm_scope = RT_SCOPE_UNIVERSE;
128         rtm->rtm_type = RTN_UNICAST;
129         rtm->rtm_table = RT_TABLE_MAIN;
130         rtm->rtm_protocol = RTPROT_BOOT;
131
132         return 0;
133 }
134
135 int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change) {
136         struct ifinfomsg *ifi;
137
138         assert_return(m, -EINVAL);
139         assert_return(m->hdr, -EINVAL);
140         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
141         assert_return(change, -EINVAL);
142
143         ifi = NLMSG_DATA(m->hdr);
144
145         ifi->ifi_flags = flags;
146         ifi->ifi_change = change;
147
148         return 0;
149 }
150
151 int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type) {
152         struct ifinfomsg *ifi;
153
154         assert_return(m, -EINVAL);
155         assert_return(m->hdr, -EINVAL);
156         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
157
158         ifi = NLMSG_DATA(m->hdr);
159
160         ifi->ifi_type = type;
161
162         return 0;
163 }
164
165 int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret,
166                              uint16_t nlmsg_type, int index) {
167         struct ifinfomsg *ifi;
168         int r;
169
170         assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
171         assert_return(nlmsg_type != RTM_DELLINK || index > 0, -EINVAL);
172         assert_return(ret, -EINVAL);
173
174         r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifinfomsg)));
175         if (r < 0)
176                 return r;
177
178         (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
179         (*ret)->hdr->nlmsg_type = nlmsg_type;
180         if (nlmsg_type == RTM_NEWLINK)
181                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
182
183         ifi = NLMSG_DATA((*ret)->hdr);
184
185         ifi->ifi_family = AF_UNSPEC;
186         ifi->ifi_index = index;
187
188         return 0;
189 }
190
191 int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
192         struct ifaddrmsg *ifa;
193
194         assert_return(m, -EINVAL);
195         assert_return(m->hdr, -EINVAL);
196         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
197
198         ifa = NLMSG_DATA(m->hdr);
199
200         if ((ifa->ifa_family == AF_INET && prefixlen > 32) ||
201             (ifa->ifa_family == AF_INET6 && prefixlen > 128))
202                 return -ERANGE;
203
204         ifa->ifa_prefixlen = prefixlen;
205
206         return 0;
207 }
208
209 int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags) {
210         struct ifaddrmsg *ifa;
211
212         assert_return(m, -EINVAL);
213         assert_return(m->hdr, -EINVAL);
214         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
215
216         ifa = NLMSG_DATA(m->hdr);
217
218         ifa->ifa_flags = flags;
219
220         return 0;
221 }
222
223 int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) {
224         struct ifaddrmsg *ifa;
225
226         assert_return(m, -EINVAL);
227         assert_return(m->hdr, -EINVAL);
228         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
229
230         ifa = NLMSG_DATA(m->hdr);
231
232         ifa->ifa_scope = scope;
233
234         return 0;
235 }
236
237 int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
238                              uint16_t nlmsg_type, int index,
239                              unsigned char family) {
240         struct ifaddrmsg *ifa;
241         int r;
242
243         assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
244         assert_return(index > 0, -EINVAL);
245         assert_return(family == AF_INET || family == AF_INET6, -EINVAL);
246         assert_return(ret, -EINVAL);
247
248         r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifaddrmsg)));
249         if (r < 0)
250                 return r;
251
252         (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
253         (*ret)->hdr->nlmsg_type = nlmsg_type;
254         if (nlmsg_type == RTM_GETADDR && family == AF_INET)
255                 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
256
257         ifa = NLMSG_DATA((*ret)->hdr);
258
259         ifa->ifa_index = index;
260         ifa->ifa_family = family;
261         if (family == AF_INET)
262                 ifa->ifa_prefixlen = 32;
263         else if (family == AF_INET6)
264                 ifa->ifa_prefixlen = 128;
265
266         return 0;
267 }
268
269 sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
270         if (m)
271                 assert_se(REFCNT_INC(m->n_ref) >= 2);
272
273         return m;
274 }
275
276 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
277         if (m && REFCNT_DEC(m->n_ref) <= 0) {
278                 unsigned i;
279
280                 free(m->hdr);
281
282                 for (i = 0; i <= m->n_containers; i++)
283                         free(m->rta_offset_tb[i]);
284
285                 free(m);
286         }
287
288         return NULL;
289 }
290
291 int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type) {
292         assert_return(m, -EINVAL);
293         assert_return(type, -EINVAL);
294
295         *type = m->hdr->nlmsg_type;
296
297         return 0;
298 }
299
300 int sd_rtnl_message_is_broadcast(sd_rtnl_message *m) {
301         assert_return(m, -EINVAL);
302
303         return !m->hdr->nlmsg_pid;
304 }
305
306 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex) {
307         struct ifinfomsg *ifi;
308
309         assert_return(m, -EINVAL);
310         assert_return(m->hdr, -EINVAL);
311         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
312         assert_return(ifindex, -EINVAL);
313
314         ifi = NLMSG_DATA(m->hdr);
315
316         *ifindex = ifi->ifi_index;
317
318         return 0;
319 }
320
321 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
322         struct ifinfomsg *ifi;
323
324         assert_return(m, -EINVAL);
325         assert_return(m->hdr, -EINVAL);
326         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
327         assert_return(flags, -EINVAL);
328
329         ifi = NLMSG_DATA(m->hdr);
330
331         *flags = ifi->ifi_flags;
332
333         return 0;
334 }
335
336 /* If successful the updated message will be correctly aligned, if
337    unsuccessful the old message is untouched. */
338 static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
339         uint32_t rta_length, message_length;
340         struct nlmsghdr *new_hdr;
341         struct rtattr *rta;
342         char *padding;
343         unsigned i;
344
345         assert(m);
346         assert(m->hdr);
347         assert(!m->sealed);
348         assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
349         assert(!data || data_length > 0);
350         assert(data || m->n_containers < RTNL_CONTAINER_DEPTH);
351
352         /* get the size of the new rta attribute (with padding at the end) */
353         rta_length = RTA_LENGTH(data_length);
354
355         /* get the new message size (with padding at the end) */
356         message_length = m->hdr->nlmsg_len + RTA_ALIGN(rta_length);
357
358         /* realloc to fit the new attribute */
359         new_hdr = realloc(m->hdr, message_length);
360         if (!new_hdr)
361                 return -ENOMEM;
362         m->hdr = new_hdr;
363
364         /* get pointer to the attribute we are about to add */
365         rta = (struct rtattr *) ((uint8_t *) m->hdr + m->hdr->nlmsg_len);
366
367         /* if we are inside containers, extend them */
368         for (i = 0; i < m->n_containers; i++)
369                 GET_CONTAINER(m, i)->rta_len += message_length - m->hdr->nlmsg_len;
370
371         /* fill in the attribute */
372         rta->rta_type = type;
373         rta->rta_len = rta_length;
374         if (!data) {
375                 /* this is the start of a new container */
376                 m->container_offsets[m->n_containers ++] = m->hdr->nlmsg_len;
377         } else {
378                 /* we don't deal with the case where the user lies about the type
379                  * and gives us too little data (so don't do that)
380                 */
381                 padding = mempcpy(RTA_DATA(rta), data, data_length);
382                 /* make sure also the padding at the end of the message is initialized */
383                 memzero(padding,
384                         (uint8_t *) m->hdr + message_length - (uint8_t *) padding);
385         }
386
387         /* update message size */
388         m->hdr->nlmsg_len = message_length;
389
390         return 0;
391 }
392
393 int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
394         uint16_t rtm_type;
395         int r;
396
397         assert_return(m, -EINVAL);
398         assert_return(!m->sealed, -EPERM);
399         assert_return(data, -EINVAL);
400
401         r = sd_rtnl_message_get_type(m, &rtm_type);
402         if (r < 0)
403                 return r;
404
405         /* check that the type is correct */
406         switch (rtm_type) {
407                 case RTM_NEWLINK:
408                 case RTM_SETLINK:
409                 case RTM_GETLINK:
410                 case RTM_DELLINK:
411                         if (m->n_containers == 1) {
412                                 if (GET_CONTAINER(m, 0)->rta_type != IFLA_LINKINFO ||
413                                     type != IFLA_INFO_KIND)
414                                         return -ENOTSUP;
415                         } else {
416                                 switch (type) {
417                                         case IFLA_IFNAME:
418                                         case IFLA_IFALIAS:
419                                         case IFLA_QDISC:
420                                                 break;
421                                         default:
422                                                 return -ENOTSUP;
423                                 }
424                         }
425                         break;
426                 case RTM_NEWADDR:
427                 case RTM_GETADDR:
428                 case RTM_DELADDR:
429                         if (type != IFA_LABEL)
430                                 return -ENOTSUP;
431                         break;
432                 default:
433                         return -ENOTSUP;
434         }
435
436         r = add_rtattr(m, type, data, strlen(data) + 1);
437         if (r < 0)
438                 return r;
439
440         return 0;
441 }
442
443 int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data) {
444         uint16_t rtm_type;
445         int r;
446
447         assert_return(m, -EINVAL);
448         assert_return(!m->sealed, -EPERM);
449
450         r = sd_rtnl_message_get_type(m, &rtm_type);
451         if (r < 0)
452                 return r;
453
454         switch (rtm_type) {
455                 case RTM_NEWLINK:
456                 case RTM_SETLINK:
457                 case RTM_GETLINK:
458                 case RTM_DELLINK:
459                         switch (type) {
460                                 case IFLA_CARRIER:
461                                 case IFLA_OPERSTATE:
462                                 case IFLA_LINKMODE:
463                                 case IFLA_IPTUN_TTL:
464                                 case IFLA_IPTUN_TOS:
465                                 case IFLA_IPTUN_PROTO:
466                                 case IFLA_IPTUN_PMTUDISC:
467                                 case IFLA_IPTUN_ENCAP_LIMIT:
468                                 case IFLA_GRE_TTL:
469                                 break;
470                         default:
471                                 return -ENOTSUP;
472                         }
473
474                         break;
475                 default:
476                         return -ENOTSUP;
477         }
478
479         r = add_rtattr(m, type, &data, sizeof(uint8_t));
480         if (r < 0)
481                 return r;
482
483         return 0;
484 }
485
486
487 int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t data) {
488         uint16_t rtm_type;
489         int r;
490
491         assert_return(m, -EINVAL);
492         assert_return(!m->sealed, -EPERM);
493
494         r = sd_rtnl_message_get_type(m, &rtm_type);
495         if (r < 0)
496                 return r;
497
498         /* check that the type is correct */
499         switch (rtm_type) {
500                 case RTM_NEWLINK:
501                 case RTM_SETLINK:
502                 case RTM_GETLINK:
503                 case RTM_DELLINK:
504                         if (m->n_containers == 2 &&
505                             GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO &&
506                             GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA) {
507                                 switch (type) {
508                                        case IFLA_VLAN_ID:
509                                        case IFLA_IPTUN_FLAGS:
510                                        case IFLA_GRE_IFLAGS:
511                                        case IFLA_GRE_OFLAGS:
512                                        case IFLA_IPTUN_6RD_PREFIXLEN:
513                                        case IFLA_IPTUN_6RD_RELAY_PREFIXLEN:
514                                                break;
515                                        default:
516                                             return -ENOTSUP;
517                                 }
518                         } else
519                                 return -ENOTSUP;
520
521                         break;
522                 default:
523                         return -ENOTSUP;
524         }
525
526         r = add_rtattr(m, type, &data, sizeof(uint16_t));
527         if (r < 0)
528                 return r;
529
530         return 0;
531 }
532
533 int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data) {
534         uint16_t rtm_type;
535         int r;
536
537         assert_return(m, -EINVAL);
538         assert_return(!m->sealed, -EPERM);
539
540         r = sd_rtnl_message_get_type(m, &rtm_type);
541         if (r < 0)
542                 return r;
543
544         /* check that the type is correct */
545         switch (rtm_type) {
546                 case RTM_NEWLINK:
547                 case RTM_SETLINK:
548                 case RTM_GETLINK:
549                 case RTM_DELLINK:
550                         switch (type) {
551                                 case IFLA_MASTER:
552                                 case IFLA_MTU:
553                                 case IFLA_LINK:
554                                 case IFLA_GROUP:
555                                 case IFLA_TXQLEN:
556                                 case IFLA_WEIGHT:
557                                 case IFLA_NET_NS_FD:
558                                 case IFLA_NET_NS_PID:
559                                 case IFLA_PROMISCUITY:
560                                 case IFLA_NUM_TX_QUEUES:
561                                 case IFLA_NUM_RX_QUEUES:
562                                 case IFLA_IPTUN_LOCAL:
563                                 case IFLA_IPTUN_REMOTE:
564                                 case IFLA_MACVLAN_MODE:
565                                 case IFLA_IPTUN_FLAGS:
566                                 case IFLA_IPTUN_FLOWINFO:
567                                 case IFLA_GRE_FLOWINFO:
568                                         break;
569                                 default:
570                                         return -ENOTSUP;
571                         }
572                         break;
573                 case RTM_NEWROUTE:
574                 case RTM_GETROUTE:
575                 case RTM_DELROUTE:
576                         switch (type) {
577                                 case RTA_TABLE:
578                                 case RTA_PRIORITY:
579                                 case RTA_IIF:
580                                 case RTA_OIF:
581                                 case RTA_MARK:
582                                         break;
583                                 default:
584                                         return -ENOTSUP;
585                         }
586                         break;
587                 default:
588                         return -ENOTSUP;
589         }
590
591         r = add_rtattr(m, type, &data, sizeof(uint32_t));
592         if (r < 0)
593                 return r;
594
595         return 0;
596 }
597
598 int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data) {
599         struct ifaddrmsg *ifa;
600         struct rtmsg *rtm;
601         uint16_t rtm_type;
602         int r;
603
604         assert_return(m, -EINVAL);
605         assert_return(!m->sealed, -EPERM);
606         assert_return(data, -EINVAL);
607
608         r = sd_rtnl_message_get_type(m, &rtm_type);
609         if (r < 0)
610                 return r;
611
612         /* check that the type is correct */
613         switch (rtm_type) {
614                 case RTM_NEWADDR:
615                 case RTM_GETADDR:
616                 case RTM_DELADDR:
617                         switch (type) {
618                                 case IFA_ADDRESS:
619                                 case IFA_LOCAL:
620                                 case IFA_BROADCAST:
621                                 case IFA_ANYCAST:
622                                 case IFLA_GRE_LOCAL:
623                                 case IFLA_GRE_REMOTE:
624                                         ifa = NLMSG_DATA(m->hdr);
625
626                                         if (ifa->ifa_family != AF_INET)
627                                                 return -EINVAL;
628
629                                         break;
630                                 default:
631                                         return -ENOTSUP;
632                         }
633                         break;
634                 case RTM_NEWROUTE:
635                 case RTM_GETROUTE:
636                 case RTM_DELROUTE:
637                         switch (type) {
638                                 case RTA_DST:
639                                 case RTA_SRC:
640                                 case RTA_GATEWAY:
641                                         rtm = NLMSG_DATA(m->hdr);
642
643                                         if (rtm->rtm_family != AF_INET)
644                                                 return -EINVAL;
645
646                                         break;
647                                 default:
648                                         return -ENOTSUP;
649                         }
650                         break;
651                 default:
652                         return -ENOTSUP;
653         }
654
655         r = add_rtattr(m, type, data, sizeof(struct in_addr));
656         if (r < 0)
657                 return r;
658
659         return 0;
660 }
661
662 int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data) {
663         struct ifaddrmsg *ifa;
664         struct rtmsg *rtm;
665         uint16_t rtm_type;
666         int r;
667
668         assert_return(m, -EINVAL);
669         assert_return(!m->sealed, -EPERM);
670         assert_return(data, -EINVAL);
671
672         r = sd_rtnl_message_get_type(m, &rtm_type);
673         if (r < 0)
674                 return r;
675
676         /* check that the type is correct */
677         switch (rtm_type) {
678                 case RTM_NEWADDR:
679                 case RTM_GETADDR:
680                 case RTM_DELADDR:
681                         switch (type) {
682                                 case IFA_ADDRESS:
683                                 case IFA_LOCAL:
684                                 case IFA_BROADCAST:
685                                 case IFA_ANYCAST:
686                                 case IFLA_GRE_LOCAL:
687                                 case IFLA_GRE_REMOTE:
688                                 case IFLA_IPTUN_6RD_PREFIX:
689                                         ifa = NLMSG_DATA(m->hdr);
690
691                                         if (ifa->ifa_family != AF_INET6)
692                                                 return -EINVAL;
693
694                                         break;
695                                 default:
696                                         return -ENOTSUP;
697                         }
698                         break;
699                 case RTM_NEWROUTE:
700                 case RTM_GETROUTE:
701                 case RTM_DELROUTE:
702                         switch (type) {
703                                 case RTA_DST:
704                                 case RTA_SRC:
705                                 case RTA_GATEWAY:
706                                         rtm = NLMSG_DATA(m->hdr);
707
708                                         if (rtm->rtm_family != AF_INET6)
709                                                 return -EINVAL;
710
711                                         break;
712                                 default:
713                                         return -ENOTSUP;
714                         }
715                 default:
716                         return -ENOTSUP;
717         }
718
719         r = add_rtattr(m, type, data, sizeof(struct in6_addr));
720         if (r < 0)
721                 return r;
722
723         return 0;
724 }
725
726 int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data) {
727         uint16_t rtm_type;
728         int r;
729
730         assert_return(m, -EINVAL);
731         assert_return(!m->sealed, -EPERM);
732         assert_return(data, -EINVAL);
733
734         sd_rtnl_message_get_type(m, &rtm_type);
735
736         switch (rtm_type) {
737                 case RTM_NEWLINK:
738                 case RTM_SETLINK:
739                 case RTM_DELLINK:
740                 case RTM_GETLINK:
741                         switch (type) {
742                                 case IFLA_ADDRESS:
743                                 case IFLA_BROADCAST:
744                                         break;
745                                 default:
746                                         return -ENOTSUP;
747                         }
748                         break;
749                 default:
750                         return -ENOTSUP;
751         }
752
753         r = add_rtattr(m, type, data, ETH_ALEN);
754         if (r < 0)
755                 return r;
756
757         return 0;
758 }
759
760 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
761         uint16_t rtm_type;
762
763         assert_return(m, -EINVAL);
764         assert_return(!m->sealed, -EPERM);
765
766         sd_rtnl_message_get_type(m, &rtm_type);
767
768         if (rtnl_message_type_is_link(rtm_type)) {
769
770                 if ((type == IFLA_LINKINFO && m->n_containers == 0) ||
771                     (type == IFLA_INFO_DATA && m->n_containers == 1 &&
772                      GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO))
773                         return add_rtattr(m, type, NULL, 0);
774                 else if (type == VETH_INFO_PEER && m->n_containers == 2 &&
775                          GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA &&
776                          GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO)
777                         return add_rtattr(m, type, NULL, sizeof(struct ifinfomsg));
778         }
779
780         return -ENOTSUP;
781 }
782
783 int sd_rtnl_message_close_container(sd_rtnl_message *m) {
784         assert_return(m, -EINVAL);
785         assert_return(!m->sealed, -EPERM);
786         assert_return(m->n_containers > 0, -EINVAL);
787
788         m->n_containers --;
789
790         return 0;
791 }
792
793 int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
794         struct rtattr *rta;
795
796         assert_return(m, -EINVAL);
797         assert_return(m->sealed, -EPERM);
798         assert_return(data, -EINVAL);
799         assert_return(m->rta_offset_tb[m->n_containers], -EINVAL);
800         assert_return(type < m->rta_tb_size[m->n_containers], -EINVAL);
801
802         if(!m->rta_offset_tb[m->n_containers][type])
803                 return -ENODATA;
804
805         rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[m->n_containers][type]);
806
807         *data = RTA_DATA(rta);
808
809         return RTA_PAYLOAD(rta);
810 }
811
812 int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, char **data) {
813         int r;
814         void *attr_data;
815
816         assert_return(data, -EINVAL);
817
818         r = rtnl_message_read_internal(m, type, &attr_data);
819         if (r < 0)
820                 return r;
821         else if (strnlen(attr_data, r) >= (size_t) r)
822                 return -EIO;
823
824         *data = (char *) attr_data;
825
826         return 0;
827 }
828
829 int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data) {
830         int r;
831         void *attr_data;
832
833         assert_return(data, -EINVAL);
834
835         r = rtnl_message_read_internal(m, type, &attr_data);
836         if (r < 0)
837                 return r;
838         else if ((size_t) r < sizeof(uint8_t))
839                 return -EIO;
840
841         *data = *(uint8_t *) attr_data;
842
843         return 0;
844 }
845
846 int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data) {
847         int r;
848         void *attr_data;
849
850         assert_return(data, -EINVAL);
851
852         r = rtnl_message_read_internal(m, type, &attr_data);
853         if (r < 0)
854                 return r;
855         else if ((size_t) r < sizeof(uint16_t))
856                 return -EIO;
857
858         *data = *(uint16_t *) attr_data;
859
860         return 0;
861 }
862
863 int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data) {
864         int r;
865         void *attr_data;
866
867         assert_return(data, -EINVAL);
868
869         r = rtnl_message_read_internal(m, type, &attr_data);
870         if (r < 0)
871                 return r;
872         else if ((size_t)r < sizeof(uint32_t))
873                 return -EIO;
874
875         *data = *(uint32_t *) attr_data;
876
877         return 0;
878 }
879
880 int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data) {
881         int r;
882         void *attr_data;
883
884         assert_return(data, -EINVAL);
885
886         r = rtnl_message_read_internal(m, type, &attr_data);
887         if (r < 0)
888                 return r;
889         else if ((size_t)r < sizeof(struct ether_addr))
890                 return -EIO;
891
892         memcpy(data, attr_data, sizeof(struct ether_addr));
893
894         return 0;
895 }
896
897 int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
898         int r;
899         void *attr_data;
900
901         assert_return(data, -EINVAL);
902
903         r = rtnl_message_read_internal(m, type, &attr_data);
904         if (r < 0)
905                 return r;
906         else if ((size_t)r < sizeof(struct in_addr))
907                 return -EIO;
908
909         memcpy(data, attr_data, sizeof(struct in_addr));
910
911         return 0;
912 }
913
914 int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data) {
915         int r;
916         void *attr_data;
917
918         assert_return(data, -EINVAL);
919
920         r = rtnl_message_read_internal(m, type, &attr_data);
921         if (r < 0)
922                 return r;
923         else if ((size_t)r < sizeof(struct in6_addr))
924                 return -EIO;
925
926         memcpy(data, attr_data, sizeof(struct in6_addr));
927
928         return 0;
929 }
930
931 int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type) {
932         uint16_t rtm_type;
933         unsigned short parent_type;
934         void *container;
935         size_t container_length;
936         int max, r;
937
938         assert_return(m, -EINVAL);
939         assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
940
941         r = rtnl_message_read_internal(m, type, &container);
942         if (r < 0)
943                 return r;
944         else
945                 container_length = r;
946
947         r = sd_rtnl_message_get_type(m, &rtm_type);
948         if (r < 0)
949                 return r;
950
951         if (rtnl_message_type_is_link(rtm_type)) {
952                 switch (m->n_containers) {
953                         case 0:
954                                 switch (type) {
955                                         case IFLA_LINKINFO:
956                                                 max = IFLA_INFO_MAX;
957                                                 break;
958                                         default:
959                                                 return -ENOTSUP;
960                                 }
961                                 break;
962                         case 1:
963                                 parent_type = GET_CONTAINER(m, 0)->rta_type;
964                                 switch (parent_type) {
965                                         case IFLA_LINKINFO:
966                                                 switch (type) {
967                                                         case IFLA_INFO_DATA: {
968                                                                 char *kind;
969
970                                                                 r = sd_rtnl_message_read_string(m, IFLA_INFO_KIND, &kind);
971                                                                 if (r < 0)
972                                                                         return r;
973
974                                                                 if (streq(kind, "vlan")) {
975                                                                         max = IFLA_VLAN_MAX;
976                                                                 } else if (streq(kind, "bridge")) {
977                                                                         max = IFLA_BRIDGE_MAX;
978                                                                 } else if (streq(kind, "veth")) {
979                                                                         max = VETH_INFO_MAX;
980                                                                         container = IFLA_RTA(container);
981                                                                 } else
982                                                                         return -ENOTSUP;
983
984                                                                 break;
985                                                         }
986                                                         default:
987                                                                 return -ENOTSUP;
988                                                 }
989                                                 break;
990                                         default:
991                                                 return -ENOTSUP;
992                                 }
993                                 break;
994                         default:
995                                 return -ENOTSUP;
996                 }
997         } else
998                 return -ENOTSUP;
999
1000         r = rtnl_message_parse(m,
1001                                &m->rta_offset_tb[m->n_containers + 1],
1002                                &m->rta_tb_size[m->n_containers + 1],
1003                                max,
1004                                container,
1005                                container_length);
1006         if (r < 0)
1007                 return r;
1008
1009         m->n_containers ++;
1010
1011         return 0;
1012 }
1013
1014 int sd_rtnl_message_exit_container(sd_rtnl_message *m) {
1015         assert_return(m, -EINVAL);
1016         assert_return(m->sealed, -EINVAL);
1017         assert_return(m->n_containers > 0, -EINVAL);
1018
1019         free(m->rta_offset_tb[m->n_containers]);
1020         m->rta_offset_tb[m->n_containers] = NULL;
1021
1022         m->n_containers --;
1023
1024         return 0;
1025 }
1026
1027 uint32_t rtnl_message_get_serial(sd_rtnl_message *m) {
1028         assert(m);
1029         assert(m->hdr);
1030
1031         return m->hdr->nlmsg_seq;
1032 }
1033
1034 int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
1035         struct nlmsgerr *err;
1036
1037         assert_return(m, -EINVAL);
1038         assert_return(m->hdr, -EINVAL);
1039
1040         if (m->hdr->nlmsg_type != NLMSG_ERROR)
1041                 return 0;
1042
1043         err = NLMSG_DATA(m->hdr);
1044
1045         return err->error;
1046 }
1047
1048 static int message_receive_need(sd_rtnl *rtnl, size_t *need) {
1049         assert(rtnl);
1050         assert(need);
1051
1052         /* ioctl(rtnl->fd, FIONREAD, &need)
1053            Does not appear to work on netlink sockets. libnl uses
1054            MSG_PEEK instead. I don't know if that is worth the
1055            extra roundtrip.
1056
1057            For now we simply use the maximum message size the kernel
1058            may use (NLMSG_GOODSIZE), and then realloc to the actual
1059            size after reading the message (hence avoiding huge memory
1060            usage in case many small messages are kept around) */
1061         *need = page_size();
1062         if (*need > 8192UL)
1063                 *need = 8192UL;
1064
1065         return 0;
1066 }
1067
1068 int rtnl_message_parse(sd_rtnl_message *m,
1069                        size_t **rta_offset_tb,
1070                        unsigned short *rta_tb_size,
1071                        int max,
1072                        struct rtattr *rta,
1073                        unsigned int rt_len) {
1074         unsigned short type;
1075         size_t *tb;
1076
1077         tb = (size_t *) new0(size_t *, max);
1078         if(!tb)
1079                 return -ENOMEM;
1080
1081         *rta_tb_size = max;
1082
1083         for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
1084                 type = rta->rta_type;
1085
1086                 if (type > max) {
1087                         log_debug("rtnl: message parse - ignore out of range attribute type");
1088                         continue;
1089                 }
1090
1091                 if (tb[type])
1092                         log_debug("rtnl: message parse - overwriting repeated attribute");
1093
1094                 tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
1095         }
1096
1097         *rta_offset_tb = tb;
1098
1099         return 0;
1100 }
1101
1102 /* returns the number of bytes sent, or a negative error code */
1103 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
1104         union {
1105                 struct sockaddr sa;
1106                 struct sockaddr_nl nl;
1107         } addr = {
1108                 .nl.nl_family = AF_NETLINK,
1109         };
1110         ssize_t k;
1111
1112         assert(nl);
1113         assert(m);
1114         assert(m->hdr);
1115
1116         k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
1117                         0, &addr.sa, sizeof(addr));
1118         if (k < 0)
1119                 return (errno == EAGAIN) ? 0 : -errno;
1120
1121         return k;
1122 }
1123
1124 /* On success, the number of bytes received is returned and *ret points to the received message
1125  * which has a valid header and the correct size.
1126  * If nothing useful was received 0 is returned.
1127  * On failure, a negative error code is returned.
1128  */
1129 int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
1130         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
1131         struct nlmsghdr *new_hdr;
1132         union {
1133                 struct sockaddr sa;
1134                 struct sockaddr_nl nl;
1135         } addr;
1136         socklen_t addr_len;
1137         size_t need, len;
1138         int r;
1139
1140         assert(nl);
1141         assert(ret);
1142
1143         r = message_receive_need(nl, &need);
1144         if (r < 0)
1145                 return r;
1146
1147         r = message_new(nl, &m, need);
1148         if (r < 0)
1149                 return r;
1150
1151         addr_len = sizeof(addr);
1152
1153         r = recvfrom(nl->fd, m->hdr, need,
1154                         0, &addr.sa, &addr_len);
1155         if (r < 0)
1156                 return (errno == EAGAIN) ? 0 : -errno; /* no data */
1157         else if (r == 0)
1158                 return -ECONNRESET; /* connection was closed by the kernel */
1159         else if (addr_len != sizeof(addr.nl) ||
1160                         addr.nl.nl_family != AF_NETLINK)
1161                 return -EIO; /* not a netlink message */
1162         else if (addr.nl.nl_pid != 0)
1163                 return 0; /* not from the kernel */
1164         else if ((size_t) r < sizeof(struct nlmsghdr) ||
1165                         (size_t) r < m->hdr->nlmsg_len)
1166                 return -EIO; /* too small (we do accept too big though) */
1167         else if (m->hdr->nlmsg_pid && m->hdr->nlmsg_pid != nl->sockaddr.nl.nl_pid)
1168                 return 0; /* not broadcast and not for us */
1169         else
1170                 len = (size_t) r;
1171
1172         /* check that the size matches the message type */
1173         switch (m->hdr->nlmsg_type) {
1174
1175         case NLMSG_ERROR:
1176                 if (len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
1177                         return -EIO;
1178                 break;
1179
1180         case RTM_NEWLINK:
1181         case RTM_SETLINK:
1182         case RTM_DELLINK:
1183         case RTM_GETLINK:
1184                 if (len < NLMSG_LENGTH(sizeof(struct ifinfomsg)))
1185                         return -EIO;
1186                 break;
1187
1188         case RTM_NEWADDR:
1189         case RTM_DELADDR:
1190         case RTM_GETADDR:
1191                 if (len < NLMSG_LENGTH(sizeof(struct ifaddrmsg)))
1192                         return -EIO;
1193                 break;
1194         case RTM_NEWROUTE:
1195         case RTM_DELROUTE:
1196         case RTM_GETROUTE:
1197                 if (len < NLMSG_LENGTH(sizeof(struct rtmsg)))
1198                         return -EIO;
1199                 break;
1200         case NLMSG_NOOP:
1201                 return 0;
1202         default:
1203                 log_debug("sd-rtnl: ignored message with unknown type");
1204                 return 0;
1205         }
1206
1207         /* we probably allocated way too much memory, give it back */
1208         new_hdr = realloc(m->hdr, len);
1209         if (!new_hdr)
1210                 return -ENOMEM;
1211         m->hdr = new_hdr;
1212
1213         /* seal and parse the top-level message */
1214         r = sd_rtnl_message_rewind(m);
1215         if (r < 0)
1216                 return r;
1217
1218         *ret = m;
1219         m = NULL;
1220
1221         return len;
1222 }
1223
1224 int sd_rtnl_message_rewind(sd_rtnl_message *m) {
1225         struct ifinfomsg *ifi;
1226         struct ifaddrmsg *ifa;
1227         struct rtmsg *rtm;
1228         unsigned i;
1229         int r;
1230
1231         assert_return(m, -EINVAL);
1232         assert_return(m->hdr, -EINVAL);
1233
1234         /* don't allow appending to message once parsed */
1235         if (!m->sealed)
1236                 rtnl_message_seal(m);
1237
1238         for (i = 1; i <= m->n_containers; i++) {
1239                 free(m->rta_offset_tb[i]);
1240                 m->rta_offset_tb[i] = NULL;
1241                 m->rta_tb_size[i] = 0;
1242         }
1243
1244         m->n_containers = 0;
1245
1246         if (m->rta_offset_tb[0]) {
1247                 /* top-level attributes have already been parsed */
1248                 return 0;
1249         }
1250
1251         /* parse top-level attributes */
1252         switch(m->hdr->nlmsg_type) {
1253                 case NLMSG_NOOP:
1254                 case NLMSG_ERROR:
1255                         break;
1256                 case RTM_NEWLINK:
1257                 case RTM_SETLINK:
1258                 case RTM_GETLINK:
1259                 case RTM_DELLINK:
1260                         ifi = NLMSG_DATA(m->hdr);
1261
1262                         r = rtnl_message_parse(m,
1263                                                &m->rta_offset_tb[0],
1264                                                &m->rta_tb_size[0],
1265                                                IFLA_MAX,
1266                                                IFLA_RTA(ifi),
1267                                                IFLA_PAYLOAD(m->hdr));
1268                         if (r < 0)
1269                                 return r;
1270
1271                         break;
1272                 case RTM_NEWADDR:
1273                 case RTM_GETADDR:
1274                 case RTM_DELADDR:
1275                         ifa = NLMSG_DATA(m->hdr);
1276
1277                         r = rtnl_message_parse(m,
1278                                                &m->rta_offset_tb[0],
1279                                                &m->rta_tb_size[0],
1280                                                IFA_MAX,
1281                                                IFA_RTA(ifa),
1282                                                IFA_PAYLOAD(m->hdr));
1283                         if (r < 0)
1284                                 return r;
1285
1286                         break;
1287                 case RTM_NEWROUTE:
1288                 case RTM_GETROUTE:
1289                 case RTM_DELROUTE:
1290                         rtm = NLMSG_DATA(m->hdr);
1291
1292                         r = rtnl_message_parse(m,
1293                                                &m->rta_offset_tb[0],
1294                                                &m->rta_tb_size[0],
1295                                                RTA_MAX,
1296                                                RTM_RTA(rtm),
1297                                                RTM_PAYLOAD(m->hdr));
1298
1299                         break;
1300                 default:
1301                         return -ENOTSUP;
1302         }
1303
1304         return 0;
1305 }
1306
1307 void rtnl_message_seal(sd_rtnl_message *m) {
1308         assert(m);
1309         assert(!m->sealed);
1310
1311         m->sealed = true;
1312 }