1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python 2*387f9dfdSAndroid Build Coastguard Worker 3*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function 4*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF 5*387f9dfdSAndroid Build Coastguard Workerfrom ctypes import * 6*387f9dfdSAndroid Build Coastguard Workerimport argparse 7*387f9dfdSAndroid Build Coastguard Workerimport os 8*387f9dfdSAndroid Build Coastguard Workerfrom time import sleep,time,localtime,asctime 9*387f9dfdSAndroid Build Coastguard Worker 10*387f9dfdSAndroid Build Coastguard Worker# pre defines ------------------------------- 11*387f9dfdSAndroid Build Coastguard WorkerROOT_PATH = "/sys/class/net" 12*387f9dfdSAndroid Build Coastguard WorkerIFNAMSIZ = 16 13*387f9dfdSAndroid Build Coastguard WorkerCOL_WIDTH = 10 14*387f9dfdSAndroid Build Coastguard WorkerMAX_QUEUE_NUM = 1024 15*387f9dfdSAndroid Build Coastguard WorkerEBPF_FILE = "netqtop.c" 16*387f9dfdSAndroid Build Coastguard Worker 17*387f9dfdSAndroid Build Coastguard Worker# structure for network interface name array 18*387f9dfdSAndroid Build Coastguard Workerclass Devname(Structure): 19*387f9dfdSAndroid Build Coastguard Worker _fields_=[ 20*387f9dfdSAndroid Build Coastguard Worker ('name', c_char*IFNAMSIZ) 21*387f9dfdSAndroid Build Coastguard Worker ] 22*387f9dfdSAndroid Build Coastguard Worker 23*387f9dfdSAndroid Build Coastguard Worker################## printer for results ################### 24*387f9dfdSAndroid Build Coastguard Workerdef to_str(num): 25*387f9dfdSAndroid Build Coastguard Worker s = "" 26*387f9dfdSAndroid Build Coastguard Worker if num > 1000000: 27*387f9dfdSAndroid Build Coastguard Worker return str(round(num/(1024*1024.0), 2)) + 'M' 28*387f9dfdSAndroid Build Coastguard Worker elif num > 1000: 29*387f9dfdSAndroid Build Coastguard Worker return str(round(num/1024.0, 2)) + 'K' 30*387f9dfdSAndroid Build Coastguard Worker else: 31*387f9dfdSAndroid Build Coastguard Worker if isinstance(num, float): 32*387f9dfdSAndroid Build Coastguard Worker return str(round(num, 2)) 33*387f9dfdSAndroid Build Coastguard Worker else: 34*387f9dfdSAndroid Build Coastguard Worker return str(num) 35*387f9dfdSAndroid Build Coastguard Worker 36*387f9dfdSAndroid Build Coastguard Workerdef print_table(table, qnum): 37*387f9dfdSAndroid Build Coastguard Worker global print_interval 38*387f9dfdSAndroid Build Coastguard Worker 39*387f9dfdSAndroid Build Coastguard Worker # ---- print headers ---------------- 40*387f9dfdSAndroid Build Coastguard Worker headers = [ 41*387f9dfdSAndroid Build Coastguard Worker "QueueID", 42*387f9dfdSAndroid Build Coastguard Worker "avg_size", 43*387f9dfdSAndroid Build Coastguard Worker "[0, 64)", 44*387f9dfdSAndroid Build Coastguard Worker "[64, 512)", 45*387f9dfdSAndroid Build Coastguard Worker "[512, 2K)", 46*387f9dfdSAndroid Build Coastguard Worker "[2K, 16K)", 47*387f9dfdSAndroid Build Coastguard Worker "[16K, 64K)" 48*387f9dfdSAndroid Build Coastguard Worker ] 49*387f9dfdSAndroid Build Coastguard Worker if args.throughput: 50*387f9dfdSAndroid Build Coastguard Worker headers.append("BPS") 51*387f9dfdSAndroid Build Coastguard Worker headers.append("PPS") 52*387f9dfdSAndroid Build Coastguard Worker 53*387f9dfdSAndroid Build Coastguard Worker print(" ", end="") 54*387f9dfdSAndroid Build Coastguard Worker for hd in headers: 55*387f9dfdSAndroid Build Coastguard Worker print( "%-11s" % hd, end="") 56*387f9dfdSAndroid Build Coastguard Worker print() 57*387f9dfdSAndroid Build Coastguard Worker 58*387f9dfdSAndroid Build Coastguard Worker # ------- calculates -------------- 59*387f9dfdSAndroid Build Coastguard Worker qids=[] 60*387f9dfdSAndroid Build Coastguard Worker tBPS = 0 61*387f9dfdSAndroid Build Coastguard Worker tPPS = 0 62*387f9dfdSAndroid Build Coastguard Worker tAVG = 0 63*387f9dfdSAndroid Build Coastguard Worker tGroup = [0,0,0,0,0] 64*387f9dfdSAndroid Build Coastguard Worker tpkt = 0 65*387f9dfdSAndroid Build Coastguard Worker tlen = 0 66*387f9dfdSAndroid Build Coastguard Worker for k, v in table.items(): 67*387f9dfdSAndroid Build Coastguard Worker qids += [k.value] 68*387f9dfdSAndroid Build Coastguard Worker tlen += v.total_pkt_len 69*387f9dfdSAndroid Build Coastguard Worker tpkt += v.num_pkt 70*387f9dfdSAndroid Build Coastguard Worker tGroup[0] += v.size_64B 71*387f9dfdSAndroid Build Coastguard Worker tGroup[1] += v.size_512B 72*387f9dfdSAndroid Build Coastguard Worker tGroup[2] += v.size_2K 73*387f9dfdSAndroid Build Coastguard Worker tGroup[3] += v.size_16K 74*387f9dfdSAndroid Build Coastguard Worker tGroup[4] += v.size_64K 75*387f9dfdSAndroid Build Coastguard Worker tBPS = tlen / print_interval 76*387f9dfdSAndroid Build Coastguard Worker tPPS = tpkt / print_interval 77*387f9dfdSAndroid Build Coastguard Worker if tpkt != 0: 78*387f9dfdSAndroid Build Coastguard Worker tAVG = tlen / tpkt 79*387f9dfdSAndroid Build Coastguard Worker 80*387f9dfdSAndroid Build Coastguard Worker # -------- print table -------------- 81*387f9dfdSAndroid Build Coastguard Worker for k in range(qnum): 82*387f9dfdSAndroid Build Coastguard Worker if k in qids: 83*387f9dfdSAndroid Build Coastguard Worker item = table[c_ushort(k)] 84*387f9dfdSAndroid Build Coastguard Worker data = [ 85*387f9dfdSAndroid Build Coastguard Worker k, 86*387f9dfdSAndroid Build Coastguard Worker item.total_pkt_len, 87*387f9dfdSAndroid Build Coastguard Worker item.num_pkt, 88*387f9dfdSAndroid Build Coastguard Worker item.size_64B, 89*387f9dfdSAndroid Build Coastguard Worker item.size_512B, 90*387f9dfdSAndroid Build Coastguard Worker item.size_2K, 91*387f9dfdSAndroid Build Coastguard Worker item.size_16K, 92*387f9dfdSAndroid Build Coastguard Worker item.size_64K 93*387f9dfdSAndroid Build Coastguard Worker ] 94*387f9dfdSAndroid Build Coastguard Worker else: 95*387f9dfdSAndroid Build Coastguard Worker data = [k,0,0,0,0,0,0,0] 96*387f9dfdSAndroid Build Coastguard Worker 97*387f9dfdSAndroid Build Coastguard Worker # print a line per queue 98*387f9dfdSAndroid Build Coastguard Worker avg = 0 99*387f9dfdSAndroid Build Coastguard Worker if data[2] != 0: 100*387f9dfdSAndroid Build Coastguard Worker avg = data[1] / data[2] 101*387f9dfdSAndroid Build Coastguard Worker print(" %-11d%-11s%-11s%-11s%-11s%-11s%-11s" % ( 102*387f9dfdSAndroid Build Coastguard Worker data[0], 103*387f9dfdSAndroid Build Coastguard Worker to_str(avg), 104*387f9dfdSAndroid Build Coastguard Worker to_str(data[3]), 105*387f9dfdSAndroid Build Coastguard Worker to_str(data[4]), 106*387f9dfdSAndroid Build Coastguard Worker to_str(data[5]), 107*387f9dfdSAndroid Build Coastguard Worker to_str(data[6]), 108*387f9dfdSAndroid Build Coastguard Worker to_str(data[7]) 109*387f9dfdSAndroid Build Coastguard Worker ), end="") 110*387f9dfdSAndroid Build Coastguard Worker if args.throughput: 111*387f9dfdSAndroid Build Coastguard Worker BPS = data[1] / print_interval 112*387f9dfdSAndroid Build Coastguard Worker PPS = data[2] / print_interval 113*387f9dfdSAndroid Build Coastguard Worker print("%-11s%-11s" % ( 114*387f9dfdSAndroid Build Coastguard Worker to_str(BPS), 115*387f9dfdSAndroid Build Coastguard Worker to_str(PPS) 116*387f9dfdSAndroid Build Coastguard Worker )) 117*387f9dfdSAndroid Build Coastguard Worker else: 118*387f9dfdSAndroid Build Coastguard Worker print() 119*387f9dfdSAndroid Build Coastguard Worker 120*387f9dfdSAndroid Build Coastguard Worker # ------- print total -------------- 121*387f9dfdSAndroid Build Coastguard Worker print(" Total %-11s%-11s%-11s%-11s%-11s%-11s" % ( 122*387f9dfdSAndroid Build Coastguard Worker to_str(tAVG), 123*387f9dfdSAndroid Build Coastguard Worker to_str(tGroup[0]), 124*387f9dfdSAndroid Build Coastguard Worker to_str(tGroup[1]), 125*387f9dfdSAndroid Build Coastguard Worker to_str(tGroup[2]), 126*387f9dfdSAndroid Build Coastguard Worker to_str(tGroup[3]), 127*387f9dfdSAndroid Build Coastguard Worker to_str(tGroup[4]) 128*387f9dfdSAndroid Build Coastguard Worker ), end="") 129*387f9dfdSAndroid Build Coastguard Worker 130*387f9dfdSAndroid Build Coastguard Worker if args.throughput: 131*387f9dfdSAndroid Build Coastguard Worker print("%-11s%-11s" % ( 132*387f9dfdSAndroid Build Coastguard Worker to_str(tBPS), 133*387f9dfdSAndroid Build Coastguard Worker to_str(tPPS) 134*387f9dfdSAndroid Build Coastguard Worker )) 135*387f9dfdSAndroid Build Coastguard Worker else: 136*387f9dfdSAndroid Build Coastguard Worker print() 137*387f9dfdSAndroid Build Coastguard Worker 138*387f9dfdSAndroid Build Coastguard Worker 139*387f9dfdSAndroid Build Coastguard Workerdef print_result(b): 140*387f9dfdSAndroid Build Coastguard Worker # --------- print tx queues --------------- 141*387f9dfdSAndroid Build Coastguard Worker print(asctime(localtime(time()))) 142*387f9dfdSAndroid Build Coastguard Worker print("TX") 143*387f9dfdSAndroid Build Coastguard Worker table = b['tx_q'] 144*387f9dfdSAndroid Build Coastguard Worker print_table(table, tx_num) 145*387f9dfdSAndroid Build Coastguard Worker b['tx_q'].clear() 146*387f9dfdSAndroid Build Coastguard Worker 147*387f9dfdSAndroid Build Coastguard Worker # --------- print rx queues --------------- 148*387f9dfdSAndroid Build Coastguard Worker print("") 149*387f9dfdSAndroid Build Coastguard Worker print("RX") 150*387f9dfdSAndroid Build Coastguard Worker table = b['rx_q'] 151*387f9dfdSAndroid Build Coastguard Worker print_table(table, rx_num) 152*387f9dfdSAndroid Build Coastguard Worker b['rx_q'].clear() 153*387f9dfdSAndroid Build Coastguard Worker if args.throughput: 154*387f9dfdSAndroid Build Coastguard Worker print("-"*95) 155*387f9dfdSAndroid Build Coastguard Worker else: 156*387f9dfdSAndroid Build Coastguard Worker print("-"*77) 157*387f9dfdSAndroid Build Coastguard Worker 158*387f9dfdSAndroid Build Coastguard Worker############## specify network interface ################# 159*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(description="") 160*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--name", "-n", type=str, default="") 161*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--interval", "-i", type=float, default=1) 162*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--throughput", "-t", action="store_true") 163*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true", help=argparse.SUPPRESS) 164*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args() 165*387f9dfdSAndroid Build Coastguard Worker 166*387f9dfdSAndroid Build Coastguard Workerif args.ebpf: 167*387f9dfdSAndroid Build Coastguard Worker with open(EBPF_FILE) as fileobj: 168*387f9dfdSAndroid Build Coastguard Worker progtxt = fileobj.read() 169*387f9dfdSAndroid Build Coastguard Worker print(progtxt) 170*387f9dfdSAndroid Build Coastguard Worker exit() 171*387f9dfdSAndroid Build Coastguard Worker 172*387f9dfdSAndroid Build Coastguard Workerif args.name == "": 173*387f9dfdSAndroid Build Coastguard Worker print ("Please specify a network interface.") 174*387f9dfdSAndroid Build Coastguard Worker exit() 175*387f9dfdSAndroid Build Coastguard Workerelse: 176*387f9dfdSAndroid Build Coastguard Worker dev_name = args.name 177*387f9dfdSAndroid Build Coastguard Worker 178*387f9dfdSAndroid Build Coastguard Workerif len(dev_name) > IFNAMSIZ-1: 179*387f9dfdSAndroid Build Coastguard Worker print ("NIC name too long") 180*387f9dfdSAndroid Build Coastguard Worker exit() 181*387f9dfdSAndroid Build Coastguard Worker 182*387f9dfdSAndroid Build Coastguard Workerprint_interval = args.interval + 0.0 183*387f9dfdSAndroid Build Coastguard Workerif print_interval == 0: 184*387f9dfdSAndroid Build Coastguard Worker print ("print interval must be non-zero") 185*387f9dfdSAndroid Build Coastguard Worker exit() 186*387f9dfdSAndroid Build Coastguard Worker 187*387f9dfdSAndroid Build Coastguard Worker################ get number of queues ##################### 188*387f9dfdSAndroid Build Coastguard Workertx_num = 0 189*387f9dfdSAndroid Build Coastguard Workerrx_num = 0 190*387f9dfdSAndroid Build Coastguard Workerpath = ROOT_PATH + "/" + dev_name + "/queues" 191*387f9dfdSAndroid Build Coastguard Workerif not os.path.exists(path): 192*387f9dfdSAndroid Build Coastguard Worker print ("Net interface", dev_name, "does not exits.") 193*387f9dfdSAndroid Build Coastguard Worker exit() 194*387f9dfdSAndroid Build Coastguard Worker 195*387f9dfdSAndroid Build Coastguard Workerlist = os.listdir(path) 196*387f9dfdSAndroid Build Coastguard Workerfor s in list: 197*387f9dfdSAndroid Build Coastguard Worker if s[0] == 'r': 198*387f9dfdSAndroid Build Coastguard Worker rx_num += 1 199*387f9dfdSAndroid Build Coastguard Worker if s[0] == 't': 200*387f9dfdSAndroid Build Coastguard Worker tx_num += 1 201*387f9dfdSAndroid Build Coastguard Worker 202*387f9dfdSAndroid Build Coastguard Workerif tx_num > MAX_QUEUE_NUM or rx_num > MAX_QUEUE_NUM: 203*387f9dfdSAndroid Build Coastguard Worker print ("number of queues over 1024 is not supported.") 204*387f9dfdSAndroid Build Coastguard Worker exit() 205*387f9dfdSAndroid Build Coastguard Worker 206*387f9dfdSAndroid Build Coastguard Worker################## start tracing ################## 207*387f9dfdSAndroid Build Coastguard Workerb = BPF(src_file = EBPF_FILE) 208*387f9dfdSAndroid Build Coastguard Worker# --------- set hash array -------- 209*387f9dfdSAndroid Build Coastguard Workerdevname_map = b['name_map'] 210*387f9dfdSAndroid Build Coastguard Worker_name = Devname() 211*387f9dfdSAndroid Build Coastguard Worker_name.name = dev_name.encode() 212*387f9dfdSAndroid Build Coastguard Workerdevname_map[0] = _name 213*387f9dfdSAndroid Build Coastguard Worker 214*387f9dfdSAndroid Build Coastguard Workerwhile 1: 215*387f9dfdSAndroid Build Coastguard Worker try: 216*387f9dfdSAndroid Build Coastguard Worker sleep(print_interval) 217*387f9dfdSAndroid Build Coastguard Worker print_result(b) 218*387f9dfdSAndroid Build Coastguard Worker except KeyboardInterrupt: 219*387f9dfdSAndroid Build Coastguard Worker exit() 220