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