confd: Refactor how sysrepo callbacks are handled

Sysrepo only care about model changes, but we want the system
configuration. Therefore add a common callback for all modules
and handle dependencies between the modules, if someone should be
run before another for example.
This commit is contained in:
Mattias Walström
2025-10-30 12:28:03 +01:00
parent 021e864a6f
commit da29771398
17 changed files with 630 additions and 646 deletions
+213 -53
View File
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <srx/srx_val.h>
#include <srx/common.h>
#include <srx/lyx.h>
#include "core.h"
struct confd confd;
@@ -75,23 +77,118 @@ int core_post_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *modul
return SR_ERR_SYS;
}
/* skip reload in bootstrap, implicit reload in runlevel change */
if (systemf("runlevel >/dev/null 2>&1")) {
/* trigger any tasks waiting for confd to have applied *-config */
system("initctl -nbq cond set bootstrap");
return SR_ERR_OK;
}
if (systemf("initctl -b reload")) {
EMERG("initctl reload: failed applying new configuration!");
return SR_ERR_SYS;
}
AUDIT("The new configuration has been applied.");
return SR_ERR_OK;
}
static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name,
const char *xpath, sr_event_t event, uint32_t request_id, void *_confd)
{
struct lyd_node *diff = NULL, *config = NULL;
static uint32_t last_event = -1;
struct confd *confd = _confd;
static uint32_t last_id = 0;
confd_dependency_t result;
sr_data_t *cfg = NULL;
int rc = SR_ERR_OK;
if (request_id == last_id && last_event == event)
return SR_ERR_OK;
last_id = request_id;
last_event = event;
if (event == SR_EV_CHANGE || event == SR_EV_DONE) {
rc = srx_get_diff(session, &diff);
if (rc != SR_ERR_OK) {
ERROR("Failed to get diff: %d", rc);
return rc;
}
rc = sr_get_data(session, "//.", 0, 0, 0, &cfg);
if (rc || !cfg)
goto free_diff;
config = cfg->tree;
#if 0
/* Debug: print diff to file */
FILE *f = fopen("/tmp/confd-diff.json", "w");
if (f) {
lyd_print_file(f, diff, LYD_JSON, LYD_PRINT_WITHSIBLINGS);
fclose(f);
}
#endif
}
/* ietf-interfaces */
if ((rc = ietf_interfaces_change(session, config, diff, event, confd)))
goto free_diff;
/* infix-dhcp-client*/
if ((rc = infix_dhcp_client_change(session, config, diff, event, confd)))
goto free_diff;
/* ietf-keystore */
if ((rc = ietf_keystore_change(session, config, diff, event, confd)))
goto free_diff;
/* infix-services */
if ((rc = infix_services_change(session, config, diff, event, confd)))
goto free_diff;
/* ietf-syslog*/
if ((rc = ietf_syslog_change(session, config, diff, event, confd)))
goto free_diff;
/* ietf-system */
if ((rc = ietf_system_change(session, config, diff, event, confd)))
goto free_diff;
/* infix-containers */
if ((rc = infix_containers_change(session, config, diff, event, confd)))
goto free_diff;
/* ietf-hardware */
if ((rc = ietf_hardware_change(session, config, diff, event, confd)))
goto free_diff;
/* ietf-routing */
if ((rc = ietf_routing_change(session, config, diff, event, confd)))
goto free_diff;
/* infix-dhcp-server */
if ((rc = infix_dhcp_server_change(session, config, diff, event, confd)))
goto free_diff;
/* infix-firewall */
if ((rc = infix_firewall_change(session, config, diff, event, confd)))
goto free_diff;
if (cfg)
sr_release_data(cfg);
if (event == SR_EV_DONE) {
/* skip reload in bootstrap, implicit reload in runlevel change */
if (systemf("runlevel >/dev/null 2>&1")) {
/* trigger any tasks waiting for confd to have applied *-config */
system("initctl -nbq cond set bootstrap");
return SR_ERR_OK;
}
if (systemf("initctl -b reload")) {
EMERG("initctl reload: failed applying new configuration!");
return SR_ERR_SYS;
}
AUDIT("The new configuration has been applied.");
}
free_diff:
lyd_free_tree(diff);
return rc;
}
static int subscribe_module(char *model, struct confd *confd, int flags) {
return sr_module_change_subscribe(confd->session, model, "//.", change_cb, confd, CB_PRIO_PRIMARY, SR_SUBSCR_CHANGE_ALL_MODULES | SR_SUBSCR_DEFAULT | flags, &confd->sub);
}
int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv)
{
int log_opts = LOG_PID | LOG_NDELAY;
@@ -136,56 +233,119 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv)
*/
confd.ifquirks = json_load_file("/etc/product/interface-quirks.json", 0, NULL);
rc = ietf_interfaces_init(&confd);
rc = subscribe_module("ietf-interfaces", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to ietf-interfaces");
goto err;
}
rc = subscribe_module("ietf-netconf-acm", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to ietf-netconf-acm");
goto err;
}
rc = subscribe_module("infix-dhcp-client", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to infix-dhcp-client");
goto err;
}
rc = subscribe_module("ietf-keystore", &confd, SR_SUBSCR_UPDATE);
if (rc) {
ERROR("Failed to subscribe to ietf-keystore");
goto err;
}
rc = subscribe_module("infix-services", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to infix-services");
goto err;
}
rc = subscribe_module("ietf-system", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to ietf-system");
goto err;
}
rc = subscribe_module("ieee802-dot1ab-lldp", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to ieee802-dot1ab-lldp");
goto err;
}
#ifdef CONTAINERS
rc = subscribe_module("infix-containers", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to infix-containers");
goto err;
}
#endif
rc = subscribe_module("infix-dhcp-server", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to infix-dhcp-server");
goto err;
}
rc = subscribe_module("ietf-routing", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to ietf-routing");
goto err;
}
rc = subscribe_module("ietf-hardware", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to ietf-hardware");
goto err;
}
rc = subscribe_module("infix-firewall", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to infix-firewall");
goto err;
}
rc = subscribe_module("infix-meta", &confd, SR_SUBSCR_UPDATE);
if (rc) {
ERROR("Failed to subscribe to infix-meta");
goto err;
}
rc = ietf_system_rpc_init(&confd);
if (rc)
goto err;
rc = ietf_keystore_init(&confd);
rc = infix_containers_rpc_init(&confd);
if (rc)
goto err;
rc = ietf_syslog_init(&confd);
if (rc)
goto err;
rc = ietf_system_init(&confd);
if (rc)
goto err;
rc = infix_containers_init(&confd);
if (rc)
goto err;
rc = infix_dhcp_client_init(&confd);
if (rc)
goto err;
rc = infix_dhcp_server_init(&confd);
if (rc)
goto err;
rc = infix_factory_init(&confd);
if (rc)
goto err;
rc = ietf_factory_default_init(&confd);
if (rc)
goto err;
rc = ietf_routing_init(&confd);
if (rc)
goto err;
rc = infix_meta_init(&confd);
if (rc)
goto err;
rc = infix_system_sw_init(&confd);
if (rc)
goto err;
rc = infix_services_init(&confd);
if (rc)
goto err;
rc = ietf_hardware_init(&confd);
if (rc)
goto err;
rc = infix_firewall_init(&confd);
rc = infix_dhcp_server_rpc_init(&confd);
if (rc)
goto err;
rc = infix_factory_rpc_init(&confd);
if (rc)
goto err;
rc = ietf_factory_default_rpc_init(&confd);
if (rc)
goto err;
rc = infix_firewall_rpc_init(&confd);
if (rc)
goto err;
rc = infix_system_sw_rpc_init(&confd);
if (rc)
goto err;
/* Candidate infer configurations */
rc = ietf_hardware_candidate_init(&confd);
if (rc)
goto err;
rc = infix_firewall_candidate_init(&confd);
if (rc)
goto err;
rc = infix_dhcp_server_candidate_init(&confd);
if (rc)
goto err;
rc = infix_dhcp_client_candidate_init(&confd);
if (rc)
goto err;
/* YOUR_INIT GOES HERE */
return SR_ERR_OK;
err:
ERROR("init failed: %s", sr_strerror(rc));
if (confd.root)
+33 -19
View File
@@ -133,6 +133,7 @@ uint32_t core_hook_prio (void);
int core_pre_hook (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *);
int core_post_hook (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *);
int core_startup_save (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *);
int core_wait_change (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *);
static inline int register_change(sr_session_ctx_t *session, const char *module, const char *xpath,
int flags, sr_module_change_cb cb, void *arg, sr_subscription_ctx_t **sub)
@@ -206,57 +207,70 @@ static inline int register_rpc(sr_session_ctx_t *session, const char *xpath,
return rc;
}
/* ietf-interfaces.c */
int ietf_interfaces_init(struct confd *confd);
int ietf_interfaces_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
int ietf_interfaces_cand_init(struct confd *confd);
/* ietf-syslog.c */
int ietf_syslog_init(struct confd *confd);
int ietf_syslog_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
/* ietf-system.c */
int ietf_system_init (struct confd *confd);
int ietf_system_rpc_init (struct confd *confd);
int hostnamefmt (struct confd *confd, const char *fmt, char *hostnm, size_t hostlen, char *domain, size_t domlen);
int ietf_system_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
/* infix-containers.c */
#ifdef CONTAINERS
int infix_containers_init(struct confd *confd);
int infix_containers_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
int infix_containers_rpc_init(struct confd *confd);
#else
static inline int infix_containers_init(struct confd *confd) { return 0; }
static inline int infix_containers_rpc_init(struct confd *confd) { return 0; }
static inline int infix_containers_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd) { return 0; }
#endif
/* infix-dhcp-common.c */
int dhcp_option_lookup(const struct lyd_node *id);
/* infix-dhcp-client.c */
int infix_dhcp_client_init(struct confd *confd);
int infix_dhcp_client_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
int infix_dhcp_client_candidate_init(struct confd *confd);
/* infix-dhcp-server.c */
int infix_dhcp_server_init(struct confd *confd);
/* ietf-factory-default */
int ietf_factory_default_init(struct confd *confd);
int infix_dhcp_server_candidate_init(struct confd *confd);
int infix_dhcp_server_rpc_init(struct confd *confd);
int infix_dhcp_server_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
/* ietf-routing */
int ietf_routing_init(struct confd *confd);
int ietf_routing_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
/* infix-factory.c */
int infix_factory_init(struct confd *confd);
int infix_factory_rpc_init(struct confd *confd);
/* infix-factory.c */
int infix_meta_init(struct confd *confd);
/* ietf-factory-default */
int ietf_factory_default_rpc_init(struct confd *confd);
/* infix-meta.c */
int infix_meta_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
/* infix-system-software.c */
int infix_system_sw_init(struct confd *confd);
int infix_system_sw_rpc_init(struct confd *confd);
/* infix-services.c */
int infix_services_init(struct confd *confd);
int infix_services_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
/* ietf-hardware.c */
int ietf_hardware_init(struct confd *confd);
int ietf_hardware_candidate_init(struct confd *confd);
int ietf_hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
/* ietf-keystore.c */
int ietf_keystore_init(struct confd *confd);
#define SSH_HOSTKEYS "/etc/ssh/hostkeys"
#define SSH_HOSTKEYS_NEXT SSH_HOSTKEYS"+"
int ietf_keystore_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
/* infix-firewall.c */
int infix_firewall_init(struct confd *confd);
int infix_firewall_rpc_init(struct confd *confd);
int infix_firewall_candidate_init(struct confd *confd);
int infix_firewall_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
#endif /* CONFD_CORE_H_ */
+1 -1
View File
@@ -16,7 +16,7 @@ static int factory_reset(sr_session_ctx_t *session, uint32_t sub_id, const char
return 0;
}
int ietf_factory_default_init(struct confd *confd)
int ietf_factory_default_rpc_init(struct confd *confd)
{
int rc;
+7 -23
View File
@@ -183,26 +183,15 @@ static int hardware_cand(sr_session_ctx_t *session, uint32_t sub_id, const char
return err;
}
static int change_hardware(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
int ietf_hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *diff, *difs = NULL, *dif = NULL, *cifs = NULL, *cif = NULL;
sr_data_t *cfg;
struct lyd_node *difs = NULL, *dif = NULL, *cifs = NULL, *cif = NULL;
int rc = SR_ERR_OK;
struct confd *confd = (struct confd *)priv;
if (event != SR_EV_DONE)
if (event != SR_EV_DONE || !lydx_find_xpathf(diff, XPATH_BASE_))
return SR_ERR_OK;
rc = sr_get_data(session, XPATH_BASE_ "//.", 0, 0, 0, &cfg);
if (rc || !cfg)
goto err;
rc = srx_get_diff(session, &diff);
if (rc)
goto err_release_data;
cifs = lydx_get_descendant(cfg->tree, "hardware", "component", NULL);
cifs = lydx_get_descendant(config, "hardware", "component", NULL);
difs = lydx_get_descendant(diff, "hardware", "component", NULL);
LYX_LIST_FOR_EACH(difs, dif, "component") {
@@ -216,7 +205,7 @@ static int change_hardware(sr_session_ctx_t *session, uint32_t sub_id, const cha
if (op == LYDX_OP_DELETE) {
if (usb_authorize(confd->root, name, 0)) {
rc = SR_ERR_INTERNAL;
goto err_release_diff;
goto err;;
}
continue;
}
@@ -233,23 +222,18 @@ static int change_hardware(sr_session_ctx_t *session, uint32_t sub_id, const cha
admin_state = lydx_get_cattr(state, "admin-state");
if (usb_authorize(confd->root, name, !strcmp(admin_state, "unlocked"))) {
rc = SR_ERR_INTERNAL;
goto err_release_diff;
goto err;;
}
}
}
err_release_diff:
lyd_free_tree(diff);
err_release_data:
sr_release_data(cfg);
err:
return rc;
}
int ietf_hardware_init(struct confd *confd)
int ietf_hardware_candidate_init(struct confd *confd)
{
int rc = 0;
REGISTER_CHANGE(confd->session, "ietf-hardware", XPATH_BASE_, 0, change_hardware, confd, &confd->sub);
REGISTER_CHANGE(confd->cand, "ietf-hardware", XPATH_BASE_,
SR_SUBSCR_UPDATE, hardware_cand, confd, &confd->sub);
+9 -84
View File
@@ -787,12 +787,9 @@ static sr_error_t ifchange_post(sr_session_ctx_t *session, struct dagger *net,
return err ? SR_ERR_INTERNAL : SR_ERR_OK;
}
static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
int ietf_interfaces_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *diff, *cifs, *difs, *cif, *dif;
struct confd *confd = _confd;
sr_data_t *cfg;
struct lyd_node *cifs, *difs, *cif, *dif;
sr_error_t err;
switch (event) {
@@ -814,19 +811,11 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu
if (err)
return err;
err = sr_get_data(session, "//.", 0, 0, 0, &cfg);
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, (struct lyd_node **)&diff);
if (err)
goto err_release_data;
cifs = lydx_get_descendant(cfg->tree, "interfaces", "interface", NULL);
cifs = lydx_get_descendant(config, "interfaces", "interface", NULL);
difs = lydx_get_descendant(diff, "interfaces", "interface", NULL);
err = netdag_init(session, &confd->netdag, cifs, difs);
if (err)
goto err_free_diff;
goto err_out;
LYX_LIST_FOR_EACH(difs, dif, "interface") {
LYX_LIST_FOR_EACH(cifs, cif, "interface")
@@ -840,71 +829,9 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu
}
err = err ? : ifchange_post(session, &confd->netdag, cifs, difs);
err_free_diff:
lyd_free_tree(diff);
err_release_data:
sr_release_data(cfg);
err_abandon:
if (err)
dagger_abandon(&confd->netdag);
return err;
}
static int keystorecb(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
{
const struct lyd_node *diff;
const char *secret_name;
struct confd *confd = _confd;
struct lyd_node *interfaces, *interface, *dkeys, *dkey, *wifi;
sr_data_t *cfg = NULL;
int err = SR_ERR_OK;
switch (event) {
case SR_EV_CHANGE:
break;
default:
return SR_ERR_OK;
}
err = sr_get_data(session, "/interfaces/interface", 0, 0, 0, &cfg);
if (err || !cfg)
return err;
diff = sr_get_change_diff(session);
if (!diff)
goto cleanup;
interfaces = lydx_get_descendant(cfg->tree, "interfaces", "interface", NULL);
dkeys = lydx_get_descendant((struct lyd_node*) diff, "keystore", "symmetric-keys", "symmetric-key", NULL);
LYX_LIST_FOR_EACH(dkeys, dkey, "symmetric-key") {
secret_name = lydx_get_cattr(dkey, "name");
if (!secret_name)
continue;
LYX_LIST_FOR_EACH(interfaces, interface, "interface") {
const char *name;
if (iftype_from_iface(interface) != IFT_WIFI)
continue;
wifi = lydx_get_child(interface, "wifi");
if (!wifi)
continue;
name = lydx_get_cattr(wifi, "secret");
if (!name || strcmp(name, secret_name))
continue;
wifi_gen(NULL, interface, &confd->netdag);
}
}
cleanup:
if (cfg)
sr_release_data(cfg);
err_out:
return err;
}
@@ -974,18 +901,16 @@ int ietf_interfaces_get_all_l3(const struct lyd_node *tree, char ***ifaces)
return 0;
}
int ietf_interfaces_init(struct confd *confd)
int ietf_interfaces_cand_init(struct confd *confd)
{
int rc;
int rc = SR_ERR_OK;
REGISTER_CHANGE(confd->session, "ietf-interfaces", "/ietf-interfaces:interfaces//.",
SR_SUBSCR_CHANGE_ALL_MODULES, ifchange, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-keystore", "//*",
SR_SUBSCR_CHANGE_ALL_MODULES, keystorecb, confd, &confd->sub);
REGISTER_CHANGE(confd->cand, "ietf-interfaces", "/ietf-interfaces:interfaces//.",
SR_SUBSCR_UPDATE, ifchange_cand, confd, &confd->sub);
return SR_ERR_OK;
fail:
ERROR("failed, error %d: %s", rc, sr_strerror(rc));
return rc;
}
+120 -85
View File
@@ -51,106 +51,141 @@ static char *filerd(const char *fn, size_t len)
return buf;
}
static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name,
const char *xpath, sr_event_t event, uint32_t request_id, void *_)
int ietf_keystore_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
int rc = SR_ERR_INTERNAL;
sr_val_t *list = NULL;
struct lyd_node *changes, *change;
sr_val_t *list = NULL;
int rc = SR_ERR_OK;
size_t count = 0;
if (diff && !lydx_find_xpathf(diff, XPATH_KEYSTORE_))
return SR_ERR_OK;
switch (event) {
case SR_EV_UPDATE:
/* Check SSH (and NETCONF) default hostkey pair */
rc = sr_get_items(session, "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key", 0, 0, &list, &count);
if (rc != SR_ERR_OK) {
ERROR("Cannot find any asymmetric keys in configuration");
return 0;
}
for (size_t i = 0; i < count; ++i) {
sr_val_t *entry = &list[i];
if (!srx_isset(session, "%s/cleartext-private-key", entry->xpath) && !srx_isset(session, "%s/public-key", entry->xpath)) {
char *private_key_format, *public_key_format;
public_key_format = srx_get_str(session, "%s/public-key-format", entry->xpath);
if (!public_key_format)
continue;
private_key_format = srx_get_str(session, "%s/private-key-format", entry->xpath);
if (!private_key_format) {
free(public_key_format);
continue;
}
if (!strcmp(private_key_format, "infix-crypto-types:rsa-private-key-format") &&
!strcmp(public_key_format, "infix-crypto-types:ssh-public-key-format")) {
char *pub_key = NULL, *priv_key = NULL, *name;
name = srx_get_str(session, "%s/name", entry->xpath);
NOTE("SSH key (%s) does not exist, generating...", name);
if (systemf("/usr/libexec/infix/mkkeys %s %s", SSH_PRIVATE_KEY, SSH_PUBLIC_KEY)) {
ERROR("Failed to generate SSH keys for %s", name);
goto next;
}
priv_key = filerd(SSH_PRIVATE_KEY, filesz(SSH_PRIVATE_KEY));
if (!priv_key)
goto next;
pub_key = filerd(SSH_PUBLIC_KEY, filesz(SSH_PUBLIC_KEY));
if (!pub_key)
goto next;
rc = srx_set_str(session, priv_key, 0, "%s/cleartext-private-key", entry->xpath);
if (rc) {
ERROR("Failed setting private key for %s... rc: %d", name, rc);
goto next;
}
rc = srx_set_str(session, pub_key, 0, "%s/public-key", entry->xpath);
if (rc != SR_ERR_OK) {
ERROR("Failed setting public key for %s... rc: %d", name, rc);
goto next;
}
next:
if (erase(SSH_PRIVATE_KEY))
ERRNO("Failed removing SSH server private key");
if (erase(SSH_PUBLIC_KEY))
ERRNO("Failed removing SSH server public key");
if (priv_key)
free(priv_key);
if (pub_key)
free(pub_key);
free(name);
}
free(public_key_format);
free(private_key_format);
}
}
if (list)
sr_free_values(list, count);
break;
case SR_EV_CHANGE:
case SR_EV_ENABLED:
break;
case SR_EV_ABORT:
rmrf(SSH_HOSTKEYS_NEXT);
return SR_ERR_OK;
case SR_EV_DONE:
if(fexist(SSH_HOSTKEYS_NEXT)) {
if(rmrf(SSH_HOSTKEYS)) {
ERRNO("Failed to remove old SSH hostkeys: %d", errno);
}
if (rename(SSH_HOSTKEYS_NEXT, SSH_HOSTKEYS))
ERRNO("Failed switching to new %s", SSH_HOSTKEYS);
}
return SR_ERR_OK;
default:
return SR_ERR_OK;
}
rc = sr_get_items(session, xpath, 0, 0, &list, &count);
if (rc != SR_ERR_OK) {
ERROR("Cannot find any asymmetric keys in configuration");
return 0;
}
changes = lydx_get_descendant(config, "keystore", "asymmetric-keys", "asymmetric-key", NULL);
LYX_LIST_FOR_EACH(changes, change, "asymmetric-key") {
const char *name, *private_key_type, *public_key_type;
const char *private_key, *public_key;
for (size_t i = 0; i < count; ++i) {
sr_val_t *entry = &list[i];
name = lydx_get_cattr(change, "name");
private_key_type = lydx_get_cattr(change, "private-key-format");
public_key_type = lydx_get_cattr(change, "public-key-format");
if (!srx_isset(session, "%s/cleartext-private-key", entry->xpath) && !srx_isset(session, "%s/public-key", entry->xpath)) {
char *private_key_format, *public_key_format;
public_key_format = srx_get_str(session, "%s/public-key-format", entry->xpath);
if (!public_key_format)
continue;
private_key_format = srx_get_str(session, "%s/private-key-format", entry->xpath);
if (!private_key_format) {
free(public_key_format);
continue;
}
if (!strcmp(private_key_format, "infix-crypto-types:rsa-private-key-format") &&
!strcmp(public_key_format, "infix-crypto-types:ssh-public-key-format")) {
char *pub_key = NULL, *priv_key = NULL, *name;
name = srx_get_str(session, "%s/name", entry->xpath);
NOTE("SSH key (%s) does not exist, generating...", name);
if (systemf("/usr/libexec/infix/mkkeys %s %s", SSH_PRIVATE_KEY, SSH_PUBLIC_KEY)) {
ERROR("Failed to generate SSH keys for %s", name);
goto next;
}
priv_key = filerd(SSH_PRIVATE_KEY, filesz(SSH_PRIVATE_KEY));
if (!priv_key)
goto next;
pub_key = filerd(SSH_PUBLIC_KEY, filesz(SSH_PUBLIC_KEY));
if (!pub_key)
goto next;
rc = srx_set_str(session, priv_key, 0, "%s/cleartext-private-key", entry->xpath);
if (rc) {
ERROR("Failed setting private key for %s... rc: %d", name, rc);
goto next;
}
rc = srx_set_str(session, pub_key, 0, "%s/public-key", entry->xpath);
if (rc != SR_ERR_OK) {
ERROR("Failed setting public key for %s... rc: %d", name, rc);
goto next;
}
next:
if (erase(SSH_PRIVATE_KEY))
ERRNO("Failed removing SSH server private key");
if (erase(SSH_PUBLIC_KEY))
ERRNO("Failed removing SSH server public key");
if (priv_key)
free(priv_key);
if (pub_key)
free(pub_key);
free(name);
}
free(public_key_format);
free(private_key_format);
if (strcmp(private_key_type, "infix-crypto-types:rsa-private-key-format")) {
INFO("Private key %s is not of SSH type", name);
continue;
}
if (strcmp(public_key_type, "infix-crypto-types:ssh-public-key-format")) {
INFO("Public key %s is not of SSH type", name);
continue;
}
private_key = lydx_get_cattr(change, "cleartext-private-key");
public_key = lydx_get_cattr(change, "public-key");
if (mkdir(SSH_HOSTKEYS_NEXT, 0600) && (errno != EEXIST)) {
ERRNO("Failed creating %s", SSH_HOSTKEYS_NEXT);
rc = SR_ERR_INTERNAL;
}
if(systemf("/usr/libexec/infix/mksshkey %s %s %s %s", name, SSH_HOSTKEYS_NEXT, public_key, private_key))
rc = SR_ERR_INTERNAL;
}
if (list)
sr_free_values(list, count);
return SR_ERR_OK;
}
int ietf_keystore_init(struct confd *confd)
{
int rc;
REGISTER_CHANGE(confd->session, "ietf-keystore", "/ietf-keystore:keystore//.",
SR_SUBSCR_UPDATE, change_cb, confd, &confd->sub);
return SR_ERR_OK;
fail:
if(rc)
ERROR("%s failed: %s", __func__, sr_strerror(rc));
return rc;
}
+13 -34
View File
@@ -244,17 +244,18 @@ static int parse_static_routes(sr_session_ctx_t *session, struct lyd_node *paren
return num_routes;
}
static int change_control_plane_protocols(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
int ietf_routing_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
int staticd_enabled = 0, ospfd_enabled = 0, bfdd_enabled = 0;
struct lyd_node *cplane, *cplanes;
bool ospfd_running, bfdd_running;
struct lyd_node *cplane, *tmp;
bool restart_zebra = false;
int rc = SR_ERR_OK;
sr_data_t *cfg;
FILE *fp;
if (diff && !lydx_get_xpathf(diff, "/ietf-routing:routing"))
return SR_ERR_OK;
switch (event) {
case SR_EV_ENABLED: /* first time, on register. */
case SR_EV_CHANGE: /* regular change (copy cand running) */
@@ -351,27 +352,18 @@ static int change_control_plane_protocols(sr_session_ctx_t *session, uint32_t su
return SR_ERR_OK;
}
rc = sr_get_data(session, "/ietf-routing:routing/control-plane-protocols//.", 0, 0, 0, &cfg);
if (rc || !cfg) {
NOTE("No control-plane-protocols available.");
goto err_close;
}
cplanes = lydx_get_descendant(config, "routing", "control-plane-protocols", "control-plane-protocol", NULL);
LYX_LIST_FOR_EACH(cplanes, cplane, "control-plane-protocol") {
const char *type;
LY_LIST_FOR(lyd_child(cfg->tree), tmp) {
LY_LIST_FOR(lyd_child(tmp), cplane) {
const char *type;
type = lydx_get_cattr(cplane, "type");
if (!strcmp(type, "infix-routing:static")) {
staticd_enabled = parse_static_routes(session, lydx_get_child(cplane, "static-routes"), fp);
} else if (!strcmp(type, "infix-routing:ospfv2")) {
parse_ospf(session, lydx_get_child(cplane, "ospf"));
}
type = lydx_get_cattr(cplane, "type");
if (!strcmp(type, "infix-routing:static")) {
staticd_enabled = parse_static_routes(session, lydx_get_child(cplane, "static-routes"), fp);
} else if (!strcmp(type, "infix-routing:ospfv2")) {
parse_ospf(session, lydx_get_child(cplane, "ospf"));
}
}
sr_release_data(cfg);
err_close:
fclose(fp);
if (!staticd_enabled)
(void)remove(STATICD_CONF_NEXT);
@@ -379,16 +371,3 @@ err_close:
err_abandon:
return rc;
}
int ietf_routing_init(struct confd *confd)
{
int rc = 0;
REGISTER_CHANGE(confd->session, "ietf-routing", "/ietf-routing:routing/control-plane-protocols",
0, change_control_plane_protocols, confd, &confd->sub);
return SR_ERR_OK;
fail:
ERROR("Init routing failed: %s", sr_strerror(rc));
return rc;
}
+29 -41
View File
@@ -218,13 +218,12 @@ static const char *getnm(struct lyd_node *node, char *xpath, size_t len)
return name;
}
static int file_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int file_change(sr_session_ctx_t *session, struct lyd_node *config,struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *files, *file, *tree;
int err;
if (SR_EV_DONE != event)
if (SR_EV_DONE != event || !lydx_get_xpathf(diff, XPATH_FILE_))
return SR_ERR_OK;
err = srx_get_diff(session, &tree);
@@ -253,21 +252,15 @@ static int file_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
return SR_ERR_OK;
}
static int remote_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int remote_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *remotes, *remote, *tree;
int err;
struct lyd_node *dremotes, *remote;
if (SR_EV_DONE != event)
if (SR_EV_DONE != event || !lydx_get_xpathf(diff, XPATH_REMOTE_))
return SR_ERR_OK;
err = srx_get_diff(session, &tree);
if (err)
return SR_ERR_OK;
remotes = lydx_get_descendant(tree, "syslog", "actions", "remote", "destination", NULL);
LYX_LIST_FOR_EACH(remotes, remote, "destination") {
dremotes = lydx_get_descendant(diff, "syslog", "actions", "remote", "destination", NULL);
LYX_LIST_FOR_EACH(dremotes, remote, "destination") {
struct lyd_node *node = lydx_get_child(remote, "name");
enum lydx_op op = lydx_get_op(node);
char path[512] = XPATH_REMOTE_;
@@ -283,23 +276,22 @@ static int remote_change(sr_session_ctx_t *session, uint32_t sub_id, const char
addr.address = srx_get_str(session, "%s/udp/address", path);
srx_get_int(session, &addr.port, SR_UINT16_T, "%s/udp/port", path);
action(session, name, xpath, &addr);
action(session, name, path, &addr);
}
}
srx_free_changes(tree);
systemf("initctl -nbq touch sysklogd");
return SR_ERR_OK;
}
static int rotate_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int rotate_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
char path[512] = XPATH_ROTATE_;
char *sz, *cnt;
FILE *fp;
if (SR_EV_DONE != event)
if (SR_EV_DONE != event || !lydx_get_xpathf(diff, XPATH_ROTATE_))
return SR_ERR_OK;
fp = fopen(SYSLOG_ROTATE, "w");
@@ -308,13 +300,13 @@ static int rotate_change(sr_session_ctx_t *session, uint32_t sub_id, const char
return SR_ERR_SYS;
}
sz = srx_get_str(session, "%s/max-file-size", xpath);
sz = srx_get_str(session, "%s/max-file-size", path);
if (sz) {
fprintf(fp, "rotate_size %sk\n", sz);
free(sz);
}
cnt = srx_get_str(session, "%s/number-of-files", xpath);
cnt = srx_get_str(session, "%s/number-of-files", path);
if (cnt) {
fprintf(fp, "rotate_count %s\n", cnt);
free(cnt);
@@ -326,18 +318,18 @@ static int rotate_change(sr_session_ctx_t *session, uint32_t sub_id, const char
return SR_ERR_OK;
}
static int server_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int server_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
char path[512] = XPATH_SERVER_;
sr_val_t *list = NULL;
size_t count;
FILE *fp;
if (SR_EV_DONE != event)
if (SR_EV_DONE != event || !lydx_get_xpathf(diff, XPATH_SERVER_))
return SR_ERR_OK;
if (!srx_enabled(session, "%s/enabled", xpath)) {
if (remove(SYSLOG_SERVER))
if (!srx_enabled(session, "%s/enabled", path)) {
if (erase(SYSLOG_SERVER))
ERRNO("failed disabling syslog server");
goto done;
}
@@ -351,7 +343,7 @@ static int server_change(sr_session_ctx_t *session, uint32_t sub_id, const char
/* Allow listening on port 514, or custom listen below */
fprintf(fp, "secure_mode 0\n");
if (!srx_get_items(session, &list, &count, "%s/listen/udp", xpath)) {
if (!srx_get_items(session, &list, &count, "%s/listen/udp", path)) {
for (size_t i = 0; i < count; ++i) {
sr_val_t *entry = &list[i];
char *address, *port;
@@ -373,21 +365,17 @@ done:
return SR_ERR_OK;
}
int ietf_syslog_init(struct confd *confd)
int ietf_syslog_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
int rc = SR_ERR_SYS;
if (!confd)
goto fail;
REGISTER_CHANGE(confd->session, "ietf-syslog", XPATH_FILE_"//.", 0, file_change, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-syslog", XPATH_REMOTE_"//.", 0, remote_change, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-syslog", XPATH_ROTATE_"//.", 0, rotate_change, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-syslog", XPATH_SERVER_"//.", 0, server_change, confd, &confd->sub);
int rc = SR_ERR_OK;
if ((rc = file_change(session, config, diff, event, confd)))
return rc;
if ((rc = remote_change(session, config, diff, event, confd)))
return rc;
if ((rc = rotate_change(session, config, diff, event, confd)))
return rc;
if ((rc = server_change(session, config, diff, event, confd)))
return rc;
return SR_ERR_OK;
fail:
ERROR("%s failed: %s", __func__, sr_strerror(rc));
return rc;
}
+73 -55
View File
@@ -21,12 +21,18 @@
#include "base64.h"
#include "core.h"
#define NACM_BASE_ "/ietf-netconf-acm:nacm"
#define XPATH_BASE_ "/ietf-system:system"
#define XPATH_AUTH_ XPATH_BASE_"/authentication"
#define CLOCK_PATH_ "/ietf-system:system-state/clock"
#define PLATFORM_PATH_ "/ietf-system:system-state/platform"
#define PASSWORD_PATH "/ietf-system:system/authentication/user/password"
#define NACM_BASE_ "/ietf-netconf-acm:nacm"
#define XPATH_BASE_ "/ietf-system:system"
#define XPATH_AUTH_ XPATH_BASE_"/authentication"
#define XPATH_NTP_ XPATH_BASE_"/ntp"
#define XPATH_DNS_ XPATH_BASE_"/dns-resolver"
#define XPATH_HOSTNAME_ XPATH_BASE_"/hostname"
#define XPATH_MOTD_BANNER_ XPATH_BASE_"/infix-system:motd-banner"
#define XPATH_MOTD_ XPATH_BASE_"/infix-system:motd"
#define XPATH_EDITOR_ XPATH_BASE_"/infix-system:text-editor"
#define CLOCK_PATH_ "/ietf-system:system-state/clock"
#define PLATFORM_PATH_ "/ietf-system:system-state/platform"
#define PASSWORD_PATH "/ietf-system:system/authentication/user/password"
#define _PATH_PASSWD "/etc/passwd"
#define _PATH_HOSTNAME "/etc/hostname"
@@ -210,12 +216,13 @@ static int sys_reload_services(void)
#define TIMEZONE_PREV TIMEZONE_CONF "-"
#define TIMEZONE_NEXT TIMEZONE_CONF "+"
static int change_clock(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int change_clock(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
char *tz_utc_offset, *timezone;
int rc = SR_ERR_OK;
if (diff && !lydx_get_xpathf(diff, XPATH_BASE_"/clock"))
return SR_ERR_OK;
switch (event) {
case SR_EV_ENABLED: /* first time, on register. */
case SR_EV_CHANGE: /* regular change (copy cand running) */
@@ -280,8 +287,7 @@ err:
return rc;
}
static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *_, sr_event_t event, unsigned request_id, void *priv)
static int change_ntp(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
sr_change_iter_t *iter = NULL;
int rc, err = SR_ERR_OK;
@@ -289,6 +295,8 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
sr_val_t *val;
size_t cnt;
if (diff && !lydx_get_xpathf(diff, XPATH_NTP_))
return SR_ERR_OK;
switch (event) {
case SR_EV_ENABLED: /* first time, on register. */
case SR_EV_CHANGE: /* regular change (copy cand running) */
@@ -299,7 +307,7 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
return SR_ERR_OK;
case SR_EV_DONE:
if (!srx_enabled(session, XPATH_BASE_"/ntp/enabled")) {
if (!srx_enabled(session, XPATH_NTP_"/enabled")) {
systemf("rm -rf /etc/chrony/conf.d/* /etc/chrony/sources.d/*");
systemf("initctl -nbq disable chronyd");
return SR_ERR_OK;
@@ -411,8 +419,7 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
#define RESOLV_PREV RESOLV_CONF "-"
#define RESOLV_NEXT RESOLV_CONF "+"
static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int change_dns(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
const char *fn = RESOLV_NEXT;
int timeout = 0, attempts = 0;
@@ -421,6 +428,9 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
size_t cnt;
FILE *fp;
if (diff && !lydx_get_xpathf(diff, XPATH_DNS_))
return SR_ERR_OK;
switch (event) {
case SR_EV_ENABLED: /* first time, on register. */
case SR_EV_CHANGE: /* regular change (copy cand running) */
@@ -453,8 +463,8 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
return SR_ERR_SYS;
}
SRX_GET_UINT8(session, timeout, XPATH_BASE_"/dns-resolver/options/timeout");
SRX_GET_UINT8(session, attempts, XPATH_BASE_"/dns-resolver/options/attempts");
SRX_GET_UINT8(session, timeout, XPATH_DNS_"/options/timeout");
SRX_GET_UINT8(session, attempts, XPATH_DNS_"/dns-resolver/options/attempts");
if (timeout || attempts) {
fprintf(fp, "options");
if (timeout)
@@ -1288,11 +1298,10 @@ cleanup:
return err;
}
static int change_auth(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int change_auth(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct confd *confd = (struct confd *)priv;
if (diff && !lydx_get_xpathf(diff, XPATH_AUTH_))
return SR_ERR_OK;
switch (event) {
case SR_EV_UPDATE:
return change_auth_ctp(confd, session);
@@ -1307,14 +1316,13 @@ static int change_auth(sr_session_ctx_t *session, uint32_t sub_id, const char *m
return SR_ERR_OK;
}
static int change_nacm(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *_, sr_event_t event, unsigned request_id, void *priv)
static int change_nacm(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
sr_val_t *users = NULL;
size_t user_count = 0;
int rc;
if (event != SR_EV_DONE)
if (event != SR_EV_DONE ||!lydx_get_xpathf(diff, NACM_BASE_))
return SR_ERR_OK;
/* Fetch all users from ietf-system */
@@ -1346,18 +1354,18 @@ cleanup:
return 0;
}
static int change_motd(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int change_motd(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
const char *fn = "/etc/motd";
char *message;
int rc = 0;
/* Ignore all events except SR_EV_DONE */
if (event != SR_EV_DONE)
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, XPATH_MOTD_))
return SR_ERR_OK;
message = srx_get_str(session, "%s", xpath);
message = srx_get_str(session, "%s", XPATH_MOTD_);
if (message) {
rc = writesf(message, "w", "%s", fn);
free(message);
@@ -1371,8 +1379,7 @@ static int change_motd(sr_session_ctx_t *session, uint32_t sub_id, const char *m
return SR_ERR_OK;
}
static int change_motd_banner(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int change_motd_banner(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
const char *fn = "/etc/motd";
unsigned char *raw;
@@ -1380,24 +1387,24 @@ static int change_motd_banner(sr_session_ctx_t *session, uint32_t sub_id, const
int rc = 0;
/* Ignore all events except SR_EV_DONE */
if (event != SR_EV_DONE)
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, XPATH_MOTD_BANNER_))
return SR_ERR_OK;
legacy = srx_get_str(session, "/ietf-system:system/infix-system:motd");
legacy = srx_get_str(session, XPATH_MOTD_);
if (legacy) {
NOTE("Legacy /system/motd exists, skipping %s", xpath);
NOTE("Legacy /system/motd exists, skipping %s", XPATH_MOTD_BANNER_);
free(legacy);
return SR_ERR_OK;
}
raw = (unsigned char *)srx_get_str(session, "%s", xpath);
raw = (unsigned char *)srx_get_str(session, "%s", XPATH_BASE_"/infix-system:motd-banner");
if (raw) {
unsigned char *txt;
size_t txt_len;
txt = base64_decode(raw, strlen((char *)raw), &txt_len);
if (!txt) {
ERRNO("failed base64 decoding of %s", xpath);
ERRNO("failed base64 decoding of %s", XPATH_BASE_"/infix-system:motd-banner");
rc = -1;
} else {
FILE *fp = fopen(fn, "w");
@@ -1431,8 +1438,7 @@ static int change_motd_banner(sr_session_ctx_t *session, uint32_t sub_id, const
return SR_ERR_OK;
}
static int change_editor(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int change_editor(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
const char *alt = "/etc/alternatives/editor";
struct { const char *editor, *path; } map[] = {
@@ -1444,10 +1450,10 @@ static int change_editor(sr_session_ctx_t *session, uint32_t sub_id, const char
int rc = 0;
/* Ignore all events except SR_EV_DONE */
if (event != SR_EV_DONE)
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, XPATH_EDITOR_))
return SR_ERR_OK;
editor = srx_get_str(session, "%s", xpath);
editor = srx_get_str(session, "%s", XPATH_BASE_"/infix-system:text-editor");
if (!editor)
return SR_ERR_OK;
@@ -1550,20 +1556,18 @@ int hostnamefmt(struct confd *confd, const char *fmt, char *hostnm, size_t hostl
return 0;
}
static int change_hostname(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
static int change_hostname(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct confd *confd = (struct confd *)priv;
const char *hostip = "127.0.1.1";
char hostnm[65], domain[65];
char buf[256], *fmt;
FILE *nfp, *fp;
int err, fd;
if (event != SR_EV_DONE)
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, XPATH_HOSTNAME_))
return SR_ERR_OK;
fmt = srx_get_str(session, "%s", xpath);
fmt = srx_get_str(session, "%s", XPATH_BASE_"/hostname");
if (!fmt)
fmt = strdup(nm);
@@ -1648,24 +1652,38 @@ err:
return SR_ERR_OK;
}
int ietf_system_init(struct confd *confd)
int ietf_system_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
int rc = SR_ERR_OK;
if ((rc = change_auth(session, config, diff, event, confd)))
return rc;
if ((rc = change_ntp(session, config, diff, event, confd)))
return rc;
if ((rc = change_dns(session, config, diff, event, confd)))
return rc;
if ((rc = change_editor(session,config, diff, event, confd)))
return rc;
if ((rc = change_clock(session, config, diff, event, confd)))
return rc;
if ((rc = change_hostname(session, config, diff, event, confd)))
return rc;
if ((rc = change_motd(session, config, diff, event, confd)))
return rc;
if ((rc = change_motd_banner(session, config, diff, event, confd)))
return rc;
if ((rc = change_nacm(session, config, diff, event, confd))) /* Must be called after ietf_system_change_auth, which create the users */
return rc;
return SR_ERR_OK;
}
int ietf_system_rpc_init(struct confd *confd)
{
int rc;
os_init();
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_AUTH_, 0, change_auth, confd, &confd->sub);
REGISTER_MONITOR(confd->session, "ietf-netconf-acm", "/ietf-netconf-acm:nacm//.",
0, change_nacm, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/hostname", 0, change_hostname, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:motd", 0, change_motd, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:motd-banner", 0, change_motd_banner, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:text-editor", 0, change_editor, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/clock", 0, change_clock, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/ntp", 0, change_ntp, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/dns-resolver", 0, change_dns, confd, &confd->sub);
REGISTER_RPC(confd->session, "/ietf-system:system-restart", rpc_exec, "reboot", &confd->sub);
REGISTER_RPC(confd->session, "/ietf-system:system-shutdown", rpc_exec, "poweroff", &confd->sub);
REGISTER_RPC(confd->session, "/ietf-system:set-current-datetime", rpc_set_datetime, NULL, &confd->sub);
+7 -28
View File
@@ -349,23 +349,19 @@ static int del(const char *name)
return SR_ERR_OK;
}
static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
int infix_containers_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *diff, *cifs, *difs, *cif, *dif;
struct lyd_node *cifs, *difs, *cif, *dif;
sr_error_t err = 0;
sr_data_t *cfg;
if (diff && !lydx_get_xpathf(diff, CFG_XPATH))
return SR_ERR_OK;
switch (event) {
case SR_EV_DONE:
break;
case SR_EV_CHANGE:
err = sr_get_data(session, CFG_XPATH "//.", 0, 0, 0, &cfg);
if (err || !cfg)
return SR_ERR_INTERNAL;
cifs = lydx_get_descendant(cfg->tree, "containers", "container", NULL);
cifs = lydx_get_descendant(config, "containers", "container", NULL);
LYX_LIST_FOR_EACH(cifs, cif, "container") {
struct lyd_node *mount;
LYX_LIST_FOR_EACH(lyd_child(cif), mount, "mount") {
@@ -379,13 +375,10 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
"Container '%s': mount '%s' source file '%s' is invalid: %s",
lydx_get_cattr(cif, "name"), id, src, reason);
sr_session_set_error_message(session, errmsg);
sr_release_data(cfg);
return SR_ERR_VALIDATION_FAILED;
}
}
}
sr_release_data(cfg);
return SR_ERR_OK;
case SR_EV_ABORT:
@@ -393,15 +386,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
return SR_ERR_OK;
}
err = sr_get_data(session, CFG_XPATH "//.", 0, 0, 0, &cfg);
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, &diff);
if (err)
goto err_release_data;
cifs = lydx_get_descendant(cfg->tree, "containers", "container", NULL);
cifs = lydx_get_descendant(config, "containers", "container", NULL);
difs = lydx_get_descendant(diff, "containers", "container", NULL);
/* find the modified one, delete or recreate only that */
@@ -422,11 +407,6 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
}
}
lyd_free_tree(diff);
err_release_data:
sr_release_data(cfg);
err_abandon:
return err;
}
@@ -484,11 +464,10 @@ static int oci_load(sr_session_ctx_t *session, uint32_t sub_id, const char *xpat
return SR_ERR_OK;
}
int infix_containers_init(struct confd *confd)
int infix_containers_rpc_init(struct confd *confd)
{
int rc;
REGISTER_CHANGE(confd->session, MODULE, CFG_XPATH, 0, change, confd, &confd->sub);
REGISTER_RPC(confd->session, CFG_XPATH "/container/start", action, NULL, &confd->sub);
REGISTER_RPC(confd->session, CFG_XPATH "/container/stop", action, NULL, &confd->sub);
REGISTER_RPC(confd->session, CFG_XPATH "/container/restart", action, NULL, &confd->sub);
+5 -21
View File
@@ -278,12 +278,10 @@ static void del(const char *ifname)
systemf("initctl -bfq delete dhcp-client-%s", ifname);
}
static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
int infix_dhcp_client_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *global, *diff, *cifs, *difs, *cif, *dif;
struct lyd_node *global, *cifs, *difs, *cif, *dif;
sr_error_t err = 0;
sr_data_t *cfg;
int ena = 0;
switch (event) {
@@ -295,18 +293,10 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
return SR_ERR_OK;
}
err = sr_get_data(session, "//.", 0, 0, 0, &cfg);
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, &diff);
if (err)
goto err_release_data;
global = lydx_get_descendant(cfg->tree, "dhcp-client", NULL);
global = lydx_get_descendant(config, "dhcp-client", NULL);
ena = lydx_is_enabled(global, "enabled");
cifs = lydx_get_descendant(cfg->tree, "dhcp-client", "client-if", NULL);
cifs = lydx_get_descendant(config, "dhcp-client", "client-if", NULL);
difs = lydx_get_descendant(diff, "dhcp-client", "client-if", NULL);
/* find the modified one, delete or recreate only that */
@@ -339,11 +329,6 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
}
}
lyd_free_tree(diff);
err_release_data:
sr_release_data(cfg);
err_abandon:
return err;
}
@@ -421,11 +406,10 @@ static int cand(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
return SR_ERR_OK;
}
int infix_dhcp_client_init(struct confd *confd)
int infix_dhcp_client_candidate_init(struct confd *confd)
{
int rc;
REGISTER_CHANGE(confd->session, MODULE, XPATH, 0, change, confd, &confd->sub);
REGISTER_CHANGE(confd->cand, MODULE, XPATH"//.", SR_SUBSCR_UPDATE, cand, confd, &confd->sub);
return SR_ERR_OK;
+20 -22
View File
@@ -294,13 +294,14 @@ static void del(const char *subnet, struct lyd_node *cfg)
ERRNO("Failed switching to new %s", DNSMASQ_LEASES);
}
static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
int infix_dhcp_server_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *global, *diff, *cifs, *difs, *cif, *dif;
struct lyd_node *global, *cifs, *difs, *cif, *dif;
int enabled = 0, added = 0, deleted = 0;
sr_error_t err = 0;
sr_data_t *cfg;
if (!lydx_get_xpathf(diff, CFG_XPATH))
return SR_ERR_OK;
switch (event) {
case SR_EV_DONE:
@@ -311,18 +312,10 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
return SR_ERR_OK;
}
err = sr_get_data(session, "//.", 0, 0, 0, &cfg);
if (err || !cfg)
goto err_abandon;
err = srx_get_diff(session, &diff);
if (err)
goto err_release_data;
global = lydx_get_descendant(cfg->tree, "dhcp-server", NULL);
global = lydx_get_descendant(config, "dhcp-server", NULL);
enabled = lydx_is_enabled(global, "enabled");
cifs = lydx_get_descendant(cfg->tree, "dhcp-server", "subnet", NULL);
cifs = lydx_get_descendant(config, "dhcp-server", "subnet", NULL);
difs = lydx_get_descendant(diff, "dhcp-server", "subnet", NULL);
/* find the modified one, delete or recreate only that */
@@ -356,7 +349,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
if (!fp)
goto err_done;
node = lydx_get_xpathf(cfg->tree, "/ietf-system:system/hostname");
node = lydx_get_xpathf(config, "/ietf-system:system/hostname");
if (node) {
const char *hostname = lyd_get_value(node);
const char *ptr = hostname ? strchr(hostname, '.') : NULL;
@@ -385,11 +378,6 @@ err_done:
if (added || deleted)
system("initctl -nbq touch dnsmasq");
lyd_free_tree(diff);
err_release_data:
sr_release_data(cfg);
err_abandon:
return err;
}
@@ -461,12 +449,22 @@ static int clear_stats(sr_session_ctx_t *session, uint32_t sub_id, const char *x
return SR_ERR_OK;
}
int infix_dhcp_server_init(struct confd *confd)
int infix_dhcp_server_candidate_init(struct confd *confd)
{
int rc;
REGISTER_CHANGE(confd->session, MODULE, CFG_XPATH, 0, change, confd, &confd->sub);
REGISTER_CHANGE(confd->cand, MODULE, CFG_XPATH "//.", SR_SUBSCR_UPDATE, cand, confd, &confd->sub);
return SR_ERR_OK;
fail:
ERROR("init failed: %s", sr_strerror(rc));
return rc;
}
int infix_dhcp_server_rpc_init(struct confd *confd)
{
int rc;
REGISTER_RPC(confd->session, CFG_XPATH "/statistics/clear", clear_stats, NULL, &confd->sub);
return SR_ERR_OK;
+1 -1
View File
@@ -33,7 +33,7 @@ static int rpc(sr_session_ctx_t *session, uint32_t sub_id, const char *xpath,
return rc;
}
int infix_factory_init(struct confd *confd)
int infix_factory_rpc_init(struct confd *confd)
{
int rc;
REGISTER_RPC(confd->session, "/infix-factory-default:factory-default", rpc, NULL, &confd->fsub);
+20 -26
View File
@@ -477,16 +477,16 @@ static int infer_policy(sr_session_ctx_t *session, const char *name, const char
}
#endif
static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
int infix_firewall_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *tree, *global;
struct lyd_node *clist, *cnode;
struct lyd_node *diff = NULL;
sr_error_t err = SR_ERR_OK;
sr_data_t *cfg = NULL;
char **ifaces = NULL;
if (diff && !lydx_get_xpathf(diff, XPATH))
return SR_ERR_OK;
switch (event) {
case SR_EV_CHANGE:
/* Generate configuration to /etc/firewalld+ */
@@ -518,11 +518,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
return SR_ERR_OK;
}
err = sr_get_data(session, "//.", 0, 0, 0, &cfg);
if (err || !cfg)
return SR_ERR_INTERNAL;
tree = cfg->tree;
tree = config;
global = lydx_get_descendant(tree, "firewall", NULL);
/* Clean up any stale /etc/firewalld+ first */
@@ -540,13 +536,6 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
ifaces = NULL;
}
err = srx_get_diff(session, &diff);
if (err)
goto done;
if (!diff)
goto done;
/* Create /etc/firewalld+ directory structure */
if (fmkpath(0755, FIREWALLD_DIR_NEXT) ||
fmkpath(0755, FIREWALLD_ZONES_DIR) ||
@@ -642,12 +631,6 @@ done:
free(ifaces);
}
if (diff)
lyd_free_tree(diff);
if (cfg)
sr_release_data(cfg);
return err;
}
@@ -699,7 +682,7 @@ static int cand(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
#if INFER_POLICY
/* Infer allow-host-ipv6 policy */
rc = infer_policy(session, "allow-host-ipv6",
rc = infer_policy(session, "allow-host-ipv6",
"Allows basic IPv6 functionality for the host.",
"continue", any, host, icmp_types);
if (rc)
@@ -725,12 +708,10 @@ static int lockdown(sr_session_ctx_t *session, uint32_t sub_id, const char *xpat
return SR_ERR_OK;
}
int infix_firewall_init(struct confd *confd)
int infix_firewall_rpc_init(struct confd *confd)
{
int rc;
REGISTER_CHANGE(confd->session, MODULE, XPATH "//.", 0, change, confd, &confd->sub);
REGISTER_CHANGE(confd->cand, MODULE, XPATH "//.", SR_SUBSCR_UPDATE, cand, confd, &confd->sub);
REGISTER_RPC(confd->session, XPATH "/lockdown-mode", lockdown, NULL, &confd->sub);
return SR_ERR_OK;
@@ -738,3 +719,16 @@ fail:
ERROR("init failed: %s", sr_strerror(rc));
return rc;
}
int infix_firewall_candidate_init(struct confd *confd)
{
int rc;
REGISTER_CHANGE(confd->cand, MODULE, XPATH "//.", SR_SUBSCR_UPDATE, cand, confd, &confd->sub);
return SR_ERR_OK;
fail:
ERROR("init failed: %s", sr_strerror(rc));
return rc;
}
+1 -14
View File
@@ -18,23 +18,10 @@ static int set_version(sr_session_ctx_t *session)
return SR_ERR_OK;
}
static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
int infix_meta_change_cb(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
if (event == SR_EV_UPDATE)
return set_version(session);
return SR_ERR_OK;
}
int infix_meta_init(struct confd *confd)
{
int rc;
REGISTER_CHANGE(confd->session, "infix-meta", META_XPATH, SR_SUBSCR_UPDATE,
change_cb, confd, &confd->sub);
return SR_ERR_OK;
fail:
ERROR("%s(): failed. %s", __func__, sr_strerror(rc));
return rc;
}
+77 -138
View File
@@ -19,9 +19,6 @@
#define GENERATE_ENUM(ENUM) ENUM,
#define GENERATE_STRING(STRING) #STRING,
#define SSH_HOSTKEYS "/etc/ssh/hostkeys"
#define SSH_HOSTKEYS_NEXT SSH_HOSTKEYS"+"
#define LLDP_CONFIG "/etc/lldpd.d/confd.conf"
#define LLDP_CONFIG_NEXT LLDP_CONFIG"+"
@@ -39,7 +36,13 @@
#define SSHD_CONFIG_BASE SSH_BASE "/sshd_config.d"
#define SSHD_CONFIG_LISTEN SSHD_CONFIG_BASE "/listen.conf"
#define SSHD_CONFIG_HOSTKEY SSHD_CONFIG_BASE "/host-keys.conf"
#define LLDP_XPATH "/ieee802-dot1ab-lldp:lldp"
#define SSH_XPATH "/infix-services:ssh"
#define MDNS_XPATH "/infix-services:mdns"
#define WEB_XPATH "/infix-services:web"
#define WEB_RESTCONF_XPATH WEB_XPATH"/restconf"
#define WEB_NETBROWSE_XPATH WEB_XPATH"/netbrowse"
#define WEB_CONSOLE_XPATH WEB_XPATH"/console"
typedef enum {
FOREACH_SVC(GENERATE_ENUM)
} svc;
@@ -184,13 +187,13 @@ static void svc_enadis(int ena, svc type, const char *svc)
systemf("initctl -nbq touch avahi");
systemf("initctl -nbq touch nginx");
}
/* TODO Handle in dependency tracking
static int hostname_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
{
return mdns_records("update", all);
}
*/
static void fput_list(FILE *fp, struct lyd_node *cfg, const char *list, const char *heading)
{
const char *prefix = heading;
@@ -279,14 +282,16 @@ static void mdns_cname(sr_session_ctx_t *session)
svc_enadis(ena, none, "mdns-alias");
}
static int mdns_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
static int mdns_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *srv = NULL;
sr_data_t *cfg;
int ena;
cfg = get(session, event, xpath, &srv, "mdns", NULL);
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, MDNS_XPATH))
return SR_ERR_OK;
cfg = get(session, event, MDNS_XPATH, &srv, "mdns", NULL);
if (!cfg)
return SR_ERR_OK;
@@ -305,20 +310,18 @@ static int mdns_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
return put(cfg);
}
static int lldp_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
static int lldp_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *node = NULL;
sr_data_t *cfg;
struct lyd_node *subnode;
if (diff && !lydx_get_xpathf(diff, LLDP_XPATH))
return SR_ERR_OK;
switch (event) {
case SR_EV_ENABLED:
case SR_EV_CHANGE:
if (sr_get_data(session, xpath, 0, 0, 0, &cfg) || !cfg)
break;
node = cfg->tree;
node = lydx_get_xpathf(config, LLDP_XPATH);
if (lydx_is_enabled(node, "enabled")){
const char *tx_interval = lydx_get_cattr(node, "message-tx-interval");
FILE *fp = fopen(LLDP_CONFIG_NEXT, "w");
@@ -342,7 +345,7 @@ static int lldp_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
fclose(fp);
}
return put(cfg);
return SR_ERR_OK;
case SR_EV_DONE:
if (fexist(LLDP_CONFIG_NEXT)){
@@ -356,7 +359,7 @@ static int lldp_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
if (erase(LLDP_CONFIG))
ERRNO("Failed to remove old %s", LLDP_CONFIG);
svc_change(session, event, xpath, "lldp", "lldpd");
svc_change(session, event, LLDP_XPATH, "lldp", "lldpd");
break;
case SR_EV_ABORT:
@@ -370,13 +373,15 @@ static int lldp_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
return SR_ERR_OK;
}
static int ttyd_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
static int ttyd_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *srv = NULL;
sr_data_t *cfg;
cfg = get(session, event, xpath, &srv, "web", "console", NULL);
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, WEB_CONSOLE_XPATH))
return SR_ERR_OK;
cfg = get(session, event, WEB_XPATH, &srv, "web", "console", NULL);
if (!cfg)
return SR_ERR_OK;
@@ -385,13 +390,15 @@ static int ttyd_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
return put(cfg);
}
static int netbrowse_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
static int netbrowse_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *srv = NULL;
sr_data_t *cfg;
cfg = get(session, event, xpath, &srv, "web", "netbrowse", NULL);
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, WEB_NETBROWSE_XPATH))
return SR_ERR_OK;
cfg = get(session, event, WEB_XPATH, &srv, "web", "netbrowse", NULL);
if (!cfg)
return SR_ERR_OK;
@@ -401,13 +408,19 @@ static int netbrowse_change(sr_session_ctx_t *session, uint32_t sub_id, const ch
return put(cfg);
}
static int restconf_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
static int restconf_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *srv = NULL;
sr_data_t *cfg;
char *out;
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, WEB_RESTCONF_XPATH))
return SR_ERR_OK;
cfg = get(session, event, xpath, &srv, "web", "restconf", NULL);
ERROR("RESTCONF CHANGES DETECTED");
lyd_print_mem(&out, diff, LYD_JSON,
LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
ERROR("%s", out);
cfg = get(session, event, WEB_XPATH, &srv, "web", "restconf", NULL);
if (!cfg)
return SR_ERR_OK;
@@ -416,17 +429,18 @@ static int restconf_change(sr_session_ctx_t *session, uint32_t sub_id, const cha
return put(cfg);
}
static int ssh_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
static int ssh_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *ssh = NULL, *listen, *host_key;
sr_error_t rc = SR_ERR_OK;
sr_data_t *cfg;
FILE *fp;
if (diff && !lydx_get_xpathf(diff, SSH_XPATH))
return SR_ERR_OK;
switch (event) {
case SR_EV_DONE:
return svc_change(session, event, xpath, "ssh", "sshd");
return svc_change(session, event, SSH_XPATH, "ssh", "sshd");
case SR_EV_ENABLED:
case SR_EV_CHANGE:
break;
@@ -436,10 +450,7 @@ static int ssh_change(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
return SR_ERR_OK;
}
if (sr_get_data(session, xpath, 0, 0, 0, &cfg) || !cfg) {
return SR_ERR_OK;
}
ssh = cfg->tree;
ssh = lydx_get_xpathf(config, SSH_XPATH);
if (!lydx_is_enabled(ssh, "enabled")) {
goto out;
@@ -479,27 +490,29 @@ static int ssh_change(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
fclose(fp);
out:
sr_release_data(cfg);
return rc;
}
static int web_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
static int web_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
struct lyd_node *srv = NULL;
sr_data_t *cfg;
int ena;
cfg = get(session, event, xpath, &srv, "web", NULL);
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, WEB_XPATH))
return SR_ERR_OK;
cfg = get(session, event, WEB_XPATH, &srv, "web", NULL);
if (!cfg)
return SR_ERR_OK;
ena = lydx_is_enabled(srv, "enabled");
if (ena) {
svc_enadis(srx_enabled(session, "%s/console/enabled", xpath), ttyd, "ttyd");
svc_enadis(srx_enabled(session, "%s/netbrowse/enabled", xpath), netbrowse, "netbrowse");
svc_enadis(srx_enabled(session, "%s/restconf/enabled", xpath), restconf, "restconf");
svc_enadis(srx_enabled(session, "%s/enabled", WEB_CONSOLE_XPATH), ttyd, "ttyd");
svc_enadis(srx_enabled(session, "%s/enabled", WEB_NETBROWSE_XPATH), netbrowse, "netbrowse");
svc_enadis(srx_enabled(session, "%s/enabled", WEB_RESTCONF_XPATH), restconf, "restconf");
} else {
svc_enadis(0, ttyd, NULL);
svc_enadis(0, netbrowse, NULL);
@@ -512,104 +525,30 @@ static int web_change(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
return put(cfg);
}
/* Store SSH public/private keys */
static int change_keystore_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name,
const char *xpath, sr_event_t event, uint32_t request_id, void *_)
{
int rc = SR_ERR_OK;
sr_data_t *cfg;
struct lyd_node *changes, *change;
switch (event) {
case SR_EV_CHANGE:
case SR_EV_ENABLED:
break;
case SR_EV_ABORT:
rmrf(SSH_HOSTKEYS_NEXT);
return SR_ERR_OK;
case SR_EV_DONE:
if(fexist(SSH_HOSTKEYS_NEXT)) {
if(rmrf(SSH_HOSTKEYS)) {
ERRNO("Failed to remove old SSH hostkeys: %d", errno);
}
if (rename(SSH_HOSTKEYS_NEXT, SSH_HOSTKEYS))
ERRNO("Failed switching to new %s", SSH_HOSTKEYS);
svc_change(session, event, "/infix-services:ssh", "ssh", "sshd");
}
return SR_ERR_OK;
default:
return SR_ERR_OK;
}
if (sr_get_data(session, "/ietf-keystore:keystore/asymmetric-keys//.", 0, 0, 0, &cfg) || !cfg) {
return SR_ERR_OK;
}
changes = lydx_get_descendant(cfg->tree, "keystore", "asymmetric-keys", "asymmetric-key", NULL);
LYX_LIST_FOR_EACH(changes, change, "asymmetric-key") {
const char *name, *private_key_type, *public_key_type;
const char *private_key, *public_key;
name = lydx_get_cattr(change, "name");
private_key_type = lydx_get_cattr(change, "private-key-format");
public_key_type = lydx_get_cattr(change, "public-key-format");
if (strcmp(private_key_type, "infix-crypto-types:rsa-private-key-format")) {
INFO("Private key %s is not of SSH type", name);
continue;
}
if (strcmp(public_key_type, "infix-crypto-types:ssh-public-key-format")) {
INFO("Public key %s is not of SSH type", name);
continue;
}
private_key = lydx_get_cattr(change, "cleartext-private-key");
public_key = lydx_get_cattr(change, "public-key");
if (mkdir(SSH_HOSTKEYS_NEXT, 0600) && (errno != EEXIST)) {
ERRNO("Failed creating %s", SSH_HOSTKEYS_NEXT);
rc = SR_ERR_INTERNAL;
}
if(systemf("/usr/libexec/infix/mksshkey %s %s %s %s", name, SSH_HOSTKEYS_NEXT, public_key, private_key))
rc = SR_ERR_INTERNAL;
}
sr_release_data(cfg);
return rc;
}
int infix_services_init(struct confd *confd)
int infix_services_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
{
int rc;
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:mdns",
0, mdns_change, confd, &confd->sub);
REGISTER_MONITOR(confd->session, "ietf-system", "/ietf-system:system/hostname",
0, hostname_change, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:ssh",
0, ssh_change, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:web",
0, web_change, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:web/infix-services:console",
0, ttyd_change, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:web/infix-services:netbrowse",
0, netbrowse_change, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:web/infix-services:restconf",
0, restconf_change, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ieee802-dot1ab-lldp", "/ieee802-dot1ab-lldp:lldp",
0, lldp_change, confd, &confd->sub);
/* Store SSH keys */
REGISTER_CHANGE(confd->session, "ietf-keystore", "/ietf-keystore:keystore//.",
0, change_keystore_cb, confd, &confd->sub);
rc = lldp_change(session, config, diff, event, confd);
if (rc)
return rc;
rc = mdns_change(session, config, diff, event, confd); /* TODO: Depends on hostname changes */
if (rc)
return rc;
rc = ssh_change(session, config, diff, event, confd); /* TODO: Depends on keystore changes*/
if (rc)
return rc;
rc = web_change(session, config, diff, event, confd);
if (rc)
return rc;
rc = ttyd_change(session, config, diff, event, confd);
if (rc)
return rc;
rc = restconf_change(session, config, diff, event, confd);
if (rc)
return rc;
rc = netbrowse_change(session, config, diff, event, confd);
if (rc)
return rc;
return SR_ERR_OK;
fail:
ERROR("init failed: %s", sr_strerror(rc));
return rc;
}
+1 -1
View File
@@ -89,7 +89,7 @@ static int infix_system_sw_set_boot_order(sr_session_ctx_t *session, uint32_t su
return SR_ERR_OK;
}
int infix_system_sw_init(struct confd *confd)
int infix_system_sw_rpc_init(struct confd *confd)
{
int rc = 0;