Skip to content

Commit 3e17438

Browse files
committed
confd: Add support for dependency tracking between modules
1 parent ce56a1e commit 3e17438

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

src/confd/src/core.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
84203
static 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");

src/confd/src/core.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <jansson.h>
2626

27+
#include <srx/lyx.h>
2728
#include <srx/common.h>
2829
#include <srx/helpers.h>
2930
#include <srx/systemv.h>
@@ -100,6 +101,11 @@ static inline char *xpath_base(const char *xpath)
100101

101102
return path;
102103
}
104+
typedef enum {
105+
CONFD_DEP_DONE = 0,
106+
CONFD_DEP_ADDED = 1,
107+
CONFD_DEP_ERROR = 2
108+
} confd_dependency_t;
103109

104110
#define REGISTER_CHANGE(s,m,x,f,c,a,u) \
105111
if ((rc = register_change(s, m, x, f, c, a, u))) \

0 commit comments

Comments
 (0)