1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
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.
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.
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/>.
22 #include <netinet/in.h>
23 #include <netinet/ether.h>
26 #include <linux/netlink.h>
27 #include <linux/veth.h>
30 #include <linux/if_tunnel.h>
31 #include <linux/if_bridge.h>
38 #include "rtnl-util.h"
39 #include "rtnl-internal.h"
40 #include "rtnl-types.h"
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;
45 static int message_new_empty(sd_rtnl *rtnl, sd_rtnl_message **ret) {
48 assert_return(ret, -EINVAL);
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.
55 m = new0(sd_rtnl_message, 1);
59 m->n_ref = REFCNT_INIT;
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;
74 r = type_system_get_type(NULL, &nl_type, type);
78 assert(nl_type->type == NLA_NESTED);
80 r = message_new_empty(rtnl, &m);
84 size = NLMSG_SPACE(nl_type->size);
86 assert(size >= sizeof(struct nlmsghdr));
87 m->hdr = malloc0(size);
91 m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
93 m->container_type_system[0] = nl_type->type_system;
94 m->hdr->nlmsg_len = size;
95 m->hdr->nlmsg_type = type;
103 int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
106 assert_return(m, -EINVAL);
107 assert_return(m->hdr, -EINVAL);
108 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
110 rtm = NLMSG_DATA(m->hdr);
112 if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
113 (rtm->rtm_family == AF_INET6 && prefixlen > 128))
116 rtm->rtm_dst_len = prefixlen;
121 int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
124 assert_return(m, -EINVAL);
125 assert_return(m->hdr, -EINVAL);
126 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
128 rtm = NLMSG_DATA(m->hdr);
130 rtm->rtm_scope = scope;
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) {
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);
145 r = message_new(rtnl, ret, nlmsg_type);
149 if (nlmsg_type == RTM_NEWROUTE)
150 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
152 rtm = NLMSG_DATA((*ret)->hdr);
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;
163 int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change) {
164 struct ifinfomsg *ifi;
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);
171 ifi = NLMSG_DATA(m->hdr);
173 ifi->ifi_flags = flags;
174 ifi->ifi_change = change;
179 int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type) {
180 struct ifinfomsg *ifi;
182 assert_return(m, -EINVAL);
183 assert_return(m->hdr, -EINVAL);
184 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
186 ifi = NLMSG_DATA(m->hdr);
188 ifi->ifi_type = type;
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;
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);
202 r = message_new(rtnl, ret, nlmsg_type);
206 if (nlmsg_type == RTM_NEWLINK)
207 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
209 ifi = NLMSG_DATA((*ret)->hdr);
211 ifi->ifi_family = AF_UNSPEC;
212 ifi->ifi_index = index;
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,
226 m->hdr->nlmsg_flags |= NLM_F_DUMP;
228 m->hdr->nlmsg_flags &= ~NLM_F_DUMP;
233 int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
234 struct ifaddrmsg *ifa;
236 assert_return(m, -EINVAL);
237 assert_return(m->hdr, -EINVAL);
238 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
240 ifa = NLMSG_DATA(m->hdr);
242 if ((ifa->ifa_family == AF_INET && prefixlen > 32) ||
243 (ifa->ifa_family == AF_INET6 && prefixlen > 128))
246 ifa->ifa_prefixlen = prefixlen;
251 int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags) {
252 struct ifaddrmsg *ifa;
254 assert_return(m, -EINVAL);
255 assert_return(m->hdr, -EINVAL);
256 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
258 ifa = NLMSG_DATA(m->hdr);
260 ifa->ifa_flags = flags;
265 int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) {
266 struct ifaddrmsg *ifa;
268 assert_return(m, -EINVAL);
269 assert_return(m->hdr, -EINVAL);
270 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
272 ifa = NLMSG_DATA(m->hdr);
274 ifa->ifa_scope = scope;
279 int sd_rtnl_message_addr_get_family(sd_rtnl_message *m, int *family) {
280 struct ifaddrmsg *ifa;
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);
287 ifa = NLMSG_DATA(m->hdr);
289 *family = ifa->ifa_family;
294 int sd_rtnl_message_addr_get_prefixlen(sd_rtnl_message *m, unsigned char *prefixlen) {
295 struct ifaddrmsg *ifa;
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);
302 ifa = NLMSG_DATA(m->hdr);
304 *prefixlen = ifa->ifa_prefixlen;
309 int sd_rtnl_message_addr_get_scope(sd_rtnl_message *m, unsigned char *scope) {
310 struct ifaddrmsg *ifa;
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);
317 ifa = NLMSG_DATA(m->hdr);
319 *scope = ifa->ifa_scope;
324 int sd_rtnl_message_addr_get_flags(sd_rtnl_message *m, unsigned char *flags) {
325 struct ifaddrmsg *ifa;
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);
332 ifa = NLMSG_DATA(m->hdr);
334 *flags = ifa->ifa_flags;
339 int sd_rtnl_message_addr_get_ifindex(sd_rtnl_message *m, int *ifindex) {
340 struct ifaddrmsg *ifa;
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);
347 ifa = NLMSG_DATA(m->hdr);
349 *ifindex = ifa->ifa_index;
354 int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
355 uint16_t nlmsg_type, int index,
357 struct ifaddrmsg *ifa;
360 assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
361 assert_return((nlmsg_type == RTM_GETADDR && index == 0) ||
363 assert_return((nlmsg_type == RTM_GETADDR && family == AF_UNSPEC) ||
364 family == AF_INET || family == AF_INET6, -EINVAL);
365 assert_return(ret, -EINVAL);
367 r = message_new(rtnl, ret, nlmsg_type);
371 if (nlmsg_type == RTM_GETADDR)
372 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
374 ifa = NLMSG_DATA((*ret)->hdr);
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;
386 int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret,
387 int index, int family) {
390 r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family);
394 (*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE;
399 sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
401 assert_se(REFCNT_INC(m->n_ref) >= 2);
406 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
407 if (m && REFCNT_DEC(m->n_ref) <= 0) {
412 for (i = 0; i <= m->n_containers; i++)
413 free(m->rta_offset_tb[i]);
415 sd_rtnl_message_unref(m->next);
423 int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type) {
424 assert_return(m, -EINVAL);
425 assert_return(type, -EINVAL);
427 *type = m->hdr->nlmsg_type;
432 int sd_rtnl_message_is_broadcast(sd_rtnl_message *m) {
433 assert_return(m, -EINVAL);
435 return !m->hdr->nlmsg_pid;
438 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex) {
439 struct ifinfomsg *ifi;
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);
446 ifi = NLMSG_DATA(m->hdr);
448 *ifindex = ifi->ifi_index;
453 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
454 struct ifinfomsg *ifi;
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);
461 ifi = NLMSG_DATA(m->hdr);
463 *flags = ifi->ifi_flags;
468 int sd_rtnl_message_link_get_type(sd_rtnl_message *m, unsigned *type) {
469 struct ifinfomsg *ifi;
471 assert_return(m, -EINVAL);
472 assert_return(m->hdr, -EINVAL);
473 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
474 assert_return(type, -EINVAL);
476 ifi = NLMSG_DATA(m->hdr);
478 *type = ifi->ifi_type;
483 /* If successful the updated message will be correctly aligned, if
484 unsuccessful the old message is untouched. */
485 static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
487 size_t message_length, padding_length;
488 struct nlmsghdr *new_hdr;
497 assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
498 assert(!data || data_length);
500 /* get offset of the new attribute */
501 offset = m->hdr->nlmsg_len;
503 /* get the size of the new rta attribute (with padding at the end) */
504 rta_length = RTA_LENGTH(data_length);
506 /* get the new message size (with padding at the end) */
507 message_length = offset + RTA_ALIGN(rta_length);
509 /* realloc to fit the new attribute */
510 new_hdr = realloc(m->hdr, message_length);
515 /* get pointer to the attribute we are about to add */
516 rta = (struct rtattr *) ((uint8_t *) m->hdr + offset);
518 /* if we are inside containers, extend them */
519 for (i = 0; i < m->n_containers; i++)
520 GET_CONTAINER(m, i)->rta_len += message_length - offset;
522 /* fill in the attribute */
523 rta->rta_type = type;
524 rta->rta_len = rta_length;
526 /* we don't deal with the case where the user lies about the type
527 * and gives us too little data (so don't do that)
529 padding = mempcpy(RTA_DATA(rta), data, data_length);
531 /* if no data was passed, make sure we still initialize the padding
532 note that we can have data_length > 0 (used by some containers) */
533 padding = RTA_DATA(rta);
536 /* make sure also the padding at the end of the message is initialized */
537 padding_length = (uint8_t*)m->hdr + message_length - (uint8_t*)padding;
538 memzero(padding, padding_length);
540 /* update message size */
541 m->hdr->nlmsg_len = message_length;
546 static int message_attribute_has_type(sd_rtnl_message *m, uint16_t attribute_type, uint16_t data_type) {
550 r = type_system_get_type(m->container_type_system[m->n_containers], &type, attribute_type);
554 if (type->type != data_type)
560 int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
564 assert_return(m, -EINVAL);
565 assert_return(!m->sealed, -EPERM);
566 assert_return(data, -EINVAL);
568 r = message_attribute_has_type(m, type, NLA_STRING);
575 length = strnlen(data, size);
579 length = strlen(data);
581 r = add_rtattr(m, type, data, length + 1);
588 int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data) {
591 assert_return(m, -EINVAL);
592 assert_return(!m->sealed, -EPERM);
594 r = message_attribute_has_type(m, type, NLA_U8);
598 r = add_rtattr(m, type, &data, sizeof(uint8_t));
606 int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t data) {
609 assert_return(m, -EINVAL);
610 assert_return(!m->sealed, -EPERM);
612 r = message_attribute_has_type(m, type, NLA_U16);
616 r = add_rtattr(m, type, &data, sizeof(uint16_t));
623 int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data) {
626 assert_return(m, -EINVAL);
627 assert_return(!m->sealed, -EPERM);
629 r = message_attribute_has_type(m, type, NLA_U32);
633 r = add_rtattr(m, type, &data, sizeof(uint32_t));
640 int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data) {
643 assert_return(m, -EINVAL);
644 assert_return(!m->sealed, -EPERM);
645 assert_return(data, -EINVAL);
647 r = message_attribute_has_type(m, type, NLA_IN_ADDR);
651 r = add_rtattr(m, type, data, sizeof(struct in_addr));
658 int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data) {
661 assert_return(m, -EINVAL);
662 assert_return(!m->sealed, -EPERM);
663 assert_return(data, -EINVAL);
665 r = message_attribute_has_type(m, type, NLA_IN_ADDR);
669 r = add_rtattr(m, type, data, sizeof(struct in6_addr));
676 int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data) {
679 assert_return(m, -EINVAL);
680 assert_return(!m->sealed, -EPERM);
681 assert_return(data, -EINVAL);
683 r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
687 r = add_rtattr(m, type, data, ETH_ALEN);
694 int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short type, const struct ifa_cacheinfo *info) {
697 assert_return(m, -EINVAL);
698 assert_return(!m->sealed, -EPERM);
699 assert_return(info, -EINVAL);
701 r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
705 r = add_rtattr(m, type, info, sizeof(struct ifa_cacheinfo));
712 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
716 assert_return(m, -EINVAL);
717 assert_return(!m->sealed, -EPERM);
718 assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE);
720 r = message_attribute_has_type(m, type, NLA_NESTED);
726 r = type_system_get_type_system(m->container_type_system[m->n_containers],
727 &m->container_type_system[m->n_containers + 1],
732 r = add_rtattr(m, type, NULL, size);
736 m->container_offsets[m->n_containers ++] = r;
741 int sd_rtnl_message_open_container_union(sd_rtnl_message *m, unsigned short type, const char *key) {
742 const NLTypeSystemUnion *type_system_union;
745 assert_return(m, -EINVAL);
746 assert_return(!m->sealed, -EPERM);
748 r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type);
752 r = type_system_union_get_type_system(type_system_union,
753 &m->container_type_system[m->n_containers + 1],
758 r = sd_rtnl_message_append_string(m, type_system_union->match, key);
762 /* do we evere need non-null size */
763 r = add_rtattr(m, type, NULL, 0);
767 m->container_offsets[m->n_containers ++] = r;
773 int sd_rtnl_message_close_container(sd_rtnl_message *m) {
774 assert_return(m, -EINVAL);
775 assert_return(!m->sealed, -EPERM);
776 assert_return(m->n_containers > 0, -EINVAL);
778 m->container_type_system[m->n_containers] = NULL;
784 int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
787 assert_return(m, -EINVAL);
788 assert_return(m->sealed, -EPERM);
789 assert_return(data, -EINVAL);
790 assert(m->n_containers <= RTNL_CONTAINER_DEPTH);
791 assert(m->rta_offset_tb[m->n_containers]);
792 assert(type < m->rta_tb_size[m->n_containers]);
794 if(!m->rta_offset_tb[m->n_containers][type])
797 rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[m->n_containers][type]);
799 *data = RTA_DATA(rta);
801 return RTA_PAYLOAD(rta);
804 int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, const char **data) {
808 r = message_attribute_has_type(m, type, NLA_STRING);
812 r = rtnl_message_read_internal(m, type, &attr_data);
815 else if (strnlen(attr_data, r) >= (size_t) r)
818 *data = (const char *) attr_data;
823 int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data) {
827 r = message_attribute_has_type(m, type, NLA_U8);
831 r = rtnl_message_read_internal(m, type, &attr_data);
834 else if ((size_t) r < sizeof(uint8_t))
837 *data = *(uint8_t *) attr_data;
842 int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data) {
846 r = message_attribute_has_type(m, type, NLA_U16);
850 r = rtnl_message_read_internal(m, type, &attr_data);
853 else if ((size_t) r < sizeof(uint16_t))
856 *data = *(uint16_t *) attr_data;
861 int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data) {
865 r = message_attribute_has_type(m, type, NLA_U32);
869 r = rtnl_message_read_internal(m, type, &attr_data);
872 else if ((size_t)r < sizeof(uint32_t))
875 *data = *(uint32_t *) attr_data;
880 int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data) {
884 r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
888 r = rtnl_message_read_internal(m, type, &attr_data);
891 else if ((size_t)r < sizeof(struct ether_addr))
894 memcpy(data, attr_data, sizeof(struct ether_addr));
899 int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, struct ifa_cacheinfo *info) {
903 r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
907 r = rtnl_message_read_internal(m, type, &attr_data);
910 else if ((size_t)r < sizeof(struct ifa_cacheinfo))
913 memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
918 int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
922 r = message_attribute_has_type(m, type, NLA_IN_ADDR);
926 r = rtnl_message_read_internal(m, type, &attr_data);
929 else if ((size_t)r < sizeof(struct in_addr))
932 memcpy(data, attr_data, sizeof(struct in_addr));
937 int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data) {
941 r = message_attribute_has_type(m, type, NLA_IN_ADDR);
945 r = rtnl_message_read_internal(m, type, &attr_data);
948 else if ((size_t)r < sizeof(struct in6_addr))
951 memcpy(data, attr_data, sizeof(struct in6_addr));
956 int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type) {
957 const NLType *nl_type;
958 const NLTypeSystem *type_system;
963 assert_return(m, -EINVAL);
964 assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
966 r = type_system_get_type(m->container_type_system[m->n_containers],
972 if (nl_type->type == NLA_NESTED) {
973 r = type_system_get_type_system(m->container_type_system[m->n_containers],
978 } else if (nl_type->type == NLA_UNION) {
979 const NLTypeSystemUnion *type_system_union;
982 r = type_system_get_type_system_union(m->container_type_system[m->n_containers],
988 r = sd_rtnl_message_read_string(m, type_system_union->match, &key);
992 r = type_system_union_get_type_system(type_system_union,
1000 r = rtnl_message_read_internal(m, type, &container);
1008 r = rtnl_message_parse(m,
1009 &m->rta_offset_tb[m->n_containers],
1010 &m->rta_tb_size[m->n_containers],
1019 m->container_type_system[m->n_containers] = type_system;
1024 int sd_rtnl_message_exit_container(sd_rtnl_message *m) {
1025 assert_return(m, -EINVAL);
1026 assert_return(m->sealed, -EINVAL);
1027 assert_return(m->n_containers > 0, -EINVAL);
1029 free(m->rta_offset_tb[m->n_containers]);
1030 m->rta_offset_tb[m->n_containers] = NULL;
1031 m->container_type_system[m->n_containers] = NULL;
1038 uint32_t rtnl_message_get_serial(sd_rtnl_message *m) {
1042 return m->hdr->nlmsg_seq;
1045 int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
1046 struct nlmsgerr *err;
1048 assert_return(m, -EINVAL);
1049 assert_return(m->hdr, -EINVAL);
1051 if (m->hdr->nlmsg_type != NLMSG_ERROR)
1054 err = NLMSG_DATA(m->hdr);
1059 int rtnl_message_parse(sd_rtnl_message *m,
1060 size_t **rta_offset_tb,
1061 unsigned short *rta_tb_size,
1064 unsigned int rt_len) {
1065 unsigned short type;
1068 tb = new0(size_t, max + 1);
1072 *rta_tb_size = max + 1;
1074 for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
1075 type = rta->rta_type;
1077 /* if the kernel is newer than the headers we used
1078 when building, we ignore out-of-range attributes
1084 log_debug("rtnl: message parse - overwriting repeated attribute");
1086 tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
1089 *rta_offset_tb = tb;
1094 /* returns the number of bytes sent, or a negative error code */
1095 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
1098 struct sockaddr_nl nl;
1100 .nl.nl_family = AF_NETLINK,
1108 k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
1109 0, &addr.sa, sizeof(addr));
1111 return (errno == EAGAIN) ? 0 : -errno;
1116 static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool peek) {
1117 uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred)) +
1118 CMSG_SPACE(sizeof(struct nl_pktinfo))];
1119 struct msghdr msg = {
1122 .msg_control = cred_buffer,
1123 .msg_controllen = sizeof(cred_buffer),
1125 struct cmsghdr *cmsg;
1133 r = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
1136 if (errno == ENOBUFS)
1137 log_debug("rtnl: kernel receive buffer overrun");
1139 return (errno == EAGAIN) ? 0 : -errno;
1141 /* connection was closed by the kernel */
1144 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1145 if (cmsg->cmsg_level == SOL_SOCKET &&
1146 cmsg->cmsg_type == SCM_CREDENTIALS &&
1147 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1148 struct ucred *ucred = (void *)CMSG_DATA(cmsg);
1150 /* from the kernel */
1151 if (ucred->uid == 0 && ucred->pid == 0)
1153 } else if (cmsg->cmsg_level == SOL_NETLINK &&
1154 cmsg->cmsg_type == NETLINK_PKTINFO &&
1155 cmsg->cmsg_len == CMSG_LEN(sizeof(struct nl_pktinfo))) {
1156 struct nl_pktinfo *pktinfo = (void *)CMSG_DATA(cmsg);
1158 /* multi-cast group */
1159 group = pktinfo->group;
1164 /* not from the kernel, ignore */
1173 /* On success, the number of bytes received is returned and *ret points to the received message
1174 * which has a valid header and the correct size.
1175 * If nothing useful was received 0 is returned.
1176 * On failure, a negative error code is returned.
1178 int socket_read_message(sd_rtnl *rtnl) {
1179 _cleanup_rtnl_message_unref_ sd_rtnl_message *first = NULL;
1180 struct iovec iov = {};
1182 bool multi_part = false, done = false;
1183 struct nlmsghdr *new_msg;
1189 assert(rtnl->rbuffer);
1190 assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
1192 /* read nothing, just get the pending message size */
1193 r = socket_recv_message(rtnl->fd, &iov, &group, true);
1199 /* make room for the pending message */
1200 if (!greedy_realloc((void **)&rtnl->rbuffer,
1201 &rtnl->rbuffer_allocated,
1202 len, sizeof(uint8_t)))
1205 iov.iov_base = rtnl->rbuffer;
1206 iov.iov_len = rtnl->rbuffer_allocated;
1208 /* read the pending message */
1209 r = socket_recv_message(rtnl->fd, &iov, &group, false);
1215 if (len > rtnl->rbuffer_allocated)
1216 /* message did not fit in read buffer */
1219 if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
1222 for (i = 0; i < rtnl->rqueue_partial_size; i++) {
1223 if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
1224 rtnl->rbuffer->nlmsg_seq) {
1225 first = rtnl->rqueue_partial[i];
1231 for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len); new_msg = NLMSG_NEXT(new_msg, len)) {
1232 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
1233 const NLType *nl_type;
1235 if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
1236 /* not broadcast and not for us */
1239 if (new_msg->nlmsg_type == NLMSG_NOOP)
1240 /* silently drop noop messages */
1243 if (new_msg->nlmsg_type == NLMSG_DONE) {
1244 /* finished reading multi-part message */
1249 /* check that we support this message type */
1250 r = type_system_get_type(NULL, &nl_type, new_msg->nlmsg_type);
1253 log_debug("sd-rtnl: ignored message with unknown type: %u",
1254 new_msg->nlmsg_type);
1259 /* check that the size matches the message type */
1260 if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size))
1263 r = message_new_empty(rtnl, &m);
1267 m->hdr = memdup(new_msg, new_msg->nlmsg_len);
1271 /* seal and parse the top-level message */
1272 r = sd_rtnl_message_rewind(m);
1276 /* push the message onto the multi-part message stack */
1284 log_debug("sd-rtnl: discarding %zu bytes of incoming message", len);
1289 if (!multi_part || done) {
1290 /* we got a complete message, push it on the read queue */
1291 r = rtnl_rqueue_make_room(rtnl);
1295 rtnl->rqueue[rtnl->rqueue_size ++] = first;
1298 if (multi_part && (i < rtnl->rqueue_partial_size)) {
1299 /* remove the message form the partial read queue */
1300 memmove(rtnl->rqueue_partial + i,rtnl->rqueue_partial + i + 1,
1301 sizeof(sd_rtnl_message*) * (rtnl->rqueue_partial_size - i - 1));
1302 rtnl->rqueue_partial_size --;
1307 /* we only got a partial multi-part message, push it on the
1308 partial read queue */
1309 if (i < rtnl->rqueue_partial_size) {
1310 rtnl->rqueue_partial[i] = first;
1312 r = rtnl_rqueue_partial_make_room(rtnl);
1316 rtnl->rqueue_partial[rtnl->rqueue_partial_size ++] = first;
1324 int sd_rtnl_message_rewind(sd_rtnl_message *m) {
1329 assert_return(m, -EINVAL);
1331 /* don't allow appending to message once parsed */
1333 rtnl_message_seal(m);
1335 for (i = 1; i <= m->n_containers; i++) {
1336 free(m->rta_offset_tb[i]);
1337 m->rta_offset_tb[i] = NULL;
1338 m->rta_tb_size[i] = 0;
1339 m->container_type_system[i] = NULL;
1342 m->n_containers = 0;
1344 if (m->rta_offset_tb[0]) {
1345 /* top-level attributes have already been parsed */
1351 r = type_system_get_type(NULL, &type, m->hdr->nlmsg_type);
1355 if (type->type == NLA_NESTED) {
1356 const NLTypeSystem *type_system = type->type_system;
1358 assert(type_system);
1360 m->container_type_system[0] = type_system;
1362 r = rtnl_message_parse(m,
1363 &m->rta_offset_tb[m->n_containers],
1364 &m->rta_tb_size[m->n_containers],
1366 (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) +
1367 NLMSG_ALIGN(type->size)),
1368 NLMSG_PAYLOAD(m->hdr, type->size));
1376 void rtnl_message_seal(sd_rtnl_message *m) {
1383 sd_rtnl_message *sd_rtnl_message_next(sd_rtnl_message *m) {
1384 assert_return(m, NULL);