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_NEWLINK ||
170 nlmsg_type == RTM_SETLINK || index > 0, -EINVAL);
171 assert_return(ret, -EINVAL);
173 r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifinfomsg)));
177 (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
178 (*ret)->hdr->nlmsg_type = nlmsg_type;
179 if (nlmsg_type == RTM_NEWLINK)
180 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE;
182 ifi = NLMSG_DATA((*ret)->hdr);
184 ifi->ifi_family = AF_UNSPEC;
185 ifi->ifi_index = index;
187 UPDATE_RTA(*ret, IFLA_RTA(ifi));
192 int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
193 struct ifaddrmsg *ifa;
195 assert_return(m, -EINVAL);
196 assert_return(m->hdr, -EINVAL);
197 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
199 ifa = NLMSG_DATA(m->hdr);
201 if ((ifa->ifa_family == AF_INET && prefixlen > 32) ||
202 (ifa->ifa_family == AF_INET6 && prefixlen > 128))
205 ifa->ifa_prefixlen = prefixlen;
210 int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags) {
211 struct ifaddrmsg *ifa;
213 assert_return(m, -EINVAL);
214 assert_return(m->hdr, -EINVAL);
215 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
217 ifa = NLMSG_DATA(m->hdr);
219 ifa->ifa_flags = flags;
224 int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) {
225 struct ifaddrmsg *ifa;
227 assert_return(m, -EINVAL);
228 assert_return(m->hdr, -EINVAL);
229 assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
231 ifa = NLMSG_DATA(m->hdr);
233 ifa->ifa_scope = scope;
238 int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
239 uint16_t nlmsg_type, int index,
240 unsigned char family) {
241 struct ifaddrmsg *ifa;
244 assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
245 assert_return(index > 0, -EINVAL);
246 assert_return(family == AF_INET || family == AF_INET6, -EINVAL);
247 assert_return(ret, -EINVAL);
249 r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifaddrmsg)));
253 (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
254 (*ret)->hdr->nlmsg_type = nlmsg_type;
255 if (nlmsg_type == RTM_GETADDR && family == AF_INET)
256 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
258 ifa = NLMSG_DATA((*ret)->hdr);
260 ifa->ifa_index = index;
261 ifa->ifa_family = family;
262 if (family == AF_INET)
263 ifa->ifa_prefixlen = 32;
264 else if (family == AF_INET6)
265 ifa->ifa_prefixlen = 128;
267 UPDATE_RTA(*ret, IFA_RTA(ifa));
272 sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
274 assert_se(REFCNT_INC(m->n_ref) >= 2);
279 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
280 if (m && REFCNT_DEC(m->n_ref) <= 0) {
281 sd_rtnl_unref(m->rtnl);
283 free(m->rta_offset_tb);
290 int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type) {
291 assert_return(m, -EINVAL);
292 assert_return(type, -EINVAL);
294 *type = m->hdr->nlmsg_type;
299 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex) {
300 struct ifinfomsg *ifi;
302 assert_return(m, -EINVAL);
303 assert_return(m->hdr, -EINVAL);
304 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
305 assert_return(ifindex, -EINVAL);
307 ifi = NLMSG_DATA(m->hdr);
309 *ifindex = ifi->ifi_index;
314 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
315 struct ifinfomsg *ifi;
317 assert_return(m, -EINVAL);
318 assert_return(m->hdr, -EINVAL);
319 assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
320 assert_return(flags, -EINVAL);
322 ifi = NLMSG_DATA(m->hdr);
324 *flags = ifi->ifi_flags;
329 /* If successful the updated message will be correctly aligned, if
330 unsuccessful the old message is untouched. */
331 static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
332 uint32_t rta_length, message_length;
333 struct nlmsghdr *new_hdr;
341 assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
342 assert(!data || data_length > 0);
343 assert(data || m->n_containers < RTNL_CONTAINER_DEPTH);
345 /* get the size of the new rta attribute (with padding at the end) */
346 rta_length = RTA_LENGTH(data_length);
348 /* get the new message size (with padding at the end) */
349 message_length = m->hdr->nlmsg_len + RTA_ALIGN(rta_length);
351 /* realloc to fit the new attribute */
352 new_hdr = realloc(m->hdr, message_length);
357 /* get pointer to the attribute we are about to add */
358 rta = (struct rtattr *) ((uint8_t *) m->hdr + m->hdr->nlmsg_len);
360 /* if we are inside containers, extend them */
361 for (i = 0; i < m->n_containers; i++)
362 GET_CONTAINER(m, i)->rta_len += message_length - m->hdr->nlmsg_len;
364 /* fill in the attribute */
365 rta->rta_type = type;
366 rta->rta_len = rta_length;
368 /* this is the start of a new container */
369 m->container_offsets[m->n_containers ++] = m->hdr->nlmsg_len;
371 /* we don't deal with the case where the user lies about the type
372 * and gives us too little data (so don't do that)
374 padding = mempcpy(RTA_DATA(rta), data, data_length);
375 /* make sure also the padding at the end of the message is initialized */
377 (uint8_t *) m->hdr + message_length - (uint8_t *) padding);
380 /* update message size */
381 m->hdr->nlmsg_len = message_length;
386 int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
390 assert_return(m, -EINVAL);
391 assert_return(!m->sealed, -EPERM);
392 assert_return(data, -EINVAL);
394 r = sd_rtnl_message_get_type(m, &rtm_type);
398 /* check that the type is correct */
404 if (m->n_containers == 1) {
405 if (GET_CONTAINER(m, 0)->rta_type != IFLA_LINKINFO ||
406 type != IFLA_INFO_KIND)
422 if (type != IFA_LABEL)
429 r = add_rtattr(m, type, data, strlen(data) + 1);
436 int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data) {
440 assert_return(m, -EINVAL);
441 assert_return(!m->sealed, -EPERM);
443 r = sd_rtnl_message_get_type(m, &rtm_type);
466 r = add_rtattr(m, type, &data, sizeof(uint8_t));
474 int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t data) {
478 assert_return(m, -EINVAL);
479 assert_return(!m->sealed, -EPERM);
481 r = sd_rtnl_message_get_type(m, &rtm_type);
485 /* check that the type is correct */
491 if (m->n_containers == 2 &&
492 GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO &&
493 GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA &&
494 type == IFLA_VLAN_ID)
503 r = add_rtattr(m, type, &data, sizeof(uint16_t));
510 int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data) {
514 assert_return(m, -EINVAL);
515 assert_return(!m->sealed, -EPERM);
517 r = sd_rtnl_message_get_type(m, &rtm_type);
521 /* check that the type is correct */
535 case IFLA_NET_NS_PID:
536 case IFLA_PROMISCUITY:
537 case IFLA_NUM_TX_QUEUES:
538 case IFLA_NUM_RX_QUEUES:
539 case IFLA_MACVLAN_MODE:
563 r = add_rtattr(m, type, &data, sizeof(uint32_t));
570 int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data) {
571 struct ifaddrmsg *ifa;
576 assert_return(m, -EINVAL);
577 assert_return(!m->sealed, -EPERM);
578 assert_return(data, -EINVAL);
580 r = sd_rtnl_message_get_type(m, &rtm_type);
584 /* check that the type is correct */
594 ifa = NLMSG_DATA(m->hdr);
596 if (ifa->ifa_family != AF_INET)
611 rtm = NLMSG_DATA(m->hdr);
613 if (rtm->rtm_family != AF_INET)
625 r = add_rtattr(m, type, data, sizeof(struct in_addr));
632 int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data) {
633 struct ifaddrmsg *ifa;
638 assert_return(m, -EINVAL);
639 assert_return(!m->sealed, -EPERM);
640 assert_return(data, -EINVAL);
642 r = sd_rtnl_message_get_type(m, &rtm_type);
646 /* check that the type is correct */
656 ifa = NLMSG_DATA(m->hdr);
658 if (ifa->ifa_family != AF_INET6)
673 rtm = NLMSG_DATA(m->hdr);
675 if (rtm->rtm_family != AF_INET6)
686 r = add_rtattr(m, type, data, sizeof(struct in6_addr));
693 int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data) {
697 assert_return(m, -EINVAL);
698 assert_return(!m->sealed, -EPERM);
699 assert_return(data, -EINVAL);
701 sd_rtnl_message_get_type(m, &rtm_type);
720 r = add_rtattr(m, type, data, ETH_ALEN);
727 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
730 assert_return(m, -EINVAL);
731 assert_return(!m->sealed, -EPERM);
733 sd_rtnl_message_get_type(m, &rtm_type);
735 if (rtnl_message_type_is_link(rtm_type)) {
737 if ((type == IFLA_LINKINFO && m->n_containers == 0) ||
738 (type == IFLA_INFO_DATA && m->n_containers == 1 &&
739 GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO))
740 return add_rtattr(m, type, NULL, 0);
741 else if (type == VETH_INFO_PEER && m->n_containers == 2 &&
742 GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA &&
743 GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO)
744 return add_rtattr(m, type, NULL, sizeof(struct ifinfomsg));
750 int sd_rtnl_message_close_container(sd_rtnl_message *m) {
751 assert_return(m, -EINVAL);
752 assert_return(!m->sealed, -EPERM);
753 assert_return(m->n_containers > 0, -EINVAL);
760 int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data) {
761 size_t remaining_size;
765 assert_return(m, -EINVAL);
766 assert_return(m->sealed, -EPERM);
767 assert_return(m->next_rta_offset, -EINVAL);
768 assert_return(type, -EINVAL);
769 assert_return(data, -EINVAL);
771 /* only read until the end of the current container */
773 remaining_size = GET_CONTAINER(m, m->n_containers - 1)->rta_len -
774 (m->next_rta_offset -
775 m->container_offsets[m->n_containers - 1]);
777 remaining_size = m->hdr->nlmsg_len - m->next_rta_offset;
779 if (!RTA_OK(NEXT_RTA(m), remaining_size))
782 /* if we read a container, return its type, but do not enter it*/
783 r = sd_rtnl_message_get_type(m, &rtm_type);
787 *type = NEXT_RTA(m)->rta_type;
789 if (rtnl_message_type_is_link(rtm_type) &&
790 ((m->n_containers == 0 &&
791 NEXT_RTA(m)->rta_type == IFLA_LINKINFO) ||
792 (m->n_containers == 1 &&
793 GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO &&
794 NEXT_RTA(m)->rta_type == IFLA_INFO_DATA)))
797 *data = RTA_DATA(NEXT_RTA(m));
799 UPDATE_RTA(m, RTA_NEXT(NEXT_RTA(m), remaining_size));
804 int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
805 assert_return(m, -EINVAL);
806 assert_return(m->sealed, -EPERM);
807 assert_return(data, -EINVAL);
808 assert_return(m->rta_offset_tb, -EINVAL);
809 assert_return(type < m->rta_tb_size, -EINVAL);
811 if(!m->rta_offset_tb[type])
814 *data = RTA_DATA((struct rtattr *)((uint8_t *) m->hdr + m->rta_offset_tb[type]));
819 int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, char **data) {
823 assert_return(data, -EINVAL);
825 r = rtnl_message_read_internal(m, type, &attr_data);
829 *data = (char *) attr_data;
834 int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data) {
838 assert_return(data, -EINVAL);
840 r = rtnl_message_read_internal(m, type, &attr_data);
844 *data = *(uint8_t *) attr_data;
849 int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data) {
853 assert_return(data, -EINVAL);
855 r = rtnl_message_read_internal(m, type, &attr_data);
859 *data = *(uint16_t *) attr_data;
864 int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data) {
868 assert_return(data, -EINVAL);
870 r = rtnl_message_read_internal(m, type, &attr_data);
874 *data = *(uint32_t *) attr_data;
879 int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data) {
883 assert_return(data, -EINVAL);
885 r = rtnl_message_read_internal(m, type, &attr_data);
889 memcpy(data, attr_data, sizeof(struct ether_addr));
894 int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
898 assert_return(data, -EINVAL);
900 r = rtnl_message_read_internal(m, type, &attr_data);
904 memcpy(data, attr_data, sizeof(struct in_addr));
909 int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data) {
913 assert_return(data, -EINVAL);
915 r = rtnl_message_read_internal(m, type, &attr_data);
919 memcpy(data, attr_data, sizeof(struct in6_addr));
924 int sd_rtnl_message_exit_container(sd_rtnl_message *m) {
925 assert_return(m, -EINVAL);
926 assert_return(m->sealed, -EINVAL);
927 assert_return(m->n_containers > 0, -EINVAL);
934 uint32_t rtnl_message_get_serial(sd_rtnl_message *m) {
938 return m->hdr->nlmsg_seq;
941 int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
942 struct nlmsgerr *err;
944 assert_return(m, -EINVAL);
945 assert_return(m->hdr, -EINVAL);
947 if (m->hdr->nlmsg_type != NLMSG_ERROR)
950 err = NLMSG_DATA(m->hdr);
955 int rtnl_message_seal(sd_rtnl *nl, sd_rtnl_message *m) {
965 m->hdr->nlmsg_seq = nl->serial++;
969 r = sd_rtnl_message_rewind(m);
976 static int message_receive_need(sd_rtnl *rtnl, size_t *need) {
980 /* ioctl(rtnl->fd, FIONREAD, &need)
981 Does not appear to work on netlink sockets. libnl uses
982 MSG_PEEK instead. I don't know if that is worth the
985 For now we simply use the maximum message size the kernel
986 may use (NLMSG_GOODSIZE), and then realloc to the actual
987 size after reading the message (hence avoiding huge memory
988 usage in case many small messages are kept around) */
996 int rtnl_message_parse(sd_rtnl_message *m,
997 size_t **rta_offset_tb,
998 unsigned short *rta_tb_size,
1001 unsigned int rt_len) {
1005 tb = (size_t *) new0(size_t *, max);
1011 for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
1012 type = rta->rta_type;
1014 if (type < max && !tb[type])
1015 tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
1018 *rta_offset_tb = tb;
1023 /* returns the number of bytes sent, or a negative error code */
1024 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
1027 struct sockaddr_nl nl;
1029 .nl.nl_family = AF_NETLINK,
1037 k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
1038 0, &addr.sa, sizeof(addr));
1040 return (errno == EAGAIN) ? 0 : -errno;
1045 /* On success, the number of bytes received is returned and *ret points to the received message
1046 * which has a valid header and the correct size.
1047 * If nothing useful was received 0 is returned.
1048 * On failure, a negative error code is returned.
1050 int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
1054 struct sockaddr_nl nl;
1064 r = message_receive_need(nl, &need);
1068 r = message_new(nl, &m, need);
1072 /* don't allow sealing/appending to received messages */
1075 addr_len = sizeof(addr);
1077 k = recvfrom(nl->fd, m->hdr, need,
1078 0, &addr.sa, &addr_len);
1080 k = (errno == EAGAIN) ? 0 : -errno; /* no data */
1082 k = -ECONNRESET; /* connection was closed by the kernel */
1083 else if (addr_len != sizeof(addr.nl) ||
1084 addr.nl.nl_family != AF_NETLINK)
1085 k = -EIO; /* not a netlink message */
1086 else if (addr.nl.nl_pid != 0)
1087 k = 0; /* not from the kernel */
1088 else if ((size_t) k < sizeof(struct nlmsghdr) ||
1089 (size_t) k < m->hdr->nlmsg_len)
1090 k = -EIO; /* too small (we do accept too big though) */
1091 else if (m->hdr->nlmsg_pid && m->hdr->nlmsg_pid != nl->sockaddr.nl.nl_pid)
1092 k = 0; /* not broadcast and not for us */
1095 switch (m->hdr->nlmsg_type) {
1096 /* check that the size matches the message type */
1098 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
1105 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg)))
1108 struct ifinfomsg *ifi;
1110 ifi = NLMSG_DATA(m->hdr);
1111 UPDATE_RTA(m, IFLA_RTA(ifi));
1113 r = rtnl_message_parse(m,
1118 IFLA_PAYLOAD(m->hdr));
1125 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifaddrmsg)))
1128 struct ifaddrmsg *ifa;
1130 ifa = NLMSG_DATA(m->hdr);
1131 UPDATE_RTA(m, IFA_RTA(ifa));
1133 r = rtnl_message_parse(m,
1138 IFA_PAYLOAD(m->hdr));
1144 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg)))
1149 rtm = NLMSG_DATA(m->hdr);
1150 UPDATE_RTA(m, RTM_RTA(rtm));
1152 r = rtnl_message_parse(m,
1157 RTM_PAYLOAD(m->hdr));
1164 k = 0; /* ignoring message of unknown type */
1168 sd_rtnl_message_unref(m);
1170 /* we probably allocated way too much memory, give it back */
1171 m->hdr = realloc(m->hdr, m->hdr->nlmsg_len);
1178 int sd_rtnl_message_rewind(sd_rtnl_message *m) {
1179 struct ifinfomsg *ifi;
1180 struct ifaddrmsg *ifa;
1183 assert_return(m, -EINVAL);
1184 assert_return(m->sealed, -EPERM);
1185 assert_return(m->hdr, -EINVAL);
1187 switch(m->hdr->nlmsg_type) {
1192 ifi = NLMSG_DATA(m->hdr);
1193 UPDATE_RTA(m, IFLA_RTA(ifi));
1199 ifa = NLMSG_DATA(m->hdr);
1200 UPDATE_RTA(m, IFA_RTA(ifa));
1206 rtm = NLMSG_DATA(m->hdr);
1207 UPDATE_RTA(m, RTM_RTA(rtm));
1214 m->n_containers = 0;