diff --git a/pyroute2/netlink/rtnl/tcmsg/sched_htb.py b/pyroute2/netlink/rtnl/tcmsg/sched_htb.py index 373831f7d..d522b5acf 100644 --- a/pyroute2/netlink/rtnl/tcmsg/sched_htb.py +++ b/pyroute2/netlink/rtnl/tcmsg/sched_htb.py @@ -81,6 +81,8 @@ def get_class_parameters(kwarg): quantum = kwarg.get('quantum', 0) rate = get_rate(kwarg.get('rate', None)) ceil = get_rate(kwarg.get('ceil', 0)) or rate + rate64 = 0 + ceil64 = 0 burst = ( kwarg.get('burst', None) @@ -104,7 +106,13 @@ def get_class_parameters(kwarg): cburst = ceil / get_hz() + mtu cburst = calc_xmittime(ceil, cburst) - return { + if rate >= 1 << 32: + rate64 = rate + rate = (1 << 32) - 1 + if ceil >= 1 << 32: + ceil64 = ceil + ceil = (1 << 32) - 1 + ret = { 'attrs': [ [ 'TCA_HTB_PARMS', @@ -125,6 +133,11 @@ def get_class_parameters(kwarg): ['TCA_HTB_CTAB', True], ] } + if rate64 > 0: + ret['attrs'].append(['TCA_HTB_RATE64', rate64]) + if ceil64 > 0: + ret['attrs'].append(['TCA_HTB_CEIL64', ceil64]) + return ret def get_parameters(kwarg): @@ -195,6 +208,11 @@ class options(nla_plus_rtab): ('TCA_HTB_INIT', 'htb_glob'), ('TCA_HTB_CTAB', 'ctab'), ('TCA_HTB_RTAB', 'rtab'), + ('TCA_HTB_DIRECT_QLEN', 'uint32'), + ('TCA_HTB_RATE64', 'uint64'), + ('TCA_HTB_CEIL64', 'uint64'), + ('TCA_HTB_PAD', 'hex'), + ('TCA_HTB_OFFLOAD', 'hex'), ) class htb_glob(nla): diff --git a/tests/test_linux/test_tc/test_htb.py b/tests/test_linux/test_tc/test_htb.py index 13764334f..fc1e4b49a 100644 --- a/tests/test_linux/test_tc/test_htb.py +++ b/tests/test_linux/test_tc/test_htb.py @@ -9,6 +9,68 @@ test_matrix = make_test_matrix(targets=['local', 'netns']) +@pytest.mark.parametrize('context', test_matrix, indirect=True) +@skip_if_not_supported +def test_htb_over_32gbit(context): + + index, ifname = context.default_interface + + # 8<----------------------------------------------------- + # root queue, '1:0' handle notation + context.ipr.tc('add', 'htb', index=index, handle='1:', default='20:0') + + assert qdisc_exists(context.netns, 'htb', ifname=ifname) + + # 8<----------------------------------------------------- + # classes, both string and int handle notation + context.ipr.tc( + 'add-class', + 'htb', + index=index, + handle=0x10001, + parent=0x10000, + rate='50gbit', + ceil='50gbit', + ) + context.ipr.tc( + 'add-class', + 'htb', + index=index, + handle=0x10010, + parent=0x10001, + rate='35gbit', + ceil='35gbit', + prio=1, + ) + context.ipr.tc( + 'add-class', + 'htb', + index=index, + handle=0x10020, + parent=0x10001, + rate='128kbit', + ceil='128kbit', + prio=2, + ) + + # 8<----------------------------------------------------- + # list the installed classes + classes = context.ipr.get_classes(index=index) + assert len(classes) == 3 + rate0 = classes[0].get(('TCA_OPTIONS', 'TCA_HTB_RATE64'), 0) + ceil0 = classes[0].get(('TCA_OPTIONS', 'TCA_HTB_CEIL64'), 0) + rate1 = classes[1].get(('TCA_OPTIONS', 'TCA_HTB_RATE64'), 0) + ceil1 = classes[1].get(('TCA_OPTIONS', 'TCA_HTB_CEIL64'), 0) + rate2 = classes[2].get(('TCA_OPTIONS', 'TCA_HTB_RATE64'), 0) + ceil2 = classes[2].get(('TCA_OPTIONS', 'TCA_HTB_CEIL64'), 0) + assert rate0 == ceil0 + assert rate1 == ceil1 + assert rate2 == ceil2 + assert rate0 > rate2 + assert rate1 > rate2 + assert rate2 == 0 + + @pytest.mark.parametrize('context', test_matrix, indirect=True) @skip_if_not_supported def test_htb(context):