def test_add_tc_filter_match32(self): priv_tc_lib.add_tc_qdisc(self.device, parent=rtnl.TC_H_ROOT, kind='htb', handle='1:', namespace=self.namespace) priv_tc_lib.add_tc_policy_class(self.device, '1:', '1:10', 'htb', namespace=self.namespace, rate=10000) keys = tc_lib._mac_to_pyroute2_keys('7a:8c:f9:1f:e5:cb', 41) priv_tc_lib.add_tc_filter_match32(self.device, '1:0', 10, '1:10', [keys[0]['key'], keys[1]['key']], namespace=self.namespace) filters = tc_lib.list_tc_filters(self.device, '1:0', namespace=self.namespace) self.assertEqual(1, len(filters)) filter_keys = filters[0]['keys'] self.assertEqual(len(keys), len(filter_keys)) for index, value in enumerate(keys): value.pop('key') self.assertEqual(value, filter_keys[index])
def add_tc_policy_class(device, parent, classid, min_kbps=1, max_kbps=None, burst_kb=None, namespace=None): """Add a TC policy class :param device: (string) device name :param parent: (string) qdisc parent class ('root', 'ingress', '2:10') :param classid: (string) major:minor handler identifier ('10:20') :param min_kbps: (int) (optional) minimum bandwidth in kbps :param max_kbps: (int) (optional) maximum bandwidth in kbps :param burst_kb: (int) (optional) burst size in kb :param namespace: (string) (optional) namespace name :return: """ parent = TC_QDISC_PARENT.get(parent, parent) # NOTE(ralonsoh): pyroute2 input parameters and units [1]: # - rate (min bw): bytes/second # - ceil (max bw): bytes/second # - burst: bytes # [1] https://www.systutorials.com/docs/linux/man/8-tc/ if int(min_kbps) < 1: raise TcLibPolicyClassInvalidMinKbpsValue() args = {'rate': int(min_kbps * 1024 / 8)} if max_kbps: args['ceil'] = int(max_kbps * 1024 / 8) if burst_kb: args['burst'] = int(burst_kb * 1024 / 8) priv_tc_lib.add_tc_policy_class(device, parent, classid, 'htb', namespace=namespace, **args)
def test_delete_tc_policy_class_htb(self): priv_tc_lib.add_tc_qdisc(self.device, parent=rtnl.TC_H_ROOT, kind='htb', handle='1:', namespace=self.namespace) for classid, rates in self.CLASSES.items(): priv_tc_lib.add_tc_policy_class(self.device, '1:', classid, 'htb', namespace=self.namespace, **rates) tc_classes = priv_tc_lib.list_tc_policy_classes( self.device, namespace=self.namespace) self.assertEqual(len(self.CLASSES), len(tc_classes)) for classid in self.CLASSES: priv_tc_lib.delete_tc_policy_class(self.device, '1:', classid, namespace=self.namespace) tc_classes = priv_tc_lib.list_tc_policy_classes( self.device, namespace=self.namespace) for tc_class in tc_classes: handle = tc_lib._handle_from_hex_to_string(tc_class['handle']) self.assertIsNot(classid, handle) tc_classes = priv_tc_lib.list_tc_policy_classes( self.device, namespace=self.namespace) self.assertEqual(0, len(tc_classes))
def test_add_tc_policy_class_htb(self): priv_tc_lib.add_tc_qdisc(self.device, parent=rtnl.TC_H_ROOT, kind='htb', handle='1:', namespace=self.namespace) for classid, rates in self.CLASSES.items(): priv_tc_lib.add_tc_policy_class(self.device, '1:', classid, 'htb', namespace=self.namespace, **rates) tc_classes = priv_tc_lib.list_tc_policy_classes( self.device, namespace=self.namespace) self.assertEqual(len(self.CLASSES), len(tc_classes)) for tc_class in tc_classes: handle = tc_lib._handle_from_hex_to_string(tc_class['handle']) tca_options = tc_lib._get_attr(tc_class, 'TCA_OPTIONS') tca_htb_params = tc_lib._get_attr(tca_options, 'TCA_HTB_PARMS') self.assertEqual(self.CLASSES[handle]['rate'], tca_htb_params['rate']) self.assertEqual(self.CLASSES[handle]['ceil'], tca_htb_params['ceil']) burst = tc_lib._calc_burst(self.CLASSES[handle]['rate'], tca_htb_params['buffer']) self.assertEqual(self.CLASSES[handle]['burst'], burst)
def test_delete_tc_policy_class_htb(self): priv_tc_lib.add_tc_qdisc( self.device, parent=rtnl.TC_H_ROOT, kind='htb', handle='1:', namespace=self.namespace) for classid, rates in self.CLASSES.items(): priv_tc_lib.add_tc_policy_class( self.device, '1:', classid, 'htb', namespace=self.namespace, **rates) tc_classes = priv_tc_lib.list_tc_policy_classes( self.device, namespace=self.namespace) self.assertEqual(len(self.CLASSES), len(tc_classes)) for classid in self.CLASSES: priv_tc_lib.delete_tc_policy_class( self.device, '1:', classid, namespace=self.namespace) tc_classes = priv_tc_lib.list_tc_policy_classes( self.device, namespace=self.namespace) for tc_class in tc_classes: handle = tc_lib._handle_from_hex_to_string(tc_class['handle']) self.assertIsNot(classid, handle) tc_classes = priv_tc_lib.list_tc_policy_classes( self.device, namespace=self.namespace) self.assertEqual(0, len(tc_classes))
def add_tc_policy_class(device, parent, classid, max_kbps, min_kbps=None, burst_kb=None, namespace=None): """Add a TC policy class :param device: (string) device name :param parent: (string) qdisc parent class ('root', 'ingress', '2:10') :param classid: (string) major:minor handler identifier ('10:20') :param max_kbps: (int) maximum bandwidth in kbps :param min_kbps: (int) (optional) minimum bandwidth in kbps :param burst_kb: (int) (optional) burst size in kb :param namespace: (string) (optional) namespace name :return: """ parent = TC_QDISC_PARENT.get(parent, parent) if not burst_kb: burst_kb = max_kbps * qos_consts.DEFAULT_BURST_RATE # NOTE(ralonsoh): pyroute2 input parameters and units [1]: # - rate (min bw): bytes/second # - ceil (max bw): bytes/second # - burst: bytes # [1] https://www.systutorials.com/docs/linux/man/8-tc/ kwargs = { 'ceil': int(max_kbps * 1000 / 8), 'burst': int(burst_kb * 1000 / 8) } rate = int((min_kbps or 0) * 1000 / 8) min_rate = _calc_min_rate(kwargs['burst']) if min_rate > rate: LOG.warning( 'TC HTB class policy rate %(rate)s (bytes/second) is ' 'lower than the minimum accepted %(min_rate)s ' '(bytes/second), for device %(device)s, qdisc ' '%(qdisc)s and classid %(classid)s', { 'rate': rate, 'min_rate': min_rate, 'device': device, 'qdisc': parent, 'classid': classid }) rate = min_rate kwargs['rate'] = rate priv_tc_lib.add_tc_policy_class(device, parent, classid, 'htb', namespace=namespace, **kwargs)
def test_add_tc_policy_class_htb(self): priv_tc_lib.add_tc_qdisc( self.device, parent=rtnl.TC_H_ROOT, kind='htb', handle='1:', namespace=self.namespace) for classid, rates in self.CLASSES.items(): priv_tc_lib.add_tc_policy_class( self.device, '1:', classid, 'htb', namespace=self.namespace, **rates) tc_classes = priv_tc_lib.list_tc_policy_classes( self.device, namespace=self.namespace) self.assertEqual(len(self.CLASSES), len(tc_classes)) for tc_class in tc_classes: handle = tc_lib._handle_from_hex_to_string(tc_class['handle']) tca_options = tc_lib._get_attr(tc_class, 'TCA_OPTIONS') tca_htb_params = tc_lib._get_attr(tca_options, 'TCA_HTB_PARMS') self.assertEqual(self.CLASSES[handle]['rate'], tca_htb_params['rate']) self.assertEqual(self.CLASSES[handle]['ceil'], tca_htb_params['ceil']) burst = tc_lib._calc_burst(self.CLASSES[handle]['rate'], tca_htb_params['buffer']) self.assertEqual(self.CLASSES[handle]['burst'], burst)