chiark / gitweb /
sd-rtnl: log if kernel buffer is overrun as we currently can't handle that case
[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/netlink.h>
27 #include <linux/veth.h>
28 #include <linux/if.h>
29 #include <linux/ip.h>
30 #include <linux/if_tunnel.h>
31 #include <linux/if_bridge.h>
32
33 #include "util.h"
34 #include "refcnt.h"
35 #include "missing.h"
36
37 #include "sd-rtnl.h"
38 #include "rtnl-util.h"
39 #include "rtnl-internal.h"
40 #include "rtnl-types.h"
41
42 #define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->container_offsets[i]) : NULL)
43 #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
44
45 static int message_new_empty(sd_rtnl *rtnl, sd_rtnl_message **ret) {
46         sd_rtnl_message *m;
47
48         assert_return(ret, -EINVAL);
49
50         /* Note that 'rtnl' is curretly unused, if we start using it internally
51            we must take care to avoid problems due to mutual references between
52            busses and their queued messages. See sd-bus.
53          */
54
55         m = new0(sd_rtnl_message, 1);
56         if (!m)
57                 return -ENOMEM;
58
59         m->n_ref = REFCNT_INIT;
60
61         m->sealed = false;
62
63         *ret = m;
64
65         return 0;
66 }
67
68 int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t type) {
69         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
70         const NLType *nl_type;
71         size_t size;
72         int r;
73
74         r = type_system_get_type(NULL, &nl_type, type);
75         if (r < 0)
76                 return r;
77
78         assert(nl_type->type == NLA_NESTED);
79
80         r = message_new_empty(rtnl, &m);
81         if (r < 0)
82                 return r;
83
84         size = NLMSG_SPACE(nl_type->size);
85
86         assert(size >= sizeof(struct nlmsghdr));
87         m->hdr = malloc0(size);
88         if (!m->hdr)
89                 return -ENOMEM;
90
91         m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
92
93         m->container_type_system[0] = nl_type->type_system;
94         m->hdr->nlmsg_len = size;
95         m->hdr->nlmsg_type = type;
96
97         *ret = m;
98         m = NULL;
99
100         return 0;
101 }
102
103 int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
104         struct rtmsg *rtm;
105
106         assert_return(m, -EINVAL);
107         assert_return(m->hdr, -EINVAL);
108         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
109
110         rtm = NLMSG_DATA(m->hdr);
111
112         if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
113             (rtm->rtm_family == AF_INET6 && prefixlen > 128))
114                 return -ERANGE;
115
116         rtm->rtm_dst_len = prefixlen;
117
118         return 0;
119 }
120
121 int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
122         struct rtmsg *rtm;
123
124         assert_return(m, -EINVAL);
125         assert_return(m->hdr, -EINVAL);
126         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
127
128         rtm = NLMSG_DATA(m->hdr);
129
130         rtm->rtm_scope = scope;
131
132         return 0;
133 }
134
135 int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
136                               uint16_t nlmsg_type, int rtm_family,
137                               unsigned char rtm_protocol) {
138         struct rtmsg *rtm;
139         int r;
140
141         assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL);
142         assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
143         assert_return(ret, -EINVAL);
144
145         r = message_new(rtnl, ret, nlmsg_type);
146         if (r < 0)
147                 return r;
148
149         if (nlmsg_type == RTM_NEWROUTE)
150                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
151
152         rtm = NLMSG_DATA((*ret)->hdr);
153
154         rtm->rtm_family = rtm_family;
155         rtm->rtm_scope = RT_SCOPE_UNIVERSE;
156         rtm->rtm_type = RTN_UNICAST;
157         rtm->rtm_table = RT_TABLE_MAIN;
158         rtm->rtm_protocol = rtm_protocol;
159
160         return 0;
161 }
162
163 int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change) {
164         struct ifinfomsg *ifi;
165
166         assert_return(m, -EINVAL);
167         assert_return(m->hdr, -EINVAL);
168         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
169         assert_return(change, -EINVAL);
170
171         ifi = NLMSG_DATA(m->hdr);
172
173         ifi->ifi_flags = flags;
174         ifi->ifi_change = change;
175
176         return 0;
177 }
178
179 int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type) {
180         struct ifinfomsg *ifi;
181
182         assert_return(m, -EINVAL);
183         assert_return(m->hdr, -EINVAL);
184         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
185
186         ifi = NLMSG_DATA(m->hdr);
187
188         ifi->ifi_type = type;
189
190         return 0;
191 }
192
193 int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret,
194                              uint16_t nlmsg_type, int index) {
195         struct ifinfomsg *ifi;
196         int r;
197
198         assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
199         assert_return(nlmsg_type != RTM_DELLINK || index > 0, -EINVAL);
200         assert_return(ret, -EINVAL);
201
202         r = message_new(rtnl, ret, nlmsg_type);
203         if (r < 0)
204                 return r;
205
206         if (nlmsg_type == RTM_NEWLINK)
207                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
208
209         ifi = NLMSG_DATA((*ret)->hdr);
210
211         ifi->ifi_family = AF_UNSPEC;
212         ifi->ifi_index = index;
213
214         return 0;
215 }
216
217 int sd_rtnl_message_request_dump(sd_rtnl_message *m, int dump) {
218         assert_return(m, -EINVAL);
219         assert_return(m->hdr, -EINVAL);
220         assert_return(m->hdr->nlmsg_type == RTM_GETLINK ||
221                       m->hdr->nlmsg_type == RTM_GETADDR ||
222                       m->hdr->nlmsg_type == RTM_GETROUTE,
223                       -EINVAL);
224
225         if (dump)
226                 m->hdr->nlmsg_flags |= NLM_F_DUMP;
227         else
228                 m->hdr->nlmsg_flags &= ~NLM_F_DUMP;
229
230         return 0;
231 }
232
233 int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
234         struct ifaddrmsg *ifa;
235
236         assert_return(m, -EINVAL);
237         assert_return(m->hdr, -EINVAL);
238         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
239
240         ifa = NLMSG_DATA(m->hdr);
241
242         if ((ifa->ifa_family == AF_INET && prefixlen > 32) ||
243             (ifa->ifa_family == AF_INET6 && prefixlen > 128))
244                 return -ERANGE;
245
246         ifa->ifa_prefixlen = prefixlen;
247
248         return 0;
249 }
250
251 int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags) {
252         struct ifaddrmsg *ifa;
253
254         assert_return(m, -EINVAL);
255         assert_return(m->hdr, -EINVAL);
256         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
257
258         ifa = NLMSG_DATA(m->hdr);
259
260         ifa->ifa_flags = flags;
261
262         return 0;
263 }
264
265 int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) {
266         struct ifaddrmsg *ifa;
267
268         assert_return(m, -EINVAL);
269         assert_return(m->hdr, -EINVAL);
270         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
271
272         ifa = NLMSG_DATA(m->hdr);
273
274         ifa->ifa_scope = scope;
275
276         return 0;
277 }
278
279 int sd_rtnl_message_addr_get_family(sd_rtnl_message *m, int *family) {
280         struct ifaddrmsg *ifa;
281
282         assert_return(m, -EINVAL);
283         assert_return(m->hdr, -EINVAL);
284         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
285         assert_return(family, -EINVAL);
286
287         ifa = NLMSG_DATA(m->hdr);
288
289         *family = ifa->ifa_family;
290
291         return 0;
292 }
293
294 int sd_rtnl_message_addr_get_prefixlen(sd_rtnl_message *m, unsigned char *prefixlen) {
295         struct ifaddrmsg *ifa;
296
297         assert_return(m, -EINVAL);
298         assert_return(m->hdr, -EINVAL);
299         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
300         assert_return(prefixlen, -EINVAL);
301
302         ifa = NLMSG_DATA(m->hdr);
303
304         *prefixlen = ifa->ifa_prefixlen;
305
306         return 0;
307 }
308
309 int sd_rtnl_message_addr_get_scope(sd_rtnl_message *m, unsigned char *scope) {
310         struct ifaddrmsg *ifa;
311
312         assert_return(m, -EINVAL);
313         assert_return(m->hdr, -EINVAL);
314         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
315         assert_return(scope, -EINVAL);
316
317         ifa = NLMSG_DATA(m->hdr);
318
319         *scope = ifa->ifa_scope;
320
321         return 0;
322 }
323
324 int sd_rtnl_message_addr_get_flags(sd_rtnl_message *m, unsigned char *flags) {
325         struct ifaddrmsg *ifa;
326
327         assert_return(m, -EINVAL);
328         assert_return(m->hdr, -EINVAL);
329         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
330         assert_return(flags, -EINVAL);
331
332         ifa = NLMSG_DATA(m->hdr);
333
334         *flags = ifa->ifa_flags;
335
336         return 0;
337 }
338
339 int sd_rtnl_message_addr_get_ifindex(sd_rtnl_message *m, int *ifindex) {
340         struct ifaddrmsg *ifa;
341
342         assert_return(m, -EINVAL);
343         assert_return(m->hdr, -EINVAL);
344         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
345         assert_return(ifindex, -EINVAL);
346
347         ifa = NLMSG_DATA(m->hdr);
348
349         *ifindex = ifa->ifa_index;
350
351         return 0;
352 }
353
354 int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
355                              uint16_t nlmsg_type, int index,
356                              int family) {
357         struct ifaddrmsg *ifa;
358         int r;
359
360         assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
361         assert_return((nlmsg_type == RTM_GETADDR && index == 0) ||
362                       index > 0, -EINVAL);
363         assert_return((nlmsg_type == RTM_GETADDR && family == AF_UNSPEC) ||
364                       family == AF_INET || family == AF_INET6, -EINVAL);
365         assert_return(ret, -EINVAL);
366
367         r = message_new(rtnl, ret, nlmsg_type);
368         if (r < 0)
369                 return r;
370
371         if (nlmsg_type == RTM_GETADDR)
372                 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
373
374         ifa = NLMSG_DATA((*ret)->hdr);
375
376         ifa->ifa_index = index;
377         ifa->ifa_family = family;
378         if (family == AF_INET)
379                 ifa->ifa_prefixlen = 32;
380         else if (family == AF_INET6)
381                 ifa->ifa_prefixlen = 128;
382
383         return 0;
384 }
385
386 int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret,
387                              int index, int family) {
388         int r;
389
390         r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family);
391         if (r < 0)
392                 return r;
393
394         (*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE;
395
396         return 0;
397 }
398
399 sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
400         if (m)
401                 assert_se(REFCNT_INC(m->n_ref) >= 2);
402
403         return m;
404 }
405
406 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
407         if (m && REFCNT_DEC(m->n_ref) <= 0) {
408                 unsigned i;
409
410                 free(m->hdr);
411
412                 for (i = 0; i <= m->n_containers; i++)
413                         free(m->rta_offset_tb[i]);
414
415                 sd_rtnl_message_unref(m->next);
416
417                 free(m);
418         }
419
420         return NULL;
421 }
422
423 int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type) {
424         assert_return(m, -EINVAL);
425         assert_return(type, -EINVAL);
426
427         *type = m->hdr->nlmsg_type;
428
429         return 0;
430 }
431
432 int sd_rtnl_message_is_broadcast(sd_rtnl_message *m) {
433         assert_return(m, -EINVAL);
434
435         return !m->hdr->nlmsg_pid;
436 }
437
438 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex) {
439         struct ifinfomsg *ifi;
440
441         assert_return(m, -EINVAL);
442         assert_return(m->hdr, -EINVAL);
443         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
444         assert_return(ifindex, -EINVAL);
445
446         ifi = NLMSG_DATA(m->hdr);
447
448         *ifindex = ifi->ifi_index;
449
450         return 0;
451 }
452
453 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
454         struct ifinfomsg *ifi;
455
456         assert_return(m, -EINVAL);
457         assert_return(m->hdr, -EINVAL);
458         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
459         assert_return(flags, -EINVAL);
460
461         ifi = NLMSG_DATA(m->hdr);
462
463         *flags = ifi->ifi_flags;
464
465         return 0;
466 }
467
468 int sd_rtnl_message_link_get_type(sd_rtnl_message *m, unsigned *type) {
469         struct ifinfomsg *ifi;
470
471         assert_return(m, -EINVAL);
472         assert_return(m->hdr, -EINVAL);
473         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
474         assert_return(type, -EINVAL);
475
476         ifi = NLMSG_DATA(m->hdr);
477
478         *type = ifi->ifi_type;
479
480         return 0;
481 }
482
483 /* If successful the updated message will be correctly aligned, if
484    unsuccessful the old message is untouched. */
485 static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
486         uint32_t rta_length;
487         size_t message_length, padding_length;
488         struct nlmsghdr *new_hdr;
489         struct rtattr *rta;
490         char *padding;
491         unsigned i;
492         int offset;
493
494         assert(m);
495         assert(m->hdr);
496         assert(!m->sealed);
497         assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
498         assert(!data || data_length);
499
500         /* get offset of the new attribute */
501         offset = m->hdr->nlmsg_len;
502
503         /* get the size of the new rta attribute (with padding at the end) */
504         rta_length = RTA_LENGTH(data_length);
505
506         /* get the new message size (with padding at the end) */
507         message_length = offset + RTA_ALIGN(rta_length);
508
509         /* realloc to fit the new attribute */
510         new_hdr = realloc(m->hdr, message_length);
511         if (!new_hdr)
512                 return -ENOMEM;
513         m->hdr = new_hdr;
514
515         /* get pointer to the attribute we are about to add */
516         rta = (struct rtattr *) ((uint8_t *) m->hdr + offset);
517
518         /* if we are inside containers, extend them */
519         for (i = 0; i < m->n_containers; i++)
520                 GET_CONTAINER(m, i)->rta_len += message_length - offset;
521
522         /* fill in the attribute */
523         rta->rta_type = type;
524         rta->rta_len = rta_length;
525         if (data)
526                 /* we don't deal with the case where the user lies about the type
527                  * and gives us too little data (so don't do that)
528                  */
529                 padding = mempcpy(RTA_DATA(rta), data, data_length);
530         else {
531                 /* if no data was passed, make sure we still initialize the padding
532                    note that we can have data_length > 0 (used by some containers) */
533                 padding = RTA_DATA(rta);
534                 data_length = 0;
535         }
536
537         /* make sure also the padding at the end of the message is initialized */
538         padding_length = (uint8_t*)m->hdr + message_length - (uint8_t*)padding;
539         memzero(padding, padding_length);
540
541         /* update message size */
542         m->hdr->nlmsg_len = message_length;
543
544         return offset;
545 }
546
547 static int message_attribute_has_type(sd_rtnl_message *m, uint16_t attribute_type, uint16_t data_type) {
548         const NLType *type;
549         int r;
550
551         r = type_system_get_type(m->container_type_system[m->n_containers], &type, attribute_type);
552         if (r < 0)
553                 return r;
554
555         if (type->type != data_type)
556                 return -EINVAL;
557
558         return type->size;
559 }
560
561 int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
562         size_t length, size;
563         int r;
564
565         assert_return(m, -EINVAL);
566         assert_return(!m->sealed, -EPERM);
567         assert_return(data, -EINVAL);
568
569         r = message_attribute_has_type(m, type, NLA_STRING);
570         if (r < 0)
571                 return r;
572         else
573                 size = (size_t)r;
574
575         if (size) {
576                 length = strnlen(data, size);
577                 if (length >= size)
578                         return -EINVAL;
579         } else
580                 length = strlen(data);
581
582         r = add_rtattr(m, type, data, length + 1);
583         if (r < 0)
584                 return r;
585
586         return 0;
587 }
588
589 int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data) {
590         int r;
591
592         assert_return(m, -EINVAL);
593         assert_return(!m->sealed, -EPERM);
594
595         r = message_attribute_has_type(m, type, NLA_U8);
596         if (r < 0)
597                 return r;
598
599         r = add_rtattr(m, type, &data, sizeof(uint8_t));
600         if (r < 0)
601                 return r;
602
603         return 0;
604 }
605
606
607 int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t data) {
608         int r;
609
610         assert_return(m, -EINVAL);
611         assert_return(!m->sealed, -EPERM);
612
613         r = message_attribute_has_type(m, type, NLA_U16);
614         if (r < 0)
615                 return r;
616
617         r = add_rtattr(m, type, &data, sizeof(uint16_t));
618         if (r < 0)
619                 return r;
620
621         return 0;
622 }
623
624 int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data) {
625         int r;
626
627         assert_return(m, -EINVAL);
628         assert_return(!m->sealed, -EPERM);
629
630         r = message_attribute_has_type(m, type, NLA_U32);
631         if (r < 0)
632                 return r;
633
634         r = add_rtattr(m, type, &data, sizeof(uint32_t));
635         if (r < 0)
636                 return r;
637
638         return 0;
639 }
640
641 int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data) {
642         int r;
643
644         assert_return(m, -EINVAL);
645         assert_return(!m->sealed, -EPERM);
646         assert_return(data, -EINVAL);
647
648         r = message_attribute_has_type(m, type, NLA_IN_ADDR);
649         if (r < 0)
650                 return r;
651
652         r = add_rtattr(m, type, data, sizeof(struct in_addr));
653         if (r < 0)
654                 return r;
655
656         return 0;
657 }
658
659 int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data) {
660         int r;
661
662         assert_return(m, -EINVAL);
663         assert_return(!m->sealed, -EPERM);
664         assert_return(data, -EINVAL);
665
666         r = message_attribute_has_type(m, type, NLA_IN_ADDR);
667         if (r < 0)
668                 return r;
669
670         r = add_rtattr(m, type, data, sizeof(struct in6_addr));
671         if (r < 0)
672                 return r;
673
674         return 0;
675 }
676
677 int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data) {
678         int r;
679
680         assert_return(m, -EINVAL);
681         assert_return(!m->sealed, -EPERM);
682         assert_return(data, -EINVAL);
683
684         r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
685         if (r < 0)
686                 return r;
687
688         r = add_rtattr(m, type, data, ETH_ALEN);
689         if (r < 0)
690                 return r;
691
692         return 0;
693 }
694
695 int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short type, const struct ifa_cacheinfo *info) {
696         int r;
697
698         assert_return(m, -EINVAL);
699         assert_return(!m->sealed, -EPERM);
700         assert_return(info, -EINVAL);
701
702         r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
703         if (r < 0)
704                 return r;
705
706         r = add_rtattr(m, type, info, sizeof(struct ifa_cacheinfo));
707         if (r < 0)
708                 return r;
709
710         return 0;
711 }
712
713 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
714         size_t size;
715         int r;
716
717         assert_return(m, -EINVAL);
718         assert_return(!m->sealed, -EPERM);
719         assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE);
720
721         r = message_attribute_has_type(m, type, NLA_NESTED);
722         if (r < 0)
723                 return r;
724         else
725                 size = (size_t)r;
726
727         r = type_system_get_type_system(m->container_type_system[m->n_containers],
728                                         &m->container_type_system[m->n_containers + 1],
729                                         type);
730         if (r < 0)
731                 return r;
732
733         r = add_rtattr(m, type, NULL, size);
734         if (r < 0)
735                 return r;
736
737         m->container_offsets[m->n_containers ++] = r;
738
739         return 0;
740 }
741
742 int sd_rtnl_message_open_container_union(sd_rtnl_message *m, unsigned short type, const char *key) {
743         const NLTypeSystemUnion *type_system_union;
744         int r;
745
746         assert_return(m, -EINVAL);
747         assert_return(!m->sealed, -EPERM);
748
749         r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type);
750         if (r < 0)
751                 return r;
752
753         r = type_system_union_get_type_system(type_system_union,
754                                               &m->container_type_system[m->n_containers + 1],
755                                               key);
756         if (r < 0)
757                 return r;
758
759         r = sd_rtnl_message_append_string(m, type_system_union->match, key);
760         if (r < 0)
761                 return r;
762
763         /* do we evere need non-null size */
764         r = add_rtattr(m, type, NULL, 0);
765         if (r < 0)
766                 return r;
767
768         m->container_offsets[m->n_containers ++] = r;
769
770         return 0;
771 }
772
773
774 int sd_rtnl_message_close_container(sd_rtnl_message *m) {
775         assert_return(m, -EINVAL);
776         assert_return(!m->sealed, -EPERM);
777         assert_return(m->n_containers > 0, -EINVAL);
778
779         m->container_type_system[m->n_containers] = NULL;
780         m->n_containers --;
781
782         return 0;
783 }
784
785 int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
786         struct rtattr *rta;
787
788         assert_return(m, -EINVAL);
789         assert_return(m->sealed, -EPERM);
790         assert_return(data, -EINVAL);
791         assert(m->n_containers <= RTNL_CONTAINER_DEPTH);
792         assert(m->rta_offset_tb[m->n_containers]);
793         assert(type < m->rta_tb_size[m->n_containers]);
794
795         if(!m->rta_offset_tb[m->n_containers][type])
796                 return -ENODATA;
797
798         rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[m->n_containers][type]);
799
800         *data = RTA_DATA(rta);
801
802         return RTA_PAYLOAD(rta);
803 }
804
805 int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, const char **data) {
806         int r;
807         void *attr_data;
808
809         r = message_attribute_has_type(m, type, NLA_STRING);
810         if (r < 0)
811                 return r;
812
813         r = rtnl_message_read_internal(m, type, &attr_data);
814         if (r < 0)
815                 return r;
816         else if (strnlen(attr_data, r) >= (size_t) r)
817                 return -EIO;
818
819         *data = (const char *) attr_data;
820
821         return 0;
822 }
823
824 int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data) {
825         int r;
826         void *attr_data;
827
828         r = message_attribute_has_type(m, type, NLA_U8);
829         if (r < 0)
830                 return r;
831
832         r = rtnl_message_read_internal(m, type, &attr_data);
833         if (r < 0)
834                 return r;
835         else if ((size_t) r < sizeof(uint8_t))
836                 return -EIO;
837
838         *data = *(uint8_t *) attr_data;
839
840         return 0;
841 }
842
843 int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data) {
844         int r;
845         void *attr_data;
846
847         r = message_attribute_has_type(m, type, NLA_U16);
848         if (r < 0)
849                 return r;
850
851         r = rtnl_message_read_internal(m, type, &attr_data);
852         if (r < 0)
853                 return r;
854         else if ((size_t) r < sizeof(uint16_t))
855                 return -EIO;
856
857         *data = *(uint16_t *) attr_data;
858
859         return 0;
860 }
861
862 int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data) {
863         int r;
864         void *attr_data;
865
866         r = message_attribute_has_type(m, type, NLA_U32);
867         if (r < 0)
868                 return r;
869
870         r = rtnl_message_read_internal(m, type, &attr_data);
871         if (r < 0)
872                 return r;
873         else if ((size_t)r < sizeof(uint32_t))
874                 return -EIO;
875
876         *data = *(uint32_t *) attr_data;
877
878         return 0;
879 }
880
881 int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data) {
882         int r;
883         void *attr_data;
884
885         r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
886         if (r < 0)
887                 return r;
888
889         r = rtnl_message_read_internal(m, type, &attr_data);
890         if (r < 0)
891                 return r;
892         else if ((size_t)r < sizeof(struct ether_addr))
893                 return -EIO;
894
895         memcpy(data, attr_data, sizeof(struct ether_addr));
896
897         return 0;
898 }
899
900 int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, struct ifa_cacheinfo *info) {
901         int r;
902         void *attr_data;
903
904         r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
905         if (r < 0)
906                 return r;
907
908         r = rtnl_message_read_internal(m, type, &attr_data);
909         if (r < 0)
910                 return r;
911         else if ((size_t)r < sizeof(struct ifa_cacheinfo))
912                 return -EIO;
913
914         memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
915
916         return 0;
917 }
918
919 int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
920         int r;
921         void *attr_data;
922
923         r = message_attribute_has_type(m, type, NLA_IN_ADDR);
924         if (r < 0)
925                 return r;
926
927         r = rtnl_message_read_internal(m, type, &attr_data);
928         if (r < 0)
929                 return r;
930         else if ((size_t)r < sizeof(struct in_addr))
931                 return -EIO;
932
933         memcpy(data, attr_data, sizeof(struct in_addr));
934
935         return 0;
936 }
937
938 int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data) {
939         int r;
940         void *attr_data;
941
942         r = message_attribute_has_type(m, type, NLA_IN_ADDR);
943         if (r < 0)
944                 return r;
945
946         r = rtnl_message_read_internal(m, type, &attr_data);
947         if (r < 0)
948                 return r;
949         else if ((size_t)r < sizeof(struct in6_addr))
950                 return -EIO;
951
952         memcpy(data, attr_data, sizeof(struct in6_addr));
953
954         return 0;
955 }
956
957 int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type) {
958         const NLType *nl_type;
959         const NLTypeSystem *type_system;
960         void *container;
961         size_t size;
962         int r;
963
964         assert_return(m, -EINVAL);
965         assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
966
967         r = type_system_get_type(m->container_type_system[m->n_containers],
968                                  &nl_type,
969                                  type);
970         if (r < 0)
971                 return r;
972
973         if (nl_type->type == NLA_NESTED) {
974                 r = type_system_get_type_system(m->container_type_system[m->n_containers],
975                                                 &type_system,
976                                                 type);
977                 if (r < 0)
978                         return r;
979         } else if (nl_type->type == NLA_UNION) {
980                 const NLTypeSystemUnion *type_system_union;
981                 const char *key;
982
983                 r = type_system_get_type_system_union(m->container_type_system[m->n_containers],
984                                                       &type_system_union,
985                                                       type);
986                 if (r < 0)
987                         return r;
988
989                 r = sd_rtnl_message_read_string(m, type_system_union->match, &key);
990                 if (r < 0)
991                         return r;
992
993                 r = type_system_union_get_type_system(type_system_union,
994                                                       &type_system,
995                                                       key);
996                 if (r < 0)
997                         return r;
998         } else
999                 return -EINVAL;
1000
1001         r = rtnl_message_read_internal(m, type, &container);
1002         if (r < 0)
1003                 return r;
1004         else
1005                 size = (size_t)r;
1006
1007         m->n_containers ++;
1008
1009         r = rtnl_message_parse(m,
1010                                &m->rta_offset_tb[m->n_containers],
1011                                &m->rta_tb_size[m->n_containers],
1012                                type_system->max,
1013                                container,
1014                                size);
1015         if (r < 0) {
1016                 m->n_containers --;
1017                 return r;
1018         }
1019
1020         m->container_type_system[m->n_containers] = type_system;
1021
1022         return 0;
1023 }
1024
1025 int sd_rtnl_message_exit_container(sd_rtnl_message *m) {
1026         assert_return(m, -EINVAL);
1027         assert_return(m->sealed, -EINVAL);
1028         assert_return(m->n_containers > 0, -EINVAL);
1029
1030         free(m->rta_offset_tb[m->n_containers]);
1031         m->rta_offset_tb[m->n_containers] = NULL;
1032         m->container_type_system[m->n_containers] = NULL;
1033
1034         m->n_containers --;
1035
1036         return 0;
1037 }
1038
1039 uint32_t rtnl_message_get_serial(sd_rtnl_message *m) {
1040         assert(m);
1041         assert(m->hdr);
1042
1043         return m->hdr->nlmsg_seq;
1044 }
1045
1046 int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
1047         struct nlmsgerr *err;
1048
1049         assert_return(m, -EINVAL);
1050         assert_return(m->hdr, -EINVAL);
1051
1052         if (m->hdr->nlmsg_type != NLMSG_ERROR)
1053                 return 0;
1054
1055         err = NLMSG_DATA(m->hdr);
1056
1057         return err->error;
1058 }
1059
1060 int rtnl_message_parse(sd_rtnl_message *m,
1061                        size_t **rta_offset_tb,
1062                        unsigned short *rta_tb_size,
1063                        int max,
1064                        struct rtattr *rta,
1065                        unsigned int rt_len) {
1066         unsigned short type;
1067         size_t *tb;
1068
1069         tb = new0(size_t, max + 1);
1070         if(!tb)
1071                 return -ENOMEM;
1072
1073         *rta_tb_size = max + 1;
1074
1075         for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
1076                 type = rta->rta_type;
1077
1078                 /* if the kernel is newer than the headers we used
1079                    when building, we ignore out-of-range attributes
1080                  */
1081                 if (type > max)
1082                         continue;
1083
1084                 if (tb[type])
1085                         log_debug("rtnl: message parse - overwriting repeated attribute");
1086
1087                 tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
1088         }
1089
1090         *rta_offset_tb = tb;
1091
1092         return 0;
1093 }
1094
1095 /* returns the number of bytes sent, or a negative error code */
1096 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
1097         union {
1098                 struct sockaddr sa;
1099                 struct sockaddr_nl nl;
1100         } addr = {
1101                 .nl.nl_family = AF_NETLINK,
1102         };
1103         ssize_t k;
1104
1105         assert(nl);
1106         assert(m);
1107         assert(m->hdr);
1108
1109         k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
1110                         0, &addr.sa, sizeof(addr));
1111         if (k < 0)
1112                 return (errno == EAGAIN) ? 0 : -errno;
1113
1114         return k;
1115 }
1116
1117 static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool peek) {
1118         uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred)) +
1119                             CMSG_SPACE(sizeof(struct nl_pktinfo))];
1120         struct msghdr msg = {
1121                 .msg_iov = iov,
1122                 .msg_iovlen = 1,
1123                 .msg_control = cred_buffer,
1124                 .msg_controllen = sizeof(cred_buffer),
1125         };
1126         struct cmsghdr *cmsg;
1127         uint32_t group = 0;
1128         bool auth = false;
1129         int r;
1130
1131         assert(fd >= 0);
1132         assert(iov);
1133
1134         r = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
1135         if (r < 0) {
1136                 /* no data */
1137                 if (errno == ENOBUFS)
1138                         log_debug("rtnl: kernel receive buffer overrun");
1139
1140                 return (errno == EAGAIN) ? 0 : -errno;
1141         } else if (r == 0)
1142                 /* connection was closed by the kernel */
1143                 return -ECONNRESET;
1144
1145         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1146                 if (cmsg->cmsg_level == SOL_SOCKET &&
1147                     cmsg->cmsg_type == SCM_CREDENTIALS &&
1148                     cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1149                         struct ucred *ucred = (void *)CMSG_DATA(cmsg);
1150
1151                         /* from the kernel */
1152                         if (ucred->uid == 0 && ucred->pid == 0)
1153                                 auth = true;
1154                 } else if (cmsg->cmsg_level == SOL_NETLINK &&
1155                            cmsg->cmsg_type == NETLINK_PKTINFO &&
1156                            cmsg->cmsg_len == CMSG_LEN(sizeof(struct nl_pktinfo))) {
1157                         struct nl_pktinfo *pktinfo = (void *)CMSG_DATA(cmsg);
1158
1159                         /* multi-cast group */
1160                         group = pktinfo->group;
1161                 }
1162         }
1163
1164         if (!auth)
1165                 /* not from the kernel, ignore */
1166                 return 0;
1167
1168         if (group)
1169                 *_group = group;
1170
1171         return r;
1172 }
1173
1174 /* On success, the number of bytes received is returned and *ret points to the received message
1175  * which has a valid header and the correct size.
1176  * If nothing useful was received 0 is returned.
1177  * On failure, a negative error code is returned.
1178  */
1179 int socket_read_message(sd_rtnl *rtnl) {
1180         _cleanup_rtnl_message_unref_ sd_rtnl_message *first = NULL;
1181         struct iovec iov = {};
1182         uint32_t group = 0;
1183         bool multi_part = false, done = false;
1184         struct nlmsghdr *new_msg;
1185         size_t len;
1186         int r;
1187         unsigned i = 0;
1188
1189         assert(rtnl);
1190         assert(rtnl->rbuffer);
1191         assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
1192
1193         /* read nothing, just get the pending message size */
1194         r = socket_recv_message(rtnl->fd, &iov, &group, true);
1195         if (r <= 0)
1196                 return r;
1197         else
1198                 len = (size_t)r;
1199
1200         /* make room for the pending message */
1201         if (!greedy_realloc((void **)&rtnl->rbuffer,
1202                             &rtnl->rbuffer_allocated,
1203                             len, sizeof(uint8_t)))
1204                 return -ENOMEM;
1205
1206         iov.iov_base = rtnl->rbuffer;
1207         iov.iov_len = rtnl->rbuffer_allocated;
1208
1209         /* read the pending message */
1210         r = socket_recv_message(rtnl->fd, &iov, &group, false);
1211         if (r <= 0)
1212                 return r;
1213         else
1214                 len = (size_t)r;
1215
1216         if (len > rtnl->rbuffer_allocated)
1217                 /* message did not fit in read buffer */
1218                 return -EIO;
1219
1220         if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
1221                 multi_part = true;
1222
1223                 for (i = 0; i < rtnl->rqueue_partial_size; i++) {
1224                         if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
1225                             rtnl->rbuffer->nlmsg_seq) {
1226                                 first = rtnl->rqueue_partial[i];
1227                                 break;
1228                         }
1229                 }
1230         }
1231
1232         for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len); new_msg = NLMSG_NEXT(new_msg, len)) {
1233                 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
1234                 const NLType *nl_type;
1235
1236                 if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
1237                         /* not broadcast and not for us */
1238                         continue;
1239
1240                 if (new_msg->nlmsg_type == NLMSG_NOOP)
1241                         /* silently drop noop messages */
1242                         continue;
1243
1244                 if (new_msg->nlmsg_type == NLMSG_DONE) {
1245                         /* finished reading multi-part message */
1246                         done = true;
1247                         break;
1248                 }
1249
1250                 /* check that we support this message type */
1251                 r = type_system_get_type(NULL, &nl_type, new_msg->nlmsg_type);
1252                 if (r < 0) {
1253                         if (r == -ENOTSUP)
1254                                 log_debug("sd-rtnl: ignored message with unknown type: %u",
1255                                           new_msg->nlmsg_type);
1256
1257                         continue;
1258                 }
1259
1260                 /* check that the size matches the message type */
1261                 if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size))
1262                         continue;
1263
1264                 r = message_new_empty(rtnl, &m);
1265                 if (r < 0)
1266                         return r;
1267
1268                 m->hdr = memdup(new_msg, new_msg->nlmsg_len);
1269                 if (!m->hdr)
1270                         return -ENOMEM;
1271
1272                 /* seal and parse the top-level message */
1273                 r = sd_rtnl_message_rewind(m);
1274                 if (r < 0)
1275                         return r;
1276
1277                 /* push the message onto the multi-part message stack */
1278                 if (first)
1279                         m->next = first;
1280                 first = m;
1281                 m = NULL;
1282         }
1283
1284         if (len)
1285                 log_debug("sd-rtnl: discarding %zu bytes of incoming message", len);
1286
1287         if (!first)
1288                 return 0;
1289
1290         if (!multi_part || done) {
1291                 /* we got a complete message, push it on the read queue */
1292                 r = rtnl_rqueue_make_room(rtnl);
1293                 if (r < 0)
1294                         return r;
1295
1296                 rtnl->rqueue[rtnl->rqueue_size ++] = first;
1297                 first = NULL;
1298
1299                 if (multi_part && (i < rtnl->rqueue_partial_size)) {
1300                         /* remove the message form the partial read queue */
1301                         memmove(rtnl->rqueue_partial + i,rtnl->rqueue_partial + i + 1,
1302                                 sizeof(sd_rtnl_message*) * (rtnl->rqueue_partial_size - i - 1));
1303                         rtnl->rqueue_partial_size --;
1304                 }
1305
1306                 return 1;
1307         } else {
1308                 /* we only got a partial multi-part message, push it on the
1309                    partial read queue */
1310                 if (i < rtnl->rqueue_partial_size) {
1311                         rtnl->rqueue_partial[i] = first;
1312                 } else {
1313                         r = rtnl_rqueue_partial_make_room(rtnl);
1314                         if (r < 0)
1315                                 return r;
1316
1317                         rtnl->rqueue_partial[rtnl->rqueue_partial_size ++] = first;
1318                 }
1319                 first = NULL;
1320
1321                 return 0;
1322         }
1323 }
1324
1325 int sd_rtnl_message_rewind(sd_rtnl_message *m) {
1326         const NLType *type;
1327         unsigned i;
1328         int r;
1329
1330         assert_return(m, -EINVAL);
1331
1332         /* don't allow appending to message once parsed */
1333         if (!m->sealed)
1334                 rtnl_message_seal(m);
1335
1336         for (i = 1; i <= m->n_containers; i++) {
1337                 free(m->rta_offset_tb[i]);
1338                 m->rta_offset_tb[i] = NULL;
1339                 m->rta_tb_size[i] = 0;
1340                 m->container_type_system[i] = NULL;
1341         }
1342
1343         m->n_containers = 0;
1344
1345         if (m->rta_offset_tb[0]) {
1346                 /* top-level attributes have already been parsed */
1347                 return 0;
1348         }
1349
1350         assert(m->hdr);
1351
1352         r = type_system_get_type(NULL, &type, m->hdr->nlmsg_type);
1353         if (r < 0)
1354                 return r;
1355
1356         if (type->type == NLA_NESTED) {
1357                 const NLTypeSystem *type_system = type->type_system;
1358
1359                 assert(type_system);
1360
1361                 m->container_type_system[0] = type_system;
1362
1363                 r = rtnl_message_parse(m,
1364                                        &m->rta_offset_tb[m->n_containers],
1365                                        &m->rta_tb_size[m->n_containers],
1366                                        type_system->max,
1367                                        (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) +
1368                                                         NLMSG_ALIGN(type->size)),
1369                                        NLMSG_PAYLOAD(m->hdr, type->size));
1370                 if (r < 0)
1371                         return r;
1372         }
1373
1374         return 0;
1375 }
1376
1377 void rtnl_message_seal(sd_rtnl_message *m) {
1378         assert(m);
1379         assert(!m->sealed);
1380
1381         m->sealed = true;
1382 }
1383
1384 sd_rtnl_message *sd_rtnl_message_next(sd_rtnl_message *m) {
1385         assert_return(m, NULL);
1386
1387         return m->next;
1388 }