Skip to content

Instantly share code, notes, and snippets.

@rwestphal
Created March 25, 2020 03:59
Show Gist options
  • Save rwestphal/a2db45ac3d69d9b103c4f4f5011fa8de to your computer and use it in GitHub Desktop.
Save rwestphal/a2db45ac3d69d9b103c4f4f5011fa8de 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 lyd_replace(struct lyd_node **target, struct lyd_node *source)
{
struct lyd_difflist *diff;
diff = lyd_diff(*target, source, 0);
for (int i = 0; diff->type[i] != LYD_DIFF_END; i++) {
struct lyd_node *dnode;
struct lyd_node_leaf_list *leaf_dst, *leaf_src;
switch (diff->type[i]) {
case LYD_DIFF_CREATED:
dnode = diff->second[i];
if (diff->first[i]) {
dnode = lyd_dup(dnode, LYD_DUP_OPT_RECURSIVE);
lyd_insert(diff->first[i], dnode);
} else {
//lyd_insert_sibling(target, dnode);
lyd_merge(*target, dnode, LYD_OPT_NOSIBLINGS);
}
break;
case LYD_DIFF_DELETED:
dnode = diff->first[i];
lyd_free(dnode);
break;
case LYD_DIFF_CHANGED:
leaf_src = (struct lyd_node_leaf_list *)diff->first[i];
leaf_dst = (struct lyd_node_leaf_list *)diff->second[i];
lyd_change_leaf(leaf_dst, leaf_src->value_str);
break;
case LYD_DIFF_MOVEDAFTER1:
case LYD_DIFF_MOVEDAFTER2:
/* TODO */
default:
continue;
}
}
lyd_free_diff(diff);
}
#if 0
static void print(struct lyd_node *config)
{
lyd_print_fd(2, config, LYD_JSON, LYP_FORMAT | LYP_WITHSIBLINGS);
}
#endif
static void validate(struct lyd_node **config)
{
if (lyd_validate(config,
LYD_OPT_STRICT | LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL,
ly_ctx)
!= 0)
errx(1, "lyd_validate(): %s", ly_errmsg(ly_ctx));
}
static void commit(const char *xpath, const char *value)
{
lyd_new_path(candidate, ly_ctx, xpath, (void *)value, 0, LYD_PATH_OPT_UPDATE);
validate(&candidate);
lyd_replace(&running, candidate);
}
int main(int argc, char **argv)
{
/* initialization */
ly_ctx = ly_ctx_new("/usr/local/share/yang/", 0);
if (!ly_ctx)
errx(1, "ly_ctx_new()");
if (ly_ctx_load_module(ly_ctx, "frr-interface", NULL) == NULL)
errx(1, "ly_ctx_load_module(): %s", ly_errmsg(ly_ctx));
if (ly_ctx_load_module(ly_ctx, "frr-isisd", NULL) == NULL)
errx(1, "ly_ctx_load_module(): %s", ly_errmsg(ly_ctx));
/* initialize running and candidate configs */
validate(&running);
validate(&candidate);
/* config changes */
//commit("/frr-interface:lib/interface[name='lo'][vrf='default']/frr-isisd:isis/area-tag", "1");
//commit("/frr-interface:lib/interface[name='lo'][vrf='default']/frr-isisd:isis/ipv6-routing", "true");
//commit("/frr-interface:lib/interface[name='eth0'][vrf='default']/frr-isisd:isis/area-tag", "1");
//commit("/frr-interface:lib/interface[name='eth0'][vrf='default']/frr-isisd:isis/ipv6-routing", "true");
//commit("/frr-interface:lib/interface[name='eth0'][vrf='default']/frr-isisd:isis/hello/multiplier/level-1", "3");
commit("/frr-isisd:isis/instance[area-tag='1']", NULL);
commit("/frr-isisd:isis/instance[area-tag='1']/area-address", "49.0000.0000.0000.0011.00");
commit("/frr-isisd:isis/instance[area-tag='1']/multi-topology/ipv6-unicast", NULL);
//commit("/frr-isisd:isis/instance[area-tag='1']/is-type", "level-1");
//commit("/frr-isisd:isis/instance[area-tag='1']/redistribute/ipv4[protocol='ospf'][level='level-1']", NULL);
//commit("/frr-isisd:isis/instance[area-tag='1']/redistribute/ipv4[protocol='rip'][level='level-1']", NULL);
#if 0
/* print configs */
printf("=================\n");
printf("Running config:\n");
printf("=================\n");
print(running);
printf("=================\n");
printf("Candidate config:\n");
printf("=================\n");
print(candidate);
#endif
/* cleanup */
lyd_free_withsiblings(running);
lyd_free_withsiblings(candidate);
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