+ 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(!m->current_container, -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(m->current_container, -EINVAL);
+
+ m->current_container = NULL;
+
+ 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);
+ assert(type);
+ assert(data);
+
+ remaining_size = (uint8_t *) m->hdr + m->hdr->nlmsg_len - (uint8_t *) m->next_rta;
+
+ if (!RTA_OK(m->next_rta, 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) &&
+ m->next_rta->rta_type == IFLA_LINKINFO)
+ return -EINVAL;
+
+ *data = RTA_DATA(m->next_rta);
+ *type = m->next_rta->rta_type;
+
+ m->next_rta = RTA_NEXT(m->next_rta, remaining_size);
+
+ return 1;