statd: add ethtool frame counters to op datastore

This patch adds the framework for reading ethtool statistics and
inserting it into the operational datastore.

The ethtool data we rely on is "group data" such as "eth-mac" or
"rmon".

This data can be displayed using:
ethtool --json -S e0 --all-groups

The "group data" is still missing for most common drivers, so testing
this will require a firmware which has support for it.

Signed-off-by: Richard Alpe <richard@bit42.se>
This commit is contained in:
Richard Alpe
2023-10-17 18:17:54 +02:00
committed by Joachim Wiberg
parent 9292231674
commit 14dc3cf8a0
8 changed files with 1082 additions and 12 deletions
+1
View File
@@ -162,6 +162,7 @@ sysrepoctl -s $SEARCH \
-i infix-shell-type@2023-08-21.yang -g wheel -p 0660 \
-i infix-system@2023-08-15.yang -g wheel -p 0660 \
-i infix-services@2023-10-16.yang -g wheel -p 0660 \
-i ieee802-ethernet-interface@2019-06-21.yang -g wheel -p 0660 \
-I "${INIT_DATA}"
rc=$?
@@ -0,0 +1,928 @@
module ieee802-ethernet-interface {
yang-version 1.1;
namespace
"urn:ieee:std:802.3:yang:ieee802-ethernet-interface";
prefix ieee802-eth-if;
import ietf-yang-types {
prefix yang;
reference "IETF RFC 6991";
}
import ietf-interfaces {
prefix if;
reference "IETF RFC 8343";
}
import iana-if-type {
prefix ianaift;
reference "http://www.iana.org/assignments/yang-parameters/
iana-if-type@2018-07-03.yang";
}
organization
"IEEE Std 802.3 Ethernet Working Group
Web URL: http://www.ieee802.org/3/";
contact
"Web URL: http://www.ieee802.org/3/";
description
"This module contains YANG definitions for configuring IEEE Std
802.3 Ethernet Interfaces.
In this YANG module, 'Ethernet interface' can be interpreted
as referring to 'IEEE Std 802.3 compliant Ethernet
interfaces'.";
revision 2019-06-21{
description "Initial revision.";
reference "IEEE Std 802.3-2018, unless dated explicitly";
}
typedef eth-if-speed-type {
type decimal64 {
fraction-digits 3;
}
units "Gb/s";
description
"Used to represent the configured, negotiated, or actual speed
of an Ethernet interface in Gigabits per second (Gb/s),
accurate to 3 decimal places (i.e., accurate to 1 Mb/s).";
}
typedef duplex-type {
type enumeration {
enum full {
description
"Full duplex.";
}
enum half {
description
"Half duplex.";
}
enum unknown {
description
"Link is currently disconnected or initializing.";
}
}
default full;
description
"Used to represent the configured, negotiated, or actual
duplex mode of an Ethernet interface.";
reference "IEEE Std 802.3, 30.3.1.1.32, aDuplexStatus";
}
typedef pause-fc-direction-type {
type enumeration {
enum "disabled" {
description
"Flow-control disabled in both ingress and egress
directions, i.e., PAUSE frames are not transmitted and
PAUSE frames received in the ingress direction are
discarded without processing.";
}
enum "ingress-only" {
description
"PAUSE frame based flow control is enabled in the ingress
direction only, i.e., PAUSE frames may be transmitted to
reduce the ingress traffic flow, but PAUSE frames received
in the ingress direction are discarded without reducing
the egress traffic rate.";
}
enum "egress-only" {
description
"PAUSE frame based flow control is enabled in the egress
direction only, i.e., PAUSE frames are not transmitted,
but PAUSE frames received in the ingress direction are
processed to reduce the egress traffic rate.";
}
enum "bi-directional" {
description
"PAUSE frame based flow control is enabled in both ingress
and egress directions, i.e., PAUSE frames may be
transmitted to reduce the ingress traffic flow, and
PAUSE frames received on ingress are processed to reduce
the egress traffic rate.";
}
enum "undefined" {
description
"Link is currently disconnected or initializing.";
}
}
description
"Used to represent the configured, negotiated, or actual
PAUSE frame-based flow control setting.";
reference
"IEEE Std 802.3.1, dot3PauseAdminMode and dot3PauseOperMode";
}
feature ethernet-pfc {
description
"This device supports Ethernet priority flow-control.";
}
feature ethernet-pause {
description
"This device supports Ethernet PAUSE.";
}
augment "/if:interfaces/if:interface" {
when "derived-from-or-self(if:type, 'ianaift:ethernetCsmacd')" {
description
"Applies to all P2P Ethernet interfaces.";
}
description
"Augment interface model with Ethernet interface
specific configuration nodes.";
container ethernet {
description
"Contains all Ethernet interface related configuration.";
container auto-negotiation {
presence
"The presence of this container indicates that
auto-negotiation is supported on this Ethernet
interface.";
description
"Contains auto-negotiation transmission parameters
This container contains a data node that allows the
advertised duplex value in the negotiation to be
restricted.
If not specified then the default behavior for the duplex
data node is to negotiate all available values for the
particular type of Ethernet PHY associated with the
interface.
If auto-negotiation is enabled, and PAUSE frame based flow
control has not been explicitly configured, then the
default PAUSE frame based flow control capabilities that
are negotiated allow for bi-directional or egress-only
PAUSE frame based flow control.
If auto-negotiation is enabled, and PAUSE frame based flow
control has been explicitly configured, then the
configuration settings restrict the values that may be
negotiated. However, it should be noted that the protocol
does not allow only egress PAUSE frame based flow control
to be negotiated without also allowing bi-directional
PAUSE frame based flow control.";
reference
"IEEE Std 802.3, Clause 28 and Annexes 28A-D";
leaf enable {
type boolean;
default true;
description
"Controls whether auto-negotiation is enabled or
disabled.
For interface types that support auto-negotiation then
it defaults to being enabled.
For interface types that do not support auto-negotiation,
the related configuration data is ignored.";
}
leaf negotiation-status {
when "../enable = 'true'";
type enumeration {
enum in-progress {
description
"The auto-negotiation protocol is running and
negotiation is currently in-progress.";
}
enum complete {
description
"The auto-negotiation protocol has completed
successfully.";
}
enum failed {
description
"The auto-negotiation protocol has failed.";
}
enum unknown {
description
"The auto-negotiation status is not currently known,
this could be because it is still negotiating or the
protocol cannot run (e.g., if no medium is present).";
}
enum no-negotiation {
description
"No auto-negotiation is executed.
The auto-negotation function is either not supported
on this interface or has not been enabled.";
}
}
config false;
description
"The status of the auto-negotiation protocol.";
reference
"IEEE 802.3, 30.6.1.1.4, aAutoNegAutoConfig";
}
}
leaf duplex {
type duplex-type;
description
"Operational duplex mode of the Ethernet interface.";
reference
"IEEE Std 802.3, 30.3.1.1.32 aDuplexStatus";
}
leaf speed {
type eth-if-speed-type;
units "Gb/s";
description
"Operational speed (data rate) of the Ethernet interface.
The default value is implementation-dependent.";
}
container flow-control {
description
"Holds the different types of Ethernet PAUSE frame based
flow control that can be enabled.";
container pause {
if-feature "ethernet-pause";
description
"IEEE Std 802.3 PAUSE frame based PAUSE frame based flow
control.";
reference
"IEEE Std 802.3, Annex 31B";
leaf direction {
type pause-fc-direction-type;
description
"Indicates which direction PAUSE frame based flow
control is enabled in, or whether it is disabled.
The default flow-control settings are vendor specific.
If auto-negotiation is enabled, then PAUSE based
flow-control is negotiated by default.
The default value is implementation-dependent.";
}
container statistics {
config false;
description
"Contains the number of PAUSE frames received or
transmitted.";
leaf in-frames-pause {
type yang:counter64;
units frames;
description
"A count of PAUSE MAC Control frames transmitted on
this Ethernet interface.
Discontinuities in the values of counters in
this container can occur at re-initialization of the
management system, and at other times as indicated
by the value of the 'discontinuity-time' leaf
defined in the ietf-interfaces YANG module
(IETF RFC 8343).";
reference
"IEEE Std 802.3, 30.3.4.3 aPAUSEMACCtrlFramesReceived";
}
leaf out-frames-pause {
type yang:counter64;
units frames;
description
"A count of PAUSE MAC Control frames transmitted on
this Ethernet interface.
Discontinuities in the values of counters in
this container can occur at re-initialization of the
management system, and at other times as indicated
by the value of the 'discontinuity-time' leaf
defined in the ietf-interfaces YANG module
(IETF RFC 8343).";
reference
"IEEE Std 802.3, 30.3.4.2
aPAUSEMACCtrlFramesTransmitted";
}
}
}
container pfc {
if-feature "ethernet-pfc";
description
"IEEE Std 802.3 Priority-based flow control.";
reference
"IEEE Std 802.3, Annex 31D";
leaf enable {
type boolean;
description
"True indicates that IEEE Std 802.3 priority-based
flow control is enabled, false indicates that
IEEE Std 802.3 priority-based flow control is disabled.
For interfaces that have auto-negotiation,
the priority-based flow control is enabled by default.";
}
container statistics {
config false;
description
"This container collects all statistics for
Ethernet interfaces.";
leaf in-frames-pfc {
type yang:counter64;
units frames;
description
"A count of PFC MAC Control frames received on this
Ethernet interface.
Discontinuities in the values of counters in
this container can occur at re-initialization of the
management system, and at other times as indicated
by the value of the 'discontinuity-time' leaf
defined in the ietf-interfaces YANG module
(IETF RFC 8343).";
reference
"IEEE Std 802.3.1, dot3HCInPFCFrames";
}
leaf out-frames-pfc {
type yang:counter64;
units frames;
description
"A count of PFC MAC Control frames transmitted on
this interface.
Discontinuities in the values of counters in
this container can occur at re-initialization of the
management system, and at other times as indicated
by the value of the 'discontinuity-time' leaf
defined in the ietf-interfaces YANG module
(IETF RFC 8343).";
reference
"IEEE Std 802.3.1, dot3HCInPFCFrames";
}
}
}
leaf force-flow-control {
type boolean;
default false;
description
"Explicitly forces the local PAUSE frame based flow control
settings regardless of what has been negotiated.
Since the auto-negotiation of flow-control settings
does not allow all sane combinations to be negotiated
(e.g., consider a device that is only capable of sending
PAUSE frames connected to a peer device that is only
capable of receiving and acting on PAUSE frames) and
failing to agree on the flow-control settings does not
cause the auto-negotiation to fail completely, then it is
sometimes useful to be able to explicitly enable
particular PAUSE frame based flow control settings on
the local device regardless of what is being advertised
or negotiated.";
reference
"IEEE Std 802.3, Table 28B-3";
}
}
leaf max-frame-length {
type uint16;
units octets;
config false;
description
"This indicates the MAC frame length (including FCS bytes)
at which frames are dropped for being too long.";
reference
"IEEE Std 802.3, 30.3.1.1.37 aMaxFrameLength";
}
leaf mac-control-extension-control {
type boolean;
config false;
description
"A value that identifies the current EXTENSION MAC Control
function, as specified in IEEE Std 802.3, Annex 31C.";
reference
"IEEE Std 802.3, 30.3.8.3 aEXTENSIONMACCtrlStatus
IEEE Std 802.3.1, dot3ExtensionMacCtrlStatus ";
}
leaf frame-limit-slow-protocol {
type uint64;
units f/s;
default 10;
config false;
description
"The maximum number of Slow Protocol frames of a given
subtype that can be transmitted in a one second interval.
The default value is 10.";
reference
"IEEE Std 802.3, 30.3.1.1.38 aSlowProtocolFrameLimit";
}
container capabilities {
config false;
description
"Container all Ethernet interface specific capabilities.";
leaf auto-negotiation {
type boolean;
description
"Indicates whether auto-negotiation may be configured on
this interface.";
}
}
container statistics {
config false;
description
"Contains statistics specific to Ethernet interfaces.
Discontinuities in the values of counters in the
container can occur at re-initialization of the management
system, and at other times as indicated by the value of
the 'discontinuity-time' leaf defined in the
ietf-interfaces YANG module (IETF RFC 8343).";
container frame {
description
"Contains frame statistics specific to Ethernet
interfaces.
All octet frame lengths include the 4 byte FCS.
Error counters are only reported once ... The count
represented by an instance of this object is incremented
when the frameCheckError status is returned by the MAC
service to the LLC (or other MAC user). Received frames
for which multiple error conditions pertain are,
according to the conventions of IEEE Std 802.3 Layer
Management, counted exclusively according to the error
status presented to the LLC.
A frame that is counted by an instance of this object is
also counted by the corresponding instance of 'in-errors'
leaf defined in the ietf-interfaces YANG module
(IETF RFC 8343).
Discontinuities in the values of counters in the
container can occur at re-initialization of the
management system, and at other times as indicated by
the value of the 'discontinuity-time' leaf defined in
the ietf-interfaces YANG module (IETF RFC 8343).";
leaf in-total-frames {
type yang:counter64;
units frames;
description
"The total number of frames (including bad frames)
received on the Ethernet interface.
This counter is calculated by summing the following
IEEE Std 802.3, Clause 30 counters:
aFramesReceivedOK +
aFrameCheckSequenceErrors +
aAlignmentErrors +
aFrameTooLongErrors +
aFramesLostDueToIntMACRcvError
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, Clause 30 counters, as specified
in the description above.";
}
leaf in-total-octets {
type yang:counter64;
units octets;
description
"The total number of octets of data (including those in
bad frames) received on the Ethernet interface.
Includes the 4-octet FCS.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IETF RFC 2819, etherStatsOctets";
}
leaf in-frames {
type yang:counter64;
units frames;
description
"A count of frames (including unicast, multicast and
broadcast) that have been successfully received on the
Ethernet interface.
This count does not include frames received with
frame-too-long, FCS, length or alignment errors, or
frames lost due to internal MAC sublayer error.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.1.1.5 aFramesReceivedOK";
}
leaf in-multicast-frames {
type yang:counter64;
units frames;
description
"A count of multicast frames that have been
successfully received on the Ethernet interface.
This counter represents a subset of the frames counted
by in-frames.
This count does not include frames received with
frame-too-long, FCS, length or alignment errors, or
frames lost due to internal MAC sublayer error.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.1.1.21 aMulticastFramesReceivedOK";
}
leaf in-broadcast-frames {
type yang:counter64;
units frames;
description
"A count of broadcast frames that have been
successfully received on the Ethernet interface.
This counter represents a subset of the frames counted
by in-frames.
This count does not include frames received with
frame-too-long, FCS, length or alignment errors, or
frames lost due to internal MAC sublayer error.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.1.1.22 aBroadcastFramesReceivedOK";
}
leaf in-error-fcs-frames {
type yang:counter64;
units frames;
description
"A count of receive frames that are of valid length,
but do not pass the FCS check, regardless of whether
or not the frames are an integral number of octets in
length.
This count effectively comprises
aFrameCheckSequenceErrors and aAlignmentErrors added
together.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.1.1.6 aFrameCheckSequenceErrors;
IEEE Std 802.3, 30.3.1.1.7 aAlignmentErrors";
}
leaf in-error-undersize-frames {
type yang:counter64;
units frames;
description
"A count of frames received on a particular Ethernet
interface that are less than 64 bytes in length, and
are discarded.
This counter is incremented regardless of whether the
frame passes the FCS check.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IETF RFC 2819, etherStatsUndersizePkts and
etherStatsFragments";
}
leaf in-error-oversize-frames {
type yang:counter64;
units frames;
description
"A count of frames received on a particular Ethernet
interface that exceed the maximum permitted frame
size, that is specified in max-frame-length, and are
discarded.
This counter is incremented regardless of whether the
frame passes the FCS check.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference "IEEE Std 802.3, 30.3.1.1.25 aFrameTooLongErrors";
}
leaf in-error-mac-internal-frames {
type yang:counter64;
units frames;
description
"A count of frames for which reception on a particular
Ethernet interface fails due to an internal MAC
sublayer receive error.
A frame is only counted by an instance of this object
if it is not counted by the corresponding instance of
either the in-error-fcs-frames, in-error-undersize-frames,
or in-error-oversize-frames. The precise meaning of the
count represented by an instance of this object is
implementation-specific.
In particular, an instance of this object may
represent a count of receive errors on a particular
Ethernet interface that are not otherwise counted.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.1.1.15
aFramesLostDueToIntMACRcvError";
}
leaf out-frames {
type yang:counter64;
units frames;
description
"A count of frames (including unicast, multicast and
broadcast) that have been successfully transmitted on
the Ethernet interface.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.1.1.2 aFramesTransmittedOK";
}
leaf out-multicast-frames {
type yang:counter64;
units frames;
description
"A count of multicast frames that have been
successfully transmitted on the Ethernet interface.
This counter represents a subset of the frames counted
by out-frames.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.1.1.18 aMulticastFramesXmittedOK";
}
leaf out-broadcast-frames {
type yang:counter64;
units frames;
description
"A count of broadcast frames that have been
successfully transmitted on the Ethernet interface.
This counter represents a subset of the frames counted
by out-frames.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.1.1.19 aBroadcastFramesXmittedOK";
}
leaf out-error-mac-internal-frames {
type yang:counter64;
units frames;
description
"A count of frames for which transmission on a
particular Ethernet interface fails due to an internal
MAC sublayer transmit error.
The precise meaning of the count represented by an
instance of this object is implementation-specific. In
particular, an instance of this object may represent a
count of transmission errors on a particular Ethernet
interface that are not otherwise counted.
Also see the 'description' statement associated with
the parent 'statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.1.1.12
aFramesLostDueToIntMACXmitError";
}
}
container phy {
description
"Ethernet statistics related to the PHY layer.
Discontinuities in the values of counters in the
container can occur at re-initialization of the
management system, and at other times as indicated by
the value of the 'discontinuity-time' leaf defined in
the ietf-interfaces YANG module (IETF RFC 8343).";
leaf in-error-symbol {
type yang:counter64;
units errors;
description
"A count of the number of symbol errors that have
occurred.
For the precise definition of when the symbol error
counter is incremented, please see the 'description'
text associated with aSymbolErrorDuringCarrier,
specified in IEEE Std 802.3, 30.3.2.1.5.
Also see the 'description' statement associated with
the parent 'phy-statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.2.1.5 aSymbolErrorDuringCarrier";
}
container lpi {
description
"Physical Ethernet statistics for the energy efficiency
related low power idle indications.";
leaf in-lpi-transitions {
type yang:counter64;
units transitions;
description
"A count of occurrences of the transition from
DEASSERT to ASSERT of the LPI_INDICATE
parameter. The indication reflects the state of the
PHY according to the requirements of the RS (see
IEEE Std 802.3, 22.7, 35.4, and 46.4).
Also see the 'description' statement associated with
the parent 'phy-statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.2.1.11 aReceiveLPITransitions";
}
leaf in-lpi-time {
type decimal64 {
fraction-digits 6;
}
units seconds;
description
"A count reflecting the total amount of time (in
seconds) that the LPI_REQUEST parameter has the
value ASSERT. The request is indicated to the PHY
according to the requirements of the RS (see IEEE Std
802.3, 22.7, 35.4, and 46.4).
Also see the 'description' statement associated with
the parent 'phy-statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.2.1.9 aReceiveLPIMicroseconds";
}
leaf out-lpi-transitions {
type yang:counter64;
units transitions;
description
"A count of occurrences of the transition from state
LPI_DEASSERTED to state LPI_ASSERTED in the LPI
transmit state diagram of the RS. The state
transition corresponds to the assertion of the
LPI_REQUEST parameter. The request is indicated to
the PHY according to the requirements of the RS (see
IEEE Std 802.3, 22.7, 35.4, 46.4.)
Also see the 'description' statement associated with
the parent 'phy-statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.2.1.10 aTransmitLPITransitions";
}
leaf out-lpi-time {
type decimal64 {
fraction-digits 6;
}
units seconds;
description
"A count reflecting the total amount of time (in
seconds) that the LPI_INDICATION parameter has the
value ASSERT. The request is indicated to the PHY
according to the requirements of the RS (see IEEE
802.3, 22.7, 35.4, and 46.4).
Also see the 'description' statement associated with
the parent 'phy-statistics' container for additional
common semantics related to this counter.";
reference
"IEEE Std 802.3, 30.3.2.1.8 aTransmitLPIMicroseconds";
}
}
}
container mac-control {
description
"A group of statistics specific to MAC Control operation
of selected Ethernet interfaces.
Discontinuities in the values of counters in the
container can occur at re-initialization of the
management system, and at other times as indicated by
the value of the 'discontinuity-time' leaf defined in
the ietf-interfaces YANG module (IETF RFC 8343).";
reference
"IEEE Std 802.3.1, dot3ExtensionTable";
leaf in-frames-mac-control-unknown {
type yang:counter64;
units frames;
description
"A count of MAC Control frames with an unsupported
opcode received on this Ethernet interface.
Frames counted against this counter are also counted
against in-discards defined in the ietf-interfaces
YANG module (IETF RFC 8343).
Also see the 'description' statement associated with
the parent 'mac-control-statistics' container for
additional semantics.";
reference
"IEEE Std 802.3, 30.3.3.5 aUnsupportedOpcodesReceived";
}
leaf in-frames-mac-control-extension {
type yang:counter64;
units frames;
description
"The count of Extension MAC Control frames received on
this Ethernet interface.
Also see the 'description' statement associated with
the parent 'mac-control-statistics' container for
additional semantics.";
reference
"IEEE Std 802.3, 30.3.8.2
aEXTENSIONMACCtrlFramesReceived";
}
leaf out-frames-mac-control-extension {
type yang:counter64;
units frames;
description
"The count of Extension MAC Control frames transmitted
on this Ethernet interface.
Also see the 'description' statement associated with
the parent 'mac-control-statistics' container for
additional semantics.";
reference
"IEEE Std 802.3, 30.3.8.1
aEXTENSIONMACCtrlFramesTransmitted";
}
}
}
}
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ LDLIBS += -lsysrepo -lev -lyang -ljansson -lite -lsrx
TARGET = statd
SRC = statd.c shared.c shared.h \
iface-ip-link.c iface-ip-link.h \
iface-ip-addr.c iface-ip-addr.h
iface-ip-addr.c iface-ip-addr.h \
iface-ethtool.c iface-ethtool.h
all: $(TARGET)
+128
View File
@@ -0,0 +1,128 @@
#include <stdio.h>
#include <stdlib.h>
#include <jansson.h>
#include <srx/lyx.h>
#include <srx/common.h>
#include <srx/helpers.h>
#include "shared.h"
static json_t *json_get_ethtool(const char *ifname)
{
char cmd[512] = {}; /* Size is arbitrary */
snprintf(cmd, sizeof(cmd), "ethtool --json -S %s --all-groups 2>/dev/null", ifname);
return json_get_output(cmd);
}
static int ly_add_eth_stats(const struct ly_ctx *ctx, struct lyd_node **parent,
const char *ifname, json_t *j_iface)
{
struct {
const char *ethtool;
char *yang;
} map[] = {
{"FramesTransmittedOK", "out-frames"},
{"FramesReceivedOK", "in-frames"},
};
json_t *j_mac;
json_t *j_val;
char xpath_base[XPATH_BASE_MAX] = {};
char xpath[XPATH_MAX] = {};
struct lyd_node *frame_node = NULL;
struct lyd_node *stat_node = NULL;
struct lyd_node *eth_node = NULL;
size_t i;
int err;
j_mac = json_object_get(j_iface, "eth-mac");
if (!j_mac)
return SR_ERR_OK;
snprintf(xpath_base, sizeof(xpath_base),
"%s/interface[name='%s']/ieee802-ethernet-interface:ethernet",
XPATH_IFACE_BASE, ifname);
err = lyd_new_path(*parent, ctx, xpath_base, NULL, 0, &eth_node);
if (err) {
ERROR("Failed adding 'eth' node (%s), libyang error %d: %s",
xpath_base, err, ly_errmsg(ctx));
return SR_ERR_LY;
}
snprintf(xpath, sizeof(xpath), "%s/statistics", xpath_base);
err = lyd_new_path(eth_node, ctx, xpath, NULL, 0, &stat_node);
if (err) {
ERROR("Failed adding 'stat' node (%s), libyang error %d: %s",
xpath, err, ly_errmsg(ctx));
return SR_ERR_LY;
}
snprintf(xpath, sizeof(xpath), "%s/statistics/frame", xpath_base);
err = lyd_new_path(stat_node, ctx, xpath, NULL, 0, &frame_node);
if (err) {
ERROR("Failed adding 'frame' node (%s), libyang error %d: %s",
xpath, err, ly_errmsg(ctx));
return SR_ERR_LY;
}
for (i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
j_val = json_object_get(j_mac, map[i].ethtool);
if (!j_val)
continue;
if (!json_is_integer(j_val)) {
ERROR("Error, expecting integer value for '%s'\n", map[i].ethtool);
return SR_ERR_SYS;
}
err = lydx_new_path(ctx, &frame_node, xpath, map[i].yang,
"%lld", json_integer_value(j_val));
if (err) {
ERROR("Error, adding ethtool '%s' to data tree, libyang error %d",
map[i].yang, err);
return SR_ERR_LY;
}
}
return SR_ERR_OK;
}
int ly_add_ethtool(const struct ly_ctx *ctx, struct lyd_node **parent, char *ifname)
{
json_t *j_iface;
json_t *j_root;
int err;
j_root = json_get_ethtool(ifname);
if (!j_root) {
ERROR("Error, parsing ethtool JSON");
return SR_ERR_SYS;
}
if (json_array_size(j_root) != 1) {
ERROR("Error, expected JSON array of single iface");
json_decref(j_root);
return SR_ERR_SYS;
}
j_iface = json_array_get(j_root, 0);
if (!j_iface) {
ERROR("Error, getting JSON interface");
json_decref(j_root);
return SR_ERR_SYS;
}
err = ly_add_eth_stats(ctx, parent, ifname, j_iface);
if (err) {
ERROR("Error, adding ethtool statistics data");
json_decref(j_root);
return err;
}
json_decref(j_root);
return SR_ERR_OK;
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef STATD_IFACE_ETHTOOL_H_
#define STATD_IFACE_ETHTOOL_H_
#include <srx/lyx.h>
int ly_add_ethtool(const struct ly_ctx *ctx, struct lyd_node **parent, char *ifname);
#endif
+2 -8
View File
@@ -13,20 +13,14 @@ json_t *json_get_output(const char *cmd)
proc = popenf("re", cmd);
if (!proc) {
ERROR("Error, running ip link command");
ERROR("Error, running command %s", cmd);
return NULL;
}
j_root = json_loadf(proc, 0, &j_err);
pclose(proc);
if (!j_root) {
ERROR("Error, parsing ip link JSON");
return NULL;
}
if (!json_is_array(j_root)) {
ERROR("Expected a JSON array from ip link");
json_decref(j_root);
ERROR("Error, parsing command JSON (%s)", cmd);
return NULL;
}
+1
View File
@@ -4,6 +4,7 @@
#include <jansson.h>
#define XPATH_MAX PATH_MAX
#define XPATH_BASE_MAX 2046 /* Size is arbitrary */
#define XPATH_IFACE_BASE "/ietf-interfaces:interfaces"
json_t *json_get_output(const char *cmd);
+12 -3
View File
@@ -25,6 +25,7 @@
#include "shared.h"
#include "iface-ip-link.h"
#include "iface-ip-addr.h"
#include "iface-ethtool.h"
#define SOCK_RMEM_SIZE 1000000 /* Arbitrary chosen, default = 212992 */
#define NL_BUF_SIZE 4096 /* Arbitrary chosen */
@@ -140,13 +141,21 @@ static int sr_ifaces_cb(sr_session_ctx_t *session, uint32_t, const char *path,
}
err = ly_add_ip_link(ctx, parent, sub->ifname);
if (err)
if (err) {
ERROR("Error, adding ip link info");
goto out;
}
err = ly_add_ip_addr(ctx, parent, sub->ifname);
if (err)
ERROR("Error, adding ip link info");
if (err) {
ERROR("Error, adding ip addr info");
goto out;
}
err = ly_add_ethtool(ctx, parent, sub->ifname);
if (err)
ERROR("Error, adding ethtool info");
out:
sr_release_context(con);
return err;