In the last years there are several media streaming standards evolving that are relying on PTP. These standards make requirements about the DSCP priority of PTP messages. This patch introduces two new configuration options 'tos_event' and 'tos_general' to address that issue and to be able to set the DSCP priority separately for PTP event messages and PTP general messages.
Signed-off-by: Henry Jesuiter <***@alcnetworx.de>
---
diff -rwbBu a/config.c b/config.c
--- a/config.c 2015-09-19 16:25:11.000000000 +0200
+++ b/config.c 2016-07-07 13:13:44.465579808 +0200
@@ -226,6 +226,8 @@
PORT_ITEM_INT("syncReceiptTimeout", 0, 0, UINT8_MAX),
GLOB_ITEM_INT("timeSource", INTERNAL_OSCILLATOR, 0x10, 0xfe),
GLOB_ITEM_ENU("time_stamping", TS_HARDWARE, timestamping_enu),
+ GLOB_ITEM_INT("tos_event", 0, 0, 63),
+ GLOB_ITEM_INT("tos_general", 0, 0, 63),
PORT_ITEM_INT("transportSpecific", 0, 0, 0x0F),
PORT_ITEM_ENU("tsproc_mode", TSPROC_FILTER, tsproc_enu),
GLOB_ITEM_INT("twoStepFlag", 1, 0, 1),
diff -rwbBu a/default.cfg b/default.cfg
--- a/default.cfg 2015-09-19 16:25:11.000000000 +0200
+++ b/default.cfg 2016-07-07 13:14:21.333731697 +0200
@@ -12,6 +12,8 @@
offsetScaledLogVariance 0xFFFF
free_running 0
freq_est_interval 1
+tos_event 0
+tos_general 0
#
# Port Data Set
#
diff -rwbBu a/ptp4l.8 b/ptp4l.8
--- a/ptp4l.8 2015-09-19 16:25:11.000000000 +0200
+++ b/ptp4l.8 2016-07-07 13:04:30.601314267 +0200
@@ -446,6 +446,20 @@
Specifies the address of the UNIX domain socket for receiving local
management messages. The default is /var/run/ptp4l.
.TP
+.B tos_event
+Defines the Differentiated Services Codepoint (DSCP) to be used for PTP
+event messages. Must be a value between 0 and 63. There are several media
+streaming standards out there that require specific values for this option.
+For example 46 (EF PHB) in AES67 or 48 (CS6 PHB) in RAVENNA. The default
+is 0.
+.TP
+.B tos_general
+Defines the Differentiated Services Codepoint (DSCP) to be used for PTP
+general messages. Must be a value between 0 and 63. There are several media
+streaming standards out there that recommend specific values for this option.
+For example 34 (AF41 PHB) in AES67 or 46 (EF PHB) in RAVENNA. The default
+is 0.
+.TP
.B logging_level
The maximum logging level of messages which should be printed.
The default is 6 (LOG_INFO).
diff -rwbBu a/sk.c b/sk.c
--- a/sk.c 2015-09-19 16:25:11.000000000 +0200
+++ b/sk.c 2016-07-07 13:15:24.933969306 +0200
@@ -35,6 +35,7 @@
#include "missing.h"
#include "print.h"
#include "sk.h"
+#include "config.h"
/* globals */
@@ -78,6 +79,29 @@
return 0;
}
+static int set_priority(int fd, uint8_t dscp)
+{
+ int tos;
+ socklen_t tos_len;
+
+ tos_len = sizeof(tos);
+ if (getsockopt(fd, SOL_IP, IP_TOS, &tos, &tos_len) < 0) {
+ tos = 0;
+ }
+
+ /* clear old DSCP value */
+ tos &= ~0xFC;
+
+ /* set new DSCP value */
+ tos |= dscp<<2;
+ tos_len = sizeof(tos);
+ if (setsockopt(fd, SOL_IP, IP_TOS, &tos, tos_len) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
/* public methods */
int sk_interface_index(int fd, const char *name)
@@ -105,6 +129,25 @@
return 0;
}
+int sk_set_priority(struct config *c, int event_fd, int general_fd)
+{
+ uint8_t event_dscp = config_get_int(c, NULL, "tos_event");
+ uint8_t general_dscp = config_get_int(c, NULL, "tos_general");
+
+ int err = 0;
+
+ if (event_dscp) {
+ err = set_priority(event_fd, event_dscp);
+ }
+
+ if (!err && general_dscp) {
+ err = set_priority(general_fd, general_dscp);
+ }
+
+ return err;
+}
+
+
int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info)
{
#ifdef ETHTOOL_GET_TS_INFO
diff -rwbBu a/sk.h b/sk.h
--- a/sk.h 2015-09-19 16:25:11.000000000 +0200
+++ b/sk.h 2016-07-06 17:16:19.000000000 +0200
@@ -55,6 +55,16 @@
int sk_general_init(int fd);
/**
+ * Set DSCP value for socket.
+ * @param c Current linuxptp configuration.
+ * @param event_fd Open socket for ptp event messages.
+ * @param general_fd Open socket for ptp general messages.
+ * @return Zero on success, negative on failure
+ *
+ */
+int sk_set_priority(struct config *c, int event_fd, int general_fd);
+
+/**
* Obtain supported timestamping information
* @param name The name of the interface
* @param info Struct containing obtained timestamping information.
diff -rwbBu a/udp6.c b/udp6.c
--- a/udp6.c 2015-09-19 16:25:11.000000000 +0200
+++ b/udp6.c 2016-07-07 13:16:00.134088652 +0200
@@ -196,6 +196,10 @@
if (sk_general_init(gfd))
goto no_timestamping;
+ if (sk_set_priority(t->cfg, efd, gfd) < 0) {
+ pr_warning("Failure on setting DSCP priority.");
+ }
+
fda->fd[FD_EVENT] = efd;
fda->fd[FD_GENERAL] = gfd;
return 0;
diff -rwbBu a/udp.c b/udp.c
--- a/udp.c 2015-09-19 16:25:11.000000000 +0200
+++ b/udp.c 2016-07-07 13:15:48.358049636 +0200
@@ -186,6 +186,10 @@
if (sk_general_init(gfd))
goto no_timestamping;
+ if (sk_set_priority(t->cfg, efd, gfd) < 0) {
+ pr_warning("Failure on setting DSCP priority.");
+ }
+
fda->fd[FD_EVENT] = efd;
fda->fd[FD_GENERAL] = gfd;
return 0;
---
Some notes to the patch above:
1. I finally decided to use the decimal DSCP value. The RFCs are always using the PHB name or binary representation. On the other hand in my experience you will find more often a decimal than a hexadecimal representation. At least in the audio community - the foremost target audience of this patch.
2. Actually that config options could be done on per port basis. Currently we decided explicitly against this, since a device in a streaming network should not be able to use different priorities for pTP messages on different ports to avoid misconfiguration. It would be dangerous, if in a streaming network by some misconfiguration there is the possibility to suppress PTP event messages by media streams, which finally could lead to media drop outs. Of course, if you prefer a per port option we will implement it that way.
Best regards
Henry Jesuiter
PS: Sorry, for some reason, the last mail contained an incomplete patch, so please use the one in this mail.