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