ThrottleController.cpp revision a1992c9ff3e0d180c1f3042658ab9671d61a2fb8
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdlib.h> 18#include <errno.h> 19#include <fcntl.h> 20 21#include <sys/socket.h> 22#include <sys/stat.h> 23#include <sys/types.h> 24#include <sys/wait.h> 25 26#include <linux/netlink.h> 27#include <linux/rtnetlink.h> 28#include <linux/pkt_sched.h> 29 30#define LOG_TAG "ThrottleController" 31#include <cutils/log.h> 32 33 34#include "ThrottleController.h" 35 36static char TC_PATH[] = "/system/bin/tc"; 37 38extern "C" int logwrap(int argc, const char **argv, int background); 39 40int ThrottleController::runTcCmd(const char *cmd) { 41 char buffer[255]; 42 43 strncpy(buffer, cmd, sizeof(buffer)-1); 44 45 const char *args[32]; 46 char *next = buffer; 47 char *tmp; 48 49 args[0] = TC_PATH; 50 int i = 1; 51 52 while ((tmp = strsep(&next, " "))) { 53 args[i++] = tmp; 54 if (i == 32) { 55 LOGE("tc argument overflow"); 56 errno = E2BIG; 57 return -1; 58 } 59 } 60 args[i] = NULL; 61 62 return logwrap(i, args, 0); 63} 64 65int ThrottleController::setInterfaceThrottle(const char *iface, int rxKbps, int txKbps) { 66 char *cmd; 67 int rc; 68 69 if (txKbps == -1) { 70 reset(iface); 71 return 0; 72 } 73 74 asprintf(&cmd, "qdisc add dev %s root handle 1: cbq avpkt 1000 bandwidth 10mbit", iface); 75 rc = runTcCmd(cmd); 76 free(cmd); 77 if (rc) { 78 LOGE("Failed to add cbq qdisc (%s)", strerror(errno)); 79 reset(iface); 80 return -1; 81 } 82 83 asprintf(&cmd, 84 "class add dev %s parent 1: classid 1:1 cbq rate %dkbit allot 1500 prio 5 bounded isolated", 85 iface, txKbps); 86 rc = runTcCmd(cmd); 87 free(cmd); 88 if (rc) { 89 LOGE("Failed to add class (%s)", strerror(errno)); 90 reset(iface); 91 return -1; 92 } 93 94 asprintf(&cmd, 95 "filter add dev %s parent 1: protocol ip prio 16 u32 match ip dst 0.0.0.0/0 flowid 1:1", 96 iface); 97 rc = runTcCmd(cmd); 98 free(cmd); 99 if (runTcCmd(cmd)) { 100 LOGE("Failed to add filter (%s)", strerror(errno)); 101 reset(iface); 102 return -1; 103 } 104 105 return 0; 106} 107 108void ThrottleController::reset(const char *iface) { 109 char *cmd; 110 asprintf(&cmd, "qdisc del dev %s root", iface); 111 runTcCmd(cmd); 112 free(cmd); 113} 114 115int ThrottleController::getInterfaceRxThrottle(const char *iface, int *rx) { 116 *rx = 0; 117 return 0; 118} 119 120int ThrottleController::getInterfaceTxThrottle(const char *iface, int *tx) { 121 *tx = 0; 122 return 0; 123} 124