Re: [Linuxptp-devel] [PATCH] port: fix buffer overflow in net_sync_resp_append()

2018-04-06 Thread Richard Cochran
On Fri, Apr 06, 2018 at 05:13:11PM +0200, Miroslav Lichvar wrote:
> That's definitely better. Will you fix the patch, or would you like me
> to send v2?

I'll fix it.

Thanks,
Richard

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH] port: fix buffer overflow in net_sync_resp_append()

2018-04-06 Thread Richard Cochran
On Fri, Apr 06, 2018 at 12:30:08PM +0200, Miroslav Lichvar wrote:
> The PortAddress structure has no space for the actual address and should
> be used only as a pointer to a larger buffer.

Oh man, Sloppy!  Time for 1.9.2.  
 
> @@ -403,32 +403,34 @@ static int net_sync_resp_append(struct port *p, struct 
> ptp_message *m)
>   struct port *best = clock_best_port(p->clock);
>   struct nsm_resp_tlv_head *head;
>   struct Timestamp last_sync;
> - struct PortAddress paddr;
> + struct PortAddress *paddr;
>   struct ptp_message *tmp;
>   struct tlv_extra *extra;
>   unsigned char *ptr;
> + char buf[sizeof(*paddr) + 16];

Sure, 16 is large enough for a 128 bit ipv6 address, but I'd like this
to be explicit.

char buf[sizeof(*paddr) + sizeof(struct sockaddr_storage)];

How about this?

Thanks,
Richard

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 06/12] clock: Added pm collection for clock statistics

2018-04-06 Thread Anders Selhammer
This patch adds the pm data collection based on data from the active
slave port.

Signed-off-by: Anders Selhammer 
---
 clock.c | 46 ++
 clock.h |  7 +++
 2 files changed, 53 insertions(+)

diff --git a/clock.c b/clock.c
index 8e7af0d..8135b39 100644
--- a/clock.c
+++ b/clock.c
@@ -34,6 +34,7 @@
 #include "missing.h"
 #include "msg.h"
 #include "phc.h"
+#include "pm.h"
 #include "port.h"
 #include "servo.h"
 #include "stats.h"
@@ -122,6 +123,9 @@ struct clock {
struct clockcheck *sanity_check;
struct interface uds_interface;
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
+   /* performance monitoring */
+   int performance_monitoring;
+   struct pm_clock_stats pm_stats_record;
 };
 
 struct clock the_clock;
@@ -135,6 +139,22 @@ static int cid_eq(struct ClockIdentity *a, struct 
ClockIdentity *b)
return 0 == memcmp(a, b, sizeof(*a));
 }
 
+int clock_performance_monitoring(struct clock *c)
+{
+   return c->performance_monitoring;
+}
+
+static void clock_set_pmtime(struct clock *c)
+{
+   struct timespec now;
+   PMTimestamp pmtime;
+
+   clock_gettime(CLOCK_MONOTONIC, );
+   pmtime = timespec_to_tmv(now);
+
+   c->pm_stats_record.head.PMTime = pmtime;
+}
+
 static void remove_subscriber(struct clock_subscriber *s)
 {
LIST_REMOVE(s, list);
@@ -276,6 +296,7 @@ void clock_destroy(struct clock *c)
stats_destroy(c->stats.offset);
stats_destroy(c->stats.freq);
stats_destroy(c->stats.delay);
+   pm_destroy_clock_stats(>pm_stats_record);
if (c->sanity_check) {
clockcheck_destroy(c->sanity_check);
}
@@ -1099,6 +1120,11 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
return NULL;
}
 
+   if (pm_create_clock_stats(>pm_stats_record)) {
+   pr_err("failed to create pm clock stats");
+   return NULL;
+   }
+
/* Create the UDS interface. */
c->uds_port = port_open(phc_index, timestamping, 0, udsif, c);
if (!c->uds_port) {
@@ -1122,6 +1148,10 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
}
port_dispatch(c->uds_port, EV_INITIALIZE, 0);
 
+   if (c->performance_monitoring) {
+   clock_set_pmtime(c);
+   }
+
return c;
 }
 
@@ -1521,11 +1551,19 @@ int clock_poll(struct clock *c)
 void clock_path_delay(struct clock *c, tmv_t req, tmv_t rx)
 {
tsproc_up_ts(c->tsproc, req, rx);
+   if (c->performance_monitoring) {
+   stats_add_value(c->pm_stats_record.slaveMasterDelay,
+   tmv_dbl(tmv_sub(rx, req)));
+   }
 
if (tsproc_update_delay(c->tsproc, >path_delay))
return;
 
c->cur.meanPathDelay = tmv_to_TimeInterval(c->path_delay);
+   if (c->performance_monitoring) {
+   stats_add_value(c->pm_stats_record.meanPathDelay,
+   tmv_dbl(c->path_delay));
+   }
 
if (c->stats.delay)
stats_add_value(c->stats.delay, tmv_dbl(c->path_delay));
@@ -1597,6 +1635,10 @@ enum servo_state clock_synchronize(struct clock *c, 
tmv_t ingress, tmv_t origin)
c->ingress_ts = ingress;
 
tsproc_down_ts(c->tsproc, origin, ingress);
+   if (c->performance_monitoring) {
+   stats_add_value(c->pm_stats_record.masterSlaveDelay,
+   tmv_dbl(tmv_sub(ingress, origin)));
+   }
 
if (tsproc_update_offset(c->tsproc, >master_offset, )) {
return state;
@@ -1607,6 +1649,10 @@ enum servo_state clock_synchronize(struct clock *c, 
tmv_t ingress, tmv_t origin)
}
 
c->cur.offsetFromMaster = tmv_to_TimeInterval(c->master_offset);
+   if (c->performance_monitoring) {
+   stats_add_value(c->pm_stats_record.offsetFromMaster,
+   tmv_dbl(c->master_offset));
+   }
 
if (c->free_running) {
return clock_no_adjust(c, ingress, origin);
diff --git a/clock.h b/clock.h
index 3fa026d..c06d485 100644
--- a/clock.h
+++ b/clock.h
@@ -43,6 +43,13 @@ enum clock_type {
 };
 
 /**
+ * Obtain the performance monitoring attribute from a clock.
+ * @param c  The clock instance.
+ * @return   The value of the clock's performance monitoring flag.
+ */
+int clock_performance_monitoring(struct clock *c);
+
+/**
  * Obtains a reference to the best foreign master of a clock.
  * @param c  The clock instance.
  * @return   A pointer to the data set of the foreign master,
-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list

[Linuxptp-devel] [PATCH pm 03/12] pm: Added pm.h including struct for pm storage

2018-04-06 Thread Anders Selhammer
This patch adds pm.h which includes structs for performance monitoring
in a PTP network. The monitoring is according to Annex M in draft for
v2.1 of the ieee1588 standard

Signed-off-by: Anders Selhammer 
---
 pm.h | 99 
 1 file changed, 99 insertions(+)
 create mode 100644 pm.h

diff --git a/pm.h b/pm.h
new file mode 100644
index 000..15263ad
--- /dev/null
+++ b/pm.h
@@ -0,0 +1,99 @@
+/**
+ * @file pm.h
+ * @brief Performance monitoring
+ * @note Copyright (C) 2018 Anders Selhammer 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef HAVE_PM_H
+#define HAVE_PM_H
+
+#include 
+
+#include "stats.h"
+#include "tmv.h"
+
+#define PM_15M_TIMER 900
+
+typedef tmv_t PMTimestamp;
+
+enum {
+   /* E2E and P2P */
+   ANNOUNCE_TX,
+   ANNOUNCE_RX,
+   ANNOUNCE_FOREIGN_MASTER_RX,
+   SYNC_TX,
+   SYNC_RX,
+   FOLLOWUP_TX,
+   FOLLOWUP_RX,
+   /* E2E only */
+   DELAY_REQ_TX,
+   DELAY_REQ_RX,
+   DELAY_RESP_TX,
+   DELAY_RESP_RX,
+   /* P2P only */
+   PDELAY_REQ_TX,
+   PDELAY_REQ_RX,
+   PDELAY_RESP_TX,
+   PDELAY_RESP_RX,
+   PDELAY_RESP_FOLLOWUP_TX,
+   PDELAY_RESP_FOLLOWUP_RX,
+   N_MSG_COUNTERS
+};
+
+struct pm_head {
+   UInteger16  index;
+   PMTimestamp PMTime;
+};
+
+/* E2E and P2P */
+struct pm_clock_stats {
+   TAILQ_ENTRY(clock_pm_stats) list;
+   struct pm_head  head;
+   UInteger8   measurementValid;
+   UInteger8   periodComplete;
+   struct stats*masterSlaveDelay;
+   struct stats*slaveMasterDelay;
+   struct stats*meanPathDelay;
+   struct stats*offsetFromMaster;
+};
+
+/* P2P only */
+struct pm_port_stats {
+   TAILQ_ENTRY(port_pm_stats) list;
+   struct pm_head  head;
+   struct stats*meanLinkDelay;
+};
+
+/* E2E and P2P */
+struct pm_port_counters {
+   TAILQ_ENTRY(port_pm_counters) list;
+   struct pm_head  head;
+   UInteger32  counter[N_MSG_COUNTERS];
+};
+
+struct pm_clock_recordlist {
+   TAILQ_HEAD(clock_pm_15_stats_head, clock_pm_stats) record15_stats;
+   TAILQ_HEAD(clock_pm_24_stats_head, clock_pm_stats) record24_stats;
+};
+
+struct pm_port_recordlist {
+   TAILQ_HEAD(port_pm_15_stats_head, port_pm_stats) record15_stats;
+   TAILQ_HEAD(port_pm_24_stats_head, port_pm_stats) record24_stats;
+   TAILQ_HEAD(port_pm_15_counters_head, port_pm_counters) record15_cnt;
+   TAILQ_HEAD(port_pm_24_counters_head, port_pm_counters) record24_cnt;
+};
+
+#endif
-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 02/12] clock: Fix coding style

2018-04-06 Thread Anders Selhammer
Signed-off-by: Anders Selhammer 
---
 clock.c | 36 
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/clock.c b/clock.c
index bc67fb4..8e7af0d 100644
--- a/clock.c
+++ b/clock.c
@@ -276,8 +276,9 @@ void clock_destroy(struct clock *c)
stats_destroy(c->stats.offset);
stats_destroy(c->stats.freq);
stats_destroy(c->stats.delay);
-   if (c->sanity_check)
+   if (c->sanity_check) {
clockcheck_destroy(c->sanity_check);
+   }
memset(c, 0, sizeof(*c));
msg_cleanup();
 }
@@ -857,8 +858,9 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
clock_gettime(CLOCK_REALTIME, );
srandom(ts.tv_sec ^ ts.tv_nsec);
 
-   if (c->nports)
+   if (c->nports) {
clock_destroy(c);
+   }
 
switch (type) {
case CLOCK_TYPE_ORDINARY:
@@ -1188,8 +1190,9 @@ static int clock_resize_pollfd(struct clock *c, int 
new_nports)
new_pollfd = realloc(c->pollfd,
 (new_nports + 1) * N_CLOCK_PFD *
 sizeof(struct pollfd));
-   if (!new_pollfd)
+   if (!new_pollfd) {
return -1;
+   }
c->pollfd = new_pollfd;
return 0;
 }
@@ -1213,8 +1216,9 @@ static void clock_check_pollfd(struct clock *c)
struct port *p;
struct pollfd *dest = c->pollfd;
 
-   if (c->pollfd_valid)
+   if (c->pollfd_valid) {
return;
+   }
LIST_FOREACH(p, >ports, list) {
clock_fill_pollfd(dest, p);
dest += N_CLOCK_PFD;
@@ -1467,10 +1471,12 @@ int clock_poll(struct clock *c)
for (i = 0; i < N_POLLFD; i++) {
if (cur[i].revents & (POLLIN|POLLPRI)) {
event = port_event(p, i);
-   if (EV_STATE_DECISION_EVENT == event)
+   if (EV_STATE_DECISION_EVENT == event) {
c->sde = 1;
-   if (EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES == 
event)
+   }
+   if (EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES == 
event) {
c->sde = 1;
+   }
port_dispatch(p, event, 0);
/* Clear any fault after a little while. */
if (PS_FAULTY == port_state(p)) {
@@ -1498,8 +1504,9 @@ int clock_poll(struct clock *c)
for (i = 0; i < N_POLLFD; i++) {
if (cur[i].revents & (POLLIN|POLLPRI)) {
event = port_event(c->uds_port, i);
-   if (EV_STATE_DECISION_EVENT == event)
+   if (EV_STATE_DECISION_EVENT == event) {
c->sde = 1;
+   }
}
}
 
@@ -1591,16 +1598,19 @@ enum servo_state clock_synchronize(struct clock *c, 
tmv_t ingress, tmv_t origin)
 
tsproc_down_ts(c->tsproc, origin, ingress);
 
-   if (tsproc_update_offset(c->tsproc, >master_offset, ))
+   if (tsproc_update_offset(c->tsproc, >master_offset, )) {
return state;
+   }
 
-   if (clock_utc_correct(c, ingress))
+   if (clock_utc_correct(c, ingress)) {
return c->servo_state;
+   }
 
c->cur.offsetFromMaster = tmv_to_TimeInterval(c->master_offset);
 
-   if (c->free_running)
+   if (c->free_running) {
return clock_no_adjust(c, ingress, origin);
+   }
 
adj = servo_sample(c->servo, tmv_to_nanoseconds(c->master_offset),
   tmv_to_nanoseconds(ingress), weight, );
@@ -1633,10 +1643,12 @@ enum servo_state clock_synchronize(struct clock *c, 
tmv_t ingress, tmv_t origin)
break;
case SERVO_LOCKED:
clockadj_set_freq(c->clkid, -adj);
-   if (c->clkid == CLOCK_REALTIME)
+   if (c->clkid == CLOCK_REALTIME) {
sysclk_set_sync();
-   if (c->sanity_check)
+   }
+   if (c->sanity_check) {
clockcheck_set_freq(c->sanity_check, -adj);
+   }
break;
}
return state;
-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 09/12] clock: Added pm timer

2018-04-06 Thread Anders Selhammer
15 minutes timer is added for pm cycle.

Signed-off-by: Anders Selhammer 
---
 clock.c | 46 --
 1 file changed, 40 insertions(+), 6 deletions(-)

diff --git a/clock.c b/clock.c
index ee5f855..7e92958 100644
--- a/clock.c
+++ b/clock.c
@@ -125,6 +125,7 @@ struct clock {
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
/* performance monitoring */
int performance_monitoring;
+   int pm_fd;
struct pm_clock_stats pm_stats_record;
 };
 
@@ -144,6 +145,16 @@ int clock_performance_monitoring(struct clock *c)
return c->performance_monitoring;
 }
 
+static int clock_set_pm_tmo(struct clock *c)
+{
+   return set_tmo_lin(c->pm_fd, PM_15M_TIMER);
+}
+
+static int clock_clr_tmo(int fd)
+{
+   return set_tmo_lin(fd, 0);
+}
+
 static void clock_set_pmtime(struct clock *c)
 {
struct timespec now;
@@ -291,6 +302,8 @@ void clock_destroy(struct clock *c)
clock_remove_port(c, p);
}
port_close(c->uds_port);
+   clock_clr_tmo(c->pm_fd);
+   close(c->pm_fd);
free(c->pollfd);
if (c->clkid != CLOCK_REALTIME) {
phc_close(c->clkid);
@@ -1124,6 +1137,11 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
return NULL;
}
 
+   c->pm_fd = timerfd_create(CLOCK_MONOTONIC, 0);
+   if (c->pm_fd < 0) {
+   pr_err("timerfd_create failed: %m");
+   return NULL;
+   }
if (pm_create_clock_stats(>pm_stats_record)) {
pr_err("failed to create pm clock stats");
return NULL;
@@ -1153,6 +1171,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
port_dispatch(c->uds_port, EV_INITIALIZE, 0);
 
if (c->performance_monitoring) {
+   clock_set_pm_tmo(c);
clock_set_pmtime(c);
}
 
@@ -1220,9 +1239,10 @@ static int clock_resize_pollfd(struct clock *c, int 
new_nports)
 {
struct pollfd *new_pollfd;
 
-   /* Need to allocate one whole extra block of fds for UDS. */
+   /* Need to allocate one extra fd for pm and one whole extra block
+* of fds for UDS. */
new_pollfd = realloc(c->pollfd,
-(new_nports + 1) * N_CLOCK_PFD *
+(1 + (new_nports + 1) * N_CLOCK_PFD) *
 sizeof(struct pollfd));
if (!new_pollfd) {
return -1;
@@ -1231,7 +1251,7 @@ static int clock_resize_pollfd(struct clock *c, int 
new_nports)
return 0;
 }
 
-static void clock_fill_pollfd(struct pollfd *dest, struct port *p)
+static void clock_fill_port_pollfd(struct pollfd *dest, struct port *p)
 {
struct fdarray *fda;
int i;
@@ -1245,6 +1265,12 @@ static void clock_fill_pollfd(struct pollfd *dest, 
struct port *p)
dest[i].events = POLLIN|POLLPRI;
 }
 
+static void clock_fill_pm_pollfd(struct pollfd *dest, struct clock *c)
+{
+   dest[0].fd = c->pm_fd;
+   dest[0].events = POLLIN|POLLPRI;
+}
+
 static void clock_check_pollfd(struct clock *c)
 {
struct port *p;
@@ -1254,10 +1280,12 @@ static void clock_check_pollfd(struct clock *c)
return;
}
LIST_FOREACH(p, >ports, list) {
-   clock_fill_pollfd(dest, p);
+   clock_fill_port_pollfd(dest, p);
dest += N_CLOCK_PFD;
}
-   clock_fill_pollfd(dest, c->uds_port);
+   clock_fill_port_pollfd(dest, c->uds_port);
+   dest += N_CLOCK_PFD;
+   clock_fill_pm_pollfd(dest, c);
c->pollfd_valid = 1;
 }
 
@@ -1486,7 +1514,7 @@ int clock_poll(struct clock *c)
struct port *p;
 
clock_check_pollfd(c);
-   cnt = poll(c->pollfd, (c->nports + 1) * N_CLOCK_PFD, -1);
+   cnt = poll(c->pollfd, 1 + (c->nports + 1) * N_CLOCK_PFD, -1);
if (cnt < 0) {
if (EINTR == errno) {
return 0;
@@ -1543,6 +1571,12 @@ int clock_poll(struct clock *c)
}
}
}
+   cur += N_CLOCK_PFD;
+
+   /* Check the pm timer. */
+   if (cur[0].revents & (POLLIN|POLLPRI)) {
+   ;
+   }
 
if (c->sde) {
handle_state_decision_event(c);
-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 12/12] Add a configuration file option to enable the Performance Monitoring

2018-04-06 Thread Anders Selhammer
Signed-off-by: Anders Selhammer 
---
 clock.c | 2 ++
 config.c| 1 +
 default.cfg | 1 +
 gPTP.cfg| 1 +
 ptp4l.8 | 9 +
 5 files changed, 14 insertions(+)

diff --git a/clock.c b/clock.c
index 37959e7..78a93fc 100644
--- a/clock.c
+++ b/clock.c
@@ -1087,6 +1087,8 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
c->kernel_leap = config_get_int(config, NULL, "kernel_leap");
c->utc_offset = config_get_int(config, NULL, "utc_offset");
c->time_source = config_get_int(config, NULL, "timeSource");
+   c->performance_monitoring =
+   config_get_int(config, NULL, "performance_monitoring");
 
if (c->free_running) {
c->clkid = CLOCK_INVALID;
diff --git a/config.c b/config.c
index 320cc1b..292911e 100644
--- a/config.c
+++ b/config.c
@@ -213,6 +213,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_INT("ntpshm_segment", 0, INT_MIN, INT_MAX),
GLOB_ITEM_INT("offsetScaledLogVariance", 0x, 0, UINT16_MAX),
PORT_ITEM_INT("path_trace_enabled", 0, 0, 1),
+   GLOB_ITEM_INT("performance_monitoring", 0, 0, 1),
GLOB_ITEM_DBL("pi_integral_const", 0.0, 0.0, DBL_MAX),
GLOB_ITEM_DBL("pi_integral_exponent", 0.4, -DBL_MAX, DBL_MAX),
GLOB_ITEM_DBL("pi_integral_norm_max", 0.3, DBL_MIN, 2.0),
diff --git a/default.cfg b/default.cfg
index e76aeae..8a44cf9 100644
--- a/default.cfg
+++ b/default.cfg
@@ -36,6 +36,7 @@ path_trace_enabled0
 follow_up_info 0
 hybrid_e2e 0
 net_sync_monitor   0
+performance_monitoring 0
 tx_timestamp_timeout   1
 use_syslog 1
 verbose0
diff --git a/gPTP.cfg b/gPTP.cfg
index 1e7a33e..83ebb9a 100644
--- a/gPTP.cfg
+++ b/gPTP.cfg
@@ -34,6 +34,7 @@ path_trace_enabled1
 follow_up_info 1
 hybrid_e2e 0
 net_sync_monitor   0
+performance_monitoring 0
 tx_timestamp_timeout   1
 use_syslog 1
 verbose0
diff --git a/ptp4l.8 b/ptp4l.8
index 950e07c..b097d42 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -229,6 +229,15 @@ time stamps in the message to estimate the node's offset.  
This option
 requires that the 'hybrid_e2e' option be enabled as well.
 The default is 0 (disabled).
 .TP
+.B performance_monitoring
+Enables Performance monitoring (PM). The purpose of monitoring is to
+visulize how the PTP timestamps change over time in the network. The
+monitoring will be made in 15 minutes and 24 hour cycles. Statistics
+for the last completed and the current 24 hour cycle will be stored in
+a recordlist along with the statistics for the last 96 15 minutes
+cycles.
+The default is 0 (disabled).
+.TP
 .B ptp_dst_mac
 The MAC address to which PTP messages should be sent.
 Relevant only with L2 transport. The default is 01:1B:19:00:00:00.
-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 05/12] pm: Added pm.c including pm storage handling

2018-04-06 Thread Anders Selhammer
This patch adds pm.c which includes handling of pm data. Each 15
minute, the data is stored in 15 minute and 24 hour recordlists.
24 hour recordlist stores the last complete 24 hour cycle and the
ongoing.
15 minute recordlist stores the last 96 complete 15 minute cycles.

Signed-off-by: Anders Selhammer 
---
 makefile |   2 +-
 pm.c | 414 +++
 pm.h | 100 +--
 3 files changed, 506 insertions(+), 10 deletions(-)
 create mode 100644 pm.c

diff --git a/makefile b/makefile
index 796235b..001bf01 100644
--- a/makefile
+++ b/makefile
@@ -25,7 +25,7 @@ LDLIBS= -lm -lrt $(EXTRA_LDFLAGS)
 PRG= ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster
 OBJ = bmc.o clock.o clockadj.o clockcheck.o config.o fault.o \
  filter.o fsm.o hash.o linreg.o mave.o mmedian.o msg.o ntpshm.o nullf.o phc.o \
- pi.o port.o print.o ptp4l.o raw.o rtnl.o servo.o sk.o stats.o tlv.o \
+ pi.o pm.o port.o print.o ptp4l.o raw.o rtnl.o servo.o sk.o stats.o tlv.o \
  transport.o tsproc.o udp.o udp6.o uds.o util.o version.o
 
 OBJECTS= $(OBJ) hwstamp_ctl.o nsm.o phc2sys.o phc_ctl.o pmc.o 
pmc_common.o \
diff --git a/pm.c b/pm.c
new file mode 100644
index 000..8521c88
--- /dev/null
+++ b/pm.c
@@ -0,0 +1,414 @@
+/**
+ * @file pm.c
+ * @note Copyright (C) 2018 Anders Selhammer 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include 
+#include 
+
+#include "pm.h"
+#include "print.h"
+
+
+#define CYCLE_24HOUR 96
+#define MIN_24HOUR_INDEX 97
+#define MAX_24HOUR_INDEX 98
+
+int pm_create_clock_stats(struct pm_clock_stats *cr)
+{
+   cr->measurementValid = 1;
+   cr->periodComplete = 0;
+   cr->masterSlaveDelay = stats_create();
+   cr->slaveMasterDelay = stats_create();
+   cr->meanPathDelay= stats_create();
+   cr->offsetFromMaster = stats_create();
+   if (!cr->masterSlaveDelay || !cr->meanPathDelay ||
+   !cr->slaveMasterDelay || !cr->offsetFromMaster) {
+   return -1;
+   }
+   return 0;
+}
+
+int pm_create_port_stats(struct pm_port_stats *cr)
+{
+   cr->meanLinkDelay = stats_create();
+   if (!cr->meanLinkDelay) {
+   return -1;
+   }
+   return 0;
+}
+
+void pm_reset_clock_stats(struct pm_clock_stats *cr)
+{
+   cr->measurementValid = 1;
+   cr->periodComplete = 0;
+   stats_reset(cr->masterSlaveDelay);
+   stats_reset(cr->slaveMasterDelay);
+   stats_reset(cr->meanPathDelay);
+   stats_reset(cr->offsetFromMaster);
+}
+
+void pm_reset_port_stats(struct pm_port_stats *cr)
+{
+   stats_reset(cr->meanLinkDelay);
+}
+
+void pm_destroy_clock_stats(struct pm_clock_stats *cr)
+{
+   stats_destroy(cr->masterSlaveDelay);
+   stats_destroy(cr->slaveMasterDelay);
+   stats_destroy(cr->meanPathDelay);
+   stats_destroy(cr->offsetFromMaster);
+}
+
+void pm_destroy_port_stats(struct pm_port_stats *cr)
+{
+   stats_destroy(cr->meanLinkDelay);
+}
+void pm_free_clock_recordlist(struct pm_clock_recordlist *rl)
+{
+   struct pm_clock_stats *tmp_s;
+
+   while ((tmp_s = TAILQ_FIRST(>record15_stats)) != NULL) {
+   TAILQ_REMOVE(>record15_stats, tmp_s, list);
+   pm_destroy_clock_stats(tmp_s);
+   free(tmp_s);
+   }
+   while ((tmp_s = TAILQ_FIRST(>record24_stats)) != NULL) {
+   TAILQ_REMOVE(>record24_stats, tmp_s, list);
+   pm_destroy_clock_stats(tmp_s);
+   free(tmp_s);
+   }
+}
+void pm_free_port_recordlist(struct pm_port_recordlist *rl)
+{
+   struct pm_port_stats *tmp_s;
+   struct pm_port_counters *tmp_c;
+
+   while ((tmp_s = TAILQ_FIRST(>record15_stats)) != NULL) {
+   TAILQ_REMOVE(>record15_stats, tmp_s, list);
+   pm_destroy_port_stats(tmp_s);
+   free(tmp_s);
+   }
+   while ((tmp_s = TAILQ_FIRST(>record24_stats)) != NULL) {
+   TAILQ_REMOVE(>record24_stats, tmp_s, list);
+   pm_destroy_port_stats(tmp_s);
+   free(tmp_s);
+   }
+   while ((tmp_c = TAILQ_FIRST(>record15_cnt)) != NULL) {
+   TAILQ_REMOVE(>record15_cnt, tmp_c, list);
+   free(tmp_c);
+   }
+   while 

[Linuxptp-devel] [PATCH pm 11/12] port: Update pm recordlist

2018-04-06 Thread Anders Selhammer
When pm timer expires, the collected data should be stored in recordlist.

Signed-off-by: Anders Selhammer 
---
 clock.c| 15 ++-
 port.c | 19 +++
 port.h | 18 +-
 port_private.h |  1 +
 4 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/clock.c b/clock.c
index 6575130..37959e7 100644
--- a/clock.c
+++ b/clock.c
@@ -173,20 +173,33 @@ static void clock_set_pmtime(struct clock *c)
 
 static void clock_handle_pm_err(struct clock *c)
 {
+   struct port *p;
+
clock_clr_tmo(c->pm_fd);
pm_free_clock_recordlist(>pm_recordlist);
+   LIST_FOREACH(p, >ports, list) {
+   port_free_pm_recordlist(p);
+   }
c->performance_monitoring = 0;
 }
 
 static void clock_pm_event(struct clock *c)
 {
-   clock_set_pm_tmo(c);
+   struct port *p;
 
+   clock_set_pm_tmo(c);
if (pm_update_clock_stats_recordlist(>pm_stats_record,
 >pm_recordlist)) {
pr_err("update of pm recordlist for clock failed");
goto err;
}
+   LIST_FOREACH(p, >ports, list) {
+   if (port_update_pm_recordlist(p, 
c->pm_stats_record.cycle_index)) {
+   pr_err("update of pm recordlist for port: %d failed",
+  port_number(p));
+   goto err;
+   }
+   }
 
clock_set_pmtime(c);
return;
diff --git a/port.c b/port.c
index f46c1ae..da3305a 100644
--- a/port.c
+++ b/port.c
@@ -62,6 +62,24 @@ void port_set_pmtime(struct port *p, PMTimestamp pmtime)
p->pm_counter_record.head.PMTime = pmtime;
 }
 
+void port_free_pm_recordlist(struct port *p)
+{
+   pm_free_port_recordlist(>pm_recordlist);
+}
+
+int port_update_pm_recordlist(struct port *p, int ci)
+{
+   if (pm_update_port_stats_recordlist(>pm_stats_record,
+   >pm_recordlist, ci)) {
+   return -1;
+   }
+   if (pm_update_port_counters_recordlist(>pm_counter_record,
+  >pm_recordlist, ci)) {
+   return -1;
+   }
+   return 0;
+}
+
 static int announce_compare(struct ptp_message *m1, struct ptp_message *m2)
 {
struct announce_msg *a = >announce, *b = >announce;
@@ -2228,6 +2246,7 @@ void port_close(struct port *p)
close(p->fault_fd);
}
pm_destroy_port_stats(>pm_stats_record);
+   pm_free_port_recordlist(>pm_recordlist);
free(p);
 }
 
diff --git a/port.h b/port.h
index 6af0ecf..edd66f1 100644
--- a/port.h
+++ b/port.h
@@ -37,12 +37,28 @@ struct port;
 /**
  * Set the pm timestamp for the current port pm data.
  *
- * @param portA port instance.
+ * @param p   A port instance.
  * @param pmtime  Current pm timestamp.
  */
 void port_set_pmtime(struct port *p, PMTimestamp pmtime);
 
 /**
+ * Free all memory in the recordlist for the port.
+ *
+ * @param p   A port instance.
+ */
+void port_free_pm_recordlist(struct port *p);
+
+/**
+ * Updates the recordlist for the port.
+ *
+ * @param p   A port instance.
+ * @param ci  Cycle index for the pm.
+ * @returnZero on success, non-zero otherwise.
+ */
+int port_update_pm_recordlist(struct port *p, int ci);
+
+/**
  * Returns the dataset from a port's best foreign clock record, if any
  * has yet been discovered. This function does not bring the returned
  * dataset up to date, so the caller should invoke port_compute_best()
diff --git a/port_private.h b/port_private.h
index ae03509..d61c676 100644
--- a/port_private.h
+++ b/port_private.h
@@ -124,6 +124,7 @@ struct port {
/* performance monitoring */
struct pm_port_stats pm_stats_record;
struct pm_port_counters pm_counter_record;
+   struct pm_port_recordlist pm_recordlist;
 };
 
 #define portnum(p) (p->portIdentity.portNumber)
-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 08/12] util: Move utility function set_tmo_lin from port to util

2018-04-06 Thread Anders Selhammer
The file, port.c, contains utility functions for setting timers.
We will want to call one of this functions from clock.c so
this patch moves the utility function where they belong.

Signed-off-by: Anders Selhammer 
---
 port.c | 10 --
 port.h | 13 -
 util.c | 11 +++
 util.h | 13 +
 4 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/port.c b/port.c
index 6ae37b1..f46c1ae 100644
--- a/port.c
+++ b/port.c
@@ -212,16 +212,6 @@ int set_tmo_log(int fd, unsigned int scale, int 
log_seconds)
return timerfd_settime(fd, 0, , NULL);
 }
 
-int set_tmo_lin(int fd, int seconds)
-{
-   struct itimerspec tmo = {
-   {0, 0}, {0, 0}
-   };
-
-   tmo.it_value.tv_sec = seconds;
-   return timerfd_settime(fd, 0, , NULL);
-}
-
 int set_tmo_random(int fd, int min, int span, int log_seconds)
 {
uint64_t value_ns, min_ns, span_ns;
diff --git a/port.h b/port.h
index 028701e..6af0ecf 100644
--- a/port.h
+++ b/port.h
@@ -278,19 +278,6 @@ int set_tmo_log(int fd, unsigned int scale, int 
log_seconds);
 int set_tmo_random(int fd, int min, int span, int log_seconds);
 
 /**
- * Utility function for setting or resetting a file descriptor timer.
- *
- * This function sets the timer 'fd' to the value of the 'seconds' parameter.
- *
- * Passing 'seconds' as zero disables the timer.
- *
- * @param fd A file descriptor previously opened with timerfd_create(2).
- * @param seconds The timeout value for the timer.
- * @return Zero on success, non-zero otherwise.
- */
-int set_tmo_lin(int fd, int seconds);
-
-/**
  * Sets port's fault file descriptor timer.
  * Passing both 'scale' and 'log_seconds' as zero disables the timer.
  *
diff --git a/util.c b/util.c
index 2eacafc..6d2ce0f 100644
--- a/util.c
+++ b/util.c
@@ -25,6 +25,7 @@
 #include 
 
 #include "address.h"
+#include "missing.h"
 #include "print.h"
 #include "sk.h"
 #include "util.h"
@@ -585,3 +586,13 @@ int rate_limited(int interval, time_t *last)
 
return 0;
 }
+
+int set_tmo_lin(int fd, int seconds)
+{
+   struct itimerspec tmo = {
+   {0, 0}, {0, 0}
+   };
+
+   tmo.it_value.tv_sec = seconds;
+   return timerfd_settime(fd, 0, , NULL);
+}
diff --git a/util.h b/util.h
index 41fbdb2..1d6c511 100644
--- a/util.h
+++ b/util.h
@@ -380,4 +380,17 @@ void parray_extend(void ***a, ...);
  */
 int rate_limited(int interval, time_t *last);
 
+/**
+ * Utility function for setting or resetting a file descriptor timer.
+ *
+ * This function sets the timer 'fd' to the value of the 'seconds' parameter.
+ *
+ * Passing 'seconds' as zero disables the timer.
+ *
+ * @param fd A file descriptor previously opened with timerfd_create(2).
+ * @param seconds The timeout value for the timer.
+ * @return Zero on success, non-zero otherwise.
+ */
+int set_tmo_lin(int fd, int seconds);
+
 #endif
-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 10/12] clock: Update pm recordlist

2018-04-06 Thread Anders Selhammer
When pm timer expires, the collected data should be stored in recordlist.

Signed-off-by: Anders Selhammer 
---
 clock.c | 28 +++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/clock.c b/clock.c
index 7e92958..6575130 100644
--- a/clock.c
+++ b/clock.c
@@ -127,6 +127,7 @@ struct clock {
int performance_monitoring;
int pm_fd;
struct pm_clock_stats pm_stats_record;
+   struct pm_clock_recordlist pm_recordlist;
 };
 
 struct clock the_clock;
@@ -170,6 +171,30 @@ static void clock_set_pmtime(struct clock *c)
}
 }
 
+static void clock_handle_pm_err(struct clock *c)
+{
+   clock_clr_tmo(c->pm_fd);
+   pm_free_clock_recordlist(>pm_recordlist);
+   c->performance_monitoring = 0;
+}
+
+static void clock_pm_event(struct clock *c)
+{
+   clock_set_pm_tmo(c);
+
+   if (pm_update_clock_stats_recordlist(>pm_stats_record,
+>pm_recordlist)) {
+   pr_err("update of pm recordlist for clock failed");
+   goto err;
+   }
+
+   clock_set_pmtime(c);
+   return;
+err:
+   clock_handle_pm_err(c);
+   return;
+}
+
 static void remove_subscriber(struct clock_subscriber *s)
 {
LIST_REMOVE(s, list);
@@ -314,6 +339,7 @@ void clock_destroy(struct clock *c)
stats_destroy(c->stats.freq);
stats_destroy(c->stats.delay);
pm_destroy_clock_stats(>pm_stats_record);
+   pm_free_clock_recordlist(>pm_recordlist);
if (c->sanity_check) {
clockcheck_destroy(c->sanity_check);
}
@@ -1575,7 +1601,7 @@ int clock_poll(struct clock *c)
 
/* Check the pm timer. */
if (cur[0].revents & (POLLIN|POLLPRI)) {
-   ;
+   clock_pm_event(c);
}
 
if (c->sde) {
-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 01/12] port: Fix coding style

2018-04-06 Thread Anders Selhammer
Signed-off-by: Anders Selhammer 
---
 port.c | 70 +++---
 1 file changed, 46 insertions(+), 24 deletions(-)

diff --git a/port.c b/port.c
index cee6445..4ec8b70 100644
--- a/port.c
+++ b/port.c
@@ -330,8 +330,9 @@ static int add_foreign_master(struct port *p, struct 
ptp_message *m)
int broke_threshold = 0, diff = 0;
 
LIST_FOREACH(fc, >foreign_masters, list) {
-   if (msg_source_equal(m, fc))
+   if (msg_source_equal(m, fc)) {
break;
+   }
}
if (!fc) {
pr_notice("port %hu: new foreign master %s", portnum(p),
@@ -355,8 +356,9 @@ static int add_foreign_master(struct port *p, struct 
ptp_message *m)
 * If this message breaks the threshold, that is an important change.
 */
fc_prune(fc);
-   if (FOREIGN_MASTER_THRESHOLD - 1 == fc->n_messages)
+   if (FOREIGN_MASTER_THRESHOLD - 1 == fc->n_messages) {
broke_threshold = 1;
+   }
 
/*
 * Okay, go ahead and add this announcement.
@@ -1205,13 +1207,15 @@ static int port_pdelay_request(struct port *p)
int err;
 
/* If multiple pdelay resp were not detected the counter can be reset */
-   if (!p->multiple_pdr_detected)
+   if (!p->multiple_pdr_detected) {
p->multiple_seq_pdr_count = 0;
+   }
p->multiple_pdr_detected = 0;
 
msg = msg_allocate();
-   if (!msg)
+   if (!msg) {
return -1;
+   }
 
msg->hwts.type = p->timestamping;
 
@@ -1318,8 +1322,9 @@ static int port_tx_announce(struct port *p)
return 0;
}
msg = msg_allocate();
-   if (!msg)
+   if (!msg) {
return -1;
+   }
 
msg->hwts.type = p->timestamping;
 
@@ -1347,8 +1352,9 @@ static int port_tx_announce(struct port *p)
}
 
err = port_prepare_and_send(p, msg, 0);
-   if (err)
+   if (err) {
pr_err("port %hu: send announce failed", portnum(p));
+   }
msg_put(msg);
return err;
 }
@@ -1381,8 +1387,9 @@ static int port_tx_sync(struct port *p, struct address 
*dst)
return 0;
}
msg = msg_allocate();
-   if (!msg)
+   if (!msg) {
return -1;
+   }
fup = msg_allocate();
if (!fup) {
msg_put(msg);
@@ -1400,8 +1407,9 @@ static int port_tx_sync(struct port *p, struct address 
*dst)
msg->header.control= CTL_SYNC;
msg->header.logMessageInterval = p->logSyncInterval;
 
-   if (p->timestamping != TS_ONESTEP && p->timestamping != TS_P2P1STEP)
+   if (p->timestamping != TS_ONESTEP && p->timestamping != TS_P2P1STEP) {
msg->header.flagField[0] |= TWO_STEP;
+   }
 
if (dst) {
msg->address = *dst;
@@ -1447,8 +1455,9 @@ static int port_tx_sync(struct port *p, struct address 
*dst)
}
 
err = port_prepare_and_send(p, fup, 0);
-   if (err)
+   if (err) {
pr_err("port %hu: send follow up failed", portnum(p));
+   }
 out:
msg_put(msg);
msg_put(fup);
@@ -1675,8 +1684,9 @@ int process_announce(struct port *p, struct ptp_message 
*m)
/* Do not qualify announce messages with stepsRemoved >= 255, see
 * IEEE1588-2008 section 9.3.2.5 (d)
 */
-   if (m->announce.stepsRemoved >= 255)
+   if (m->announce.stepsRemoved >= 255) {
return result;
+   }
 
switch (p->state) {
case PS_INITIALIZING:
@@ -1705,8 +1715,9 @@ static int process_delay_req(struct port *p, struct 
ptp_message *m)
 
nsm = port_nsm_reply(p, m);
 
-   if (!nsm && p->state != PS_MASTER && p->state != PS_GRAND_MASTER)
+   if (!nsm && p->state != PS_MASTER && p->state != PS_GRAND_MASTER) {
return 0;
+   }
 
if (p->delayMechanism == DM_P2P) {
pr_warning("port %hu: delay request on P2P port", portnum(p));
@@ -1714,8 +1725,9 @@ static int process_delay_req(struct port *p, struct 
ptp_message *m)
}
 
msg = msg_allocate();
-   if (!msg)
+   if (!msg) {
return -1;
+   }
 
msg->hwts.type = p->timestamping;
 
@@ -1834,8 +1846,9 @@ void process_follow_up(struct port *p, struct ptp_message 
*m)
break;
}
master = clock_parent_identity(p->clock);
-   if (memcmp(, >header.sourcePortIdentity, sizeof(master)))
+   if (memcmp(, >header.sourcePortIdentity, sizeof(master))) {
return;
+   }
 
if (p->follow_up_info) {
struct follow_up_info_tlv *fui = follow_up_info_extract(m);
@@ -1898,8 +1911,10 @@ int process_pdelay_req(struct port *p, struct 
ptp_message *m)
}
 
rsp = msg_allocate();
-   if (!rsp)
+   if (!rsp) {
  

[Linuxptp-devel] [PATCH pm 04/12] stats: Added copy and combine help funktions

2018-04-06 Thread Anders Selhammer
Methods for copy and combine stats structs is needed for PM

Signed-off-by: Anders Selhammer 
---
 stats.c | 19 +++
 stats.h | 14 ++
 2 files changed, 33 insertions(+)

diff --git a/stats.c b/stats.c
index 41136f0..1ec88d5 100644
--- a/stats.c
+++ b/stats.c
@@ -59,6 +59,25 @@ void stats_add_value(struct stats *stats, double value)
stats->sum_diff_sqr += (value - old_mean) * (value - stats->mean);
 }
 
+void stats_copy(struct stats *to, struct stats *from)
+{
+   memcpy(to, from, sizeof(*to));
+}
+
+void stats_combine(struct stats *to, struct stats *from)
+{
+   if (!from->num) {
+   return;
+   }
+   to->min = (to->num && to->min < from->min) ? to->min : from->min;
+   to->max = (to->num && to->max > from->max) ? to->max : from->max;
+   to->mean = (to->mean * to->num + from->mean * from->num) /
+  (to->num + from->num);
+   to->num  += from->num;
+   to->sum_sqr  += from->sum_sqr;
+   to->sum_diff_sqr += from->sum_diff_sqr;
+}
+
 unsigned int stats_get_num_values(struct stats *stats)
 {
return stats->num;
diff --git a/stats.h b/stats.h
index 541a376..6e09f7b 100644
--- a/stats.h
+++ b/stats.h
@@ -43,6 +43,20 @@ void stats_destroy(struct stats *stats);
 void stats_add_value(struct stats *stats, double value);
 
 /**
+ * Copy from one stats struct to another.
+ * @param to   Pointer to stats obtained via @ref stats_create().
+ * @param from Pointer to stats obtained via @ref stats_create().
+ */
+void stats_copy(struct stats *to, struct stats *from);
+
+/**
+ * Combine from one stats struct into another.
+ * @param to   Pointer to stats obtained via @ref stats_create().
+ * @param from Pointer to stats obtained via @ref stats_create().
+ */
+void stats_combine(struct stats *to, struct stats *from);
+
+/**
  * Get the number of values collected in the stats so far.
  * @param stats Pointer to stats obtained via @ref stats_create().
  * @return  The number of values.
-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 00/12] Performance Monitoring

2018-04-06 Thread Anders Selhammer
I stumbled over the suggested solution to monitor the performance
of the network and of the network elements when I reviewed a draft
for IEEE1588 v2.1.
This set of patches implements the collection and local storage of
the data needed for this performance measurement according to Annex M
in the draft.

Anders Selhammer (12):
  port: Fix coding style
  clock: Fix coding style
  pm: Added pm.h including struct for pm storage
  stats: Added copy and combine help funktions
  pm: Added pm.c including pm storage handling
  clock: Added pm collection for clock statistics
  port: Added pm collection for port statistics
  util: Move utility function set_tmo_lin from port to util
  clock: Added pm timer
  clock: Update pm recordlist
  port: Update pm recordlist
  Add a configuration file option to enable the Performance Monitoring

 clock.c| 173 +---
 clock.h|   7 +
 config.c   |   1 +
 default.cfg|   1 +
 gPTP.cfg   |   1 +
 makefile   |   2 +-
 pm.c   | 414 +
 pm.h   | 181 +
 port.c | 160 +-
 port.h |  38 --
 port_private.h |   5 +
 ptp4l.8|   9 ++
 stats.c|  19 +++
 stats.h|  14 ++
 util.c |  11 ++
 util.h |  13 ++
 16 files changed, 983 insertions(+), 66 deletions(-)
 create mode 100644 pm.c
 create mode 100644 pm.h

-- 
1.8.3.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH pm 07/12] port: Added pm collection for port statistics

2018-04-06 Thread Anders Selhammer
This patch adds the pm data collection for the specific port.

Signed-off-by: Anders Selhammer 
---
 clock.c|  4 
 port.c | 61 ++
 port.h |  9 +
 port_private.h |  4 
 4 files changed, 78 insertions(+)

diff --git a/clock.c b/clock.c
index 8135b39..ee5f855 100644
--- a/clock.c
+++ b/clock.c
@@ -148,11 +148,15 @@ static void clock_set_pmtime(struct clock *c)
 {
struct timespec now;
PMTimestamp pmtime;
+   struct port *p;
 
clock_gettime(CLOCK_MONOTONIC, );
pmtime = timespec_to_tmv(now);
 
c->pm_stats_record.head.PMTime = pmtime;
+   LIST_FOREACH(p, >ports, list) {
+   port_set_pmtime(p, pmtime);
+   }
 }
 
 static void remove_subscriber(struct clock_subscriber *s)
diff --git a/port.c b/port.c
index 4ec8b70..6ae37b1 100644
--- a/port.c
+++ b/port.c
@@ -56,6 +56,12 @@ static int port_capable(struct port *p);
 static int port_is_ieee8021as(struct port *p);
 static void port_nrate_initialize(struct port *p);
 
+void port_set_pmtime(struct port *p, PMTimestamp pmtime)
+{
+   p->pm_stats_record.head.PMTime = pmtime;
+   p->pm_counter_record.head.PMTime = pmtime;
+}
+
 static int announce_compare(struct ptp_message *m1, struct ptp_message *m2)
 {
struct announce_msg *a = >announce, *b = >announce;
@@ -329,6 +335,8 @@ static int add_foreign_master(struct port *p, struct 
ptp_message *m)
struct ptp_message *tmp;
int broke_threshold = 0, diff = 0;
 
+   p->pm_counter_record.counter[ANNOUNCE_FOREIGN_MASTER_RX]++;
+
LIST_FOREACH(fc, >foreign_masters, list) {
if (msg_source_equal(m, fc)) {
break;
@@ -1235,6 +1243,9 @@ static int port_pdelay_request(struct port *p)
pr_err("port %hu: send peer delay request failed", portnum(p));
goto out;
}
+
+   p->pm_counter_record.counter[PDELAY_REQ_TX]++;
+
if (msg_sots_missing(msg)) {
pr_err("missing timestamp on transmitted peer delay request");
goto out;
@@ -1298,6 +1309,9 @@ int port_delay_request(struct port *p)
pr_err("port %hu: send delay request failed", portnum(p));
goto out;
}
+
+   p->pm_counter_record.counter[DELAY_REQ_TX]++;
+
if (msg_sots_missing(msg)) {
pr_err("missing timestamp on transmitted delay request");
goto out;
@@ -1354,7 +1368,11 @@ static int port_tx_announce(struct port *p)
err = port_prepare_and_send(p, msg, 0);
if (err) {
pr_err("port %hu: send announce failed", portnum(p));
+   goto out;
}
+
+   p->pm_counter_record.counter[ANNOUNCE_TX]++;
+out:
msg_put(msg);
return err;
 }
@@ -1420,6 +1438,9 @@ static int port_tx_sync(struct port *p, struct address 
*dst)
pr_err("port %hu: send sync failed", portnum(p));
goto out;
}
+
+   p->pm_counter_record.counter[SYNC_TX]++;
+
if (p->timestamping == TS_ONESTEP || p->timestamping == TS_P2P1STEP) {
goto out;
} else if (msg_sots_missing(msg)) {
@@ -1457,7 +1478,10 @@ static int port_tx_sync(struct port *p, struct address 
*dst)
err = port_prepare_and_send(p, fup, 0);
if (err) {
pr_err("port %hu: send follow up failed", portnum(p));
+   goto out;
}
+
+   p->pm_counter_record.counter[FOLLOWUP_TX]++;
 out:
msg_put(msg);
msg_put(fup);
@@ -1705,6 +1729,8 @@ int process_announce(struct port *p, struct ptp_message 
*m)
result = update_current_master(p, m);
break;
}
+
+   p->pm_counter_record.counter[ANNOUNCE_RX]++;
return result;
 }
 
@@ -1724,6 +1750,10 @@ static int process_delay_req(struct port *p, struct 
ptp_message *m)
return 0;
}
 
+   if (!nsm) {
+   p->pm_counter_record.counter[DELAY_REQ_RX]++;
+   }
+
msg = msg_allocate();
if (!msg) {
return -1;
@@ -1760,11 +1790,14 @@ static int process_delay_req(struct port *p, struct 
ptp_message *m)
pr_err("port %hu: send delay response failed", portnum(p));
goto out;
}
+
if (nsm) {
saved_seqnum_sync = p->seqnum.sync;
p->seqnum.sync = m->header.sequenceId;
err = port_tx_sync(p, >address);
p->seqnum.sync = saved_seqnum_sync;
+   } else {
+   p->pm_counter_record.counter[DELAY_RESP_TX]++;
}
 out:
msg_put(msg);
@@ -1808,6 +1841,8 @@ static void process_delay_resp(struct port *p, struct 
ptp_message *m)
TAILQ_REMOVE(>delay_req, req, list);
msg_put(req);
 
+   p->pm_counter_record.counter[DELAY_RESP_RX]++;
+
if (p->logMinDelayReqInterval == 

[Linuxptp-devel] [PATCH] port: fix buffer overflow in net_sync_resp_append()

2018-04-06 Thread Miroslav Lichvar
The PortAddress structure has no space for the actual address and should
be used only as a pointer to a larger buffer.

The issue was reported by gcc with enabled source fortification.

Signed-off-by: Miroslav Lichvar 
---
 port.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/port.c b/port.c
index cee6445..872c7be 100644
--- a/port.c
+++ b/port.c
@@ -403,32 +403,34 @@ static int net_sync_resp_append(struct port *p, struct 
ptp_message *m)
struct port *best = clock_best_port(p->clock);
struct nsm_resp_tlv_head *head;
struct Timestamp last_sync;
-   struct PortAddress paddr;
+   struct PortAddress *paddr;
struct ptp_message *tmp;
struct tlv_extra *extra;
unsigned char *ptr;
+   char buf[sizeof(*paddr) + 16];
int tlv_len;
 
last_sync = tmv_to_Timestamp(clock_ingress_time(p->clock));
pid = dad->pds.parentPortIdentity.clockIdentity;
+   paddr = (struct PortAddress *)buf;
 
if (best && memcmp(, , sizeof(cid))) {
/* Extract the parent's protocol address. */
-   paddr.networkProtocol = transport_type(best->trp);
-   paddr.addressLength =
-   transport_protocol_addr(best->trp, paddr.address);
+   paddr->networkProtocol = transport_type(best->trp);
+   paddr->addressLength =
+   transport_protocol_addr(best->trp, paddr->address);
if (best->best) {
tmp = TAILQ_FIRST(>best->messages);
-   extract_address(tmp, );
+   extract_address(tmp, paddr);
}
} else {
/* We are our own parent. */
-   paddr.networkProtocol = transport_type(p->trp);
-   paddr.addressLength =
-   transport_protocol_addr(p->trp, paddr.address);
+   paddr->networkProtocol = transport_type(p->trp);
+   paddr->addressLength =
+   transport_protocol_addr(p->trp, paddr->address);
}
 
-   tlv_len = sizeof(*head) + sizeof(*extra->foot) + paddr.addressLength;
+   tlv_len = sizeof(*head) + sizeof(*extra->foot) + paddr->addressLength;
 
extra = msg_tlv_append(m, tlv_len);
if (!extra) {
@@ -439,12 +441,12 @@ static int net_sync_resp_append(struct port *p, struct 
ptp_message *m)
head->type = TLV_PTPMON_RESP;
head->length = tlv_len - sizeof(head->type) - sizeof(head->length);
head->port_state = p->state == PS_GRAND_MASTER ? PS_MASTER : p->state;
-   head->parent_addr.networkProtocol = paddr.networkProtocol;
-   head->parent_addr.addressLength = paddr.addressLength;
-   memcpy(head->parent_addr.address, paddr.address, paddr.addressLength);
+   head->parent_addr.networkProtocol = paddr->networkProtocol;
+   head->parent_addr.addressLength = paddr->addressLength;
+   memcpy(head->parent_addr.address, paddr->address, paddr->addressLength);
 
ptr = (unsigned char *) head;
-   ptr += sizeof(*head) + paddr.addressLength;
+   ptr += sizeof(*head) + paddr->addressLength;
extra->foot = (struct nsm_resp_tlv_foot *) ptr;
 
memcpy(>foot->parent, >pds, sizeof(extra->foot->parent));
-- 
2.14.3


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH 1/2] port: Fix coding style

2018-04-06 Thread Anders Selhammer
Thursday, April 5, 2018 10:47 PM
> I appreciate the gesture, but I won't take mega- coding style patches.
> It is too hard to review.  One misplaced brace, and... you know what
> happens.

> I will take small coding style fixes as part of new development.

Ok, then I know. Got bored to make this separate coding style fix patch for 
each update.
Lets fix em all was my idea...

I will just take care of those around new development then.

/anders

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel