Skip to content

Instantly share code, notes, and snippets.

@rwestphal
Created April 22, 2018 01:21
Show Gist options
  • Save rwestphal/fc29053e07fe22a1ccbaf7b455f88d97 to your computer and use it in GitHub Desktop.
Save rwestphal/fc29053e07fe22a1ccbaf7b455f88d97 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 <libyang/libyang.h>
static struct ly_ctx *ly_ctx;
static struct lyd_node *running, *candidate;
static void print(struct lyd_node *config)
{
lyd_print_fd(2, config, LYD_JSON,
LYP_FORMAT | LYP_WD_ALL | LYP_KEEPEMPTYCONT
| LYP_WITHSIBLINGS);
}
static void validate(struct lyd_node **config)
{
if (lyd_validate(config, LYD_OPT_STRICT | LYD_OPT_CONFIG, ly_ctx) != 0)
errx(1, "lyd_validate(): %s", ly_errmsg(ly_ctx));
}
static void diff(struct lyd_node *config1, struct lyd_node *config2)
{
struct lyd_difflist *diff;
int i = 0;
// diff = lyd_diff(config1, config2, 0);
diff = lyd_diff(config1, config2, LYD_DIFFOPT_WITHDEFAULTS);
if (diff == NULL)
errx(1, "lyd_diff(): %s", ly_errmsg(ly_ctx));
while (diff->type[i] != LYD_DIFF_END) {
LYD_DIFFTYPE type;
struct lyd_node *first;
struct lyd_node *second;
char *xpath;
type = diff->type[i];
first = diff->first[i];
second = diff->second[i];
i++;
switch (type) {
case LYD_DIFF_CREATED:
printf("LYD_DIFF_CREATED:\n");
xpath = lyd_path(second);
break;
case LYD_DIFF_DELETED:
printf("LYD_DIFF_DELETED:\n");
xpath = lyd_path(first);
break;
case LYD_DIFF_CHANGED:
printf("LYD_DIFF_CHANGED:\n");
xpath = lyd_path(second);
break;
case LYD_DIFF_MOVEDAFTER1:
printf("LYD_DIFF_MOVEDAFTER1:\n");
break;
case LYD_DIFF_MOVEDAFTER2:
printf("LYD_DIFF_MOVEDAFTER2:\n");
break;
default:
printf("unknown diff type:\n");
break;
}
printf(" xpath: %s\n", xpath);
free(xpath);
}
lyd_free_diff(diff);
}
int main(int argc, char **argv)
{
const struct lys_module *module;
struct lyd_node *node;
const char *xpath = "/frr-ripd:ripd/instance/allow-ecmp";
/* initialization */
ly_ctx = ly_ctx_new(NULL, 0);
if (!ly_ctx)
errx(1, "ly_ctx_new(): %s", ly_errmsg(ly_ctx));
ly_ctx_set_searchdir(ly_ctx, "/usr/local/share/yang/");
module = lys_parse_path(ly_ctx, "/usr/local/share/yang/frr-ripd.yang",
LYS_IN_YANG);
if (module == NULL)
errx(1, "lys_parse_path(): %s", ly_errmsg(ly_ctx));
validate(&running);
validate(&candidate);
/* change candidate config - add presence container */
ly_errno = 0;
node = lyd_new_path(candidate, ly_ctx, xpath, (void *)"true", 0,
LYD_PATH_OPT_UPDATE);
if (node == NULL && ly_errno)
errx(1, "lyd_new_path(): %s", ly_errmsg(ly_ctx));
validate(&candidate);
/* print configs and the difference between them */
printf("=================\n");
printf("RUNNING CONFIG:\n");
printf("=================\n");
print(running);
printf("=================\n");
printf("CANDIDATE CONFIG:\n");
printf("=================\n");
print(candidate);
printf("=================\n");
printf("DIFF:\n");
printf("=================\n");
diff(running, candidate);
/* cleanup */
lyd_free_withsiblings(candidate);
lyd_free_withsiblings(running);
ly_ctx_remove_module(module, NULL);
ly_ctx_destroy(ly_ctx, NULL);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment