aboutgitcodebugslistschat
path: root/pcap.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-07-21 12:01:04 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-07-21 12:01:04 +0200
commit64a0ba3b272dd9ee175e0c6256a6d0cb1733599b (patch)
tree4a9ab4a8c4a264ad66d12ac8cc597a062f788963 /pcap.c
parent7fa3e90290d1966e25f3f8882ee25f14808e8e48 (diff)
downloadpasst-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.gz
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.bz2
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.lz
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.xz
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.tar.zst
passt-64a0ba3b272dd9ee175e0c6256a6d0cb1733599b.zip
udp: Introduce recvmmsg()/sendmmsg(), zero-copy path from socket
Packets are received directly onto pre-cooked, static buffers for IPv4 (with partial checksum pre-calculation) and IPv6 frames, with pre-filled Ethernet addresses and, partially, IP headers, and sent out from the same buffers with sendmmsg(), for both passt and pasta (non-local traffic only) modes. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'pcap.c')
-rw-r--r--pcap.c82
1 files changed, 80 insertions, 2 deletions
diff --git a/pcap.c b/pcap.c
index c728b8a..90529ec 100644
--- a/pcap.c
+++ b/pcap.c
@@ -12,10 +12,12 @@
* Author: Stefano Brivio <sbrivio@redhat.com>
*/
+#define _GNU_SOURCE
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -91,6 +93,65 @@ void pcap(char *pkt, size_t len)
}
/**
+ * pcapm() - Capture multiple frames from message header to pcap file
+ * @mh: Pointer to sendmsg() message header buffer
+ */
+void pcapm(struct msghdr *mh)
+{
+ struct pcap_pkthdr h;
+ struct timeval tv;
+ unsigned int i;
+
+ if (pcap_fd == -1)
+ return;
+
+ gettimeofday(&tv, NULL);
+ h.tv_sec = tv.tv_sec;
+ h.tv_usec = tv.tv_usec;
+
+ for (i = 0; i < mh->msg_iovlen; i++) {
+ struct iovec *iov = &mh->msg_iov[i];
+
+ h.caplen = h.len = iov->iov_len - 4;
+ write(pcap_fd, &h, sizeof(h));
+
+ write(pcap_fd, (char *)iov->iov_base + 4, iov->iov_len - 4);
+ }
+}
+
+/**
+ * pcapm() - Capture multiple frames from multiple message headers to pcap file
+ * @mmh: Pointer to first sendmmsg() header
+ */
+void pcapmm(struct mmsghdr *mmh, unsigned int vlen)
+{
+ struct pcap_pkthdr h;
+ struct timeval tv;
+ unsigned int i, j;
+
+ if (pcap_fd == -1)
+ return;
+
+ gettimeofday(&tv, NULL);
+ h.tv_sec = tv.tv_sec;
+ h.tv_usec = tv.tv_usec;
+
+ for (i = 0; i < vlen; i++) {
+ struct msghdr *mh = &mmh[i].msg_hdr;
+
+ for (j = 0; j < mh->msg_iovlen; j++) {
+ struct iovec *iov = &mh->msg_iov[j];
+
+ h.caplen = h.len = iov->iov_len - 4;
+ write(pcap_fd, &h, sizeof(h));
+
+ write(pcap_fd, (char *)iov->iov_base + 4,
+ iov->iov_len - 4);
+ }
+ }
+}
+
+/**
* pcap_init() - Initialise pcap file
* @c: Execution context
* @index: pcap name index: passt instance number or pasta target pid
@@ -129,10 +190,27 @@ void pcap_init(struct ctx *c, int index)
}
#else /* DEBUG */
-void pcap(char *pkt, size_t len) {
+void pcap(char *pkt, size_t len)
+{
(void)pkt;
(void)len;
}
-void pcap_init(void) { }
+void pcapm(struct msghdr *mh)
+{
+ (void)mh;
+}
+
+void pcapmm(struct mmsghdr *mmh, unsigned int vlen)
+{
+ (void)mmh;
+ (void)vlen;
+}
+
+void pcap_init(struct ctx *c, int sock_index)
+{
+ (void)c;
+ (void)sock_index;
+
+}
#endif