As per G.8275 (Annex-B) including virtual PTP ports on a PTP clock. This
virtual port will be used to support APTS, IWF between different
clock_domains.

Signed-off-by: Greg Armstrong <greg.armstrong...@renesas.com>
Signed-off-by: Leon Goldin <leon.goldin...@renesas.com>
Signed-off-by: Vipin Sharma <vipin.sha...@syncmonk.net>
Signed-off-by: Devasish Dey <devasish....@syncmonk.net>
---
 makefile |   6 +--
 vport.c  | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 vport.h  |  20 ++++++++
 3 files changed, 159 insertions(+), 3 deletions(-)
 create mode 100644 vport.c
 create mode 100644 vport.h

diff --git a/makefile b/makefile
index 5295b60..cd1f3ef 100644
--- a/makefile
+++ b/makefile
@@ -25,7 +25,7 @@ LDLIBS        = -lm -lrt -pthread $(EXTRA_LDFLAGS)
 PRG    = ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster ts2phc
 FILTERS        = filter.o mave.o mmedian.o
 SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o
-TRANSP = raw.o transport.o udp.o udp6.o uds.o
+TRANSP = raw.o transport.o udp.o udp6.o uds.o vport.o
 TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o ts2phc_generic_pps_source.o \
  ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o
 OBJ    = bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
@@ -68,8 +68,8 @@ phc_ctl: phc_ctl.o phc.o sk.o util.o clockadj.o sysoff.o 
print.o version.o
 
 timemaster: phc.o print.o rtnl.o sk.o timemaster.o util.o version.o
 
-ts2phc: config.o clockadj.o hash.o interface.o phc.o print.o $(SERVOS) sk.o \
- $(TS2PHC) util.o version.o
+ts2phc: config.o clockadj.o hash.o msg.o tlv.o interface.o phc.o print.o 
$(SERVOS) sk.o \
+ $(TS2PHC) $(TRANSP) util.o version.o
 
 version.o: .version version.sh $(filter-out version.d,$(DEPEND))
 
diff --git a/vport.c b/vport.c
new file mode 100644
index 0000000..58241ea
--- /dev/null
+++ b/vport.c
@@ -0,0 +1,136 @@
+/**
+ * @file vport.c
+ * @note Copyright (C) 2022 SyncMonk Technologies <servi...@syncmonk.net>
+ * @note SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "address.h"
+#include "contain.h"
+#include "print.h"
+#include "transport_private.h"
+#include "vport.h"
+
+#define VPORT_FILEMODE (0660) /*0660*/
+
+struct vport {
+       struct transport t;
+       struct address address;
+};
+
+static int vport_close(struct transport *t, struct fdarray *fda)
+{
+       struct sockaddr_un sa;
+       socklen_t len = sizeof(sa);
+
+       if (!getsockname(fda->fd[FD_GENERAL], (struct sockaddr *) &sa, &len) &&
+           sa.sun_family == AF_LOCAL) {
+               unlink(sa.sun_path);
+       }
+
+       close(fda->fd[FD_GENERAL]);
+       return 0;
+}
+
+static int vport_open(struct transport *t, struct interface *iface, struct 
fdarray *fda,
+                   enum timestamp_type tt)
+{
+       char *vport_path = config_get_string(t->cfg, NULL, "vport_address");
+       struct vport *vport = container_of(t, struct vport, t);
+       const char *name = interface_name(iface);
+       struct sockaddr_un sa;
+       int fd, err;
+
+       fd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+       if (fd < 0) {
+               pr_err("vport: failed to create socket: %m");
+               return -1;
+       }
+       memset(&sa, 0, sizeof(sa));
+       sa.sun_family = AF_LOCAL;
+       strncpy(sa.sun_path, name, sizeof(sa.sun_path) - 1);
+
+       unlink(name);
+
+       err = bind(fd, (struct sockaddr *) &sa, sizeof(sa));
+       if (err < 0) {
+               pr_err("vport: bind failed: %m");
+               close(fd);
+               return -1;
+       }
+
+       /* For client use, pre load the server path. */
+       memset(&sa, 0, sizeof(sa));
+       sa.sun_family = AF_LOCAL;
+       strncpy(sa.sun_path, vport_path, sizeof(sa.sun_path) - 1);
+       vport->address.sun = sa;
+       vport->address.len = sizeof(sa);
+
+       chmod(name, VPORT_FILEMODE);
+       fda->fd[FD_EVENT] = -1;
+       fda->fd[FD_GENERAL] = fd;
+       return 0;
+}
+
+static int vport_recv(struct transport *t, int fd, void *buf, int buflen,
+                   struct address *addr, struct hw_timestamp *hwts)
+{
+       int cnt;
+       struct vport *vport = container_of(t, struct vport, t);
+
+       addr->len = sizeof(addr->sun);
+       cnt = recvfrom(fd, buf, buflen, 0, &addr->sa, &addr->len);
+       if (cnt <= 0) {
+               pr_err("vport: recvfrom failed: %m");
+               return cnt;
+       }
+       vport->address = *addr;
+       return cnt;
+}
+
+static int vport_send(struct transport *t, struct fdarray *fda,
+                   enum transport_event event, int peer, void *buf, int buflen,
+                   struct address *addr, struct hw_timestamp *hwts)
+{
+       int cnt, fd = fda->fd[FD_GENERAL];
+       struct vport *vport = container_of(t, struct vport, t);
+
+       if (!addr)
+               addr = &vport->address;
+
+       cnt = sendto(fd, buf, buflen, 0, &addr->sa, addr->len);
+       if (cnt < 1) {
+               return -errno;
+       }
+       return cnt;
+}
+
+static void vport_release(struct transport *t)
+{
+       struct vport *vport = container_of(t, struct vport, t);
+
+       free(vport);
+}
+
+struct transport *vport_transport_create(void)
+{
+       struct vport *vport;
+
+       vport = calloc(1, sizeof(*vport));
+       if (!vport)
+               return NULL;
+       vport->t.close   = vport_close;
+       vport->t.open    = vport_open;
+       vport->t.recv    = vport_recv;
+       vport->t.send    = vport_send;
+       vport->t.release = vport_release;
+       return &vport->t;
+}
diff --git a/vport.h b/vport.h
new file mode 100644
index 0000000..a479fe7
--- /dev/null
+++ b/vport.h
@@ -0,0 +1,20 @@
+/**
+ * @file vport.h
+ * @note Copyright (C) 2022 SyncMonk Technologies <servi...@syncmonk.net>
+ * @note SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+#ifndef HAVE_VPORT_H
+#define HAVE_VPORT_H
+
+#include "config.h"
+#include "fd.h"
+#include "transport.h"
+
+/**
+ * Allocate an instance of a VPORT transport.
+ * @return Pointer to a new transport instance on success, NULL otherwise.
+ */
+struct transport *vport_transport_create(void);
+
+#endif
-- 
2.17.1



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to