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