@@ -81,6 +81,125 @@ int core_post_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *modul
8181 return SR_ERR_OK ;
8282}
8383
84+ static confd_dependency_t add_dependencies (struct lyd_node * * diff , const char * xpath , const char * value )
85+ {
86+ struct lyd_node * new_node = NULL ;
87+ struct lyd_node * target = NULL ;
88+ struct lyd_node * root = NULL ;
89+ int rc ;
90+
91+ if (!lydx_get_xpathf (* diff , "%s" , xpath )) {
92+ /* Create the path, potentially creating a new tree */
93+ rc = lyd_new_path (NULL , LYD_CTX (* diff ), xpath , value , LYD_NEW_PATH_UPDATE , & new_node );
94+ if (rc != LY_SUCCESS || !new_node ) {
95+ ERROR ("lyd_new_path failed with rc=%d" , rc );
96+ return CONFD_DEP_ERROR ;
97+ }
98+
99+ root = new_node ;
100+ while (root -> parent )
101+ root = lyd_parent (root );
102+
103+ rc = lyd_merge_siblings (diff , root , LYD_MERGE_DESTRUCT );
104+ if (rc != LY_SUCCESS ) {
105+ ERROR ("lyd_merge_siblings failed with rc=%d" , rc );
106+ lyd_free_tree (root );
107+ return CONFD_DEP_ERROR ;
108+ }
109+
110+ target = lydx_get_xpathf (* diff , "%s" , xpath );
111+ if (target ) {
112+ lyd_new_meta (LYD_CTX (target ), target , NULL ,
113+ "yang:operation" , "replace" , false, NULL );
114+ } else {
115+ return CONFD_DEP_ERROR ;
116+ }
117+
118+ return CONFD_DEP_ADDED ;
119+ }
120+
121+ return CONFD_DEP_DONE ;
122+ }
123+
124+ static confd_dependency_t handle_dependencies (struct lyd_node * * diff , struct lyd_node * config )
125+ {
126+ struct lyd_node * dkeys , * dkey , * hostname ;
127+ confd_dependency_t result = CONFD_DEP_DONE ;
128+ const char * key_name ;
129+
130+ dkeys = lydx_get_descendant (* diff , "keystore" , "symmetric-keys" , "symmetric-key" , NULL );
131+
132+ LYX_LIST_FOR_EACH (dkeys , dkey , "symmetric-key" ) {
133+ struct ly_set * ifaces ;
134+ uint32_t i ;
135+
136+ key_name = lydx_get_cattr (dkey , "name" );
137+ ifaces = lydx_find_xpathf (config , "/ietf-interfaces:interfaces/interface[infix-interfaces:wifi/secret='%s']" , key_name );
138+ if (ifaces && ifaces -> count > 0 ) {
139+ for (i = 0 ; i < ifaces -> count ; i ++ ) {
140+ struct lyd_node * iface = ifaces -> dnodes [i ];
141+ const char * ifname ;
142+ char xpath [256 ];
143+ ifname = lydx_get_cattr (iface , "name" );
144+ snprintf (xpath , sizeof (xpath ), "/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi/secret" , ifname );
145+ result = add_dependencies (diff , xpath , key_name );
146+ if (result == CONFD_DEP_ERROR ) {
147+ ERROR ("Failed to add wifi node to diff for interface %s" , ifname );
148+ ly_set_free (ifaces , NULL );
149+ return result ;
150+ }
151+ }
152+ ly_set_free (ifaces , NULL );
153+ }
154+ }
155+
156+ dkeys = lydx_get_descendant (* diff , "keystore" , "asymmetric-keys" , "asymmetric-key" , NULL );
157+ LYX_LIST_FOR_EACH (dkeys , dkey , "asymmetric-key" ) {
158+ struct ly_set * hostkeys ;
159+ uint32_t i ;
160+
161+ key_name = lydx_get_cattr (dkey , "name" );
162+ hostkeys = lydx_find_xpathf (config , "/infix-services:ssh/hostkey[.='%s']" , key_name );
163+ if (hostkeys && hostkeys -> count > 0 ) {
164+ for (i = 0 ; i < hostkeys -> count ; i ++ ) {
165+ char xpath [256 ];
166+ snprintf (xpath , sizeof (xpath ), "/infix-services:ssh/hostkey[.='%s']" , key_name );
167+ result = add_dependencies (diff , xpath , key_name );
168+ if (result == CONFD_DEP_ERROR ) {
169+ ERROR ("Failed to add ssh hostkey to diff for key %s" , key_name );
170+ ly_set_free (hostkeys , NULL );
171+ return result ;
172+ }
173+ }
174+ ly_set_free (hostkeys , NULL );
175+ }
176+ }
177+
178+ hostname = lydx_get_xpathf (* diff , "/ietf-system:system/hostname" );
179+ if (hostname ) {
180+ struct lyd_node * mdns , * dhcp_server ;
181+
182+ dhcp_server = lydx_get_xpathf (config , "/infix-dhcp-server:dhcp-server/enabled" );
183+ if (dhcp_server && lydx_is_enabled (dhcp_server , "enabled" )) {
184+ result = add_dependencies (diff , "/infix-dhcp-server:dhcp-server/enabled" , "true" );
185+ if (result == CONFD_DEP_ERROR ) {
186+ ERROR ("Failed to add dhcp-server to diff on hostname change" );
187+ return result ;
188+ }
189+ }
190+ mdns = lydx_get_xpathf (config , "/infix-services:mdns" );
191+ if (mdns && lydx_is_enabled (mdns , "enabled" )) {
192+ result = add_dependencies (diff , "/infix-services:mdns/enabled" , "true" );
193+ if (result == CONFD_DEP_ERROR ) {
194+ ERROR ("Failed to add mdns to diff on hostname change" );
195+ return result ;
196+ }
197+ }
198+ }
199+
200+ return result ;
201+ }
202+
84203static int change_cb (sr_session_ctx_t * session , uint32_t sub_id , const char * module_name ,
85204 const char * xpath , sr_event_t event , uint32_t request_id , void * _confd )
86205{
@@ -91,6 +210,7 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
91210 confd_dependency_t result ;
92211 sr_data_t * cfg = NULL ;
93212 int rc = SR_ERR_OK ;
213+ int max_dep = 10 ;
94214
95215 if (request_id == last_id && last_event == event )
96216 return SR_ERR_OK ;
@@ -108,6 +228,17 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
108228 goto free_diff ;
109229
110230 config = cfg -> tree ;
231+ while ((result = handle_dependencies (& diff , config )) != CONFD_DEP_DONE ) {
232+ if (max_dep == 0 ) {
233+ ERROR ("Max dependency depth reached" );
234+ return SR_ERR_INTERNAL ;
235+ }
236+ if (result == CONFD_DEP_ERROR ) {
237+ ERROR ("Failed to add dependencies" );
238+ return SR_ERR_INTERNAL ;
239+ }
240+ max_dep -- ;
241+ }
111242#if 0
112243 /* Debug: print diff to file */
113244 FILE * f = fopen ("/tmp/confd-diff.json" , "w" );
0 commit comments