Skip to content

Commit

Permalink
Netconf monitoring statistics frm RFC 6022
Browse files Browse the repository at this point in the history
  • Loading branch information
olofhagsand committed Feb 4, 2023
1 parent 5da8ce2 commit 6681eb9
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 39 deletions.
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ Expected: beginning of 2023
* New plugin callback: `ca_yang_mount`
* Standards: RFC 8528
* To enable configure with `--enable-yang-schema-mount`
* Netconf monitoring RFC 6022 , part 2
* Datastores and sessions
* Netconf monitoring RFC 6022
* This is part 2, first part was in 6.0
* Datastores, sessions and statistics
* Added clixon-specific transport identities: cli, snmp, netconf, restconf
* Added source-host fro native restonf, but no other transports
* Added source-host from native restonf, but no other transports
* Hello statistics is based on backend statistics, hellos from RESTCONF, SNMP and CLI clients are included and dropped external NETCONF sessions are not
* Standards
* RFC 6022 "YANG Module for NETCONF Monitoring"
* See [Feature Request: Support RFC 6022 (NETCONF Monitoring)](https://github.com/clicon/clixon/issues/370)
* Remaining: statistics state

### API changes on existing protocol/config features

Expand Down
39 changes: 27 additions & 12 deletions apps/backend/backend_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
the terms of any one of the Apache License version 2 or the GPL.
***** END LICENSE BLOCK *****
* note: there is also client code in clixon_backend_handle.c
*/

#ifdef HAVE_CONFIG_H
Expand Down Expand Up @@ -117,6 +117,9 @@ ce_event_cb(clicon_handle h,
}
break;
}
/* note there may be other notifications than RFC5277 streams */
ce->ce_out_notifications++;
netconf_monitoring_counter_inc(h, "out-notifications");
}
return 0;
}
Expand Down Expand Up @@ -218,7 +221,7 @@ backend_monitoring_state_get(clicon_handle h,
cprintf(cb, "<in-rpcs>%u</in-rpcs>", ce->ce_in_rpcs);
cprintf(cb, "<in-bad-rpcs>%u</in-bad-rpcs>", ce->ce_in_bad_rpcs);
cprintf(cb, "<out-rpc-errors>%u</out-rpc-errors>", ce->ce_out_rpc_errors);
cprintf(cb, "<out-notifications>%u</out-notifications>", 0);
cprintf(cb, "<out-notifications>%u</out-notifications>", ce->ce_out_notifications);
cprintf(cb, "</session>");
}
cprintf(cb, "</sessions>");
Expand Down Expand Up @@ -263,7 +266,6 @@ backend_client_rm(clicon_handle h,
clicon_err(OE_YANG, ENOENT, "No yang spec");
goto done;
}

if (if_feature(yspec, "ietf-netconf", "confirmed-commit")) {
if (confirmed_commit_state_get(h) == EPHEMERAL) {
/* See if this client is the origin */
Expand Down Expand Up @@ -301,9 +303,8 @@ backend_client_rm(clicon_handle h,
ce_prev = &c->ce_next;
}
retval = backend_client_delete(h, ce); /* actually purge it */

done:
return retval;
done:
return retval;
}

/*! Get clixon per datastore stats
Expand All @@ -325,7 +326,6 @@ clixon_stats_datastore_get(clicon_handle h,
cxobj *xn = NULL;

/* This is the db cache */

if ((xt = xmldb_cache_get(h, dbname)) == NULL){
/* Trigger cache if no exist */
if (xmldb_get(h, dbname, NULL, "/", &xn) < 0)
Expand Down Expand Up @@ -1604,7 +1604,6 @@ from_client_msg(clicon_handle h,
}

if (strcmp(rpcname, "rpc") == 0){
ce->ce_in_rpcs++; /* Track all RPCs */
}
else if (strcmp(rpcname, "hello") == 0){
if ((ret = from_client_hello(h, x, ce, cbret)) <0)
Expand All @@ -1614,23 +1613,31 @@ from_client_msg(clicon_handle h,
else{
if (netconf_unknown_element(cbret, "protocol", rpcname, "Unrecognized netconf operation")< 0)
goto done;
ce->ce_in_bad_rpcs++;
ce->ce_in_bad_rpcs++;
ce->ce_out_rpc_errors++; /* Number of <rpc-reply> messages sent that contained an <rpc-error> */
netconf_monitoring_counter_inc(h, "in-bad-rpcs");
netconf_monitoring_counter_inc(h, "out-rpc-errors");
goto reply;
}
/* As a side-effect, this expands xt with default values according to "report-all"
* This may not be correct, the RFC does not mention expanding default values for
* input RPC
*/
if ((ret = xml_yang_validate_rpc(h, x, 1, &xret)) < 0)
if ((ret = xml_yang_validate_rpc(h, x, 1, &xret)) < 0){
ce->ce_in_bad_rpcs++;
netconf_monitoring_counter_inc(h, "in-bad-rpcs");
goto done;
}
if (ret == 0){
if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0)
goto done;
ce->ce_in_bad_rpcs++;
ce->ce_in_rpcs--; /* Track all RPCs */
netconf_monitoring_counter_inc(h, "in-bad-rpcs");
goto reply;
}
ce->ce_in_rpcs++; /* Track all RPCs */
netconf_monitoring_counter_inc(h, "in-rpcs");

xe = NULL;
username = xml_find_value(x, "username");
/* May be used by callbacks, etc */
Expand All @@ -1641,6 +1648,7 @@ from_client_msg(clicon_handle h,
if (netconf_operation_not_supported(cbret, "protocol", rpc) < 0)
goto done;
ce->ce_out_rpc_errors++;
netconf_monitoring_counter_inc(h, "out-rpc-errors");
goto reply;
}
if ((ymod = ys_module(ye)) == NULL){
Expand Down Expand Up @@ -1669,13 +1677,15 @@ from_client_msg(clicon_handle h,
goto done;
if (ret == 0){ /* credentials fail */
ce->ce_out_rpc_errors++;
netconf_monitoring_counter_inc(h, "out-rpc-errors");
goto reply;
}
/* NACM rpc operation exec validation */
if ((ret = nacm_rpc(rpc, module, username, xnacm, cbret)) < 0)
goto done;
if (ret == 0){ /* Not permitted and cbret set */
ce->ce_out_rpc_errors++;
netconf_monitoring_counter_inc(h, "out-rpc-errors");
goto reply;
}
}
Expand All @@ -1685,16 +1695,19 @@ from_client_msg(clicon_handle h,
goto done;
clicon_log(LOG_NOTICE, "%s Error in rpc_callback_call:%s", __FUNCTION__, xml_name(xe));
ce->ce_out_rpc_errors++;
netconf_monitoring_counter_inc(h, "out-rpc-errors");
goto reply; /* Dont quit here on user callbacks */
}
if (ret == 0){
ce->ce_out_rpc_errors++;
netconf_monitoring_counter_inc(h, "out-rpc-errors");
goto reply;
}
if (nr == 0){ /* not handled by callback */
if (netconf_operation_not_supported(cbret, "application", "RPC operation not supported")< 0)
goto done;
ce->ce_out_rpc_errors++;
netconf_monitoring_counter_inc(h, "out-rpc-errors");
goto reply;
}
if (xnacm){
Expand Down Expand Up @@ -1775,8 +1788,10 @@ from_client(int s,
}
if (clicon_msg_rcv(ce->ce_s, &msg, &eof) < 0)
goto done;
if (eof)
if (eof){
backend_client_rm(h, ce);
netconf_monitoring_counter_inc(h, "dropped-sessions");
}
else
if (from_client_msg(h, ce, msg) < 0)
goto done;
Expand Down
1 change: 1 addition & 0 deletions apps/backend/backend_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct client_entry{
uint32_t ce_in_rpcs ; /* Number of correct <rpc> messages received. */
uint32_t ce_in_bad_rpcs; /* Not correct <rpc> messages */
uint32_t ce_out_rpc_errors; /* <rpc-error> messages*/
uint32_t ce_out_notifications; /* Outgoing notifications */
};

/*
Expand Down
16 changes: 8 additions & 8 deletions apps/backend/backend_get.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ restconf_client_get_capabilities(clicon_handle h,
* @param[in] module Name of yang module
* @param[in] top Top symbol, ie netconf or restconf-state
* @param[in,out] xret Existing XML tree, merge x into this
* @retval -1 Error (fatal)
* @retval 0 Statedata callback failed
* @retval 1 OK
* @retval 0 Statedata callback failed
* @retval -1 Error (fatal)
*/
static int
client_get_streams(clicon_handle h,
Expand Down Expand Up @@ -182,9 +182,9 @@ client_get_streams(clicon_handle h,
* @param[in] nsc XML Namespace context for xpath
* @param[in] wdef With-defaults parameter, see RFC 6243
* @param[in,out] xret Existing XML tree, merge x into this, or rpc-error
* @retval -1 Error (fatal)
* @retval 0 Statedata callback failed (error in xret)
* @retval 1 OK
* @retval 0 Statedata callback failed (error in xret)
* @retval -1 Error (fatal)
* @note This code in general does not look at xpath, needs to be filtered in retrospect
* @note Awkward error handling. Even if most of this is during development phase, except for plugin
* state callbacks.
Expand Down Expand Up @@ -497,9 +497,9 @@ get_nacm_and_reply(clicon_handle h,
* @param[in] defaultstr Default string which is accepted and sets value to 0
* @param[in,out] cbret Output buffer for internal bad-element RPC message if invalid
* @param[out] value Value
* @retval -1 Error
* @retval 0 Invalid, netconf bad-element error cbret set
* @retval 1 OK (or not found)
* @retval 0 Invalid, netconf bad-element error cbret set
* @retval -1 Error
*/
static int
element2value(clicon_handle h,
Expand Down Expand Up @@ -527,9 +527,9 @@ element2value(clicon_handle h,
* @param[out] offset Number of entries in the working result-set that should be skipped
* @param[out] limit Limits the number of entries returned from the working result-set
* @param[out] cbret Return xml tree, eg <rpc-reply>..., <rpc-error..
* @retval -1 Error
* @retval 0 Invalid, netconf bad-element error cbret set
* @retval 1 OK
* @retval 0 Invalid, netconf bad-element error cbret set
* @retval -1 Error
*/
static int
list_pagination_hdr(clicon_handle h,
Expand Down
2 changes: 2 additions & 0 deletions apps/backend/backend_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,8 @@ main(int argc,
if (stream_timer_setup(0, h) < 0)
goto done;
/* Just before event-loop, after socket bind/listen */
if (netconf_monitoring_statistics_init(h) < 0)
goto done;
clicon_log(LOG_NOTICE, "%s: %u Started", __PROGRAM__, getpid());
if (clixon_event_loop(h) < 0)
goto done;
Expand Down
1 change: 1 addition & 0 deletions apps/backend/clixon_backend_handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ backend_client_add(clicon_handle h,
}
clicon_session_id_set(h, ce->ce_id + 1);
gettimeofday(&ce->ce_time, NULL);
netconf_monitoring_counter_inc(h, "in-sessions");
bh->bh_ce_list = ce;
return ce;
}
Expand Down
2 changes: 2 additions & 0 deletions lib/clixon/clixon_netconf_monitoring.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,7 @@
* Prototypes
*/
int netconf_monitoring_state_get(clicon_handle h, yang_stmt *yspec, char *xpath, cvec *nsc, cxobj **xret, cxobj **xerr);
int netconf_monitoring_statistics_init(clicon_handle h);
int netconf_monitoring_counter_inc(clicon_handle h, char *name);

#endif /* _CLIXON_NETCONF_MONITORING_H_ */
2 changes: 1 addition & 1 deletion lib/src/clixon_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ clicon_data_get(clicon_handle h,
/*! Set generic clixon data on the form <name>=<val> where <val> is string
* @param[in] h Clicon handle
* @param[in] name Data name
* @param[in] val Data value as null-terminated string
* @param[in] val Data value as null-terminated string (copied)
* @retval 0 OK
* @retval -1 Error
* @see clicon_option_str_set
Expand Down
Loading

0 comments on commit 6681eb9

Please sign in to comment.