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/veth.h>
33 #include "rtnl-util.h"
34 #include "rtnl-internal.h"
36 #define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->container_offsets[i]) : NULL)
37 #define NEXT_RTA(m) ((struct rtattr*)((uint8_t*)(m)->hdr + (m)->next_rta_offset))
38 #define UPDATE_RTA(m, new) (m)->next_rta_offset = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
39 #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
41 int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, size_t initial_size) {
44 assert_return(ret, -EINVAL);
45 assert_return(initial_size >= sizeof(struct nlmsghdr), -EINVAL);
47 m = new0(sd_rtnl_message, 1);
51 m->hdr = malloc0(initial_size);
57 m->n_ref = REFCNT_INIT;
59 m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
63 m->rtnl = sd_rtnl_ref(rtnl);
70 int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
73 assert_return(m, -EINVAL);
74 assert_return(m->hdr, -EINVAL);
75 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
77 rtm = NLMSG_DATA(m->hdr);
79 if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
80 (rtm->rtm_family == AF_INET6 && prefixlen > 128))
83 rtm->rtm_dst_len = prefixlen;
88 int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
91 assert_return(m, -EINVAL);
92 assert_return(m->hdr, -EINVAL);
93 assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
95 rtm = NLMSG_DATA(m->hdr);
97 rtm->rtm_scope = scope;
102 int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
103 uint16_t nlmsg_type, unsigned char rtm_family) {
107 assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL);
108 assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
109 assert_return(ret, -EINVAL);
111 r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct rtmsg)));
115 (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
116 (*ret)->hdr->nlmsg_type = nlmsg_type;
117 if (nlmsg_type == RTM_NEWROUTE)
118 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
120 rtm = NLMSG_DATA((*ret)->hdr);
122 UPDATE_RTA(*ret, RTM_RTA(rtm));
124 rtm->rtm_family = rtm_family;
125 rtm->rtm_scope = RT_SCOPE_UNIVERSE;
126 rtm->rtm_type = RTN_UNICAST;
127 rtm->rtm_table = RT_TABLE_MAIN;
128 rtm->rtm_protocol = RTPROT_BOOT;
133 int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change) {
134 struct ifinfomsg *ifi;
136 assert_return(m, -EINVAL);
137 assert_return(m->hdr, -EINVAL);
138 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
139 assert_return(change, -EINVAL);
141 ifi = NLMSG_DATA(m->hdr);
143 ifi->ifi_flags = flags;
144 ifi->ifi_change = change;
149 int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type) {
150 struct ifinfomsg *ifi;
152 assert_return(m, -EINVAL);
153 assert_return(m->hdr, -EINVAL);
154 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
156 ifi = NLMSG_DATA(m->hdr);
158 ifi->ifi_type = type;
163 int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret,
164 uint16_t nlmsg_type, int index) {
165 struct ifinfomsg *ifi;
168 assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
169 assert_return(nlmsg_type != RTM_DELLINK || index > 0, -EINVAL);
170 assert_return(ret, -EINVAL);
172 r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifinfomsg)));
176 (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
177 (*ret)->hdr->nlmsg_type = nlmsg_type;
178 if (nlmsg_type == RTM_NEWLINK)
179 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
181 ifi = NLMSG_DATA((*ret)->hdr);
183 ifi->ifi_family = AF_UNSPEC;
184 ifi->ifi_index = index;
186 UPDATE_RTA(*ret, IFLA_RTA(ifi));
191 int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
192 struct ifaddrmsg *ifa;
194 assert_return(m, -EINVAL);
195 assert_return(m->hdr, -EINVAL);
196 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
198 ifa = NLMSG_DATA(m->hdr);
200 if ((ifa->ifa_family == AF_INET && prefixlen > 32) ||
201 (ifa->ifa_family == AF_INET6 && prefixlen > 128))
204 ifa->ifa_prefixlen = prefixlen;
209 int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags) {
210 struct ifaddrmsg *ifa;
212 assert_return(m, -EINVAL);
213 assert_return(m->hdr, -EINVAL);
214 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
216 ifa = NLMSG_DATA(m->hdr);
218 ifa->ifa_flags = flags;
223 int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) {
224 struct ifaddrmsg *ifa;
226 assert_return(m, -EINVAL);
227 assert_return(m->hdr, -EINVAL);
228 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
230 ifa = NLMSG_DATA(m->hdr);
232 ifa->ifa_scope = scope;
237 int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
238 uint16_t nlmsg_type, int index,
239 unsigned char family) {
240 struct ifaddrmsg *ifa;
243 assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
244 assert_return(index > 0, -EINVAL);
245 assert_return(family == AF_INET || family == AF_INET6, -EINVAL);
246 assert_return(ret, -EINVAL);
248 r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifaddrmsg)));
252 (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
253 (*ret)->hdr->nlmsg_type = nlmsg_type;
254 if (nlmsg_type == RTM_GETADDR && family == AF_INET)
255 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
257 ifa = NLMSG_DATA((*ret)->hdr);
259 ifa->ifa_index = index;
260 ifa->ifa_family = family;
261 if (family == AF_INET)
262 ifa->ifa_prefixlen = 32;
263 else if (family == AF_INET6)
264 ifa->ifa_prefixlen = 128;
266 UPDATE_RTA(*ret, IFA_RTA(ifa));
271 sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
273 assert_se(REFCNT_INC(m->n_ref) >= 2);
278 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
279 if (m && REFCNT_DEC(m->n_ref) <= 0) {
280 sd_rtnl_unref(m->rtnl);
282 free(m->rta_offset_tb);
289 int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type) {
290 assert_return(m, -EINVAL);
291 assert_return(type, -EINVAL);
293 *type = m->hdr->nlmsg_type;
298 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex) {
299 struct ifinfomsg *ifi;
301 assert_return(m, -EINVAL);
302 assert_return(m->hdr, -EINVAL);
303 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
304 assert_return(ifindex, -EINVAL);
306 ifi = NLMSG_DATA(m->hdr);
308 *ifindex = ifi->ifi_index;
313 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
314 struct ifinfomsg *ifi;
316 assert_return(m, -EINVAL);
317 assert_return(m->hdr, -EINVAL);
318 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
319 assert_return(flags, -EINVAL);
321 ifi = NLMSG_DATA(m->hdr);
323 *flags = ifi->ifi_flags;
328 /* If successful the updated message will be correctly aligned, if
329 unsuccessful the old message is untouched. */
330 static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
331 uint32_t rta_length, message_length;
332 struct nlmsghdr *new_hdr;
340 assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
341 assert(!data || data_length > 0);
342 assert(data || m->n_containers < RTNL_CONTAINER_DEPTH);
344 /* get the size of the new rta attribute (with padding at the end) */
345 rta_length = RTA_LENGTH(data_length);
347 /* get the new message size (with padding at the end) */
348 message_length = m->hdr->nlmsg_len + RTA_ALIGN(rta_length);
350 /* realloc to fit the new attribute */
351 new_hdr = realloc(m->hdr, message_length);
356 /* get pointer to the attribute we are about to add */
357 rta = (struct rtattr *) ((uint8_t *) m->hdr + m->hdr->nlmsg_len);
359 /* if we are inside containers, extend them */
360 for (i = 0; i < m->n_containers; i++)
361 GET_CONTAINER(m, i)->rta_len += message_length - m->hdr->nlmsg_len;
363 /* fill in the attribute */
364 rta->rta_type = type;
365 rta->rta_len = rta_length;
367 /* this is the start of a new container */
368 m->container_offsets[m->n_containers ++] = m->hdr->nlmsg_len;
370 /* we don't deal with the case where the user lies about the type
371 * and gives us too little data (so don't do that)
373 padding = mempcpy(RTA_DATA(rta), data, data_length);
374 /* make sure also the padding at the end of the message is initialized */
376 (uint8_t *) m->hdr + message_length - (uint8_t *) padding);
379 /* update message size */
380 m->hdr->nlmsg_len = message_length;
385 int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
389 assert_return(m, -EINVAL);
390 assert_return(!m->sealed, -EPERM);
391 assert_return(data, -EINVAL);
393 r = sd_rtnl_message_get_type(m, &rtm_type);
397 /* check that the type is correct */
403 if (m->n_containers == 1) {
404 if (GET_CONTAINER(m, 0)->rta_type != IFLA_LINKINFO ||
405 type != IFLA_INFO_KIND)
421 if (type != IFA_LABEL)
428 r = add_rtattr(m, type, data, strlen(data) + 1);
435 int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data) {
439 assert_return(m, -EINVAL);
440 assert_return(!m->sealed, -EPERM);
442 r = sd_rtnl_message_get_type(m, &rtm_type);
465 r = add_rtattr(m, type, &data, sizeof(uint8_t));
473 int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t data) {
477 assert_return(m, -EINVAL);
478 assert_return(!m->sealed, -EPERM);
480 r = sd_rtnl_message_get_type(m, &rtm_type);
484 /* check that the type is correct */
490 if (m->n_containers == 2 &&
491 GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO &&
492 GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA &&
493 type == IFLA_VLAN_ID)
502 r = add_rtattr(m, type, &data, sizeof(uint16_t));
509 int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data) {
513 assert_return(m, -EINVAL);
514 assert_return(!m->sealed, -EPERM);
516 r = sd_rtnl_message_get_type(m, &rtm_type);
520 /* check that the type is correct */
534 case IFLA_NET_NS_PID:
535 case IFLA_PROMISCUITY:
536 case IFLA_NUM_TX_QUEUES:
537 case IFLA_NUM_RX_QUEUES:
538 case IFLA_MACVLAN_MODE:
562 r = add_rtattr(m, type, &data, sizeof(uint32_t));
569 int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data) {
570 struct ifaddrmsg *ifa;
575 assert_return(m, -EINVAL);
576 assert_return(!m->sealed, -EPERM);
577 assert_return(data, -EINVAL);
579 r = sd_rtnl_message_get_type(m, &rtm_type);
583 /* check that the type is correct */
593 ifa = NLMSG_DATA(m->hdr);
595 if (ifa->ifa_family != AF_INET)
610 rtm = NLMSG_DATA(m->hdr);
612 if (rtm->rtm_family != AF_INET)
624 r = add_rtattr(m, type, data, sizeof(struct in_addr));
631 int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data) {
632 struct ifaddrmsg *ifa;
637 assert_return(m, -EINVAL);
638 assert_return(!m->sealed, -EPERM);
639 assert_return(data, -EINVAL);
641 r = sd_rtnl_message_get_type(m, &rtm_type);
645 /* check that the type is correct */
655 ifa = NLMSG_DATA(m->hdr);
657 if (ifa->ifa_family != AF_INET6)
672 rtm = NLMSG_DATA(m->hdr);
674 if (rtm->rtm_family != AF_INET6)
685 r = add_rtattr(m, type, data, sizeof(struct in6_addr));
692 int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data) {
696 assert_return(m, -EINVAL);
697 assert_return(!m->sealed, -EPERM);
698 assert_return(data, -EINVAL);
700 sd_rtnl_message_get_type(m, &rtm_type);
719 r = add_rtattr(m, type, data, ETH_ALEN);
726 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
729 assert_return(m, -EINVAL);
730 assert_return(!m->sealed, -EPERM);
732 sd_rtnl_message_get_type(m, &rtm_type);
734 if (rtnl_message_type_is_link(rtm_type)) {
736 if ((type == IFLA_LINKINFO && m->n_containers == 0) ||
737 (type == IFLA_INFO_DATA && m->n_containers == 1 &&
738 GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO))
739 return add_rtattr(m, type, NULL, 0);
740 else if (type == VETH_INFO_PEER && m->n_containers == 2 &&
741 GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA &&
742 GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO)
743 return add_rtattr(m, type, NULL, sizeof(struct ifinfomsg));
749 int sd_rtnl_message_close_container(sd_rtnl_message *m) {
750 assert_return(m, -EINVAL);
751 assert_return(!m->sealed, -EPERM);
752 assert_return(m->n_containers > 0, -EINVAL);
759 int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data) {
760 size_t remaining_size;
764 assert_return(m, -EINVAL);
765 assert_return(m->sealed, -EPERM);
766 assert_return(m->next_rta_offset, -EINVAL);
767 assert_return(type, -EINVAL);
768 assert_return(data, -EINVAL);
770 /* only read until the end of the current container */
772 remaining_size = GET_CONTAINER(m, m->n_containers - 1)->rta_len -
773 (m->next_rta_offset -
774 m->container_offsets[m->n_containers - 1]);
776 remaining_size = m->hdr->nlmsg_len - m->next_rta_offset;
778 if (!RTA_OK(NEXT_RTA(m), remaining_size))
781 /* if we read a container, return its type, but do not enter it*/
782 r = sd_rtnl_message_get_type(m, &rtm_type);
786 *type = NEXT_RTA(m)->rta_type;
788 if (rtnl_message_type_is_link(rtm_type) &&
789 ((m->n_containers == 0 &&
790 NEXT_RTA(m)->rta_type == IFLA_LINKINFO) ||
791 (m->n_containers == 1 &&
792 GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO &&
793 NEXT_RTA(m)->rta_type == IFLA_INFO_DATA)))
796 *data = RTA_DATA(NEXT_RTA(m));
798 UPDATE_RTA(m, RTA_NEXT(NEXT_RTA(m), remaining_size));
803 int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
804 assert_return(m, -EINVAL);
805 assert_return(m->sealed, -EPERM);
806 assert_return(data, -EINVAL);
807 assert_return(m->rta_offset_tb, -EINVAL);
808 assert_return(type < m->rta_tb_size, -EINVAL);
810 if(!m->rta_offset_tb[type])
813 *data = RTA_DATA((struct rtattr *)((uint8_t *) m->hdr + m->rta_offset_tb[type]));
818 int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, char **data) {
822 assert_return(data, -EINVAL);
824 r = rtnl_message_read_internal(m, type, &attr_data);
828 *data = (char *) attr_data;
833 int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data) {
837 assert_return(data, -EINVAL);
839 r = rtnl_message_read_internal(m, type, &attr_data);
843 *data = *(uint8_t *) attr_data;
848 int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data) {
852 assert_return(data, -EINVAL);
854 r = rtnl_message_read_internal(m, type, &attr_data);
858 *data = *(uint16_t *) attr_data;
863 int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data) {
867 assert_return(data, -EINVAL);
869 r = rtnl_message_read_internal(m, type, &attr_data);
873 *data = *(uint32_t *) attr_data;
878 int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data) {
882 assert_return(data, -EINVAL);
884 r = rtnl_message_read_internal(m, type, &attr_data);
888 memcpy(data, attr_data, sizeof(struct ether_addr));
893 int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
897 assert_return(data, -EINVAL);
899 r = rtnl_message_read_internal(m, type, &attr_data);
903 memcpy(data, attr_data, sizeof(struct in_addr));
908 int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data) {
912 assert_return(data, -EINVAL);
914 r = rtnl_message_read_internal(m, type, &attr_data);
918 memcpy(data, attr_data, sizeof(struct in6_addr));
923 int sd_rtnl_message_exit_container(sd_rtnl_message *m) {
924 assert_return(m, -EINVAL);
925 assert_return(m->sealed, -EINVAL);
926 assert_return(m->n_containers > 0, -EINVAL);
933 uint32_t rtnl_message_get_serial(sd_rtnl_message *m) {
937 return m->hdr->nlmsg_seq;
940 int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
941 struct nlmsgerr *err;
943 assert_return(m, -EINVAL);
944 assert_return(m->hdr, -EINVAL);
946 if (m->hdr->nlmsg_type != NLMSG_ERROR)
949 err = NLMSG_DATA(m->hdr);
954 int rtnl_message_seal(sd_rtnl *nl, sd_rtnl_message *m) {
964 m->hdr->nlmsg_seq = nl->serial++;
968 r = sd_rtnl_message_rewind(m);
975 static int message_receive_need(sd_rtnl *rtnl, size_t *need) {
979 /* ioctl(rtnl->fd, FIONREAD, &need)
980 Does not appear to work on netlink sockets. libnl uses
981 MSG_PEEK instead. I don't know if that is worth the
984 For now we simply use the maximum message size the kernel
985 may use (NLMSG_GOODSIZE), and then realloc to the actual
986 size after reading the message (hence avoiding huge memory
987 usage in case many small messages are kept around) */
995 int rtnl_message_parse(sd_rtnl_message *m,
996 size_t **rta_offset_tb,
997 unsigned short *rta_tb_size,
1000 unsigned int rt_len) {
1004 tb = (size_t *) new0(size_t *, max);
1010 for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
1011 type = rta->rta_type;
1013 if (type < max && !tb[type])
1014 tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
1017 *rta_offset_tb = tb;
1022 /* returns the number of bytes sent, or a negative error code */
1023 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
1026 struct sockaddr_nl nl;
1028 .nl.nl_family = AF_NETLINK,
1036 k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
1037 0, &addr.sa, sizeof(addr));
1039 return (errno == EAGAIN) ? 0 : -errno;
1044 /* On success, the number of bytes received is returned and *ret points to the received message
1045 * which has a valid header and the correct size.
1046 * If nothing useful was received 0 is returned.
1047 * On failure, a negative error code is returned.
1049 int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
1053 struct sockaddr_nl nl;
1063 r = message_receive_need(nl, &need);
1067 r = message_new(nl, &m, need);
1071 /* don't allow sealing/appending to received messages */
1074 addr_len = sizeof(addr);
1076 k = recvfrom(nl->fd, m->hdr, need,
1077 0, &addr.sa, &addr_len);
1079 k = (errno == EAGAIN) ? 0 : -errno; /* no data */
1081 k = -ECONNRESET; /* connection was closed by the kernel */
1082 else if (addr_len != sizeof(addr.nl) ||
1083 addr.nl.nl_family != AF_NETLINK)
1084 k = -EIO; /* not a netlink message */
1085 else if (addr.nl.nl_pid != 0)
1086 k = 0; /* not from the kernel */
1087 else if ((size_t) k < sizeof(struct nlmsghdr) ||
1088 (size_t) k < m->hdr->nlmsg_len)
1089 k = -EIO; /* too small (we do accept too big though) */
1090 else if (m->hdr->nlmsg_pid && m->hdr->nlmsg_pid != nl->sockaddr.nl.nl_pid)
1091 k = 0; /* not broadcast and not for us */
1094 switch (m->hdr->nlmsg_type) {
1095 /* check that the size matches the message type */
1097 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
1104 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg)))
1107 struct ifinfomsg *ifi;
1109 ifi = NLMSG_DATA(m->hdr);
1110 UPDATE_RTA(m, IFLA_RTA(ifi));
1112 r = rtnl_message_parse(m,
1117 IFLA_PAYLOAD(m->hdr));
1124 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifaddrmsg)))
1127 struct ifaddrmsg *ifa;
1129 ifa = NLMSG_DATA(m->hdr);
1130 UPDATE_RTA(m, IFA_RTA(ifa));
1132 r = rtnl_message_parse(m,
1137 IFA_PAYLOAD(m->hdr));
1143 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg)))
1148 rtm = NLMSG_DATA(m->hdr);
1149 UPDATE_RTA(m, RTM_RTA(rtm));
1151 r = rtnl_message_parse(m,
1156 RTM_PAYLOAD(m->hdr));
1163 k = 0; /* ignoring message of unknown type */
1167 sd_rtnl_message_unref(m);
1169 /* we probably allocated way too much memory, give it back */
1170 m->hdr = realloc(m->hdr, m->hdr->nlmsg_len);
1177 int sd_rtnl_message_rewind(sd_rtnl_message *m) {
1178 struct ifinfomsg *ifi;
1179 struct ifaddrmsg *ifa;
1182 assert_return(m, -EINVAL);
1183 assert_return(m->sealed, -EPERM);
1184 assert_return(m->hdr, -EINVAL);
1186 switch(m->hdr->nlmsg_type) {
1191 ifi = NLMSG_DATA(m->hdr);
1192 UPDATE_RTA(m, IFLA_RTA(ifi));
1198 ifa = NLMSG_DATA(m->hdr);
1199 UPDATE_RTA(m, IFA_RTA(ifa));
1205 rtm = NLMSG_DATA(m->hdr);
1206 UPDATE_RTA(m, RTM_RTA(rtm));
1213 m->n_containers = 0;