summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2015-09-26 01:27:34 +0900
committerSteve Kondik <steve@cyngn.com>2016-06-08 21:15:23 -0700
commitbee83f8d7edb48a1d8b8f2333a1b259854c44b95 (patch)
tree4b32117a26b25295f155ac185b3eca0ec26396c2
parent4f99df509e1e6626967aa8bb394045932e75576b (diff)
downloadandroid_external_android-clat-stable/cm-13.0-ZNH5Y.tar.gz
android_external_android-clat-stable/cm-13.0-ZNH5Y.tar.bz2
android_external_android-clat-stable/cm-13.0-ZNH5Y.zip
Add a "packet_burst" config option that will cause clatd to read (and write) in bursts of up to that number of packets, instead of always only reading one packet at a time. This reduces poll overhead and improves performance. The variable is initially set to 10. Bug: 24113287 Change-Id: I7feba4127538c5a89f92e0ebea1fb75971d6b901
-rw-r--r--clatd.c55
-rw-r--r--clatd.conf3
-rw-r--r--config.c8
-rw-r--r--config.h1
-rw-r--r--ring.c4
5 files changed, 44 insertions, 27 deletions
diff --git a/clatd.c b/clatd.c
index 64f2ebe..1d21977 100644
--- a/clatd.c
+++ b/clatd.c
@@ -333,39 +333,42 @@ void configure_interface(const char *uplink_interface, const char *plat_prefix,
void read_packet(int read_fd, int write_fd, int to_ipv6) {
ssize_t readlen;
uint8_t buf[PACKETLEN], *packet;
+ int numread = 0;
- readlen = read(read_fd, buf, PACKETLEN);
+ do {
+ readlen = read(read_fd, buf, PACKETLEN);
- if(readlen < 0) {
- if (errno != EAGAIN) {
- logmsg(ANDROID_LOG_WARN,"read_packet/read error: %s", strerror(errno));
+ if(readlen < 0) {
+ if (errno != EAGAIN) {
+ logmsg(ANDROID_LOG_WARN,"read_packet/read error: %s", strerror(errno));
+ }
+ return;
+ } else if(readlen == 0) {
+ logmsg(ANDROID_LOG_WARN,"read_packet/tun interface removed");
+ running = 0;
+ return;
}
- return;
- } else if(readlen == 0) {
- logmsg(ANDROID_LOG_WARN,"read_packet/tun interface removed");
- running = 0;
- return;
- }
- struct tun_pi *tun_header = (struct tun_pi *) buf;
- if (readlen < (ssize_t) sizeof(*tun_header)) {
- logmsg(ANDROID_LOG_WARN,"read_packet/short read: got %ld bytes", readlen);
- return;
- }
+ struct tun_pi *tun_header = (struct tun_pi *) buf;
+ if (readlen < (ssize_t) sizeof(*tun_header)) {
+ logmsg(ANDROID_LOG_WARN,"read_packet/short read: got %ld bytes", readlen);
+ return;
+ }
- uint16_t proto = ntohs(tun_header->proto);
- if (proto != ETH_P_IP) {
- logmsg(ANDROID_LOG_WARN, "%s: unknown packet type = 0x%x", __func__, proto);
- return;
- }
+ uint16_t proto = ntohs(tun_header->proto);
+ if (proto != ETH_P_IP) {
+ logmsg(ANDROID_LOG_WARN, "%s: unknown packet type = 0x%x", __func__, proto);
+ return;
+ }
- if(tun_header->flags != 0) {
- logmsg(ANDROID_LOG_WARN, "%s: unexpected flags = %d", __func__, tun_header->flags);
- }
+ if(tun_header->flags != 0) {
+ logmsg(ANDROID_LOG_WARN, "%s: unexpected flags = %d", __func__, tun_header->flags);
+ }
- packet = (uint8_t *) (tun_header + 1);
- readlen -= sizeof(*tun_header);
- translate_packet(write_fd, to_ipv6, packet, readlen, TP_CSUM_NONE);
+ packet = (uint8_t *) (tun_header + 1);
+ readlen -= sizeof(*tun_header);
+ translate_packet(write_fd, to_ipv6, packet, readlen, TP_CSUM_NONE);
+ } while (++numread < Global_Clatd_Config.packet_burst);
}
/* function: recv_loop
diff --git a/clatd.conf b/clatd.conf
index ff80975..dcbdd09 100644
--- a/clatd.conf
+++ b/clatd.conf
@@ -20,3 +20,6 @@ plat_from_dns64_hostname ipv4only.arpa
# plat subnet to send ipv4 traffic to. This is a /96 subnet.
# This setting only makes sense with: plat_from_dns64 no
#plat_subnet 2001:db8:1:2:3:4::
+
+# how many packets to process at a time.
+packet_burst 10
diff --git a/config.c b/config.c
index b147868..84a1e0e 100644
--- a/config.c
+++ b/config.c
@@ -371,6 +371,13 @@ int read_config(const char *file, const char *uplink_interface, const char *plat
Global_Clatd_Config.use_dynamic_iid = 1;
}
+ if(!config_item_int16_t(root, "packet_burst", "10", &Global_Clatd_Config.packet_burst))
+ goto failed;
+
+ if (Global_Clatd_Config.packet_burst < 1 || Global_Clatd_Config.packet_burst > 50) {
+ logmsg(ANDROID_LOG_FATAL, "invalid value packet_burst %d", Global_Clatd_Config.packet_burst);
+ }
+
return 1;
failed:
@@ -392,4 +399,5 @@ void dump_config() {
logmsg(ANDROID_LOG_DEBUG,"ipv4_local_prefixlen = %d", Global_Clatd_Config.ipv4_local_prefixlen);
logmsg(ANDROID_LOG_DEBUG,"plat_subnet = %s",inet_ntop(AF_INET6, &Global_Clatd_Config.plat_subnet, charbuffer, sizeof(charbuffer)));
logmsg(ANDROID_LOG_DEBUG,"default_pdp_interface = %s",Global_Clatd_Config.default_pdp_interface);
+ logmsg(ANDROID_LOG_DEBUG,"packet burst = %d",Global_Clatd_Config.packet_burst);
}
diff --git a/config.h b/config.h
index e31a81d..f562fdf 100644
--- a/config.h
+++ b/config.h
@@ -35,6 +35,7 @@ struct clat_config {
char *default_pdp_interface;
char *plat_from_dns64_hostname;
int use_dynamic_iid;
+ int16_t packet_burst;
};
extern struct clat_config Global_Clatd_Config;
diff --git a/ring.c b/ring.c
index 17f8026..dcf4310 100644
--- a/ring.c
+++ b/ring.c
@@ -24,6 +24,7 @@
#include <linux/if.h>
#include <linux/if_packet.h>
+#include "config.h"
#include "logging.h"
#include "ring.h"
#include "translate.h"
@@ -116,9 +117,10 @@ static struct tpacket2_hdr* ring_advance(struct packet_ring *ring) {
* to_ipv6 - whether the packet is to be translated to ipv6 or ipv4
*/
void ring_read(struct packet_ring *ring, int write_fd, int to_ipv6) {
+ int numread = 0;
struct tpacket2_hdr *tp = ring->next;
uint16_t val = TP_CSUM_NONE;
- if (tp->tp_status & TP_STATUS_USER) {
+ while (tp->tp_status & TP_STATUS_USER && numread++ < Global_Clatd_Config.packet_burst) {
//We expect only GRO coalesced packets to have TP_STATUS_CSUMNOTREADY
//(ip_summed = CHECKSUM_PARTIAL) in this path. Note that these packets have already gone
//through checksum validation in GRO engine. CHECKSUM_PARTIAL is defined to be 3 while