pmc: Add a new TLV to obtain per-port statistics

Add an ability of pmc to query per-port stats added in the previous patch.

Signed-off-by: Petr Machata <petrm@mellanox.com>
master
Petr Machata 2019-09-10 12:24:13 +00:00 committed by Richard Cochran
parent e3f0891996
commit 2b5bec8d27
5 changed files with 76 additions and 0 deletions

47
pmc.c
View File

@ -69,6 +69,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
struct tlv_extra *extra; struct tlv_extra *extra;
struct portDS *p; struct portDS *p;
struct port_ds_np *pnp; struct port_ds_np *pnp;
struct port_stats_np *pcp;
if (msg_type(msg) != MANAGEMENT) { if (msg_type(msg) != MANAGEMENT) {
return; return;
@ -322,6 +323,52 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
pnp->neighborPropDelayThresh, pnp->neighborPropDelayThresh,
pnp->asCapable ? 1 : 0); pnp->asCapable ? 1 : 0);
break; break;
case TLV_PORT_STATS_NP:
pcp = (struct port_stats_np *) mgt->data;
fprintf(fp, "PORT_STATS_NP "
IFMT "portIdentity %s"
IFMT "rx_Sync %" PRIu64
IFMT "rx_Delay_Req %" PRIu64
IFMT "rx_Pdelay_Req %" PRIu64
IFMT "rx_Pdelay_Resp %" PRIu64
IFMT "rx_Follow_Up %" PRIu64
IFMT "rx_Delay_Resp %" PRIu64
IFMT "rx_Pdelay_Resp_Follow_Up %" PRIu64
IFMT "rx_Announce %" PRIu64
IFMT "rx_Signaling %" PRIu64
IFMT "rx_Management %" PRIu64
IFMT "tx_Sync %" PRIu64
IFMT "tx_Delay_Req %" PRIu64
IFMT "tx_Pdelay_Req %" PRIu64
IFMT "tx_Pdelay_Resp %" PRIu64
IFMT "tx_Follow_Up %" PRIu64
IFMT "tx_Delay_Resp %" PRIu64
IFMT "tx_Pdelay_Resp_Follow_Up %" PRIu64
IFMT "tx_Announce %" PRIu64
IFMT "tx_Signaling %" PRIu64
IFMT "tx_Management %" PRIu64,
pid2str(&pcp->portIdentity),
pcp->stats.rxMsgType[SYNC],
pcp->stats.rxMsgType[DELAY_REQ],
pcp->stats.rxMsgType[PDELAY_REQ],
pcp->stats.rxMsgType[PDELAY_RESP],
pcp->stats.rxMsgType[FOLLOW_UP],
pcp->stats.rxMsgType[DELAY_RESP],
pcp->stats.rxMsgType[PDELAY_RESP_FOLLOW_UP],
pcp->stats.rxMsgType[ANNOUNCE],
pcp->stats.rxMsgType[SIGNALING],
pcp->stats.rxMsgType[MANAGEMENT],
pcp->stats.txMsgType[SYNC],
pcp->stats.txMsgType[DELAY_REQ],
pcp->stats.txMsgType[PDELAY_REQ],
pcp->stats.txMsgType[PDELAY_RESP],
pcp->stats.txMsgType[FOLLOW_UP],
pcp->stats.txMsgType[DELAY_RESP],
pcp->stats.txMsgType[PDELAY_RESP_FOLLOW_UP],
pcp->stats.txMsgType[ANNOUNCE],
pcp->stats.txMsgType[SIGNALING],
pcp->stats.txMsgType[MANAGEMENT]);
break;
case TLV_LOG_ANNOUNCE_INTERVAL: case TLV_LOG_ANNOUNCE_INTERVAL:
mtd = (struct management_tlv_datum *) mgt->data; mtd = (struct management_tlv_datum *) mgt->data;
fprintf(fp, "LOG_ANNOUNCE_INTERVAL " fprintf(fp, "LOG_ANNOUNCE_INTERVAL "

View File

@ -120,6 +120,7 @@ struct management_id idtab[] = {
{ "DELAY_MECHANISM", TLV_DELAY_MECHANISM, do_get_action }, { "DELAY_MECHANISM", TLV_DELAY_MECHANISM, do_get_action },
{ "LOG_MIN_PDELAY_REQ_INTERVAL", TLV_LOG_MIN_PDELAY_REQ_INTERVAL, do_get_action }, { "LOG_MIN_PDELAY_REQ_INTERVAL", TLV_LOG_MIN_PDELAY_REQ_INTERVAL, do_get_action },
{ "PORT_DATA_SET_NP", TLV_PORT_DATA_SET_NP, do_set_action }, { "PORT_DATA_SET_NP", TLV_PORT_DATA_SET_NP, do_set_action },
{ "PORT_STATS_NP", TLV_PORT_STATS_NP, do_get_action },
}; };
static void do_get_action(struct pmc *pmc, int action, int index, char *str) static void do_get_action(struct pmc *pmc, int action, int index, char *str)

7
port.c
View File

@ -788,6 +788,7 @@ static int port_management_fill_response(struct port *target,
struct management_tlv_datum *mtd; struct management_tlv_datum *mtd;
struct clock_description *desc; struct clock_description *desc;
struct port_properties_np *ppn; struct port_properties_np *ppn;
struct port_stats_np *psn;
struct management_tlv *tlv; struct management_tlv *tlv;
struct port_ds_np *pdsnp; struct port_ds_np *pdsnp;
struct tlv_extra *extra; struct tlv_extra *extra;
@ -943,6 +944,12 @@ static int port_management_fill_response(struct port *target,
ptp_text_set(&ppn->interface, target->iface->ts_label); ptp_text_set(&ppn->interface, target->iface->ts_label);
datalen = sizeof(*ppn) + ppn->interface.length; datalen = sizeof(*ppn) + ppn->interface.length;
break; break;
case TLV_PORT_STATS_NP:
psn = (struct port_stats_np *)tlv->data;
psn->portIdentity = target->portIdentity;
psn->stats = target->stats;
datalen = sizeof(*psn);
break;
default: default:
/* The caller should *not* respond to this message. */ /* The caller should *not* respond to this message. */
tlv_extra_recycle(extra); tlv_extra_recycle(extra);

15
tlv.c
View File

@ -92,6 +92,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
struct grandmaster_settings_np *gsn; struct grandmaster_settings_np *gsn;
struct subscribe_events_np *sen; struct subscribe_events_np *sen;
struct port_properties_np *ppn; struct port_properties_np *ppn;
struct port_stats_np *psn;
struct mgmt_clock_description *cd; struct mgmt_clock_description *cd;
int extra_len = 0, len; int extra_len = 0, len;
uint8_t *buf; uint8_t *buf;
@ -286,6 +287,14 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
extra_len = sizeof(struct port_properties_np); extra_len = sizeof(struct port_properties_np);
extra_len += ppn->interface.length; extra_len += ppn->interface.length;
break; break;
case TLV_PORT_STATS_NP:
if (data_len < sizeof(struct port_stats_np))
goto bad_length;
psn = (struct port_stats_np *)m->data;
psn->portIdentity.portNumber =
ntohs(psn->portIdentity.portNumber);
extra_len = sizeof(struct port_stats_np);
break;
case TLV_SAVE_IN_NON_VOLATILE_STORAGE: case TLV_SAVE_IN_NON_VOLATILE_STORAGE:
case TLV_RESET_NON_VOLATILE_STORAGE: case TLV_RESET_NON_VOLATILE_STORAGE:
case TLV_INITIALIZE: case TLV_INITIALIZE:
@ -319,6 +328,7 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra)
struct grandmaster_settings_np *gsn; struct grandmaster_settings_np *gsn;
struct subscribe_events_np *sen; struct subscribe_events_np *sen;
struct port_properties_np *ppn; struct port_properties_np *ppn;
struct port_stats_np *psn;
struct mgmt_clock_description *cd; struct mgmt_clock_description *cd;
switch (m->id) { switch (m->id) {
case TLV_CLOCK_DESCRIPTION: case TLV_CLOCK_DESCRIPTION:
@ -391,6 +401,11 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra)
ppn = (struct port_properties_np *)m->data; ppn = (struct port_properties_np *)m->data;
ppn->portIdentity.portNumber = htons(ppn->portIdentity.portNumber); ppn->portIdentity.portNumber = htons(ppn->portIdentity.portNumber);
break; break;
case TLV_PORT_STATS_NP:
psn = (struct port_stats_np *)m->data;
psn->portIdentity.portNumber =
htons(psn->portIdentity.portNumber);
break;
} }
} }

6
tlv.h
View File

@ -105,6 +105,7 @@ enum management_action {
#define TLV_LOG_MIN_PDELAY_REQ_INTERVAL 0x6001 #define TLV_LOG_MIN_PDELAY_REQ_INTERVAL 0x6001
#define TLV_PORT_DATA_SET_NP 0xC002 #define TLV_PORT_DATA_SET_NP 0xC002
#define TLV_PORT_PROPERTIES_NP 0xC004 #define TLV_PORT_PROPERTIES_NP 0xC004
#define TLV_PORT_STATS_NP 0xC005
/* Management error ID values */ /* Management error ID values */
#define TLV_RESPONSE_TOO_BIG 0x0001 #define TLV_RESPONSE_TOO_BIG 0x0001
@ -280,6 +281,11 @@ struct port_properties_np {
struct PTPText interface; struct PTPText interface;
} PACKED; } PACKED;
struct port_stats_np {
struct PortIdentity portIdentity;
struct PortStats stats;
} PACKED;
#define PROFILE_ID_LEN 6 #define PROFILE_ID_LEN 6
struct mgmt_clock_description { struct mgmt_clock_description {