pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-pcap/+/39948?usp=email )
Change subject: client: use pcap_dispatch to avoid extra pkt buffer copy
......................................................................
client: use pcap_dispatch to avoid extra pkt buffer copy
pcap_next() allows use of returned buffer until next time the same API
is called. In order to do so, it internally calls pcap_dispatch() with
an internal handler (in the case of linux pcapint_oneshot_linux()).
That handler basically memcpy()s the pkt buffer obtained in the
pcap_dispatch callback into a temporary static buffer which is then
returned.
We don't need any of that here, and by using pcap_dispatch() directly
(as recommended in pcapint_oneshot_linux() function documentation) we
can skip an extra memcpy() of each packet buffer captured.
Furthermore, it will allow us processing multiple packets from the
captured queue (RA_SOCKET+mmap implementation in linux) in one poll
iteration if several packets have been captured. This will be done in a
follow-up patch.
pcap handle is marked non-blocking to allow polling from it without
ending up blocked. Applying filter is moved beforehand, as seen in
libpcap capturetest example.
Related: SYS#7290
Change-Id: I055efb66fac5e04c541d75ec2c0f654cdfb17838
---
M src/osmo_client_core.c
1 file changed, 28 insertions(+), 14 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-pcap refs/changes/48/39948/1
diff --git a/src/osmo_client_core.c b/src/osmo_client_core.c
index 62b2c3c..5ded001 100644
--- a/src/osmo_client_core.c
+++ b/src/osmo_client_core.c
@@ -152,27 +152,36 @@
return check_gprs(payload_data, payload_len);
}
+static void pcap_read_one_cb(u_char *user, const struct pcap_pkthdr *hdr, const u_char
*data)
+{
+ struct osmo_pcap_handle *ph = (struct osmo_pcap_handle *)user;
+ struct osmo_pcap_client *client = ph->client;
+ struct osmo_pcap_client_conn *conn;
+
+ /* NOTE: hdr & data are only available during the call of this callback,
+ * and should be copied somewhere else if need be accessed later.
+ * In here we are fine since we generate a msgb and copy over the
+ * content on each loop iteration below. */
+
+ if (!can_forward_packet(client, ph, hdr, data))
+ return;
+
+ llist_for_each_entry(conn, &client->conns, entry)
+ osmo_client_conn_send_data(conn, ph, hdr, data);
+}
static int pcap_read_cb(struct osmo_fd *fd, unsigned int what)
{
struct osmo_pcap_handle *ph = fd->data;
- struct osmo_pcap_client *client = ph->client;
- struct osmo_pcap_client_conn *conn;
- struct pcap_pkthdr hdr;
- const u_char *data;
+ int rc;
- data = pcap_next(ph->handle, &hdr);
- if (!data) {
+ rc = pcap_dispatch(ph->handle, 1, pcap_read_one_cb, (u_char *)ph);
+ if (rc < 0) {
rate_ctr_inc2(ph->ctrg, PH_CTR_PERR);
- rate_ctr_inc2(client->ctrg, CLIENT_CTR_PERR);
+ rate_ctr_inc2(ph->client->ctrg, CLIENT_CTR_PERR);
return -1;
}
- if (!can_forward_packet(client, ph, &hdr, data))
- return 0;
-
- llist_for_each_entry(conn, &client->conns, entry)
- osmo_client_conn_send_data(conn, ph, &hdr, data);
return 0;
}
@@ -440,6 +449,7 @@
struct osmo_pcap_client *client = ph->client;
int fd;
char errbuf[PCAP_ERRBUF_SIZE];
+ int one = 1;
LOGPH(ph, LOGL_INFO, "Opening device for capture with snaplen %zu\n", (size_t)
client->snaplen);
ph->handle = pcap_open_live(ph->devname, client->snaplen, 0, 1000, errbuf);
@@ -448,6 +458,12 @@
return -2;
}
+ if (client->filter_string)
+ osmo_pcap_handle_install_filter(ph);
+
+ if (pcap_setnonblock(ph->handle, one, errbuf) == -1)
+ LOGPH(ph, LOGL_ERROR, "Failed pcap_setnonblock(): %s\n", errbuf);
+
fd = pcap_fileno(ph->handle);
if (fd == -1) {
LOGPH(ph, LOGL_ERROR, "No file descriptor provided.\n");
@@ -463,7 +479,5 @@
osmo_timer_setup(&ph->pcap_stat_timer, pcap_check_stats_cb, ph);
pcap_check_stats_cb(ph);
- if (client->filter_string)
- osmo_pcap_handle_install_filter(ph);
return 0;
}
--
To view, visit
https://gerrit.osmocom.org/c/osmo-pcap/+/39948?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmo-pcap
Gerrit-Branch: master
Gerrit-Change-Id: I055efb66fac5e04c541d75ec2c0f654cdfb17838
Gerrit-Change-Number: 39948
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>