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>