diff options
| author | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2020-08-18 17:00:33 -0300 | 
|---|---|---|
| committer | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2020-11-24 07:54:07 -0300 | 
| commit | 400632a9a2edbdac79befb5574480db661f33213 (patch) | |
| tree | 8202fa8ee0857f701e4439a64b2f5d82bbc710a1 /bfdd/dplane.c | |
| parent | efd04d60caa237de5c564355089c59794057ff1d (diff) | |
bfdd: distributed BFD show commands
Show BFD sessions updated counters by asking the data plane for this
information and show data plane statistics.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to 'bfdd/dplane.c')
| -rw-r--r-- | bfdd/dplane.c | 118 | 
1 files changed, 118 insertions, 0 deletions
diff --git a/bfdd/dplane.c b/bfdd/dplane.c index 5785c349c1..f68fd2cb26 100644 --- a/bfdd/dplane.c +++ b/bfdd/dplane.c @@ -244,6 +244,24 @@ static void bfd_dplane_debug_message(const struct bfddp_message *msg)  	}  } +/** + * Gets the next unused non zero identification. + * + * \param bdc the data plane context. + * + * \returns next usable id. + */ +static uint16_t bfd_dplane_next_id(struct bfd_dplane_ctx *bdc) +{ +	bdc->last_id++; + +	/* Don't use reserved id `0`. */ +	if (bdc->last_id == 0) +		bdc->last_id = 1; + +	return bdc->last_id; +} +  static ssize_t bfd_dplane_flush(struct bfd_dplane_ctx *bdc)  {  	ssize_t total = 0; @@ -717,6 +735,52 @@ static int _bfd_dplane_add_session(struct bfd_dplane_ctx *bdc,  	return rv;  } +static void _bfd_dplane_update_session_counters(struct bfddp_message *msg, +						void *arg) +{ +	struct bfd_session *bs = arg; + +	bs->stats.rx_ctrl_pkt = +		be64toh(msg->data.session_counters.control_input_packets); +	bs->stats.tx_ctrl_pkt = +		be64toh(msg->data.session_counters.control_output_packets); +	bs->stats.rx_echo_pkt = +		be64toh(msg->data.session_counters.echo_input_packets); +	bs->stats.tx_echo_pkt = +		be64toh(msg->data.session_counters.echo_output_bytes); +} + +/** + * Send message to data plane requesting the session counters. + * + * \param bs the BFD session. + * + * \returns `0` on failure or the request id. + */ +static uint16_t bfd_dplane_request_counters(const struct bfd_session *bs) +{ +	struct bfddp_message msg = {}; +	size_t msglen = sizeof(msg.header) + sizeof(msg.data.counters_req); + +	/* Fill header information. */ +	msg.header.version = BFD_DP_VERSION; +	msg.header.length = htons(msglen); +	msg.header.type = htons(DP_REQUEST_SESSION_COUNTERS); +	msg.header.id = htons(bfd_dplane_next_id(bs->bdc)); + +	/* Session to get counters. */ +	msg.data.counters_req.lid = htonl(bs->discrs.my_discr); + +	/* If enqueue failed, let caller know. */ +	if (bfd_dplane_enqueue(bs->bdc, &msg, msglen) == -1) +		return 0; + +	/* Flush socket. */ +	bfd_dplane_flush(bs->bdc); + +	return ntohs(msg.header.id); +} +  /*   * Data plane listening socket.   */ @@ -876,3 +940,57 @@ int bfd_dplane_delete_session(struct bfd_session *bs)  	return rv;  } + +/* + * Data plane CLI. + */ +void bfd_dplane_show_counters(struct vty *vty) +{ +	struct bfd_dplane_ctx *bdc; + +#define SHOW_COUNTER(label, counter, formatter)                                \ +	vty_out(vty, "%28s: %" formatter "\n", (label), (counter)) + +	vty_out(vty, "%28s\n%28s\n", "Data plane", "=========="); +	TAILQ_FOREACH (bdc, &bglobal.bg_dplaneq, entry) { +		SHOW_COUNTER("File descriptor", bdc->sock, "d"); +		SHOW_COUNTER("Input bytes", bdc->in_bytes, PRIu64); +		SHOW_COUNTER("Input bytes peak", bdc->in_bytes_peak, PRIu64); +		SHOW_COUNTER("Input messages", bdc->in_msgs, PRIu64); +		SHOW_COUNTER("Input current usage", STREAM_READABLE(bdc->inbuf), +			     "zu"); +		SHOW_COUNTER("Output bytes", bdc->out_bytes, PRIu64); +		SHOW_COUNTER("Output bytes peak", bdc->out_bytes_peak, PRIu64); +		SHOW_COUNTER("Output messages", bdc->out_msgs, PRIu64); +		SHOW_COUNTER("Output full events", bdc->out_fullev, PRIu64); +		SHOW_COUNTER("Output current usage", +			     STREAM_READABLE(bdc->inbuf), "zu"); +		vty_out(vty, "\n"); +	} +#undef SHOW_COUNTER +} + +int bfd_dplane_update_session_counters(struct bfd_session *bs) +{ +	uint16_t id; +	int rv; + +	/* If session is not using data plane, then just return success. */ +	if (bs->bdc == NULL) +		return 0; + +	/* Make the request. */ +	id = bfd_dplane_request_counters(bs); +	if (id == 0) { +		zlog_debug("%s: counters request failed", __func__); +		return -1; +	} + +	/* Handle interruptions. */ +	do { +		rv = bfd_dplane_expect(bs->bdc, id, +				       _bfd_dplane_update_session_counters, bs); +	} while (rv == -2); + +	return rv; +}  | 
