@@ -93,17 +93,139 @@ int core_post_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *modul
9393 return SR_ERR_OK ;
9494}
9595
96+ static confd_dependency_t add_dependencies (struct lyd_node * * diff , const char * xpath , const char * value )
97+ {
98+ struct lyd_node * new_node = NULL ;
99+ struct lyd_node * target = NULL ;
100+ struct lyd_node * root = NULL ;
101+ int rc ;
102+
103+ if (!lydx_get_xpathf (* diff , "%s" , xpath )) {
104+ /* Create the path, potentially creating a new tree */
105+ rc = lyd_new_path (NULL , LYD_CTX (* diff ), xpath , value , LYD_NEW_PATH_UPDATE , & new_node );
106+ if (rc != LY_SUCCESS || !new_node ) {
107+ ERROR ("lyd_new_path failed with rc=%d" , rc );
108+ return CONFD_DEP_ERROR ;
109+ }
110+
111+ root = new_node ;
112+ while (root -> parent )
113+ root = lyd_parent (root );
114+
115+ rc = lyd_merge_siblings (diff , root , LYD_MERGE_DESTRUCT );
116+ if (rc != LY_SUCCESS ) {
117+ ERROR ("lyd_merge_siblings failed with rc=%d" , rc );
118+ lyd_free_tree (root );
119+ return CONFD_DEP_ERROR ;
120+ }
121+
122+ target = lydx_get_xpathf (* diff , "%s" , xpath );
123+ if (target ) {
124+ lyd_new_meta (LYD_CTX (target ), target , NULL ,
125+ "yang:operation" , "replace" , false, NULL );
126+ } else {
127+ return CONFD_DEP_ERROR ;
128+ }
129+
130+ return CONFD_DEP_ADDED ;
131+ }
132+
133+ return CONFD_DEP_DONE ;
134+ }
135+
136+ static confd_dependency_t handle_dependencies (struct lyd_node * * diff , struct lyd_node * config )
137+ {
138+ struct lyd_node * dkeys , * dkey , * hostname ;
139+ confd_dependency_t result = CONFD_DEP_DONE ;
140+ const char * key_name ;
141+
142+ dkeys = lydx_get_descendant (* diff , "keystore" , "symmetric-keys" , "symmetric-key" , NULL );
143+
144+ LYX_LIST_FOR_EACH (dkeys , dkey , "symmetric-key" ) {
145+ struct ly_set * ifaces ;
146+ uint32_t i ;
147+
148+ key_name = lydx_get_cattr (dkey , "name" );
149+ ifaces = lydx_find_xpathf (config , "/ietf-interfaces:interfaces/interface[infix-interfaces:wifi/secret='%s']" , key_name );
150+ if (ifaces && ifaces -> count > 0 ) {
151+ for (i = 0 ; i < ifaces -> count ; i ++ ) {
152+ struct lyd_node * iface = ifaces -> dnodes [i ];
153+ const char * ifname ;
154+ char xpath [256 ];
155+ ifname = lydx_get_cattr (iface , "name" );
156+ snprintf (xpath , sizeof (xpath ), "/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi/secret" , ifname );
157+ result = add_dependencies (diff , xpath , key_name );
158+ if (result == CONFD_DEP_ERROR ) {
159+ ERROR ("Failed to add wifi node to diff for interface %s" , ifname );
160+ ly_set_free (ifaces , NULL );
161+ return result ;
162+ }
163+ }
164+ ly_set_free (ifaces , NULL );
165+ }
166+ }
167+
168+ dkeys = lydx_get_descendant (* diff , "keystore" , "asymmetric-keys" , "asymmetric-key" , NULL );
169+ LYX_LIST_FOR_EACH (dkeys , dkey , "asymmetric-key" ) {
170+ struct ly_set * hostkeys ;
171+ uint32_t i ;
172+
173+ key_name = lydx_get_cattr (dkey , "name" );
174+ hostkeys = lydx_find_xpathf (config , "/infix-services:ssh/hostkey[.='%s']" , key_name );
175+ if (hostkeys && hostkeys -> count > 0 ) {
176+ for (i = 0 ; i < hostkeys -> count ; i ++ ) {
177+ char xpath [256 ];
178+ snprintf (xpath , sizeof (xpath ), "/infix-services:ssh/hostkey[.='%s']" , key_name );
179+ result = add_dependencies (diff , xpath , key_name );
180+ if (result == CONFD_DEP_ERROR ) {
181+ ERROR ("Failed to add ssh hostkey to diff for key %s" , key_name );
182+ ly_set_free (hostkeys , NULL );
183+ return result ;
184+ }
185+ }
186+ ly_set_free (hostkeys , NULL );
187+ }
188+ }
189+
190+ hostname = lydx_get_xpathf (* diff , "/ietf-system:system/hostname" );
191+ if (hostname ) {
192+ struct lyd_node * mdns , * dhcp_server ;
193+
194+ dhcp_server = lydx_get_xpathf (config , "/infix-dhcp-server:dhcp-server/enabled" );
195+ if (dhcp_server && lydx_is_enabled (dhcp_server , "enabled" )) {
196+ result = add_dependencies (diff , "/infix-dhcp-server:dhcp-server/enabled" , "true" );
197+ if (result == CONFD_DEP_ERROR ) {
198+ ERROR ("Failed to add dhcp-server to diff on hostname change" );
199+ return result ;
200+ }
201+ }
202+ mdns = lydx_get_xpathf (config , "/infix-services:mdns" );
203+ if (mdns && lydx_is_enabled (mdns , "enabled" )) {
204+ result = add_dependencies (diff , "/infix-services:mdns/enabled" , "true" );
205+ if (result == CONFD_DEP_ERROR ) {
206+ ERROR ("Failed to add mdns to diff on hostname change" );
207+ return result ;
208+ }
209+ }
210+ }
211+
212+ return result ;
213+ }
214+
96215static int change_cb (sr_session_ctx_t * session , uint32_t sub_id , const char * module_name ,
97216 const char * xpath , sr_event_t event , uint32_t request_id , void * _confd )
98217{
218+ <<<<<<< HEAD
99219 struct confd * confd = _confd ;
100220 char * output = NULL ;
101221 struct lyd_node * diff = NULL , * config = NULL ;
102222 sr_data_t * cfg = NULL ;
103-
223+ confd_dependency_t result ;
104224 int rc = SR_ERR_OK ;
105225 static uint32_t last_id = 0 ;
106226 static uint32_t last_event = -1 ;
227+ int max_dep = 10 ;
228+
107229 if (request_id == last_id && last_event == event )
108230 return SR_ERR_OK ;
109231 last_id = request_id ;
@@ -121,28 +243,34 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
121243
122244 config = cfg -> tree ;
123245 }
124-
125- // For logging: Write to file instead of using ERROR() to avoid truncation
126- if (diff ) {
127- FILE * f = fopen ("/tmp/sysrepo_diff.json" , "w" );
128- if (f ) {
129- lyd_print_file (f , diff , LYD_JSON ,
130- LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL );
131- fclose (f );
132- ERROR ("req_id=%u event=%d module=%s - Full diff written to /tmp/sysrepo_diff.json" ,
133- request_id , event , module_name );
134- } else {
135- // Fallback: print to memory but limit what we log
136- lyd_print_mem (& output , diff , LYD_JSON , LYD_PRINT_WITHSIBLINGS );
137- if (output ) {
138- // Only log first 500 chars to avoid truncation
139- ERROR ("req_id=%u event=%d module=%s - Diff (truncated): %.500s..." ,
140- request_id , event , module_name , output );
141- free (output );
142- }
143- }
246+ while ((result = handle_dependencies (& diff , config )) != CONFD_DEP_DONE ) {
247+ if (result == CONFD_DEP_ERROR ) {
248+ ERROR ("Failed to add dependencies" );
249+ break ;
250+ }
144251 }
145252
253+ config = cfg -> tree ;
254+ while ((result = handle_dependencies (& diff , config )) != CONFD_DEP_DONE ) {
255+ if (max_dep == 0 ) {
256+ ERROR ("Max dependency depth reached" );
257+ return SR_ERR_INTERNAL ;
258+ }
259+ if (result == CONFD_DEP_ERROR ) {
260+ ERROR ("Failed to add dependencies" );
261+ return SR_ERR_INTERNAL ;
262+ }
263+ max_dep -- ;
264+ }
265+ #if 0
266+ /* Debug: print diff to file */
267+ FILE * f = fopen ("/tmp/confd-diff.json" , "w" );
268+ if (f ) {
269+ lyd_print_file (f , diff , LYD_JSON , LYD_PRINT_WITHSIBLINGS );
270+ fclose (f );
271+ }
272+ #endif
273+ }
146274 /* ietf-interfaces */
147275 ietf_interfaces_change (session , config , diff , event , confd );
148276
0 commit comments