From 2b5bec8d2740c5f466aa423ae3710d812d5b16f8 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Tue, 10 Sep 2019 12:24:13 +0000 Subject: [PATCH] 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 --- pmc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ pmc_common.c | 1 + port.c | 7 +++++++ tlv.c | 15 +++++++++++++++ tlv.h | 6 ++++++ 5 files changed, 76 insertions(+) diff --git a/pmc.c b/pmc.c index 440c905..868fc2a 100644 --- a/pmc.c +++ b/pmc.c @@ -69,6 +69,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) struct tlv_extra *extra; struct portDS *p; struct port_ds_np *pnp; + struct port_stats_np *pcp; if (msg_type(msg) != MANAGEMENT) { return; @@ -322,6 +323,52 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) pnp->neighborPropDelayThresh, pnp->asCapable ? 1 : 0); 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: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "LOG_ANNOUNCE_INTERVAL " diff --git a/pmc_common.c b/pmc_common.c index 4d48e3a..592cc93 100644 --- a/pmc_common.c +++ b/pmc_common.c @@ -120,6 +120,7 @@ struct management_id idtab[] = { { "DELAY_MECHANISM", TLV_DELAY_MECHANISM, 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_STATS_NP", TLV_PORT_STATS_NP, do_get_action }, }; static void do_get_action(struct pmc *pmc, int action, int index, char *str) diff --git a/port.c b/port.c index 471e6f4..07ad3f0 100644 --- a/port.c +++ b/port.c @@ -788,6 +788,7 @@ static int port_management_fill_response(struct port *target, struct management_tlv_datum *mtd; struct clock_description *desc; struct port_properties_np *ppn; + struct port_stats_np *psn; struct management_tlv *tlv; struct port_ds_np *pdsnp; 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); datalen = sizeof(*ppn) + ppn->interface.length; 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: /* The caller should *not* respond to this message. */ tlv_extra_recycle(extra); diff --git a/tlv.c b/tlv.c index 6a5387e..2440482 100644 --- a/tlv.c +++ b/tlv.c @@ -92,6 +92,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len, struct grandmaster_settings_np *gsn; struct subscribe_events_np *sen; struct port_properties_np *ppn; + struct port_stats_np *psn; struct mgmt_clock_description *cd; int extra_len = 0, len; 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 += ppn->interface.length; 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_RESET_NON_VOLATILE_STORAGE: 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 subscribe_events_np *sen; struct port_properties_np *ppn; + struct port_stats_np *psn; struct mgmt_clock_description *cd; switch (m->id) { 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->portIdentity.portNumber = htons(ppn->portIdentity.portNumber); break; + case TLV_PORT_STATS_NP: + psn = (struct port_stats_np *)m->data; + psn->portIdentity.portNumber = + htons(psn->portIdentity.portNumber); + break; } } diff --git a/tlv.h b/tlv.h index bcbfdd9..faf5742 100644 --- a/tlv.h +++ b/tlv.h @@ -105,6 +105,7 @@ enum management_action { #define TLV_LOG_MIN_PDELAY_REQ_INTERVAL 0x6001 #define TLV_PORT_DATA_SET_NP 0xC002 #define TLV_PORT_PROPERTIES_NP 0xC004 +#define TLV_PORT_STATS_NP 0xC005 /* Management error ID values */ #define TLV_RESPONSE_TOO_BIG 0x0001 @@ -280,6 +281,11 @@ struct port_properties_np { struct PTPText interface; } PACKED; +struct port_stats_np { + struct PortIdentity portIdentity; + struct PortStats stats; +} PACKED; + #define PROFILE_ID_LEN 6 struct mgmt_clock_description {