We are programming C, not Java, and so opening braces of a function belong on a
line all by themselves. 😉
+static void extract_address(struct ptp_message *m, struct PortAddress *paddr) {
static int msg_current(struct ptp_message *m, struct timespec now) {
static struct follow_up_info_tlv *follow_up_info_extract(struct ptp_message *m)
{
+static int port_nsm_reply(struct port *p, struct ptp_message *m) {
static int process_delay_req(struct port *p, struct ptp_message *m) {
no line break on this:
+ memcpy(&extra->foot->lastsync, &last_sync,
+sizeof(extra->foot->lastsync));
-----Ursprungligt meddelande-----
Från: Richard Cochran [mailto:[email protected]]
Skickat: den 1 mars 2018 20:41
Till: [email protected]
Ämne: [Linuxptp-devel] [PATCH RFC V2 08/11] port: Implement the NetSync Monitor
protocol.
When NSM is enabled on a given port, that port always replies to a NSM delay
request with a delay response, sync, and follow up, regardless of the current
state of the port.
Signed-off-by: Richard Cochran <[email protected]>
---
port.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 128 insertions(+), 4 deletions(-)
diff --git a/port.c b/port.c
index cc5a09e..52b9282 100644
--- a/port.c
+++ b/port.c
@@ -126,6 +126,7 @@ struct port {
int freq_est_interval;
int hybrid_e2e;
int min_neighbor_prop_delay;
+ int net_sync_monitor;
int path_trace_enabled;
int rx_timestamp_offset;
int tx_timestamp_offset;
@@ -184,6 +185,29 @@ static int clear_fault_asap(struct fault_interval *faint)
return 0;
}
+static void extract_address(struct ptp_message *m, struct PortAddress
+*paddr) {
+ int len = 0;
+
+ switch (paddr->networkProtocol) {
+ case TRANS_UDP_IPV4:
+ len = sizeof(m->address.sin.sin_addr.s_addr);
+ memcpy(paddr->address, &m->address.sin.sin_addr.s_addr, len);
+ break;
+ case TRANS_UDP_IPV6:
+ len = sizeof(m->address.sin6.sin6_addr.s6_addr);
+ memcpy(paddr->address, &m->address.sin6.sin6_addr.s6_addr, len);
+ break;
+ case TRANS_IEEE_802_3:
+ len = MAC_LEN;
+ memcpy(paddr->address, &m->address.sll.sll_addr, len);
+ break;
+ default:
+ return;
+ }
+ paddr->addressLength = len;
+}
+
static int msg_current(struct ptp_message *m, struct timespec now) {
int64_t t1, t2, tmo;
@@ -449,6 +473,67 @@ static int follow_up_info_append(struct port *p, struct
ptp_message *m)
return 0;
}
+static int net_sync_resp_append(struct port *p, struct ptp_message *m)
+{
+ struct timePropertiesDS *tp = clock_time_properties(p->clock);
+ struct ClockIdentity cid = clock_identity(p->clock), pid;
+ struct currentDS *cds = clock_current_dataset(p->clock);
+ struct parent_ds *dad = clock_parent_ds(p->clock);
+ struct port *best = clock_best_port(p->clock);
+ struct nsm_resp_tlv_head *head;
+ struct Timestamp last_sync;
+ struct PortAddress paddr;
+ struct ptp_message *tmp;
+ struct tlv_extra *extra;
+ unsigned char *ptr;
+ int tlv_len;
+
+ last_sync = tmv_to_Timestamp(clock_ingress_time(p->clock));
+ pid = dad->pds.parentPortIdentity.clockIdentity;
+
+ if (best && memcmp(&cid, &pid, sizeof(cid))) {
+ /* Extract the parent's protocol address. */
+ paddr.networkProtocol = transport_type(best->trp);
+ paddr.addressLength =
+ transport_protocol_addr(best->trp, paddr.address);
+ if (best->best) {
+ tmp = TAILQ_FIRST(&best->best->messages);
+ 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);
+ }
+
+ tlv_len = sizeof(*head) + sizeof(*extra->foot) + paddr.addressLength;
+
+ extra = msg_tlv_append(m, tlv_len);
+ if (!extra) {
+ return -1;
+ }
+
+ head = (struct nsm_resp_tlv_head *) extra->tlv;
+ 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);
+
+ ptr = (unsigned char *) head;
+ ptr += sizeof(*head) + paddr.addressLength;
+ extra->foot = (struct nsm_resp_tlv_foot *) ptr;
+
+ memcpy(&extra->foot->parent, &dad->pds, sizeof(extra->foot->parent));
+ memcpy(&extra->foot->current, cds, sizeof(extra->foot->current));
+ memcpy(&extra->foot->timeprop, tp, sizeof(extra->foot->timeprop));
+ memcpy(&extra->foot->lastsync, &last_sync,
+sizeof(extra->foot->lastsync));
+
+ return 0;
+}
+
static struct follow_up_info_tlv *follow_up_info_extract(struct ptp_message
*m) {
struct follow_up_info_tlv *f;
@@ -677,6 +762,27 @@ static int port_ignore(struct port *p, struct ptp_message
*m)
return 0;
}
+static int port_nsm_reply(struct port *p, struct ptp_message *m) {
+ struct tlv_extra *extra;
+
+ if (!p->net_sync_monitor) {
+ return 0;
+ }
+ if (!p->hybrid_e2e) {
+ return 0;
+ }
+ if (!(m->header.flagField[0] & UNICAST)) {
+ return 0;
+ }
+ TAILQ_FOREACH(extra, &m->tlv_list, list) {
+ if (extra->tlv->type == TLV_PTPMON_REQ) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
/*
* Test whether a 802.1AS port may transmit a sync message.
*/
@@ -1662,10 +1768,12 @@ static int process_announce(struct port *p, struct
ptp_message *m)
static int process_delay_req(struct port *p, struct ptp_message *m) {
+ int err, nsm, saved_seqnum_sync;
struct ptp_message *msg;
- int err;
- if (p->state != PS_MASTER && p->state != PS_GRAND_MASTER)
+ nsm = port_nsm_reply(p, m);
+
+ if (!nsm && p->state != PS_MASTER && p->state != PS_GRAND_MASTER)
return 0;
if (p->delayMechanism == DM_P2P) {
@@ -1698,10 +1806,23 @@ static int process_delay_req(struct port *p, struct
ptp_message *m)
msg->header.flagField[0] |= UNICAST;
msg->header.logMessageInterval = 0x7f;
}
-
+ if (nsm && net_sync_resp_append(p, msg)) {
+ pr_err("port %hu: append NSM failed", portnum(p));
+ err = -1;
+ goto out;
+ }
err = port_prepare_and_send(p, msg, 0);
- if (err)
+ if (err) {
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, &m->address);
+ p->seqnum.sync = saved_seqnum_sync;
+ }
+out:
msg_put(msg);
return err;
}
@@ -2728,6 +2849,9 @@ struct port *port_open(int phc_index,
if (p->hybrid_e2e && p->delayMechanism != DM_E2E) {
pr_warning("port %d: hybrid_e2e only works with E2E", number);
}
+ if (p->net_sync_monitor && !p->hybrid_e2e) {
+ pr_warning("port %d: net_sync_monitor needs hybrid_e2e",
number);
+ }
/* Set fault timeouts to a default value */
for (i = 0; i < FT_CNT; i++) {
--
2.11.0
------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel
------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel