int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned short type, const char *key) { const NLTypeSystemUnion *type_system_union; int r; assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type); if (r < 0) return r; r = type_system_union_get_type_system(type_system_union, &m->containers[m->n_containers + 1].type_system, key); if (r < 0) return r; r = sd_netlink_message_append_string(m, type_system_union->match, key); if (r < 0) return r; /* do we evere need non-null size */ r = add_rtattr(m, type | NLA_F_NESTED, NULL, 0); if (r < 0) return r; m->containers[m->n_containers ++].offset = r; return 0; }
int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type) { size_t size; int r; assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE); r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_NESTED); if (r < 0) { const NLTypeSystemUnion *type_system_union; int family; r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_UNION); if (r < 0) return r; r = sd_rtnl_message_get_family(m, &family); if (r < 0) return r; r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type); if (r < 0) return r; r = type_system_union_protocol_get_type_system(type_system_union, &m->containers[m->n_containers + 1].type_system, family); if (r < 0) return r; } else { r = type_system_get_type_system(m->containers[m->n_containers].type_system, &m->containers[m->n_containers + 1].type_system, type); if (r < 0) return r; } r = add_rtattr(m, type | NLA_F_NESTED, NULL, size); if (r < 0) return r; m->containers[m->n_containers ++].offset = r; return 0; }
int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type_id) { const NLType *nl_type; const NLTypeSystem *type_system; void *container; uint16_t type; size_t size; int r; assert_return(m, -EINVAL); assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL); r = type_system_get_type(m->containers[m->n_containers].type_system, &nl_type, type_id); if (r < 0) return r; type = type_get_type(nl_type); if (type == NETLINK_TYPE_NESTED) { r = type_system_get_type_system(m->containers[m->n_containers].type_system, &type_system, type_id); if (r < 0) return r; } else if (type == NETLINK_TYPE_UNION) { const NLTypeSystemUnion *type_system_union; r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type_id); if (r < 0) return r; switch (type_system_union->match_type) { case NL_MATCH_SIBLING: { const char *key; r = sd_netlink_message_read_string(m, type_system_union->match, &key); if (r < 0) return r; r = type_system_union_get_type_system(type_system_union, &type_system, key); if (r < 0) return r; break; } case NL_MATCH_PROTOCOL: { int family; r = sd_rtnl_message_get_family(m, &family); if (r < 0) return r; r = type_system_union_protocol_get_type_system(type_system_union, &type_system, family); if (r < 0) return r; break; } default: assert_not_reached("sd-netlink: invalid type system union type"); } } else return -EINVAL; r = netlink_message_read_internal(m, type_id, &container, NULL); if (r < 0) return r; else size = (size_t)r; m->n_containers ++; r = netlink_container_parse(m, &m->containers[m->n_containers], type_system_get_count(type_system), container, size); if (r < 0) { m->n_containers --; return r; } m->containers[m->n_containers].type_system = type_system; return 0; }
int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type) { const NLType *nl_type; const NLTypeSystem *type_system; void *container; size_t size; int r; assert_return(m, -EINVAL); assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL); r = type_system_get_type(m->container_type_system[m->n_containers], &nl_type, type); if (r < 0) return r; if (nl_type->type == NLA_NESTED) { r = type_system_get_type_system(m->container_type_system[m->n_containers], &type_system, type); if (r < 0) return r; } else if (nl_type->type == NLA_UNION) { const NLTypeSystemUnion *type_system_union; const char *key; r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type); if (r < 0) return r; r = sd_rtnl_message_read_string(m, type_system_union->match, &key); if (r < 0) return r; r = type_system_union_get_type_system(type_system_union, &type_system, key); if (r < 0) return r; } else return -EINVAL; r = rtnl_message_read_internal(m, type, &container); if (r < 0) return r; else size = (size_t)r; m->n_containers ++; r = rtnl_message_parse(m, &m->rta_offset_tb[m->n_containers], &m->rta_tb_size[m->n_containers], type_system->max, container, size); if (r < 0) { m->n_containers --; return r; } m->container_type_system[m->n_containers] = type_system; return 0; }