libyang icon indicating copy to clipboard operation
libyang copied to clipboard

Duplicated extensions in rpc input/output

Open olivier-matz-6wind opened this issue 1 year ago • 1 comments

The extensions appear twice in the compiled schema node for rpc input and output. The following code can be used to reproduce the issue:

#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>

#include <libyang/libyang.h>

const char *yang = "module my-mod {\n"
                "  yang-version 1.1;\n"
                "  namespace \"http://example.com/my-mod\";\n"
                "  prefix my-mod;\n"
                "\n"
                "  extension my-ext {\n"
                "    argument arg;\n"
                "    description \"my desc\";\n"
                "  }\n"
                "\n"
                "  extension my-ext2 {\n"
                "    description \"my desc\";\n"
                "  }\n"
                "\n"
                "  rpc my-rpc {\n"
                "    my-mod:my-ext arg-rpc;\n"
                "    input {\n"
                "      my-mod:my-ext arg-input;\n"
                "      my-mod:my-ext2;\n"
                "      leaf in-value {\n"
                "        my-mod:my-ext arg-in-value;\n"
                "        type uint32;\n"
                "      }\n"
                "    }\n"
                "    output {\n"
                "      my-mod:my-ext arg-output;\n"
                "      leaf out-value {\n"
                "        my-mod:my-ext arg-out-value;\n"
                "        type uint32;\n"
                "      }\n"
                "    }\n"
                "  }\n"
                "}\n";

static void
print_extensions(const struct lysc_node *snode)
{
    const struct lysc_ext_instance *ext_table = snode->exts;
    const struct lysc_node *iter;
    size_t i;

    printf("%s: %ld extensions\n", snode->name, LY_ARRAY_COUNT(ext_table));

    for (i = 0; i < LY_ARRAY_COUNT(ext_table); i++) {
        const struct lysc_ext_instance *ext = ext_table + i;

        printf("  %s %s\n", ext->def->name, ext->argument);
    }

    LY_LIST_FOR(lysc_node_child(snode), iter) {
        print_extensions(iter);
    }
}

int main(int argc, char **argv)
{
    const struct lysc_node *snode = NULL;
    struct lys_module *mod = NULL;
    struct ly_ctx *ctx = NULL;
    int exit_code = 1;
    int ret;

    (void)argc;
    (void)argv;

    ret = ly_ctx_new(NULL, 0, &ctx);
    if (ret != LY_SUCCESS) {
        fprintf(stderr, "ly_ctx_new() failed: %s\n", ly_strerrcode(ret));
        goto fail;
    }

    ret = lys_parse_mem(ctx, yang, LYS_IN_YANG, &mod);
    if (ret != LY_SUCCESS) {
        fprintf(stderr, "lys_parse_mem() failed: %s\n", ly_strerrcode(ret));
        goto fail;
    }

    while ((snode = lys_getnext(snode, NULL, mod->compiled, 0)) != NULL) {
        print_extensions(snode);
    }
    exit_code = 0;

fail:
    ly_ctx_destroy(ctx);

    return exit_code;
}

The output of this program compiled with latest libyang (3.1.3) is:

my-rpc: 1 extensions
  my-ext arg-rpc
input: 4 extensions
  my-ext arg-input
  my-ext2 (null)
  my-ext arg-input
  my-ext2 (null)
in-value: 1 extensions
  my-ext arg-in-value
output: 2 extensions
  my-ext arg-output
  my-ext arg-output
out-value: 1 extensions
  my-ext arg-out-value

The extensions of input and output are duplicated.

Note that initially I started to write this example code to reproduce another issue of my application where an extension does not appear at all on an rpc input schema node (node->exts is NULL). I don't know if these 2 issues are related or not.

olivier-matz-6wind avatar Aug 02 '24 13:08 olivier-matz-6wind

After some analysis, it appears that the extensions are compiled once in lys_compile_node_action_inout(), then another time in lys_compile_node_(), which adds the same extensions again.

I don't know if it's the proper fix, but removing COMPILE_EXTS_GOTO() from lys_compile_node_action_inout() seems to solve the issue. I'll submit a pull request for this.

About the second issue (node->exts is NULL), it's not related so I'm opening a new issue.

olivier-matz-6wind avatar Aug 05 '24 11:08 olivier-matz-6wind