コード例 #1
0
ファイル: ofconfig-datastore.c プロジェクト: JimBrv/of-config
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;
}
コード例 #2
0
/* !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;
}
コード例 #3
0
/* !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;
}
コード例 #4
0
ファイル: ofconfig-datastore.c プロジェクト: JimBrv/of-config
int
ofcds_unlock(void *UNUSED(data), NC_DATASTORE target, const char *session_id,
             struct nc_err **error)
{
    int *locked;
    char **sid;

    switch (target) {
    case NC_DATASTORE_RUNNING:
        locked = &(locks.running);
        sid = &(locks.running_sid);
        break;
    case NC_DATASTORE_STARTUP:
        locked = &(locks.startup);
        sid = &(locks.startup_sid);
        break;
    case NC_DATASTORE_CANDIDATE:
        locked = &(locks.cand);
        sid = &(locks.cand_sid);
        break;
    default:
        /* handled by libnetconf */
        return EXIT_FAILURE;
    }

    if (*locked) {
        if (strcmp(*sid, session_id) == 0) {
            /* correct request, unlock */
            *locked = 0;
            free(*sid);
            *sid = NULL;
            nc_verb_verbose("OFC datastore %d unlocked by %s.", target,
                            session_id);
        } else {
            /* locked by another session */
            *error = nc_err_new(NC_ERR_LOCK_DENIED);
            nc_err_set(*error, NC_ERR_PARAM_INFO_SID, *sid);
            nc_err_set(*error, NC_ERR_PARAM_MSG,
                       "Target datastore is locked by another session.");
            return EXIT_FAILURE;
        }
    } else {
        /* not locked */
        *error = nc_err_new(NC_ERR_OP_FAILED);
        nc_err_set(*error, NC_ERR_PARAM_MSG,
                   "Target datastore is not locked.");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
コード例 #5
0
/* !DO NOT ALTER FUNCTION SIGNATURE! */
int callback_n_netopeer_n_tls_n_server_key(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr UNUSED(old_node), xmlNodePtr new_node, struct nc_err** error) {
	char* key = NULL, *type = NULL;
	xmlNodePtr child;

	if (op & (XMLDIFF_MOD | XMLDIFF_ADD)) {
		for (child = new_node->children; child != NULL; child = child->next) {
			if (xmlStrEqual(child->name, BAD_CAST "key-data")) {
				key = get_node_content(child);
			}

			if (xmlStrEqual(child->name, BAD_CAST "key-type")) {
				type = get_node_content(child);
			}
		}

		if (key == NULL || type == NULL) {
			*error = nc_err_new(NC_ERR_MISSING_ELEM);
			nc_err_set(*error, NC_ERR_PARAM_MSG, "key-data and/or key-type element missing.");
			return EXIT_FAILURE;
		}

		if (strcmp(type, "RSA") != 0 && strcmp(type, "DSA") != 0) {
			*error = nc_err_new(NC_ERR_BAD_ELEM);
			nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "/netopeer/tls/server-key/key-type");
			return EXIT_FAILURE;
		}
	}

	/* TLS_CTX LOCK */
	pthread_mutex_lock(&netopeer_options.tls_opts->tls_ctx_lock);

	free(netopeer_options.tls_opts->server_key);
	netopeer_options.tls_opts->server_key = NULL;
	if (op & (XMLDIFF_MOD | XMLDIFF_ADD)) {
		netopeer_options.tls_opts->server_key = strdup(key);
		if (strcmp(type, "RSA") == 0) {
			netopeer_options.tls_opts->server_key_type = 1;
		} else {
			netopeer_options.tls_opts->server_key_type = 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;
}
コード例 #6
0
/* !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;
}
コード例 #7
0
ファイル: ofconfig-datastore.c プロジェクト: JimBrv/of-config
int
ofcds_lock(void *UNUSED(data), NC_DATASTORE target, const char *session_id,
           struct nc_err **error)
{
    int *locked;
    char **sid;

    switch (target) {
    case NC_DATASTORE_RUNNING:
        locked = &(locks.running);
        sid = &(locks.running_sid);
        break;
    case NC_DATASTORE_STARTUP:
        locked = &(locks.startup);
        sid = &(locks.startup_sid);
        break;
    case NC_DATASTORE_CANDIDATE:
        locked = &(locks.cand);
        sid = &(locks.cand_sid);
        break;
    default:
        /* handled by libnetconf */
        return EXIT_FAILURE;
    }

    if (*locked) {
        /* datastore is already locked */
        *error = nc_err_new(NC_ERR_LOCK_DENIED);
        nc_err_set(*error, NC_ERR_PARAM_INFO_SID, *sid);
        return EXIT_FAILURE;
    } else {
        /* remember the lock */
        *locked = 1;
        *sid = strdup(session_id);
        nc_verb_verbose("OFC datastore %d locked by %s.", target, session_id);
    }

    return EXIT_SUCCESS;
}
コード例 #8
0
ファイル: session.c プロジェクト: rponczkowski/libnetconf
static PyObject *ncProcessRPC(ncSessionObject *self)
{
	NC_MSG_TYPE ret;
	NC_RPC_TYPE req_type;
	NC_OP req_op;
	nc_rpc *rpc = NULL;
	nc_reply *reply = NULL;
	struct nc_err* e = NULL;

	SESSION_CHECK(self);

	/* receive incoming message */
	ret = nc_session_recv_rpc(self->session, -1, &rpc);
	if (ret != NC_MSG_RPC) {
		if (nc_session_get_status(self->session) != NC_SESSION_STATUS_WORKING) {
			/* something really bad happend, and communication is not possible anymore */
			nc_session_free(self->session);
			self->session = NULL;
		}
		Py_RETURN_NONE;
	}

	/* process it */
	req_type = nc_rpc_get_type(rpc);
	req_op = nc_rpc_get_op(rpc);
	if (req_type == NC_RPC_SESSION) {
		/* process operations affectinf session */
		switch(req_op) {
		case NC_OP_CLOSESESSION:
			/* exit the event loop immediately without processing any following request */
			reply = nc_reply_ok();
			break;
		case NC_OP_KILLSESSION:
			/* todo: kill the requested session */
			reply = nc_reply_error(nc_err_new(NC_ERR_OP_NOT_SUPPORTED));
			break;
		default:
			reply = nc_reply_error(nc_err_new(NC_ERR_OP_NOT_SUPPORTED));
			break;
		}
	} else if (req_type == NC_RPC_DATASTORE_READ) {
		/* process operations reading datastore */
		switch (req_op) {
		case NC_OP_GET:
		case NC_OP_GETCONFIG:
			reply = ncds_apply_rpc2all(self->session, rpc,  NULL);
			break;
		default:
			reply = nc_reply_error(nc_err_new(NC_ERR_OP_NOT_SUPPORTED));
			break;
		}
	} else if (req_type == NC_RPC_DATASTORE_WRITE) {
		/* process operations affecting datastore */
		switch (req_op) {
		case NC_OP_LOCK:
		case NC_OP_UNLOCK:
		case NC_OP_COPYCONFIG:
		case NC_OP_DELETECONFIG:
		case NC_OP_EDITCONFIG:
			reply = ncds_apply_rpc2all(self->session, rpc, NULL);
			break;
		default:
			reply = nc_reply_error(nc_err_new(NC_ERR_OP_NOT_SUPPORTED));
			break;
		}
	} else {
		/* process other operations */
		reply = ncds_apply_rpc2all(self->session, rpc, NULL);
	}

	/* create reply */
	if (reply == NULL) {
		reply = nc_reply_error(nc_err_new(NC_ERR_OP_FAILED));
	} else if (reply == NCDS_RPC_NOT_APPLICABLE) {
		e = nc_err_new(NC_ERR_OP_FAILED);
		nc_err_set(e, NC_ERR_PARAM_MSG, "Requested operation cannot be performed on the managed datastore.");
		reply = nc_reply_error(e);
	}

	/* and send the reply to the client */
	nc_session_send_reply(self->session, rpc, reply);
	nc_rpc_free(rpc);
	nc_reply_free(reply);

	if (req_op == NC_OP_CLOSESESSION) {
		/* free the Session */
		nc_session_free(self->session);
		self->session = NULL;
	}

	Py_RETURN_NONE;
}
コード例 #9
0
/* !DO NOT ALTER FUNCTION SIGNATURE! */
int callback_n_netopeer_n_tls_n_cert_maps_n_cert_to_name(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr old_node, xmlNodePtr new_node, struct nc_err** error) {
	char* id = NULL, *fingerprint = NULL, *map_type = NULL, *name = NULL, *ptr, *msg;
	xmlNodePtr child;

callback_restart:
	for (child = (op & (XMLDIFF_MOD | XMLDIFF_REM) ? old_node->children : new_node->children); child != NULL; child = child->next) {
		if (xmlStrEqual(child->name, BAD_CAST "id")) {
			id = get_node_content(child);
		}
		if (xmlStrEqual(child->name, BAD_CAST "fingerprint")) {
			fingerprint = get_node_content(child);
		}
		if (xmlStrEqual(child->name, BAD_CAST "map-type")) {
			map_type = get_node_content(child);
			if (strchr(map_type, ':') != NULL) {
				map_type = strchr(map_type, ':')+1;
			}
		}
		if (xmlStrEqual(child->name, BAD_CAST "name")) {
			name = get_node_content(child);
		}
	}

	if (id == NULL || fingerprint == NULL || map_type == NULL) {
		*error = nc_err_new(NC_ERR_MISSING_ELEM);
		nc_err_set(*error, NC_ERR_PARAM_MSG, "id and/or fingerprint and/or map-type element missing.");
		return EXIT_FAILURE;
	}
	strtol(id, &ptr, 10);
	if (*ptr != '\0') {
		asprintf(&msg, "Could not convert '%s' to a number.", id);
		*error = nc_err_new(NC_ERR_BAD_ELEM);
		nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "/netopeer/tls/cert-maps/cert-to-name/id");
		nc_err_set(*error, NC_ERR_PARAM_MSG, msg);
		free(msg);
		return EXIT_FAILURE;
	}
	if (strcmp(map_type, "specified") == 0 && name == NULL) {
		*error = nc_err_new(NC_ERR_MISSING_ELEM);
		nc_err_set(*error, NC_ERR_PARAM_MSG, "name element missing.");
		return EXIT_FAILURE;
	}

	/* CTN_MAP LOCK */
	pthread_mutex_lock(&netopeer_options.tls_opts->ctn_map_lock);

	if (op & (XMLDIFF_REM | XMLDIFF_MOD)) {
		if (del_ctn_item(&netopeer_options.tls_opts->ctn_map, atoi(id), fingerprint, ctn_type_parse(map_type), name) != 0) {
			nc_verb_error("%s: inconsistent state (%s:%d)", __func__, __FILE__, __LINE__);
		}

		if (op & XMLDIFF_MOD) {
			/* CTN_MAP UNLOCK */
			pthread_mutex_unlock(&netopeer_options.tls_opts->ctn_map_lock);
			op = XMLDIFF_ADD;
			goto callback_restart;
		}
	}
	if (op & XMLDIFF_ADD) {
		add_ctn_item(&netopeer_options.tls_opts->ctn_map, atoi(id), fingerprint, ctn_type_parse(map_type), name);
	}

	/* CTN_MAP UNLOCK */
	pthread_mutex_unlock(&netopeer_options.tls_opts->ctn_map_lock);

	return EXIT_SUCCESS;
}
コード例 #10
0
int ncds_custom_unlock(struct ncds_ds* ds, const struct nc_session* session, NC_DATASTORE target, struct nc_err** error) {
	int retval, localinfo = 0;
	const char *sid = NULL;
	struct ncds_ds_custom *c_ds = (struct ncds_ds_custom *) ds;
	struct ncds_lockinfo *linfo;
	pthread_mutex_t* linfo_mut = NULL;

	linfo = get_lockinfo(target, &linfo_mut);
	if (linfo == NULL) {
		*error = nc_err_new(NC_ERR_BAD_ELEM);
		nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "target");
		return (EXIT_FAILURE);
	}

	pthread_mutex_lock(linfo_mut);
	if (c_ds->callbacks->is_locked == NULL) {
		/* is_locked() is not implemented by custom datastore, so we will
		 * try to use local info */
		localinfo = 1;
		if (linfo->sid == NULL) {
			/* datastore is not locked */
			retval = 0;
		} else {
			retval = 1;
			sid = linfo->sid;
		}
	} else {
		/* take locking access into custom datastore plugin */
		sem_wait(cds_lock); /* localinfo = 0 */

		/* get current info using is_locked() */
		retval = c_ds->callbacks->is_locked(c_ds->data, target, &sid, NULL);
		if (retval < 0) { /* error */
			sem_post(cds_lock);
			pthread_mutex_unlock(linfo_mut);
			ERROR("%s: custom datastore's is_locked() function failed (error %d)", __func__, retval);
			*error = nc_err_new(NC_ERR_OP_FAILED);
			nc_err_set(*error, NC_ERR_PARAM_MSG, "custom datastore's is_locked() function failed");
			return (EXIT_FAILURE);
		}
	}

	if (retval == 0) {
		if (localinfo) {
			/* try to call custom's unlock() if our info was up-to-date */
			retval = c_ds->callbacks->unlock(c_ds->data, target, session->session_id, error);
			/* if unlock succeeded, we were wrong and operation succeeds */
		} else {
			/* datastore is not locked */
			*error = nc_err_new(NC_ERR_OP_FAILED);
			nc_err_set(*error, NC_ERR_PARAM_MSG, "Target datastore is not locked.");
			retval = EXIT_FAILURE;
		}
	} else { /* retval == 1 */
		/* datastore is locked, check that we can unlock it and do it */
		if (strcmp(sid, session->session_id) != 0) {
			if (localinfo) {
				/* try to call custom's unlock() if our info was up-to-date */
				retval = c_ds->callbacks->unlock(c_ds->data, target, session->session_id, error);
				/* if unlock succeeded, we were wrong and operation succeeds */
			} else {
				/* datastore is locked by someone else */
				*error = nc_err_new(NC_ERR_OP_FAILED);
				nc_err_set(*error, NC_ERR_PARAM_MSG, "Target datastore is locked by another session.");
				retval = EXIT_FAILURE;
			}
		} else {
			/* try to unlock the datastore */
			retval = c_ds->callbacks->unlock(c_ds->data, target, session->session_id, error);
		}
	}

	/* drop locking access into custom datastore plugin */
	if (localinfo == 0) {
		sem_post(cds_lock);
	}

	if (retval == EXIT_SUCCESS) {
		free(linfo->time);
		free(linfo->sid);
		linfo->time = NULL;
		linfo->sid = NULL;
	}

	pthread_mutex_unlock(linfo_mut);
	return (retval);
}
コード例 #11
0
int ncds_custom_lock(struct ncds_ds* ds, const struct nc_session* session, NC_DATASTORE target, struct nc_err** error) {
	int retval, localinfo = 0;
	const char *sid = NULL;
	struct ncds_ds_custom *c_ds = (struct ncds_ds_custom *) ds;
	struct ncds_lockinfo *linfo;
	pthread_mutex_t* linfo_mut = NULL;

	linfo = get_lockinfo(target, &linfo_mut);
	if (linfo == NULL) {
		*error = nc_err_new(NC_ERR_BAD_ELEM);
		nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "target");
		return (EXIT_FAILURE);
	}

	pthread_mutex_lock(linfo_mut);
	if (c_ds->callbacks->is_locked == NULL) {
		/* is_locked() is not implemented by custom datastore, use local info */
		localinfo = 1;
		if (linfo->sid != NULL) {
			/* datastore is already locked */
			retval = 1;
			sid = linfo->sid;
		} else {
			retval = 0;
		}
	} else {
		/* take locking access into custom datastore plugin */
		sem_wait(cds_lock); /* localinfo = 0 */

		/* get current info using is_locked() */
		retval = c_ds->callbacks->is_locked(c_ds->data, target, &sid, NULL);
		if (retval < 0) { /* error */
			sem_post(cds_lock);
			pthread_mutex_unlock(linfo_mut);
			ERROR("%s: custom datastore's is_locked() function failed (error %d)", __func__, retval);
			*error = nc_err_new(NC_ERR_OP_FAILED);
			nc_err_set(*error, NC_ERR_PARAM_MSG, "custom datastore's is_locked() function failed");
			return (EXIT_FAILURE);
		}
	}

	/* check current status of the lock */
	if (retval == 0 || localinfo) {
		/* datastore is not locked (or we are not sure), try to lock it */
		retval = c_ds->callbacks->lock(c_ds->data, target, session->session_id, error);
	} else { /* retval == 1 && localinfo == 0 */
		/* datastore is already locked */
		*error = nc_err_new(NC_ERR_LOCK_DENIED);
		nc_err_set(*error, NC_ERR_PARAM_INFO_SID, sid);
		retval = EXIT_FAILURE;
	}

	/* drop locking access into custom datastore plugin */
	if (localinfo == 0) {
		sem_post(cds_lock);
	}

	/* update localinfo structure */
	if (retval == EXIT_SUCCESS) {
		linfo->time = nc_time2datetime(time(NULL), NULL);
		linfo->sid = strdup(session->session_id);
	}

	pthread_mutex_unlock(linfo_mut);
	return (retval);
}
コード例 #12
0
ファイル: ofconfig-datastore.c プロジェクト: JimBrv/of-config
int
ofcds_copyconfig(void *UNUSED(data), NC_DATASTORE target,
                 NC_DATASTORE source, char *config, struct nc_err **error)
{
    int ret = EXIT_FAILURE;
    char *s;
    xmlDocPtr src_doc = NULL;
    xmlDocPtr dst_doc = NULL;
    xmlNodePtr root;
    static const char *ds[] = {"error", "<config>", "URL", "running",
                               "startup", "candidate"};

    nc_verb_verbose("OFC COPY-CONFIG (from %s to %s)", ds[source], ds[target]);

    switch (source) {
    case NC_DATASTORE_RUNNING:
        s = ofcds_getconfig(NULL, NC_DATASTORE_RUNNING, error);
        if (!s) {
            nc_verb_error
                ("copy-config: unable to get running source repository");
            return EXIT_FAILURE;
        }
        src_doc = xmlReadMemory(s, strlen(s), NULL, NULL, XML_READ_OPT);
        free(s);
        if (!src_doc) {
            nc_verb_error("copy-config: invalid running source data");
            *error = nc_err_new(NC_ERR_OP_FAILED);
            nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM,
                       "invalid running source data");
            return EXIT_FAILURE;
        }
        break;
    case NC_DATASTORE_STARTUP:
        src_doc = xmlCopyDoc(gds_startup, 1);
        break;
    case NC_DATASTORE_CANDIDATE:
        src_doc = xmlCopyDoc(gds_cand, 1);
        break;
    case NC_DATASTORE_CONFIG:
        if (config && strlen(config) > 0) {
            src_doc = xmlReadMemory(config, strlen(config), NULL, NULL,
                                    XML_READ_OPT);
        }
        if (!config || (strlen(config) > 0 && !src_doc)) {
            nc_verb_error("Invalid source configuration data.");
            *error = nc_err_new(NC_ERR_BAD_ELEM);
            nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "config");
            return EXIT_FAILURE;
        }

        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 EXIT_FAILURE;
    }

    switch (target) {
    case NC_DATASTORE_RUNNING:
        /* apply source to OVSDB */

        s = ofcds_getconfig(NULL, NC_DATASTORE_RUNNING, error);
        if (!s) {
            nc_verb_error("copy-config: unable to get running source data");
            goto cleanup;
        }
        dst_doc = xmlReadMemory(s, strlen(s), NULL, NULL, XML_READ_OPT);
        free(s);

        root = xmlDocGetRootElement(src_doc);
        if (!dst_doc) {
            /* create envelope */
            dst_doc = xmlNewDoc(BAD_CAST "1.0");
        }
        if (!rollbacking) {
            store_rollback(xmlCopyDoc(dst_doc, 1), target);
        }

        txn_init();
        if (edit_replace(dst_doc, root, 1, error)) {
            txn_abort();
        } else {
            ret = txn_commit(error);
        }
        xmlFreeDoc(dst_doc);
        goto cleanup;
        break;
    case NC_DATASTORE_STARTUP:
    case NC_DATASTORE_CANDIDATE:
        /* create copy */
        if (src_doc) {
            dst_doc = src_doc;
            src_doc = NULL;
        }

        /* store the copy */
        if (target == NC_DATASTORE_STARTUP) {
            if (!rollbacking) {
                store_rollback(gds_startup, target);
            } else {
                xmlFreeDoc(gds_startup);
            }
            gds_startup = dst_doc;
        } else {                /* NC_DATASTORE_CANDIDATE */
            if (!rollbacking) {
                store_rollback(gds_cand, target);
            } else {
                xmlFreeDoc(gds_cand);
            }
            gds_cand = dst_doc;
        }

        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");
        goto cleanup;
    }

    ret = EXIT_SUCCESS;

cleanup:
    xmlFreeDoc(src_doc);

    return ret;
}
コード例 #13
0
ファイル: ofconfig-datastore.c プロジェクト: JimBrv/of-config
int
ofcds_editconfig(void *UNUSED(data), const nc_rpc * UNUSED(rpc),
                 NC_DATASTORE target, const char *config,
                 NC_EDIT_DEFOP_TYPE defop,
                 NC_EDIT_ERROPT_TYPE UNUSED(errop), struct nc_err **error)
{
    int ret = EXIT_FAILURE, running = 0;
    char *aux;
    int cfgds_new = 0;
    xmlDocPtr cfgds = NULL, cfg = NULL, cfg_clone = NULL;
    xmlNodePtr rootcfg;

    if (defop == NC_EDIT_DEFOP_NOTSET) {
        defop = NC_EDIT_DEFOP_MERGE;
    }

    cfg = xmlReadMemory(config, strlen(config), NULL, NULL, XML_READ_OPT);
    rootcfg = xmlDocGetRootElement(cfg);
    if (!cfg
        || (rootcfg
            && !xmlStrEqual(rootcfg->name, BAD_CAST "capable-switch"))) {
        nc_verb_error("Invalid <edit-config> configuration data.");
        *error = nc_err_new(NC_ERR_BAD_ELEM);
        nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "config");
        return EXIT_FAILURE;
    }

    switch (target) {
    case NC_DATASTORE_RUNNING:
        /* Make a copy of parsed config - we will find port/configuration in
         * it.  It is used after txn_commit(). */
        cfg_clone = xmlCopyDoc(cfg, 1);

        aux = ofc_get_config_data();
        if (!aux) {
            *error = nc_err_new(NC_ERR_OP_FAILED);
            goto error_cleanup;
        }
        cfgds = xmlReadMemory(aux, strlen(aux), NULL, NULL, XML_READ_OPT);
        free(aux);

        running = 1;
        break;
    case NC_DATASTORE_STARTUP:
        cfgds = gds_startup;
        break;
    case NC_DATASTORE_CANDIDATE:
        cfgds = gds_cand;
        break;
    default:
        nc_verb_error("Invalid <edit-config> target.");
        *error = nc_err_new(NC_ERR_BAD_ELEM);
        nc_err_set(*error, NC_ERR_PARAM_INFO_BADELEM, "target");
        goto error_cleanup;
    }
    store_rollback(xmlCopyDoc(cfgds, 1), target);

    /* check keys in config's lists */
    ret = check_keys(cfg, error);
    if (ret != EXIT_SUCCESS) {
        goto error_cleanup;
    }

    /* check operations */
    ret = check_edit_ops(NC_EDIT_OP_DELETE, defop, cfgds, cfg, error);
    if (ret != EXIT_SUCCESS) {
        goto error_cleanup;
    }
    ret = check_edit_ops(NC_EDIT_OP_CREATE, defop, cfgds, cfg, error);
    if (ret != EXIT_SUCCESS) {
        goto error_cleanup;
    }

    if (target == NC_DATASTORE_RUNNING) {
        txn_init();
    }

    ret = compact_edit_operations(cfg, defop);
    if (ret != EXIT_SUCCESS) {
        nc_verb_error("Compacting edit-config operations failed.");
        if (error != NULL) {
            *error = nc_err_new(NC_ERR_OP_FAILED);
        }
        goto error_cleanup;
    }

    /* perform operations */
    if (!cfgds) {
        cfgds_new = 1;
        cfgds = xmlNewDoc(BAD_CAST "1.0");
    }
    ret = edit_operations(cfgds, cfg, defop, running, error);
    if (ret != EXIT_SUCCESS) {
        goto error_cleanup;
    }

    /* with defaults capability */
    if (ncdflt_get_basic_mode() == NCWD_MODE_TRIM) {
        /* server work in trim basic mode and therefore all default values
         * must be removed from the datastore. */
        /* TODO */
    }

    if (target == NC_DATASTORE_RUNNING) {
        ret = txn_commit(error);

        if (ret == EXIT_SUCCESS) {
            /* modify port/configuration of ports that were created */
            ret = of_post_ports(xmlDocGetRootElement(cfg_clone), error);
        }
        /* config clone was used and it is not needed by now */
        xmlFreeDoc(cfg_clone);

        xmlFreeDoc(cfgds);
    } else if (cfgds_new){
        if (cfgds->children) {
            /* document changed, because we started with empty document */
            if (target == NC_DATASTORE_STARTUP) {
                gds_startup = cfgds;
                cfgds = NULL;
            } else if (target == NC_DATASTORE_CANDIDATE) {
                gds_cand = cfgds;
                cfgds = NULL;
            }
        }
        xmlFreeDoc(cfgds);
    }
    xmlFreeDoc(cfg);

    return ret;

error_cleanup:

    if (target == NC_DATASTORE_RUNNING) {
        txn_abort();
        xmlFreeDoc(cfg_clone);
        xmlFreeDoc(cfgds);
    }
    xmlFreeDoc(cfg);

    return ret;
}
コード例 #14
0
ファイル: error.c プロジェクト: CESNET/libnetconf
API struct nc_err* nc_err_new(NC_ERR error)
{
	struct nc_err* err = NULL;

	err = calloc(1, sizeof(struct nc_err));
	if (err == NULL) {
		ERROR("Memory allocation failed - %s (%s:%d).", strerror (errno), __FILE__, __LINE__);
		return (NULL);
	}

	/* set error structure according to some predefined errors in RFC 6241 */
	switch (error) {
	case NC_ERR_EMPTY:
		/* do nothing */
		break;
	case NC_ERR_IN_USE:
		nc_err_set(err, NC_ERR_PARAM_TAG, "in-use");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "The request requires a resource that is already in use.");
		break;
	case NC_ERR_INVALID_VALUE:
		nc_err_set(err, NC_ERR_PARAM_TAG, "invalid-value");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "The request specifies an unacceptable value for one or more parameters.");
		break;
	case NC_ERR_TOO_BIG:
		nc_err_set(err, NC_ERR_PARAM_TAG, "too-big");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "The request or response is too large for the implementation to handle.");
		break;
	case NC_ERR_MISSING_ATTR:
		nc_err_set(err, NC_ERR_PARAM_TAG, "missing-attribute");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "An expected attribute is missing.");
		break;
	case NC_ERR_BAD_ATTR:
		nc_err_set(err, NC_ERR_PARAM_TAG, "bad-attribute");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "An attribute value is not correct.");
		break;
	case NC_ERR_UNKNOWN_ATTR:
		nc_err_set(err, NC_ERR_PARAM_TAG, "unknown-attribute");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "An unexpected attribute is present.");
		break;
	case NC_ERR_MISSING_ELEM:
		nc_err_set(err, NC_ERR_PARAM_TAG, "missing-element");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "An expected element is missing.");
		break;
	case NC_ERR_BAD_ELEM:
		nc_err_set(err, NC_ERR_PARAM_TAG, "bad-element");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "An element value is not correct.");
		break;
	case NC_ERR_UNKNOWN_ELEM:
		nc_err_set(err, NC_ERR_PARAM_TAG, "unknown-element");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "An unexpected element is present.");
		break;
	case NC_ERR_UNKNOWN_NS:
		nc_err_set(err, NC_ERR_PARAM_TAG, "unknown-namespace");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "An unexpected namespace is present.");
		break;
	case NC_ERR_ACCESS_DENIED:
		nc_err_set(err, NC_ERR_PARAM_TAG, "access-denied");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "Access to the requested protocol operation or data model is denied because the authorization failed.");
		break;
	case NC_ERR_LOCK_DENIED:
		nc_err_set(err, NC_ERR_PARAM_TAG, "lock-denied");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "protocol");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "Access to the requested lock is denied because the lock is currently held by another entity.");
		break;
	case NC_ERR_RES_DENIED:
		nc_err_set(err, NC_ERR_PARAM_TAG, "resource-denied");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "protocol");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "Request could not be completed because of insufficient resources.");
		break;
	case NC_ERR_ROLLBACK_FAILED:
		nc_err_set(err, NC_ERR_PARAM_TAG, "rollback-failed");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "Request to roll back some configuration change was not completed for some reason.");
		break;
	case NC_ERR_DATA_EXISTS:
		nc_err_set(err, NC_ERR_PARAM_TAG, "data-exists");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "Request could not be completed because the relevant data model content already exists.");
		break;
	case NC_ERR_DATA_MISSING:
		nc_err_set(err, NC_ERR_PARAM_TAG, "data-missing");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "Request could not be completed because the relevant data model content does not exist.");
		break;
	case NC_ERR_OP_NOT_SUPPORTED:
		nc_err_set(err, NC_ERR_PARAM_TAG, "operation-not-supported");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "Request could not be completed because the requested operation is not supported by this implementation.");
		break;
	case NC_ERR_OP_FAILED:
		nc_err_set(err, NC_ERR_PARAM_TAG, "operation-failed");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "application");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "Some unspecified error occurred.");
		break;
	case NC_ERR_MALFORMED_MSG:
		nc_err_set(err, NC_ERR_PARAM_TAG, "malformed-message");
		nc_err_set(err, NC_ERR_PARAM_TYPE, "rpc");
		nc_err_set(err, NC_ERR_PARAM_SEVERITY, "error");
		nc_err_set(err, NC_ERR_PARAM_MSG, "A message could not be handled because it failed to be parsed correctly.");
		break;
	}

	return (err);
}
コード例 #15
-1
ファイル: ofconfig-datastore.c プロジェクト: JimBrv/of-config
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;
}