@@ -1049,57 +1049,168 @@ np_url_setcap(void)
10491049struct nc_server_reply *
10501050np_op_parse_config (struct lyd_node_any * node , uint32_t parse_options , struct lyd_node * * config )
10511051{
1052+ struct nc_server_reply * reply = NULL ;
10521053 const struct ly_ctx * ly_ctx ;
1054+ const struct lys_module * ly_mod ;
1055+ sr_data_t * sr_ln2_nc_server = NULL ;
1056+ struct lyd_node * ignored_mod ;
1057+ char * xpath = NULL , * msg ;
1058+ struct ly_set * set = NULL ;
10531059
10541060 assert (node && node -> schema && (node -> schema -> nodetype & LYD_NODE_ANY ));
10551061
10561062 if (!node -> value .str ) {
10571063 /* nothing to do, no data */
1058- return NULL ;
1064+ goto cleanup ;
10591065 }
10601066
10611067 ly_ctx = LYD_CTX (node );
10621068
1069+ /* get/parse the data */
10631070 switch (node -> value_type ) {
10641071 case LYD_ANYDATA_STRING :
10651072 case LYD_ANYDATA_XML :
10661073 if (lyd_parse_data_mem (ly_ctx , node -> value .str , LYD_XML , parse_options , 0 , config )) {
1067- return np_reply_err_op_failed (NULL , ly_ctx , ly_last_logmsg ());
1074+ reply = np_reply_err_op_failed (NULL , ly_ctx , ly_last_logmsg ());
1075+ goto cleanup ;
10681076 }
10691077 break ;
10701078 case LYD_ANYDATA_DATATREE :
10711079 if (lyd_dup_siblings (node -> value .tree , NULL , LYD_DUP_RECURSIVE , config )) {
1072- return np_reply_err_op_failed (NULL , ly_ctx , ly_last_logmsg ());
1080+ reply = np_reply_err_op_failed (NULL , ly_ctx , ly_last_logmsg ());
1081+ goto cleanup ;
10731082 }
10741083 if (!(parse_options & (LYD_PARSE_ONLY | LYD_PARSE_OPAQ ))) {
10751084 /* separate validation if requested */
10761085 if (lyd_validate_all (config , NULL , LYD_VALIDATE_NO_STATE , NULL )) {
1077- return np_reply_err_op_failed (NULL , ly_ctx , ly_last_logmsg ());
1086+ reply = np_reply_err_op_failed (NULL , ly_ctx , ly_last_logmsg ());
1087+ goto cleanup ;
10781088 }
10791089 }
10801090 break ;
10811091 case LYD_ANYDATA_LYB :
10821092 if (lyd_parse_data_mem (ly_ctx , node -> value .mem , LYD_LYB , parse_options , 0 , config )) {
1083- return np_reply_err_op_failed (NULL , ly_ctx , ly_last_logmsg ());
1093+ reply = np_reply_err_op_failed (NULL , ly_ctx , ly_last_logmsg ());
1094+ goto cleanup ;
10841095 }
10851096 break ;
10861097 case LYD_ANYDATA_JSON :
10871098 EINT ;
1088- return np_reply_err_op_failed (NULL , ly_ctx , "Internal error." );
1099+ reply = np_reply_err_op_failed (NULL , ly_ctx , "Internal error." );
1100+ goto cleanup ;
10891101 }
10901102
1091- return NULL ;
1103+ if (* config ) {
1104+ /* get the list of ignored modules, skip NACM */
1105+ if (sr_get_data (np2srv .sr_sess , "/libnetconf2-netconf-server:ln2-netconf-server/ignored-hello-module" , 0 ,
1106+ np2srv .sr_timeout , 0 , & sr_ln2_nc_server )) {
1107+ reply = np_reply_err_sr (np2srv .sr_sess , "get" );
1108+ goto cleanup ;
1109+ }
1110+
1111+ if (sr_ln2_nc_server ) {
1112+ LY_LIST_FOR (lyd_child (sr_ln2_nc_server -> tree ), ignored_mod ) {
1113+ if (strcmp (LYD_NAME (ignored_mod ), "ignored-hello-module" )) {
1114+ continue ;
1115+ }
1116+
1117+ ly_mod = ly_ctx_get_module_implemented (ly_ctx , lyd_get_value (ignored_mod ));
1118+ if (!ly_mod ) {
1119+ /* module not implemented or not in the context */
1120+ continue ;
1121+ }
1122+
1123+ /* find any module data */
1124+ if (asprintf (& xpath , "/%s:*" , ly_mod -> name ) == -1 ) {
1125+ reply = np_reply_err_op_failed (NULL , ly_ctx , "Memory allocation failed." );
1126+ goto cleanup ;
1127+ }
1128+ if (lyd_find_xpath (* config , xpath , & set )) {
1129+ reply = np_reply_err_op_failed (NULL , ly_ctx , ly_last_logmsg ());
1130+ goto cleanup ;
1131+ }
1132+
1133+ if (set -> count ) {
1134+ /* invalid data */
1135+ if (asprintf (& msg , "Config includes data of the module \"%s\" that is not supported by NETCONF." ,
1136+ ly_mod -> name ) == -1 ) {
1137+ msg = NULL ;
1138+ }
1139+ reply = np_reply_err_invalid_val (ly_ctx , msg , LYD_NAME (set -> dnodes [0 ]));
1140+ free (msg );
1141+ goto cleanup ;
1142+ }
1143+
1144+ /* next iter */
1145+ free (xpath );
1146+ xpath = NULL ;
1147+ ly_set_free (set , NULL );
1148+ set = NULL ;
1149+ }
1150+ }
1151+ }
1152+
1153+ cleanup :
1154+ sr_release_data (sr_ln2_nc_server );
1155+ free (xpath );
1156+ ly_set_free (set , NULL );
1157+ return reply ;
1158+ }
1159+
1160+ /**
1161+ * @brief Remove any data referencing or belonging to a module that should be ignored for NETCONF.
1162+ *
1163+ * @param[in,out] data Data tree to modify.
1164+ * @param[in] ignored_mod Name of the ignored module.
1165+ */
1166+ static void
1167+ np_op_filter_data_ignored_mod (struct lyd_node * * data , const char * ignored_mod )
1168+ {
1169+ const struct lys_module * ly_mod ;
1170+ struct ly_set * set = NULL ;
1171+ char * xpath = NULL ;
1172+ uint32_t i ;
1173+
1174+ ly_mod = ly_ctx_get_module_implemented (LYD_CTX (* data ), ignored_mod );
1175+ if (!ly_mod ) {
1176+ /* module not implemented or not in the context */
1177+ goto cleanup ;
1178+ }
1179+
1180+ /* remove from ietf-yang-library data and the module's data directly */
1181+ if (asprintf (& xpath , "/ietf-yang-library:yang-library/module-set/module[name='%s'] | "
1182+ "/ietf-yang-library:modules-state/module[conformance-type='implement'][name='%s'] | "
1183+ "/sysrepo-monitoring:sysrepo-state/module[name='%s'] |"
1184+ "/ietf-netconf-monitoring:netconf-state/schemas/schema[identifier='%s'] |"
1185+ "/%s:*" , ly_mod -> name , ly_mod -> name , ly_mod -> name , ly_mod -> name , ly_mod -> name ) == -1 ) {
1186+ goto cleanup ;
1187+ }
1188+ if (lyd_find_xpath (* data , xpath , & set )) {
1189+ goto cleanup ;
1190+ }
1191+
1192+ /* just free all the found nodes */
1193+ for (i = 0 ; i < set -> count ; ++ i ) {
1194+ if (set -> dnodes [i ] == * data ) {
1195+ * data = (* data )-> next ;
1196+ }
1197+ lyd_free_tree (set -> dnodes [i ]);
1198+ }
1199+
1200+ cleanup :
1201+ free (xpath );
1202+ ly_set_free (set , NULL );
10921203}
10931204
10941205struct nc_server_reply *
10951206np_op_filter_data_get (sr_session_ctx_t * session , uint32_t max_depth , sr_get_options_t get_opts , const char * xp_filter ,
10961207 struct lyd_node * * data )
10971208{
1098- sr_data_t * sr_data = NULL ;
1099- struct lyd_node * e ;
1209+ sr_data_t * sr_data = NULL , * sr_ln2_nc_server = NULL ;
1210+ struct lyd_node * e , * ignored_mod ;
11001211 const sr_error_info_t * err_info ;
11011212 const sr_error_info_err_t * err ;
1102- struct nc_server_reply * reply ;
1213+ struct nc_server_reply * reply = NULL ;
11031214 int r ;
11041215
11051216 if (!xp_filter ) {
@@ -1124,21 +1235,41 @@ np_op_filter_data_get(sr_session_ctx_t *session, uint32_t max_depth, sr_get_opti
11241235 /* other error */
11251236 reply = np_reply_err_sr (session , "get" );
11261237 }
1127- return reply ;
1238+ goto cleanup ;
11281239 }
11291240
11301241 if (sr_data ) {
1242+ /* get the list of ignored modules, skip NACM */
1243+ if (sr_get_data (np2srv .sr_sess , "/libnetconf2-netconf-server:ln2-netconf-server/ignored-hello-module" , 0 ,
1244+ np2srv .sr_timeout , 0 , & sr_ln2_nc_server )) {
1245+ reply = np_reply_err_sr (np2srv .sr_sess , "get" );
1246+ goto cleanup ;
1247+ }
1248+ if (sr_ln2_nc_server ) {
1249+ LY_LIST_FOR (lyd_child (sr_ln2_nc_server -> tree ), ignored_mod ) {
1250+ if (strcmp (LYD_NAME (ignored_mod ), "ignored-hello-module" )) {
1251+ continue ;
1252+ }
1253+
1254+ /* remove data connected with the module */
1255+ np_op_filter_data_ignored_mod (& sr_data -> tree , lyd_get_value (ignored_mod ));
1256+ }
1257+ }
1258+
11311259 /* merge */
11321260 r = lyd_merge_siblings (data , sr_data -> tree , LYD_MERGE_DESTRUCT );
11331261 sr_data -> tree = NULL ;
11341262 sr_release_data (sr_data );
11351263 if (r ) {
11361264 /* other error */
1137- return np_reply_err_op_failed (session , NULL , ly_last_logmsg ());
1265+ reply = np_reply_err_op_failed (session , NULL , ly_last_logmsg ());
1266+ goto cleanup ;
11381267 }
11391268 }
11401269
1141- return NULL ;
1270+ cleanup :
1271+ sr_release_data (sr_ln2_nc_server );
1272+ return reply ;
11421273}
11431274
11441275struct nc_server_reply *
0 commit comments