Miroslav Lichvar
2015-08-31 12:02:46 UTC
Use the udp_ttl option to configure both IPv4 and IPv6 transports.
Signed-off-by: Miroslav Lichvar <***@redhat.com>
---
default.cfg | 1 +
ptp4l.8 | 7 +++++++
udp6.c | 14 ++++++++++----
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/default.cfg b/default.cfg
index b46c0f6..dead280 100644
--- a/default.cfg
+++ b/default.cfg
@@ -60,6 +60,7 @@ ntpshm_segment 0
transportSpecific 0x0
ptp_dst_mac 01:1B:19:00:00:00
p2p_dst_mac 01:80:C2:00:00:0E
+udp_ttl 1
udp6_scope 0x0E
uds_address /var/run/ptp4l
#
diff --git a/ptp4l.8 b/ptp4l.8
index 14830c5..ff7041b 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -243,6 +243,13 @@ devices" that are not synchronized to each other. For this mode, the
collection of clocks must be synchronized by an external program, for
example phc2sys(8) in "automatic" mode.
The default is 0 (disabled).
+.TP
+.B udp_ttl
+Specifies the Time to live (TTL) value for IPv4 multicast messages and the hop
+limit for IPv6 multicast messages. This option is only relevant with the IPv4
+and IPv6 UDP transports. The default is 1 to restrict the messages sent by
+.B ptp4l
+to the same subnet.
.SH PROGRAM AND CLOCK OPTIONS
diff --git a/udp6.c b/udp6.c
index fdf5799..b67809f 100644
--- a/udp6.c
+++ b/udp6.c
@@ -99,7 +99,7 @@ static int udp6_close(struct transport *t, struct fdarray *fda)
}
static int open_socket_ipv6(const char *name, struct in6_addr mc_addr[2], short port,
- int *interface_index)
+ int *interface_index, int hop_limit)
{
struct sockaddr_in6 addr;
int fd, index, on = 1;
@@ -132,6 +132,11 @@ static int open_socket_ipv6(const char *name, struct in6_addr mc_addr[2], short
pr_err("setsockopt SO_BINDTODEVICE failed: %m");
goto no_option;
}
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hop_limit,
+ sizeof(hop_limit))) {
+ pr_err("setsockopt IPV6_MULTICAST_HOPS failed: %m");
+ goto no_option;
+ }
addr.sin6_addr = mc_addr[0];
if (mc_join(fd, index, (struct sockaddr *) &addr, sizeof(addr))) {
pr_err("mcast_join failed");
@@ -160,8 +165,9 @@ 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);
- int efd, gfd;
+ int efd, gfd, hop_limit;
+ hop_limit = config_get_int(t->cfg, name, "udp_ttl");
udp6->mac.len = 0;
sk_interface_macaddr(name, &udp6->mac);
@@ -176,11 +182,11 @@ static int udp6_open(struct transport *t, const char *name, struct fdarray *fda,
if (1 != inet_pton(AF_INET6, PTP_PDELAY_MCAST_IP6ADDR, &mc6_addr[MC_PDELAY]))
return -1;
- efd = open_socket_ipv6(name, mc6_addr, EVENT_PORT, &udp6->index);
+ efd = open_socket_ipv6(name, mc6_addr, EVENT_PORT, &udp6->index, hop_limit);
if (efd < 0)
goto no_event;
- gfd = open_socket_ipv6(name, mc6_addr, GENERAL_PORT, &udp6->index);
+ gfd = open_socket_ipv6(name, mc6_addr, GENERAL_PORT, &udp6->index, hop_limit);
if (gfd < 0)
goto no_general;
Signed-off-by: Miroslav Lichvar <***@redhat.com>
---
default.cfg | 1 +
ptp4l.8 | 7 +++++++
udp6.c | 14 ++++++++++----
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/default.cfg b/default.cfg
index b46c0f6..dead280 100644
--- a/default.cfg
+++ b/default.cfg
@@ -60,6 +60,7 @@ ntpshm_segment 0
transportSpecific 0x0
ptp_dst_mac 01:1B:19:00:00:00
p2p_dst_mac 01:80:C2:00:00:0E
+udp_ttl 1
udp6_scope 0x0E
uds_address /var/run/ptp4l
#
diff --git a/ptp4l.8 b/ptp4l.8
index 14830c5..ff7041b 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -243,6 +243,13 @@ devices" that are not synchronized to each other. For this mode, the
collection of clocks must be synchronized by an external program, for
example phc2sys(8) in "automatic" mode.
The default is 0 (disabled).
+.TP
+.B udp_ttl
+Specifies the Time to live (TTL) value for IPv4 multicast messages and the hop
+limit for IPv6 multicast messages. This option is only relevant with the IPv4
+and IPv6 UDP transports. The default is 1 to restrict the messages sent by
+.B ptp4l
+to the same subnet.
.SH PROGRAM AND CLOCK OPTIONS
diff --git a/udp6.c b/udp6.c
index fdf5799..b67809f 100644
--- a/udp6.c
+++ b/udp6.c
@@ -99,7 +99,7 @@ static int udp6_close(struct transport *t, struct fdarray *fda)
}
static int open_socket_ipv6(const char *name, struct in6_addr mc_addr[2], short port,
- int *interface_index)
+ int *interface_index, int hop_limit)
{
struct sockaddr_in6 addr;
int fd, index, on = 1;
@@ -132,6 +132,11 @@ static int open_socket_ipv6(const char *name, struct in6_addr mc_addr[2], short
pr_err("setsockopt SO_BINDTODEVICE failed: %m");
goto no_option;
}
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hop_limit,
+ sizeof(hop_limit))) {
+ pr_err("setsockopt IPV6_MULTICAST_HOPS failed: %m");
+ goto no_option;
+ }
addr.sin6_addr = mc_addr[0];
if (mc_join(fd, index, (struct sockaddr *) &addr, sizeof(addr))) {
pr_err("mcast_join failed");
@@ -160,8 +165,9 @@ 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);
- int efd, gfd;
+ int efd, gfd, hop_limit;
+ hop_limit = config_get_int(t->cfg, name, "udp_ttl");
udp6->mac.len = 0;
sk_interface_macaddr(name, &udp6->mac);
@@ -176,11 +182,11 @@ static int udp6_open(struct transport *t, const char *name, struct fdarray *fda,
if (1 != inet_pton(AF_INET6, PTP_PDELAY_MCAST_IP6ADDR, &mc6_addr[MC_PDELAY]))
return -1;
- efd = open_socket_ipv6(name, mc6_addr, EVENT_PORT, &udp6->index);
+ efd = open_socket_ipv6(name, mc6_addr, EVENT_PORT, &udp6->index, hop_limit);
if (efd < 0)
goto no_event;
- gfd = open_socket_ipv6(name, mc6_addr, GENERAL_PORT, &udp6->index);
+ gfd = open_socket_ipv6(name, mc6_addr, GENERAL_PORT, &udp6->index, hop_limit);
if (gfd < 0)
goto no_general;
--
2.1.0
------------------------------------------------------------------------------
2.1.0
------------------------------------------------------------------------------