Skip to content

Instantly share code, notes, and snippets.

@rwestphal
Created April 2, 2018 19:02
Show Gist options
  • Save rwestphal/16141e6d1b08dc549af574678c6560c5 to your computer and use it in GitHub Desktop.
Save rwestphal/16141e6d1b08dc549af574678c6560c5 to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <err.h>
#include <assert.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <libyang/libyang.h>
static struct ly_ctx *ctx;
static struct lyd_node *running, *candidate;
static void print(struct lyd_node *config)
{
lyd_print_fd(2, config, LYD_JSON, LYP_FORMAT);
}
static void validate(struct lyd_node *config)
{
#if 0
/*
* HACK: don't validate if only the top-level node is present.
*/
struct ly_set *set;
set = lyd_find_path(candidate, "//*");
if (set == NULL)
errx(1, "lyd_find_path");
if (set->number == 1)
return;
#endif
if (lyd_validate(&config, LYD_OPT_CONFIG, ctx) != 0)
errx(1, "lyd_validate");
}
static void create_candidate(void)
{
candidate = lyd_dup(running, 1);
if (candidate == NULL)
errx(1, "lyd_dup");
}
static void merge_candidate(void)
{
lyd_free_withsiblings(running);
running = candidate;
candidate = NULL;
}
int main(int argc, char **argv)
{
const struct lys_module *module;
struct lyd_node *node;
struct ly_set *set;
const char *xpath_container = "/frr-ripd:ripd/instance";
/* initialization */
ctx = ly_ctx_new(NULL, 0);
if (!ctx)
errx(1, "ly_ctx_new");
ly_ctx_set_searchdir(ctx, "/usr/local/share/yang/");
module = lys_parse_path(ctx, "/usr/local/share/yang/frr-ripd.yang",
LYS_IN_YANG);
if (!module)
errx(1, "lys_parse_path");
running = lyd_new(NULL, module, "ripd");
for (int i = 0; i < 2; i++) {
printf("===========================================\n");
printf("ADDING CONTAINER:\n");
printf("===========================================\n");
/* 1 - Create candidate config */
create_candidate();
/* 2 - Change candidate config - add presence container */
ly_errno = 0;
node = lyd_new_path(candidate, ctx, xpath_container, NULL, 0,
LYD_PATH_OPT_UPDATE);
if (node == NULL && ly_errno)
errx(1, "lyd_new_path");
/*
* 3 - Validate candidate config
* 4 - Merge candidate into running
* 5 - Print running config
*/
validate(candidate);
merge_candidate();
print(running);
printf("===========================================\n");
printf("DELETING CONTAINER:\n");
printf("===========================================\n");
/* 1 - Create candidate config */
create_candidate();
/* 2 - Change candidate config - delete presence container */
set = lyd_find_path(candidate, xpath_container);
if (set == NULL)
errx(1, "lyd_find_path");
if (set->number != 1)
errx(1, "couldn't find node");
node = set->set.d[0];
ly_set_free(set);
lyd_free(node);
/*
* 3 - Validate candidate config
* 4 - Merge candidate into running
* 5 - Print running config
*/
validate(candidate);
merge_candidate();
print(running);
}
/* cleanup */
lyd_free_withsiblings(running);
ly_ctx_remove_module(module, NULL);
ly_ctx_destroy(ctx, NULL);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment