xref: /aosp_15_r20/external/libnl/python/netlink/route/tc.py (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
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