Discussion:
[Linuxptp-devel] [PATCH v2 0/2] Common address struct, sendto implementation
Jiri Benc
2014-04-22 14:00:58 UTC
Permalink
Changes in v2: removed default_addr, passing NULL address to transport send
methods instead.

Jiri Benc (2):
Common type holding an address
Implement transport_sendto

address.h | 38 +++++++++++++++++++++++++++
msg.h | 6 ++++
raw.c | 50 +++++++++++++++++++++++-------------
sk.c | 34 ++++++++++++++----------
sk.h | 11 ++++---
transport.c | 14 ++++++++--
transport.h | 33 ++++++++++++++++++++++++
transport_private.h | 8 +++--
udp.c | 66 ++++++++++++++++++++++++++++-------------------
udp6.c | 70 +++++++++++++++++++++++++++++---------------------
uds.c | 27 ++++++++++++-------
util.c | 18 +++++++------
12 files changed, 258 insertions(+), 117 deletions(-)
create mode 100644 address.h
--
1.7.6.5
Jiri Benc
2014-04-22 14:01:00 UTC
Permalink
Also, document transport_send, transport_peer and transport_sendto usage.

Signed-off-by: Jiri Benc <***@redhat.com>
---
transport.c | 8 ++++++++
transport.h | 33 +++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/transport.c b/transport.c
index b2d4dd14ee65..fc187406b5bd 100644
--- a/transport.c
+++ b/transport.c
@@ -58,6 +58,14 @@ int transport_peer(struct transport *t, struct fdarray *fda, int event,
return t->send(t, fda, event, 1, msg, len, NULL, &msg->hwts);
}

+int transport_sendto(struct transport *t, struct fdarray *fda, int event,
+ struct ptp_message *msg)
+{
+ int len = ntohs(msg->header.messageLength);
+
+ return t->send(t, fda, event, 0, msg, len, &msg->address, &msg->hwts);
+}
+
int transport_physical_addr(struct transport *t, uint8_t *addr)
{
if (t->physical_addr) {
diff --git a/transport.h b/transport.h
index 5153c46d7887..8e0d4214af5a 100644
--- a/transport.h
+++ b/transport.h
@@ -57,13 +57,46 @@ int transport_open(struct transport *t, const char *name,

int transport_recv(struct transport *t, int fd, struct ptp_message *msg);

+/**
+ * Sends the PTP message using the given transport. The message is sent to
+ * the default (usually multicast) address, any address field in the
+ * ptp_message itself is ignored.
+ * @param t The transport.
+ * @param fda The array of descriptors filled in by transport_open.
+ * @param event 1 for event message, 0 for general message.
+ * @param msg The message to send.
+ * @return Number of bytes send, or negative value in case of an error.
+ */
int transport_send(struct transport *t, struct fdarray *fda, int event,
struct ptp_message *msg);

+/**
+ * Sends the PTP message using the given transport. The message is sent to
+ * the address used for p2p delay measurements (usually a multicast
+ * address), any address field in the ptp_message itself is ignored.
+ * @param t The transport.
+ * @param fda The array of descriptors filled in by transport_open.
+ * @param event 1 for event message, 0 for general message.
+ * @param msg The message to send.
+ * @return Number of bytes send, or negative value in case of an error.
+ */
int transport_peer(struct transport *t, struct fdarray *fda, int event,
struct ptp_message *msg);

/**
+ * Sends the PTP message using the given transport. The address has to be
+ * provided in the address field of the message.
+ * @param t The transport.
+ * @param fda The array of descriptors filled in by transport_open.
+ * @param event 1 for event message, 0 for general message.
+ * @param msg The message to send. The address of the destination has to
+ * be set in the address field.
+ * @return Number of bytes send, or negative value in case of an error.
+ */
+int transport_sendto(struct transport *t, struct fdarray *fda, int event,
+ struct ptp_message *msg);
+
+/**
* Returns the transport's type.
*/
enum transport_type transport_type(struct transport *t);
--
1.7.6.5
Jiri Benc
2014-04-22 14:00:59 UTC
Permalink
This modifies all transports to use a new common address type, struct
address. This address is stored in a ptp_message for all received messages.

For sending, the "default" address is used with the default sending
functions, transport_send and transport_peer. The default address depends on
the transport; it's supposed to be the multicast address assigned by the
transport specification.

Later, a new transport_sendto function will be implemented that sends to the
address contained in the passed ptp_message.

Signed-off-by: Jiri Benc <***@redhat.com>
---
address.h | 38 +++++++++++++++++++++++++++
msg.h | 6 ++++
raw.c | 50 +++++++++++++++++++++++-------------
sk.c | 34 ++++++++++++++----------
sk.h | 11 ++++---
transport.c | 6 ++--
transport_private.h | 8 +++--
udp.c | 66 ++++++++++++++++++++++++++++-------------------
udp6.c | 70 +++++++++++++++++++++++++++++---------------------
uds.c | 27 ++++++++++++-------
util.c | 18 +++++++------
11 files changed, 217 insertions(+), 117 deletions(-)
create mode 100644 address.h

diff --git a/address.h b/address.h
new file mode 100644
index 000000000000..b7803879f8b2
--- /dev/null
+++ b/address.h
@@ -0,0 +1,38 @@
+/**
+ * @file address.h
+ * @brief Definition of a structure to hold an address.
+ * @note Copyright (C) 2014 Red Hat, Inc., Jiri Benc <***@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef HAVE_ADDRESS_H
+#define HAVE_ADDRESS_H
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+struct address {
+ socklen_t len;
+ union {
+ struct sockaddr_storage ss;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ struct sockaddr_un sun;
+ struct sockaddr sa;
+ };
+};
+
+#endif
diff --git a/msg.h b/msg.h
index 564cc9bfa0df..3fa58338f07a 100644
--- a/msg.h
+++ b/msg.h
@@ -24,6 +24,7 @@
#include <sys/queue.h>
#include <time.h>

+#include "address.h"
#include "ddt.h"
#include "tlv.h"

@@ -214,6 +215,11 @@ struct ptp_message {
*/
struct hw_timestamp hwts;
/**
+ * Contains the address this message was received from or should be
+ * sent to.
+ */
+ struct address address;
+ /**
* Contains the number of TLVs in the suffix.
*/
int tlv_count;
diff --git a/raw.c b/raw.c
index 2de0793745ee..cd7bd901c3b8 100644
--- a/raw.c
+++ b/raw.c
@@ -36,6 +36,7 @@
#include <linux/net_tstamp.h>
#include <linux/sockios.h>

+#include "address.h"
#include "contain.h"
#include "ether.h"
#include "print.h"
@@ -45,9 +46,9 @@

struct raw {
struct transport t;
- eth_addr src_addr;
- eth_addr ptp_addr;
- eth_addr p2p_addr;
+ struct address src_addr;
+ struct address ptp_addr;
+ struct address p2p_addr;
int vlan;
};

@@ -185,16 +186,28 @@ no_socket:
return -1;
}

+static void mac_to_addr(struct address *addr, void *mac)
+{
+ addr->sa.sa_family = AF_UNSPEC;
+ memcpy(&addr->sa.sa_data, mac, MAC_LEN);
+ addr->len = sizeof(addr->sa.sa_family) + MAC_LEN;
+}
+
+static void addr_to_mac(void *mac, struct address *addr)
+{
+ memcpy(mac, &addr->sa.sa_data, MAC_LEN);
+}
+
static int raw_open(struct transport *t, const char *name,
struct fdarray *fda, enum timestamp_type ts_type)
{
struct raw *raw = container_of(t, struct raw, t);
int efd, gfd;

- memcpy(raw->ptp_addr, ptp_dst_mac, MAC_LEN);
- memcpy(raw->p2p_addr, p2p_dst_mac, MAC_LEN);
+ mac_to_addr(&raw->ptp_addr, ptp_dst_mac);
+ mac_to_addr(&raw->p2p_addr, p2p_dst_mac);

- if (sk_interface_macaddr(name, raw->src_addr, MAC_LEN))
+ if (sk_interface_macaddr(name, &raw->src_addr))
goto no_mac;

efd = open_socket(name, 1);
@@ -225,7 +238,7 @@ no_mac:
}

static int raw_recv(struct transport *t, int fd, void *buf, int buflen,
- struct hw_timestamp *hwts)
+ struct address *addr, struct hw_timestamp *hwts)
{
int cnt, hlen;
unsigned char *ptr = buf;
@@ -241,7 +254,7 @@ static int raw_recv(struct transport *t, int fd, void *buf, int buflen,
buflen += hlen;
hdr = (struct eth_hdr *) ptr;

- cnt = sk_receive(fd, ptr, buflen, hwts, 0);
+ cnt = sk_receive(fd, ptr, buflen, addr, hwts, 0);

if (cnt >= 0)
cnt -= hlen;
@@ -262,8 +275,9 @@ static int raw_recv(struct transport *t, int fd, void *buf, int buflen,
return cnt;
}

-static int raw_send(struct transport *t, struct fdarray *fda, int event, int peer,
- void *buf, int len, struct hw_timestamp *hwts)
+static int raw_send(struct transport *t, struct fdarray *fda, int event,
+ int peer, void *buf, int len, struct address *addr,
+ struct hw_timestamp *hwts)
{
struct raw *raw = container_of(t, struct raw, t);
ssize_t cnt;
@@ -274,12 +288,12 @@ static int raw_send(struct transport *t, struct fdarray *fda, int event, int pee
ptr -= sizeof(*hdr);
len += sizeof(*hdr);

+ if (!addr)
+ addr = peer ? &raw->p2p_addr : &raw->ptp_addr;
+
hdr = (struct eth_hdr *) ptr;
- if (peer)
- memcpy(&hdr->dst, &raw->p2p_addr, MAC_LEN);
- else
- memcpy(&hdr->dst, &raw->ptp_addr, MAC_LEN);
- memcpy(&hdr->src, &raw->src_addr, MAC_LEN);
+ addr_to_mac(&hdr->dst, addr);
+ addr_to_mac(&hdr->src, &raw->src_addr);

hdr->type = htons(ETH_P_1588);

@@ -291,7 +305,7 @@ static int raw_send(struct transport *t, struct fdarray *fda, int event, int pee
/*
* Get the time stamp right away.
*/
- return event == TRANS_EVENT ? sk_receive(fd, pkt, len, hwts, MSG_ERRQUEUE) : cnt;
+ return event == TRANS_EVENT ? sk_receive(fd, pkt, len, NULL, hwts, MSG_ERRQUEUE) : cnt;
}

static void raw_release(struct transport *t)
@@ -303,14 +317,14 @@ static void raw_release(struct transport *t)
static int raw_physical_addr(struct transport *t, uint8_t *addr)
{
struct raw *raw = container_of(t, struct raw, t);
- memcpy(addr, raw->src_addr, MAC_LEN);
+ addr_to_mac(addr, &raw->src_addr);
return MAC_LEN;
}

static int raw_protocol_addr(struct transport *t, uint8_t *addr)
{
struct raw *raw = container_of(t, struct raw, t);
- memcpy(addr, raw->src_addr, MAC_LEN);
+ addr_to_mac(addr, &raw->src_addr);
return MAC_LEN;
}

diff --git a/sk.c b/sk.c
index 8d70d1acf5dd..838004eab14e 100644
--- a/sk.c
+++ b/sk.c
@@ -30,6 +30,8 @@
#include <stdlib.h>
#include <poll.h>

+#include "address.h"
+#include "ether.h"
#include "print.h"
#include "sk.h"

@@ -146,7 +148,7 @@ failed:
return -1;
}

-int sk_interface_macaddr(const char *name, unsigned char *mac, int len)
+int sk_interface_macaddr(const char *name, struct address *mac)
{
struct ifreq ifreq;
int err, fd;
@@ -167,16 +169,17 @@ int sk_interface_macaddr(const char *name, unsigned char *mac, int len)
return -1;
}

- memcpy(mac, ifreq.ifr_hwaddr.sa_data, len);
+ memcpy(&mac->sa, &ifreq.ifr_hwaddr, sizeof(ifreq.ifr_hwaddr));
+ mac->len = sizeof(ifreq.ifr_hwaddr.sa_family) + MAC_LEN;
close(fd);
return 0;
}

-int sk_interface_addr(const char *name, int family, uint8_t *addr, int len)
+int sk_interface_addr(const char *name, int family, struct address *addr)
{
struct ifaddrs *ifaddr, *i;
- int copy_len, result = -1;
- void *copy_from;
+ int result = -1;
+
if (getifaddrs(&ifaddr) == -1) {
pr_err("getifaddrs failed: %m");
return -1;
@@ -187,20 +190,16 @@ int sk_interface_addr(const char *name, int family, uint8_t *addr, int len)
{
switch (family) {
case AF_INET:
- copy_len = 4;
- copy_from = &((struct sockaddr_in *)i->ifa_addr)->sin_addr.s_addr;
+ addr->len = sizeof(addr->sin);
break;
case AF_INET6:
- copy_len = 16;
- copy_from = &((struct sockaddr_in6 *)i->ifa_addr)->sin6_addr.s6_addr;
+ addr->len = sizeof(addr->sin6);
break;
default:
continue;
}
- if (copy_len > len)
- copy_len = len;
- memcpy(addr, copy_from, copy_len);
- result = copy_len;
+ memcpy(&addr->sa, &i->ifa_addr, addr->len);
+ result = 0;
break;
}
}
@@ -209,7 +208,7 @@ int sk_interface_addr(const char *name, int family, uint8_t *addr, int len)
}

int sk_receive(int fd, void *buf, int buflen,
- struct hw_timestamp *hwts, int flags)
+ struct address *addr, struct hw_timestamp *hwts, int flags)
{
char control[256];
int cnt = 0, res = 0, level, type;
@@ -220,6 +219,10 @@ int sk_receive(int fd, void *buf, int buflen,

memset(control, 0, sizeof(control));
memset(&msg, 0, sizeof(msg));
+ if (addr) {
+ msg.msg_name = &addr->ss;
+ msg.msg_namelen = sizeof(addr->ss);
+ }
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = control;
@@ -265,6 +268,9 @@ int sk_receive(int fd, void *buf, int buflen,
}
}

+ if (addr)
+ addr->len = msg.msg_namelen;
+
if (!ts) {
memset(&hwts->ts, 0, sizeof(hwts->ts));
return cnt;
diff --git a/sk.h b/sk.h
index ea338c13f021..f05d1df5ff86 100644
--- a/sk.h
+++ b/sk.h
@@ -20,6 +20,7 @@
#ifndef HAVE_SK_H
#define HAVE_SK_H

+#include "address.h"
#include "transport.h"

/**
@@ -65,32 +66,32 @@ int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
* Obtain the MAC address of a network interface.
* @param name The name of the interface
* @param mac Buffer to hold the result
- * @param len Length of 'mac'
* @return Zero on success, non-zero otherwise.
*/
-int sk_interface_macaddr(const char *name, unsigned char *mac, int len);
+int sk_interface_macaddr(const char *name, struct address *mac);

/**
* Obtains the first IP address assigned to a network interface.
* @param name The name of the interface
* @param family The family of the address to get: AF_INET or AF_INET6
* @param addr Buffer to hold the result
- * @param len Length of 'addr'
* @return The number of bytes written to addr on success, -1 otherwise.
*/
-int sk_interface_addr(const char *name, int family, uint8_t *addr, int len);
+int sk_interface_addr(const char *name, int family, struct address *addr);

/**
* Read a message from a socket.
* @param fd An open socket.
* @param buf Buffer to receive the message.
* @param buflen Size of 'buf' in bytes.
+ * @param addr Pointer to a buffer to receive the message's source
+ * address. May be NULL.
* @param hwts Pointer to a buffer to receive the message's time stamp.
* @param flags Flags to pass to RECV(2).
* @return
*/
int sk_receive(int fd, void *buf, int buflen,
- struct hw_timestamp *hwts, int flags);
+ struct address *addr, struct hw_timestamp *hwts, int flags);

/**
* Enable time stamping on a given network interface.
diff --git a/transport.c b/transport.c
index cb799a68aa9f..b2d4dd14ee65 100644
--- a/transport.c
+++ b/transport.c
@@ -39,7 +39,7 @@ int transport_open(struct transport *t, const char *name,

int transport_recv(struct transport *t, int fd, struct ptp_message *msg)
{
- return t->recv(t, fd, msg, sizeof(msg->data), &msg->hwts);
+ return t->recv(t, fd, msg, sizeof(msg->data), &msg->address, &msg->hwts);
}

int transport_send(struct transport *t, struct fdarray *fda, int event,
@@ -47,7 +47,7 @@ int transport_send(struct transport *t, struct fdarray *fda, int event,
{
int len = ntohs(msg->header.messageLength);

- return t->send(t, fda, event, 0, msg, len, &msg->hwts);
+ return t->send(t, fda, event, 0, msg, len, NULL, &msg->hwts);
}

int transport_peer(struct transport *t, struct fdarray *fda, int event,
@@ -55,7 +55,7 @@ int transport_peer(struct transport *t, struct fdarray *fda, int event,
{
int len = ntohs(msg->header.messageLength);

- return t->send(t, fda, event, 1, msg, len, &msg->hwts);
+ return t->send(t, fda, event, 1, msg, len, NULL, &msg->hwts);
}

int transport_physical_addr(struct transport *t, uint8_t *addr)
diff --git a/transport_private.h b/transport_private.h
index 7124f94af424..3e0ba9adf113 100644
--- a/transport_private.h
+++ b/transport_private.h
@@ -22,6 +22,7 @@

#include <time.h>

+#include "address.h"
#include "fd.h"
#include "transport.h"

@@ -34,10 +35,11 @@ struct transport {
enum timestamp_type tt);

int (*recv)(struct transport *t, int fd, void *buf, int buflen,
- struct hw_timestamp *hwts);
+ struct address *addr, struct hw_timestamp *hwts);

- int (*send)(struct transport *t, struct fdarray *fda, int event, int peer,
- void *buf, int buflen, struct hw_timestamp *hwts);
+ int (*send)(struct transport *t, struct fdarray *fda, int event,
+ int peer, void *buf, int buflen, struct address *addr,
+ struct hw_timestamp *hwts);

void (*release)(struct transport *t);

diff --git a/udp.c b/udp.c
index 818cbfd53b6a..b100dbfa05ca 100644
--- a/udp.c
+++ b/udp.c
@@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <unistd.h>

+#include "address.h"
#include "contain.h"
#include "print.h"
#include "sk.h"
@@ -43,10 +44,8 @@

struct udp {
struct transport t;
- uint8_t ip[4];
- int ip_len;
- uint8_t mac[MAC_LEN];
- int mac_len;
+ struct address ip;
+ struct address mac;
};

static int mcast_bind(int fd, int index)
@@ -154,13 +153,11 @@ static int udp_open(struct transport *t, const char *name, struct fdarray *fda,
struct udp *udp = container_of(t, struct udp, t);
int efd, gfd;

- udp->mac_len = 0;
- if (sk_interface_macaddr(name, udp->mac, MAC_LEN) == 0)
- udp->mac_len = MAC_LEN;
+ udp->mac.len = 0;
+ sk_interface_macaddr(name, &udp->mac);

- udp->ip_len = sk_interface_addr(name, AF_INET, udp->ip, sizeof(udp->ip));
- if (udp->ip_len == -1)
- udp->ip_len = 0;
+ udp->ip.len = 0;
+ sk_interface_addr(name, AF_INET, &udp->ip);

if (!inet_aton(PTP_PRIMARY_MCAST_IPADDR, &mcast_addr[MC_PRIMARY]))
return -1;
@@ -195,23 +192,30 @@ no_event:
}

static int udp_recv(struct transport *t, int fd, void *buf, int buflen,
- struct hw_timestamp *hwts)
+ struct address *addr, struct hw_timestamp *hwts)
{
- return sk_receive(fd, buf, buflen, hwts, 0);
+ return sk_receive(fd, buf, buflen, addr, hwts, 0);
}

-static int udp_send(struct transport *t, struct fdarray *fda, int event, int peer,
- void *buf, int len, struct hw_timestamp *hwts)
+static int udp_send(struct transport *t, struct fdarray *fda, int event,
+ int peer, void *buf, int len, struct address *addr,
+ struct hw_timestamp *hwts)
{
ssize_t cnt;
int fd = event ? fda->fd[FD_EVENT] : fda->fd[FD_GENERAL];
- struct sockaddr_in addr;
+ struct address addr_buf;
unsigned char junk[1600];

- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr = peer ? mcast_addr[MC_PDELAY] : mcast_addr[MC_PRIMARY];
- addr.sin_port = htons(event ? EVENT_PORT : GENERAL_PORT);
+ if (!addr) {
+ memset(&addr_buf, 0, sizeof(addr_buf));
+ addr_buf.sin.sin_family = AF_INET;
+ addr_buf.sin.sin_addr = peer ? mcast_addr[MC_PDELAY] :
+ mcast_addr[MC_PRIMARY];
+ addr_buf.sin.sin_port = htons(event ? EVENT_PORT :
+ GENERAL_PORT);
+ addr_buf.len = sizeof(addr_buf.sin);
+ addr = &addr_buf;
+ }

/*
* Extend the payload by two, for UDP checksum correction.
@@ -221,7 +225,7 @@ static int udp_send(struct transport *t, struct fdarray *fda, int event, int pee
if (event == TRANS_ONESTEP)
len += 2;

- cnt = sendto(fd, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr));
+ cnt = sendto(fd, buf, len, 0, &addr->sa, sizeof(addr->sin));
if (cnt < 1) {
pr_err("sendto failed: %m");
return cnt;
@@ -229,7 +233,7 @@ static int udp_send(struct transport *t, struct fdarray *fda, int event, int pee
/*
* Get the time stamp right away.
*/
- return event == TRANS_EVENT ? sk_receive(fd, junk, len, hwts, MSG_ERRQUEUE) : cnt;
+ return event == TRANS_EVENT ? sk_receive(fd, junk, len, NULL, hwts, MSG_ERRQUEUE) : cnt;
}

static void udp_release(struct transport *t)
@@ -241,17 +245,25 @@ static void udp_release(struct transport *t)
static int udp_physical_addr(struct transport *t, uint8_t *addr)
{
struct udp *udp = container_of(t, struct udp, t);
- if (udp->mac_len)
- memcpy(addr, udp->mac, udp->mac_len);
- return udp->mac_len;
+ int len = 0;
+
+ if (udp->mac.len) {
+ len = MAC_LEN;
+ memcpy(addr, udp->mac.sa.sa_data, len);
+ }
+ return len;
}

static int udp_protocol_addr(struct transport *t, uint8_t *addr)
{
struct udp *udp = container_of(t, struct udp, t);
- if (udp->ip_len)
- memcpy(addr, &udp->ip, udp->ip_len);
- return udp->ip_len;
+ int len = 0;
+
+ if (udp->ip.len) {
+ len = sizeof(udp->ip.sin.sin_addr.s_addr);
+ memcpy(addr, &udp->ip.sin.sin_addr.s_addr, len);
+ }
+ return len;
}

struct transport *udp_transport_create(void)
diff --git a/udp6.c b/udp6.c
index e26195b4fffd..f098b8c625d9 100644
--- a/udp6.c
+++ b/udp6.c
@@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <unistd.h>

+#include "address.h"
#include "contain.h"
#include "print.h"
#include "sk.h"
@@ -46,10 +47,8 @@ unsigned char udp6_scope = 0x0E;
struct udp6 {
struct transport t;
int index;
- uint8_t ip[16];
- int ip_len;
- uint8_t mac[MAC_LEN];
- int mac_len;
+ struct address ip;
+ struct address mac;
};

static int is_link_local(struct in6_addr *addr)
@@ -164,13 +163,11 @@ static int udp6_open(struct transport *t, const char *name, struct fdarray *fda,
struct udp6 *udp6 = container_of(t, struct udp6, t);
int efd, gfd;

- udp6->mac_len = 0;
- if (sk_interface_macaddr(name, udp6->mac, MAC_LEN) == 0)
- udp6->mac_len = MAC_LEN;
+ udp6->mac.len = 0;
+ sk_interface_macaddr(name, &udp6->mac);

- udp6->ip_len = sk_interface_addr(name, AF_INET6, udp6->ip, sizeof(udp6->ip));
- if (udp6->ip_len == -1)
- udp6->ip_len = 0;
+ udp6->ip.len = 0;
+ sk_interface_addr(name, AF_INET6, &udp6->ip);

if (1 != inet_pton(AF_INET6, PTP_PRIMARY_MCAST_IP6ADDR, &mc6_addr[MC_PRIMARY]))
return -1;
@@ -207,32 +204,39 @@ no_event:
}

static int udp6_recv(struct transport *t, int fd, void *buf, int buflen,
- struct hw_timestamp *hwts)
+ struct address *addr, struct hw_timestamp *hwts)
{
- return sk_receive(fd, buf, buflen, hwts, 0);
+ return sk_receive(fd, buf, buflen, addr, hwts, 0);
}

-static int udp6_send(struct transport *t, struct fdarray *fda, int event, int peer,
- void *buf, int len, struct hw_timestamp *hwts)
+static int udp6_send(struct transport *t, struct fdarray *fda, int event,
+ int peer, void *buf, int len, struct address *addr,
+ struct hw_timestamp *hwts)
{
struct udp6 *udp6 = container_of(t, struct udp6, t);
ssize_t cnt;
int fd = event ? fda->fd[FD_EVENT] : fda->fd[FD_GENERAL];
- struct sockaddr_in6 addr;
+ struct address addr_buf;
unsigned char junk[1600];

- memset(&addr, 0, sizeof(addr));
- addr.sin6_family = AF_INET6;
- addr.sin6_addr = peer ? mc6_addr[MC_PDELAY] : mc6_addr[MC_PRIMARY];
- addr.sin6_port = htons(event ? EVENT_PORT : GENERAL_PORT);
+ if (!addr) {
+ memset(&addr_buf, 0, sizeof(addr_buf));
+ addr_buf.sin6.sin6_family = AF_INET6;
+ addr_buf.sin6.sin6_addr = peer ? mc6_addr[MC_PDELAY] :
+ mc6_addr[MC_PRIMARY];
+ addr_buf.sin6.sin6_port = htons(event ? EVENT_PORT :
+ GENERAL_PORT);

- if (is_link_local(&addr.sin6_addr)) {
- addr.sin6_scope_id = udp6->index;
+ if (is_link_local(&addr_buf.sin6.sin6_addr))
+ addr_buf.sin6.sin6_scope_id = udp6->index;
+
+ addr_buf.len = sizeof(addr_buf.sin6);
+ addr = &addr_buf;
}

len += 2; /* Extend the payload by two, for UDP checksum corrections. */

- cnt = sendto(fd, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr));
+ cnt = sendto(fd, buf, len, 0, &addr->sa, sizeof(addr->sin6));
if (cnt < 1) {
pr_err("sendto failed: %m");
return cnt;
@@ -240,7 +244,7 @@ static int udp6_send(struct transport *t, struct fdarray *fda, int event, int pe
/*
* Get the time stamp right away.
*/
- return event == TRANS_EVENT ? sk_receive(fd, junk, len, hwts, MSG_ERRQUEUE) : cnt;
+ return event == TRANS_EVENT ? sk_receive(fd, junk, len, NULL, hwts, MSG_ERRQUEUE) : cnt;
}

static void udp6_release(struct transport *t)
@@ -252,17 +256,25 @@ static void udp6_release(struct transport *t)
static int udp6_physical_addr(struct transport *t, uint8_t *addr)
{
struct udp6 *udp6 = container_of(t, struct udp6, t);
- if (udp6->mac_len)
- memcpy(addr, udp6->mac, udp6->mac_len);
- return udp6->mac_len;
+ int len = 0;
+
+ if (udp6->mac.len) {
+ len = MAC_LEN;
+ memcpy(addr, udp6->mac.sa.sa_data, len);
+ }
+ return len;
}

static int udp6_protocol_addr(struct transport *t, uint8_t *addr)
{
struct udp6 *udp6 = container_of(t, struct udp6, t);
- if (udp6->ip_len)
- memcpy(addr, &udp6->ip, udp6->ip_len);
- return udp6->ip_len;
+ int len = 0;
+
+ if (udp6->ip.len) {
+ len = sizeof(udp6->ip.sin6.sin6_addr.s6_addr);
+ memcpy(addr, &udp6->ip.sin6.sin6_addr.s6_addr, len);
+ }
+ return len;
}

struct transport *udp6_transport_create(void)
diff --git a/uds.c b/uds.c
index 35f5eccf0545..e88b333e4f00 100644
--- a/uds.c
+++ b/uds.c
@@ -25,6 +25,7 @@
#include <sys/un.h>
#include <unistd.h>

+#include "address.h"
#include "contain.h"
#include "print.h"
#include "transport_private.h"
@@ -36,8 +37,7 @@ char uds_path[MAX_IFNAME_SIZE + 1] = "/var/run/ptp4l";

struct uds {
struct transport t;
- struct sockaddr_un sa;
- socklen_t len;
+ struct address address;
};

static int uds_close(struct transport *t, struct fdarray *fda)
@@ -75,8 +75,8 @@ static int uds_open(struct transport *t, const char *name, struct fdarray *fda,
memset(&sa, 0, sizeof(sa));
sa.sun_family = AF_LOCAL;
strncpy(sa.sun_path, uds_path, sizeof(sa.sun_path) - 1);
- uds->sa = sa;
- uds->len = sizeof(sa);
+ uds->address.sun = sa;
+ uds->address.len = sizeof(sa);

chmod(name, UDS_FILEMODE);
fda->fd[FD_EVENT] = -1;
@@ -85,25 +85,32 @@ static int uds_open(struct transport *t, const char *name, struct fdarray *fda,
}

static int uds_recv(struct transport *t, int fd, void *buf, int buflen,
- struct hw_timestamp *hwts)
+ struct address *addr, struct hw_timestamp *hwts)
{
int cnt;
struct uds *uds = container_of(t, struct uds, t);
- socklen_t *len = &uds->len;
- uds->len = sizeof(uds->sa);
- cnt = recvfrom(fd, buf, buflen, 0, (struct sockaddr *) &uds->sa, len);
+
+ addr->len = sizeof(addr->sun);
+ cnt = recvfrom(fd, buf, buflen, 0, &addr->sa, &addr->len);
if (cnt <= 0) {
pr_err("uds: recvfrom failed: %m");
+ return cnt;
}
+ uds->address = *addr;
return cnt;
}

static int uds_send(struct transport *t, struct fdarray *fda, int event,
- int peer, void *buf, int buflen, struct hw_timestamp *hwts)
+ int peer, void *buf, int buflen, struct address *addr,
+ struct hw_timestamp *hwts)
{
int cnt, fd = fda->fd[FD_GENERAL];
struct uds *uds = container_of(t, struct uds, t);
- cnt = sendto(fd, buf, buflen, 0, (struct sockaddr *) &uds->sa, uds->len);
+
+ if (!addr)
+ addr = &uds->address;
+
+ cnt = sendto(fd, buf, buflen, 0, &addr->sa, addr->len);
if (cnt <= 0) {
pr_err("uds: sendto failed: %m");
}
diff --git a/util.c b/util.c
index 56af8efcb0fa..1e86040c61f7 100644
--- a/util.c
+++ b/util.c
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>

+#include "address.h"
#include "sk.h"
#include "util.h"

@@ -100,17 +101,18 @@ int str2pid(const char *s, struct PortIdentity *result)

int generate_clock_identity(struct ClockIdentity *ci, const char *name)
{
- unsigned char mac[6];
- if (sk_interface_macaddr(name, mac, sizeof(mac)))
+ struct address addr;
+
+ if (sk_interface_macaddr(name, &addr))
return -1;
- ci->id[0] = mac[0];
- ci->id[1] = mac[1];
- ci->id[2] = mac[2];
+ ci->id[0] = addr.sa.sa_data[0];
+ ci->id[1] = addr.sa.sa_data[1];
+ ci->id[2] = addr.sa.sa_data[2];
ci->id[3] = 0xFF;
ci->id[4] = 0xFE;
- ci->id[5] = mac[3];
- ci->id[6] = mac[4];
- ci->id[7] = mac[5];
+ ci->id[5] = addr.sa.sa_data[3];
+ ci->id[6] = addr.sa.sa_data[4];
+ ci->id[7] = addr.sa.sa_data[5];
return 0;
}
--
1.7.6.5
Richard Cochran
2014-04-26 09:07:00 UTC
Permalink
Post by Jiri Benc
Changes in v2: removed default_addr, passing NULL address to transport send
methods instead.
Common type holding an address
Implement transport_sendto
Both patches applied.

Thanks,
Richard

Loading...