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