[Linuxptp-devel] [PATCHv3 08/10] ptp4l: use ts label to get ts info
PTP IEEE 1588 stack for Linux
Brought to you by:
rcochran
|
From: Hangbin L. <liu...@gm...> - 2017-08-16 13:33:20
|
Now the ts label will be either the bond active slave or the interface
name, which is the exactly interface we need to get ts info.
If there is a fail over and ts_label changed, we need to check the
clock_required_modes. We will set the link to LINK_DOWN by force if
the new ts_label's timestamp do not support required mode.
If all good, then we will switch phc index to new one.
Signed-off-by: Hangbin Liu <liu...@gm...>
---
clock.c | 14 ++++++++++++++
config.c | 1 -
port.c | 35 ++++++++++++++++++++++++++++++++++-
3 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/clock.c b/clock.c
index bd2b91b..a9da8c6 100644
--- a/clock.c
+++ b/clock.c
@@ -38,6 +38,7 @@
#include "servo.h"
#include "stats.h"
#include "print.h"
+#include "rtnl.h"
#include "tlv.h"
#include "tsproc.h"
#include "uds.h"
@@ -834,6 +835,16 @@ int clock_required_modes(struct clock *c)
return required_modes;
}
+/*
+ * If we do not have a slave or the rtnl query failed, then use our
+ * own interface name as the time stamping interface name.
+ */
+static void ensure_ts_label(struct interface *iface)
+{
+ if (iface->ts_label[0] == '\0')
+ strncpy(iface->ts_label, iface->name, MAX_IFNAME_SIZE);
+}
+
struct clock *clock_create(enum clock_type type, struct config *config,
const char *phc_device)
{
@@ -945,6 +956,9 @@ struct clock *clock_create(enum clock_type type, struct config *config,
c->timestamping = timestamping;
required_modes = clock_required_modes(c);
STAILQ_FOREACH(iface, &config->interfaces, list) {
+ rtnl_get_ts_label(iface);
+ ensure_ts_label(iface);
+ sk_get_ts_info(iface->ts_label, &iface->ts_info);
if (iface->ts_info.valid &&
((iface->ts_info.so_timestamping & required_modes) != required_modes)) {
pr_err("interface '%s' does not support "
diff --git a/config.c b/config.c
index e6fe676..bbaf36e 100644
--- a/config.c
+++ b/config.c
@@ -633,7 +633,6 @@ struct interface *config_create_interface(char *name, struct config *cfg)
}
strncpy(iface->name, name, MAX_IFNAME_SIZE);
- sk_get_ts_info(iface->name, &iface->ts_info);
STAILQ_INSERT_TAIL(&cfg->interfaces, iface, list);
cfg->n_interfaces++;
diff --git a/port.c b/port.c
index 81d52ff..5f638c0 100644
--- a/port.c
+++ b/port.c
@@ -60,6 +60,7 @@ enum link_state {
LINK_DOWN = (1<<0),
LINK_UP = (1<<1),
LINK_STATE_CHANGED = (1<<3),
+ TS_LABEL_CHANGED = (1<<4),
};
struct nrate_estimator {
@@ -2231,6 +2232,8 @@ static void port_link_status(void *ctx, int linkup, int ts_index)
{
struct port *p = ctx;
int link_state;
+ char ts_label[MAX_IFNAME_SIZE + 1];
+ int required_modes;
link_state = linkup ? LINK_UP : LINK_DOWN;
if (p->link_status & link_state) {
@@ -2240,6 +2243,35 @@ static void port_link_status(void *ctx, int linkup, int ts_index)
pr_notice("port %hu: link %s", portnum(p), linkup ? "up" : "down");
}
+ /* ts_label changed */
+ if (if_indextoname(ts_index, ts_label) && strcmp(p->iface->ts_label, ts_label)) {
+ strncpy(p->iface->ts_label, ts_label, MAX_IFNAME_SIZE);
+ sk_get_ts_info(p->iface->ts_label, &p->iface->ts_info);
+
+ p->link_status |= TS_LABEL_CHANGED;
+ pr_notice("port %hu: ts label changed to %s", portnum(p), ts_label);
+ }
+
+ /* We set the link status to down by force if its timestamp not
+ * support required mode. But the link's status is actually up.
+ *
+ * So the next time we receive this link's rtnl message, we need
+ * to check the required_modes again. If still not support
+ * required_modes, then keep the link status down.
+ */
+ if (p->iface->ts_info.valid) {
+ required_modes = clock_required_modes(p->clock);
+ if ((p->iface->ts_info.so_timestamping & required_modes) != required_modes) {
+ pr_err("interface '%s' does not support requested "
+ "timestamping mode, set link status down by force.",
+ p->iface->ts_label);
+ p->link_status = LINK_DOWN | LINK_STATE_CHANGED;
+ } else if (p->link_status & TS_LABEL_CHANGED) {
+ p->phc_index = p->iface->ts_info.phc_index;
+ clock_switch_phc(p->clock, p->phc_index);
+ }
+ }
+
/*
* A port going down can affect the BMCA result.
* Force a state decision event.
@@ -2292,7 +2324,8 @@ enum fsm_event port_event(struct port *p, int fd_index)
rtnl_link_status(fd, p->name, port_link_status, p);
if (p->link_status == (LINK_UP | LINK_STATE_CHANGED))
return EV_FAULT_CLEARED;
- else if (p->link_status == (LINK_DOWN | LINK_STATE_CHANGED))
+ else if ((p->link_status == (LINK_DOWN | LINK_STATE_CHANGED)) ||
+ (p->link_status & TS_LABEL_CHANGED))
return EV_FAULT_DETECTED;
else
return EV_NONE;
--
2.5.5
|