diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2015-09-26 01:27:34 +0900 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2016-06-08 21:15:23 -0700 |
commit | bee83f8d7edb48a1d8b8f2333a1b259854c44b95 (patch) | |
tree | 4b32117a26b25295f155ac185b3eca0ec26396c2 | |
parent | 4f99df509e1e6626967aa8bb394045932e75576b (diff) | |
download | android_external_android-clat-bee83f8d7edb48a1d8b8f2333a1b259854c44b95.tar.gz android_external_android-clat-bee83f8d7edb48a1d8b8f2333a1b259854c44b95.tar.bz2 android_external_android-clat-bee83f8d7edb48a1d8b8f2333a1b259854c44b95.zip |
Process packets in bursts.HEADreplicant-6.0-0004-transitionreplicant-6.0-0004-rc6replicant-6.0-0004-rc5-transitionreplicant-6.0-0004-rc5replicant-6.0-0004-rc4replicant-6.0-0004-rc3replicant-6.0-0004-rc2replicant-6.0-0004-rc1replicant-6.0-0004replicant-6.0-0003replicant-6.0-0002replicant-6.0-0001stable/cm-13.0-ZNH5Ycm-13.0
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.c | 55 | ||||
-rw-r--r-- | clatd.conf | 3 | ||||
-rw-r--r-- | config.c | 8 | ||||
-rw-r--r-- | config.h | 1 | ||||
-rw-r--r-- | ring.c | 4 |
5 files changed, 44 insertions, 27 deletions
@@ -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 @@ -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 @@ -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); } @@ -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; @@ -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 |