1*4dc78e53SAndroid Build Coastguard Worker# 2*4dc78e53SAndroid Build Coastguard Worker# Copyright (c) 2011 Thomas Graf <[email protected]> 3*4dc78e53SAndroid Build Coastguard Worker# 4*4dc78e53SAndroid Build Coastguard Workerfrom __future__ import absolute_import 5*4dc78e53SAndroid Build Coastguard Worker 6*4dc78e53SAndroid Build Coastguard Worker__all__ = [ 7*4dc78e53SAndroid Build Coastguard Worker "TcCache", 8*4dc78e53SAndroid Build Coastguard Worker "Tc", 9*4dc78e53SAndroid Build Coastguard Worker "QdiscCache", 10*4dc78e53SAndroid Build Coastguard Worker "Qdisc", 11*4dc78e53SAndroid Build Coastguard Worker "TcClassCache", 12*4dc78e53SAndroid Build Coastguard Worker "TcClass", 13*4dc78e53SAndroid Build Coastguard Worker] 14*4dc78e53SAndroid Build Coastguard Worker 15*4dc78e53SAndroid Build Coastguard Workerfrom .. import core as netlink 16*4dc78e53SAndroid Build Coastguard Workerfrom . import capi as capi 17*4dc78e53SAndroid Build Coastguard Workerfrom .. import util as util 18*4dc78e53SAndroid Build Coastguard Workerfrom . import link as Link 19*4dc78e53SAndroid Build Coastguard Worker 20*4dc78e53SAndroid Build Coastguard WorkerTC_PACKETS = 0 21*4dc78e53SAndroid Build Coastguard WorkerTC_BYTES = 1 22*4dc78e53SAndroid Build Coastguard WorkerTC_RATE_BPS = 2 23*4dc78e53SAndroid Build Coastguard WorkerTC_RATE_PPS = 3 24*4dc78e53SAndroid Build Coastguard WorkerTC_QLEN = 4 25*4dc78e53SAndroid Build Coastguard WorkerTC_BACKLOG = 5 26*4dc78e53SAndroid Build Coastguard WorkerTC_DROPS = 6 27*4dc78e53SAndroid Build Coastguard WorkerTC_REQUEUES = 7 28*4dc78e53SAndroid Build Coastguard WorkerTC_OVERLIMITS = 9 29*4dc78e53SAndroid Build Coastguard Worker 30*4dc78e53SAndroid Build Coastguard WorkerTC_H_ROOT = 0xFFFFFFFF 31*4dc78e53SAndroid Build Coastguard WorkerTC_H_INGRESS = 0xFFFFFFF1 32*4dc78e53SAndroid Build Coastguard Worker 33*4dc78e53SAndroid Build Coastguard WorkerSTAT_PACKETS = 0 34*4dc78e53SAndroid Build Coastguard WorkerSTAT_BYTES = 1 35*4dc78e53SAndroid Build Coastguard WorkerSTAT_RATE_BPS = 2 36*4dc78e53SAndroid Build Coastguard WorkerSTAT_RATE_PPS = 3 37*4dc78e53SAndroid Build Coastguard WorkerSTAT_QLEN = 4 38*4dc78e53SAndroid Build Coastguard WorkerSTAT_BACKLOG = 5 39*4dc78e53SAndroid Build Coastguard WorkerSTAT_DROPS = 6 40*4dc78e53SAndroid Build Coastguard WorkerSTAT_REQUEUES = 7 41*4dc78e53SAndroid Build Coastguard WorkerSTAT_OVERLIMITS = 8 42*4dc78e53SAndroid Build Coastguard WorkerSTAT_MAX = STAT_OVERLIMITS 43*4dc78e53SAndroid Build Coastguard Worker 44*4dc78e53SAndroid Build Coastguard Worker 45*4dc78e53SAndroid Build Coastguard Workerclass Handle(object): 46*4dc78e53SAndroid Build Coastguard Worker """Traffic control handle 47*4dc78e53SAndroid Build Coastguard Worker 48*4dc78e53SAndroid Build Coastguard Worker Representation of a traffic control handle which uniquely identifies 49*4dc78e53SAndroid Build Coastguard Worker each traffic control object in its link namespace. 50*4dc78e53SAndroid Build Coastguard Worker 51*4dc78e53SAndroid Build Coastguard Worker handle = tc.Handle('10:20') 52*4dc78e53SAndroid Build Coastguard Worker handle = tc.handle('root') 53*4dc78e53SAndroid Build Coastguard Worker print int(handle) 54*4dc78e53SAndroid Build Coastguard Worker print str(handle) 55*4dc78e53SAndroid Build Coastguard Worker """ 56*4dc78e53SAndroid Build Coastguard Worker 57*4dc78e53SAndroid Build Coastguard Worker def __init__(self, val=None): 58*4dc78e53SAndroid Build Coastguard Worker if type(val) is str: 59*4dc78e53SAndroid Build Coastguard Worker val = capi.tc_str2handle(val) 60*4dc78e53SAndroid Build Coastguard Worker elif not val: 61*4dc78e53SAndroid Build Coastguard Worker val = 0 62*4dc78e53SAndroid Build Coastguard Worker 63*4dc78e53SAndroid Build Coastguard Worker self._val = int(val) 64*4dc78e53SAndroid Build Coastguard Worker 65*4dc78e53SAndroid Build Coastguard Worker def __cmp__(self, other): 66*4dc78e53SAndroid Build Coastguard Worker if other is None: 67*4dc78e53SAndroid Build Coastguard Worker other = 0 68*4dc78e53SAndroid Build Coastguard Worker 69*4dc78e53SAndroid Build Coastguard Worker if isinstance(other, Handle): 70*4dc78e53SAndroid Build Coastguard Worker return int(self) - int(other) 71*4dc78e53SAndroid Build Coastguard Worker elif isinstance(other, int): 72*4dc78e53SAndroid Build Coastguard Worker return int(self) - other 73*4dc78e53SAndroid Build Coastguard Worker else: 74*4dc78e53SAndroid Build Coastguard Worker raise TypeError() 75*4dc78e53SAndroid Build Coastguard Worker 76*4dc78e53SAndroid Build Coastguard Worker def __int__(self): 77*4dc78e53SAndroid Build Coastguard Worker return self._val 78*4dc78e53SAndroid Build Coastguard Worker 79*4dc78e53SAndroid Build Coastguard Worker def __str__(self): 80*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_tc_handle2str(self._val, 64)[0] 81*4dc78e53SAndroid Build Coastguard Worker 82*4dc78e53SAndroid Build Coastguard Worker def isroot(self): 83*4dc78e53SAndroid Build Coastguard Worker return self._val == TC_H_ROOT or self._val == TC_H_INGRESS 84*4dc78e53SAndroid Build Coastguard Worker 85*4dc78e53SAndroid Build Coastguard Worker 86*4dc78e53SAndroid Build Coastguard Workerclass TcCache(netlink.Cache): 87*4dc78e53SAndroid Build Coastguard Worker """Cache of traffic control object""" 88*4dc78e53SAndroid Build Coastguard Worker 89*4dc78e53SAndroid Build Coastguard Worker def __getitem__(self, key): 90*4dc78e53SAndroid Build Coastguard Worker raise NotImplementedError() 91*4dc78e53SAndroid Build Coastguard Worker 92*4dc78e53SAndroid Build Coastguard Worker 93*4dc78e53SAndroid Build Coastguard Workerclass Tc(netlink.Object): 94*4dc78e53SAndroid Build Coastguard Worker def __cmp__(self, other): 95*4dc78e53SAndroid Build Coastguard Worker diff = self.ifindex - other.ifindex 96*4dc78e53SAndroid Build Coastguard Worker if diff == 0: 97*4dc78e53SAndroid Build Coastguard Worker diff = int(self.handle) - int(other.handle) 98*4dc78e53SAndroid Build Coastguard Worker return diff 99*4dc78e53SAndroid Build Coastguard Worker 100*4dc78e53SAndroid Build Coastguard Worker def _tc_module_lookup(self): 101*4dc78e53SAndroid Build Coastguard Worker self._module_lookup(self._module_path + self.kind, "init_" + self._name) 102*4dc78e53SAndroid Build Coastguard Worker 103*4dc78e53SAndroid Build Coastguard Worker @property 104*4dc78e53SAndroid Build Coastguard Worker def root(self): 105*4dc78e53SAndroid Build Coastguard Worker """True if tc object is a root object""" 106*4dc78e53SAndroid Build Coastguard Worker return self.parent.isroot() 107*4dc78e53SAndroid Build Coastguard Worker 108*4dc78e53SAndroid Build Coastguard Worker @property 109*4dc78e53SAndroid Build Coastguard Worker def ifindex(self): 110*4dc78e53SAndroid Build Coastguard Worker """interface index""" 111*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_tc_get_ifindex(self._rtnl_tc) 112*4dc78e53SAndroid Build Coastguard Worker 113*4dc78e53SAndroid Build Coastguard Worker @ifindex.setter 114*4dc78e53SAndroid Build Coastguard Worker def ifindex(self, value): 115*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_tc_set_ifindex(self._rtnl_tc, int(value)) 116*4dc78e53SAndroid Build Coastguard Worker 117*4dc78e53SAndroid Build Coastguard Worker @property 118*4dc78e53SAndroid Build Coastguard Worker def link(self): 119*4dc78e53SAndroid Build Coastguard Worker link = capi.rtnl_tc_get_link(self._rtnl_tc) 120*4dc78e53SAndroid Build Coastguard Worker if not link: 121*4dc78e53SAndroid Build Coastguard Worker return None 122*4dc78e53SAndroid Build Coastguard Worker 123*4dc78e53SAndroid Build Coastguard Worker return Link.Link.from_capi(link) 124*4dc78e53SAndroid Build Coastguard Worker 125*4dc78e53SAndroid Build Coastguard Worker @link.setter 126*4dc78e53SAndroid Build Coastguard Worker def link(self, value): 127*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_tc_set_link(self._rtnl_tc, value._link) 128*4dc78e53SAndroid Build Coastguard Worker 129*4dc78e53SAndroid Build Coastguard Worker @property 130*4dc78e53SAndroid Build Coastguard Worker def mtu(self): 131*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_tc_get_mtu(self._rtnl_tc) 132*4dc78e53SAndroid Build Coastguard Worker 133*4dc78e53SAndroid Build Coastguard Worker @mtu.setter 134*4dc78e53SAndroid Build Coastguard Worker def mtu(self, value): 135*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_tc_set_mtu(self._rtnl_tc, int(value)) 136*4dc78e53SAndroid Build Coastguard Worker 137*4dc78e53SAndroid Build Coastguard Worker @property 138*4dc78e53SAndroid Build Coastguard Worker def mpu(self): 139*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_tc_get_mpu(self._rtnl_tc) 140*4dc78e53SAndroid Build Coastguard Worker 141*4dc78e53SAndroid Build Coastguard Worker @mpu.setter 142*4dc78e53SAndroid Build Coastguard Worker def mpu(self, value): 143*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_tc_set_mpu(self._rtnl_tc, int(value)) 144*4dc78e53SAndroid Build Coastguard Worker 145*4dc78e53SAndroid Build Coastguard Worker @property 146*4dc78e53SAndroid Build Coastguard Worker def overhead(self): 147*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_tc_get_overhead(self._rtnl_tc) 148*4dc78e53SAndroid Build Coastguard Worker 149*4dc78e53SAndroid Build Coastguard Worker @overhead.setter 150*4dc78e53SAndroid Build Coastguard Worker def overhead(self, value): 151*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_tc_set_overhead(self._rtnl_tc, int(value)) 152*4dc78e53SAndroid Build Coastguard Worker 153*4dc78e53SAndroid Build Coastguard Worker @property 154*4dc78e53SAndroid Build Coastguard Worker def linktype(self): 155*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_tc_get_linktype(self._rtnl_tc) 156*4dc78e53SAndroid Build Coastguard Worker 157*4dc78e53SAndroid Build Coastguard Worker @linktype.setter 158*4dc78e53SAndroid Build Coastguard Worker def linktype(self, value): 159*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_tc_set_linktype(self._rtnl_tc, int(value)) 160*4dc78e53SAndroid Build Coastguard Worker 161*4dc78e53SAndroid Build Coastguard Worker @property 162*4dc78e53SAndroid Build Coastguard Worker @netlink.nlattr(fmt=util.handle) 163*4dc78e53SAndroid Build Coastguard Worker def handle(self): 164*4dc78e53SAndroid Build Coastguard Worker return Handle(capi.rtnl_tc_get_handle(self._rtnl_tc)) 165*4dc78e53SAndroid Build Coastguard Worker 166*4dc78e53SAndroid Build Coastguard Worker @handle.setter 167*4dc78e53SAndroid Build Coastguard Worker def handle(self, value): 168*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_tc_set_handle(self._rtnl_tc, int(value)) 169*4dc78e53SAndroid Build Coastguard Worker 170*4dc78e53SAndroid Build Coastguard Worker @property 171*4dc78e53SAndroid Build Coastguard Worker @netlink.nlattr(fmt=util.handle) 172*4dc78e53SAndroid Build Coastguard Worker def parent(self): 173*4dc78e53SAndroid Build Coastguard Worker return Handle(capi.rtnl_tc_get_parent(self._rtnl_tc)) 174*4dc78e53SAndroid Build Coastguard Worker 175*4dc78e53SAndroid Build Coastguard Worker @parent.setter 176*4dc78e53SAndroid Build Coastguard Worker def parent(self, value): 177*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_tc_set_parent(self._rtnl_tc, int(value)) 178*4dc78e53SAndroid Build Coastguard Worker 179*4dc78e53SAndroid Build Coastguard Worker @property 180*4dc78e53SAndroid Build Coastguard Worker @netlink.nlattr(fmt=util.bold) 181*4dc78e53SAndroid Build Coastguard Worker def kind(self): 182*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_tc_get_kind(self._rtnl_tc) 183*4dc78e53SAndroid Build Coastguard Worker 184*4dc78e53SAndroid Build Coastguard Worker @kind.setter 185*4dc78e53SAndroid Build Coastguard Worker def kind(self, value): 186*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_tc_set_kind(self._rtnl_tc, value) 187*4dc78e53SAndroid Build Coastguard Worker self._tc_module_lookup() 188*4dc78e53SAndroid Build Coastguard Worker 189*4dc78e53SAndroid Build Coastguard Worker def get_stat(self, id): 190*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_tc_get_stat(self._rtnl_tc, id) 191*4dc78e53SAndroid Build Coastguard Worker 192*4dc78e53SAndroid Build Coastguard Worker @property 193*4dc78e53SAndroid Build Coastguard Worker def _dev(self): 194*4dc78e53SAndroid Build Coastguard Worker buf = util.kw("dev") + " " 195*4dc78e53SAndroid Build Coastguard Worker 196*4dc78e53SAndroid Build Coastguard Worker if self.link: 197*4dc78e53SAndroid Build Coastguard Worker return buf + util.string(self.link.name) 198*4dc78e53SAndroid Build Coastguard Worker else: 199*4dc78e53SAndroid Build Coastguard Worker return buf + util.num(self.ifindex) 200*4dc78e53SAndroid Build Coastguard Worker 201*4dc78e53SAndroid Build Coastguard Worker def brief(self, title, nodev=False, noparent=False): 202*4dc78e53SAndroid Build Coastguard Worker ret = title + " {a|kind} {a|handle}" 203*4dc78e53SAndroid Build Coastguard Worker 204*4dc78e53SAndroid Build Coastguard Worker if not nodev: 205*4dc78e53SAndroid Build Coastguard Worker ret += " {a|_dev}" 206*4dc78e53SAndroid Build Coastguard Worker 207*4dc78e53SAndroid Build Coastguard Worker if not noparent: 208*4dc78e53SAndroid Build Coastguard Worker ret += " {t|parent}" 209*4dc78e53SAndroid Build Coastguard Worker 210*4dc78e53SAndroid Build Coastguard Worker return ret + self._module_brief() 211*4dc78e53SAndroid Build Coastguard Worker 212*4dc78e53SAndroid Build Coastguard Worker @staticmethod 213*4dc78e53SAndroid Build Coastguard Worker def details(): 214*4dc78e53SAndroid Build Coastguard Worker return "{t|mtu} {t|mpu} {t|overhead} {t|linktype}" 215*4dc78e53SAndroid Build Coastguard Worker 216*4dc78e53SAndroid Build Coastguard Worker @property 217*4dc78e53SAndroid Build Coastguard Worker def packets(self): 218*4dc78e53SAndroid Build Coastguard Worker return self.get_stat(STAT_PACKETS) 219*4dc78e53SAndroid Build Coastguard Worker 220*4dc78e53SAndroid Build Coastguard Worker @property 221*4dc78e53SAndroid Build Coastguard Worker def bytes(self): 222*4dc78e53SAndroid Build Coastguard Worker return self.get_stat(STAT_BYTES) 223*4dc78e53SAndroid Build Coastguard Worker 224*4dc78e53SAndroid Build Coastguard Worker @property 225*4dc78e53SAndroid Build Coastguard Worker def qlen(self): 226*4dc78e53SAndroid Build Coastguard Worker return self.get_stat(STAT_QLEN) 227*4dc78e53SAndroid Build Coastguard Worker 228*4dc78e53SAndroid Build Coastguard Worker @staticmethod 229*4dc78e53SAndroid Build Coastguard Worker def stats(fmt): 230*4dc78e53SAndroid Build Coastguard Worker return fmt.nl("{t|packets} {t|bytes} {t|qlen}") 231*4dc78e53SAndroid Build Coastguard Worker 232*4dc78e53SAndroid Build Coastguard Worker 233*4dc78e53SAndroid Build Coastguard Workerclass QdiscCache(netlink.Cache): 234*4dc78e53SAndroid Build Coastguard Worker """Cache of qdiscs""" 235*4dc78e53SAndroid Build Coastguard Worker 236*4dc78e53SAndroid Build Coastguard Worker def __init__(self, cache=None): 237*4dc78e53SAndroid Build Coastguard Worker if not cache: 238*4dc78e53SAndroid Build Coastguard Worker cache = self._alloc_cache_name("route/qdisc") 239*4dc78e53SAndroid Build Coastguard Worker 240*4dc78e53SAndroid Build Coastguard Worker self._protocol = netlink.NETLINK_ROUTE 241*4dc78e53SAndroid Build Coastguard Worker self._nl_cache = cache 242*4dc78e53SAndroid Build Coastguard Worker 243*4dc78e53SAndroid Build Coastguard Worker # def __getitem__(self, key): 244*4dc78e53SAndroid Build Coastguard Worker # if type(key) is int: 245*4dc78e53SAndroid Build Coastguard Worker # link = capi.rtnl_link_get(self._this, key) 246*4dc78e53SAndroid Build Coastguard Worker # elif type(key) is str: 247*4dc78e53SAndroid Build Coastguard Worker # link = capi.rtnl_link_get_by_name(self._this, key) 248*4dc78e53SAndroid Build Coastguard Worker # 249*4dc78e53SAndroid Build Coastguard Worker # if qdisc is None: 250*4dc78e53SAndroid Build Coastguard Worker # raise KeyError() 251*4dc78e53SAndroid Build Coastguard Worker # else: 252*4dc78e53SAndroid Build Coastguard Worker # return Qdisc._from_capi(capi.qdisc2obj(qdisc)) 253*4dc78e53SAndroid Build Coastguard Worker 254*4dc78e53SAndroid Build Coastguard Worker @staticmethod 255*4dc78e53SAndroid Build Coastguard Worker def _new_object(obj): 256*4dc78e53SAndroid Build Coastguard Worker return Qdisc(obj) 257*4dc78e53SAndroid Build Coastguard Worker 258*4dc78e53SAndroid Build Coastguard Worker @staticmethod 259*4dc78e53SAndroid Build Coastguard Worker def _new_cache(cache): 260*4dc78e53SAndroid Build Coastguard Worker return QdiscCache(cache=cache) 261*4dc78e53SAndroid Build Coastguard Worker 262*4dc78e53SAndroid Build Coastguard Worker 263*4dc78e53SAndroid Build Coastguard Workerclass Qdisc(Tc): 264*4dc78e53SAndroid Build Coastguard Worker """Queueing discipline""" 265*4dc78e53SAndroid Build Coastguard Worker 266*4dc78e53SAndroid Build Coastguard Worker def __init__(self, obj=None): 267*4dc78e53SAndroid Build Coastguard Worker netlink.Object.__init__(self, "route/qdisc", "qdisc", obj) 268*4dc78e53SAndroid Build Coastguard Worker self._module_path = "netlink.route.qdisc." 269*4dc78e53SAndroid Build Coastguard Worker self._rtnl_qdisc = self._obj2type(self._nl_object) 270*4dc78e53SAndroid Build Coastguard Worker self._rtnl_tc = capi.obj2tc(self._nl_object) 271*4dc78e53SAndroid Build Coastguard Worker 272*4dc78e53SAndroid Build Coastguard Worker if self.kind: 273*4dc78e53SAndroid Build Coastguard Worker self._tc_module_lookup() 274*4dc78e53SAndroid Build Coastguard Worker 275*4dc78e53SAndroid Build Coastguard Worker @classmethod 276*4dc78e53SAndroid Build Coastguard Worker def from_capi(cls, obj): 277*4dc78e53SAndroid Build Coastguard Worker return cls(capi.qdisc2obj(obj)) 278*4dc78e53SAndroid Build Coastguard Worker 279*4dc78e53SAndroid Build Coastguard Worker @staticmethod 280*4dc78e53SAndroid Build Coastguard Worker def _obj2type(obj): 281*4dc78e53SAndroid Build Coastguard Worker return capi.obj2qdisc(obj) 282*4dc78e53SAndroid Build Coastguard Worker 283*4dc78e53SAndroid Build Coastguard Worker @staticmethod 284*4dc78e53SAndroid Build Coastguard Worker def _new_instance(obj): 285*4dc78e53SAndroid Build Coastguard Worker if not obj: 286*4dc78e53SAndroid Build Coastguard Worker raise ValueError() 287*4dc78e53SAndroid Build Coastguard Worker 288*4dc78e53SAndroid Build Coastguard Worker return Qdisc(obj) 289*4dc78e53SAndroid Build Coastguard Worker 290*4dc78e53SAndroid Build Coastguard Worker @property 291*4dc78e53SAndroid Build Coastguard Worker def childs(self): 292*4dc78e53SAndroid Build Coastguard Worker ret = [] 293*4dc78e53SAndroid Build Coastguard Worker 294*4dc78e53SAndroid Build Coastguard Worker if int(self.handle): 295*4dc78e53SAndroid Build Coastguard Worker ret += get_cls(self.ifindex, parent=self.handle) 296*4dc78e53SAndroid Build Coastguard Worker 297*4dc78e53SAndroid Build Coastguard Worker if self.root: 298*4dc78e53SAndroid Build Coastguard Worker ret += get_class(self.ifindex, parent=TC_H_ROOT) 299*4dc78e53SAndroid Build Coastguard Worker 300*4dc78e53SAndroid Build Coastguard Worker ret += get_class(self.ifindex, parent=self.handle) 301*4dc78e53SAndroid Build Coastguard Worker 302*4dc78e53SAndroid Build Coastguard Worker return ret 303*4dc78e53SAndroid Build Coastguard Worker 304*4dc78e53SAndroid Build Coastguard Worker # def add(self, socket, flags=None): 305*4dc78e53SAndroid Build Coastguard Worker # if not flags: 306*4dc78e53SAndroid Build Coastguard Worker # flags = netlink.NLM_F_CREATE 307*4dc78e53SAndroid Build Coastguard Worker # 308*4dc78e53SAndroid Build Coastguard Worker # ret = capi.rtnl_link_add(socket._sock, self._link, flags) 309*4dc78e53SAndroid Build Coastguard Worker # if ret < 0: 310*4dc78e53SAndroid Build Coastguard Worker # raise netlink.KernelError(ret) 311*4dc78e53SAndroid Build Coastguard Worker # 312*4dc78e53SAndroid Build Coastguard Worker # def change(self, socket, flags=0): 313*4dc78e53SAndroid Build Coastguard Worker # """Commit changes made to the link object""" 314*4dc78e53SAndroid Build Coastguard Worker # if not self._orig: 315*4dc78e53SAndroid Build Coastguard Worker # raise NetlinkError('Original link not available') 316*4dc78e53SAndroid Build Coastguard Worker # ret = capi.rtnl_link_change(socket._sock, self._orig, self._link, flags) 317*4dc78e53SAndroid Build Coastguard Worker # if ret < 0: 318*4dc78e53SAndroid Build Coastguard Worker # raise netlink.KernelError(ret) 319*4dc78e53SAndroid Build Coastguard Worker # 320*4dc78e53SAndroid Build Coastguard Worker # def delete(self, socket): 321*4dc78e53SAndroid Build Coastguard Worker # """Attempt to delete this link in the kernel""" 322*4dc78e53SAndroid Build Coastguard Worker # ret = capi.rtnl_link_delete(socket._sock, self._link) 323*4dc78e53SAndroid Build Coastguard Worker # if ret < 0: 324*4dc78e53SAndroid Build Coastguard Worker # raise netlink.KernelError(ret) 325*4dc78e53SAndroid Build Coastguard Worker 326*4dc78e53SAndroid Build Coastguard Worker def format( 327*4dc78e53SAndroid Build Coastguard Worker self, details=False, stats=False, nodev=False, noparent=False, indent="" 328*4dc78e53SAndroid Build Coastguard Worker ): 329*4dc78e53SAndroid Build Coastguard Worker """Return qdisc as formatted text""" 330*4dc78e53SAndroid Build Coastguard Worker fmt = util.MyFormatter(self, indent) 331*4dc78e53SAndroid Build Coastguard Worker 332*4dc78e53SAndroid Build Coastguard Worker buf = fmt.format(self.brief("qdisc", nodev, noparent)) 333*4dc78e53SAndroid Build Coastguard Worker 334*4dc78e53SAndroid Build Coastguard Worker if details: 335*4dc78e53SAndroid Build Coastguard Worker buf += fmt.nl("\t" + self.details()) 336*4dc78e53SAndroid Build Coastguard Worker 337*4dc78e53SAndroid Build Coastguard Worker if stats: 338*4dc78e53SAndroid Build Coastguard Worker buf += self.stats(fmt) 339*4dc78e53SAndroid Build Coastguard Worker 340*4dc78e53SAndroid Build Coastguard Worker # if stats: 341*4dc78e53SAndroid Build Coastguard Worker # l = [['Packets', RX_PACKETS, TX_PACKETS], 342*4dc78e53SAndroid Build Coastguard Worker # ['Bytes', RX_BYTES, TX_BYTES], 343*4dc78e53SAndroid Build Coastguard Worker # ['Errors', RX_ERRORS, TX_ERRORS], 344*4dc78e53SAndroid Build Coastguard Worker # ['Dropped', RX_DROPPED, TX_DROPPED], 345*4dc78e53SAndroid Build Coastguard Worker # ['Compressed', RX_COMPRESSED, TX_COMPRESSED], 346*4dc78e53SAndroid Build Coastguard Worker # ['FIFO Errors', RX_FIFO_ERR, TX_FIFO_ERR], 347*4dc78e53SAndroid Build Coastguard Worker # ['Length Errors', RX_LEN_ERR, None], 348*4dc78e53SAndroid Build Coastguard Worker # ['Over Errors', RX_OVER_ERR, None], 349*4dc78e53SAndroid Build Coastguard Worker # ['CRC Errors', RX_CRC_ERR, None], 350*4dc78e53SAndroid Build Coastguard Worker # ['Frame Errors', RX_FRAME_ERR, None], 351*4dc78e53SAndroid Build Coastguard Worker # ['Missed Errors', RX_MISSED_ERR, None], 352*4dc78e53SAndroid Build Coastguard Worker # ['Abort Errors', None, TX_ABORT_ERR], 353*4dc78e53SAndroid Build Coastguard Worker # ['Carrier Errors', None, TX_CARRIER_ERR], 354*4dc78e53SAndroid Build Coastguard Worker # ['Heartbeat Errors', None, TX_HBEAT_ERR], 355*4dc78e53SAndroid Build Coastguard Worker # ['Window Errors', None, TX_WIN_ERR], 356*4dc78e53SAndroid Build Coastguard Worker # ['Collisions', None, COLLISIONS], 357*4dc78e53SAndroid Build Coastguard Worker # ['Multicast', None, MULTICAST], 358*4dc78e53SAndroid Build Coastguard Worker # ['', None, None], 359*4dc78e53SAndroid Build Coastguard Worker # ['Ipv6:', None, None], 360*4dc78e53SAndroid Build Coastguard Worker # ['Packets', IP6_INPKTS, IP6_OUTPKTS], 361*4dc78e53SAndroid Build Coastguard Worker # ['Bytes', IP6_INOCTETS, IP6_OUTOCTETS], 362*4dc78e53SAndroid Build Coastguard Worker # ['Discards', IP6_INDISCARDS, IP6_OUTDISCARDS], 363*4dc78e53SAndroid Build Coastguard Worker # ['Multicast Packets', IP6_INMCASTPKTS, IP6_OUTMCASTPKTS], 364*4dc78e53SAndroid Build Coastguard Worker # ['Multicast Bytes', IP6_INMCASTOCTETS, IP6_OUTMCASTOCTETS], 365*4dc78e53SAndroid Build Coastguard Worker # ['Broadcast Packets', IP6_INBCASTPKTS, IP6_OUTBCASTPKTS], 366*4dc78e53SAndroid Build Coastguard Worker # ['Broadcast Bytes', IP6_INBCASTOCTETS, IP6_OUTBCASTOCTETS], 367*4dc78e53SAndroid Build Coastguard Worker # ['Delivers', IP6_INDELIVERS, None], 368*4dc78e53SAndroid Build Coastguard Worker # ['Forwarded', None, IP6_OUTFORWDATAGRAMS], 369*4dc78e53SAndroid Build Coastguard Worker # ['No Routes', IP6_INNOROUTES, IP6_OUTNOROUTES], 370*4dc78e53SAndroid Build Coastguard Worker # ['Header Errors', IP6_INHDRERRORS, None], 371*4dc78e53SAndroid Build Coastguard Worker # ['Too Big Errors', IP6_INTOOBIGERRORS, None], 372*4dc78e53SAndroid Build Coastguard Worker # ['Address Errors', IP6_INADDRERRORS, None], 373*4dc78e53SAndroid Build Coastguard Worker # ['Unknown Protocol', IP6_INUNKNOWNPROTOS, None], 374*4dc78e53SAndroid Build Coastguard Worker # ['Truncated Packets', IP6_INTRUNCATEDPKTS, None], 375*4dc78e53SAndroid Build Coastguard Worker # ['Reasm Timeouts', IP6_REASMTIMEOUT, None], 376*4dc78e53SAndroid Build Coastguard Worker # ['Reasm Requests', IP6_REASMREQDS, None], 377*4dc78e53SAndroid Build Coastguard Worker # ['Reasm Failures', IP6_REASMFAILS, None], 378*4dc78e53SAndroid Build Coastguard Worker # ['Reasm OK', IP6_REASMOKS, None], 379*4dc78e53SAndroid Build Coastguard Worker # ['Frag Created', None, IP6_FRAGCREATES], 380*4dc78e53SAndroid Build Coastguard Worker # ['Frag Failures', None, IP6_FRAGFAILS], 381*4dc78e53SAndroid Build Coastguard Worker # ['Frag OK', None, IP6_FRAGOKS], 382*4dc78e53SAndroid Build Coastguard Worker # ['', None, None], 383*4dc78e53SAndroid Build Coastguard Worker # ['ICMPv6:', None, None], 384*4dc78e53SAndroid Build Coastguard Worker # ['Messages', ICMP6_INMSGS, ICMP6_OUTMSGS], 385*4dc78e53SAndroid Build Coastguard Worker # ['Errors', ICMP6_INERRORS, ICMP6_OUTERRORS]] 386*4dc78e53SAndroid Build Coastguard Worker # 387*4dc78e53SAndroid Build Coastguard Worker # buf += '\n\t%s%s%s%s\n' % (33 * ' ', util.title('RX'), 388*4dc78e53SAndroid Build Coastguard Worker # 15 * ' ', util.title('TX')) 389*4dc78e53SAndroid Build Coastguard Worker # 390*4dc78e53SAndroid Build Coastguard Worker # for row in l: 391*4dc78e53SAndroid Build Coastguard Worker # row[0] = util.kw(row[0]) 392*4dc78e53SAndroid Build Coastguard Worker # row[1] = self.get_stat(row[1]) if row[1] else '' 393*4dc78e53SAndroid Build Coastguard Worker # row[2] = self.get_stat(row[2]) if row[2] else '' 394*4dc78e53SAndroid Build Coastguard Worker # buf += '\t{0:27} {1:>16} {2:>16}\n'.format(*row) 395*4dc78e53SAndroid Build Coastguard Worker 396*4dc78e53SAndroid Build Coastguard Worker return buf 397*4dc78e53SAndroid Build Coastguard Worker 398*4dc78e53SAndroid Build Coastguard Worker 399*4dc78e53SAndroid Build Coastguard Workerclass TcClassCache(netlink.Cache): 400*4dc78e53SAndroid Build Coastguard Worker """Cache of traffic classes""" 401*4dc78e53SAndroid Build Coastguard Worker 402*4dc78e53SAndroid Build Coastguard Worker def __init__(self, ifindex, cache=None): 403*4dc78e53SAndroid Build Coastguard Worker if not cache: 404*4dc78e53SAndroid Build Coastguard Worker cache = self._alloc_cache_name("route/class") 405*4dc78e53SAndroid Build Coastguard Worker 406*4dc78e53SAndroid Build Coastguard Worker self._protocol = netlink.NETLINK_ROUTE 407*4dc78e53SAndroid Build Coastguard Worker self._nl_cache = cache 408*4dc78e53SAndroid Build Coastguard Worker self._set_arg1(ifindex) 409*4dc78e53SAndroid Build Coastguard Worker 410*4dc78e53SAndroid Build Coastguard Worker @staticmethod 411*4dc78e53SAndroid Build Coastguard Worker def _new_object(obj): 412*4dc78e53SAndroid Build Coastguard Worker return TcClass(obj) 413*4dc78e53SAndroid Build Coastguard Worker 414*4dc78e53SAndroid Build Coastguard Worker def _new_cache(self, cache): 415*4dc78e53SAndroid Build Coastguard Worker return TcClassCache(self.arg1, cache=cache) 416*4dc78e53SAndroid Build Coastguard Worker 417*4dc78e53SAndroid Build Coastguard Worker 418*4dc78e53SAndroid Build Coastguard Workerclass TcClass(Tc): 419*4dc78e53SAndroid Build Coastguard Worker """Traffic Class""" 420*4dc78e53SAndroid Build Coastguard Worker 421*4dc78e53SAndroid Build Coastguard Worker def __init__(self, obj=None): 422*4dc78e53SAndroid Build Coastguard Worker netlink.Object.__init__(self, "route/class", "class", obj) 423*4dc78e53SAndroid Build Coastguard Worker self._module_path = "netlink.route.qdisc." 424*4dc78e53SAndroid Build Coastguard Worker self._rtnl_class = self._obj2type(self._nl_object) 425*4dc78e53SAndroid Build Coastguard Worker self._rtnl_tc = capi.obj2tc(self._nl_object) 426*4dc78e53SAndroid Build Coastguard Worker 427*4dc78e53SAndroid Build Coastguard Worker if self.kind: 428*4dc78e53SAndroid Build Coastguard Worker self._tc_module_lookup() 429*4dc78e53SAndroid Build Coastguard Worker 430*4dc78e53SAndroid Build Coastguard Worker @classmethod 431*4dc78e53SAndroid Build Coastguard Worker def from_capi(cls, obj): 432*4dc78e53SAndroid Build Coastguard Worker return cls(capi.class2obj(obj)) 433*4dc78e53SAndroid Build Coastguard Worker 434*4dc78e53SAndroid Build Coastguard Worker @staticmethod 435*4dc78e53SAndroid Build Coastguard Worker def _obj2type(obj): 436*4dc78e53SAndroid Build Coastguard Worker return capi.obj2class(obj) 437*4dc78e53SAndroid Build Coastguard Worker 438*4dc78e53SAndroid Build Coastguard Worker @staticmethod 439*4dc78e53SAndroid Build Coastguard Worker def _new_instance(obj): 440*4dc78e53SAndroid Build Coastguard Worker if not obj: 441*4dc78e53SAndroid Build Coastguard Worker raise ValueError() 442*4dc78e53SAndroid Build Coastguard Worker 443*4dc78e53SAndroid Build Coastguard Worker return TcClass(obj) 444*4dc78e53SAndroid Build Coastguard Worker 445*4dc78e53SAndroid Build Coastguard Worker @property 446*4dc78e53SAndroid Build Coastguard Worker def childs(self): 447*4dc78e53SAndroid Build Coastguard Worker ret = [] 448*4dc78e53SAndroid Build Coastguard Worker 449*4dc78e53SAndroid Build Coastguard Worker # classes can have classifiers, child classes and leaf 450*4dc78e53SAndroid Build Coastguard Worker # qdiscs 451*4dc78e53SAndroid Build Coastguard Worker ret += get_cls(self.ifindex, parent=self.handle) 452*4dc78e53SAndroid Build Coastguard Worker ret += get_class(self.ifindex, parent=self.handle) 453*4dc78e53SAndroid Build Coastguard Worker ret += get_qdisc(self.ifindex, parent=self.handle) 454*4dc78e53SAndroid Build Coastguard Worker 455*4dc78e53SAndroid Build Coastguard Worker return ret 456*4dc78e53SAndroid Build Coastguard Worker 457*4dc78e53SAndroid Build Coastguard Worker def format( 458*4dc78e53SAndroid Build Coastguard Worker self, details=False, _stats=False, nodev=False, noparent=False, indent="" 459*4dc78e53SAndroid Build Coastguard Worker ): 460*4dc78e53SAndroid Build Coastguard Worker """Return class as formatted text""" 461*4dc78e53SAndroid Build Coastguard Worker fmt = util.MyFormatter(self, indent) 462*4dc78e53SAndroid Build Coastguard Worker 463*4dc78e53SAndroid Build Coastguard Worker buf = fmt.format(self.brief("class", nodev, noparent)) 464*4dc78e53SAndroid Build Coastguard Worker 465*4dc78e53SAndroid Build Coastguard Worker if details: 466*4dc78e53SAndroid Build Coastguard Worker buf += fmt.nl("\t" + self.details()) 467*4dc78e53SAndroid Build Coastguard Worker 468*4dc78e53SAndroid Build Coastguard Worker return buf 469*4dc78e53SAndroid Build Coastguard Worker 470*4dc78e53SAndroid Build Coastguard Worker 471*4dc78e53SAndroid Build Coastguard Workerclass ClassifierCache(netlink.Cache): 472*4dc78e53SAndroid Build Coastguard Worker """Cache of traffic classifiers objects""" 473*4dc78e53SAndroid Build Coastguard Worker 474*4dc78e53SAndroid Build Coastguard Worker def __init__(self, ifindex, parent, cache=None): 475*4dc78e53SAndroid Build Coastguard Worker if not cache: 476*4dc78e53SAndroid Build Coastguard Worker cache = self._alloc_cache_name("route/cls") 477*4dc78e53SAndroid Build Coastguard Worker 478*4dc78e53SAndroid Build Coastguard Worker self._protocol = netlink.NETLINK_ROUTE 479*4dc78e53SAndroid Build Coastguard Worker self._nl_cache = cache 480*4dc78e53SAndroid Build Coastguard Worker self._set_arg1(ifindex) 481*4dc78e53SAndroid Build Coastguard Worker self._set_arg2(int(parent)) 482*4dc78e53SAndroid Build Coastguard Worker 483*4dc78e53SAndroid Build Coastguard Worker @staticmethod 484*4dc78e53SAndroid Build Coastguard Worker def _new_object(obj): 485*4dc78e53SAndroid Build Coastguard Worker return Classifier(obj) 486*4dc78e53SAndroid Build Coastguard Worker 487*4dc78e53SAndroid Build Coastguard Worker def _new_cache(self, cache): 488*4dc78e53SAndroid Build Coastguard Worker return ClassifierCache(self.arg1, self.arg2, cache=cache) 489*4dc78e53SAndroid Build Coastguard Worker 490*4dc78e53SAndroid Build Coastguard Worker 491*4dc78e53SAndroid Build Coastguard Workerclass Classifier(Tc): 492*4dc78e53SAndroid Build Coastguard Worker """Classifier""" 493*4dc78e53SAndroid Build Coastguard Worker 494*4dc78e53SAndroid Build Coastguard Worker def __init__(self, obj=None): 495*4dc78e53SAndroid Build Coastguard Worker netlink.Object.__init__(self, "route/cls", "cls", obj) 496*4dc78e53SAndroid Build Coastguard Worker self._module_path = "netlink.route.cls." 497*4dc78e53SAndroid Build Coastguard Worker self._rtnl_cls = self._obj2type(self._nl_object) 498*4dc78e53SAndroid Build Coastguard Worker self._rtnl_tc = capi.obj2tc(self._nl_object) 499*4dc78e53SAndroid Build Coastguard Worker 500*4dc78e53SAndroid Build Coastguard Worker @classmethod 501*4dc78e53SAndroid Build Coastguard Worker def from_capi(cls, obj): 502*4dc78e53SAndroid Build Coastguard Worker return cls(capi.cls2obj(obj)) 503*4dc78e53SAndroid Build Coastguard Worker 504*4dc78e53SAndroid Build Coastguard Worker @staticmethod 505*4dc78e53SAndroid Build Coastguard Worker def _obj2type(obj): 506*4dc78e53SAndroid Build Coastguard Worker return capi.obj2cls(obj) 507*4dc78e53SAndroid Build Coastguard Worker 508*4dc78e53SAndroid Build Coastguard Worker @staticmethod 509*4dc78e53SAndroid Build Coastguard Worker def _new_instance(obj): 510*4dc78e53SAndroid Build Coastguard Worker if not obj: 511*4dc78e53SAndroid Build Coastguard Worker raise ValueError() 512*4dc78e53SAndroid Build Coastguard Worker 513*4dc78e53SAndroid Build Coastguard Worker return Classifier(obj) 514*4dc78e53SAndroid Build Coastguard Worker 515*4dc78e53SAndroid Build Coastguard Worker @property 516*4dc78e53SAndroid Build Coastguard Worker def priority(self): 517*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_cls_get_prio(self._rtnl_cls) 518*4dc78e53SAndroid Build Coastguard Worker 519*4dc78e53SAndroid Build Coastguard Worker @priority.setter 520*4dc78e53SAndroid Build Coastguard Worker def priority(self, value): 521*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_cls_set_prio(self._rtnl_cls, int(value)) 522*4dc78e53SAndroid Build Coastguard Worker 523*4dc78e53SAndroid Build Coastguard Worker @property 524*4dc78e53SAndroid Build Coastguard Worker def protocol(self): 525*4dc78e53SAndroid Build Coastguard Worker return capi.rtnl_cls_get_protocol(self._rtnl_cls) 526*4dc78e53SAndroid Build Coastguard Worker 527*4dc78e53SAndroid Build Coastguard Worker @protocol.setter 528*4dc78e53SAndroid Build Coastguard Worker def protocol(self, value): 529*4dc78e53SAndroid Build Coastguard Worker capi.rtnl_cls_set_protocol(self._rtnl_cls, int(value)) 530*4dc78e53SAndroid Build Coastguard Worker 531*4dc78e53SAndroid Build Coastguard Worker @property 532*4dc78e53SAndroid Build Coastguard Worker def childs(self): 533*4dc78e53SAndroid Build Coastguard Worker return [] 534*4dc78e53SAndroid Build Coastguard Worker 535*4dc78e53SAndroid Build Coastguard Worker def format( 536*4dc78e53SAndroid Build Coastguard Worker self, details=False, _stats=False, nodev=False, noparent=False, indent="" 537*4dc78e53SAndroid Build Coastguard Worker ): 538*4dc78e53SAndroid Build Coastguard Worker """Return class as formatted text""" 539*4dc78e53SAndroid Build Coastguard Worker fmt = util.MyFormatter(self, indent) 540*4dc78e53SAndroid Build Coastguard Worker 541*4dc78e53SAndroid Build Coastguard Worker buf = fmt.format(self.brief("classifier", nodev, noparent)) 542*4dc78e53SAndroid Build Coastguard Worker buf += fmt.format(" {t|priority} {t|protocol}") 543*4dc78e53SAndroid Build Coastguard Worker 544*4dc78e53SAndroid Build Coastguard Worker if details: 545*4dc78e53SAndroid Build Coastguard Worker buf += fmt.nl("\t" + self.details()) 546*4dc78e53SAndroid Build Coastguard Worker 547*4dc78e53SAndroid Build Coastguard Worker return buf 548*4dc78e53SAndroid Build Coastguard Worker 549*4dc78e53SAndroid Build Coastguard Worker 550*4dc78e53SAndroid Build Coastguard Worker_qdisc_cache = QdiscCache() 551*4dc78e53SAndroid Build Coastguard Worker 552*4dc78e53SAndroid Build Coastguard Worker 553*4dc78e53SAndroid Build Coastguard Workerdef get_qdisc(ifindex, handle=None, parent=None): 554*4dc78e53SAndroid Build Coastguard Worker lst = [] 555*4dc78e53SAndroid Build Coastguard Worker 556*4dc78e53SAndroid Build Coastguard Worker _qdisc_cache.refill() 557*4dc78e53SAndroid Build Coastguard Worker 558*4dc78e53SAndroid Build Coastguard Worker for qdisc in _qdisc_cache: 559*4dc78e53SAndroid Build Coastguard Worker if qdisc.ifindex != ifindex: 560*4dc78e53SAndroid Build Coastguard Worker continue 561*4dc78e53SAndroid Build Coastguard Worker if (handle is not None) and (qdisc.handle != handle): 562*4dc78e53SAndroid Build Coastguard Worker continue 563*4dc78e53SAndroid Build Coastguard Worker if (parent is not None) and (qdisc.parent != parent): 564*4dc78e53SAndroid Build Coastguard Worker continue 565*4dc78e53SAndroid Build Coastguard Worker lst.append(qdisc) 566*4dc78e53SAndroid Build Coastguard Worker 567*4dc78e53SAndroid Build Coastguard Worker return lst 568*4dc78e53SAndroid Build Coastguard Worker 569*4dc78e53SAndroid Build Coastguard Worker 570*4dc78e53SAndroid Build Coastguard Worker_class_cache = {} 571*4dc78e53SAndroid Build Coastguard Worker 572*4dc78e53SAndroid Build Coastguard Worker 573*4dc78e53SAndroid Build Coastguard Workerdef get_class(ifindex, parent, handle=None): 574*4dc78e53SAndroid Build Coastguard Worker lst = [] 575*4dc78e53SAndroid Build Coastguard Worker 576*4dc78e53SAndroid Build Coastguard Worker try: 577*4dc78e53SAndroid Build Coastguard Worker cache = _class_cache[ifindex] 578*4dc78e53SAndroid Build Coastguard Worker except KeyError: 579*4dc78e53SAndroid Build Coastguard Worker cache = TcClassCache(ifindex) 580*4dc78e53SAndroid Build Coastguard Worker _class_cache[ifindex] = cache 581*4dc78e53SAndroid Build Coastguard Worker 582*4dc78e53SAndroid Build Coastguard Worker cache.refill() 583*4dc78e53SAndroid Build Coastguard Worker 584*4dc78e53SAndroid Build Coastguard Worker for cl in cache: 585*4dc78e53SAndroid Build Coastguard Worker if (parent is not None) and (cl.parent != parent): 586*4dc78e53SAndroid Build Coastguard Worker continue 587*4dc78e53SAndroid Build Coastguard Worker if (handle is not None) and (cl.handle != handle): 588*4dc78e53SAndroid Build Coastguard Worker continue 589*4dc78e53SAndroid Build Coastguard Worker lst.append(cl) 590*4dc78e53SAndroid Build Coastguard Worker 591*4dc78e53SAndroid Build Coastguard Worker return lst 592*4dc78e53SAndroid Build Coastguard Worker 593*4dc78e53SAndroid Build Coastguard Worker 594*4dc78e53SAndroid Build Coastguard Worker_cls_cache = {} 595*4dc78e53SAndroid Build Coastguard Worker 596*4dc78e53SAndroid Build Coastguard Worker 597*4dc78e53SAndroid Build Coastguard Workerdef get_cls(ifindex, parent, handle=None): 598*4dc78e53SAndroid Build Coastguard Worker 599*4dc78e53SAndroid Build Coastguard Worker chain = _cls_cache.get(ifindex, {}) 600*4dc78e53SAndroid Build Coastguard Worker 601*4dc78e53SAndroid Build Coastguard Worker try: 602*4dc78e53SAndroid Build Coastguard Worker cache = chain[parent] 603*4dc78e53SAndroid Build Coastguard Worker except KeyError: 604*4dc78e53SAndroid Build Coastguard Worker cache = ClassifierCache(ifindex, parent) 605*4dc78e53SAndroid Build Coastguard Worker chain[parent] = cache 606*4dc78e53SAndroid Build Coastguard Worker 607*4dc78e53SAndroid Build Coastguard Worker cache.refill() 608*4dc78e53SAndroid Build Coastguard Worker 609*4dc78e53SAndroid Build Coastguard Worker if handle is None: 610*4dc78e53SAndroid Build Coastguard Worker return list(cache) 611*4dc78e53SAndroid Build Coastguard Worker 612*4dc78e53SAndroid Build Coastguard Worker return [cls for cls in cache if cls.handle == handle] 613