+ r = add_rtattr(m, type, data, ETH_ALEN);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
+int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
+ uint16_t rtm_type;
+
+ assert_return(m, -EINVAL);
+ assert_return(!CURRENT_CONTAINER(m), -EINVAL);
+
+ sd_rtnl_message_get_type(m, &rtm_type);
+
+ if (message_type_is_link(rtm_type)) {
+ if (type == IFLA_LINKINFO)
+ return add_rtattr(m, type, NULL, 0);
+ else
+ return -ENOTSUP;
+ } else
+ return -ENOTSUP;
+
+ return 0;
+}
+
+int sd_rtnl_message_close_container(sd_rtnl_message *m) {
+ assert_return(m, -EINVAL);
+ assert_return(CURRENT_CONTAINER(m), -EINVAL);
+
+ m->container_offset = 0;
+
+ return 0;
+}
+
+int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data) {
+ size_t remaining_size;
+ uint16_t rtm_type;
+ int r;
+
+ assert(m);
+ assert(m->next_rta_offset);
+ assert(type);
+ assert(data);
+
+ remaining_size = m->hdr->nlmsg_len - m->next_rta_offset;
+
+ if (!RTA_OK(NEXT_RTA(m), remaining_size))
+ return 0;
+
+ /* make sure we don't try to read a container
+ * TODO: add support for entering containers for reading */
+ r = sd_rtnl_message_get_type(m, &rtm_type);
+ if (r < 0)
+ return r;
+
+ if (message_type_is_link(rtm_type) &&
+ NEXT_RTA(m)->rta_type == IFLA_LINKINFO)
+ return -EINVAL;
+
+ *data = RTA_DATA(NEXT_RTA(m));
+ *type = NEXT_RTA(m)->rta_type;
+
+ UPDATE_RTA(m, RTA_NEXT(NEXT_RTA(m), remaining_size));
+
+ return 1;