Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
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;
}