|
|
4693f0 |
commit 17aa750a49ebaecfc7b063c770aa8d36f5078b2c
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Jul 10 15:39:28 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
rtnl: replace obsolete RTMGRP_LINK with RTNLGRP_LINK for nl groups
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/rtnl.c b/rtnl.c
|
|
|
4693f0 |
index 5cddc4b..d7a430d 100644
|
|
|
4693f0 |
--- a/rtnl.c
|
|
|
4693f0 |
+++ b/rtnl.c
|
|
|
4693f0 |
@@ -151,7 +151,7 @@ int rtnl_open(void)
|
|
|
4693f0 |
|
|
|
4693f0 |
memset(&sa, 0, sizeof(sa));
|
|
|
4693f0 |
sa.nl_family = AF_NETLINK;
|
|
|
4693f0 |
- sa.nl_groups = RTMGRP_LINK;
|
|
|
4693f0 |
+ sa.nl_groups = RTNLGRP_LINK;
|
|
|
4693f0 |
|
|
|
4693f0 |
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
|
|
4693f0 |
if (fd < 0) {
|
|
|
4693f0 |
commit c149a3dbc1b38e833de783ae863038562baca0fe
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Jul 10 15:39:29 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
port: add FD_RTNL event to track per-port status
|
|
|
4693f0 |
|
|
|
4693f0 |
With rtnl socket we can track link status per port(except UDS port).
|
|
|
4693f0 |
|
|
|
4693f0 |
We can make sure we get the correct interface and latest status with function
|
|
|
4693f0 |
port_link_status().
|
|
|
4693f0 |
|
|
|
4693f0 |
At the same time we need to set clock sde after link down. But we return
|
|
|
4693f0 |
EV_FAULT_DETECTED in port_event(), which will not set clock sde. So we need
|
|
|
4693f0 |
to set it in port_link_status().
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/clock.c b/clock.c
|
|
|
4693f0 |
index b6afba9..4c5c4e3 100644
|
|
|
4693f0 |
--- a/clock.c
|
|
|
4693f0 |
+++ b/clock.c
|
|
|
4693f0 |
@@ -1469,6 +1469,11 @@ struct PortIdentity clock_parent_identity(struct clock *c)
|
|
|
4693f0 |
return c->dad.pds.parentPortIdentity;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+void clock_set_sde(struct clock *c, int sde)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ c->sde = sde;
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
int clock_poll(struct clock *c)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
int cnt, i;
|
|
|
4693f0 |
diff --git a/clock.h b/clock.h
|
|
|
4693f0 |
index fcd9328..49ecb76 100644
|
|
|
4693f0 |
--- a/clock.h
|
|
|
4693f0 |
+++ b/clock.h
|
|
|
4693f0 |
@@ -205,6 +205,13 @@ void clock_peer_delay(struct clock *c, tmv_t ppd, tmv_t req, tmv_t rx,
|
|
|
4693f0 |
double nrr);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
+ * Set clock sde
|
|
|
4693f0 |
+ * @param c A pointer to a clock instance obtained with clock_create().
|
|
|
4693f0 |
+ * @param sde Pass one (1) if need a decision event and zero if not.
|
|
|
4693f0 |
+ */
|
|
|
4693f0 |
+void clock_set_sde(struct clock *c, int sde);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+/**
|
|
|
4693f0 |
* Poll for events and dispatch them.
|
|
|
4693f0 |
* @param c A pointer to a clock instance obtained with clock_create().
|
|
|
4693f0 |
* @return Zero on success, non-zero otherwise.
|
|
|
4693f0 |
diff --git a/fd.h b/fd.h
|
|
|
4693f0 |
index e328e98..23401f4 100644
|
|
|
4693f0 |
--- a/fd.h
|
|
|
4693f0 |
+++ b/fd.h
|
|
|
4693f0 |
@@ -31,6 +31,7 @@ enum {
|
|
|
4693f0 |
FD_QUALIFICATION_TIMER,
|
|
|
4693f0 |
FD_MANNO_TIMER,
|
|
|
4693f0 |
FD_SYNC_TX_TIMER,
|
|
|
4693f0 |
+ FD_RTNL,
|
|
|
4693f0 |
N_POLLFD,
|
|
|
4693f0 |
};
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/port.c b/port.c
|
|
|
4693f0 |
index ec02825..2896d1a 100644
|
|
|
4693f0 |
--- a/port.c
|
|
|
4693f0 |
+++ b/port.c
|
|
|
4693f0 |
@@ -23,6 +23,7 @@
|
|
|
4693f0 |
#include <string.h>
|
|
|
4693f0 |
#include <unistd.h>
|
|
|
4693f0 |
#include <sys/queue.h>
|
|
|
4693f0 |
+#include <net/if.h>
|
|
|
4693f0 |
|
|
|
4693f0 |
#include "bmc.h"
|
|
|
4693f0 |
#include "clock.h"
|
|
|
4693f0 |
@@ -32,6 +33,7 @@
|
|
|
4693f0 |
#include "phc.h"
|
|
|
4693f0 |
#include "port.h"
|
|
|
4693f0 |
#include "print.h"
|
|
|
4693f0 |
+#include "rtnl.h"
|
|
|
4693f0 |
#include "sk.h"
|
|
|
4693f0 |
#include "tlv.h"
|
|
|
4693f0 |
#include "tmv.h"
|
|
|
4693f0 |
@@ -1458,7 +1460,9 @@ static void port_disable(struct port *p)
|
|
|
4693f0 |
for (i = 0; i < N_TIMER_FDS; i++) {
|
|
|
4693f0 |
close(p->fda.fd[FD_ANNOUNCE_TIMER + i]);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
- port_clear_fda(p, N_POLLFD);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ /* Keep rtnl socket to get link status info. */
|
|
|
4693f0 |
+ port_clear_fda(p, FD_RTNL);
|
|
|
4693f0 |
clock_fda_changed(p->clock);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
@@ -1502,6 +1506,14 @@ static int port_initialize(struct port *p)
|
|
|
4693f0 |
if (port_set_announce_tmo(p))
|
|
|
4693f0 |
goto no_tmo;
|
|
|
4693f0 |
|
|
|
4693f0 |
+ /* No need to open rtnl socket on UDS port. */
|
|
|
4693f0 |
+ if (transport_type(p->trp) != TRANS_UDS) {
|
|
|
4693f0 |
+ if (p->fda.fd[FD_RTNL] == -1)
|
|
|
4693f0 |
+ p->fda.fd[FD_RTNL] = rtnl_open();
|
|
|
4693f0 |
+ if (p->fda.fd[FD_RTNL] >= 0)
|
|
|
4693f0 |
+ rtnl_link_query(p->fda.fd[FD_RTNL]);
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
port_nrate_initialize(p);
|
|
|
4693f0 |
|
|
|
4693f0 |
clock_fda_changed(p->clock);
|
|
|
4693f0 |
@@ -2025,6 +2037,10 @@ void port_close(struct port *p)
|
|
|
4693f0 |
if (port_is_enabled(p)) {
|
|
|
4693f0 |
port_disable(p);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (p->fda.fd[FD_RTNL] >= 0)
|
|
|
4693f0 |
+ rtnl_close(p->fda.fd[FD_RTNL]);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
transport_destroy(p->trp);
|
|
|
4693f0 |
tsproc_destroy(p->tsproc);
|
|
|
4693f0 |
if (p->fault_fd >= 0)
|
|
|
4693f0 |
@@ -2204,6 +2220,24 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
|
|
4693f0 |
}
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+static void port_link_status(void *ctx, int index, int linkup)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ struct port *p = ctx;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (index != if_nametoindex(p->name) || p->link_status == linkup)
|
|
|
4693f0 |
+ return;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ p->link_status = linkup;
|
|
|
4693f0 |
+ pr_notice("port %hu: link %s", portnum(p), linkup ? "up" : "down");
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ /*
|
|
|
4693f0 |
+ * A port going down can affect the BMCA result.
|
|
|
4693f0 |
+ * Force a state decision event.
|
|
|
4693f0 |
+ */
|
|
|
4693f0 |
+ if (!p->link_status)
|
|
|
4693f0 |
+ clock_set_sde(p->clock, 1);
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
enum fsm_event port_event(struct port *p, int fd_index)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
enum fsm_event event = EV_NONE;
|
|
|
4693f0 |
@@ -2242,6 +2276,11 @@ enum fsm_event port_event(struct port *p, int fd_index)
|
|
|
4693f0 |
pr_debug("port %hu: master sync timeout", portnum(p));
|
|
|
4693f0 |
port_set_sync_tx_tmo(p);
|
|
|
4693f0 |
return port_tx_sync(p) ? EV_FAULT_DETECTED : EV_NONE;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ case FD_RTNL:
|
|
|
4693f0 |
+ pr_debug("port %hu: received link status notification", portnum(p));
|
|
|
4693f0 |
+ rtnl_link_status(fd, port_link_status, p);
|
|
|
4693f0 |
+ return port_link_status_get(p) ? EV_FAULT_CLEARED : EV_FAULT_DETECTED;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
msg = msg_allocate();
|
|
|
4693f0 |
commit 25ec8a3b4e2222b394794ff830bd3583e9cf6c71
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Jul 10 15:39:30 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
clock: remove rtnl fd on clock
|
|
|
4693f0 |
|
|
|
4693f0 |
Remove rtnl fd on clock since we track the link status per port now.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/clock.c b/clock.c
|
|
|
4693f0 |
index 4c5c4e3..354f038 100644
|
|
|
4693f0 |
--- a/clock.c
|
|
|
4693f0 |
+++ b/clock.c
|
|
|
4693f0 |
@@ -39,7 +39,6 @@
|
|
|
4693f0 |
#include "servo.h"
|
|
|
4693f0 |
#include "stats.h"
|
|
|
4693f0 |
#include "print.h"
|
|
|
4693f0 |
-#include "rtnl.h"
|
|
|
4693f0 |
#include "sk.h"
|
|
|
4693f0 |
#include "tlv.h"
|
|
|
4693f0 |
#include "tsproc.h"
|
|
|
4693f0 |
@@ -274,9 +273,6 @@ void clock_destroy(struct clock *c)
|
|
|
4693f0 |
LIST_FOREACH_SAFE(p, &c->ports, list, tmp) {
|
|
|
4693f0 |
clock_remove_port(c, p);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
- if (c->pollfd[0].fd >= 0) {
|
|
|
4693f0 |
- rtnl_close(c->pollfd[0].fd);
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
port_close(c->uds_port);
|
|
|
4693f0 |
free(c->pollfd);
|
|
|
4693f0 |
hash_destroy(c->index2port, NULL);
|
|
|
4693f0 |
@@ -326,30 +322,6 @@ static void clock_freq_est_reset(struct clock *c)
|
|
|
4693f0 |
c->fest.count = 0;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
-static void clock_link_status(void *ctx, int index, int linkup)
|
|
|
4693f0 |
-{
|
|
|
4693f0 |
- struct clock *c = ctx;
|
|
|
4693f0 |
- struct port *p;
|
|
|
4693f0 |
- char key[16];
|
|
|
4693f0 |
-
|
|
|
4693f0 |
- snprintf(key, sizeof(key), "%d", index);
|
|
|
4693f0 |
- p = hash_lookup(c->index2port, key);
|
|
|
4693f0 |
- if (!p) {
|
|
|
4693f0 |
- return;
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
- port_link_status_set(p, linkup);
|
|
|
4693f0 |
- if (linkup) {
|
|
|
4693f0 |
- port_dispatch(p, EV_FAULT_CLEARED, 0);
|
|
|
4693f0 |
- } else {
|
|
|
4693f0 |
- port_dispatch(p, EV_FAULT_DETECTED, 0);
|
|
|
4693f0 |
- /*
|
|
|
4693f0 |
- * A port going down can affect the BMCA result.
|
|
|
4693f0 |
- * Force a state decision event.
|
|
|
4693f0 |
- */
|
|
|
4693f0 |
- c->sde = 1;
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
-}
|
|
|
4693f0 |
-
|
|
|
4693f0 |
static void clock_management_send_error(struct port *p,
|
|
|
4693f0 |
struct ptp_message *msg, int error_id)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
@@ -1133,10 +1105,6 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
|
|
4693f0 |
return NULL;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
- /* Open a RT netlink socket. */
|
|
|
4693f0 |
- c->pollfd[0].fd = rtnl_open();
|
|
|
4693f0 |
- c->pollfd[0].events = POLLIN|POLLPRI;
|
|
|
4693f0 |
-
|
|
|
4693f0 |
/* Create the UDS interface. */
|
|
|
4693f0 |
c->uds_port = port_open(phc_index, timestamping, 0, udsif, c);
|
|
|
4693f0 |
if (!c->uds_port) {
|
|
|
4693f0 |
@@ -1164,9 +1132,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
|
|
4693f0 |
port_dispatch(p, EV_INITIALIZE, 0);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
port_dispatch(c->uds_port, EV_INITIALIZE, 0);
|
|
|
4693f0 |
- if (c->pollfd[0].fd >= 0) {
|
|
|
4693f0 |
- rtnl_link_query(c->pollfd[0].fd);
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
return c;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
@@ -1231,12 +1197,9 @@ static int clock_resize_pollfd(struct clock *c, int new_nports)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct pollfd *new_pollfd;
|
|
|
4693f0 |
|
|
|
4693f0 |
- /*
|
|
|
4693f0 |
- * Need to allocate one descriptor for RT netlink and one
|
|
|
4693f0 |
- * whole extra block of fds for UDS.
|
|
|
4693f0 |
- */
|
|
|
4693f0 |
+ /* Need to allocate one whole extra block of fds for UDS. */
|
|
|
4693f0 |
new_pollfd = realloc(c->pollfd,
|
|
|
4693f0 |
- (1 + (new_nports + 1) * N_CLOCK_PFD) *
|
|
|
4693f0 |
+ (new_nports + 1) * N_CLOCK_PFD *
|
|
|
4693f0 |
sizeof(struct pollfd));
|
|
|
4693f0 |
if (!new_pollfd)
|
|
|
4693f0 |
return -1;
|
|
|
4693f0 |
@@ -1261,7 +1224,7 @@ static void clock_fill_pollfd(struct pollfd *dest, struct port *p)
|
|
|
4693f0 |
static void clock_check_pollfd(struct clock *c)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct port *p;
|
|
|
4693f0 |
- struct pollfd *dest = c->pollfd + 1;
|
|
|
4693f0 |
+ struct pollfd *dest = c->pollfd;
|
|
|
4693f0 |
|
|
|
4693f0 |
if (c->pollfd_valid)
|
|
|
4693f0 |
return;
|
|
|
4693f0 |
@@ -1482,7 +1445,7 @@ int clock_poll(struct clock *c)
|
|
|
4693f0 |
struct port *p;
|
|
|
4693f0 |
|
|
|
4693f0 |
clock_check_pollfd(c);
|
|
|
4693f0 |
- cnt = poll(c->pollfd, 1 + (c->nports + 1) * N_CLOCK_PFD, -1);
|
|
|
4693f0 |
+ cnt = poll(c->pollfd, (c->nports + 1) * N_CLOCK_PFD, -1);
|
|
|
4693f0 |
if (cnt < 0) {
|
|
|
4693f0 |
if (EINTR == errno) {
|
|
|
4693f0 |
return 0;
|
|
|
4693f0 |
@@ -1494,13 +1457,8 @@ int clock_poll(struct clock *c)
|
|
|
4693f0 |
return 0;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
- /* Check the RT netlink. */
|
|
|
4693f0 |
cur = c->pollfd;
|
|
|
4693f0 |
- if (cur->revents & (POLLIN|POLLPRI)) {
|
|
|
4693f0 |
- rtnl_link_status(cur->fd, clock_link_status, c);
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
|
|
|
4693f0 |
- cur++;
|
|
|
4693f0 |
LIST_FOREACH(p, &c->ports, list) {
|
|
|
4693f0 |
/* Let the ports handle their events. */
|
|
|
4693f0 |
for (i = 0; i < N_POLLFD; i++) {
|
|
|
4693f0 |
diff --git a/port.c b/port.c
|
|
|
4693f0 |
index 2896d1a..34837cc 100644
|
|
|
4693f0 |
--- a/port.c
|
|
|
4693f0 |
+++ b/port.c
|
|
|
4693f0 |
@@ -2411,12 +2411,6 @@ int port_link_status_get(struct port *p)
|
|
|
4693f0 |
return p->link_status;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
-void port_link_status_set(struct port *p, int up)
|
|
|
4693f0 |
-{
|
|
|
4693f0 |
- p->link_status = up ? 1 : 0;
|
|
|
4693f0 |
- pr_notice("port %hu: link %s", portnum(p), up ? "up" : "down");
|
|
|
4693f0 |
-}
|
|
|
4693f0 |
-
|
|
|
4693f0 |
int port_manage(struct port *p, struct port *ingress, struct ptp_message *msg)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct management_tlv *mgt;
|
|
|
4693f0 |
diff --git a/port.h b/port.h
|
|
|
4693f0 |
index b00bc64..60fd0a4 100644
|
|
|
4693f0 |
--- a/port.h
|
|
|
4693f0 |
+++ b/port.h
|
|
|
4693f0 |
@@ -132,13 +132,6 @@ int port_number(struct port *p);
|
|
|
4693f0 |
int port_link_status_get(struct port *p);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
- * Sets the link status for a port.
|
|
|
4693f0 |
- * @param p A port instance.
|
|
|
4693f0 |
- * @param up Pass one (1) if the link is up and zero if down.
|
|
|
4693f0 |
- */
|
|
|
4693f0 |
-void port_link_status_set(struct port *p, int up);
|
|
|
4693f0 |
-
|
|
|
4693f0 |
-/**
|
|
|
4693f0 |
* Manage a port according to a given message.
|
|
|
4693f0 |
* @param p A pointer previously obtained via port_open().
|
|
|
4693f0 |
* @param ingress The port on which 'msg' was received.
|
|
|
4693f0 |
commit 7c3f9579f0c230ee798644a26d664ebd3efc612f
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Jul 10 15:39:31 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
clock: remove hash table index2port
|
|
|
4693f0 |
|
|
|
4693f0 |
Remove index2port since we don't need it now.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/clock.c b/clock.c
|
|
|
4693f0 |
index 354f038..da15882 100644
|
|
|
4693f0 |
--- a/clock.c
|
|
|
4693f0 |
+++ b/clock.c
|
|
|
4693f0 |
@@ -31,7 +31,6 @@
|
|
|
4693f0 |
#include "clockcheck.h"
|
|
|
4693f0 |
#include "foreign.h"
|
|
|
4693f0 |
#include "filter.h"
|
|
|
4693f0 |
-#include "hash.h"
|
|
|
4693f0 |
#include "missing.h"
|
|
|
4693f0 |
#include "msg.h"
|
|
|
4693f0 |
#include "phc.h"
|
|
|
4693f0 |
@@ -39,7 +38,6 @@
|
|
|
4693f0 |
#include "servo.h"
|
|
|
4693f0 |
#include "stats.h"
|
|
|
4693f0 |
#include "print.h"
|
|
|
4693f0 |
-#include "sk.h"
|
|
|
4693f0 |
#include "tlv.h"
|
|
|
4693f0 |
#include "tsproc.h"
|
|
|
4693f0 |
#include "uds.h"
|
|
|
4693f0 |
@@ -96,7 +94,6 @@ struct clock {
|
|
|
4693f0 |
int nports; /* does not include the UDS port */
|
|
|
4693f0 |
int last_port_number;
|
|
|
4693f0 |
int sde;
|
|
|
4693f0 |
- struct hash *index2port;
|
|
|
4693f0 |
int free_running;
|
|
|
4693f0 |
int freq_est_interval;
|
|
|
4693f0 |
int grand_master_capable; /* for 802.1AS only */
|
|
|
4693f0 |
@@ -275,7 +272,6 @@ void clock_destroy(struct clock *c)
|
|
|
4693f0 |
}
|
|
|
4693f0 |
port_close(c->uds_port);
|
|
|
4693f0 |
free(c->pollfd);
|
|
|
4693f0 |
- hash_destroy(c->index2port, NULL);
|
|
|
4693f0 |
if (c->clkid != CLOCK_REALTIME) {
|
|
|
4693f0 |
phc_close(c->clkid);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
@@ -773,8 +769,6 @@ static int clock_add_port(struct clock *c, int phc_index,
|
|
|
4693f0 |
struct interface *iface)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct port *p, *piter, *lastp = NULL;
|
|
|
4693f0 |
- int fd, index;
|
|
|
4693f0 |
- char key[16];
|
|
|
4693f0 |
|
|
|
4693f0 |
if (clock_resize_pollfd(c, c->nports + 1)) {
|
|
|
4693f0 |
return -1;
|
|
|
4693f0 |
@@ -795,24 +789,6 @@ static int clock_add_port(struct clock *c, int phc_index,
|
|
|
4693f0 |
c->nports++;
|
|
|
4693f0 |
clock_fda_changed(c);
|
|
|
4693f0 |
|
|
|
4693f0 |
- /* Remember the index to port mapping, for link status tracking. */
|
|
|
4693f0 |
- fd = sk_interface_fd();
|
|
|
4693f0 |
- if (fd < 0) {
|
|
|
4693f0 |
- return -1;
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
- index = sk_interface_index(fd, iface->name);
|
|
|
4693f0 |
- if (index < 0) {
|
|
|
4693f0 |
- close(fd);
|
|
|
4693f0 |
- return -1;
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
- snprintf(key, sizeof(key), "%d", index);
|
|
|
4693f0 |
- if (hash_insert(c->index2port, key, p)) {
|
|
|
4693f0 |
- pr_err("failed to add port with index %d twice!", index);
|
|
|
4693f0 |
- close(fd);
|
|
|
4693f0 |
- return -1;
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
- close(fd);
|
|
|
4693f0 |
-
|
|
|
4693f0 |
return 0;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
@@ -1113,11 +1089,6 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
|
|
4693f0 |
}
|
|
|
4693f0 |
clock_fda_changed(c);
|
|
|
4693f0 |
|
|
|
4693f0 |
- c->index2port = hash_create();
|
|
|
4693f0 |
- if (!c->index2port) {
|
|
|
4693f0 |
- pr_err("failed create index-to-port hash table");
|
|
|
4693f0 |
- return NULL;
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
/* Create the ports. */
|
|
|
4693f0 |
STAILQ_FOREACH(iface, &config->interfaces, list) {
|
|
|
4693f0 |
if (clock_add_port(c, phc_index, timestamping, iface)) {
|
|
|
4693f0 |
commit 9e744d9e8a2dab6ec0ea5ece5ac25e7384264575
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:39 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
config: add new element ts_label in struct interface
|
|
|
4693f0 |
|
|
|
4693f0 |
Add new element ts_label in struct interface to track real ts interface.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/config.h b/config.h
|
|
|
4693f0 |
index 1cc7051..c79855e 100644
|
|
|
4693f0 |
--- a/config.h
|
|
|
4693f0 |
+++ b/config.h
|
|
|
4693f0 |
@@ -36,6 +36,7 @@
|
|
|
4693f0 |
struct interface {
|
|
|
4693f0 |
STAILQ_ENTRY(interface) list;
|
|
|
4693f0 |
char name[MAX_IFNAME_SIZE + 1];
|
|
|
4693f0 |
+ char ts_label[MAX_IFNAME_SIZE + 1];
|
|
|
4693f0 |
struct sk_ts_info ts_info;
|
|
|
4693f0 |
};
|
|
|
4693f0 |
|
|
|
4693f0 |
commit 7e294a4d047654f746c3fcdff7bce512be149e37
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:40 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
port: track interface info in port
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/port.c b/port.c
|
|
|
4693f0 |
index 34837cc..849a7c1 100644
|
|
|
4693f0 |
--- a/port.c
|
|
|
4693f0 |
+++ b/port.c
|
|
|
4693f0 |
@@ -68,6 +68,7 @@ struct nrate_estimator {
|
|
|
4693f0 |
struct port {
|
|
|
4693f0 |
LIST_ENTRY(port) list;
|
|
|
4693f0 |
char *name;
|
|
|
4693f0 |
+ struct interface *iface;
|
|
|
4693f0 |
struct clock *clock;
|
|
|
4693f0 |
struct transport *trp;
|
|
|
4693f0 |
enum timestamp_type timestamping;
|
|
|
4693f0 |
@@ -2619,6 +2620,7 @@ struct port *port_open(int phc_index,
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
p->name = interface->name;
|
|
|
4693f0 |
+ p->iface = interface;
|
|
|
4693f0 |
p->asymmetry = config_get_int(cfg, p->name, "delayAsymmetry");
|
|
|
4693f0 |
p->asymmetry <<= 16;
|
|
|
4693f0 |
p->announce_span = transport == TRANS_UDS ? 0 : ANNOUNCE_SPAN;
|
|
|
4693f0 |
commit 05bba46198cfc4ccfe0aff2e67e76d78898bbd96
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:41 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
rtnl: update rtgenmsg to ifinfomsg when request link info
|
|
|
4693f0 |
|
|
|
4693f0 |
The previous function use general message and will dump all interfaces'
|
|
|
4693f0 |
information. Now update with ifinfomsg so we could get specific interface's
|
|
|
4693f0 |
information.
|
|
|
4693f0 |
|
|
|
4693f0 |
We still could get all interfaces' info if set device to NULL.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/port.c b/port.c
|
|
|
4693f0 |
index 849a7c1..5b85d87 100644
|
|
|
4693f0 |
--- a/port.c
|
|
|
4693f0 |
+++ b/port.c
|
|
|
4693f0 |
@@ -1512,7 +1512,7 @@ static int port_initialize(struct port *p)
|
|
|
4693f0 |
if (p->fda.fd[FD_RTNL] == -1)
|
|
|
4693f0 |
p->fda.fd[FD_RTNL] = rtnl_open();
|
|
|
4693f0 |
if (p->fda.fd[FD_RTNL] >= 0)
|
|
|
4693f0 |
- rtnl_link_query(p->fda.fd[FD_RTNL]);
|
|
|
4693f0 |
+ rtnl_link_query(p->fda.fd[FD_RTNL], p->iface->name);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
port_nrate_initialize(p);
|
|
|
4693f0 |
diff --git a/rtnl.c b/rtnl.c
|
|
|
4693f0 |
index d7a430d..8ecf6fe 100644
|
|
|
4693f0 |
--- a/rtnl.c
|
|
|
4693f0 |
+++ b/rtnl.c
|
|
|
4693f0 |
@@ -42,7 +42,7 @@ int rtnl_close(int fd)
|
|
|
4693f0 |
return close(fd);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
-int rtnl_link_query(int fd)
|
|
|
4693f0 |
+int rtnl_link_query(int fd, char *device)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct sockaddr_nl sa;
|
|
|
4693f0 |
struct msghdr msg;
|
|
|
4693f0 |
@@ -51,19 +51,21 @@ int rtnl_link_query(int fd)
|
|
|
4693f0 |
|
|
|
4693f0 |
struct {
|
|
|
4693f0 |
struct nlmsghdr hdr;
|
|
|
4693f0 |
- struct rtgenmsg gen;
|
|
|
4693f0 |
+ struct ifinfomsg ifm;
|
|
|
4693f0 |
} __attribute__((packed)) request;
|
|
|
4693f0 |
|
|
|
4693f0 |
memset(&sa, 0, sizeof(sa));
|
|
|
4693f0 |
sa.nl_family = AF_NETLINK;
|
|
|
4693f0 |
|
|
|
4693f0 |
memset(&request, 0, sizeof(request));
|
|
|
4693f0 |
- request.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(request.gen));
|
|
|
4693f0 |
+ request.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(request.ifm));
|
|
|
4693f0 |
request.hdr.nlmsg_type = RTM_GETLINK;
|
|
|
4693f0 |
- request.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
|
|
|
4693f0 |
+ request.hdr.nlmsg_flags = NLM_F_REQUEST;
|
|
|
4693f0 |
request.hdr.nlmsg_seq = 1;
|
|
|
4693f0 |
request.hdr.nlmsg_pid = 0;
|
|
|
4693f0 |
- request.gen.rtgen_family = AF_UNSPEC;
|
|
|
4693f0 |
+ request.ifm.ifi_family = AF_UNSPEC;
|
|
|
4693f0 |
+ request.ifm.ifi_index = if_nametoindex(device ? device : "");
|
|
|
4693f0 |
+ request.ifm.ifi_change = 0xffffffff;
|
|
|
4693f0 |
|
|
|
4693f0 |
iov.iov_base = &request;
|
|
|
4693f0 |
iov.iov_len = sizeof(request);
|
|
|
4693f0 |
diff --git a/rtnl.h b/rtnl.h
|
|
|
4693f0 |
index f1871f2..5c93eec 100644
|
|
|
4693f0 |
--- a/rtnl.h
|
|
|
4693f0 |
+++ b/rtnl.h
|
|
|
4693f0 |
@@ -31,10 +31,11 @@ int rtnl_close(int fd);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
* Request the link status from the kernel.
|
|
|
4693f0 |
- * @param fd A socket obtained via rtnl_open().
|
|
|
4693f0 |
- * @return Zero on success, non-zero otherwise.
|
|
|
4693f0 |
+ * @param fd A socket obtained via rtnl_open().
|
|
|
4693f0 |
+ * @param device Interface name. Request all iface's status if set NULL.
|
|
|
4693f0 |
+ * @return Zero on success, non-zero otherwise.
|
|
|
4693f0 |
*/
|
|
|
4693f0 |
-int rtnl_link_query(int fd);
|
|
|
4693f0 |
+int rtnl_link_query(int fd, char *device);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
* Read kernel messages looking for a link up/down events.
|
|
|
4693f0 |
Backport of commit 80bc4d4c2f4d1c3c246091aa6f103bb7943202ec
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:42 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
rtnl: update function rtnl_link_status to get bond slave info
|
|
|
4693f0 |
|
|
|
4693f0 |
Update function rtnl_link_status to get bond slave info. Pass the slave index
|
|
|
4693f0 |
to call back functions. i.e. port_link_status.
|
|
|
4693f0 |
|
|
|
4693f0 |
Also check the interface index of rtnl message in function rtnl_link_status.
|
|
|
4693f0 |
Then we don't need to check it in port_link_status.
|
|
|
4693f0 |
|
|
|
4693f0 |
[BACKPORT: not included] Add ifndef IFLA_BOND_MAX in case we build linuxptp
|
|
|
4693f0 |
on kernel before v3.13-rc1.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/port.c b/port.c
|
|
|
4693f0 |
index 5b85d87..05fc321 100644
|
|
|
4693f0 |
--- a/port.c
|
|
|
4693f0 |
+++ b/port.c
|
|
|
4693f0 |
@@ -2221,11 +2221,11 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
|
|
4693f0 |
}
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
-static void port_link_status(void *ctx, int index, int linkup)
|
|
|
4693f0 |
+static void port_link_status(void *ctx, int linkup, int ts_index)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct port *p = ctx;
|
|
|
4693f0 |
|
|
|
4693f0 |
- if (index != if_nametoindex(p->name) || p->link_status == linkup)
|
|
|
4693f0 |
+ if (p->link_status == linkup)
|
|
|
4693f0 |
return;
|
|
|
4693f0 |
|
|
|
4693f0 |
p->link_status = linkup;
|
|
|
4693f0 |
@@ -2280,7 +2280,7 @@ enum fsm_event port_event(struct port *p, int fd_index)
|
|
|
4693f0 |
|
|
|
4693f0 |
case FD_RTNL:
|
|
|
4693f0 |
pr_debug("port %hu: received link status notification", portnum(p));
|
|
|
4693f0 |
- rtnl_link_status(fd, port_link_status, p);
|
|
|
4693f0 |
+ rtnl_link_status(fd, p->name, port_link_status, p);
|
|
|
4693f0 |
return port_link_status_get(p) ? EV_FAULT_CLEARED : EV_FAULT_DETECTED;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/rtnl.c b/rtnl.c
|
|
|
4693f0 |
index 8ecf6fe..3419873 100644
|
|
|
4693f0 |
--- a/rtnl.c
|
|
|
4693f0 |
+++ b/rtnl.c
|
|
|
4693f0 |
@@ -84,15 +85,79 @@ int rtnl_link_query(int fd, char *device)
|
|
|
4693f0 |
return 0;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
-int rtnl_link_status(int fd, rtnl_callback cb, void *ctx)
|
|
|
4693f0 |
+static inline __u32 rta_getattr_u32(const struct rtattr *rta)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
- int index, len;
|
|
|
4693f0 |
+ return *(__u32 *)RTA_DATA(rta);
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+static inline const char *rta_getattr_str(const struct rtattr *rta)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ return (const char *)RTA_DATA(rta);
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+static int rtnl_rtattr_parse(struct rtattr *tb[], int max, struct rtattr *rta, int len)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ unsigned short type;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ memset(tb, 0, sizeof(struct rtattr *) * max);
|
|
|
4693f0 |
+ while (RTA_OK(rta, len)) {
|
|
|
4693f0 |
+ type = rta->rta_type;
|
|
|
4693f0 |
+ if ((type < max) && (!tb[type]))
|
|
|
4693f0 |
+ tb[type] = rta;
|
|
|
4693f0 |
+ rta = RTA_NEXT(rta, len);
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ if (len) {
|
|
|
4693f0 |
+ pr_err("Length mismatch: len %d, rta_len=%d\n", len, rta->rta_len);
|
|
|
4693f0 |
+ return -1;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ return 0;
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+static inline int rtnl_nested_rtattr_parse(struct rtattr *tb[], int max, struct rtattr *rta)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ return rtnl_rtattr_parse(tb, max, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+static int rtnl_linkinfo_parse(struct rtattr *rta)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ int index = -1;
|
|
|
4693f0 |
+ const char *kind;
|
|
|
4693f0 |
+ struct rtattr *linkinfo[IFLA_INFO_MAX];
|
|
|
4693f0 |
+ struct rtattr *bond[IFLA_BOND_MAX];
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (rtnl_nested_rtattr_parse(linkinfo, IFLA_INFO_MAX, rta) < 0)
|
|
|
4693f0 |
+ return -1;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (linkinfo[IFLA_INFO_KIND]) {
|
|
|
4693f0 |
+ kind = rta_getattr_str(linkinfo[IFLA_INFO_KIND]);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (kind && !strncmp(kind, "bond", 4) &&
|
|
|
4693f0 |
+ linkinfo[IFLA_INFO_DATA]) {
|
|
|
4693f0 |
+ if (rtnl_nested_rtattr_parse(bond, IFLA_BOND_MAX,
|
|
|
4693f0 |
+ linkinfo[IFLA_INFO_DATA]) < 0)
|
|
|
4693f0 |
+ return -1;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (bond[IFLA_BOND_ACTIVE_SLAVE]) {
|
|
|
4693f0 |
+ index = rta_getattr_u32(bond[IFLA_BOND_ACTIVE_SLAVE]);
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ return index;
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+int rtnl_link_status(int fd, char *device, rtnl_callback cb, void *ctx)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ int index, len, link_up;
|
|
|
4693f0 |
+ int slave_index = -1;
|
|
|
4693f0 |
struct iovec iov;
|
|
|
4693f0 |
struct sockaddr_nl sa;
|
|
|
4693f0 |
struct msghdr msg;
|
|
|
4693f0 |
struct nlmsghdr *nh;
|
|
|
4693f0 |
struct ifinfomsg *info = NULL;
|
|
|
4693f0 |
+ struct rtattr *tb[IFLA_MAX+1];
|
|
|
4693f0 |
|
|
|
4693f0 |
+ index = if_nametoindex(device);
|
|
|
4693f0 |
if (!rtnl_buf) {
|
|
|
4693f0 |
rtnl_len = 4096;
|
|
|
4693f0 |
rtnl_buf = malloc(rtnl_len);
|
|
|
4693f0 |
@@ -135,14 +200,27 @@ int rtnl_link_status(int fd, rtnl_callback cb, void *ctx)
|
|
|
4693f0 |
nh = (struct nlmsghdr *) rtnl_buf;
|
|
|
4693f0 |
|
|
|
4693f0 |
for ( ; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
|
|
|
4693f0 |
- if (nh->nlmsg_type == RTM_NEWLINK) {
|
|
|
4693f0 |
- info = NLMSG_DATA(nh);
|
|
|
4693f0 |
- index = info->ifi_index;
|
|
|
4693f0 |
- pr_debug("interface index %d is %s", index,
|
|
|
4693f0 |
- info->ifi_flags & IFF_RUNNING ? "up" : "down");
|
|
|
4693f0 |
- cb(ctx, index, info->ifi_flags & IFF_RUNNING ? 1 : 0);
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
+ if (nh->nlmsg_type != RTM_NEWLINK)
|
|
|
4693f0 |
+ continue;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ info = NLMSG_DATA(nh);
|
|
|
4693f0 |
+ if (index != info->ifi_index)
|
|
|
4693f0 |
+ continue;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ link_up = info->ifi_flags & IFF_RUNNING ? 1 : 0;
|
|
|
4693f0 |
+ pr_debug("interface index %d is %s", index,
|
|
|
4693f0 |
+ link_up ? "up" : "down");
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ rtnl_rtattr_parse(tb, IFLA_MAX, IFLA_RTA(info),
|
|
|
4693f0 |
+ IFLA_PAYLOAD(nh));
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (tb[IFLA_LINKINFO])
|
|
|
4693f0 |
+ slave_index = rtnl_linkinfo_parse(tb[IFLA_LINKINFO]);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (cb)
|
|
|
4693f0 |
+ cb(ctx, link_up, slave_index);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
return 0;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/rtnl.h b/rtnl.h
|
|
|
4693f0 |
index 5c93eec..6eced2d 100644
|
|
|
4693f0 |
--- a/rtnl.h
|
|
|
4693f0 |
+++ b/rtnl.h
|
|
|
4693f0 |
@@ -20,7 +20,7 @@
|
|
|
4693f0 |
#ifndef HAVE_RTNL_H
|
|
|
4693f0 |
#define HAVE_RTNL_H
|
|
|
4693f0 |
|
|
|
4693f0 |
-typedef void (*rtnl_callback)(void *ctx, int index, int linkup);
|
|
|
4693f0 |
+typedef void (*rtnl_callback)(void *ctx, int linkup, int ts_index);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
* Close a RT netlink socket.
|
|
|
4693f0 |
@@ -39,12 +39,13 @@ int rtnl_link_query(int fd, char *device);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
* Read kernel messages looking for a link up/down events.
|
|
|
4693f0 |
- * @param fd Readable socket obtained via rtnl_open().
|
|
|
4693f0 |
- * @param cb Callback function to be invoked on each event.
|
|
|
4693f0 |
- * @param ctx Private context passed to the callback.
|
|
|
4693f0 |
- * @return Zero on success, non-zero otherwise.
|
|
|
4693f0 |
+ * @param fd Readable socket obtained via rtnl_open().
|
|
|
4693f0 |
+ * @param device The device which we need to get link info.
|
|
|
4693f0 |
+ * @param cb Callback function to be invoked on each event.
|
|
|
4693f0 |
+ * @param ctx Private context passed to the callback.
|
|
|
4693f0 |
+ * @return Zero on success, non-zero otherwise.
|
|
|
4693f0 |
*/
|
|
|
4693f0 |
-int rtnl_link_status(int fd, rtnl_callback cb, void *ctx);
|
|
|
4693f0 |
+int rtnl_link_status(int fd, char *device, rtnl_callback cb, void *ctx);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
* Open a RT netlink socket for monitoring link state.
|
|
|
4693f0 |
commit 6d1e2a62bdb4f6353e3a9006f2d603031f4648e6
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:43 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
rtnl: add function rtnl_get_ts_label to get interface ts_label info
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/rtnl.c b/rtnl.c
|
|
|
4693f0 |
index 3419873..cea936b 100644
|
|
|
4693f0 |
--- a/rtnl.c
|
|
|
4693f0 |
+++ b/rtnl.c
|
|
|
4693f0 |
@@ -43,6 +43,37 @@ int rtnl_close(int fd)
|
|
|
4693f0 |
return close(fd);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+static void rtnl_get_ts_label_callback(void *ctx, int linkup, int ts_index)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ int *dst = ctx;
|
|
|
4693f0 |
+ *dst = ts_index;
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+int rtnl_get_ts_label(struct interface *iface)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ int err, fd;
|
|
|
4693f0 |
+ int ts_index = -1;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ fd = rtnl_open();
|
|
|
4693f0 |
+ if (fd < 0)
|
|
|
4693f0 |
+ return fd;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ err = rtnl_link_query(fd, iface->name);
|
|
|
4693f0 |
+ if (err) {
|
|
|
4693f0 |
+ goto no_info;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ rtnl_link_status(fd, iface->name, rtnl_get_ts_label_callback, &ts_index);
|
|
|
4693f0 |
+ if (ts_index > 0 && if_indextoname(ts_index, iface->ts_label))
|
|
|
4693f0 |
+ err = 0;
|
|
|
4693f0 |
+ else
|
|
|
4693f0 |
+ err = -1;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+no_info:
|
|
|
4693f0 |
+ rtnl_close(fd);
|
|
|
4693f0 |
+ return err;
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
int rtnl_link_query(int fd, char *device)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct sockaddr_nl sa;
|
|
|
4693f0 |
diff --git a/rtnl.h b/rtnl.h
|
|
|
4693f0 |
index 6eced2d..2906d74 100644
|
|
|
4693f0 |
--- a/rtnl.h
|
|
|
4693f0 |
+++ b/rtnl.h
|
|
|
4693f0 |
@@ -20,6 +20,8 @@
|
|
|
4693f0 |
#ifndef HAVE_RTNL_H
|
|
|
4693f0 |
#define HAVE_RTNL_H
|
|
|
4693f0 |
|
|
|
4693f0 |
+#include "config.h"
|
|
|
4693f0 |
+
|
|
|
4693f0 |
typedef void (*rtnl_callback)(void *ctx, int linkup, int ts_index);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
@@ -30,6 +32,13 @@ typedef void (*rtnl_callback)(void *ctx, int linkup, int ts_index);
|
|
|
4693f0 |
int rtnl_close(int fd);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
+ * Get interface ts_label information
|
|
|
4693f0 |
+ * @param iface struct interface.
|
|
|
4693f0 |
+ * @return Zero on success, or -1 on error.
|
|
|
4693f0 |
+ */
|
|
|
4693f0 |
+int rtnl_get_ts_label(struct interface *iface);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+/**
|
|
|
4693f0 |
* Request the link status from the kernel.
|
|
|
4693f0 |
* @param fd A socket obtained via rtnl_open().
|
|
|
4693f0 |
* @param device Interface name. Request all iface's status if set NULL.
|
|
|
4693f0 |
commit b65b1d5f3b5d8e85e47e9cf19c2e5aa6dc2ebd77
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:44 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
port: update port link_status to enum
|
|
|
4693f0 |
|
|
|
4693f0 |
Besides link up and down, we may also receive other rtnl messages, like
|
|
|
4693f0 |
bond slave changed info, which link state keeps the same.
|
|
|
4693f0 |
|
|
|
4693f0 |
So we should return EV_FAULT_CLEARED only when both LINK_UP and
|
|
|
4693f0 |
LINK_STATE_CHANGED.
|
|
|
4693f0 |
|
|
|
4693f0 |
When the link state keep the same, we should return EV_NONE.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/port.c b/port.c
|
|
|
4693f0 |
index 05fc321..81d52ff 100644
|
|
|
4693f0 |
--- a/port.c
|
|
|
4693f0 |
+++ b/port.c
|
|
|
4693f0 |
@@ -56,6 +56,12 @@ enum syfu_event {
|
|
|
4693f0 |
FUP_MATCH,
|
|
|
4693f0 |
};
|
|
|
4693f0 |
|
|
|
4693f0 |
+enum link_state {
|
|
|
4693f0 |
+ LINK_DOWN = (1<<0),
|
|
|
4693f0 |
+ LINK_UP = (1<<1),
|
|
|
4693f0 |
+ LINK_STATE_CHANGED = (1<<3),
|
|
|
4693f0 |
+};
|
|
|
4693f0 |
+
|
|
|
4693f0 |
struct nrate_estimator {
|
|
|
4693f0 |
double ratio;
|
|
|
4693f0 |
tmv_t origin1;
|
|
|
4693f0 |
@@ -122,7 +128,7 @@ struct port {
|
|
|
4693f0 |
int path_trace_enabled;
|
|
|
4693f0 |
int rx_timestamp_offset;
|
|
|
4693f0 |
int tx_timestamp_offset;
|
|
|
4693f0 |
- int link_status;
|
|
|
4693f0 |
+ enum link_state link_status;
|
|
|
4693f0 |
struct fault_interval flt_interval_pertype[FT_CNT];
|
|
|
4693f0 |
enum fault_type last_fault_type;
|
|
|
4693f0 |
unsigned int versionNumber; /*UInteger4*/
|
|
|
4693f0 |
@@ -2224,18 +2230,21 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
|
|
4693f0 |
static void port_link_status(void *ctx, int linkup, int ts_index)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct port *p = ctx;
|
|
|
4693f0 |
+ int link_state;
|
|
|
4693f0 |
|
|
|
4693f0 |
- if (p->link_status == linkup)
|
|
|
4693f0 |
- return;
|
|
|
4693f0 |
-
|
|
|
4693f0 |
- p->link_status = linkup;
|
|
|
4693f0 |
- pr_notice("port %hu: link %s", portnum(p), linkup ? "up" : "down");
|
|
|
4693f0 |
+ link_state = linkup ? LINK_UP : LINK_DOWN;
|
|
|
4693f0 |
+ if (p->link_status & link_state) {
|
|
|
4693f0 |
+ p->link_status = link_state;
|
|
|
4693f0 |
+ } else {
|
|
|
4693f0 |
+ p->link_status = link_state | LINK_STATE_CHANGED;
|
|
|
4693f0 |
+ pr_notice("port %hu: link %s", portnum(p), linkup ? "up" : "down");
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
|
|
|
4693f0 |
/*
|
|
|
4693f0 |
* A port going down can affect the BMCA result.
|
|
|
4693f0 |
* Force a state decision event.
|
|
|
4693f0 |
*/
|
|
|
4693f0 |
- if (!p->link_status)
|
|
|
4693f0 |
+ if (p->link_status & LINK_DOWN)
|
|
|
4693f0 |
clock_set_sde(p->clock, 1);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
@@ -2281,7 +2290,12 @@ enum fsm_event port_event(struct port *p, int fd_index)
|
|
|
4693f0 |
case FD_RTNL:
|
|
|
4693f0 |
pr_debug("port %hu: received link status notification", portnum(p));
|
|
|
4693f0 |
rtnl_link_status(fd, p->name, port_link_status, p);
|
|
|
4693f0 |
- return port_link_status_get(p) ? EV_FAULT_CLEARED : EV_FAULT_DETECTED;
|
|
|
4693f0 |
+ if (p->link_status == (LINK_UP | LINK_STATE_CHANGED))
|
|
|
4693f0 |
+ return EV_FAULT_CLEARED;
|
|
|
4693f0 |
+ else if (p->link_status == (LINK_DOWN | LINK_STATE_CHANGED))
|
|
|
4693f0 |
+ return EV_FAULT_DETECTED;
|
|
|
4693f0 |
+ else
|
|
|
4693f0 |
+ return EV_NONE;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
msg = msg_allocate();
|
|
|
4693f0 |
@@ -2409,7 +2423,7 @@ int port_number(struct port *p)
|
|
|
4693f0 |
|
|
|
4693f0 |
int port_link_status_get(struct port *p)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
- return p->link_status;
|
|
|
4693f0 |
+ return !!(p->link_status & LINK_UP);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
int port_manage(struct port *p, struct port *ingress, struct ptp_message *msg)
|
|
|
4693f0 |
@@ -2630,7 +2644,7 @@ struct port *port_open(int phc_index,
|
|
|
4693f0 |
p->path_trace_enabled = config_get_int(cfg, p->name, "path_trace_enabled");
|
|
|
4693f0 |
p->rx_timestamp_offset = config_get_int(cfg, p->name, "ingressLatency");
|
|
|
4693f0 |
p->tx_timestamp_offset = config_get_int(cfg, p->name, "egressLatency");
|
|
|
4693f0 |
- p->link_status = 1;
|
|
|
4693f0 |
+ p->link_status = LINK_UP;
|
|
|
4693f0 |
p->clock = clock;
|
|
|
4693f0 |
p->trp = transport_create(cfg, transport);
|
|
|
4693f0 |
if (!p->trp)
|
|
|
4693f0 |
commit 1440f093847a79d0e80ea6b4bca011ddd87090d0
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:45 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
clock: add clock_required_modes to obtain the required time stamping mode
|
|
|
4693f0 |
|
|
|
4693f0 |
Separate required_modes setting from clock_create so we can obtain the
|
|
|
4693f0 |
required time stamping flags from other place.
|
|
|
4693f0 |
|
|
|
4693f0 |
Add enum timestamping in struct clock to store the time stamping mode.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/clock.c b/clock.c
|
|
|
4693f0 |
index 9d224c9..5926a3c 100644
|
|
|
4693f0 |
--- a/clock.c
|
|
|
4693f0 |
+++ b/clock.c
|
|
|
4693f0 |
@@ -105,6 +105,7 @@ struct clock {
|
|
|
4693f0 |
int time_flags; /* grand master role */
|
|
|
4693f0 |
int time_source; /* grand master role */
|
|
|
4693f0 |
enum servo_state servo_state;
|
|
|
4693f0 |
+ enum timestamp_type timestamping;
|
|
|
4693f0 |
tmv_t master_offset;
|
|
|
4693f0 |
tmv_t path_delay;
|
|
|
4693f0 |
tmv_t ingress_ts;
|
|
|
4693f0 |
@@ -803,6 +804,34 @@ static void clock_remove_port(struct clock *c, struct port *p)
|
|
|
4693f0 |
port_close(p);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+int clock_required_modes(struct clock *c)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ int required_modes = 0;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ switch (c->timestamping) {
|
|
|
4693f0 |
+ case TS_SOFTWARE:
|
|
|
4693f0 |
+ required_modes |= SOF_TIMESTAMPING_TX_SOFTWARE |
|
|
|
4693f0 |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
|
|
|
4693f0 |
+ SOF_TIMESTAMPING_SOFTWARE;
|
|
|
4693f0 |
+ break;
|
|
|
4693f0 |
+ case TS_LEGACY_HW:
|
|
|
4693f0 |
+ required_modes |= SOF_TIMESTAMPING_TX_HARDWARE |
|
|
|
4693f0 |
+ SOF_TIMESTAMPING_RX_HARDWARE |
|
|
|
4693f0 |
+ SOF_TIMESTAMPING_SYS_HARDWARE;
|
|
|
4693f0 |
+ break;
|
|
|
4693f0 |
+ case TS_HARDWARE:
|
|
|
4693f0 |
+ case TS_ONESTEP:
|
|
|
4693f0 |
+ required_modes |= SOF_TIMESTAMPING_TX_HARDWARE |
|
|
|
4693f0 |
+ SOF_TIMESTAMPING_RX_HARDWARE |
|
|
|
4693f0 |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
|
|
|
4693f0 |
+ break;
|
|
|
4693f0 |
+ default:
|
|
|
4693f0 |
+ break;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ return required_modes;
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
struct clock *clock_create(enum clock_type type, struct config *config,
|
|
|
4693f0 |
const char *phc_device)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
@@ -911,24 +940,8 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
/* Check the time stamping mode on each interface. */
|
|
|
4693f0 |
- switch (timestamping) {
|
|
|
4693f0 |
- case TS_SOFTWARE:
|
|
|
4693f0 |
- required_modes |= SOF_TIMESTAMPING_TX_SOFTWARE |
|
|
|
4693f0 |
- SOF_TIMESTAMPING_RX_SOFTWARE |
|
|
|
4693f0 |
- SOF_TIMESTAMPING_SOFTWARE;
|
|
|
4693f0 |
- break;
|
|
|
4693f0 |
- case TS_LEGACY_HW:
|
|
|
4693f0 |
- required_modes |= SOF_TIMESTAMPING_TX_HARDWARE |
|
|
|
4693f0 |
- SOF_TIMESTAMPING_RX_HARDWARE |
|
|
|
4693f0 |
- SOF_TIMESTAMPING_SYS_HARDWARE;
|
|
|
4693f0 |
- break;
|
|
|
4693f0 |
- case TS_HARDWARE:
|
|
|
4693f0 |
- case TS_ONESTEP:
|
|
|
4693f0 |
- required_modes |= SOF_TIMESTAMPING_TX_HARDWARE |
|
|
|
4693f0 |
- SOF_TIMESTAMPING_RX_HARDWARE |
|
|
|
4693f0 |
- SOF_TIMESTAMPING_RAW_HARDWARE;
|
|
|
4693f0 |
- break;
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
+ c->timestamping = timestamping;
|
|
|
4693f0 |
+ required_modes = clock_required_modes(c);
|
|
|
4693f0 |
STAILQ_FOREACH(iface, &config->interfaces, list) {
|
|
|
4693f0 |
if (iface->ts_info.valid &&
|
|
|
4693f0 |
((iface->ts_info.so_timestamping & required_modes) != required_modes)) {
|
|
|
4693f0 |
diff --git a/clock.h b/clock.h
|
|
|
4693f0 |
index 49ecb76..986d363 100644
|
|
|
4693f0 |
--- a/clock.h
|
|
|
4693f0 |
+++ b/clock.h
|
|
|
4693f0 |
@@ -73,6 +73,14 @@ UInteger8 clock_class(struct clock *c);
|
|
|
4693f0 |
struct config *clock_config(struct clock *c);
|
|
|
4693f0 |
|
|
|
4693f0 |
/**
|
|
|
4693f0 |
+ * Obtains the required time stamping mode.
|
|
|
4693f0 |
+ * @param c The clock instance.
|
|
|
4693f0 |
+ * @return The value of required time stamping mode, which is a bit mask
|
|
|
4693f0 |
+ * of SOF_TIMESTAMPING_ flags.
|
|
|
4693f0 |
+ */
|
|
|
4693f0 |
+int clock_required_modes(struct clock *c);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+/**
|
|
|
4693f0 |
* Create a clock instance. There can only be one clock in any system,
|
|
|
4693f0 |
* so subsequent calls will destroy the previous clock instance.
|
|
|
4693f0 |
*
|
|
|
4693f0 |
commit 536a71031d5c7689fd186ff550dc11cf743e02cb
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:46 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
ptp4l: use ts label to get ts info
|
|
|
4693f0 |
|
|
|
4693f0 |
Now the ts label will be either the bond active slave or the interface
|
|
|
4693f0 |
name, which is the exactly interface we need to get ts info.
|
|
|
4693f0 |
|
|
|
4693f0 |
When the link down/up or there is a fail over and ts_label changed, the
|
|
|
4693f0 |
phc index may also changed. So we need to check get new ts info and check
|
|
|
4693f0 |
clock_required_modes. We will set the link to LINK_DOWN by force if
|
|
|
4693f0 |
the new ts_label's timestamp do not support required mode.
|
|
|
4693f0 |
|
|
|
4693f0 |
If all good, then we set phc index to new one. Also sync clock interval
|
|
|
4693f0 |
after switch phc.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/clock.c b/clock.c
|
|
|
4693f0 |
index 5926a3c..41c8f81 100644
|
|
|
4693f0 |
--- a/clock.c
|
|
|
4693f0 |
+++ b/clock.c
|
|
|
4693f0 |
@@ -38,6 +38,7 @@
|
|
|
4693f0 |
#include "servo.h"
|
|
|
4693f0 |
#include "stats.h"
|
|
|
4693f0 |
#include "print.h"
|
|
|
4693f0 |
+#include "rtnl.h"
|
|
|
4693f0 |
#include "tlv.h"
|
|
|
4693f0 |
#include "tsproc.h"
|
|
|
4693f0 |
#include "uds.h"
|
|
|
4693f0 |
@@ -832,6 +833,16 @@ int clock_required_modes(struct clock *c)
|
|
|
4693f0 |
return required_modes;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+/*
|
|
|
4693f0 |
+ * If we do not have a slave or the rtnl query failed, then use our
|
|
|
4693f0 |
+ * own interface name as the time stamping interface name.
|
|
|
4693f0 |
+ */
|
|
|
4693f0 |
+static void ensure_ts_label(struct interface *iface)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ if (iface->ts_label[0] == '\0')
|
|
|
4693f0 |
+ strncpy(iface->ts_label, iface->name, MAX_IFNAME_SIZE);
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
struct clock *clock_create(enum clock_type type, struct config *config,
|
|
|
4693f0 |
const char *phc_device)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
@@ -943,6 +954,9 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
|
|
4693f0 |
c->timestamping = timestamping;
|
|
|
4693f0 |
required_modes = clock_required_modes(c);
|
|
|
4693f0 |
STAILQ_FOREACH(iface, &config->interfaces, list) {
|
|
|
4693f0 |
+ rtnl_get_ts_label(iface);
|
|
|
4693f0 |
+ ensure_ts_label(iface);
|
|
|
4693f0 |
+ sk_get_ts_info(iface->ts_label, &iface->ts_info);
|
|
|
4693f0 |
if (iface->ts_info.valid &&
|
|
|
4693f0 |
((iface->ts_info.so_timestamping & required_modes) != required_modes)) {
|
|
|
4693f0 |
pr_err("interface '%s' does not support "
|
|
|
4693f0 |
diff --git a/config.c b/config.c
|
|
|
4693f0 |
index e6fe676..bbaf36e 100644
|
|
|
4693f0 |
--- a/config.c
|
|
|
4693f0 |
+++ b/config.c
|
|
|
4693f0 |
@@ -633,7 +633,6 @@ struct interface *config_create_interface(char *name, struct config *cfg)
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
strncpy(iface->name, name, MAX_IFNAME_SIZE);
|
|
|
4693f0 |
- sk_get_ts_info(iface->name, &iface->ts_info);
|
|
|
4693f0 |
STAILQ_INSERT_TAIL(&cfg->interfaces, iface, list);
|
|
|
4693f0 |
cfg->n_interfaces++;
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/port.c b/port.c
|
|
|
4693f0 |
index 81d52ff..615c800 100644
|
|
|
4693f0 |
--- a/port.c
|
|
|
4693f0 |
+++ b/port.c
|
|
|
4693f0 |
@@ -60,6 +60,7 @@ enum link_state {
|
|
|
4693f0 |
LINK_DOWN = (1<<0),
|
|
|
4693f0 |
LINK_UP = (1<<1),
|
|
|
4693f0 |
LINK_STATE_CHANGED = (1<<3),
|
|
|
4693f0 |
+ TS_LABEL_CHANGED = (1<<4),
|
|
|
4693f0 |
};
|
|
|
4693f0 |
|
|
|
4693f0 |
struct nrate_estimator {
|
|
|
4693f0 |
@@ -2231,6 +2232,8 @@ static void port_link_status(void *ctx, int linkup, int ts_index)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct port *p = ctx;
|
|
|
4693f0 |
int link_state;
|
|
|
4693f0 |
+ char ts_label[MAX_IFNAME_SIZE + 1] = {0};
|
|
|
4693f0 |
+ int required_modes;
|
|
|
4693f0 |
|
|
|
4693f0 |
link_state = linkup ? LINK_UP : LINK_DOWN;
|
|
|
4693f0 |
if (p->link_status & link_state) {
|
|
|
4693f0 |
@@ -2240,6 +2243,39 @@ static void port_link_status(void *ctx, int linkup, int ts_index)
|
|
|
4693f0 |
pr_notice("port %hu: link %s", portnum(p), linkup ? "up" : "down");
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+ /* ts_label changed */
|
|
|
4693f0 |
+ if (if_indextoname(ts_index, ts_label) && strcmp(p->iface->ts_label, ts_label)) {
|
|
|
4693f0 |
+ strncpy(p->iface->ts_label, ts_label, MAX_IFNAME_SIZE);
|
|
|
4693f0 |
+ p->link_status |= TS_LABEL_CHANGED;
|
|
|
4693f0 |
+ pr_notice("port %hu: ts label changed to %s", portnum(p), ts_label);
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ /* Both link down/up and change ts_label may change phc index. */
|
|
|
4693f0 |
+ if (p->link_status & LINK_UP &&
|
|
|
4693f0 |
+ (p->link_status & LINK_STATE_CHANGED || p->link_status & TS_LABEL_CHANGED)) {
|
|
|
4693f0 |
+ sk_get_ts_info(p->iface->ts_label, &p->iface->ts_info);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ /* Only switch phc with HW time stamping mode */
|
|
|
4693f0 |
+ if (p->phc_index >= 0 && p->iface->ts_info.valid) {
|
|
|
4693f0 |
+ required_modes = clock_required_modes(p->clock);
|
|
|
4693f0 |
+ if ((p->iface->ts_info.so_timestamping & required_modes) != required_modes) {
|
|
|
4693f0 |
+ pr_err("interface '%s' does not support requested "
|
|
|
4693f0 |
+ "timestamping mode, set link status down by force.",
|
|
|
4693f0 |
+ p->iface->ts_label);
|
|
|
4693f0 |
+ p->link_status = LINK_DOWN | LINK_STATE_CHANGED;
|
|
|
4693f0 |
+ } else if (p->phc_index != p->iface->ts_info.phc_index) {
|
|
|
4693f0 |
+ p->phc_index = p->iface->ts_info.phc_index;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (clock_switch_phc(p->clock, p->phc_index)) {
|
|
|
4693f0 |
+ p->last_fault_type = FT_SWITCH_PHC;
|
|
|
4693f0 |
+ port_dispatch(p, EV_FAULT_DETECTED, 0);
|
|
|
4693f0 |
+ return;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ clock_sync_interval(p->clock, p->log_sync_interval);
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
/*
|
|
|
4693f0 |
* A port going down can affect the BMCA result.
|
|
|
4693f0 |
* Force a state decision event.
|
|
|
4693f0 |
@@ -2292,7 +2328,8 @@ enum fsm_event port_event(struct port *p, int fd_index)
|
|
|
4693f0 |
rtnl_link_status(fd, p->name, port_link_status, p);
|
|
|
4693f0 |
if (p->link_status == (LINK_UP | LINK_STATE_CHANGED))
|
|
|
4693f0 |
return EV_FAULT_CLEARED;
|
|
|
4693f0 |
- else if (p->link_status == (LINK_DOWN | LINK_STATE_CHANGED))
|
|
|
4693f0 |
+ else if ((p->link_status == (LINK_DOWN | LINK_STATE_CHANGED)) ||
|
|
|
4693f0 |
+ (p->link_status & TS_LABEL_CHANGED))
|
|
|
4693f0 |
return EV_FAULT_DETECTED;
|
|
|
4693f0 |
else
|
|
|
4693f0 |
return EV_NONE;
|
|
|
4693f0 |
commit 8923bcdf64c0c95bac7af977b867393bae69e7a1
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:47 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
transport: pass struct interface to transport_open
|
|
|
4693f0 |
|
|
|
4693f0 |
Pass struct interface so we can use ts_iface in HW filter.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/pmc_common.c b/pmc_common.c
|
|
|
4693f0 |
index d92b0cd..447cf99 100644
|
|
|
4693f0 |
--- a/pmc_common.c
|
|
|
4693f0 |
+++ b/pmc_common.c
|
|
|
4693f0 |
@@ -67,6 +67,7 @@ struct pmc *pmc_create(struct config *cfg, enum transport_type transport_type,
|
|
|
4693f0 |
int zero_datalen)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct pmc *pmc;
|
|
|
4693f0 |
+ struct interface iface;
|
|
|
4693f0 |
|
|
|
4693f0 |
pmc = calloc(1, sizeof *pmc);
|
|
|
4693f0 |
if (!pmc)
|
|
|
4693f0 |
@@ -90,7 +91,9 @@ struct pmc *pmc_create(struct config *cfg, enum transport_type transport_type,
|
|
|
4693f0 |
pr_err("failed to create transport");
|
|
|
4693f0 |
goto failed;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
- if (transport_open(pmc->transport, iface_name,
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ strncpy(iface.name, iface_name, MAX_IFNAME_SIZE);
|
|
|
4693f0 |
+ if (transport_open(pmc->transport, &iface,
|
|
|
4693f0 |
&pmc->fdarray, TS_SOFTWARE)) {
|
|
|
4693f0 |
pr_err("failed to open transport");
|
|
|
4693f0 |
goto failed;
|
|
|
4693f0 |
diff --git a/port.c b/port.c
|
|
|
4693f0 |
index 615c800..1e3f474 100644
|
|
|
4693f0 |
--- a/port.c
|
|
|
4693f0 |
+++ b/port.c
|
|
|
4693f0 |
@@ -1504,7 +1504,7 @@ static int port_initialize(struct port *p)
|
|
|
4693f0 |
goto no_timers;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
}
|
|
|
4693f0 |
- if (transport_open(p->trp, p->name, &p->fda, p->timestamping))
|
|
|
4693f0 |
+ if (transport_open(p->trp, p->iface, &p->fda, p->timestamping))
|
|
|
4693f0 |
goto no_tropen;
|
|
|
4693f0 |
|
|
|
4693f0 |
for (i = 0; i < N_TIMER_FDS; i++) {
|
|
|
4693f0 |
@@ -1547,7 +1547,7 @@ static int port_renew_transport(struct port *p)
|
|
|
4693f0 |
}
|
|
|
4693f0 |
transport_close(p->trp, &p->fda);
|
|
|
4693f0 |
port_clear_fda(p, FD_ANNOUNCE_TIMER);
|
|
|
4693f0 |
- res = transport_open(p->trp, p->name, &p->fda, p->timestamping);
|
|
|
4693f0 |
+ res = transport_open(p->trp, p->iface, &p->fda, p->timestamping);
|
|
|
4693f0 |
/* Need to call clock_fda_changed even if transport_open failed in
|
|
|
4693f0 |
* order to update clock to the now closed descriptors. */
|
|
|
4693f0 |
clock_fda_changed(p->clock);
|
|
|
4693f0 |
diff --git a/raw.c b/raw.c
|
|
|
4693f0 |
index 73e45b4..8b7bcf1 100644
|
|
|
4693f0 |
--- a/raw.c
|
|
|
4693f0 |
+++ b/raw.c
|
|
|
4693f0 |
@@ -198,15 +198,16 @@ static void addr_to_mac(void *mac, struct address *addr)
|
|
|
4693f0 |
memcpy(mac, &addr->sll.sll_addr, MAC_LEN);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
-static int raw_open(struct transport *t, const char *name,
|
|
|
4693f0 |
+static int raw_open(struct transport *t, struct interface *iface,
|
|
|
4693f0 |
struct fdarray *fda, enum timestamp_type ts_type)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct raw *raw = container_of(t, struct raw, t);
|
|
|
4693f0 |
unsigned char ptp_dst_mac[MAC_LEN];
|
|
|
4693f0 |
unsigned char p2p_dst_mac[MAC_LEN];
|
|
|
4693f0 |
int efd, gfd;
|
|
|
4693f0 |
- char *str;
|
|
|
4693f0 |
+ char *str, *name;
|
|
|
4693f0 |
|
|
|
4693f0 |
+ name = iface->ts_label;
|
|
|
4693f0 |
str = config_get_string(t->cfg, name, "ptp_dst_mac");
|
|
|
4693f0 |
if (str2mac(str, ptp_dst_mac)) {
|
|
|
4693f0 |
pr_err("invalid ptp_dst_mac %s", str);
|
|
|
4693f0 |
diff --git a/transport.c b/transport.c
|
|
|
4693f0 |
index d24c05b..3541394 100644
|
|
|
4693f0 |
--- a/transport.c
|
|
|
4693f0 |
+++ b/transport.c
|
|
|
4693f0 |
@@ -31,10 +31,10 @@ int transport_close(struct transport *t, struct fdarray *fda)
|
|
|
4693f0 |
return t->close(t, fda);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
-int transport_open(struct transport *t, const char *name,
|
|
|
4693f0 |
+int transport_open(struct transport *t, struct interface *iface,
|
|
|
4693f0 |
struct fdarray *fda, enum timestamp_type tt)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
- return t->open(t, name, fda, tt);
|
|
|
4693f0 |
+ return t->open(t, iface, fda, tt);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
int transport_recv(struct transport *t, int fd, struct ptp_message *msg)
|
|
|
4693f0 |
diff --git a/transport.h b/transport.h
|
|
|
4693f0 |
index 5d6ba98..15616bb 100644
|
|
|
4693f0 |
--- a/transport.h
|
|
|
4693f0 |
+++ b/transport.h
|
|
|
4693f0 |
@@ -27,6 +27,7 @@
|
|
|
4693f0 |
#include "msg.h"
|
|
|
4693f0 |
|
|
|
4693f0 |
struct config;
|
|
|
4693f0 |
+struct interface;
|
|
|
4693f0 |
|
|
|
4693f0 |
/* Values from networkProtocol enumeration 7.4.1 Table 3 */
|
|
|
4693f0 |
enum transport_type {
|
|
|
4693f0 |
@@ -54,7 +55,7 @@ struct transport;
|
|
|
4693f0 |
|
|
|
4693f0 |
int transport_close(struct transport *t, struct fdarray *fda);
|
|
|
4693f0 |
|
|
|
4693f0 |
-int transport_open(struct transport *t, const char *name,
|
|
|
4693f0 |
+int transport_open(struct transport *t, struct interface *iface,
|
|
|
4693f0 |
struct fdarray *fda, enum timestamp_type tt);
|
|
|
4693f0 |
|
|
|
4693f0 |
int transport_recv(struct transport *t, int fd, struct ptp_message *msg);
|
|
|
4693f0 |
diff --git a/transport_private.h b/transport_private.h
|
|
|
4693f0 |
index b54f32a..7530896 100644
|
|
|
4693f0 |
--- a/transport_private.h
|
|
|
4693f0 |
+++ b/transport_private.h
|
|
|
4693f0 |
@@ -32,8 +32,8 @@ struct transport {
|
|
|
4693f0 |
|
|
|
4693f0 |
int (*close)(struct transport *t, struct fdarray *fda);
|
|
|
4693f0 |
|
|
|
4693f0 |
- int (*open)(struct transport *t, const char *name, struct fdarray *fda,
|
|
|
4693f0 |
- enum timestamp_type tt);
|
|
|
4693f0 |
+ int (*open)(struct transport *t, struct interface *iface,
|
|
|
4693f0 |
+ struct fdarray *fda, enum timestamp_type tt);
|
|
|
4693f0 |
|
|
|
4693f0 |
int (*recv)(struct transport *t, int fd, void *buf, int buflen,
|
|
|
4693f0 |
struct address *addr, struct hw_timestamp *hwts);
|
|
|
4693f0 |
diff --git a/udp.c b/udp.c
|
|
|
4693f0 |
index 530a2ee..05c2ba0 100644
|
|
|
4693f0 |
--- a/udp.c
|
|
|
4693f0 |
+++ b/udp.c
|
|
|
4693f0 |
@@ -152,12 +152,13 @@ enum { MC_PRIMARY, MC_PDELAY };
|
|
|
4693f0 |
|
|
|
4693f0 |
static struct in_addr mcast_addr[2];
|
|
|
4693f0 |
|
|
|
4693f0 |
-static int udp_open(struct transport *t, const char *name, struct fdarray *fda,
|
|
|
4693f0 |
- enum timestamp_type ts_type)
|
|
|
4693f0 |
+static int udp_open(struct transport *t, struct interface *iface,
|
|
|
4693f0 |
+ struct fdarray *fda, enum timestamp_type ts_type)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct udp *udp = container_of(t, struct udp, t);
|
|
|
4693f0 |
uint8_t event_dscp, general_dscp;
|
|
|
4693f0 |
int efd, gfd, ttl;
|
|
|
4693f0 |
+ char *name = iface->name;
|
|
|
4693f0 |
|
|
|
4693f0 |
ttl = config_get_int(t->cfg, name, "udp_ttl");
|
|
|
4693f0 |
udp->mac.len = 0;
|
|
|
4693f0 |
@@ -180,7 +181,7 @@ static int udp_open(struct transport *t, const char *name, struct fdarray *fda,
|
|
|
4693f0 |
if (gfd < 0)
|
|
|
4693f0 |
goto no_general;
|
|
|
4693f0 |
|
|
|
4693f0 |
- if (sk_timestamping_init(efd, name, ts_type, TRANS_UDP_IPV4))
|
|
|
4693f0 |
+ if (sk_timestamping_init(efd, iface->ts_label, ts_type, TRANS_UDP_IPV4))
|
|
|
4693f0 |
goto no_timestamping;
|
|
|
4693f0 |
|
|
|
4693f0 |
if (sk_general_init(gfd))
|
|
|
4693f0 |
diff --git a/udp6.c b/udp6.c
|
|
|
4693f0 |
index 89e27bf..7551e3f 100644
|
|
|
4693f0 |
--- a/udp6.c
|
|
|
4693f0 |
+++ b/udp6.c
|
|
|
4693f0 |
@@ -160,12 +160,13 @@ enum { MC_PRIMARY, MC_PDELAY };
|
|
|
4693f0 |
|
|
|
4693f0 |
static struct in6_addr mc6_addr[2];
|
|
|
4693f0 |
|
|
|
4693f0 |
-static int udp6_open(struct transport *t, const char *name, struct fdarray *fda,
|
|
|
4693f0 |
- enum timestamp_type ts_type)
|
|
|
4693f0 |
+static int udp6_open(struct transport *t, struct interface *iface,
|
|
|
4693f0 |
+ struct fdarray *fda, enum timestamp_type ts_type)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct udp6 *udp6 = container_of(t, struct udp6, t);
|
|
|
4693f0 |
uint8_t event_dscp, general_dscp;
|
|
|
4693f0 |
int efd, gfd, hop_limit;
|
|
|
4693f0 |
+ char *name = iface->name;
|
|
|
4693f0 |
|
|
|
4693f0 |
hop_limit = config_get_int(t->cfg, name, "udp_ttl");
|
|
|
4693f0 |
udp6->mac.len = 0;
|
|
|
4693f0 |
@@ -190,7 +191,7 @@ static int udp6_open(struct transport *t, const char *name, struct fdarray *fda,
|
|
|
4693f0 |
if (gfd < 0)
|
|
|
4693f0 |
goto no_general;
|
|
|
4693f0 |
|
|
|
4693f0 |
- if (sk_timestamping_init(efd, name, ts_type, TRANS_UDP_IPV6))
|
|
|
4693f0 |
+ if (sk_timestamping_init(efd, iface->ts_label, ts_type, TRANS_UDP_IPV6))
|
|
|
4693f0 |
goto no_timestamping;
|
|
|
4693f0 |
|
|
|
4693f0 |
if (sk_general_init(gfd))
|
|
|
4693f0 |
diff --git a/uds.c b/uds.c
|
|
|
4693f0 |
index d5e8f50..7e11f63 100644
|
|
|
4693f0 |
--- a/uds.c
|
|
|
4693f0 |
+++ b/uds.c
|
|
|
4693f0 |
@@ -52,13 +52,14 @@ static int uds_close(struct transport *t, struct fdarray *fda)
|
|
|
4693f0 |
return 0;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
-static int uds_open(struct transport *t, const char *name, struct fdarray *fda,
|
|
|
4693f0 |
+static int uds_open(struct transport *t, struct interface *iface, struct fdarray *fda,
|
|
|
4693f0 |
enum timestamp_type tt)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
int fd, err;
|
|
|
4693f0 |
struct sockaddr_un sa;
|
|
|
4693f0 |
struct uds *uds = container_of(t, struct uds, t);
|
|
|
4693f0 |
char *uds_path = config_get_string(t->cfg, NULL, "uds_address");
|
|
|
4693f0 |
+ char *name = iface->name;
|
|
|
4693f0 |
|
|
|
4693f0 |
fd = socket(AF_LOCAL, SOCK_DGRAM, 0);
|
|
|
4693f0 |
if (fd < 0) {
|
|
|
4693f0 |
commit cb53238d5d1a1b9319536b4df1edf237e428d931
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:48 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
phc2sys: split servo_add from function clock_add
|
|
|
4693f0 |
|
|
|
4693f0 |
We also need this part in clock_reinit() later. So split it out of
|
|
|
4693f0 |
function clock_add().
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/phc2sys.c b/phc2sys.c
|
|
|
4693f0 |
index e2b5c47..0472c68 100644
|
|
|
4693f0 |
--- a/phc2sys.c
|
|
|
4693f0 |
+++ b/phc2sys.c
|
|
|
4693f0 |
@@ -162,12 +162,45 @@ static clockid_t clock_open(char *device, int *phc_index)
|
|
|
4693f0 |
return clkid;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+static struct servo *servo_add(struct node *node, struct clock *clock)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ double ppb;
|
|
|
4693f0 |
+ int max_ppb;
|
|
|
4693f0 |
+ struct servo *servo;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ clockadj_init(clock->clkid);
|
|
|
4693f0 |
+ ppb = clockadj_get_freq(clock->clkid);
|
|
|
4693f0 |
+ /* The reading may silently fail and return 0, reset the frequency to
|
|
|
4693f0 |
+ make sure ppb is the actual frequency of the clock. */
|
|
|
4693f0 |
+ clockadj_set_freq(clock->clkid, ppb);
|
|
|
4693f0 |
+ if (clock->clkid == CLOCK_REALTIME) {
|
|
|
4693f0 |
+ sysclk_set_leap(0);
|
|
|
4693f0 |
+ max_ppb = sysclk_max_freq();
|
|
|
4693f0 |
+ } else {
|
|
|
4693f0 |
+ max_ppb = phc_max_adj(clock->clkid);
|
|
|
4693f0 |
+ if (!max_ppb) {
|
|
|
4693f0 |
+ pr_err("clock is not adjustable");
|
|
|
4693f0 |
+ return NULL;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ servo = servo_create(phc2sys_config, node->servo_type,
|
|
|
4693f0 |
+ -ppb, max_ppb, 0);
|
|
|
4693f0 |
+ if (!servo) {
|
|
|
4693f0 |
+ pr_err("Failed to create servo");
|
|
|
4693f0 |
+ return NULL;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ servo_sync_interval(servo, node->phc_interval);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ return servo;
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
static struct clock *clock_add(struct node *node, char *device)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct clock *c;
|
|
|
4693f0 |
clockid_t clkid = CLOCK_INVALID;
|
|
|
4693f0 |
- int max_ppb, phc_index = -1;
|
|
|
4693f0 |
- double ppb;
|
|
|
4693f0 |
+ int phc_index = -1;
|
|
|
4693f0 |
|
|
|
4693f0 |
if (device) {
|
|
|
4693f0 |
clkid = clock_open(device, &phc_index);
|
|
|
4693f0 |
@@ -211,25 +244,7 @@ static struct clock *clock_add(struct node *node, char *device)
|
|
|
4693f0 |
}
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
- clockadj_init(c->clkid);
|
|
|
4693f0 |
- ppb = clockadj_get_freq(c->clkid);
|
|
|
4693f0 |
- /* The reading may silently fail and return 0, reset the frequency to
|
|
|
4693f0 |
- make sure ppb is the actual frequency of the clock. */
|
|
|
4693f0 |
- clockadj_set_freq(c->clkid, ppb);
|
|
|
4693f0 |
- if (c->clkid == CLOCK_REALTIME) {
|
|
|
4693f0 |
- sysclk_set_leap(0);
|
|
|
4693f0 |
- max_ppb = sysclk_max_freq();
|
|
|
4693f0 |
- } else {
|
|
|
4693f0 |
- max_ppb = phc_max_adj(c->clkid);
|
|
|
4693f0 |
- if (!max_ppb) {
|
|
|
4693f0 |
- pr_err("clock is not adjustable");
|
|
|
4693f0 |
- return NULL;
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
- }
|
|
|
4693f0 |
-
|
|
|
4693f0 |
- c->servo = servo_create(phc2sys_config, node->servo_type,
|
|
|
4693f0 |
- -ppb, max_ppb, 0);
|
|
|
4693f0 |
- servo_sync_interval(c->servo, node->phc_interval);
|
|
|
4693f0 |
+ c->servo = servo_add(node, c);
|
|
|
4693f0 |
|
|
|
4693f0 |
if (clkid != CLOCK_REALTIME)
|
|
|
4693f0 |
c->sysoff_supported = (SYSOFF_SUPPORTED ==
|
|
|
4693f0 |
commit 8a349e557c653d24b04b0545e2f179080e10731f
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:49 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
phc2sys: re-create clock clkid and servo when phc index changed
|
|
|
4693f0 |
|
|
|
4693f0 |
When the clock device or phc index changed, the new phc device may have
|
|
|
4693f0 |
different maximum adjustment. So we need to create a new clkid and servo
|
|
|
4693f0 |
in clock_reinit().
|
|
|
4693f0 |
|
|
|
4693f0 |
At the same time, we should not only do clock_reinit() when the new state
|
|
|
4693f0 |
is PS_MASTER. We also need to reinit clock after a failover in slave mode(
|
|
|
4693f0 |
the new state is PS_SLAVE). We can do clock_reinit() even in PS_FAULTY so
|
|
|
4693f0 |
we can finish adjust offset before come back to PS_LISTENING. So I removed
|
|
|
4693f0 |
the check and let's do clock_reinit() whenever there is a new state.
|
|
|
4693f0 |
|
|
|
4693f0 |
And for servo reset, as Miroslav suggested, we will do it in these cases:
|
|
|
4693f0 |
- the system clock is the new destination (master state)
|
|
|
4693f0 |
- a PHC is the new destination (master state)
|
|
|
4693f0 |
- a PHC is switched (in any state)
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/phc2sys.c b/phc2sys.c
|
|
|
4693f0 |
index 0472c68..5c54055 100644
|
|
|
4693f0 |
--- a/phc2sys.c
|
|
|
4693f0 |
+++ b/phc2sys.c
|
|
|
4693f0 |
@@ -128,6 +128,11 @@ static int clock_handle_leap(struct node *node, struct clock *clock,
|
|
|
4693f0 |
static int run_pmc_get_utc_offset(struct node *node, int timeout);
|
|
|
4693f0 |
static void run_pmc_events(struct node *node);
|
|
|
4693f0 |
|
|
|
4693f0 |
+static int normalize_state(int state);
|
|
|
4693f0 |
+static int run_pmc_port_properties(struct node *node, int timeout,
|
|
|
4693f0 |
+ unsigned int port,
|
|
|
4693f0 |
+ int *state, int *tstamping, char *iface);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
static clockid_t clock_open(char *device, int *phc_index)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct sk_ts_info ts_info;
|
|
|
4693f0 |
@@ -309,15 +314,62 @@ static struct port *port_add(struct node *node, unsigned int number,
|
|
|
4693f0 |
return p;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
-static void clock_reinit(struct clock *clock)
|
|
|
4693f0 |
+static void clock_reinit(struct node *node, struct clock *clock, int new_state)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
- servo_reset(clock->servo);
|
|
|
4693f0 |
- clock->servo_state = SERVO_UNLOCKED;
|
|
|
4693f0 |
+ int phc_index = -1, phc_switched = 0;
|
|
|
4693f0 |
+ int state, timestamping, ret = -1;
|
|
|
4693f0 |
+ struct port *p;
|
|
|
4693f0 |
+ struct servo *servo;
|
|
|
4693f0 |
+ struct sk_ts_info ts_info;
|
|
|
4693f0 |
+ char iface[IFNAMSIZ];
|
|
|
4693f0 |
+ clockid_t clkid = CLOCK_INVALID;
|
|
|
4693f0 |
|
|
|
4693f0 |
- if (clock->offset_stats) {
|
|
|
4693f0 |
- stats_reset(clock->offset_stats);
|
|
|
4693f0 |
- stats_reset(clock->freq_stats);
|
|
|
4693f0 |
- stats_reset(clock->delay_stats);
|
|
|
4693f0 |
+ LIST_FOREACH(p, &node->ports, list) {
|
|
|
4693f0 |
+ if (p->clock == clock) {
|
|
|
4693f0 |
+ ret = run_pmc_port_properties(node, 1000, p->number,
|
|
|
4693f0 |
+ &state, ×tamping,
|
|
|
4693f0 |
+ iface);
|
|
|
4693f0 |
+ if (ret > 0)
|
|
|
4693f0 |
+ p->state = normalize_state(state);
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (ret > 0 && timestamping != TS_SOFTWARE) {
|
|
|
4693f0 |
+ /* Check if device changed */
|
|
|
4693f0 |
+ if (strcmp(clock->device, iface)) {
|
|
|
4693f0 |
+ free(clock->device);
|
|
|
4693f0 |
+ clock->device = strdup(iface);
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ /* Check if phc index changed */
|
|
|
4693f0 |
+ if (!sk_get_ts_info(clock->device, &ts_info) &&
|
|
|
4693f0 |
+ clock->phc_index != ts_info.phc_index) {
|
|
|
4693f0 |
+ clkid = clock_open(clock->device, &phc_index);
|
|
|
4693f0 |
+ if (clkid == CLOCK_INVALID)
|
|
|
4693f0 |
+ return;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ phc_close(clock->clkid);
|
|
|
4693f0 |
+ clock->clkid = clkid;
|
|
|
4693f0 |
+ clock->phc_index = phc_index;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ servo = servo_add(node, clock);
|
|
|
4693f0 |
+ if (servo) {
|
|
|
4693f0 |
+ servo_destroy(clock->servo);
|
|
|
4693f0 |
+ clock->servo = servo;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ phc_switched = 1;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (new_state == PS_MASTER || phc_switched) {
|
|
|
4693f0 |
+ servo_reset(clock->servo);
|
|
|
4693f0 |
+ clock->servo_state = SERVO_UNLOCKED;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ if (clock->offset_stats) {
|
|
|
4693f0 |
+ stats_reset(clock->offset_stats);
|
|
|
4693f0 |
+ stats_reset(clock->freq_stats);
|
|
|
4693f0 |
+ stats_reset(clock->delay_stats);
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
}
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
@@ -336,9 +388,7 @@ static void reconfigure(struct node *node)
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
if (c->new_state) {
|
|
|
4693f0 |
- if (c->new_state == PS_MASTER)
|
|
|
4693f0 |
- clock_reinit(c);
|
|
|
4693f0 |
-
|
|
|
4693f0 |
+ clock_reinit(node, c, c->new_state);
|
|
|
4693f0 |
c->state = c->new_state;
|
|
|
4693f0 |
c->new_state = 0;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
@@ -403,7 +453,7 @@ static void reconfigure(struct node *node)
|
|
|
4693f0 |
} else if (rt) {
|
|
|
4693f0 |
if (rt->state != PS_MASTER) {
|
|
|
4693f0 |
rt->state = PS_MASTER;
|
|
|
4693f0 |
- clock_reinit(rt);
|
|
|
4693f0 |
+ clock_reinit(node, rt, rt->state);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
pr_info("selecting %s for synchronization", rt->device);
|
|
|
4693f0 |
}
|
|
|
4693f0 |
commit 7092db303028d84574138c8199375dfde0b4e232
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Mon Oct 9 22:31:50 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
port: return timestamping iface in port properties
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/port.c b/port.c
|
|
|
4693f0 |
index 1e3f474..d8e29d5 100644
|
|
|
4693f0 |
--- a/port.c
|
|
|
4693f0 |
+++ b/port.c
|
|
|
4693f0 |
@@ -861,7 +861,7 @@ static int port_management_fill_response(struct port *target,
|
|
|
4693f0 |
else
|
|
|
4693f0 |
ppn->port_state = target->state;
|
|
|
4693f0 |
ppn->timestamping = target->timestamping;
|
|
|
4693f0 |
- ptp_text_set(&ppn->interface, target->name);
|
|
|
4693f0 |
+ ptp_text_set(&ppn->interface, target->iface->ts_label);
|
|
|
4693f0 |
datalen = sizeof(*ppn) + ppn->interface.length;
|
|
|
4693f0 |
respond = 1;
|
|
|
4693f0 |
break;
|
|
|
4693f0 |
commit 5ce04f9bf366c6d62db5344a6553f87a99ea52ff
|
|
|
4693f0 |
Author: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
Date: Wed Oct 18 20:31:38 2017 +0800
|
|
|
4693f0 |
|
|
|
4693f0 |
phc2sys: update '-s' option
|
|
|
4693f0 |
|
|
|
4693f0 |
Add description about bond interface.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/phc2sys.8 b/phc2sys.8
|
|
|
4693f0 |
index 2559c74..4fc4fa3 100644
|
|
|
4693f0 |
--- a/phc2sys.8
|
|
|
4693f0 |
+++ b/phc2sys.8
|
|
|
4693f0 |
@@ -94,7 +94,11 @@ together with the
|
|
|
4693f0 |
option, the master clock is used only to correct the offset by whole number of
|
|
|
4693f0 |
seconds, which cannot be fixed with PPS alone. Not compatible with the
|
|
|
4693f0 |
.B \-a
|
|
|
4693f0 |
-option.
|
|
|
4693f0 |
+option. This option does not support bonded interface (e.g. bond0). If
|
|
|
4693f0 |
+.B ptp4l
|
|
|
4693f0 |
+has a port on an active-backup bond interface, the
|
|
|
4693f0 |
+.B \-a
|
|
|
4693f0 |
+option can be used to track the active interface.
|
|
|
4693f0 |
.TP
|
|
|
4693f0 |
.BI \-i " interface"
|
|
|
4693f0 |
Performs the exact same function as
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
Backport of
|
|
|
c1aeb8 |
commit 742f8788211d2a861a0214e76449390b89ba55c2
|
|
|
c1aeb8 |
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
|
c1aeb8 |
Date: Fri Apr 13 17:11:56 2018 +0200
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
rtnl: remove dependency on config.h.
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
Change the rtnl_get_ts_label() function to accept the name of the master
|
|
|
c1aeb8 |
interface and the buffer for the slave interface directly instead of the
|
|
|
c1aeb8 |
struct interface from config.h.
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
Also, rename the function to rtnl_get_ts_device().
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
diff --git a/clock.c b/clock.c
|
|
|
c1aeb8 |
index 9ffb43e..afee960 100644
|
|
|
c1aeb8 |
--- a/clock.c
|
|
|
c1aeb8 |
+++ b/clock.c
|
|
|
c1aeb8 |
@@ -948,7 +948,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
|
|
c1aeb8 |
c->timestamping = timestamping;
|
|
|
c1aeb8 |
required_modes = clock_required_modes(c);
|
|
|
c1aeb8 |
STAILQ_FOREACH(iface, &config->interfaces, list) {
|
|
|
c1aeb8 |
- rtnl_get_ts_label(iface);
|
|
|
c1aeb8 |
+ rtnl_get_ts_device(iface->name, iface->ts_label);
|
|
|
c1aeb8 |
ensure_ts_label(iface);
|
|
|
c1aeb8 |
sk_get_ts_info(iface->ts_label, &iface->ts_info);
|
|
|
c1aeb8 |
if (iface->ts_info.valid &&
|
|
|
c1aeb8 |
diff --git a/rtnl.c b/rtnl.c
|
|
|
c1aeb8 |
index cea936b..f9a572b 100644
|
|
|
c1aeb8 |
--- a/rtnl.c
|
|
|
c1aeb8 |
+++ b/rtnl.c
|
|
|
c1aeb8 |
@@ -43,13 +43,13 @@ int rtnl_close(int fd)
|
|
|
c1aeb8 |
return close(fd);
|
|
|
c1aeb8 |
}
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
-static void rtnl_get_ts_label_callback(void *ctx, int linkup, int ts_index)
|
|
|
c1aeb8 |
+static void rtnl_get_ts_device_callback(void *ctx, int linkup, int ts_index)
|
|
|
c1aeb8 |
{
|
|
|
c1aeb8 |
int *dst = ctx;
|
|
|
c1aeb8 |
*dst = ts_index;
|
|
|
c1aeb8 |
}
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
-int rtnl_get_ts_label(struct interface *iface)
|
|
|
c1aeb8 |
+int rtnl_get_ts_device(char *device, char *ts_device)
|
|
|
c1aeb8 |
{
|
|
|
c1aeb8 |
int err, fd;
|
|
|
c1aeb8 |
int ts_index = -1;
|
|
|
c1aeb8 |
@@ -58,13 +58,13 @@ int rtnl_get_ts_label(struct interface *iface)
|
|
|
c1aeb8 |
if (fd < 0)
|
|
|
c1aeb8 |
return fd;
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
- err = rtnl_link_query(fd, iface->name);
|
|
|
c1aeb8 |
+ err = rtnl_link_query(fd, device);
|
|
|
c1aeb8 |
if (err) {
|
|
|
c1aeb8 |
goto no_info;
|
|
|
c1aeb8 |
}
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
- rtnl_link_status(fd, iface->name, rtnl_get_ts_label_callback, &ts_index);
|
|
|
c1aeb8 |
- if (ts_index > 0 && if_indextoname(ts_index, iface->ts_label))
|
|
|
c1aeb8 |
+ rtnl_link_status(fd, device, rtnl_get_ts_device_callback, &ts_index);
|
|
|
c1aeb8 |
+ if (ts_index > 0 && if_indextoname(ts_index, ts_device))
|
|
|
c1aeb8 |
err = 0;
|
|
|
c1aeb8 |
else
|
|
|
c1aeb8 |
err = -1;
|
|
|
c1aeb8 |
diff --git a/rtnl.h b/rtnl.h
|
|
|
c1aeb8 |
index 2906d74..f877cd2 100644
|
|
|
c1aeb8 |
--- a/rtnl.h
|
|
|
c1aeb8 |
+++ b/rtnl.h
|
|
|
c1aeb8 |
@@ -20,8 +20,6 @@
|
|
|
c1aeb8 |
#ifndef HAVE_RTNL_H
|
|
|
c1aeb8 |
#define HAVE_RTNL_H
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
-#include "config.h"
|
|
|
c1aeb8 |
-
|
|
|
c1aeb8 |
typedef void (*rtnl_callback)(void *ctx, int linkup, int ts_index);
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
/**
|
|
|
c1aeb8 |
@@ -32,11 +30,14 @@ typedef void (*rtnl_callback)(void *ctx, int linkup, int ts_index);
|
|
|
c1aeb8 |
int rtnl_close(int fd);
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
/**
|
|
|
c1aeb8 |
- * Get interface ts_label information
|
|
|
c1aeb8 |
- * @param iface struct interface.
|
|
|
c1aeb8 |
- * @return Zero on success, or -1 on error.
|
|
|
c1aeb8 |
+ * Get name of the slave interface which timestamps packets going through
|
|
|
c1aeb8 |
+ * a master interface (e.g. bond0)
|
|
|
c1aeb8 |
+ * @param device Name of the master interface.
|
|
|
c1aeb8 |
+ * @param ts_device Buffer for the name of the slave interface, which must be
|
|
|
c1aeb8 |
+ * at least IF_NAMESIZE bytes long.
|
|
|
c1aeb8 |
+ * @return Zero on success, or -1 on error.
|
|
|
c1aeb8 |
*/
|
|
|
c1aeb8 |
-int rtnl_get_ts_label(struct interface *iface);
|
|
|
c1aeb8 |
+int rtnl_get_ts_device(char *device, char *ts_device);
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
/**
|
|
|
c1aeb8 |
* Request the link status from the kernel.
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
commit e5ba2dae5f102a66e152b96f9cc7b06aff4b90b5
|
|
|
c1aeb8 |
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
|
c1aeb8 |
Date: Fri Apr 13 17:11:57 2018 +0200
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
timemaster: add support for bonded interfaces.
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
Use the rtnl_get_ts_device() function to get the name of the slave
|
|
|
c1aeb8 |
interface which will be timestamping PTP packets and use it instead of
|
|
|
c1aeb8 |
the master interface to check the timestamping capabilities and PHC.
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
diff --git a/makefile b/makefile
|
|
|
c1aeb8 |
index 6f5321c..17189e6 100644
|
|
|
c1aeb8 |
--- a/makefile
|
|
|
c1aeb8 |
+++ b/makefile
|
|
|
c1aeb8 |
@@ -60,7 +60,7 @@ hwstamp_ctl: hwstamp_ctl.o version.o
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
phc_ctl: phc_ctl.o phc.o sk.o util.o clockadj.o sysoff.o print.o version.o
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
-timemaster: print.o sk.o timemaster.o util.o version.o
|
|
|
c1aeb8 |
+timemaster: print.o rtnl.o sk.o timemaster.o util.o version.o
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
version.o: .version version.sh $(filter-out version.d,$(DEPEND))
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
diff --git a/timemaster.c b/timemaster.c
|
|
|
c1aeb8 |
index cda2d90..fc3ba31 100644
|
|
|
c1aeb8 |
--- a/timemaster.c
|
|
|
c1aeb8 |
+++ b/timemaster.c
|
|
|
c1aeb8 |
@@ -23,6 +23,7 @@
|
|
|
c1aeb8 |
#include <libgen.h>
|
|
|
c1aeb8 |
#include <limits.h>
|
|
|
c1aeb8 |
#include <linux/net_tstamp.h>
|
|
|
c1aeb8 |
+#include <net/if.h>
|
|
|
c1aeb8 |
#include <signal.h>
|
|
|
c1aeb8 |
#include <spawn.h>
|
|
|
c1aeb8 |
#include <stdarg.h>
|
|
|
c1aeb8 |
@@ -35,6 +36,7 @@
|
|
|
c1aeb8 |
#include <unistd.h>
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
#include "print.h"
|
|
|
c1aeb8 |
+#include "rtnl.h"
|
|
|
c1aeb8 |
#include "sk.h"
|
|
|
c1aeb8 |
#include "util.h"
|
|
|
c1aeb8 |
#include "version.h"
|
|
|
c1aeb8 |
@@ -674,6 +676,7 @@ static int add_ptp_source(struct ptp_domain *source,
|
|
|
c1aeb8 |
{
|
|
|
c1aeb8 |
struct config_file *config_file;
|
|
|
c1aeb8 |
char **command, *uds_path, **interfaces, *message_tag;
|
|
|
c1aeb8 |
+ char ts_interface[IF_NAMESIZE];
|
|
|
c1aeb8 |
int i, j, num_interfaces, *phc, *phcs, hw_ts, sw_ts;
|
|
|
c1aeb8 |
struct sk_ts_info ts_info;
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
@@ -696,26 +699,38 @@ static int add_ptp_source(struct ptp_domain *source,
|
|
|
c1aeb8 |
for (i = 0; i < num_interfaces; i++) {
|
|
|
c1aeb8 |
phcs[i] = -1;
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
+ /*
|
|
|
c1aeb8 |
+ * if it is a bonded interface, use the name of the active
|
|
|
c1aeb8 |
+ * slave interface (which will be timestamping packets)
|
|
|
c1aeb8 |
+ */
|
|
|
c1aeb8 |
+ if (!rtnl_get_ts_device(source->interfaces[i], ts_interface)) {
|
|
|
c1aeb8 |
+ pr_debug("slave interface of %s: %s",
|
|
|
c1aeb8 |
+ source->interfaces[i], ts_interface);
|
|
|
c1aeb8 |
+ } else {
|
|
|
c1aeb8 |
+ snprintf(ts_interface, sizeof(ts_interface), "%s",
|
|
|
c1aeb8 |
+ source->interfaces[i]);
|
|
|
c1aeb8 |
+ }
|
|
|
c1aeb8 |
+
|
|
|
c1aeb8 |
/* check if the interface has a usable PHC */
|
|
|
c1aeb8 |
- if (sk_get_ts_info(source->interfaces[i], &ts_info)) {
|
|
|
c1aeb8 |
+ if (sk_get_ts_info(ts_interface, &ts_info)) {
|
|
|
c1aeb8 |
pr_err("failed to get time stamping info for %s",
|
|
|
c1aeb8 |
- source->interfaces[i]);
|
|
|
c1aeb8 |
+ ts_interface);
|
|
|
c1aeb8 |
free(phcs);
|
|
|
c1aeb8 |
return 1;
|
|
|
c1aeb8 |
}
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
if (((ts_info.so_timestamping & hw_ts) != hw_ts)) {
|
|
|
c1aeb8 |
- pr_debug("interface %s: no PHC", source->interfaces[i]);
|
|
|
c1aeb8 |
+ pr_debug("interface %s: no PHC", ts_interface);
|
|
|
c1aeb8 |
if ((ts_info.so_timestamping & sw_ts) != sw_ts) {
|
|
|
c1aeb8 |
pr_err("time stamping not supported on %s",
|
|
|
c1aeb8 |
- source->interfaces[i]);
|
|
|
c1aeb8 |
+ ts_interface);
|
|
|
c1aeb8 |
free(phcs);
|
|
|
c1aeb8 |
return 1;
|
|
|
c1aeb8 |
}
|
|
|
c1aeb8 |
continue;
|
|
|
c1aeb8 |
}
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
- pr_debug("interface %s: PHC %d", source->interfaces[i],
|
|
|
c1aeb8 |
+ pr_debug("interface %s: PHC %d", ts_interface,
|
|
|
c1aeb8 |
ts_info.phc_index);
|
|
|
c1aeb8 |
|
|
|
c1aeb8 |
/* and the PHC isn't already used in another source */
|