|
|
4693f0 |
commit 7546434030d456b13b2eda6138f183ac3bf29751
|
|
|
4693f0 |
Author: Feras Daoud <ferasda@mellanox.com>
|
|
|
4693f0 |
Date: Wed Aug 9 18:27:32 2017 +0300
|
|
|
4693f0 |
|
|
|
4693f0 |
ptp4l: Add IPoIB interface support for ptp4l
|
|
|
4693f0 |
|
|
|
4693f0 |
The current implementation of ptp4l always assumes 6 octets MAC
|
|
|
4693f0 |
address, which is correct for Ethernet interfaces but not for IPoIB
|
|
|
4693f0 |
interfaces (that have 20 octets MAC), therefore running ptp4l over
|
|
|
4693f0 |
IPoIB interface does not function correctly.
|
|
|
4693f0 |
|
|
|
4693f0 |
In Infiniband, every interface has three identifiers:
|
|
|
4693f0 |
GUID, GID, and LID.
|
|
|
4693f0 |
The GUID is similar in concept to a MAC address. From RFC4392:
|
|
|
4693f0 |
The EUI-64 portion of a GID is referred to as the Global Unique
|
|
|
4693f0 |
Identifier (GUID) and is the only persistent identifier of a port.
|
|
|
4693f0 |
|
|
|
4693f0 |
Therefore, to support IPoIB interfaces, the GUID of the port should
|
|
|
4693f0 |
be used instead of the MAC.
|
|
|
4693f0 |
This patch checks the interface type before creating the clock identity,
|
|
|
4693f0 |
for Infiniband ports, it retrieves the GUID of the port using sysfs
|
|
|
4693f0 |
and use it to create the clock identity.
|
|
|
4693f0 |
|
|
|
4693f0 |
sysfs method was chosen since the GUID is the 6 lsb bytes of
|
|
|
4693f0 |
the 20 byte device address, and SIOCGIFHWADDR ioctl call returns
|
|
|
4693f0 |
the 14 msb bytes of the device address, so it is not possible to
|
|
|
4693f0 |
get the GUID using SIOCGIFHWADDR ioctl call.
|
|
|
4693f0 |
|
|
|
4693f0 |
[ RC: fixed trivial coding style error, space after switch keyword. ]
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Feras Daoud <ferasda@mellanox.com>
|
|
|
4693f0 |
Reviewed-by: Alex Vesker <valex@mellanox.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/address.h b/address.h
|
|
|
4693f0 |
index 7578f91..35ef05f 100644
|
|
|
4693f0 |
--- a/address.h
|
|
|
4693f0 |
+++ b/address.h
|
|
|
4693f0 |
@@ -24,6 +24,7 @@
|
|
|
4693f0 |
#include <netpacket/packet.h>
|
|
|
4693f0 |
#include <sys/socket.h>
|
|
|
4693f0 |
#include <sys/un.h>
|
|
|
4693f0 |
+#include <net/if_arp.h>
|
|
|
4693f0 |
|
|
|
4693f0 |
struct address {
|
|
|
4693f0 |
socklen_t len;
|
|
|
4693f0 |
diff --git a/ether.h b/ether.h
|
|
|
4693f0 |
index ce3d663..8ec9669 100644
|
|
|
4693f0 |
--- a/ether.h
|
|
|
4693f0 |
+++ b/ether.h
|
|
|
4693f0 |
@@ -22,7 +22,13 @@
|
|
|
4693f0 |
|
|
|
4693f0 |
#include <stdint.h>
|
|
|
4693f0 |
|
|
|
4693f0 |
-#define MAC_LEN 6
|
|
|
4693f0 |
+#define EUI48 6
|
|
|
4693f0 |
+#define EUI64 8
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+#define MAC_LEN EUI48
|
|
|
4693f0 |
+#define GUID_LEN EUI64
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+#define GUID_OFFSET 36
|
|
|
4693f0 |
|
|
|
4693f0 |
typedef uint8_t eth_addr[MAC_LEN];
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/sk.c b/sk.c
|
|
|
4693f0 |
index 63ec206..0cf55c5 100644
|
|
|
4693f0 |
--- a/sk.c
|
|
|
4693f0 |
+++ b/sk.c
|
|
|
4693f0 |
@@ -159,10 +159,55 @@ failed:
|
|
|
4693f0 |
return -1;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+static int sk_interface_guidaddr(const char *name, unsigned char *guid)
|
|
|
4693f0 |
+{
|
|
|
4693f0 |
+ char file_name[64], buf[64], addr[8];
|
|
|
4693f0 |
+ FILE *f;
|
|
|
4693f0 |
+ char *err;
|
|
|
4693f0 |
+ int res;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ snprintf(file_name, sizeof buf, "/sys/class/net/%s/address", name);
|
|
|
4693f0 |
+ f = fopen(file_name, "r");
|
|
|
4693f0 |
+ if (!f) {
|
|
|
4693f0 |
+ pr_err("failed to open %s: %m", buf);
|
|
|
4693f0 |
+ return -1;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ /* Set the file position to the beginning of the GUID */
|
|
|
4693f0 |
+ res = fseek(f, GUID_OFFSET, SEEK_SET);
|
|
|
4693f0 |
+ if (res) {
|
|
|
4693f0 |
+ pr_err("fseek failed: %m");
|
|
|
4693f0 |
+ goto error;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ err = fgets(buf, sizeof buf, f);
|
|
|
4693f0 |
+ if (err == NULL) {
|
|
|
4693f0 |
+ pr_err("fseek failed: %m");
|
|
|
4693f0 |
+ goto error;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ res = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
|
|
4693f0 |
+ &addr[0], &addr[1], &addr[2], &addr[3],
|
|
|
4693f0 |
+ &addr[4], &addr[5], &addr[6], &addr[7]);
|
|
|
4693f0 |
+ if (res != GUID_LEN) {
|
|
|
4693f0 |
+ pr_err("sscanf failed: %m");
|
|
|
4693f0 |
+ goto error;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ memcpy(guid, addr, GUID_LEN);
|
|
|
4693f0 |
+ fclose(f);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ return 0;
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+error:
|
|
|
4693f0 |
+ fclose(f);
|
|
|
4693f0 |
+ return -1;
|
|
|
4693f0 |
+}
|
|
|
4693f0 |
+
|
|
|
4693f0 |
int sk_interface_macaddr(const char *name, struct address *mac)
|
|
|
4693f0 |
{
|
|
|
4693f0 |
struct ifreq ifreq;
|
|
|
4693f0 |
- int err, fd;
|
|
|
4693f0 |
+ int err, fd, type;
|
|
|
4693f0 |
|
|
|
4693f0 |
memset(&ifreq, 0, sizeof(ifreq));
|
|
|
4693f0 |
strncpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name) - 1);
|
|
|
4693f0 |
@@ -180,9 +225,23 @@ int sk_interface_macaddr(const char *name, struct address *mac)
|
|
|
4693f0 |
return -1;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+ /* Get interface type */
|
|
|
4693f0 |
+ type = ifreq.ifr_hwaddr.sa_family;
|
|
|
4693f0 |
+ switch (type) {
|
|
|
4693f0 |
+ case ARPHRD_INFINIBAND:
|
|
|
4693f0 |
+ err = sk_interface_guidaddr(name, mac->sll.sll_addr);
|
|
|
4693f0 |
+ if (err) {
|
|
|
4693f0 |
+ pr_err("fail to get address using sysfs: %m");
|
|
|
4693f0 |
+ return -1;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+ mac->sll.sll_halen = EUI64;
|
|
|
4693f0 |
+ break;
|
|
|
4693f0 |
+ default:
|
|
|
4693f0 |
+ memcpy(mac->sll.sll_addr, &ifreq.ifr_hwaddr.sa_data, MAC_LEN);
|
|
|
4693f0 |
+ mac->sll.sll_halen = EUI48;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
mac->sll.sll_family = AF_PACKET;
|
|
|
4693f0 |
- mac->sll.sll_halen = MAC_LEN;
|
|
|
4693f0 |
- memcpy(mac->sll.sll_addr, &ifreq.ifr_hwaddr.sa_data, MAC_LEN);
|
|
|
4693f0 |
mac->len = sizeof(mac->sll);
|
|
|
4693f0 |
close(fd);
|
|
|
4693f0 |
return 0;
|
|
|
4693f0 |
diff --git a/util.c b/util.c
|
|
|
4693f0 |
index 2b880ff..62f2638 100644
|
|
|
4693f0 |
--- a/util.c
|
|
|
4693f0 |
+++ b/util.c
|
|
|
4693f0 |
@@ -135,14 +135,32 @@ int generate_clock_identity(struct ClockIdentity *ci, const char *name)
|
|
|
4693f0 |
|
|
|
4693f0 |
if (sk_interface_macaddr(name, &addr))
|
|
|
4693f0 |
return -1;
|
|
|
4693f0 |
- ci->id[0] = addr.sll.sll_addr[0];
|
|
|
4693f0 |
- ci->id[1] = addr.sll.sll_addr[1];
|
|
|
4693f0 |
- ci->id[2] = addr.sll.sll_addr[2];
|
|
|
4693f0 |
- ci->id[3] = 0xFF;
|
|
|
4693f0 |
- ci->id[4] = 0xFE;
|
|
|
4693f0 |
- ci->id[5] = addr.sll.sll_addr[3];
|
|
|
4693f0 |
- ci->id[6] = addr.sll.sll_addr[4];
|
|
|
4693f0 |
- ci->id[7] = addr.sll.sll_addr[5];
|
|
|
4693f0 |
+
|
|
|
4693f0 |
+ switch (addr.sll.sll_halen) {
|
|
|
4693f0 |
+ case EUI48:
|
|
|
4693f0 |
+ ci->id[0] = addr.sll.sll_addr[0];
|
|
|
4693f0 |
+ ci->id[1] = addr.sll.sll_addr[1];
|
|
|
4693f0 |
+ ci->id[2] = addr.sll.sll_addr[2];
|
|
|
4693f0 |
+ ci->id[3] = 0xFF;
|
|
|
4693f0 |
+ ci->id[4] = 0xFE;
|
|
|
4693f0 |
+ ci->id[5] = addr.sll.sll_addr[3];
|
|
|
4693f0 |
+ ci->id[6] = addr.sll.sll_addr[4];
|
|
|
4693f0 |
+ ci->id[7] = addr.sll.sll_addr[5];
|
|
|
4693f0 |
+ break;
|
|
|
4693f0 |
+ case EUI64:
|
|
|
4693f0 |
+ ci->id[0] = addr.sll.sll_addr[0];
|
|
|
4693f0 |
+ ci->id[1] = addr.sll.sll_addr[1];
|
|
|
4693f0 |
+ ci->id[2] = addr.sll.sll_addr[2];
|
|
|
4693f0 |
+ ci->id[3] = addr.sll.sll_addr[3];
|
|
|
4693f0 |
+ ci->id[4] = addr.sll.sll_addr[4];
|
|
|
4693f0 |
+ ci->id[5] = addr.sll.sll_addr[5];
|
|
|
4693f0 |
+ ci->id[6] = addr.sll.sll_addr[6];
|
|
|
4693f0 |
+ ci->id[7] = addr.sll.sll_addr[7];
|
|
|
4693f0 |
+ break;
|
|
|
4693f0 |
+ default:
|
|
|
4693f0 |
+ return -1;
|
|
|
4693f0 |
+ }
|
|
|
4693f0 |
+
|
|
|
4693f0 |
return 0;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
commit fd2646263f0fb1a31dde53e67ac24971ab1f90f4
|
|
|
4693f0 |
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
|
4693f0 |
Date: Mon Oct 16 11:29:48 2017 +0200
|
|
|
4693f0 |
|
|
|
4693f0 |
sk: don't leak socket when reading of IB GUID fails.
|
|
|
4693f0 |
|
|
|
4693f0 |
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
|
4693f0 |
|
|
|
4693f0 |
diff --git a/sk.c b/sk.c
|
|
|
4693f0 |
index 0cf55c5..2c7593b 100644
|
|
|
4693f0 |
--- a/sk.c
|
|
|
4693f0 |
+++ b/sk.c
|
|
|
4693f0 |
@@ -225,6 +225,8 @@ int sk_interface_macaddr(const char *name, struct address *mac)
|
|
|
4693f0 |
return -1;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|
|
|
4693f0 |
+ close(fd);
|
|
|
4693f0 |
+
|
|
|
4693f0 |
/* Get interface type */
|
|
|
4693f0 |
type = ifreq.ifr_hwaddr.sa_family;
|
|
|
4693f0 |
switch (type) {
|
|
|
4693f0 |
@@ -243,7 +245,6 @@ int sk_interface_macaddr(const char *name, struct address *mac)
|
|
|
4693f0 |
|
|
|
4693f0 |
mac->sll.sll_family = AF_PACKET;
|
|
|
4693f0 |
mac->len = sizeof(mac->sll);
|
|
|
4693f0 |
- close(fd);
|
|
|
4693f0 |
return 0;
|
|
|
4693f0 |
}
|
|
|
4693f0 |
|