static int netlink_container_parse(sd_netlink_message *m,
struct netlink_container *container,
- int count,
struct rtattr *rta,
unsigned rt_len) {
_cleanup_free_ struct netlink_attribute *attributes = NULL;
-
- attributes = new0(struct netlink_attribute, count);
- if (!attributes)
- return -ENOMEM;
+ size_t n_allocated = 0;
for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
unsigned short type;
type = RTA_TYPE(rta);
- /* if the kernel is newer than the headers we used
- when building, we ignore out-of-range attributes */
- if (type >= count)
- continue;
+ if (!GREEDY_REALLOC0(attributes, n_allocated, type + 1))
+ return -ENOMEM;
if (attributes[type].offset != 0)
log_debug("rtnl: message parse - overwriting repeated attribute");
}
container->attributes = TAKE_PTR(attributes);
- container->n_attributes = count;
+ container->n_attributes = n_allocated;
return 0;
}
r = netlink_container_parse(m,
&m->containers[m->n_containers],
- type_system_get_count(type_system),
container,
size);
if (r < 0) {
return 0;
}
+int sd_netlink_message_enter_array(sd_netlink_message *m, unsigned short type_id) {
+ void *container;
+ size_t size;
+ int r;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
+
+ r = netlink_message_read_internal(m, type_id, &container, NULL);
+ if (r < 0)
+ return r;
+
+ size = (size_t) r;
+
+ m->n_containers++;
+
+ r = netlink_container_parse(m,
+ &m->containers[m->n_containers],
+ container,
+ size);
+ if (r < 0) {
+ m->n_containers--;
+ return r;
+ }
+
+ m->containers[m->n_containers].type_system = m->containers[m->n_containers - 1].type_system;
+
+ return 0;
+}
+
int sd_netlink_message_exit_container(sd_netlink_message *m) {
assert_return(m, -EINVAL);
assert_return(m->sealed, -EINVAL);
r = netlink_container_parse(m,
&m->containers[m->n_containers],
- type_system_get_count(type_system),
(struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)),
NLMSG_PAYLOAD(m->hdr, size));
if (r < 0)
int sd_netlink_message_read_in_addr(sd_netlink_message *m, unsigned short type, struct in_addr *data);
int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, struct in6_addr *data);
int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type);
+int sd_netlink_message_enter_array(sd_netlink_message *m, unsigned short type);
int sd_netlink_message_exit_container(sd_netlink_message *m);
int sd_netlink_message_open_array(sd_netlink_message *m, uint16_t type);