pespin has submitted this change. ( 
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(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, but someone else must approve
  osmith: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved




diff --git a/src/osmo_client_core.c b/src/osmo_client_core.c
index 62b2c3c..e58439b 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;
 }

@@ -448,6 +457,13 @@
                return -2;
        }

+       if (client->filter_string)
+               osmo_pcap_handle_install_filter(ph);
+
+       errbuf[0] = '\0';
+       if (pcap_setnonblock(ph->handle, 1, errbuf) != 0)
+               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: merged
Gerrit-Project: osmo-pcap
Gerrit-Branch: master
Gerrit-Change-Id: I055efb66fac5e04c541d75ec2c0f654cdfb17838
Gerrit-Change-Number: 39948
Gerrit-PatchSet: 6
Gerrit-Owner: pespin <pes...@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillm...@sysmocom.de>
Gerrit-Reviewer: laforge <lafo...@osmocom.org>
Gerrit-Reviewer: osmith <osm...@sysmocom.de>
Gerrit-Reviewer: pespin <pes...@sysmocom.de>
Gerrit-CC: fixeria <vyanits...@sysmocom.de>

Reply via email to