/* Signal handler - controls main loop */ void signal_handler(int sig) { nc_verb_verbose("Signal %d received.", sig); switch (sig) { case SIGINT: case SIGTERM: case SIGQUIT: case SIGABRT: case SIGKILL: if (mainloop == 0) { /* first attempt */ mainloop = 1; } else { /* second attempt */ nc_verb_error("Hey! I need some time, be patient next time!"); exit(EXIT_FAILURE); } break; default: nc_verb_error("Exiting on signal: %d", sig); exit(EXIT_FAILURE); break; } }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_modules_n_module_n_enabled(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr old_node, xmlNodePtr new_node, struct nc_err** UNUSED(error)) { xmlNodePtr tmp, node; char* module_name = NULL, *module_enabled = NULL; struct np_module* module = netopeer_options.modules; node = (op & XMLDIFF_REM ? old_node : new_node); if (node == NULL) { return EXIT_FAILURE; } for (tmp = node->parent->children; tmp != NULL; tmp = tmp->next) { if (xmlStrEqual(tmp->name, BAD_CAST "name")) { module_name = get_node_content(tmp); break; } } module_enabled = get_node_content(node); if (module_name == NULL || module_enabled == NULL) { nc_verb_error("%s: missing module \"name\" or \"enabled\" node", __func__); return EXIT_FAILURE; } if ((op & (XMLDIFF_REM | XMLDIFF_ADD)) && strcmp(module_enabled, "false") == 0) { /* module is/was not enabled, nothing to enable/disable */ return EXIT_SUCCESS; } while (module) { if (strcmp(module->name, module_name) == 0) { break; } module = module->next; } if ((op & XMLDIFF_REM) || ((op & XMLDIFF_MOD) && strcmp(module_enabled, "false") == 0)) { if (module == NULL) { nc_verb_error("%s: internal error: module to disable not found", __func__); return EXIT_FAILURE; } if (module_disable(module, 1)) { return EXIT_FAILURE; } } else if ((op & XMLDIFF_ADD) || ((op & XMLDIFF_MOD) && strcmp(module_enabled, "true") == 0)) { if (module != NULL) { nc_verb_error("%s: internal error: module to enable already exists", __func__); return EXIT_FAILURE; } module = calloc(1, sizeof(struct np_module)); module->name = strdup(module_name); if (module_enable(module, 1)) { return EXIT_FAILURE; } } return EXIT_SUCCESS; }
static int ntp_cmd(const char* cmd) { int status; pid_t pid; const char* service[] = { NULL, /* UNKNOWN */ REDHAT_NTP_SERVICE, /* REDHAT */ SUSE_NTP_SERVICE, /* SUSE */ DEBIAN_NTP_SERVICE /* DEBIAN */ }; if (distribution_id == 0) { identity_detect(); } if (service[distribution_id] == NULL) { nc_verb_error("Unable to start NTP service (unknown Linux distro)."); return EXIT_FAILURE; } if ((pid = vfork()) == -1) { nc_verb_error("fork failed (%s).", strerror(errno)); return EXIT_FAILURE; } else if (pid == 0) { /* child */ int fd = open("/dev/null", O_RDONLY); if (fd == -1) { nc_verb_warning("Opening NULL dev failed (%s).", strerror(errno)); } else { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); close(fd); } execl("/sbin/service", "/sbin/service", service[distribution_id], cmd, (char*)NULL); nc_verb_error("exec failed (%s).", strerror(errno)); return EXIT_FAILURE; } if (waitpid(pid, &status, 0) == -1) { nc_verb_error("Failed to wait for the service child (%s).", strerror(errno)); return EXIT_FAILURE; } if (WEXITSTATUS(status) != 0) { if (strcmp(cmd, "status")) { nc_verb_error("Unable to %s NTP service (command returned %d).", cmd, WEXITSTATUS(status)); } return EXIT_FAILURE; } return EXIT_SUCCESS; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_logical_switches (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); print_element_names(node, 0); int rv = EXIT_SUCCESS; if (NULL != node->children) { assert(ofc_state.lsi_list); assert(XMLDIFF_CHAIN & op); if ((XMLDIFF_ADD|XMLDIFF_REM|XMLDIFF_MOD|XMLDIFF_CHAIN) & op) { struct lsi *current_lsi; while ( (current_lsi = list_next(ofc_state.lsi_list)) ) { handle_ports(current_lsi->res.port_list_del); } while ( (current_lsi = list_pop_head(ofc_state.lsi_list)) ) { handle_ports(current_lsi->res.port_list_add); lsi_cleanup(current_lsi); } } else { nc_verb_error("unsupported op"); assert(0); } list_delete(ofc_state.lsi_list); ofc_state.lsi_list = NULL; } return rv; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_logical_switches_ofc_switch_ofc_controllers_ofc_controller (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); print_element_names(node, 0); if (NULL == *data) { *data = calloc(1, sizeof(struct lsi)); assert(*data); } if ((XMLDIFF_ADD) & op) { if (NULL == LSI(data)->controller_list_add) { LSI(data)->controller_list_add = list_new(); assert(LSI(data)->controller_list_add); } list_append_data(LSI(data)->controller_list_add, __data); __data = NULL; } else if ((XMLDIFF_REM) & op) { if (NULL == LSI(data)->controller_list_del) { LSI(data)->controller_list_del = list_new(); assert(LSI(data)->controller_list_del); } list_append_data(LSI(data)->controller_list_del, __data); __data = NULL; } else { nc_verb_error("not implemented"); assert(0); } return EXIT_SUCCESS; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_tls_n_server_cert(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr UNUSED(old_node), xmlNodePtr new_node, struct nc_err** error) { char* content = NULL; if (op & (XMLDIFF_MOD | XMLDIFF_ADD)) { content = get_node_content(new_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } } /* TLS_CTX LOCK */ pthread_mutex_lock(&netopeer_options.tls_opts->tls_ctx_lock); free(netopeer_options.tls_opts->server_cert); netopeer_options.tls_opts->server_cert = NULL; if (op & (XMLDIFF_MOD | XMLDIFF_ADD)) { netopeer_options.tls_opts->server_cert = strdup(content); } netopeer_options.tls_opts->tls_ctx_change_flag = 1; /* TLS_CTX UNLOCK */ pthread_mutex_unlock(&netopeer_options.tls_opts->tls_ctx_lock); return EXIT_SUCCESS; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_max_sessions(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr UNUSED(old_node), xmlNodePtr new_node, struct nc_err** error) { char* content = NULL, *ptr, *msg; uint16_t num; if (op & XMLDIFF_REM) { netopeer_options.max_sessions = 8; return EXIT_SUCCESS; } content = get_node_content(new_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } num = strtol(content, &ptr, 10); if (*ptr != '\0') { asprintf(&msg, "Could not convert '%s' to a number.", content); *error = nc_err_new(NC_ERR_BAD_ELEM); nc_err_set(*error, NC_ERR_PARAM_MSG, msg); nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "/netopeer/max-sessions"); free(msg); return EXIT_FAILURE; } netopeer_options.max_sessions = num; return EXIT_SUCCESS; }
int ofcds_rollback(void *UNUSED(data)) { xmlChar *data; int size, ret; struct nc_err *e; if (rollback.type == NC_DATASTORE_ERROR) { nc_verb_error("No data to rollback"); return EXIT_FAILURE; } /* dump data for copy-config */ if (rollback.doc) { xmlDocDumpMemory(rollback.doc, &data, &size); } else { data = xmlStrdup(BAD_CAST ""); } rollbacking = 1; ret = ofcds_copyconfig(NULL, rollback.type, NC_DATASTORE_CONFIG, (char *) data, &e); rollbacking = 0; if (ret) { nc_err_free(e); } xmlFree(data); return ret; }
int ofcds_deleteconfig(void *UNUSED(data), NC_DATASTORE target, struct nc_err **error) { switch (target) { case NC_DATASTORE_RUNNING: *error = nc_err_new(NC_ERR_OP_FAILED); nc_err_set(*error, NC_ERR_PARAM_MSG, "Cannot delete a running datastore."); return EXIT_FAILURE; case NC_DATASTORE_STARTUP: store_rollback(gds_startup, NC_DATASTORE_STARTUP); gds_startup = NULL; break; case NC_DATASTORE_CANDIDATE: store_rollback(gds_cand, NC_DATASTORE_CANDIDATE); gds_cand = NULL; break; default: nc_verb_error("Invalid <delete-config> target."); *error = nc_err_new(NC_ERR_BAD_ELEM); nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "target"); return EXIT_FAILURE; } return EXIT_SUCCESS; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_ssh_n_auth_timeout(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr UNUSED(old_node), xmlNodePtr new_node, struct nc_err** error) { char* content = NULL, *ptr, *msg; uint16_t num; if (op & XMLDIFF_REM) { netopeer_options.ssh_opts->auth_timeout = 10; return EXIT_SUCCESS; } content = get_node_content(new_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } num = strtol(content, &ptr, 10); if (*ptr != '\0') { *error = nc_err_new(NC_ERR_OP_FAILED); if (asprintf(&msg, "Could not convert '%s' to a number.", content) == 0) { nc_err_set(*error, NC_ERR_PARAM_MSG, msg); free(msg); } return EXIT_FAILURE; } netopeer_options.ssh_opts->auth_timeout = num; return EXIT_SUCCESS; }
int cmd_remove(const char* arg) { char* ptr, *argv; struct ncds_ds_list* ds; struct model_list* model; if (strlen(arg) < 7) { cmd_remove_help(); return 1; } argv = strdupa(arg + strlen("remove ")); ptr = strtok(argv, " "); ds = find_datastore(ptr); if (ds == NULL) { model = find_model(ptr); if (model == NULL) { nc_verb_error("No datastore or model \"%s\" found", ptr); return 1; } else { ncds_ds_model_free(model->model); } } else { ncds_free(ds->datastore); } remove_hint(ptr); return 0; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_tls_n_crl_dir(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr UNUSED(old_node), xmlNodePtr new_node, struct nc_err** error) { char* content = NULL; if (op & (XMLDIFF_MOD | XMLDIFF_ADD)) { content = get_node_content(new_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } } /* CRL_DIR LOCK */ pthread_mutex_lock(&netopeer_options.tls_opts->crl_dir_lock); free(netopeer_options.tls_opts->crl_dir); netopeer_options.tls_opts->crl_dir = NULL; if (op & (XMLDIFF_MOD | XMLDIFF_ADD)) { netopeer_options.tls_opts->crl_dir = strdup(content); } /* CRL_DIR UNLOCK */ pthread_mutex_unlock(&netopeer_options.tls_opts->crl_dir_lock); return EXIT_SUCCESS; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_hello_timeout(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr UNUSED(old_node), xmlNodePtr new_node, struct nc_err** error) { char* content = NULL, *ptr, *msg; uint32_t num; if (op & XMLDIFF_REM) { /* set default value */ nc_hello_timeout(600 * 1000); return EXIT_SUCCESS; } content = get_node_content(new_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } num = strtol(content, &ptr, 10); if (*ptr != '\0') { *error = nc_err_new(NC_ERR_BAD_ELEM); if (asprintf(&msg, "Could not convert '%s' to a number.", content) == 0) { nc_err_set(*error, NC_ERR_PARAM_MSG, msg); nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "/netopeer/hello-timeout"); free(msg); } return EXIT_FAILURE; } nc_hello_timeout(num * 1000); return EXIT_SUCCESS; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_tls_n_trusted_ca_certs_n_trusted_ca_cert(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr old_node, xmlNodePtr new_node, struct nc_err** error) { char* content = NULL; if (op & (XMLDIFF_REM | XMLDIFF_MOD)) { content = get_node_content(old_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } /* TLS_CTX LOCK */ pthread_mutex_lock(&netopeer_options.tls_opts->tls_ctx_lock); if (del_trusted_cert(&netopeer_options.tls_opts->trusted_certs, content, 0) != 0) { nc_verb_error("%s: inconsistent state (%s:%d)", __func__, __FILE__, __LINE__); } else { netopeer_options.tls_opts->tls_ctx_change_flag = 1; } /* TLS_CTX UNLOCK */ pthread_mutex_unlock(&netopeer_options.tls_opts->tls_ctx_lock); } if (op & (XMLDIFF_MOD | XMLDIFF_ADD)) { content = get_node_content(new_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } /* TLS_CTX LOCK */ pthread_mutex_lock(&netopeer_options.tls_opts->tls_ctx_lock); add_trusted_cert(&netopeer_options.tls_opts->trusted_certs, content, 0); netopeer_options.tls_opts->tls_ctx_change_flag = 1; /* TLS_CTX UNLOCK */ pthread_mutex_unlock(&netopeer_options.tls_opts->tls_ctx_lock); } return EXIT_SUCCESS; }
/* always returns only a single new connection */ static struct client_struct* sock_accept(const struct np_sock* npsock) { int r; unsigned int i; socklen_t client_saddr_len; struct client_struct* ret; if (npsock == NULL) { return NULL; } /* poll for a new connection */ errno = 0; r = poll(npsock->pollsock, npsock->count, netopeer_options.response_time); if (r == 0 || (r == -1 && errno == EINTR)) { /* we either timeouted or going to exit or restart */ return NULL; } if (r == -1) { nc_verb_error("%s: poll failed (%s)", __func__, strerror(errno)); return NULL; } ret = calloc(1, sizeof(struct client_struct)); client_saddr_len = sizeof(struct sockaddr_storage); /* accept the first polled connection */ for (i = 0; i < npsock->count; ++i) { if (npsock->pollsock[i].revents & POLLIN) { ret->sock = accept(npsock->pollsock[i].fd, (struct sockaddr*)&ret->saddr, &client_saddr_len); if (ret->sock == -1) { nc_verb_error("%s: accept failed (%s)", __func__, strerror(errno)); free(ret); return NULL; } ret->transport = npsock->transport[i]; npsock->pollsock[i].revents = 0; break; } } return ret; }
int cmd_print(const char* arg) { char* ptr, *argv; xmlDocPtr doc; struct ncds_ds_list* ds; struct model_list* model; argv = strdupa(arg); strtok(argv, " "); ptr = strtok(NULL, " "); if (ptr == NULL) { ds = ncds.datastores; model = models_list; printf("Datastores:\n"); if (ds == NULL) { printf("\tnone\n"); } for (; ds != NULL; ds = ds->next) { printf("\t%s\n", ds->datastore->data_model->name); } printf("Models:\n"); if (model == NULL) { printf("\tnone\n"); } for (; model != NULL; model = model->next) { printf("\t%s\n", model->model->name); } } else { char* buf = NULL; int buf_len = 0; ds = find_datastore(ptr); if (ds == NULL) { model = find_model(ptr); if (model == NULL) { nc_verb_error("No datastore or model \"%s\" found", ptr); return 1; } else { doc = model->model->xml; } } else { doc = ds->datastore->ext_model; } xmlDocDumpFormatMemory(doc, (xmlChar**)&buf, &buf_len, 1); fwrite(buf, 1, buf_len, stdout); free(buf); } return 0; }
void* data_thread(void* UNUSED(arg)) { struct client_struct* client; int skip_sleep, to_send_size; char* to_send; to_send_size = BASE_READ_BUFFER_SIZE; to_send = malloc(to_send_size); do { skip_sleep = 0; /* GLOBAL READ LOCK */ pthread_rwlock_rdlock(&netopeer_state.global_lock); /* go through all the clients */ for (client = netopeer_state.clients; client != NULL; client = client->next) { switch (client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: skip_sleep = np_ssh_client_data((struct client_struct_ssh*)client, &to_send, &to_send_size); break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: skip_sleep = np_tls_client_data((struct client_struct_tls*)client, &to_send, &to_send_size); break; #endif default: nc_verb_error("%s: internal error (%s:%d)", __func__, __FILE__, __LINE__); } /* we removed a client, maybe the last so quit the loop */ if (skip_sleep == 2) { break; } } /* GLOBAL READ UNLOCK */ pthread_rwlock_unlock(&netopeer_state.global_lock); if (!skip_sleep) { /* we did not do anything productive, so let the thread sleep */ usleep(netopeer_options.response_time*1000); } } while (!quit || netopeer_state.clients != NULL); free(to_send); #ifdef NP_TLS np_tls_thread_cleanup(); #endif return NULL; }
void np_client_remove(struct client_struct** root, struct client_struct* del_client) { struct client_struct* client, *prev_client = NULL; for (client = *root; client != NULL; client = client->next) { if (client == del_client) { break; } prev_client = client; } if (client == NULL) { nc_verb_error("%s: internal error: client not found (%s:%d)", __func__, __FILE__, __LINE__); return; } if (prev_client == NULL) { *root = (*root)->next; } else { prev_client->next = client->next; } switch (client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: client_free_ssh((struct client_struct_ssh*)client); break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: client_free_tls((struct client_struct_tls*)client); break; #endif default: nc_verb_error("%s: internal error (%s:%d)", __func__, __FILE__, __LINE__); } free(client); }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_resources_ofc_port_ofc_configuration_ofc_admin_state (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); print_element_names(node, 0); int rv = EXIT_SUCCESS; int down = 0; // default is up if ((XMLDIFF_ADD|XMLDIFF_MOD) & op) { if (xmlStrEqual(XML_GET_CONTENT(node->children), BAD_CAST "down")) { down = 1; } // sanity check... if the content is not "down", it has to be "up" assert(down || xmlStrEqual(XML_GET_CONTENT(node->children), BAD_CAST "up")); // currently the resource-id is the port name (even if the name is not set xmlNodePtr tmp = find_element(BAD_CAST "resource-id", node->parent->parent->children); assert(tmp); if (down) { // set interface down nc_verb_verbose("set interface %s down\n", tmp->children->content); if (port_disable(ofc_state.xmp_client_handle, tmp->children->content)) { rv = EXIT_FAILURE; } } else { // set interface up nc_verb_verbose("set interface %s up\n", tmp->children->content); if (port_enable(ofc_state.xmp_client_handle, tmp->children->content)) { rv = EXIT_FAILURE; } } } else if (XMLDIFF_REM & op) { // setting interface up } else { nc_verb_error("unsupported op"); assert(0); } return rv; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_logical_switches_ofc_switch_ofc_controllers_ofc_controller_ofc_ip_address (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); assert(__data); if ((XMLDIFF_ADD) & op) { // fixme handle zone in address (see http://www.netconfcentral.org/modules/ietf-inet-types) CONTROLLER(__data)->ip_domain = parse_ip_address(XML_GET_CONTENT(node->children), &CONTROLLER(__data)->ip); } else if ((XMLDIFF_REM) & op) { } else { nc_verb_error("not implemented"); assert(0); } return EXIT_SUCCESS; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_logical_switches_ofc_switch_ofc_controllers_ofc_controller_ofc_port (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); assert(__data); if ((XMLDIFF_ADD) & op) { CONTROLLER(__data)->port = strtoul(XML_GET_CONTENT(node->children), NULL, 10); } else if ((XMLDIFF_REM) & op) { } else { nc_verb_error("not implemented"); assert(0); } return EXIT_SUCCESS; }
int cmd_verb(const char* arg) { const char* verb; verb = arg + 5; if (strcmp(verb, "error") == 0) { nc_verbosity(NC_VERB_ERROR); } else if (strcmp(verb, "warning") == 0) { nc_verbosity(NC_VERB_WARNING); } else if (strcmp(verb, "verbose") == 0) { nc_verbosity(NC_VERB_VERBOSE); } else if (strcmp(verb, "debug") == 0) { nc_verbosity(NC_VERB_DEBUG); } else { nc_verb_error("Unknown verbosity \"%s\"", verb); return 1; } return 0; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_logical_switches_ofc_switch_ofc_controllers_ofc_controller_ofc_id (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); assert(NULL == __data); if ((XMLDIFF_ADD|XMLDIFF_REM) & op) { __data = calloc(1, sizeof(struct controller)); CONTROLLER(__data)->id = strdup(XML_GET_CONTENT(node->children)); assert(CONTROLLER(__data)->id); } else { nc_verb_error("not implemented"); assert(0); } return EXIT_SUCCESS; }
void np_client_detach(struct client_struct** root, struct client_struct* del_client) { struct client_struct* client, *prev_client = NULL; for (client = *root; client != NULL; client = client->next) { if (client == del_client) { break; } prev_client = client; } if (client == NULL) { nc_verb_error("%s: internal error: client not found (%s:%d)", __func__, __FILE__, __LINE__); return; } if (prev_client == NULL) { *root = (*root)->next; } else { prev_client->next = client->next; } }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_ssh_n_server_keys_n_dsa_key(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr UNUSED(old_node), xmlNodePtr new_node, struct nc_err** error) { char* content = NULL; if (op & XMLDIFF_REM) { free(netopeer_options.ssh_opts->dsa_key); netopeer_options.ssh_opts->dsa_key = NULL; netopeer_options.ssh_opts->server_key_change_flag = 1; return EXIT_SUCCESS; } content = get_node_content(new_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } free(netopeer_options.ssh_opts->dsa_key); netopeer_options.ssh_opts->dsa_key = strdup(content); netopeer_options.ssh_opts->server_key_change_flag = 1; return EXIT_SUCCESS; }
void* netconf_rpc_thread(void* UNUSED(arg)) { struct client_struct* client; do { /* GLOBAL READ LOCK */ pthread_rwlock_rdlock(&netopeer_state.global_lock); for (client = netopeer_state.clients; client != NULL; client = client->next) { if (client->to_free) { continue; } switch (client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: np_ssh_client_netconf_rpc((struct client_struct_ssh*)client); break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: np_tls_client_netconf_rpc((struct client_struct_tls*)client); break; #endif default: nc_verb_error("%s: internal error (%s:%d)", __func__, __FILE__, __LINE__); } } /* GLOBAL READ UNLOCK */ pthread_rwlock_unlock(&netopeer_state.global_lock); usleep(netopeer_options.response_time*1000); } while (!quit); #ifdef NP_TLS np_tls_thread_cleanup(); #endif return NULL; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_ssh_n_password_auth_enabled(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr UNUSED(old_node), xmlNodePtr new_node, struct nc_err** error) { char* content = NULL; if (op & XMLDIFF_REM) { netopeer_options.ssh_opts->password_auth_enabled = 1; return EXIT_SUCCESS; } content = get_node_content(new_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } if (strcmp(content, "false") == 0) { netopeer_options.ssh_opts->password_auth_enabled = 0; } else { netopeer_options.ssh_opts->password_auth_enabled = 1; } return EXIT_SUCCESS; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_logical_switches_ofc_switch_ofc_datapath_id (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); assert(NULL == __data); if (NULL == *data) { *data = calloc(1, sizeof(struct lsi)); assert(*data); } if ((XMLDIFF_ADD|XMLDIFF_REM) & op) { xmlChar* text = xmlNodeListGetString(node->doc, node->children, 1); uint64_t dpid = parse_dpid(text); xmlFree(text); LSI(data)->dpid = dpid; } else { // todo add operation to modify dpid nc_verb_error("not implemented"); assert(0); } return EXIT_SUCCESS; }
int main (int argc, char** argv) { conn_t* conn = NULL; struct sigaction action; sigset_t block_mask; char *aux_string = NULL, path[PATH_MAX]; int next_option, ret; int daemonize = 0, len; int verbose = 0; struct module * netopeer_module = NULL, *server_module = NULL; /* initialize message system and set verbose and debug variables */ if ((aux_string = getenv (ENVIRONMENT_VERBOSE)) == NULL) { verbose = NC_VERB_ERROR; } else { verbose = atoi (aux_string); } aux_string = NULL; /* for sure to avoid unwanted changes in environment */ /* parse given options */ while ((next_option = getopt (argc, argv, OPTSTRING)) != -1) { switch (next_option) { case 'd': daemonize = 1; break; case 'h': print_usage (argv[0]); break; case 'v': verbose = atoi (optarg); break; case 'V': print_version (argv[0]); break; default: print_usage (argv[0]); break; } } /* set signal handler */ sigfillset (&block_mask); action.sa_handler = signal_handler; action.sa_mask = block_mask; action.sa_flags = 0; sigaction (SIGINT, &action, NULL); sigaction (SIGQUIT, &action, NULL); sigaction (SIGABRT, &action, NULL); sigaction (SIGTERM, &action, NULL); sigaction (SIGKILL, &action, NULL); sigaction (SIGHUP, &action, NULL); nc_callback_print (clb_print); /* normalize value if not from the enum */ if (verbose < NC_VERB_ERROR) { nc_verbosity (NC_VERB_ERROR); } else if (verbose > NC_VERB_DEBUG) { nc_verbosity (NC_VERB_DEBUG); } else { nc_verbosity (verbose); } /* go to the background as a daemon */ if (daemonize == 1) { if (daemon(0, 0) != 0) { nc_verb_error("Going to background failed (%s)", strerror(errno)); return (EXIT_FAILURE); } openlog("netopeer-server", LOG_PID, LOG_DAEMON); } else { openlog("netopeer-server", LOG_PID|LOG_PERROR, LOG_DAEMON); } /* make sure we were executed by root */ if (geteuid() != 0) { nc_verb_error("Failed to start, must have root privileges."); return (EXIT_FAILURE); } /* * this initialize the library and check potential ABI mismatches * between the version it was compiled for and the actual shared * library used. */ LIBXML_TEST_VERSION /* initialize library including internal datastores and maybee something more */ if ((ret = nc_init (NC_INIT_ALL | NC_INIT_MULTILAYER)) < 0) { nc_verb_error("Library initialization failed."); return (EXIT_FAILURE); } /* Initiate communication subsystem for communicate with agents */ conn = comm_init(ret & NC_INITRET_RECOVERY); if (conn == NULL) { nc_verb_error("Communication subsystem not initiated."); return (EXIT_FAILURE); } server_start = 1; restart: /* start NETCONF server module */ if ((server_module = calloc(1, sizeof(struct module))) == NULL) { nc_verb_error("Creating necessary NETCONF server plugin failed!"); comm_destroy(conn); return(EXIT_FAILURE); } server_module->name = strdup(NCSERVER_MODULE_NAME); if (module_enable(server_module, 0)) { nc_verb_error("Starting necessary NETCONF server plugin failed!"); free(server_module->name); free(server_module); comm_destroy(conn); return EXIT_FAILURE; } /* start netopeer device module - it will start all modules that are * in its configuration and in server configuration */ if ((netopeer_module = calloc(1, sizeof(struct module))) == NULL) { nc_verb_error("Creating necessary Netopeer plugin failed!"); module_disable(server_module, 1); comm_destroy(conn); return(EXIT_FAILURE); } netopeer_module->name = strdup(NETOPEER_MODULE_NAME); if (module_enable(netopeer_module, 0)) { nc_verb_error("Starting necessary Netopeer plugin failed!"); module_disable(server_module, 1); free(netopeer_module->name); free(netopeer_module); comm_destroy(conn); return EXIT_FAILURE; } server_start = 0; nc_verb_verbose("Netopeer server successfully initialized."); while (!done) { comm_loop(conn, 500); } /* unload Netopeer module -> unload all modules */ module_disable(server_module, 1); module_disable(netopeer_module, 1); /* main cleanup */ if (!restart_soft) { /* close connection and destroy all sessions only when shutting down or hard restarting the server */ comm_destroy(conn); server_sessions_destroy_all (); nc_close (); } /* *Free the global variables that may *have been allocated by the parser. */ xmlCleanupParser (); if (restart_soft) { nc_verb_verbose("Server is going to soft restart."); restart_soft = 0; done = 0; goto restart; } else if (restart_hard) { nc_verb_verbose("Server is going to hard restart."); len = readlink("/proc/self/exe", path, PATH_MAX); path[len] = 0; execv(path, argv); } return (EXIT_SUCCESS); }
char * ofcds_getconfig(void *UNUSED(data), NC_DATASTORE target, struct nc_err **error) { xmlChar *config_data = NULL; switch (target) { case NC_DATASTORE_RUNNING: /* If there is no id of the capable-switch (no configuration data were * provided), continue as there is no OVSDB */ return ofc_get_config_data(); case NC_DATASTORE_STARTUP: if (!gds_startup) { config_data = xmlStrdup(BAD_CAST ""); } else { xmlDocDumpMemory(gds_startup, &config_data, NULL); } break; case NC_DATASTORE_CANDIDATE: if (!gds_cand) { config_data = xmlStrdup(BAD_CAST ""); } else { xmlDocDumpMemory(gds_cand, &config_data, NULL); } break; default: nc_verb_error("Invalid <get-config> source."); *error = nc_err_new(NC_ERR_BAD_ELEM); nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "source"); } return (char *) config_data; }