chiark / gitweb /
refcnt: refcnt is unsigned, fix comparisons
[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         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->pid == 0)
1367                                 auth = true;
1368                         else
1369                                 log_debug("rtnl: ignoring message from pid %u", 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                 if (peek) {
1383                         /* drop the message */
1384                         r = recvmsg(fd, &msg, 0);
1385                         if (r < 0)
1386                                 return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
1387                 }
1388
1389                 return 0;
1390         }
1391
1392         if (group)
1393                 *_group = group;
1394
1395         return r;
1396 }
1397
1398 /* On success, the number of bytes received is returned and *ret points to the received message
1399  * which has a valid header and the correct size.
1400  * If nothing useful was received 0 is returned.
1401  * On failure, a negative error code is returned.
1402  */
1403 int socket_read_message(sd_rtnl *rtnl) {
1404         _cleanup_rtnl_message_unref_ sd_rtnl_message *first = NULL;
1405         struct iovec iov = {};
1406         uint32_t group = 0;
1407         bool multi_part = false, done = false;
1408         struct nlmsghdr *new_msg;
1409         size_t len;
1410         int r;
1411         unsigned i = 0;
1412
1413         assert(rtnl);
1414         assert(rtnl->rbuffer);
1415         assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
1416
1417         /* read nothing, just get the pending message size */
1418         r = socket_recv_message(rtnl->fd, &iov, &group, true);
1419         if (r <= 0)
1420                 return r;
1421         else
1422                 len = (size_t)r;
1423
1424         /* make room for the pending message */
1425         if (!greedy_realloc((void **)&rtnl->rbuffer,
1426                             &rtnl->rbuffer_allocated,
1427                             len, sizeof(uint8_t)))
1428                 return -ENOMEM;
1429
1430         iov.iov_base = rtnl->rbuffer;
1431         iov.iov_len = rtnl->rbuffer_allocated;
1432
1433         /* read the pending message */
1434         r = socket_recv_message(rtnl->fd, &iov, &group, false);
1435         if (r <= 0)
1436                 return r;
1437         else
1438                 len = (size_t)r;
1439
1440         if (len > rtnl->rbuffer_allocated)
1441                 /* message did not fit in read buffer */
1442                 return -EIO;
1443
1444         if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
1445                 multi_part = true;
1446
1447                 for (i = 0; i < rtnl->rqueue_partial_size; i++) {
1448                         if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
1449                             rtnl->rbuffer->nlmsg_seq) {
1450                                 first = rtnl->rqueue_partial[i];
1451                                 break;
1452                         }
1453                 }
1454         }
1455
1456         for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) {
1457                 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
1458                 const NLType *nl_type;
1459
1460                 if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
1461                         /* not broadcast and not for us */
1462                         continue;
1463
1464                 if (new_msg->nlmsg_type == NLMSG_NOOP)
1465                         /* silently drop noop messages */
1466                         continue;
1467
1468                 if (new_msg->nlmsg_type == NLMSG_DONE) {
1469                         /* finished reading multi-part message */
1470                         done = true;
1471
1472                         continue;
1473                 }
1474
1475                 /* check that we support this message type */
1476                 r = type_system_get_type(NULL, &nl_type, new_msg->nlmsg_type);
1477                 if (r < 0) {
1478                         if (r == -ENOTSUP)
1479                                 log_debug("sd-rtnl: ignored message with unknown type: %u",
1480                                           new_msg->nlmsg_type);
1481
1482                         continue;
1483                 }
1484
1485                 /* check that the size matches the message type */
1486                 if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size)) {
1487                         log_debug("sd-rtnl: message larger than expected, dropping");
1488                         continue;
1489                 }
1490
1491                 r = message_new_empty(rtnl, &m);
1492                 if (r < 0)
1493                         return r;
1494
1495                 m->hdr = memdup(new_msg, new_msg->nlmsg_len);
1496                 if (!m->hdr)
1497                         return -ENOMEM;
1498
1499                 /* seal and parse the top-level message */
1500                 r = sd_rtnl_message_rewind(m);
1501                 if (r < 0)
1502                         return r;
1503
1504                 /* push the message onto the multi-part message stack */
1505                 if (first)
1506                         m->next = first;
1507                 first = m;
1508                 m = NULL;
1509         }
1510
1511         if (len)
1512                 log_debug("sd-rtnl: discarding %zu bytes of incoming message", len);
1513
1514         if (!first)
1515                 return 0;
1516
1517         if (!multi_part || done) {
1518                 /* we got a complete message, push it on the read queue */
1519                 r = rtnl_rqueue_make_room(rtnl);
1520                 if (r < 0)
1521                         return r;
1522
1523                 rtnl->rqueue[rtnl->rqueue_size ++] = first;
1524                 first = NULL;
1525
1526                 if (multi_part && (i < rtnl->rqueue_partial_size)) {
1527                         /* remove the message form the partial read queue */
1528                         memmove(rtnl->rqueue_partial + i,rtnl->rqueue_partial + i + 1,
1529                                 sizeof(sd_rtnl_message*) * (rtnl->rqueue_partial_size - i - 1));
1530                         rtnl->rqueue_partial_size --;
1531                 }
1532
1533                 return 1;
1534         } else {
1535                 /* we only got a partial multi-part message, push it on the
1536                    partial read queue */
1537                 if (i < rtnl->rqueue_partial_size) {
1538                         rtnl->rqueue_partial[i] = first;
1539                 } else {
1540                         r = rtnl_rqueue_partial_make_room(rtnl);
1541                         if (r < 0)
1542                                 return r;
1543
1544                         rtnl->rqueue_partial[rtnl->rqueue_partial_size ++] = first;
1545                 }
1546                 first = NULL;
1547
1548                 return 0;
1549         }
1550 }
1551
1552 int sd_rtnl_message_rewind(sd_rtnl_message *m) {
1553         const NLType *type;
1554         unsigned i;
1555         int r;
1556
1557         assert_return(m, -EINVAL);
1558
1559         /* don't allow appending to message once parsed */
1560         if (!m->sealed)
1561                 rtnl_message_seal(m);
1562
1563         for (i = 1; i <= m->n_containers; i++) {
1564                 free(m->rta_offset_tb[i]);
1565                 m->rta_offset_tb[i] = NULL;
1566                 m->rta_tb_size[i] = 0;
1567                 m->container_type_system[i] = NULL;
1568         }
1569
1570         m->n_containers = 0;
1571
1572         if (m->rta_offset_tb[0]) {
1573                 /* top-level attributes have already been parsed */
1574                 return 0;
1575         }
1576
1577         assert(m->hdr);
1578
1579         r = type_system_get_type(NULL, &type, m->hdr->nlmsg_type);
1580         if (r < 0)
1581                 return r;
1582
1583         if (type->type == NLA_NESTED) {
1584                 const NLTypeSystem *type_system = type->type_system;
1585
1586                 assert(type_system);
1587
1588                 m->container_type_system[0] = type_system;
1589
1590                 r = rtnl_message_parse(m,
1591                                        &m->rta_offset_tb[m->n_containers],
1592                                        &m->rta_tb_size[m->n_containers],
1593                                        type_system->max,
1594                                        (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) +
1595                                                         NLMSG_ALIGN(type->size)),
1596                                        NLMSG_PAYLOAD(m->hdr, type->size));
1597                 if (r < 0)
1598                         return r;
1599         }
1600
1601         return 0;
1602 }
1603
1604 void rtnl_message_seal(sd_rtnl_message *m) {
1605         assert(m);
1606         assert(!m->sealed);
1607
1608         m->sealed = true;
1609 }
1610
1611 sd_rtnl_message *sd_rtnl_message_next(sd_rtnl_message *m) {
1612         assert_return(m, NULL);
1613
1614         return m->next;
1615 }