diff --git a/config.c b/config.c index 80fa255..5da5ecc 100644 --- a/config.c +++ b/config.c @@ -180,6 +180,8 @@ struct config_item config_tab[] = { PORT_ITEM_ENU("delay_filter", FILTER_MOVING_MEDIAN, delay_filter_enu), PORT_ITEM_INT("delay_filter_length", 10, 1, INT_MAX), PORT_ITEM_ENU("delay_mechanism", DM_E2E, delay_mech_enu), + GLOB_ITEM_INT("dscp_event", 0, 0, 63), + GLOB_ITEM_INT("dscp_general", 0, 0, 63), GLOB_ITEM_INT("domainNumber", 0, 0, 127), PORT_ITEM_INT("egressLatency", 0, INT_MIN, INT_MAX), PORT_ITEM_INT("fault_badpeernet_interval", 16, INT32_MIN, INT32_MAX), diff --git a/default.cfg b/default.cfg index 67f5b3a..12542c0 100644 --- a/default.cfg +++ b/default.cfg @@ -12,6 +12,8 @@ clockAccuracy 0xFE offsetScaledLogVariance 0xFFFF free_running 0 freq_est_interval 1 +dscp_event 0 +dscp_general 0 # # Port Data Set # diff --git a/ptp4l.8 b/ptp4l.8 index 72baf86..63e9abd 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -448,6 +448,20 @@ is only relevant with IPv6 transport. See RFC 4291. The default is Specifies the address of the UNIX domain socket for receiving local management messages. The default is /var/run/ptp4l. .TP +.B dscp_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 dscp_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 --git a/sk.c b/sk.c index e80f608..ad30f71 100644 --- a/sk.c +++ b/sk.c @@ -298,6 +298,29 @@ int sk_receive(int fd, void *buf, int buflen, return cnt; } +int sk_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; +} + int sk_timestamping_init(int fd, const char *device, enum timestamp_type type, enum transport_type transport) { diff --git a/sk.h b/sk.h index f05d1df..31cc88e 100644 --- a/sk.h +++ b/sk.h @@ -93,6 +93,14 @@ int sk_interface_addr(const char *name, int family, struct address *addr); int sk_receive(int fd, void *buf, int buflen, struct address *addr, struct hw_timestamp *hwts, int flags); +/** + * Set DSCP value for socket. + * @param fd An open socket. + * @param dscp The desired DSCP code. + * @return Zero on success, negative on failure + */ +int sk_set_priority(int fd, uint8_t dscp); + /** * Enable time stamping on a given network interface. * @param fd An open socket. diff --git a/udp.c b/udp.c index 07277c7..6dabc31 100644 --- a/udp.c +++ b/udp.c @@ -157,6 +157,7 @@ static int udp_open(struct transport *t, const char *name, struct fdarray *fda, enum timestamp_type ts_type) { struct udp *udp = container_of(t, struct udp, t); + uint8_t event_dscp, general_dscp; int efd, gfd, ttl; ttl = config_get_int(t->cfg, name, "udp_ttl"); @@ -186,6 +187,16 @@ static int udp_open(struct transport *t, const char *name, struct fdarray *fda, if (sk_general_init(gfd)) goto no_timestamping; + event_dscp = config_get_int(t->cfg, NULL, "dscp_event"); + general_dscp = config_get_int(t->cfg, NULL, "dscp_general"); + + if (event_dscp && sk_set_priority(efd, event_dscp)) { + pr_warning("Failed to set event DSCP priority."); + } + if (general_dscp && sk_set_priority(gfd, general_dscp)) { + pr_warning("Failed to set general DSCP priority."); + } + fda->fd[FD_EVENT] = efd; fda->fd[FD_GENERAL] = gfd; return 0; diff --git a/udp6.c b/udp6.c index 070e762..c229cac 100644 --- a/udp6.c +++ b/udp6.c @@ -165,6 +165,7 @@ static int udp6_open(struct transport *t, const char *name, struct fdarray *fda, enum timestamp_type ts_type) { struct udp6 *udp6 = container_of(t, struct udp6, t); + uint8_t event_dscp, general_dscp; int efd, gfd, hop_limit; hop_limit = config_get_int(t->cfg, name, "udp_ttl"); @@ -196,6 +197,16 @@ static int udp6_open(struct transport *t, const char *name, struct fdarray *fda, if (sk_general_init(gfd)) goto no_timestamping; + event_dscp = config_get_int(t->cfg, NULL, "dscp_event"); + general_dscp = config_get_int(t->cfg, NULL, "dscp_general"); + + if (event_dscp && sk_set_priority(efd, event_dscp)) { + pr_warning("Failed to set event DSCP priority."); + } + if (general_dscp && sk_set_priority(gfd, general_dscp)) { + pr_warning("Failed to set general DSCP priority."); + } + fda->fd[FD_EVENT] = efd; fda->fd[FD_GENERAL] = gfd; return 0;