internal netconf hello mechanism to obtain session-id

This commit is contained in:
Olof hagsand 2019-10-24 11:46:06 +02:00
parent 59825214f3
commit 44138c0071
14 changed files with 250 additions and 264 deletions

View file

@ -67,6 +67,7 @@
#include "clixon_xml_map.h"
#include "clixon_xpath_ctx.h"
#include "clixon_xpath.h"
#include "clixon_yang_module.h"
#include "clixon_netconf_lib.h"
/*! Create Netconf in-use error XML tree according to RFC 6241 Appendix A
@ -1397,3 +1398,102 @@ netconf_content_int2str(netconf_content nr)
{
return clicon_int2str(netconf_content_map, nr);
}
/*! Create Netconf server hello. Single cap and defer individual to querying modules
* @param[in] h Clicon handle
* @param[in] cb Msg buffer
* @param[in] session_id Id of client session
* Lots of dependencies here. regarding the hello protocol.
* RFC6241 NETCONF Protocol says: (8.1)
* MUST send a <hello> element containing a list of that peer's capabilities
* MUST send at least the base NETCONF capability, urn:ietf:params:netconf:base:1.1
* MAY include capabilities for previous NETCONF versions
* A server MUST include a <session-id>
* A client MUST NOT include a <session-id>
* A server receiving <session-id> MUST terminate the NETCONF session.
* A client not receiving <session-id> MUST terminate w/o sending<close-session>
* the example shows urn:ietf:params:netconf:capability:startup:1.0
* RFC5277 NETCONF Event Notifications
* urn:ietf:params:netconf:capability:notification:1.0 is advertised during the capability exchange
*
* RFC6022 YANG Module for NETCONF Monitoring
* MUST advertise the capability URI "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"
* RFC7895 Yang module library defines how to announce module features (not hell capabilities)
* RFC7950 YANG 1.1 says (5.6.4);
* MUST announce the modules it implements by implementing the YANG module
* "ietf-yang-library" (RFC7895) and listing all implemented modules in the
* "/modules-state/module" list.
* MUST advertise urn:ietf:params:netconf:capability:yang-library:1.0?
* revision=<date>&module-set-id=<id> in the <hello> message.
*
* Question: should the NETCONF in RFC6241 sections 8.2-8.9 be announced both
* as features and as capabilities in the <hello> message according to RFC6241?
* urn:ietf:params:netconf:capability:candidate:1.0 (8.3)
* urn:ietf:params:netconf:capability:validate:1.1 (8.6)
* urn:ietf:params:netconf:capability:startup:1.0 (8.7)
* urn:ietf:params:netconf:capability:xpath:1.0 (8.9)
* urn:ietf:params:netconf:capability:notification:1.0 (RFC5277)
*
* @note the hello message is created bythe netconf application, not the
* backend, and backend may implement more modules - please consider if using
* library routines for detecting capabilities here. In contrast, yang module
* list (RFC7895) is processed by the backend.
* @note encode bodies, see xml_chardata_encode()
* @see yang_modules_state_get
* @see netconf_module_load
*/
int
netconf_hello_server(clicon_handle h,
cbuf *cb,
uint32_t session_id)
{
int retval = -1;
char *module_set_id;
char *ietf_yang_library_revision;
char *encstr = NULL;
module_set_id = clicon_option_str(h, "CLICON_MODULE_SET_ID");
if ((ietf_yang_library_revision = yang_modules_revision(h)) == NULL)
goto done;
cprintf(cb, "<hello xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
cprintf(cb, "<capabilities>");
cprintf(cb, "<capability>urn:ietf:params:netconf:base:1.0</capability>");
if (xml_chardata_encode(&encstr, "urn:ietf:params:netconf:capability:yang-library:1.0?revision=%s&module-set-id=%s",
ietf_yang_library_revision,
module_set_id) < 0)
goto done;
cprintf(cb, "<capability>%s</capability>", encstr);
cprintf(cb, "<capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>");
cprintf(cb, "<capability>urn:ietf:params:netconf:capability:validate:1.1</capability>");
cprintf(cb, "<capability>urn:ietf:params:netconf:capability:startup:1.0</capability>");
cprintf(cb, "<capability>urn:ietf:params:netconf:capability:xpath:1.0</capability>");
cprintf(cb, "<capability>urn:ietf:params:netconf:capability:notification:1.0</capability>");
cprintf(cb, "</capabilities>");
if (session_id)
cprintf(cb, "<session-id>%lu</session-id>", (long unsigned int)session_id);
cprintf(cb, "</hello>");
cprintf(cb, "]]>]]>");
retval = 0;
done:
if (encstr)
free(encstr);
return retval;
}
int
netconf_hello_req(clicon_handle h,
cbuf *cb)
{
int retval = -1;
cprintf(cb, "<hello xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
cprintf(cb, "<capabilities>");
cprintf(cb, "<capability>urn:ietf:params:netconf:base:1.0</capability>");
cprintf(cb, "</capabilities>");
cprintf(cb, "</hello>");
cprintf(cb, "]]>]]>");
retval = 0;
return retval;
}

View file

@ -902,7 +902,6 @@ clicon_rpc_debug(clicon_handle h,
char *username;
username = clicon_username_get(h);
/* XXX: hardcoded example yang, should be clixon-config!!! */
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;
@ -925,3 +924,53 @@ clicon_rpc_debug(clicon_handle h,
return retval;
}
/*! Send a debug request to backend server
* @param[in] h CLICON handle
* @param[in] level Debug level
* @retval 0 OK
* @retval -1 Error and logged to syslog
*/
int
clicon_hello_req(clicon_handle h,
uint32_t *id)
{
int retval = -1;
struct clicon_msg *msg = NULL;
cxobj *xret = NULL;
cxobj *xerr;
cxobj *x;
char *username;
char *b;
int ret;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode(0, "<hello username=\"%s\" xmlns=\"%s\"><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello>",
username?username:"",
NETCONF_BASE_NAMESPACE)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
clicon_rpc_generate_error("Hello", xerr);
goto done;
}
if ((x = xpath_first(xret, "hello/session-id")) == NULL){
clicon_err(OE_XML, 0, "hello session-id");
goto done;
}
b = xml_body(x);
if ((ret = parse_uint32(b, id, NULL)) <= 0){
clicon_err(OE_XML, errno, "parse_uint32");
goto done;
}
fprintf(stderr, "id:%lu\n", *id);
retval = 0;
done:
if (msg)
free(msg);
if (xret)
xml_free(xret);
return retval;
}

View file

@ -278,7 +278,7 @@ x +--ro namespace inet:uri
+--ro name yang:yang-identifier
+--ro revision union
+--ro schema? inet:uri
* @see netconf_create_hello
* @see netconf_hello_server
*/
int
yang_modules_state_get(clicon_handle h,