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