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>
32 #include "rtnl-util.h"
33 #include "rtnl-internal.h"
34 #include "rtnl-types.h"
36 #define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->container_offsets[i]) : NULL)
37 #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
39 #define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK)
41 static int message_new_empty(sd_rtnl *rtnl, sd_rtnl_message **ret) {
44 assert_return(ret, -EINVAL);
46 /* Note that 'rtnl' is curretly unused, if we start using it internally
47 we must take care to avoid problems due to mutual references between
48 busses and their queued messages. See sd-bus.
51 m = new0(sd_rtnl_message, 1);
55 m->n_ref = REFCNT_INIT;
64 int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t type) {
65 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
66 const NLType *nl_type;
70 r = type_system_get_type(NULL, &nl_type, type);
74 assert(nl_type->type == NLA_NESTED);
76 r = message_new_empty(rtnl, &m);
80 size = NLMSG_SPACE(nl_type->size);
82 assert(size >= sizeof(struct nlmsghdr));
83 m->hdr = malloc0(size);
87 m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
89 m->container_type_system[0] = nl_type->type_system;
90 m->hdr->nlmsg_len = size;
91 m->hdr->nlmsg_type = type;
99 int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
102 assert_return(m, -EINVAL);
103 assert_return(m->hdr, -EINVAL);
104 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
106 rtm = NLMSG_DATA(m->hdr);
108 if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
109 (rtm->rtm_family == AF_INET6 && prefixlen > 128))
112 rtm->rtm_dst_len = prefixlen;
117 int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
120 assert_return(m, -EINVAL);
121 assert_return(m->hdr, -EINVAL);
122 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
124 rtm = NLMSG_DATA(m->hdr);
126 rtm->rtm_scope = scope;
131 int sd_rtnl_message_route_get_family(sd_rtnl_message *m, int *family) {
134 assert_return(m, -EINVAL);
135 assert_return(m->hdr, -EINVAL);
136 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
137 assert_return(family, -EINVAL);
139 rtm = NLMSG_DATA(m->hdr);
141 *family = rtm->rtm_family;
146 int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
147 uint16_t nlmsg_type, int rtm_family,
148 unsigned char rtm_protocol) {
152 assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL);
153 assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
154 assert_return(ret, -EINVAL);
156 r = message_new(rtnl, ret, nlmsg_type);
160 if (nlmsg_type == RTM_NEWROUTE)
161 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
163 rtm = NLMSG_DATA((*ret)->hdr);
165 rtm->rtm_family = rtm_family;
166 rtm->rtm_scope = RT_SCOPE_UNIVERSE;
167 rtm->rtm_type = RTN_UNICAST;
168 rtm->rtm_table = RT_TABLE_MAIN;
169 rtm->rtm_protocol = rtm_protocol;
174 int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change) {
175 struct ifinfomsg *ifi;
177 assert_return(m, -EINVAL);
178 assert_return(m->hdr, -EINVAL);
179 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
180 assert_return(change, -EINVAL);
182 ifi = NLMSG_DATA(m->hdr);
184 ifi->ifi_flags = flags;
185 ifi->ifi_change = change;
190 int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type) {
191 struct ifinfomsg *ifi;
193 assert_return(m, -EINVAL);
194 assert_return(m->hdr, -EINVAL);
195 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
197 ifi = NLMSG_DATA(m->hdr);
199 ifi->ifi_type = type;
204 int sd_rtnl_message_link_set_family(sd_rtnl_message *m, unsigned family) {
205 struct ifinfomsg *ifi;
207 assert_return(m, -EINVAL);
208 assert_return(m->hdr, -EINVAL);
209 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
211 ifi = NLMSG_DATA(m->hdr);
213 ifi->ifi_family = family;
218 int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret,
219 uint16_t nlmsg_type, int index) {
220 struct ifinfomsg *ifi;
223 assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
224 assert_return(nlmsg_type != RTM_DELLINK || index > 0, -EINVAL);
225 assert_return(ret, -EINVAL);
227 r = message_new(rtnl, ret, nlmsg_type);
231 if (nlmsg_type == RTM_NEWLINK)
232 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
234 ifi = NLMSG_DATA((*ret)->hdr);
236 ifi->ifi_family = AF_UNSPEC;
237 ifi->ifi_index = index;
242 int sd_rtnl_message_request_dump(sd_rtnl_message *m, int dump) {
243 assert_return(m, -EINVAL);
244 assert_return(m->hdr, -EINVAL);
245 assert_return(m->hdr->nlmsg_type == RTM_GETLINK ||
246 m->hdr->nlmsg_type == RTM_GETADDR ||
247 m->hdr->nlmsg_type == RTM_GETROUTE,
251 m->hdr->nlmsg_flags |= NLM_F_DUMP;
253 m->hdr->nlmsg_flags &= ~NLM_F_DUMP;
258 int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
259 struct ifaddrmsg *ifa;
261 assert_return(m, -EINVAL);
262 assert_return(m->hdr, -EINVAL);
263 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
265 ifa = NLMSG_DATA(m->hdr);
267 if ((ifa->ifa_family == AF_INET && prefixlen > 32) ||
268 (ifa->ifa_family == AF_INET6 && prefixlen > 128))
271 ifa->ifa_prefixlen = prefixlen;
276 int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags) {
277 struct ifaddrmsg *ifa;
279 assert_return(m, -EINVAL);
280 assert_return(m->hdr, -EINVAL);
281 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
283 ifa = NLMSG_DATA(m->hdr);
285 ifa->ifa_flags = flags;
290 int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) {
291 struct ifaddrmsg *ifa;
293 assert_return(m, -EINVAL);
294 assert_return(m->hdr, -EINVAL);
295 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
297 ifa = NLMSG_DATA(m->hdr);
299 ifa->ifa_scope = scope;
304 int sd_rtnl_message_addr_get_family(sd_rtnl_message *m, int *family) {
305 struct ifaddrmsg *ifa;
307 assert_return(m, -EINVAL);
308 assert_return(m->hdr, -EINVAL);
309 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
310 assert_return(family, -EINVAL);
312 ifa = NLMSG_DATA(m->hdr);
314 *family = ifa->ifa_family;
319 int sd_rtnl_message_addr_get_prefixlen(sd_rtnl_message *m, unsigned char *prefixlen) {
320 struct ifaddrmsg *ifa;
322 assert_return(m, -EINVAL);
323 assert_return(m->hdr, -EINVAL);
324 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
325 assert_return(prefixlen, -EINVAL);
327 ifa = NLMSG_DATA(m->hdr);
329 *prefixlen = ifa->ifa_prefixlen;
334 int sd_rtnl_message_addr_get_scope(sd_rtnl_message *m, unsigned char *scope) {
335 struct ifaddrmsg *ifa;
337 assert_return(m, -EINVAL);
338 assert_return(m->hdr, -EINVAL);
339 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
340 assert_return(scope, -EINVAL);
342 ifa = NLMSG_DATA(m->hdr);
344 *scope = ifa->ifa_scope;
349 int sd_rtnl_message_addr_get_flags(sd_rtnl_message *m, unsigned char *flags) {
350 struct ifaddrmsg *ifa;
352 assert_return(m, -EINVAL);
353 assert_return(m->hdr, -EINVAL);
354 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
355 assert_return(flags, -EINVAL);
357 ifa = NLMSG_DATA(m->hdr);
359 *flags = ifa->ifa_flags;
364 int sd_rtnl_message_addr_get_ifindex(sd_rtnl_message *m, int *ifindex) {
365 struct ifaddrmsg *ifa;
367 assert_return(m, -EINVAL);
368 assert_return(m->hdr, -EINVAL);
369 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
370 assert_return(ifindex, -EINVAL);
372 ifa = NLMSG_DATA(m->hdr);
374 *ifindex = ifa->ifa_index;
379 int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
380 uint16_t nlmsg_type, int index,
382 struct ifaddrmsg *ifa;
385 assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
386 assert_return((nlmsg_type == RTM_GETADDR && index == 0) ||
388 assert_return((nlmsg_type == RTM_GETADDR && family == AF_UNSPEC) ||
389 family == AF_INET || family == AF_INET6, -EINVAL);
390 assert_return(ret, -EINVAL);
392 r = message_new(rtnl, ret, nlmsg_type);
396 if (nlmsg_type == RTM_GETADDR)
397 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
399 ifa = NLMSG_DATA((*ret)->hdr);
401 ifa->ifa_index = index;
402 ifa->ifa_family = family;
403 if (family == AF_INET)
404 ifa->ifa_prefixlen = 32;
405 else if (family == AF_INET6)
406 ifa->ifa_prefixlen = 128;
411 int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret,
412 int index, int family) {
415 r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family);
419 (*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE;
424 sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
426 assert_se(REFCNT_INC(m->n_ref) >= 2);
431 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
432 if (m && REFCNT_DEC(m->n_ref) <= 0) {
437 for (i = 0; i <= m->n_containers; i++)
438 free(m->rta_offset_tb[i]);
440 sd_rtnl_message_unref(m->next);
448 int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type) {
449 assert_return(m, -EINVAL);
450 assert_return(type, -EINVAL);
452 *type = m->hdr->nlmsg_type;
457 int sd_rtnl_message_is_broadcast(sd_rtnl_message *m) {
458 assert_return(m, -EINVAL);
460 return !m->hdr->nlmsg_pid;
463 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex) {
464 struct ifinfomsg *ifi;
466 assert_return(m, -EINVAL);
467 assert_return(m->hdr, -EINVAL);
468 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
469 assert_return(ifindex, -EINVAL);
471 ifi = NLMSG_DATA(m->hdr);
473 *ifindex = ifi->ifi_index;
478 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
479 struct ifinfomsg *ifi;
481 assert_return(m, -EINVAL);
482 assert_return(m->hdr, -EINVAL);
483 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
484 assert_return(flags, -EINVAL);
486 ifi = NLMSG_DATA(m->hdr);
488 *flags = ifi->ifi_flags;
493 int sd_rtnl_message_link_get_type(sd_rtnl_message *m, unsigned *type) {
494 struct ifinfomsg *ifi;
496 assert_return(m, -EINVAL);
497 assert_return(m->hdr, -EINVAL);
498 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
499 assert_return(type, -EINVAL);
501 ifi = NLMSG_DATA(m->hdr);
503 *type = ifi->ifi_type;
508 /* If successful the updated message will be correctly aligned, if
509 unsuccessful the old message is untouched. */
510 static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
512 size_t message_length, padding_length;
513 struct nlmsghdr *new_hdr;
522 assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
523 assert(!data || data_length);
525 /* get offset of the new attribute */
526 offset = m->hdr->nlmsg_len;
528 /* get the size of the new rta attribute (with padding at the end) */
529 rta_length = RTA_LENGTH(data_length);
531 /* get the new message size (with padding at the end) */
532 message_length = offset + RTA_ALIGN(rta_length);
534 /* realloc to fit the new attribute */
535 new_hdr = realloc(m->hdr, message_length);
540 /* get pointer to the attribute we are about to add */
541 rta = (struct rtattr *) ((uint8_t *) m->hdr + offset);
543 /* if we are inside containers, extend them */
544 for (i = 0; i < m->n_containers; i++)
545 GET_CONTAINER(m, i)->rta_len += message_length - offset;
547 /* fill in the attribute */
548 rta->rta_type = type;
549 rta->rta_len = rta_length;
551 /* we don't deal with the case where the user lies about the type
552 * and gives us too little data (so don't do that)
554 padding = mempcpy(RTA_DATA(rta), data, data_length);
556 /* if no data was passed, make sure we still initialize the padding
557 note that we can have data_length > 0 (used by some containers) */
558 padding = RTA_DATA(rta);
561 /* make sure also the padding at the end of the message is initialized */
562 padding_length = (uint8_t*)m->hdr + message_length - (uint8_t*)padding;
563 memzero(padding, padding_length);
565 /* update message size */
566 m->hdr->nlmsg_len = message_length;
571 static int message_attribute_has_type(sd_rtnl_message *m, uint16_t attribute_type, uint16_t data_type) {
575 r = type_system_get_type(m->container_type_system[m->n_containers], &type, attribute_type);
579 if (type->type != data_type)
585 int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
589 assert_return(m, -EINVAL);
590 assert_return(!m->sealed, -EPERM);
591 assert_return(data, -EINVAL);
593 r = message_attribute_has_type(m, type, NLA_STRING);
600 length = strnlen(data, size);
604 length = strlen(data);
606 r = add_rtattr(m, type, data, length + 1);
613 int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data) {
616 assert_return(m, -EINVAL);
617 assert_return(!m->sealed, -EPERM);
619 r = message_attribute_has_type(m, type, NLA_U8);
623 r = add_rtattr(m, type, &data, sizeof(uint8_t));
631 int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t data) {
634 assert_return(m, -EINVAL);
635 assert_return(!m->sealed, -EPERM);
637 r = message_attribute_has_type(m, type, NLA_U16);
641 r = add_rtattr(m, type, &data, sizeof(uint16_t));
648 int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data) {
651 assert_return(m, -EINVAL);
652 assert_return(!m->sealed, -EPERM);
654 r = message_attribute_has_type(m, type, NLA_U32);
658 r = add_rtattr(m, type, &data, sizeof(uint32_t));
665 int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data) {
668 assert_return(m, -EINVAL);
669 assert_return(!m->sealed, -EPERM);
670 assert_return(data, -EINVAL);
672 r = message_attribute_has_type(m, type, NLA_IN_ADDR);
676 r = add_rtattr(m, type, data, sizeof(struct in_addr));
683 int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data) {
686 assert_return(m, -EINVAL);
687 assert_return(!m->sealed, -EPERM);
688 assert_return(data, -EINVAL);
690 r = message_attribute_has_type(m, type, NLA_IN_ADDR);
694 r = add_rtattr(m, type, data, sizeof(struct in6_addr));
701 int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data) {
704 assert_return(m, -EINVAL);
705 assert_return(!m->sealed, -EPERM);
706 assert_return(data, -EINVAL);
708 r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
712 r = add_rtattr(m, type, data, ETH_ALEN);
719 int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short type, const struct ifa_cacheinfo *info) {
722 assert_return(m, -EINVAL);
723 assert_return(!m->sealed, -EPERM);
724 assert_return(info, -EINVAL);
726 r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
730 r = add_rtattr(m, type, info, sizeof(struct ifa_cacheinfo));
737 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
741 assert_return(m, -EINVAL);
742 assert_return(!m->sealed, -EPERM);
743 assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE);
745 r = message_attribute_has_type(m, type, NLA_NESTED);
751 r = type_system_get_type_system(m->container_type_system[m->n_containers],
752 &m->container_type_system[m->n_containers + 1],
757 r = add_rtattr(m, type | NLA_F_NESTED, NULL, size);
761 m->container_offsets[m->n_containers ++] = r;
766 int sd_rtnl_message_open_container_union(sd_rtnl_message *m, unsigned short type, const char *key) {
767 const NLTypeSystemUnion *type_system_union;
770 assert_return(m, -EINVAL);
771 assert_return(!m->sealed, -EPERM);
773 r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type);
777 r = type_system_union_get_type_system(type_system_union,
778 &m->container_type_system[m->n_containers + 1],
783 r = sd_rtnl_message_append_string(m, type_system_union->match, key);
787 /* do we evere need non-null size */
788 r = add_rtattr(m, type, NULL, 0);
792 m->container_offsets[m->n_containers ++] = r;
798 int sd_rtnl_message_close_container(sd_rtnl_message *m) {
799 assert_return(m, -EINVAL);
800 assert_return(!m->sealed, -EPERM);
801 assert_return(m->n_containers > 0, -EINVAL);
803 m->container_type_system[m->n_containers] = NULL;
809 int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
812 assert_return(m, -EINVAL);
813 assert_return(m->sealed, -EPERM);
814 assert_return(data, -EINVAL);
815 assert(m->n_containers <= RTNL_CONTAINER_DEPTH);
816 assert(m->rta_offset_tb[m->n_containers]);
817 assert(type < m->rta_tb_size[m->n_containers]);
819 if(!m->rta_offset_tb[m->n_containers][type])
822 rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[m->n_containers][type]);
824 *data = RTA_DATA(rta);
826 return RTA_PAYLOAD(rta);
829 int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, const char **data) {
833 assert_return(m, -EINVAL);
835 r = message_attribute_has_type(m, type, NLA_STRING);
839 r = rtnl_message_read_internal(m, type, &attr_data);
842 else if (strnlen(attr_data, r) >= (size_t) r)
846 *data = (const char *) attr_data;
851 int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data) {
855 assert_return(m, -EINVAL);
857 r = message_attribute_has_type(m, type, NLA_U8);
861 r = rtnl_message_read_internal(m, type, &attr_data);
864 else if ((size_t) r < sizeof(uint8_t))
868 *data = *(uint8_t *) attr_data;
873 int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data) {
877 assert_return(m, -EINVAL);
879 r = message_attribute_has_type(m, type, NLA_U16);
883 r = rtnl_message_read_internal(m, type, &attr_data);
886 else if ((size_t) r < sizeof(uint16_t))
890 *data = *(uint16_t *) attr_data;
895 int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data) {
899 assert_return(m, -EINVAL);
901 r = message_attribute_has_type(m, type, NLA_U32);
905 r = rtnl_message_read_internal(m, type, &attr_data);
908 else if ((size_t)r < sizeof(uint32_t))
912 *data = *(uint32_t *) attr_data;
917 int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data) {
921 assert_return(m, -EINVAL);
923 r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
927 r = rtnl_message_read_internal(m, type, &attr_data);
930 else if ((size_t)r < sizeof(struct ether_addr))
934 memcpy(data, attr_data, sizeof(struct ether_addr));
939 int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, struct ifa_cacheinfo *info) {
943 assert_return(m, -EINVAL);
945 r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
949 r = rtnl_message_read_internal(m, type, &attr_data);
952 else if ((size_t)r < sizeof(struct ifa_cacheinfo))
956 memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
961 int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
965 assert_return(m, -EINVAL);
967 r = message_attribute_has_type(m, type, NLA_IN_ADDR);
971 r = rtnl_message_read_internal(m, type, &attr_data);
974 else if ((size_t)r < sizeof(struct in_addr))
978 memcpy(data, attr_data, sizeof(struct in_addr));
983 int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data) {
987 assert_return(m, -EINVAL);
989 r = message_attribute_has_type(m, type, NLA_IN_ADDR);
993 r = rtnl_message_read_internal(m, type, &attr_data);
996 else if ((size_t)r < sizeof(struct in6_addr))
1000 memcpy(data, attr_data, sizeof(struct in6_addr));
1005 int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type) {
1006 const NLType *nl_type;
1007 const NLTypeSystem *type_system;
1012 assert_return(m, -EINVAL);
1013 assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
1015 r = type_system_get_type(m->container_type_system[m->n_containers],
1021 if (nl_type->type == NLA_NESTED) {
1022 r = type_system_get_type_system(m->container_type_system[m->n_containers],
1027 } else if (nl_type->type == NLA_UNION) {
1028 const NLTypeSystemUnion *type_system_union;
1031 r = type_system_get_type_system_union(m->container_type_system[m->n_containers],
1037 r = sd_rtnl_message_read_string(m, type_system_union->match, &key);
1041 r = type_system_union_get_type_system(type_system_union,
1049 r = rtnl_message_read_internal(m, type, &container);
1057 r = rtnl_message_parse(m,
1058 &m->rta_offset_tb[m->n_containers],
1059 &m->rta_tb_size[m->n_containers],
1068 m->container_type_system[m->n_containers] = type_system;
1073 int sd_rtnl_message_exit_container(sd_rtnl_message *m) {
1074 assert_return(m, -EINVAL);
1075 assert_return(m->sealed, -EINVAL);
1076 assert_return(m->n_containers > 0, -EINVAL);
1078 free(m->rta_offset_tb[m->n_containers]);
1079 m->rta_offset_tb[m->n_containers] = NULL;
1080 m->container_type_system[m->n_containers] = NULL;
1087 uint32_t rtnl_message_get_serial(sd_rtnl_message *m) {
1091 return m->hdr->nlmsg_seq;
1094 int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
1095 struct nlmsgerr *err;
1097 assert_return(m, -EINVAL);
1098 assert_return(m->hdr, -EINVAL);
1100 if (m->hdr->nlmsg_type != NLMSG_ERROR)
1103 err = NLMSG_DATA(m->hdr);
1108 int rtnl_message_parse(sd_rtnl_message *m,
1109 size_t **rta_offset_tb,
1110 unsigned short *rta_tb_size,
1113 unsigned int rt_len) {
1114 unsigned short type;
1117 tb = new0(size_t, max + 1);
1121 *rta_tb_size = max + 1;
1123 for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
1124 type = RTA_TYPE(rta);
1126 /* if the kernel is newer than the headers we used
1127 when building, we ignore out-of-range attributes
1133 log_debug("rtnl: message parse - overwriting repeated attribute");
1135 tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
1138 *rta_offset_tb = tb;
1143 /* returns the number of bytes sent, or a negative error code */
1144 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
1147 struct sockaddr_nl nl;
1149 .nl.nl_family = AF_NETLINK,
1157 k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
1158 0, &addr.sa, sizeof(addr));
1160 return (errno == EAGAIN) ? 0 : -errno;
1165 static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool peek) {
1166 uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred)) +
1167 CMSG_SPACE(sizeof(struct nl_pktinfo))];
1168 struct msghdr msg = {
1171 .msg_control = cred_buffer,
1172 .msg_controllen = sizeof(cred_buffer),
1174 struct cmsghdr *cmsg;
1182 r = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
1185 if (errno == ENOBUFS)
1186 log_debug("rtnl: kernel receive buffer overrun");
1188 return (errno == EAGAIN) ? 0 : -errno;
1190 /* connection was closed by the kernel */
1193 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1194 if (cmsg->cmsg_level == SOL_SOCKET &&
1195 cmsg->cmsg_type == SCM_CREDENTIALS &&
1196 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1197 struct ucred *ucred = (void *)CMSG_DATA(cmsg);
1199 /* from the kernel */
1200 if (ucred->uid == 0 && ucred->pid == 0)
1202 } else if (cmsg->cmsg_level == SOL_NETLINK &&
1203 cmsg->cmsg_type == NETLINK_PKTINFO &&
1204 cmsg->cmsg_len == CMSG_LEN(sizeof(struct nl_pktinfo))) {
1205 struct nl_pktinfo *pktinfo = (void *)CMSG_DATA(cmsg);
1207 /* multi-cast group */
1208 group = pktinfo->group;
1213 /* not from the kernel, ignore */
1222 /* On success, the number of bytes received is returned and *ret points to the received message
1223 * which has a valid header and the correct size.
1224 * If nothing useful was received 0 is returned.
1225 * On failure, a negative error code is returned.
1227 int socket_read_message(sd_rtnl *rtnl) {
1228 _cleanup_rtnl_message_unref_ sd_rtnl_message *first = NULL;
1229 struct iovec iov = {};
1231 bool multi_part = false, done = false;
1232 struct nlmsghdr *new_msg;
1238 assert(rtnl->rbuffer);
1239 assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
1241 /* read nothing, just get the pending message size */
1242 r = socket_recv_message(rtnl->fd, &iov, &group, true);
1248 /* make room for the pending message */
1249 if (!greedy_realloc((void **)&rtnl->rbuffer,
1250 &rtnl->rbuffer_allocated,
1251 len, sizeof(uint8_t)))
1254 iov.iov_base = rtnl->rbuffer;
1255 iov.iov_len = rtnl->rbuffer_allocated;
1257 /* read the pending message */
1258 r = socket_recv_message(rtnl->fd, &iov, &group, false);
1264 if (len > rtnl->rbuffer_allocated)
1265 /* message did not fit in read buffer */
1268 if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
1271 for (i = 0; i < rtnl->rqueue_partial_size; i++) {
1272 if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
1273 rtnl->rbuffer->nlmsg_seq) {
1274 first = rtnl->rqueue_partial[i];
1280 for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len); new_msg = NLMSG_NEXT(new_msg, len)) {
1281 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
1282 const NLType *nl_type;
1284 if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
1285 /* not broadcast and not for us */
1288 if (new_msg->nlmsg_type == NLMSG_NOOP)
1289 /* silently drop noop messages */
1292 if (new_msg->nlmsg_type == NLMSG_DONE) {
1293 /* finished reading multi-part message */
1298 /* check that we support this message type */
1299 r = type_system_get_type(NULL, &nl_type, new_msg->nlmsg_type);
1302 log_debug("sd-rtnl: ignored message with unknown type: %u",
1303 new_msg->nlmsg_type);
1308 /* check that the size matches the message type */
1309 if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size))
1312 r = message_new_empty(rtnl, &m);
1316 m->hdr = memdup(new_msg, new_msg->nlmsg_len);
1320 /* seal and parse the top-level message */
1321 r = sd_rtnl_message_rewind(m);
1325 /* push the message onto the multi-part message stack */
1333 log_debug("sd-rtnl: discarding %zu bytes of incoming message", len);
1338 if (!multi_part || done) {
1339 /* we got a complete message, push it on the read queue */
1340 r = rtnl_rqueue_make_room(rtnl);
1344 rtnl->rqueue[rtnl->rqueue_size ++] = first;
1347 if (multi_part && (i < rtnl->rqueue_partial_size)) {
1348 /* remove the message form the partial read queue */
1349 memmove(rtnl->rqueue_partial + i,rtnl->rqueue_partial + i + 1,
1350 sizeof(sd_rtnl_message*) * (rtnl->rqueue_partial_size - i - 1));
1351 rtnl->rqueue_partial_size --;
1356 /* we only got a partial multi-part message, push it on the
1357 partial read queue */
1358 if (i < rtnl->rqueue_partial_size) {
1359 rtnl->rqueue_partial[i] = first;
1361 r = rtnl_rqueue_partial_make_room(rtnl);
1365 rtnl->rqueue_partial[rtnl->rqueue_partial_size ++] = first;
1373 int sd_rtnl_message_rewind(sd_rtnl_message *m) {
1378 assert_return(m, -EINVAL);
1380 /* don't allow appending to message once parsed */
1382 rtnl_message_seal(m);
1384 for (i = 1; i <= m->n_containers; i++) {
1385 free(m->rta_offset_tb[i]);
1386 m->rta_offset_tb[i] = NULL;
1387 m->rta_tb_size[i] = 0;
1388 m->container_type_system[i] = NULL;
1391 m->n_containers = 0;
1393 if (m->rta_offset_tb[0]) {
1394 /* top-level attributes have already been parsed */
1400 r = type_system_get_type(NULL, &type, m->hdr->nlmsg_type);
1404 if (type->type == NLA_NESTED) {
1405 const NLTypeSystem *type_system = type->type_system;
1407 assert(type_system);
1409 m->container_type_system[0] = type_system;
1411 r = rtnl_message_parse(m,
1412 &m->rta_offset_tb[m->n_containers],
1413 &m->rta_tb_size[m->n_containers],
1415 (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) +
1416 NLMSG_ALIGN(type->size)),
1417 NLMSG_PAYLOAD(m->hdr, type->size));
1425 void rtnl_message_seal(sd_rtnl_message *m) {
1432 sd_rtnl_message *sd_rtnl_message_next(sd_rtnl_message *m) {
1433 assert_return(m, NULL);