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