Merge branch 'master' of https://github.com/clicon/clixon
This commit is contained in:
commit
9a6478e267
23 changed files with 229 additions and 155 deletions
|
|
@ -18,6 +18,8 @@
|
||||||
* `except` means exact match is done except for root and www user.This is necessary for Restconf. This is default.
|
* `except` means exact match is done except for root and www user.This is necessary for Restconf. This is default.
|
||||||
|
|
||||||
### API changes on existing features (you may need to change your code)
|
### API changes on existing features (you may need to change your code)
|
||||||
|
* Internal backend socket protocol changed: uint32_t session-id added, see clixon_proto.h
|
||||||
|
* C-code: added `id` parameter to `clicon_msg_encode()` and `clicon_msg_decode()`
|
||||||
* NACM users are cross-checked with client user credentials (see new features).
|
* NACM users are cross-checked with client user credentials (see new features).
|
||||||
* Changed "Demon error" to "Daemon error" in logs and debug.
|
* Changed "Demon error" to "Daemon error" in logs and debug.
|
||||||
* Stricter handling of multi-namespace handling
|
* Stricter handling of multi-namespace handling
|
||||||
|
|
@ -51,6 +53,8 @@
|
||||||
* Replaced JSON `null` with `[null]` as proper empty JSON leaf/leaf-list encoding.
|
* Replaced JSON `null` with `[null]` as proper empty JSON leaf/leaf-list encoding.
|
||||||
|
|
||||||
### Minor changes
|
### Minor changes
|
||||||
|
* Changed session-id handing. Instead of using pid of peer process, a proper session id generated by the server is used, following RFC6241.
|
||||||
|
* Code in kill_session is removed where this fact was used to actually kill the client process.
|
||||||
* XPATH canonical form implemented for NETCONF get and get-config. This means that all callbacks (including state callbacks) will have the prefixes that corresponds to module prefixes. If an xpath have other prefixes (or null as default), they will be translated to canonical form before any callbacks.
|
* XPATH canonical form implemented for NETCONF get and get-config. This means that all callbacks (including state callbacks) will have the prefixes that corresponds to module prefixes. If an xpath have other prefixes (or null as default), they will be translated to canonical form before any callbacks.
|
||||||
* Example of a canonical form: `/a:x/a:y`, then symbols must belong to a yang module with prefix `a`.
|
* Example of a canonical form: `/a:x/a:y`, then symbols must belong to a yang module with prefix `a`.
|
||||||
* Configure and test modification for better Freebsd port
|
* Configure and test modification for better Freebsd port
|
||||||
|
|
|
||||||
|
|
@ -69,14 +69,18 @@
|
||||||
#include "backend_client.h"
|
#include "backend_client.h"
|
||||||
#include "backend_handle.h"
|
#include "backend_handle.h"
|
||||||
|
|
||||||
|
/*! Find client by session-id
|
||||||
|
* @param[in] ce_list List of clients
|
||||||
|
* @param[in] id Session id
|
||||||
|
*/
|
||||||
static struct client_entry *
|
static struct client_entry *
|
||||||
ce_find_bypid(struct client_entry *ce_list,
|
ce_find_byid(struct client_entry *ce_list,
|
||||||
int pid)
|
uint32_t id)
|
||||||
{
|
{
|
||||||
struct client_entry *ce;
|
struct client_entry *ce;
|
||||||
|
|
||||||
for (ce = ce_list; ce; ce = ce->ce_next)
|
for (ce = ce_list; ce; ce = ce->ce_next)
|
||||||
if (ce->ce_pid == pid)
|
if (ce->ce_id == id)
|
||||||
return ce;
|
return ce;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -104,7 +108,7 @@ ce_event_cb(clicon_handle h,
|
||||||
backend_client_rm(h, ce);
|
backend_client_rm(h, ce);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (send_msg_notify_xml(ce->ce_s, event) < 0){
|
if (send_msg_notify_xml(h, ce->ce_s, event) < 0){
|
||||||
if (errno == ECONNRESET || errno == EPIPE){
|
if (errno == ECONNRESET || errno == EPIPE){
|
||||||
clicon_log(LOG_WARNING, "client %d reset", ce->ce_nr);
|
clicon_log(LOG_WARNING, "client %d reset", ce->ce_nr);
|
||||||
}
|
}
|
||||||
|
|
@ -483,12 +487,13 @@ from_client_edit_config(clicon_handle h,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct client_entry *ce = (struct client_entry *)arg;
|
struct client_entry *ce = (struct client_entry *)arg;
|
||||||
int mypid = ce->ce_pid;
|
uint32_t myid = ce->ce_id;
|
||||||
|
uint32_t iddb;
|
||||||
char *target;
|
char *target;
|
||||||
cxobj *xc;
|
cxobj *xc;
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
enum operation_type operation = OP_MERGE;
|
enum operation_type operation = OP_MERGE;
|
||||||
int piddb;
|
|
||||||
int non_config = 0;
|
int non_config = 0;
|
||||||
yang_stmt *yspec;
|
yang_stmt *yspec;
|
||||||
cbuf *cbx = NULL; /* Assist cbuf */
|
cbuf *cbx = NULL; /* Assist cbuf */
|
||||||
|
|
@ -517,9 +522,9 @@ from_client_edit_config(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* Check if target locked by other client */
|
/* Check if target locked by other client */
|
||||||
piddb = xmldb_islocked(h, target);
|
iddb = xmldb_islocked(h, target);
|
||||||
if (piddb && mypid != piddb){
|
if (iddb && myid != iddb){
|
||||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -612,8 +617,8 @@ from_client_copy_config(clicon_handle h,
|
||||||
struct client_entry *ce = (struct client_entry *)arg;
|
struct client_entry *ce = (struct client_entry *)arg;
|
||||||
char *source;
|
char *source;
|
||||||
char *target;
|
char *target;
|
||||||
int piddb;
|
uint32_t iddb;
|
||||||
int mypid = ce->ce_pid;
|
uint32_t myid = ce->ce_id;
|
||||||
cbuf *cbx = NULL; /* Assist cbuf */
|
cbuf *cbx = NULL; /* Assist cbuf */
|
||||||
|
|
||||||
if ((source = netconf_db_find(xe, "source")) == NULL){
|
if ((source = netconf_db_find(xe, "source")) == NULL){
|
||||||
|
|
@ -643,9 +648,9 @@ from_client_copy_config(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* Check if target locked by other client */
|
/* Check if target locked by other client */
|
||||||
piddb = xmldb_islocked(h, target);
|
iddb = xmldb_islocked(h, target);
|
||||||
if (piddb && mypid != piddb){
|
if (iddb && myid != iddb){
|
||||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Copy failed, lock is already held") < 0)
|
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Copy failed, lock is already held") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -683,9 +688,9 @@ from_client_delete_config(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct client_entry *ce = (struct client_entry *)arg;
|
struct client_entry *ce = (struct client_entry *)arg;
|
||||||
char *target;
|
char *target;
|
||||||
int piddb;
|
uint32_t iddb;
|
||||||
|
uint32_t myid = ce->ce_id;
|
||||||
cbuf *cbx = NULL; /* Assist cbuf */
|
cbuf *cbx = NULL; /* Assist cbuf */
|
||||||
int mypid = ce->ce_pid;
|
|
||||||
|
|
||||||
if ((target = netconf_db_find(xe, "target")) == NULL ||
|
if ((target = netconf_db_find(xe, "target")) == NULL ||
|
||||||
strcmp(target, "running")==0){
|
strcmp(target, "running")==0){
|
||||||
|
|
@ -704,9 +709,9 @@ from_client_delete_config(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* Check if target locked by other client */
|
/* Check if target locked by other client */
|
||||||
piddb = xmldb_islocked(h, target);
|
iddb = xmldb_islocked(h, target);
|
||||||
if (piddb && mypid != piddb){
|
if (iddb && myid != iddb){
|
||||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -749,9 +754,9 @@ from_client_lock(clicon_handle h,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct client_entry *ce = (struct client_entry *)arg;
|
struct client_entry *ce = (struct client_entry *)arg;
|
||||||
int pid = ce->ce_pid;
|
uint32_t id = ce->ce_id;
|
||||||
|
uint32_t iddb;
|
||||||
char *db;
|
char *db;
|
||||||
int piddb;
|
|
||||||
cbuf *cbx = NULL; /* Assist cbuf */
|
cbuf *cbx = NULL; /* Assist cbuf */
|
||||||
|
|
||||||
if ((db = netconf_db_find(xe, "target")) == NULL){
|
if ((db = netconf_db_find(xe, "target")) == NULL){
|
||||||
|
|
@ -775,15 +780,15 @@ from_client_lock(clicon_handle h,
|
||||||
* 2) The target configuration is <candidate>, it has already been modified, and
|
* 2) The target configuration is <candidate>, it has already been modified, and
|
||||||
* these changes have not been committed or rolled back.
|
* these changes have not been committed or rolled back.
|
||||||
*/
|
*/
|
||||||
piddb = xmldb_islocked(h, db);
|
iddb = xmldb_islocked(h, db);
|
||||||
if (piddb){
|
if (iddb != 0){
|
||||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (xmldb_lock(h, db, pid) < 0)
|
if (xmldb_lock(h, db, id) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||||
}
|
}
|
||||||
|
|
@ -814,9 +819,9 @@ from_client_unlock(clicon_handle h,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct client_entry *ce = (struct client_entry *)arg;
|
struct client_entry *ce = (struct client_entry *)arg;
|
||||||
int pid = ce->ce_pid;
|
uint32_t id = ce->ce_id;
|
||||||
|
uint32_t iddb; /* DBs lock, if any */
|
||||||
char *db;
|
char *db;
|
||||||
int piddb;
|
|
||||||
cbuf *cbx = NULL; /* Assist cbuf */
|
cbuf *cbx = NULL; /* Assist cbuf */
|
||||||
|
|
||||||
if ((db = netconf_db_find(xe, "target")) == NULL){
|
if ((db = netconf_db_find(xe, "target")) == NULL){
|
||||||
|
|
@ -834,7 +839,7 @@ from_client_unlock(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
piddb = xmldb_islocked(h, db);
|
iddb = xmldb_islocked(h, db);
|
||||||
/*
|
/*
|
||||||
* An unlock operation will not succeed if any of the following
|
* An unlock operation will not succeed if any of the following
|
||||||
* conditions are true:
|
* conditions are true:
|
||||||
|
|
@ -842,8 +847,8 @@ from_client_unlock(clicon_handle h,
|
||||||
* 2) the session issuing the <unlock> operation is not the same
|
* 2) the session issuing the <unlock> operation is not the same
|
||||||
* session that obtained the lock
|
* session that obtained the lock
|
||||||
*/
|
*/
|
||||||
if (piddb==0 || piddb != pid){
|
if (iddb == 0 || iddb != id){
|
||||||
cprintf(cbx, "<session-id>pid=%d piddb=%d</session-id>", pid, piddb);
|
cprintf(cbx, "<session-id>id=%u iddb=%d</session-id>", id, iddb);
|
||||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Unlock failed, lock is already held") < 0)
|
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Unlock failed, lock is already held") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -1013,9 +1018,9 @@ from_client_close_session(clicon_handle h,
|
||||||
void *regarg)
|
void *regarg)
|
||||||
{
|
{
|
||||||
struct client_entry *ce = (struct client_entry *)arg;
|
struct client_entry *ce = (struct client_entry *)arg;
|
||||||
int pid = ce->ce_pid;
|
uint32_t id = ce->ce_id;
|
||||||
|
|
||||||
xmldb_unlock_all(h, pid);
|
xmldb_unlock_all(h, id);
|
||||||
stream_ss_delete_all(h, ce_event_cb, (void*)ce);
|
stream_ss_delete_all(h, ce_event_cb, (void*)ce);
|
||||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1039,11 +1044,13 @@ from_client_kill_session(clicon_handle h,
|
||||||
void *regarg)
|
void *regarg)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
uint32_t pid; /* other pid */
|
uint32_t id; /* session id */
|
||||||
char *str;
|
char *str;
|
||||||
struct client_entry *ce;
|
struct client_entry *ce;
|
||||||
char *db = "running"; /* XXX */
|
char *db = "running"; /* XXX */
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
|
int ret;
|
||||||
|
char *reason = NULL;
|
||||||
|
|
||||||
if ((x = xml_find(xe, "session-id")) == NULL ||
|
if ((x = xml_find(xe, "session-id")) == NULL ||
|
||||||
(str = xml_find_value(x, "body")) == NULL){
|
(str = xml_find_value(x, "body")) == NULL){
|
||||||
|
|
@ -1051,36 +1058,28 @@ from_client_kill_session(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
pid = atoi(str);
|
if ((ret = parse_uint32(str, &id, &reason)) < 0){
|
||||||
|
clicon_err(OE_XML, errno, "parse_uint32");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (ret == 0){
|
||||||
|
if (netconf_bad_element(cbret, "protocol", "session-id", reason) < 0)
|
||||||
|
goto done;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* may or may not be in active client list, probably not */
|
/* may or may not be in active client list, probably not */
|
||||||
if ((ce = ce_find_bypid(backend_client_list(h), pid)) != NULL){
|
if ((ce = ce_find_byid(backend_client_list(h), id)) != NULL){
|
||||||
xmldb_unlock_all(h, pid);
|
xmldb_unlock_all(h, id);
|
||||||
backend_client_rm(h, ce);
|
backend_client_rm(h, ce);
|
||||||
}
|
}
|
||||||
|
if (xmldb_islocked(h, db) == id)
|
||||||
if (kill (pid, 0) != 0 && errno == ESRCH) /* Nothing there */
|
|
||||||
;
|
|
||||||
else{
|
|
||||||
killpg(pid, SIGTERM);
|
|
||||||
kill(pid, SIGTERM);
|
|
||||||
#if 0 /* Hate sleeps we assume it died, see also 0 in next if.. */
|
|
||||||
sleep(1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (1 || (kill (pid, 0) != 0 && errno == ESRCH)){ /* Nothing there */
|
|
||||||
/* clear from locks */
|
|
||||||
if (xmldb_islocked(h, db) == pid)
|
|
||||||
xmldb_unlock(h, db);
|
xmldb_unlock(h, db);
|
||||||
}
|
|
||||||
else{ /* failed to kill client */
|
|
||||||
if (netconf_operation_failed(cbret, "application", "Failed to kill session")< 0)
|
|
||||||
goto done;
|
|
||||||
goto ok;
|
|
||||||
}
|
|
||||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (reason)
|
||||||
|
free(reason);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1328,6 +1327,7 @@ from_client_msg(clicon_handle h,
|
||||||
yang_stmt *ymod;
|
yang_stmt *ymod;
|
||||||
cxobj *xnacm = NULL;
|
cxobj *xnacm = NULL;
|
||||||
cxobj *xret = NULL;
|
cxobj *xret = NULL;
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
yspec = clicon_dbspec_yang(h);
|
yspec = clicon_dbspec_yang(h);
|
||||||
|
|
@ -1338,12 +1338,13 @@ from_client_msg(clicon_handle h,
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (clicon_msg_decode(msg, yspec, &xt) < 0){
|
/* Decode msg from client -> xml top (ct) and session id */
|
||||||
|
if (clicon_msg_decode(msg, yspec, &id, &xt) < 0){
|
||||||
if (netconf_malformed_message(cbret, "XML parse error")< 0)
|
if (netconf_malformed_message(cbret, "XML parse error")< 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto reply;
|
goto reply;
|
||||||
}
|
}
|
||||||
|
ce->ce_id = id;
|
||||||
if ((x = xpath_first_nsc(xt, NULL, "/rpc")) == NULL){
|
if ((x = xpath_first_nsc(xt, NULL, "/rpc")) == NULL){
|
||||||
if (netconf_malformed_message(cbret, "rpc keyword expected")< 0)
|
if (netconf_malformed_message(cbret, "rpc keyword expected")< 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ struct client_entry{
|
||||||
int ce_nr; /* Client number (for dbg/tracing) */
|
int ce_nr; /* Client number (for dbg/tracing) */
|
||||||
int ce_stat_in; /* Nr of received msgs from client */
|
int ce_stat_in; /* Nr of received msgs from client */
|
||||||
int ce_stat_out;/* Nr of sent msgs to client */
|
int ce_stat_out;/* Nr of sent msgs to client */
|
||||||
int ce_pid; /* Peer Process id */
|
int ce_id; /* Session id */
|
||||||
char *ce_username;/* Translated from peer user cred */
|
char *ce_username;/* Translated from peer user cred */
|
||||||
clicon_handle ce_handle; /* clicon config handle (all clients have same?) */
|
clicon_handle ce_handle; /* clicon config handle (all clients have same?) */
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -607,19 +607,19 @@ from_client_commit(clicon_handle h,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct client_entry *ce = (struct client_entry *)arg;
|
struct client_entry *ce = (struct client_entry *)arg;
|
||||||
int mypid = ce->ce_pid;
|
uint32_t myid = ce->ce_id;
|
||||||
int piddb;
|
uint32_t iddb;
|
||||||
cbuf *cbx = NULL; /* Assist cbuf */
|
cbuf *cbx = NULL; /* Assist cbuf */
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Check if target locked by other client */
|
/* Check if target locked by other client */
|
||||||
piddb = xmldb_islocked(h, "running");
|
iddb = xmldb_islocked(h, "running");
|
||||||
if (piddb && mypid != piddb){
|
if (iddb && myid != iddb){
|
||||||
if ((cbx = cbuf_new()) == NULL){
|
if ((cbx = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -662,18 +662,18 @@ from_client_discard_changes(clicon_handle h,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct client_entry *ce = (struct client_entry *)arg;
|
struct client_entry *ce = (struct client_entry *)arg;
|
||||||
int mypid = ce->ce_pid;
|
uint32_t myid = ce->ce_id;
|
||||||
int piddb;
|
uint32_t iddb;
|
||||||
cbuf *cbx = NULL; /* Assist cbuf */
|
cbuf *cbx = NULL; /* Assist cbuf */
|
||||||
|
|
||||||
/* Check if target locked by other client */
|
/* Check if target locked by other client */
|
||||||
piddb = xmldb_islocked(h, "candidate");
|
iddb = xmldb_islocked(h, "candidate");
|
||||||
if (piddb && mypid != piddb){
|
if (iddb && myid != iddb){
|
||||||
if ((cbx = cbuf_new()) == NULL){
|
if ((cbx = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
|
||||||
|
|
@ -886,6 +886,9 @@ main(int argc,
|
||||||
if (check_drop_priv(h, gid) < 0)
|
if (check_drop_priv(h, gid) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
/* Start session-id for clients */
|
||||||
|
clicon_session_id_set(h, 0);
|
||||||
|
|
||||||
if (stream_timer_setup(0, h) < 0)
|
if (stream_timer_setup(0, h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (event_loop() < 0)
|
if (event_loop() < 0)
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,8 @@ backend_socket_init(clicon_handle h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Accept new socket client
|
/*! Accept new socket client
|
||||||
* XXX: credentials not properly implemented
|
* @param[in] fd Socket (unix or ip)
|
||||||
|
* @param[in] arg typecast clicon_handle
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
backend_accept_client(int fd,
|
backend_accept_client(int fd,
|
||||||
|
|
@ -228,12 +229,11 @@ backend_accept_client(int fd,
|
||||||
struct sockaddr from = {0,};
|
struct sockaddr from = {0,};
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
struct client_entry *ce;
|
struct client_entry *ce;
|
||||||
int i;
|
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
#ifdef HAVE_SO_PEERCRED
|
#ifdef HAVE_SO_PEERCRED /* Linux. */
|
||||||
socklen_t clen;
|
socklen_t clen;
|
||||||
struct ucred cr = {0,}; /* Linux. */
|
struct ucred cr = {0,};
|
||||||
#elif defined(HAVE_GETPEEREID)
|
#elif defined(HAVE_GETPEEREID) /* FreeBSD */
|
||||||
uid_t euid;
|
uid_t euid;
|
||||||
uid_t guid;
|
uid_t guid;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -259,7 +259,6 @@ backend_accept_client(int fd,
|
||||||
clicon_err(OE_UNIX, errno, "getsockopt");
|
clicon_err(OE_UNIX, errno, "getsockopt");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ce->ce_pid = cr.pid; /* XXX no use session-id */
|
|
||||||
if (uid2name(cr.uid, &name) < 0)
|
if (uid2name(cr.uid, &name) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#elif defined(HAVE_GETPEEREID)
|
#elif defined(HAVE_GETPEEREID)
|
||||||
|
|
@ -277,10 +276,7 @@ backend_accept_client(int fd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AF_INET: /* XXX: HACK ce->ce_pid */
|
case AF_INET:
|
||||||
ce->ce_pid = 0;
|
|
||||||
for (i=0; i<len; i++)
|
|
||||||
ce->ce_pid ^= from.sa_data[i];
|
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
default:
|
default:
|
||||||
|
|
@ -297,5 +293,3 @@ backend_accept_client(int fd,
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -983,7 +983,7 @@ cli_notification_cb(int s,
|
||||||
event_unreg_fd(s, cli_notification_cb);
|
event_unreg_fd(s, cli_notification_cb);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (clicon_msg_decode(reply, NULL, &xt) < 0) /* XXX pass yang_spec */
|
if (clicon_msg_decode(reply, NULL, NULL, &xt) < 0) /* XXX pass yang_spec */
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xt, "//event")) != NULL){
|
if ((xe = xpath_first(xt, "//event")) != NULL){
|
||||||
x = NULL;
|
x = NULL;
|
||||||
|
|
|
||||||
|
|
@ -595,6 +595,11 @@ main(int argc, char **argv)
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
/* XXX get session id from backend hello */
|
||||||
|
clicon_session_id_set(h, getpid());
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Go into event-loop unless -1 command-line */
|
/* Go into event-loop unless -1 command-line */
|
||||||
if (!once)
|
if (!once)
|
||||||
retval = cli_interactive(h);
|
retval = cli_interactive(h);
|
||||||
|
|
|
||||||
|
|
@ -529,6 +529,11 @@ main(int argc,
|
||||||
/* Call start function is all plugins before we go interactive */
|
/* Call start function is all plugins before we go interactive */
|
||||||
if (clixon_plugin_start(h) < 0)
|
if (clixon_plugin_start(h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
#if 1
|
||||||
|
/* XXX get session id from backend hello */
|
||||||
|
clicon_session_id_set(h, getpid());
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
send_hello(h, 1);
|
send_hello(h, 1);
|
||||||
if (event_reg_fd(0, netconf_input_cb, h, "netconf socket") < 0)
|
if (event_reg_fd(0, netconf_input_cb, h, "netconf socket") < 0)
|
||||||
|
|
|
||||||
|
|
@ -443,7 +443,7 @@ netconf_notification_cb(int s,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
yspec = clicon_dbspec_yang(h);
|
yspec = clicon_dbspec_yang(h);
|
||||||
if (clicon_msg_decode(reply, yspec, &xt) < 0)
|
if (clicon_msg_decode(reply, yspec, NULL, &xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netconf:notification:1.0")) == NULL)
|
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netconf:notification:1.0")) == NULL)
|
||||||
|
|
|
||||||
|
|
@ -779,6 +779,10 @@ main(int argc,
|
||||||
clicon_err(OE_CFG, errno, "FCGX_OpenSocket");
|
clicon_err(OE_CFG, errno, "FCGX_OpenSocket");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
/* XXX get session id from backend hello */
|
||||||
|
clicon_session_id_set(h, getpid());
|
||||||
|
#endif
|
||||||
if (clicon_socket_set(h, sock) < 0)
|
if (clicon_socket_set(h, sock) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* umask settings may interfer: we want group to write: this is 774 */
|
/* umask settings may interfer: we want group to write: this is 774 */
|
||||||
|
|
|
||||||
|
|
@ -684,8 +684,7 @@ api_data_write(clicon_handle h,
|
||||||
if (cbx)
|
if (cbx)
|
||||||
cbuf_free(cbx);
|
cbuf_free(cbx);
|
||||||
return retval;
|
return retval;
|
||||||
} /* api_data_put */
|
} /* api_data_write */
|
||||||
|
|
||||||
|
|
||||||
/*! Generic REST PUT method
|
/*! Generic REST PUT method
|
||||||
* @param[in] h CLIXON handle
|
* @param[in] h CLIXON handle
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ restconf_stream_cb(int s,
|
||||||
clicon_exit_set();
|
clicon_exit_set();
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (clicon_msg_decode(reply, NULL, &xtop) < 0) /* XXX pass yang_spec */
|
if (clicon_msg_decode(reply, NULL, NULL, &xtop) < 0) /* XXX pass yang_spec */
|
||||||
goto done;
|
goto done;
|
||||||
/* create event */
|
/* create event */
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
*/
|
*/
|
||||||
/* Struct per database in hash */
|
/* Struct per database in hash */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int de_pid;
|
uint32_t de_id; /* session id */
|
||||||
cxobj *de_xml; /* cache */
|
cxobj *de_xml; /* cache */
|
||||||
} db_elmnt;
|
} db_elmnt;
|
||||||
|
|
||||||
|
|
@ -98,4 +98,7 @@ int clicon_xml_changelog_set(clicon_handle h, cxobj *xchlog);
|
||||||
int clicon_argv_get(clicon_handle h, int *argc, char ***argv);
|
int clicon_argv_get(clicon_handle h, int *argc, char ***argv);
|
||||||
int clicon_argv_set(clicon_handle h, char *argv0, int argc, char **argv);
|
int clicon_argv_set(clicon_handle h, char *argv0, int argc, char **argv);
|
||||||
|
|
||||||
|
int clicon_session_id_set(clicon_handle h, uint32_t id);
|
||||||
|
uint32_t clicon_session_id_get(clicon_handle h);
|
||||||
|
|
||||||
#endif /* _CLIXON_DATA_H_ */
|
#endif /* _CLIXON_DATA_H_ */
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,10 @@ int xmldb_get0_clear(clicon_handle h, cxobj *x);
|
||||||
int xmldb_get0_free(clicon_handle h, cxobj **xp);
|
int xmldb_get0_free(clicon_handle h, cxobj **xp);
|
||||||
int xmldb_put(clicon_handle h, const char *db, enum operation_type op, cxobj *xt, char *username, cbuf *cbret); /* in clixon_datastore_write.[ch] */
|
int xmldb_put(clicon_handle h, const char *db, enum operation_type op, cxobj *xt, char *username, cbuf *cbret); /* in clixon_datastore_write.[ch] */
|
||||||
int xmldb_copy(clicon_handle h, const char *from, const char *to);
|
int xmldb_copy(clicon_handle h, const char *from, const char *to);
|
||||||
int xmldb_lock(clicon_handle h, const char *db, int pid);
|
int xmldb_lock(clicon_handle h, const char *db, uint32_t id);
|
||||||
int xmldb_unlock(clicon_handle h, const char *db);
|
int xmldb_unlock(clicon_handle h, const char *db);
|
||||||
int xmldb_unlock_all(clicon_handle h, int pid);
|
int xmldb_unlock_all(clicon_handle h, uint32_t id);
|
||||||
int xmldb_islocked(clicon_handle h, const char *db);
|
uint32_t xmldb_islocked(clicon_handle h, const char *db);
|
||||||
int xmldb_exists(clicon_handle h, const char *db);
|
int xmldb_exists(clicon_handle h, const char *db);
|
||||||
int xmldb_delete(clicon_handle h, const char *db);
|
int xmldb_delete(clicon_handle h, const char *db);
|
||||||
int xmldb_create(clicon_handle h, const char *db);
|
int xmldb_create(clicon_handle h, const char *db);
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ enum format_enum{
|
||||||
/* Protocol message header */
|
/* Protocol message header */
|
||||||
struct clicon_msg {
|
struct clicon_msg {
|
||||||
uint32_t op_len; /* length of message. network byte order. */
|
uint32_t op_len; /* length of message. network byte order. */
|
||||||
|
uint32_t op_id; /* session-id. network byte order. */
|
||||||
char op_body[0]; /* rest of message, actual data */
|
char op_body[0]; /* rest of message, actual data */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -62,11 +63,11 @@ char *format_int2str(enum format_enum showas);
|
||||||
enum format_enum format_str2int(char *str);
|
enum format_enum format_str2int(char *str);
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
struct clicon_msg *clicon_msg_encode(char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
struct clicon_msg *clicon_msg_encode(uint32_t id, char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||||
#else
|
#else
|
||||||
struct clicon_msg *clicon_msg_encode(char *format, ...);
|
struct clicon_msg *clicon_msg_encode(uint32_t id, char *format, ...);
|
||||||
#endif
|
#endif
|
||||||
int clicon_msg_decode(struct clicon_msg *msg, yang_stmt *yspec, cxobj **xml);
|
int clicon_msg_decode(struct clicon_msg *msg, yang_stmt *yspec, uint32_t *id, cxobj **xml);
|
||||||
|
|
||||||
int clicon_connect_unix(char *sockpath);
|
int clicon_connect_unix(char *sockpath);
|
||||||
|
|
||||||
|
|
@ -87,7 +88,7 @@ int clicon_msg_send(int s, struct clicon_msg *msg);
|
||||||
|
|
||||||
int clicon_msg_rcv(int s, struct clicon_msg **msg, int *eof);
|
int clicon_msg_rcv(int s, struct clicon_msg **msg, int *eof);
|
||||||
|
|
||||||
int send_msg_notify_xml(int s, cxobj *xev);
|
int send_msg_notify_xml(clicon_handle h, int s, cxobj *xev);
|
||||||
|
|
||||||
int send_msg_reply(int s, char *data, uint32_t datalen);
|
int send_msg_reply(int s, char *data, uint32_t datalen);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ int clicon_rpc_lock(clicon_handle h, char *db);
|
||||||
int clicon_rpc_unlock(clicon_handle h, char *db);
|
int clicon_rpc_unlock(clicon_handle h, char *db);
|
||||||
int clicon_rpc_get(clicon_handle h, char *xpath, cvec *nsc, netconf_content content, int32_t depth, cxobj **xret);
|
int clicon_rpc_get(clicon_handle h, char *xpath, cvec *nsc, netconf_content content, int32_t depth, cxobj **xret);
|
||||||
int clicon_rpc_close_session(clicon_handle h);
|
int clicon_rpc_close_session(clicon_handle h);
|
||||||
int clicon_rpc_kill_session(clicon_handle h, int session_id);
|
int clicon_rpc_kill_session(clicon_handle h, uint32_t session_id);
|
||||||
int clicon_rpc_validate(clicon_handle h, char *db);
|
int clicon_rpc_validate(clicon_handle h, char *db);
|
||||||
int clicon_rpc_commit(clicon_handle h);
|
int clicon_rpc_commit(clicon_handle h);
|
||||||
int clicon_rpc_discard_changes(clicon_handle h);
|
int clicon_rpc_discard_changes(clicon_handle h);
|
||||||
|
|
|
||||||
|
|
@ -495,3 +495,35 @@ clicon_db_elmnt_set(clicon_handle h,
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Get session id
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @retval id Session identifier
|
||||||
|
* Two uses: the backend assigns session-id for clients.
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
clicon_session_id_get(clicon_handle h)
|
||||||
|
{
|
||||||
|
clicon_hash_t *cdat = clicon_data(h);
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if ((p = clicon_hash_value(cdat, "session-id", NULL)) == NULL)
|
||||||
|
return 0;
|
||||||
|
return *(uint32_t*)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Set session id
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] id Session id
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clicon_session_id_set(clicon_handle h,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
clicon_hash_t *cdat = clicon_data(h);
|
||||||
|
|
||||||
|
clicon_hash_add(cdat, "session-id", &id, sizeof(uint32_t));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -254,30 +254,29 @@ xmldb_copy(clicon_handle h,
|
||||||
/*! Lock database
|
/*! Lock database
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] db Database
|
* @param[in] db Database
|
||||||
* @param[in] pid Process id
|
* @param[in] id Session id
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmldb_lock(clicon_handle h,
|
xmldb_lock(clicon_handle h,
|
||||||
const char *db,
|
const char *db,
|
||||||
int pid)
|
uint32_t id)
|
||||||
{
|
{
|
||||||
db_elmnt *de = NULL;
|
db_elmnt *de = NULL;
|
||||||
db_elmnt de0 = {0,};
|
db_elmnt de0 = {0,};
|
||||||
|
|
||||||
if ((de = clicon_db_elmnt_get(h, db)) != NULL)
|
if ((de = clicon_db_elmnt_get(h, db)) != NULL)
|
||||||
de0 = *de;
|
de0 = *de;
|
||||||
de0.de_pid = pid;
|
de0.de_id = id;
|
||||||
clicon_db_elmnt_set(h, db, &de0);
|
clicon_db_elmnt_set(h, db, &de0);
|
||||||
clicon_debug(1, "%s: locked by %u", db, pid);
|
clicon_debug(1, "%s: locked by %u", db, id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Unlock database
|
/*! Unlock database
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] db Database
|
* @param[in] db Database
|
||||||
* @param[in] pid Process id
|
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* Assume all sanity checks have been made
|
* Assume all sanity checks have been made
|
||||||
|
|
@ -289,21 +288,21 @@ xmldb_unlock(clicon_handle h,
|
||||||
db_elmnt *de = NULL;
|
db_elmnt *de = NULL;
|
||||||
|
|
||||||
if ((de = clicon_db_elmnt_get(h, db)) != NULL){
|
if ((de = clicon_db_elmnt_get(h, db)) != NULL){
|
||||||
de->de_pid = 0;
|
de->de_id = 0;
|
||||||
clicon_db_elmnt_set(h, db, de);
|
clicon_db_elmnt_set(h, db, de);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Unlock all databases locked by pid (eg process dies)
|
/*! Unlock all databases locked by session-id (eg process dies)
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] pid Process / Session id
|
* @param[in] id Session id
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmldb_unlock_all(clicon_handle h,
|
xmldb_unlock_all(clicon_handle h,
|
||||||
int pid)
|
uint32_t id)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char **keys = NULL;
|
char **keys = NULL;
|
||||||
|
|
@ -315,8 +314,8 @@ xmldb_unlock_all(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
for (i = 0; i < klen; i++)
|
for (i = 0; i < klen; i++)
|
||||||
if ((de = clicon_db_elmnt_get(h, keys[i])) != NULL &&
|
if ((de = clicon_db_elmnt_get(h, keys[i])) != NULL &&
|
||||||
de->de_pid == pid){
|
de->de_id == id){
|
||||||
de->de_pid = 0;
|
de->de_id = 0;
|
||||||
clicon_db_elmnt_set(h, keys[i], de);
|
clicon_db_elmnt_set(h, keys[i], de);
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -333,7 +332,7 @@ xmldb_unlock_all(clicon_handle h,
|
||||||
* @retval 0 Not locked
|
* @retval 0 Not locked
|
||||||
* @retval >0 Id of locker
|
* @retval >0 Id of locker
|
||||||
*/
|
*/
|
||||||
int
|
uint32_t
|
||||||
xmldb_islocked(clicon_handle h,
|
xmldb_islocked(clicon_handle h,
|
||||||
const char *db)
|
const char *db)
|
||||||
{
|
{
|
||||||
|
|
@ -341,7 +340,7 @@ xmldb_islocked(clicon_handle h,
|
||||||
|
|
||||||
if ((de = clicon_db_elmnt_get(h, db)) == NULL)
|
if ((de = clicon_db_elmnt_get(h, db)) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
return de->de_pid;
|
return de->de_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Check if db exists
|
/*! Check if db exists
|
||||||
|
|
|
||||||
|
|
@ -122,14 +122,17 @@ format_str2int(char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Encode a clicon netconf message using variable argument lists
|
/*! Encode a clicon netconf message using variable argument lists
|
||||||
|
* @param[in] id Session id of client
|
||||||
* @param[in] format Variable agrument list format an XML netconf string
|
* @param[in] format Variable agrument list format an XML netconf string
|
||||||
|
* @retval NULL Error
|
||||||
* @retval msg Clicon message to send to eg clicon_msg_send()
|
* @retval msg Clicon message to send to eg clicon_msg_send()
|
||||||
* @note if format includes %, they will be expanded according to printf rules.
|
* @note if format includes %, they will be expanded according to printf rules.
|
||||||
* if this is a problem, use ("%s", xml) instaead of (xml)
|
* if this is a problem, use ("%s", xml) instaead of (xml)
|
||||||
* Notaly this may an issue of RFC 3896 encoded strings
|
* Notaly this may an issue of RFC 3896 encoded strings
|
||||||
*/
|
*/
|
||||||
struct clicon_msg *
|
struct clicon_msg *
|
||||||
clicon_msg_encode(char *format, ...)
|
clicon_msg_encode(uint32_t id,
|
||||||
|
char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
uint32_t xmllen;
|
uint32_t xmllen;
|
||||||
|
|
@ -149,6 +152,7 @@ clicon_msg_encode(char *format, ...)
|
||||||
memset(msg, 0, len);
|
memset(msg, 0, len);
|
||||||
/* hdr */
|
/* hdr */
|
||||||
msg->op_len = htonl(len);
|
msg->op_len = htonl(len);
|
||||||
|
msg->op_id = htonl(id);
|
||||||
|
|
||||||
/* body */
|
/* body */
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
|
@ -161,16 +165,21 @@ clicon_msg_encode(char *format, ...)
|
||||||
/*! Decode a clicon netconf message
|
/*! Decode a clicon netconf message
|
||||||
* @param[in] msg CLICON msg
|
* @param[in] msg CLICON msg
|
||||||
* @param[in] yspec Yang specification, (can be NULL)
|
* @param[in] yspec Yang specification, (can be NULL)
|
||||||
|
* @param[out] id Session id
|
||||||
* @param[out] xml XML parse tree
|
* @param[out] xml XML parse tree
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_msg_decode(struct clicon_msg *msg,
|
clicon_msg_decode(struct clicon_msg *msg,
|
||||||
yang_stmt *yspec,
|
yang_stmt *yspec,
|
||||||
|
uint32_t *id,
|
||||||
cxobj **xml)
|
cxobj **xml)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *xmlstr;
|
char *xmlstr;
|
||||||
|
|
||||||
|
/* hdr */
|
||||||
|
if (id)
|
||||||
|
*id = ntohl(msg->op_id);
|
||||||
/* body */
|
/* body */
|
||||||
xmlstr = msg->op_body;
|
xmlstr = msg->op_body;
|
||||||
clicon_debug(1, "%s %s", __FUNCTION__, xmlstr);
|
clicon_debug(1, "%s %s", __FUNCTION__, xmlstr);
|
||||||
|
|
@ -575,7 +584,7 @@ send_msg_notify(int s,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct clicon_msg *msg = NULL;
|
struct clicon_msg *msg = NULL;
|
||||||
|
|
||||||
if ((msg=clicon_msg_encode("%s", event)) == NULL)
|
if ((msg=clicon_msg_encode(0, "%s", event)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_msg_send(s, msg) < 0)
|
if (clicon_msg_send(s, msg) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -596,7 +605,8 @@ send_msg_notify(int s,
|
||||||
* @see send_msg_notify XXX beauty contest
|
* @see send_msg_notify XXX beauty contest
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
send_msg_notify_xml(int s,
|
send_msg_notify_xml(clicon_handle h,
|
||||||
|
int s,
|
||||||
cxobj *xev)
|
cxobj *xev)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ clicon_rpc_netconf(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct clicon_msg *msg = NULL;
|
struct clicon_msg *msg = NULL;
|
||||||
|
|
||||||
if ((msg = clicon_msg_encode("%s", xmlstr)) < 0)
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h), "%s", xmlstr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, xret, sp) < 0)
|
if (clicon_rpc_msg(h, msg, xret, sp) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -318,7 +318,8 @@ clicon_rpc_get_config(clicon_handle h,
|
||||||
cprintf(cb, "/>");
|
cprintf(cb, "/>");
|
||||||
}
|
}
|
||||||
cprintf(cb, "</get-config></rpc>");
|
cprintf(cb, "</get-config></rpc>");
|
||||||
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"%s", cbuf_get(cb))) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -384,7 +385,8 @@ clicon_rpc_edit_config(clicon_handle h,
|
||||||
if (xmlstr)
|
if (xmlstr)
|
||||||
cprintf(cb, "%s", xmlstr);
|
cprintf(cb, "%s", xmlstr);
|
||||||
cprintf(cb, "</edit-config></rpc>");
|
cprintf(cb, "</edit-config></rpc>");
|
||||||
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"%s", cbuf_get(cb))) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -428,7 +430,8 @@ clicon_rpc_copy_config(clicon_handle h,
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><copy-config><source><%s/></source><target><%s/></target></copy-config></rpc>",
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><copy-config><source><%s/></source><target><%s/></target></copy-config></rpc>",
|
||||||
username?username:"",
|
username?username:"",
|
||||||
db1, db2)) == NULL)
|
db1, db2)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -468,7 +471,8 @@ clicon_rpc_delete_config(clicon_handle h,
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><edit-config><target><%s/></target><default-operation>none</default-operation><config operation=\"delete\"/></edit-config></rpc>",
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><edit-config><target><%s/></target><default-operation>none</default-operation><config operation=\"delete\"/></edit-config></rpc>",
|
||||||
username?username:"", db)) == NULL)
|
username?username:"", db)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
|
|
@ -503,7 +507,8 @@ clicon_rpc_lock(clicon_handle h,
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><lock><target><%s/></target></lock></rpc>",
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><lock><target><%s/></target></lock></rpc>",
|
||||||
username?username:"", db)) == NULL)
|
username?username:"", db)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
|
|
@ -538,7 +543,8 @@ clicon_rpc_unlock(clicon_handle h,
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><unlock><target><%s/></target></unlock></rpc>", username?username:"", db)) == NULL)
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><unlock><target><%s/></target></unlock></rpc>", username?username:"", db)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -634,7 +640,8 @@ clicon_rpc_get(clicon_handle h,
|
||||||
cprintf(cb, "/>");
|
cprintf(cb, "/>");
|
||||||
}
|
}
|
||||||
cprintf(cb, "</get></rpc>");
|
cprintf(cb, "</get></rpc>");
|
||||||
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"%s", cbuf_get(cb))) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -676,7 +683,8 @@ clicon_rpc_close_session(clicon_handle h)
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><close-session/></rpc>",
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><close-session/></rpc>",
|
||||||
username?username:"")) == NULL)
|
username?username:"")) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
|
|
@ -702,7 +710,7 @@ clicon_rpc_close_session(clicon_handle h)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_rpc_kill_session(clicon_handle h,
|
clicon_rpc_kill_session(clicon_handle h,
|
||||||
int session_id)
|
uint32_t session_id)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct clicon_msg *msg = NULL;
|
struct clicon_msg *msg = NULL;
|
||||||
|
|
@ -711,7 +719,8 @@ clicon_rpc_kill_session(clicon_handle h,
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><kill-session><session-id>%d</session-id></kill-session></rpc>",
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><kill-session><session-id>%u</session-id></kill-session></rpc>",
|
||||||
username?username:"", session_id)) == NULL)
|
username?username:"", session_id)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
|
|
@ -746,7 +755,8 @@ clicon_rpc_validate(clicon_handle h,
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><validate><source><%s/></source></validate></rpc>", username?username:"", db)) == NULL)
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><validate><source><%s/></source></validate></rpc>", username?username:"", db)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -778,7 +788,8 @@ clicon_rpc_commit(clicon_handle h)
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><commit/></rpc>", username?username:"")) == NULL)
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><commit/></rpc>", username?username:"")) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -810,7 +821,8 @@ clicon_rpc_discard_changes(clicon_handle h)
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><discard-changes/></rpc>", username?username:"")) == NULL)
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><discard-changes/></rpc>", username?username:"")) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -850,7 +862,8 @@ clicon_rpc_create_subscription(clicon_handle h,
|
||||||
char *username;
|
char *username;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">"
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">"
|
||||||
"<stream>%s</stream>"
|
"<stream>%s</stream>"
|
||||||
"<filter type=\"xpath\" select=\"%s\" />"
|
"<filter type=\"xpath\" select=\"%s\" />"
|
||||||
"</create-subscription></rpc>",
|
"</create-subscription></rpc>",
|
||||||
|
|
@ -890,7 +903,8 @@ clicon_rpc_debug(clicon_handle h,
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
/* XXX: hardcoded example yang, should be clixon-config!!! */
|
/* XXX: hardcoded example yang, should be clixon-config!!! */
|
||||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><debug xmlns=\"http://clicon.org/lib\"><level>%d</level></debug></rpc>", username?username:"", level)) == NULL)
|
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||||
|
"<rpc username=\"%s\"><debug xmlns=\"http://clicon.org/lib\"><level>%d</level></debug></rpc>", username?username:"", level)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ main(int argc, char **argv)
|
||||||
char *xmlfilename = NULL;
|
char *xmlfilename = NULL;
|
||||||
char *dbdir = NULL;
|
char *dbdir = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
int pid;
|
uint32_t id;
|
||||||
enum operation_type op;
|
enum operation_type op;
|
||||||
cxobj *xt = NULL;
|
cxobj *xt = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -277,8 +277,8 @@ main(int argc, char **argv)
|
||||||
else if (strcmp(cmd, "lock")==0){
|
else if (strcmp(cmd, "lock")==0){
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
usage(argv0);
|
usage(argv0);
|
||||||
pid = atoi(argv[1]);
|
id = atoi(argv[1]);
|
||||||
if (xmldb_lock(h, db, pid) < 0)
|
if (xmldb_lock(h, db, id) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else if (strcmp(cmd, "unlock")==0){
|
else if (strcmp(cmd, "unlock")==0){
|
||||||
|
|
@ -290,8 +290,8 @@ main(int argc, char **argv)
|
||||||
else if (strcmp(cmd, "unlock_all")==0){
|
else if (strcmp(cmd, "unlock_all")==0){
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
usage(argv0);
|
usage(argv0);
|
||||||
pid = atoi(argv[1]);
|
id = atoi(argv[1]);
|
||||||
if (xmldb_unlock_all(h, pid) < 0)
|
if (xmldb_unlock_all(h, id) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else if (strcmp(cmd, "islocked")==0){
|
else if (strcmp(cmd, "islocked")==0){
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ main(int argc,
|
||||||
}
|
}
|
||||||
if (clicon_xml2cbuf(cb, xc, 0, 0, -1) < 0)
|
if (clicon_xml2cbuf(cb, xc, 0, 0, -1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) < 0)
|
if ((msg = clicon_msg_encode(getpid(), "%s", cbuf_get(cb))) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (strcmp(family, "UNIX")==0){
|
if (strcmp(family, "UNIX")==0){
|
||||||
if (clicon_rpc_connect_unix(msg, sockpath, &retdata, NULL) < 0)
|
if (clicon_rpc_connect_unix(msg, sockpath, &retdata, NULL) < 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue