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