diff options
| author | Christian Hopps <chopps@gmail.com> | 2021-05-04 10:41:58 -0400 | 
|---|---|---|
| committer | Christian Hopps <chopps@labn.net> | 2021-05-13 16:24:48 -0400 | 
| commit | 3bb513c399c2e7c8dd597b7399dd7c0f064842d0 (patch) | |
| tree | 14f3e677c49fce272946788f8a8b8f3f8a3e26b5 /lib/yang_translator.c | |
| parent | 17daea8a184c0e85b9788329f3c808ceab916ad5 (diff) | |
lib: adapt to version 2 of libyang
Compile with v2.0.0 tag of `libyang2` branch of:
https://github.com/CESNET/libyang
staticd init load time of 10k routes now 6s vs ly1 time of 150s
Signed-off-by: Christian Hopps <chopps@labn.net>
Diffstat (limited to 'lib/yang_translator.c')
| -rw-r--r-- | lib/yang_translator.c | 129 | 
1 files changed, 67 insertions, 62 deletions
diff --git a/lib/yang_translator.c b/lib/yang_translator.c index 5b1d96f24c..d562e4d29e 100644 --- a/lib/yang_translator.c +++ b/lib/yang_translator.c @@ -93,7 +93,7 @@ yang_mapping_lookup(const struct yang_translator *translator, int dir,  }  static void yang_mapping_add(struct yang_translator *translator, int dir, -			     const struct lys_node *snode, +			     const struct lysc_node *snode,  			     const char *xpath_from_fmt,  			     const char *xpath_to_fmt)  { @@ -135,13 +135,15 @@ struct yang_translator *yang_translator_load(const char *path)  	struct lyd_node *dnode;  	struct ly_set *set;  	struct listnode *ln; +	LY_ERR err;  	/* Load module translator (JSON file). */ -	dnode = lyd_parse_path(ly_translator_ctx, path, LYD_JSON, -			       LYD_OPT_CONFIG); -	if (!dnode) { +	err = lyd_parse_data_path(ly_translator_ctx, path, LYD_JSON, +				  LYD_PARSE_NO_STATE, LYD_VALIDATE_NO_STATE, +				  &dnode); +	if (err) {  		flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD, -			  "%s: lyd_parse_path() failed", __func__); +			  "%s: lyd_parse_path() failed: %d", __func__, err);  		return NULL;  	}  	dnode = yang_dnode_get(dnode, @@ -171,89 +173,94 @@ struct yang_translator *yang_translator_load(const char *path)  	RB_INSERT(yang_translators, &yang_translators, translator);  	/* Initialize the translator libyang context. */ -	translator->ly_ctx = yang_ctx_new_setup(false); +	translator->ly_ctx = yang_ctx_new_setup(false, false);  	if (!translator->ly_ctx) {  		flog_warn(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);  		goto error;  	} -	/* Load modules and deviations. */ -	set = lyd_find_path(dnode, "./module"); -	assert(set); -	for (size_t i = 0; i < set->number; i++) { +	/* Load modules */ +	if (lyd_find_xpath(dnode, "./module", &set) != LY_SUCCESS) +		assert(0); /* XXX libyang2: old ly1 code asserted success */ + +	for (size_t i = 0; i < set->count; i++) {  		const char *module_name;  		tmodule =  			XCALLOC(MTYPE_YANG_TRANSLATOR_MODULE, sizeof(*tmodule)); -		module_name = yang_dnode_get_string(set->set.d[i], "./name"); +		module_name = yang_dnode_get_string(set->dnodes[i], "./name");  		tmodule->module = ly_ctx_load_module(translator->ly_ctx, -						     module_name, NULL); +						     module_name, NULL, NULL);  		if (!tmodule->module) {  			flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,  				  "%s: failed to load module: %s", __func__,  				  module_name); -			ly_set_free(set); +			ly_set_free(set, NULL);  			goto error;  		} +	} -		module_name = -			yang_dnode_get_string(set->set.d[i], "./deviations"); -		tmodule->deviations = ly_ctx_load_module(translator->ly_ctx, -							 module_name, NULL); +	/* Count nodes in modules. */ +	for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) { +		tmodule->nodes_before_deviations = +			yang_module_nodes_count(tmodule->module); +	} + +	/* Load the deviations and count nodes again */ +	for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) { +		const char *module_name = tmodule->module->name; +		tmodule->deviations = ly_ctx_load_module( +			translator->ly_ctx, module_name, NULL, NULL);  		if (!tmodule->deviations) {  			flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,  				  "%s: failed to load module: %s", __func__,  				  module_name); -			ly_set_free(set); +			ly_set_free(set, NULL);  			goto error;  		} -		lys_set_disabled(tmodule->deviations); -		listnode_add(translator->modules, tmodule); +		tmodule->nodes_after_deviations = +			yang_module_nodes_count(tmodule->module);  	} -	ly_set_free(set); +	ly_set_free(set, NULL);  	/* Calculate the coverage. */  	for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) { -		tmodule->nodes_before_deviations = -			yang_module_nodes_count(tmodule->module); - -		lys_set_enabled(tmodule->deviations); - -		tmodule->nodes_after_deviations = -			yang_module_nodes_count(tmodule->module);  		tmodule->coverage = ((double)tmodule->nodes_after_deviations  				     / (double)tmodule->nodes_before_deviations)  				    * 100;  	}  	/* Load mappings. */ -	set = lyd_find_path(dnode, "./module/mappings"); -	assert(set); -	for (size_t i = 0; i < set->number; i++) { +	if (lyd_find_xpath(dnode, "./module/mappings", &set) != LY_SUCCESS) +		assert(0); /* XXX libyang2: old ly1 code asserted success */ +	for (size_t i = 0; i < set->count; i++) {  		const char *xpath_custom, *xpath_native; -		const struct lys_node *snode_custom, *snode_native; +		const struct lysc_node *snode_custom, *snode_native; + +		xpath_custom = +			yang_dnode_get_string(set->dnodes[i], "./custom"); -		xpath_custom = yang_dnode_get_string(set->set.d[i], "./custom"); -		snode_custom = ly_ctx_get_node(translator->ly_ctx, NULL, -					       xpath_custom, 0); +		snode_custom = lys_find_path(translator->ly_ctx, NULL, +					     xpath_custom, 0);  		if (!snode_custom) {  			flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,  				  "%s: unknown data path: %s", __func__,  				  xpath_custom); -			ly_set_free(set); +			ly_set_free(set, NULL);  			goto error;  		} -		xpath_native = yang_dnode_get_string(set->set.d[i], "./native"); +		xpath_native = +			yang_dnode_get_string(set->dnodes[i], "./native");  		snode_native = -			ly_ctx_get_node(ly_native_ctx, NULL, xpath_native, 0); +			lys_find_path(ly_native_ctx, NULL, xpath_native, 0);  		if (!snode_native) {  			flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,  				  "%s: unknown data path: %s", __func__,  				  xpath_native); -			ly_set_free(set); +			ly_set_free(set, NULL);  			goto error;  		} @@ -262,7 +269,7 @@ struct yang_translator *yang_translator_load(const char *path)  		yang_mapping_add(translator, YANG_TRANSLATE_FROM_NATIVE,  				 snode_native, xpath_native, xpath_custom);  	} -	ly_set_free(set); +	ly_set_free(set, NULL);  	/* Validate mappings. */  	if (yang_translator_validate(translator) != 0) @@ -290,7 +297,7 @@ void yang_translator_unload(struct yang_translator *translator)  		hash_clean(translator->mappings[i], yang_mapping_hash_free);  	translator->modules->del = (void (*)(void *))yang_tmodule_delete;  	list_delete(&translator->modules); -	ly_ctx_destroy(translator->ly_ctx, NULL); +	ly_ctx_destroy(translator->ly_ctx);  	RB_REMOVE(yang_translators, &yang_translators, translator);  	XFREE(MTYPE_YANG_TRANSLATOR, translator);  } @@ -308,7 +315,7 @@ yang_translate_xpath(const struct yang_translator *translator, int dir,  		     char *xpath, size_t xpath_len)  {  	struct ly_ctx *ly_ctx; -	const struct lys_node *snode; +	const struct lysc_node *snode;  	struct yang_mapping_node *mapping;  	char xpath_canonical[XPATH_MAXLEN];  	char keys[4][LIST_MAXKEYLEN]; @@ -319,7 +326,7 @@ yang_translate_xpath(const struct yang_translator *translator, int dir,  	else  		ly_ctx = ly_native_ctx; -	snode = ly_ctx_get_node(ly_ctx, NULL, xpath, 0); +	snode = lys_find_path(ly_ctx, NULL, xpath, 0);  	if (!snode) {  		flog_warn(EC_LIB_YANG_TRANSLATION_ERROR,  			  "%s: unknown data path: %s", __func__, xpath); @@ -352,7 +359,7 @@ int yang_translate_dnode(const struct yang_translator *translator, int dir,  {  	struct ly_ctx *ly_ctx;  	struct lyd_node *new; -	struct lyd_node *root, *next, *dnode_iter; +	struct lyd_node *root, *dnode_iter;  	/* Create new libyang data node to hold the translated data. */  	if (dir == YANG_TRANSLATE_TO_NATIVE) @@ -362,8 +369,8 @@ int yang_translate_dnode(const struct yang_translator *translator, int dir,  	new = yang_dnode_new(ly_ctx, false);  	/* Iterate over all nodes from the data tree. */ -	LY_TREE_FOR (*dnode, root) { -		LY_TREE_DFS_BEGIN (root, next, dnode_iter) { +	LY_LIST_FOR (*dnode, root) { +		LYD_TREE_DFS_BEGIN (root, dnode_iter) {  			char xpath[XPATH_MAXLEN];  			enum yang_translate_result ret; @@ -380,19 +387,17 @@ int yang_translate_dnode(const struct yang_translator *translator, int dir,  			}  			/* Create new node in the tree of translated data. */ -			ly_errno = 0; -			if (!lyd_new_path(new, ly_ctx, xpath, -					  (void *)yang_dnode_get_string( -						  dnode_iter, NULL), -					  0, LYD_PATH_OPT_UPDATE) -			    && ly_errno) { +			if (lyd_new_path(new, ly_ctx, xpath, +					 (void *)yang_dnode_get_string( +						 dnode_iter, NULL), +					 LYD_NEW_PATH_UPDATE, NULL)) {  				flog_err(EC_LIB_LIBYANG,  					 "%s: lyd_new_path() failed", __func__);  				goto error;  			}  		next: -			LY_TREE_DFS_END(root, next, dnode_iter); +			LYD_TREE_DFS_END(root, dnode_iter);  		}  	} @@ -413,13 +418,13 @@ struct translator_validate_args {  	unsigned int errors;  }; -static int yang_translator_validate_cb(const struct lys_node *snode_custom, +static int yang_translator_validate_cb(const struct lysc_node *snode_custom,  				       void *arg)  {  	struct translator_validate_args *args = arg;  	struct yang_mapping_node *mapping; -	const struct lys_node *snode_native; -	const struct lys_type *stype_custom, *stype_native; +	const struct lysc_node *snode_native; +	const struct lysc_type *stype_custom, *stype_native;  	char xpath[XPATH_MAXLEN];  	yang_snode_get_path(snode_custom, YANG_PATH_DATA, xpath, sizeof(xpath)); @@ -433,14 +438,14 @@ static int yang_translator_validate_cb(const struct lys_node *snode_custom,  	}  	snode_native = -		ly_ctx_get_node(ly_native_ctx, NULL, mapping->xpath_to_fmt, 0); +		lys_find_path(ly_native_ctx, NULL, mapping->xpath_to_fmt, 0);  	assert(snode_native);  	/* Check if the YANG types are compatible. */  	stype_custom = yang_snode_get_type(snode_custom);  	stype_native = yang_snode_get_type(snode_native);  	if (stype_custom && stype_native) { -		if (stype_custom->base != stype_native->base) { +		if (stype_custom->basetype != stype_native->basetype) {  			flog_warn(  				EC_LIB_YANG_TRANSLATOR_LOAD,  				"%s: YANG types are incompatible (xpath: \"%s\")", @@ -486,7 +491,7 @@ static unsigned int yang_translator_validate(struct yang_translator *translator)  	return args.errors;  } -static int yang_module_nodes_count_cb(const struct lys_node *snode, void *arg) +static int yang_module_nodes_count_cb(const struct lysc_node *snode, void *arg)  {  	unsigned int *total = arg; @@ -511,14 +516,14 @@ static unsigned int yang_module_nodes_count(const struct lys_module *module)  void yang_translator_init(void)  { -	ly_translator_ctx = yang_ctx_new_setup(true); +	ly_translator_ctx = yang_ctx_new_setup(true, false);  	if (!ly_translator_ctx) {  		flog_err(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);  		exit(1);  	}  	if (!ly_ctx_load_module(ly_translator_ctx, "frr-module-translator", -				NULL)) { +				NULL, NULL)) {  		flog_err(  			EC_LIB_YANG_MODULE_LOAD,  			"%s: failed to load the \"frr-module-translator\" module", @@ -536,5 +541,5 @@ void yang_translator_terminate(void)  		yang_translator_unload(translator);  	} -	ly_ctx_destroy(ly_translator_ctx, NULL); +	ly_ctx_destroy(ly_translator_ctx);  }  | 
