Libor Pechacek
2013-03-20 14:14:43 UTC
Hello,
I've played with linuxptp in a network where was a host talking PTPv1. All the
announcements the other host sent out were reported as "bad message" by ptp4l
which was pretty annoying.
The question is how to deal with this situation. msg_post_recv() returns zero
if all is OK, and -1 for any other condition. We need to distinguish between
ignored and malformed packets here, possibly with more fine-grained diagnostics
of the error for better field debugging. One way would be to define our own
set of error conditions, another is to re-use the standard set of error numbers
and give them new meaning in the PTP context.
I'm in favor of trying the second approach as drafted below. Opinions?
Libor
---
msg.c | 19 ++++++++++---------
pmc_common.c | 10 +++++++---
port.c | 9 ++++++---
3 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/msg.c b/msg.c
index eefd359..5c3f9ac 100644
--- a/msg.c
+++ b/msg.c
@@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <arpa/inet.h>
+#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <time.h>
@@ -90,7 +91,7 @@ int64_t net2host64(int64_t val)
static int hdr_post_recv(struct ptp_header *m)
{
if ((m->ver & VERSION_MASK) != VERSION)
- return -1;
+ return -EPROTO;
m->messageLength = ntohs(m->messageLength);
m->correction = net2host64(m->correction);
m->sourcePortIdentity.portNumber = ntohs(m->sourcePortIdentity.portNumber);
@@ -251,14 +252,14 @@ void msg_get(struct ptp_message *m)
int msg_post_recv(struct ptp_message *m, int cnt)
{
- int pdulen, type;
+ int pdulen, type, ret;
uint8_t *suffix = NULL;
if (cnt < sizeof(struct ptp_header))
- return -1;
+ return -EBADMSG;
- if (hdr_post_recv(&m->header))
- return -1;
+ if (ret = hdr_post_recv(&m->header))
+ return ret;
type = msg_type(m);
@@ -294,11 +295,11 @@ int msg_post_recv(struct ptp_message *m, int cnt)
pdulen = sizeof(struct management_msg);
break;
default:
- return -1;
+ return -EBADMSG;
}
if (cnt < pdulen)
- return -1;
+ return -EBADMSG;
switch (type) {
case SYNC:
@@ -341,12 +342,12 @@ int msg_post_recv(struct ptp_message *m, int cnt)
if (msg_sots_missing(m)) {
pr_err("received %s without timestamp", msg_type_string(type));
- return -1;
+ return -EBADMSG;
}
m->tlv_count = suffix_post_recv(suffix, cnt - pdulen, &m->last_tlv);
if (m->tlv_count == -1) {
- return -1;
+ return -EBADMSG;
}
return 0;
diff --git a/pmc_common.c b/pmc_common.c
index ee88bda..cefd038 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -17,6 +17,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include <errno.h>
#include <string.h>
#include <stdlib.h>
@@ -163,7 +164,7 @@ int pmc_send_get_action(struct pmc *pmc, int id)
struct ptp_message *pmc_recv(struct pmc *pmc)
{
struct ptp_message *msg;
- int cnt;
+ int cnt, ret;
msg = msg_allocate();
if (!msg) {
@@ -176,8 +177,11 @@ struct ptp_message *pmc_recv(struct pmc *pmc)
if (cnt <= 0) {
pr_err("recv message failed");
goto failed;
- } else if (msg_post_recv(msg, cnt)) {
- pr_err("bad message");
+ } else if (ret = msg_post_recv(msg, cnt)) {
+ if (ret == -EBADMSG)
+ pr_err("bad message");
+ else
+ pr_debug("ignoring message");
goto failed;
}
diff --git a/port.c b/port.c
index a1b17b7..141b8ac 100644
--- a/port.c
+++ b/port.c
@@ -1768,7 +1768,7 @@ enum fsm_event port_event(struct port *p, int fd_index)
{
enum fsm_event event = EV_NONE;
struct ptp_message *msg;
- int cnt, fd = p->fda.fd[fd_index];
+ int cnt, fd = p->fda.fd[fd_index], ret;
switch (fd_index) {
case FD_ANNOUNCE_TIMER:
@@ -1813,8 +1813,11 @@ enum fsm_event port_event(struct port *p, int fd_index)
msg_put(msg);
return EV_FAULT_DETECTED;
}
- if (msg_post_recv(msg, cnt)) {
- pr_err("port %hu: bad message", portnum(p));
+ if (ret = msg_post_recv(msg, cnt)) {
+ if (ret == -EBADMSG)
+ pr_err("port %hu: bad message", portnum(p));
+ else
+ pr_debug("port %hu: ignoring message", portnum(p));
msg_put(msg);
return EV_NONE;
}
I've played with linuxptp in a network where was a host talking PTPv1. All the
announcements the other host sent out were reported as "bad message" by ptp4l
which was pretty annoying.
The question is how to deal with this situation. msg_post_recv() returns zero
if all is OK, and -1 for any other condition. We need to distinguish between
ignored and malformed packets here, possibly with more fine-grained diagnostics
of the error for better field debugging. One way would be to define our own
set of error conditions, another is to re-use the standard set of error numbers
and give them new meaning in the PTP context.
I'm in favor of trying the second approach as drafted below. Opinions?
Libor
---
msg.c | 19 ++++++++++---------
pmc_common.c | 10 +++++++---
port.c | 9 ++++++---
3 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/msg.c b/msg.c
index eefd359..5c3f9ac 100644
--- a/msg.c
+++ b/msg.c
@@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <arpa/inet.h>
+#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <time.h>
@@ -90,7 +91,7 @@ int64_t net2host64(int64_t val)
static int hdr_post_recv(struct ptp_header *m)
{
if ((m->ver & VERSION_MASK) != VERSION)
- return -1;
+ return -EPROTO;
m->messageLength = ntohs(m->messageLength);
m->correction = net2host64(m->correction);
m->sourcePortIdentity.portNumber = ntohs(m->sourcePortIdentity.portNumber);
@@ -251,14 +252,14 @@ void msg_get(struct ptp_message *m)
int msg_post_recv(struct ptp_message *m, int cnt)
{
- int pdulen, type;
+ int pdulen, type, ret;
uint8_t *suffix = NULL;
if (cnt < sizeof(struct ptp_header))
- return -1;
+ return -EBADMSG;
- if (hdr_post_recv(&m->header))
- return -1;
+ if (ret = hdr_post_recv(&m->header))
+ return ret;
type = msg_type(m);
@@ -294,11 +295,11 @@ int msg_post_recv(struct ptp_message *m, int cnt)
pdulen = sizeof(struct management_msg);
break;
default:
- return -1;
+ return -EBADMSG;
}
if (cnt < pdulen)
- return -1;
+ return -EBADMSG;
switch (type) {
case SYNC:
@@ -341,12 +342,12 @@ int msg_post_recv(struct ptp_message *m, int cnt)
if (msg_sots_missing(m)) {
pr_err("received %s without timestamp", msg_type_string(type));
- return -1;
+ return -EBADMSG;
}
m->tlv_count = suffix_post_recv(suffix, cnt - pdulen, &m->last_tlv);
if (m->tlv_count == -1) {
- return -1;
+ return -EBADMSG;
}
return 0;
diff --git a/pmc_common.c b/pmc_common.c
index ee88bda..cefd038 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -17,6 +17,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include <errno.h>
#include <string.h>
#include <stdlib.h>
@@ -163,7 +164,7 @@ int pmc_send_get_action(struct pmc *pmc, int id)
struct ptp_message *pmc_recv(struct pmc *pmc)
{
struct ptp_message *msg;
- int cnt;
+ int cnt, ret;
msg = msg_allocate();
if (!msg) {
@@ -176,8 +177,11 @@ struct ptp_message *pmc_recv(struct pmc *pmc)
if (cnt <= 0) {
pr_err("recv message failed");
goto failed;
- } else if (msg_post_recv(msg, cnt)) {
- pr_err("bad message");
+ } else if (ret = msg_post_recv(msg, cnt)) {
+ if (ret == -EBADMSG)
+ pr_err("bad message");
+ else
+ pr_debug("ignoring message");
goto failed;
}
diff --git a/port.c b/port.c
index a1b17b7..141b8ac 100644
--- a/port.c
+++ b/port.c
@@ -1768,7 +1768,7 @@ enum fsm_event port_event(struct port *p, int fd_index)
{
enum fsm_event event = EV_NONE;
struct ptp_message *msg;
- int cnt, fd = p->fda.fd[fd_index];
+ int cnt, fd = p->fda.fd[fd_index], ret;
switch (fd_index) {
case FD_ANNOUNCE_TIMER:
@@ -1813,8 +1813,11 @@ enum fsm_event port_event(struct port *p, int fd_index)
msg_put(msg);
return EV_FAULT_DETECTED;
}
- if (msg_post_recv(msg, cnt)) {
- pr_err("port %hu: bad message", portnum(p));
+ if (ret = msg_post_recv(msg, cnt)) {
+ if (ret == -EBADMSG)
+ pr_err("port %hu: bad message", portnum(p));
+ else
+ pr_debug("port %hu: ignoring message", portnum(p));
msg_put(msg);
return EV_NONE;
}
--
1.7.12.4
1.7.12.4