chiark / gitweb /
fc71ed90183c4547a2ccbf604c6651c09f595c88
[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 #include <linux/netlink.h>
27 #include <linux/veth.h>
28 #include <linux/if.h>
29 #include <linux/ip.h>
30 #include <linux/if_tunnel.h>
31 #include <linux/if_bridge.h>
32
33 #include "util.h"
34 #include "refcnt.h"
35 #include "missing.h"
36
37 #include "sd-rtnl.h"
38 #include "rtnl-util.h"
39 #include "rtnl-internal.h"
40 #include "rtnl-types.h"
41
42 #define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->container_offsets[i]) : NULL)
43 #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
44
45 static int message_new_empty(sd_rtnl *rtnl, sd_rtnl_message **ret) {
46         sd_rtnl_message *m;
47
48         assert_return(ret, -EINVAL);
49
50         /* Note that 'rtnl' is curretly unused, if we start using it internally
51            we must take care to avoid problems due to mutual references between
52            busses and their queued messages. See sd-bus.
53          */
54
55         m = new0(sd_rtnl_message, 1);
56         if (!m)
57                 return -ENOMEM;
58
59         m->n_ref = REFCNT_INIT;
60
61         m->sealed = false;
62
63         *ret = m;
64
65         return 0;
66 }
67
68 int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t type) {
69         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
70         const NLType *nl_type;
71         size_t size;
72         int r;
73
74         r = type_system_get_type(NULL, &nl_type, type);
75         if (r < 0)
76                 return r;
77
78         assert(nl_type->type == NLA_NESTED);
79
80         r = message_new_empty(rtnl, &m);
81         if (r < 0)
82                 return r;
83
84         size = NLMSG_SPACE(nl_type->size);
85
86         assert(size >= sizeof(struct nlmsghdr));
87         m->hdr = malloc0(size);
88         if (!m->hdr)
89                 return -ENOMEM;
90
91         m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
92
93         m->container_type_system[0] = nl_type->type_system;
94         m->hdr->nlmsg_len = size;
95         m->hdr->nlmsg_type = type;
96
97         *ret = m;
98         m = NULL;
99
100         return 0;
101 }
102
103 int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
104         struct rtmsg *rtm;
105
106         assert_return(m, -EINVAL);
107         assert_return(m->hdr, -EINVAL);
108         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
109
110         rtm = NLMSG_DATA(m->hdr);
111
112         if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
113             (rtm->rtm_family == AF_INET6 && prefixlen > 128))
114                 return -ERANGE;
115
116         rtm->rtm_dst_len = prefixlen;
117
118         return 0;
119 }
120
121 int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
122         struct rtmsg *rtm;
123
124         assert_return(m, -EINVAL);
125         assert_return(m->hdr, -EINVAL);
126         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
127
128         rtm = NLMSG_DATA(m->hdr);
129
130         rtm->rtm_scope = scope;
131
132         return 0;
133 }
134
135 int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
136                               uint16_t nlmsg_type, unsigned char rtm_family) {
137         struct rtmsg *rtm;
138         int r;
139
140         assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL);
141         assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
142         assert_return(ret, -EINVAL);
143
144         r = message_new(rtnl, ret, nlmsg_type);
145         if (r < 0)
146                 return r;
147
148         if (nlmsg_type == RTM_NEWROUTE)
149                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
150
151         rtm = NLMSG_DATA((*ret)->hdr);
152
153         rtm->rtm_family = rtm_family;
154         rtm->rtm_scope = RT_SCOPE_UNIVERSE;
155         rtm->rtm_type = RTN_UNICAST;
156         rtm->rtm_table = RT_TABLE_MAIN;
157         rtm->rtm_protocol = RTPROT_BOOT;
158
159         return 0;
160 }
161
162 int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change) {
163         struct ifinfomsg *ifi;
164
165         assert_return(m, -EINVAL);
166         assert_return(m->hdr, -EINVAL);
167         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
168         assert_return(change, -EINVAL);
169
170         ifi = NLMSG_DATA(m->hdr);
171
172         ifi->ifi_flags = flags;
173         ifi->ifi_change = change;
174
175         return 0;
176 }
177
178 int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type) {
179         struct ifinfomsg *ifi;
180
181         assert_return(m, -EINVAL);
182         assert_return(m->hdr, -EINVAL);
183         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
184
185         ifi = NLMSG_DATA(m->hdr);
186
187         ifi->ifi_type = type;
188
189         return 0;
190 }
191
192 int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret,
193                              uint16_t nlmsg_type, int index) {
194         struct ifinfomsg *ifi;
195         int r;
196
197         assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
198         assert_return(nlmsg_type != RTM_DELLINK || index > 0, -EINVAL);
199         assert_return(ret, -EINVAL);
200
201         r = message_new(rtnl, ret, nlmsg_type);
202         if (r < 0)
203                 return r;
204
205         if (nlmsg_type == RTM_NEWLINK)
206                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
207
208         ifi = NLMSG_DATA((*ret)->hdr);
209
210         ifi->ifi_family = AF_UNSPEC;
211         ifi->ifi_index = index;
212
213         return 0;
214 }
215
216 int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
217         struct ifaddrmsg *ifa;
218
219         assert_return(m, -EINVAL);
220         assert_return(m->hdr, -EINVAL);
221         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
222
223         ifa = NLMSG_DATA(m->hdr);
224
225         if ((ifa->ifa_family == AF_INET && prefixlen > 32) ||
226             (ifa->ifa_family == AF_INET6 && prefixlen > 128))
227                 return -ERANGE;
228
229         ifa->ifa_prefixlen = prefixlen;
230
231         return 0;
232 }
233
234 int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags) {
235         struct ifaddrmsg *ifa;
236
237         assert_return(m, -EINVAL);
238         assert_return(m->hdr, -EINVAL);
239         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
240
241         ifa = NLMSG_DATA(m->hdr);
242
243         ifa->ifa_flags = flags;
244
245         return 0;
246 }
247
248 int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) {
249         struct ifaddrmsg *ifa;
250
251         assert_return(m, -EINVAL);
252         assert_return(m->hdr, -EINVAL);
253         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
254
255         ifa = NLMSG_DATA(m->hdr);
256
257         ifa->ifa_scope = scope;
258
259         return 0;
260 }
261
262 int sd_rtnl_message_addr_get_family(sd_rtnl_message *m, unsigned char *family) {
263         struct ifaddrmsg *ifa;
264
265         assert_return(m, -EINVAL);
266         assert_return(m->hdr, -EINVAL);
267         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
268         assert_return(family, -EINVAL);
269
270         ifa = NLMSG_DATA(m->hdr);
271
272         *family = ifa->ifa_family;
273
274         return 0;
275 }
276
277 int sd_rtnl_message_addr_get_scope(sd_rtnl_message *m, unsigned char *scope) {
278         struct ifaddrmsg *ifa;
279
280         assert_return(m, -EINVAL);
281         assert_return(m->hdr, -EINVAL);
282         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
283         assert_return(scope, -EINVAL);
284
285         ifa = NLMSG_DATA(m->hdr);
286
287         *scope = ifa->ifa_scope;
288
289         return 0;
290 }
291
292 int sd_rtnl_message_addr_get_flags(sd_rtnl_message *m, unsigned char *flags) {
293         struct ifaddrmsg *ifa;
294
295         assert_return(m, -EINVAL);
296         assert_return(m->hdr, -EINVAL);
297         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
298         assert_return(flags, -EINVAL);
299
300         ifa = NLMSG_DATA(m->hdr);
301
302         *flags = ifa->ifa_flags;
303
304         return 0;
305 }
306
307 int sd_rtnl_message_addr_get_ifindex(sd_rtnl_message *m, int *ifindex) {
308         struct ifaddrmsg *ifa;
309
310         assert_return(m, -EINVAL);
311         assert_return(m->hdr, -EINVAL);
312         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
313         assert_return(ifindex, -EINVAL);
314
315         ifa = NLMSG_DATA(m->hdr);
316
317         *ifindex = ifa->ifa_index;
318
319         return 0;
320 }
321
322 int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
323                              uint16_t nlmsg_type, int index,
324                              unsigned char family) {
325         struct ifaddrmsg *ifa;
326         int r;
327
328         assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
329         assert_return(index > 0, -EINVAL);
330         assert_return(family == AF_INET || family == AF_INET6, -EINVAL);
331         assert_return(ret, -EINVAL);
332
333         r = message_new(rtnl, ret, nlmsg_type);
334         if (r < 0)
335                 return r;
336
337         if (nlmsg_type == RTM_GETADDR && family == AF_INET)
338                 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
339
340         ifa = NLMSG_DATA((*ret)->hdr);
341
342         ifa->ifa_index = index;
343         ifa->ifa_family = family;
344         if (family == AF_INET)
345                 ifa->ifa_prefixlen = 32;
346         else if (family == AF_INET6)
347                 ifa->ifa_prefixlen = 128;
348
349         return 0;
350 }
351
352 int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret,
353                              int index, unsigned char family) {
354         int r;
355
356         r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family);
357         if (r < 0)
358                 return r;
359
360         (*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE;
361
362         return 0;
363 }
364
365 sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
366         if (m)
367                 assert_se(REFCNT_INC(m->n_ref) >= 2);
368
369         return m;
370 }
371
372 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
373         if (m && REFCNT_DEC(m->n_ref) <= 0) {
374                 unsigned i;
375
376                 free(m->hdr);
377
378                 for (i = 0; i <= m->n_containers; i++)
379                         free(m->rta_offset_tb[i]);
380
381                 free(m);
382         }
383
384         return NULL;
385 }
386
387 int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type) {
388         assert_return(m, -EINVAL);
389         assert_return(type, -EINVAL);
390
391         *type = m->hdr->nlmsg_type;
392
393         return 0;
394 }
395
396 int sd_rtnl_message_is_broadcast(sd_rtnl_message *m) {
397         assert_return(m, -EINVAL);
398
399         return !m->hdr->nlmsg_pid;
400 }
401
402 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex) {
403         struct ifinfomsg *ifi;
404
405         assert_return(m, -EINVAL);
406         assert_return(m->hdr, -EINVAL);
407         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
408         assert_return(ifindex, -EINVAL);
409
410         ifi = NLMSG_DATA(m->hdr);
411
412         *ifindex = ifi->ifi_index;
413
414         return 0;
415 }
416
417 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
418         struct ifinfomsg *ifi;
419
420         assert_return(m, -EINVAL);
421         assert_return(m->hdr, -EINVAL);
422         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
423         assert_return(flags, -EINVAL);
424
425         ifi = NLMSG_DATA(m->hdr);
426
427         *flags = ifi->ifi_flags;
428
429         return 0;
430 }
431
432 /* If successful the updated message will be correctly aligned, if
433    unsuccessful the old message is untouched. */
434 static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
435         uint32_t rta_length, message_length;
436         struct nlmsghdr *new_hdr;
437         struct rtattr *rta;
438         char *padding;
439         unsigned i;
440
441         assert(m);
442         assert(m->hdr);
443         assert(!m->sealed);
444         assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
445         assert(!data || data_length > 0);
446         assert(data || m->n_containers < RTNL_CONTAINER_DEPTH);
447
448         /* get the size of the new rta attribute (with padding at the end) */
449         rta_length = RTA_LENGTH(data_length);
450
451         /* get the new message size (with padding at the end) */
452         message_length = m->hdr->nlmsg_len + RTA_ALIGN(rta_length);
453
454         /* realloc to fit the new attribute */
455         new_hdr = realloc(m->hdr, message_length);
456         if (!new_hdr)
457                 return -ENOMEM;
458         m->hdr = new_hdr;
459
460         /* get pointer to the attribute we are about to add */
461         rta = (struct rtattr *) ((uint8_t *) m->hdr + m->hdr->nlmsg_len);
462
463         /* if we are inside containers, extend them */
464         for (i = 0; i < m->n_containers; i++)
465                 GET_CONTAINER(m, i)->rta_len += message_length - m->hdr->nlmsg_len;
466
467         /* fill in the attribute */
468         rta->rta_type = type;
469         rta->rta_len = rta_length;
470         if (!data) {
471                 //TODO: simply return this value rather than check for !data
472                 /* this is the start of a new container */
473                 m->container_offsets[m->n_containers ++] = m->hdr->nlmsg_len;
474         } else {
475                 /* we don't deal with the case where the user lies about the type
476                  * and gives us too little data (so don't do that)
477                 */
478                 padding = mempcpy(RTA_DATA(rta), data, data_length);
479                 /* make sure also the padding at the end of the message is initialized */
480                 memzero(padding,
481                         (uint8_t *) m->hdr + message_length - (uint8_t *) padding);
482         }
483
484         /* update message size */
485         m->hdr->nlmsg_len = message_length;
486
487         return 0;
488 }
489
490 static int message_attribute_has_type(sd_rtnl_message *m, uint16_t attribute_type, uint16_t data_type) {
491         const NLType *type;
492         int r;
493
494         r = type_system_get_type(m->container_type_system[m->n_containers], &type, attribute_type);
495         if (r < 0)
496                 return r;
497
498         if (type->type != data_type)
499                 return -EINVAL;
500
501         return type->size;
502 }
503
504 int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
505         size_t length, size;
506         int r;
507
508         assert_return(m, -EINVAL);
509         assert_return(!m->sealed, -EPERM);
510         assert_return(data, -EINVAL);
511
512         r = message_attribute_has_type(m, type, NLA_STRING);
513         if (r < 0)
514                 return r;
515         else
516                 size = (size_t)r;
517
518         if (size) {
519                 length = strnlen(data, size);
520                 if (length >= size)
521                         return -EINVAL;
522         } else
523                 length = strlen(data);
524
525         r = add_rtattr(m, type, data, length + 1);
526         if (r < 0)
527                 return r;
528
529         return 0;
530 }
531
532 int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data) {
533         int r;
534
535         assert_return(m, -EINVAL);
536         assert_return(!m->sealed, -EPERM);
537
538         r = message_attribute_has_type(m, type, NLA_U8);
539         if (r < 0)
540                 return r;
541
542         r = add_rtattr(m, type, &data, sizeof(uint8_t));
543         if (r < 0)
544                 return r;
545
546         return 0;
547 }
548
549
550 int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t data) {
551         int r;
552
553         assert_return(m, -EINVAL);
554         assert_return(!m->sealed, -EPERM);
555
556         r = message_attribute_has_type(m, type, NLA_U16);
557         if (r < 0)
558                 return r;
559
560         r = add_rtattr(m, type, &data, sizeof(uint16_t));
561         if (r < 0)
562                 return r;
563
564         return 0;
565 }
566
567 int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data) {
568         int r;
569
570         assert_return(m, -EINVAL);
571         assert_return(!m->sealed, -EPERM);
572
573         r = message_attribute_has_type(m, type, NLA_U32);
574         if (r < 0)
575                 return r;
576
577         r = add_rtattr(m, type, &data, sizeof(uint32_t));
578         if (r < 0)
579                 return r;
580
581         return 0;
582 }
583
584 int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data) {
585         int r;
586
587         assert_return(m, -EINVAL);
588         assert_return(!m->sealed, -EPERM);
589         assert_return(data, -EINVAL);
590
591         r = message_attribute_has_type(m, type, NLA_IN_ADDR);
592         if (r < 0)
593                 return r;
594
595         r = add_rtattr(m, type, data, sizeof(struct in_addr));
596         if (r < 0)
597                 return r;
598
599         return 0;
600 }
601
602 int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data) {
603         int r;
604
605         assert_return(m, -EINVAL);
606         assert_return(!m->sealed, -EPERM);
607         assert_return(data, -EINVAL);
608
609         r = message_attribute_has_type(m, type, NLA_IN_ADDR);
610         if (r < 0)
611                 return r;
612
613         r = add_rtattr(m, type, data, sizeof(struct in6_addr));
614         if (r < 0)
615                 return r;
616
617         return 0;
618 }
619
620 int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data) {
621         int r;
622
623         assert_return(m, -EINVAL);
624         assert_return(!m->sealed, -EPERM);
625         assert_return(data, -EINVAL);
626
627         r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
628         if (r < 0)
629                 return r;
630
631         r = add_rtattr(m, type, data, ETH_ALEN);
632         if (r < 0)
633                 return r;
634
635         return 0;
636 }
637
638 int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short type, const struct ifa_cacheinfo *info) {
639         int r;
640
641         assert_return(m, -EINVAL);
642         assert_return(!m->sealed, -EPERM);
643         assert_return(info, -EINVAL);
644
645         r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
646         if (r < 0)
647                 return r;
648
649         r = add_rtattr(m, type, info, sizeof(struct ifa_cacheinfo));
650         if (r < 0)
651                 return r;
652
653         return 0;
654 }
655
656 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
657         size_t size;
658         int r;
659
660         assert_return(m, -EINVAL);
661         assert_return(!m->sealed, -EPERM);
662
663         r = message_attribute_has_type(m, type, NLA_NESTED);
664         if (r < 0)
665                 return r;
666         else
667                 size = (size_t)r;
668
669         r = type_system_get_type_system(m->container_type_system[m->n_containers],
670                                         &m->container_type_system[m->n_containers + 1],
671                                         type);
672         if (r < 0)
673                 return r;
674
675         r = add_rtattr(m, type, NULL, size);
676         if (r < 0)
677                 return r;
678
679         return 0;
680 }
681
682 int sd_rtnl_message_open_container_union(sd_rtnl_message *m, unsigned short type, const char *key) {
683         const NLTypeSystemUnion *type_system_union;
684         int r;
685
686         assert_return(m, -EINVAL);
687         assert_return(!m->sealed, -EPERM);
688
689         r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type);
690         if (r < 0)
691                 return r;
692
693         r = type_system_union_get_type_system(type_system_union,
694                                               &m->container_type_system[m->n_containers + 1],
695                                               key);
696         if (r < 0)
697                 return r;
698
699         r = sd_rtnl_message_append_string(m, type_system_union->match, key);
700         if (r < 0)
701                 return r;
702
703         /* do we evere need non-null size */
704         r = add_rtattr(m, type, NULL, 0);
705         if (r < 0)
706                 return r;
707
708         return 0;
709 }
710
711
712 int sd_rtnl_message_close_container(sd_rtnl_message *m) {
713         assert_return(m, -EINVAL);
714         assert_return(!m->sealed, -EPERM);
715         assert_return(m->n_containers > 0, -EINVAL);
716
717         m->container_type_system[m->n_containers] = NULL;
718         m->n_containers --;
719
720         return 0;
721 }
722
723 int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
724         struct rtattr *rta;
725
726         assert_return(m, -EINVAL);
727         assert_return(m->sealed, -EPERM);
728         assert_return(data, -EINVAL);
729         assert(m->n_containers <= RTNL_CONTAINER_DEPTH);
730         assert(m->rta_offset_tb[m->n_containers]);
731         assert(type < m->rta_tb_size[m->n_containers]);
732
733         if(!m->rta_offset_tb[m->n_containers][type])
734                 return -ENODATA;
735
736         rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[m->n_containers][type]);
737
738         *data = RTA_DATA(rta);
739
740         return RTA_PAYLOAD(rta);
741 }
742
743 int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, char **data) {
744         int r;
745         void *attr_data;
746
747         r = message_attribute_has_type(m, type, NLA_STRING);
748         if (r < 0)
749                 return r;
750
751         r = rtnl_message_read_internal(m, type, &attr_data);
752         if (r < 0)
753                 return r;
754         else if (strnlen(attr_data, r) >= (size_t) r)
755                 return -EIO;
756
757         *data = (char *) attr_data;
758
759         return 0;
760 }
761
762 int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data) {
763         int r;
764         void *attr_data;
765
766         r = message_attribute_has_type(m, type, NLA_U8);
767         if (r < 0)
768                 return r;
769
770         r = rtnl_message_read_internal(m, type, &attr_data);
771         if (r < 0)
772                 return r;
773         else if ((size_t) r < sizeof(uint8_t))
774                 return -EIO;
775
776         *data = *(uint8_t *) attr_data;
777
778         return 0;
779 }
780
781 int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data) {
782         int r;
783         void *attr_data;
784
785         r = message_attribute_has_type(m, type, NLA_U16);
786         if (r < 0)
787                 return r;
788
789         r = rtnl_message_read_internal(m, type, &attr_data);
790         if (r < 0)
791                 return r;
792         else if ((size_t) r < sizeof(uint16_t))
793                 return -EIO;
794
795         *data = *(uint16_t *) attr_data;
796
797         return 0;
798 }
799
800 int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data) {
801         int r;
802         void *attr_data;
803
804         r = message_attribute_has_type(m, type, NLA_U32);
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 ((size_t)r < sizeof(uint32_t))
812                 return -EIO;
813
814         *data = *(uint32_t *) attr_data;
815
816         return 0;
817 }
818
819 int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data) {
820         int r;
821         void *attr_data;
822
823         r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
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(struct ether_addr))
831                 return -EIO;
832
833         memcpy(data, attr_data, sizeof(struct ether_addr));
834
835         return 0;
836 }
837
838 int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, struct ifa_cacheinfo *info) {
839         int r;
840         void *attr_data;
841
842         r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
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(struct ifa_cacheinfo))
850                 return -EIO;
851
852         memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
853
854         return 0;
855 }
856
857 int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
858         int r;
859         void *attr_data;
860
861         r = message_attribute_has_type(m, type, NLA_IN_ADDR);
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(struct in_addr))
869                 return -EIO;
870
871         memcpy(data, attr_data, sizeof(struct in_addr));
872
873         return 0;
874 }
875
876 int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data) {
877         int r;
878         void *attr_data;
879
880         r = message_attribute_has_type(m, type, NLA_IN_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 in6_addr))
888                 return -EIO;
889
890         memcpy(data, attr_data, sizeof(struct in6_addr));
891
892         return 0;
893 }
894
895 int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type) {
896         const NLType *nl_type;
897         const NLTypeSystem *type_system;
898         void *container;
899         size_t size;
900         int r;
901
902         assert_return(m, -EINVAL);
903         assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
904
905         r = type_system_get_type(m->container_type_system[m->n_containers],
906                                  &nl_type,
907                                  type);
908         if (r < 0)
909                 return r;
910
911         if (nl_type->type == NLA_NESTED) {
912                 r = type_system_get_type_system(m->container_type_system[m->n_containers],
913                                                 &type_system,
914                                                 type);
915                 if (r < 0)
916                         return r;
917         } else if (nl_type->type == NLA_UNION) {
918                 const NLTypeSystemUnion *type_system_union;
919                 char *key;
920
921                 r = type_system_get_type_system_union(m->container_type_system[m->n_containers],
922                                                       &type_system_union,
923                                                       type);
924                 if (r < 0)
925                         return r;
926
927                 r = sd_rtnl_message_read_string(m, type_system_union->match, &key);
928                 if (r < 0)
929                         return r;
930
931                 r = type_system_union_get_type_system(type_system_union,
932                                                       &type_system,
933                                                       key);
934                 if (r < 0)
935                         return r;
936         } else
937                 return -EINVAL;
938
939         r = rtnl_message_read_internal(m, type, &container);
940         if (r < 0)
941                 return r;
942         else
943                 size = (size_t)r;
944
945         m->n_containers ++;
946
947         r = rtnl_message_parse(m,
948                                &m->rta_offset_tb[m->n_containers],
949                                &m->rta_tb_size[m->n_containers],
950                                type_system->max,
951                                container,
952                                size);
953         if (r < 0) {
954                 m->n_containers --;
955                 return r;
956         }
957
958         m->container_type_system[m->n_containers] = type_system;
959
960         return 0;
961 }
962
963 int sd_rtnl_message_exit_container(sd_rtnl_message *m) {
964         assert_return(m, -EINVAL);
965         assert_return(m->sealed, -EINVAL);
966         assert_return(m->n_containers > 0, -EINVAL);
967
968         free(m->rta_offset_tb[m->n_containers]);
969         m->rta_offset_tb[m->n_containers] = NULL;
970         m->container_type_system[m->n_containers] = NULL;
971
972         m->n_containers --;
973
974         return 0;
975 }
976
977 uint32_t rtnl_message_get_serial(sd_rtnl_message *m) {
978         assert(m);
979         assert(m->hdr);
980
981         return m->hdr->nlmsg_seq;
982 }
983
984 int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
985         struct nlmsgerr *err;
986
987         assert_return(m, -EINVAL);
988         assert_return(m->hdr, -EINVAL);
989
990         if (m->hdr->nlmsg_type != NLMSG_ERROR)
991                 return 0;
992
993         err = NLMSG_DATA(m->hdr);
994
995         return err->error;
996 }
997
998 static int message_receive_need(sd_rtnl *rtnl, size_t *need) {
999         assert(rtnl);
1000         assert(need);
1001
1002         /* ioctl(rtnl->fd, FIONREAD, &need)
1003            Does not appear to work on netlink sockets. libnl uses
1004            MSG_PEEK instead. I don't know if that is worth the
1005            extra roundtrip.
1006
1007            For now we simply use the maximum message size the kernel
1008            may use (NLMSG_GOODSIZE), and then realloc to the actual
1009            size after reading the message (hence avoiding huge memory
1010            usage in case many small messages are kept around) */
1011         *need = page_size();
1012         if (*need > 8192UL)
1013                 *need = 8192UL;
1014
1015         return 0;
1016 }
1017
1018 int rtnl_message_parse(sd_rtnl_message *m,
1019                        size_t **rta_offset_tb,
1020                        unsigned short *rta_tb_size,
1021                        int max,
1022                        struct rtattr *rta,
1023                        unsigned int rt_len) {
1024         unsigned short type;
1025         size_t *tb;
1026
1027         tb = new0(size_t, max + 1);
1028         if(!tb)
1029                 return -ENOMEM;
1030
1031         *rta_tb_size = max + 1;
1032
1033         for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
1034                 type = rta->rta_type;
1035
1036                 /* if the kernel is newer than the headers we used
1037                    when building, we ignore out-of-range attributes
1038                  */
1039                 if (type > max)
1040                         continue;
1041
1042                 if (tb[type])
1043                         log_debug("rtnl: message parse - overwriting repeated attribute");
1044
1045                 tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
1046         }
1047
1048         *rta_offset_tb = tb;
1049
1050         return 0;
1051 }
1052
1053 /* returns the number of bytes sent, or a negative error code */
1054 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
1055         union {
1056                 struct sockaddr sa;
1057                 struct sockaddr_nl nl;
1058         } addr = {
1059                 .nl.nl_family = AF_NETLINK,
1060         };
1061         ssize_t k;
1062
1063         assert(nl);
1064         assert(m);
1065         assert(m->hdr);
1066
1067         k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
1068                         0, &addr.sa, sizeof(addr));
1069         if (k < 0)
1070                 return (errno == EAGAIN) ? 0 : -errno;
1071
1072         return k;
1073 }
1074
1075 /* On success, the number of bytes received is returned and *ret points to the received message
1076  * which has a valid header and the correct size.
1077  * If nothing useful was received 0 is returned.
1078  * On failure, a negative error code is returned.
1079  */
1080 int socket_read_message(sd_rtnl *rtnl) {
1081         _cleanup_free_ void *buffer = NULL;
1082         uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred))];
1083         struct iovec iov = {};
1084         struct msghdr msg = {
1085                 .msg_iov = &iov,
1086                 .msg_iovlen = 1,
1087                 .msg_control = cred_buffer,
1088                 .msg_controllen = sizeof(cred_buffer),
1089         };
1090         struct cmsghdr *cmsg;
1091         bool auth = false;
1092         struct nlmsghdr *new_msg;
1093         size_t need, len;
1094         int r, ret = 0;
1095
1096         assert(rtnl);
1097
1098         r = message_receive_need(rtnl, &need);
1099         if (r < 0)
1100                 return r;
1101
1102         buffer = malloc0(need);
1103         if (!buffer)
1104                 return -ENOMEM;
1105
1106         iov.iov_base = buffer;
1107         iov.iov_len = need;
1108
1109         r = recvmsg(rtnl->fd, &msg, 0);
1110         if (r < 0)
1111                 /* no data */
1112                 return (errno == EAGAIN) ? 0 : -errno;
1113         else if (r == 0)
1114                 /* connection was closed by the kernel */
1115                 return -ECONNRESET;
1116         else
1117                 len = (size_t)r;
1118
1119         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1120                 if (cmsg->cmsg_level == SOL_SOCKET &&
1121                     cmsg->cmsg_type == SCM_CREDENTIALS &&
1122                     cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1123                         struct ucred *ucred = (void *)CMSG_DATA(cmsg);
1124
1125                         /* from the kernel */
1126                         if (ucred->uid == 0 && ucred->pid == 0) {
1127                                 auth = true;
1128                                 break;
1129                         }
1130                 }
1131         }
1132
1133         if (!auth)
1134                 /* not from the kernel, ignore */
1135                 return 0;
1136
1137         for (new_msg = buffer; NLMSG_OK(new_msg, len); new_msg = NLMSG_NEXT(new_msg, len)) {
1138                 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
1139                 const NLType *nl_type;
1140
1141                 if (new_msg->nlmsg_pid && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
1142                         /* not broadcast and not for us */
1143                         continue;
1144
1145                 /* silently drop noop messages */
1146                 if (new_msg->nlmsg_type == NLMSG_NOOP)
1147                         continue;
1148
1149                 /* check that we support this message type */
1150                 r = type_system_get_type(NULL, &nl_type, new_msg->nlmsg_type);
1151                 if (r < 0) {
1152                         if (r == -ENOTSUP)
1153                                 log_debug("sd-rtnl: ignored message with unknown type: %u",
1154                                           new_msg->nlmsg_type);
1155
1156                         continue;
1157                 }
1158
1159                 /* check that the size matches the message type */
1160                 if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size))
1161                         continue;
1162
1163                 r = message_new_empty(rtnl, &m);
1164                 if (r < 0)
1165                         return r;
1166
1167                 m->hdr = memdup(new_msg, new_msg->nlmsg_len);
1168                 if (!m->hdr)
1169                         return -ENOMEM;
1170
1171                 /* seal and parse the top-level message */
1172                 r = sd_rtnl_message_rewind(m);
1173                 if (r < 0)
1174                         return r;
1175
1176                 r = rtnl_rqueue_make_room(rtnl);
1177                 if (r < 0)
1178                         return r;
1179
1180                 rtnl->rqueue[rtnl->rqueue_size ++] = m;
1181                 m = NULL;
1182                 ret += new_msg->nlmsg_len;
1183
1184                 /* reached end of multi-part message, or not a multi-part
1185                    message at all */
1186                 if (new_msg->nlmsg_type == NLMSG_DONE ||
1187                     !(new_msg->nlmsg_flags & NLM_F_MULTI))
1188                         break;
1189         }
1190
1191         return ret;
1192 }
1193
1194 int sd_rtnl_message_rewind(sd_rtnl_message *m) {
1195         const NLType *type;
1196         unsigned i;
1197         int r;
1198
1199         assert_return(m, -EINVAL);
1200
1201         /* don't allow appending to message once parsed */
1202         if (!m->sealed)
1203                 rtnl_message_seal(m);
1204
1205         for (i = 1; i <= m->n_containers; i++) {
1206                 free(m->rta_offset_tb[i]);
1207                 m->rta_offset_tb[i] = NULL;
1208                 m->rta_tb_size[i] = 0;
1209                 m->container_type_system[i] = NULL;
1210         }
1211
1212         m->n_containers = 0;
1213
1214         if (m->rta_offset_tb[0]) {
1215                 /* top-level attributes have already been parsed */
1216                 return 0;
1217         }
1218
1219         assert(m->hdr);
1220
1221         r = type_system_get_type(NULL, &type, m->hdr->nlmsg_type);
1222         if (r < 0)
1223                 return r;
1224
1225         if (type->type == NLA_NESTED) {
1226                 const NLTypeSystem *type_system = type->type_system;
1227
1228                 assert(type_system);
1229
1230                 m->container_type_system[0] = type_system;
1231
1232                 r = rtnl_message_parse(m,
1233                                        &m->rta_offset_tb[m->n_containers],
1234                                        &m->rta_tb_size[m->n_containers],
1235                                        type_system->max,
1236                                        (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) +
1237                                                         NLMSG_ALIGN(type->size)),
1238                                        NLMSG_PAYLOAD(m->hdr, type->size));
1239                 if (r < 0)
1240                         return r;
1241         }
1242
1243         return 0;
1244 }
1245
1246 void rtnl_message_seal(sd_rtnl_message *m) {
1247         assert(m);
1248         assert(!m->sealed);
1249
1250         m->sealed = true;
1251 }