summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authord0u9 <d0u9.su@outlook.com>2018-10-31 05:13:13 (GMT)
committerThomas Haller <thaller@redhat.com>2019-09-01 12:44:42 (GMT)
commit4cf69a1b7b2518d18e1a62c79a461bca109132fc (patch)
treed9d746c7dfbe661c3759ed85882c01b3a5fbef04
parent2154891180bbae40af2f1abab5f6c4f7040de81a (diff)
downloadlibnl-4cf69a1b7b2518d18e1a62c79a461bca109132fc.zip
libnl-4cf69a1b7b2518d18e1a62c79a461bca109132fc.tar.gz
libnl-4cf69a1b7b2518d18e1a62c79a461bca109132fc.tar.bz2
Add 64bit rate/ceil support for htb class
Htb class has already supported 64bit rate and ceil settings for times. Now, in this patch, we grant this ability to libnl library.
-rw-r--r--doc/route.txt8
-rw-r--r--include/netlink-private/types.h2
-rw-r--r--include/netlink/route/qdisc/htb.h8
-rw-r--r--include/netlink/route/tc.h4
-rw-r--r--lib/route/qdisc/htb.c54
-rw-r--r--lib/route/tc.c4
-rw-r--r--python/netlink/route/capi.i8
7 files changed, 54 insertions, 34 deletions
diff --git a/doc/route.txt b/doc/route.txt
index 9d4c23a..c2a3b1b 100644
--- a/doc/route.txt
+++ b/doc/route.txt
@@ -1886,8 +1886,8 @@ or erqual than the rate of its children.
+
[source,c]
-----
-uint32_t rtnl_htb_get_rate(struct rtnl_class *class);
-int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t ceil);
+uint64_t rtnl_htb_get_rate(struct rtnl_class *class);
+int rtnl_htb_set_rate(struct rtnl_class *class, uint64_t ceil);
-----
Ceil Rate::
@@ -1899,8 +1899,8 @@ be greater or erqual than the ceil rate of its children.
+
[source,c]
-----
-uint32_t rtnl_htb_get_ceil(struct rtnl_class *class);
-int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil);
+uint64_t rtnl_htb_get_ceil(struct rtnl_class *class);
+int rtnl_htb_set_ceil(struct rtnl_class *class, uint64_t ceil);
-----
Burst::
diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h
index 209f099..f192379 100644
--- a/include/netlink-private/types.h
+++ b/include/netlink-private/types.h
@@ -776,6 +776,8 @@ struct rtnl_htb_class
uint32_t ch_quantum;
uint32_t ch_mask;
uint32_t ch_level;
+ uint64_t ch_rate64;
+ uint64_t ch_ceil64;
};
struct rtnl_cbq
diff --git a/include/netlink/route/qdisc/htb.h b/include/netlink/route/qdisc/htb.h
index c5065f4..72f7f75 100644
--- a/include/netlink/route/qdisc/htb.h
+++ b/include/netlink/route/qdisc/htb.h
@@ -30,10 +30,10 @@ extern int rtnl_htb_set_defcls(struct rtnl_qdisc *, uint32_t);
extern uint32_t rtnl_htb_get_prio(struct rtnl_class *);
extern int rtnl_htb_set_prio(struct rtnl_class *, uint32_t);
-extern uint32_t rtnl_htb_get_rate(struct rtnl_class *);
-extern int rtnl_htb_set_rate(struct rtnl_class *, uint32_t);
-extern uint32_t rtnl_htb_get_ceil(struct rtnl_class *);
-extern int rtnl_htb_set_ceil(struct rtnl_class *, uint32_t);
+extern uint64_t rtnl_htb_get_rate(struct rtnl_class *);
+extern int rtnl_htb_set_rate(struct rtnl_class *, uint64_t);
+extern uint64_t rtnl_htb_get_ceil(struct rtnl_class *);
+extern int rtnl_htb_set_ceil(struct rtnl_class *, uint64_t);
extern uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *);
extern int rtnl_htb_set_rbuffer(struct rtnl_class *, uint32_t);
extern uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *);
diff --git a/include/netlink/route/tc.h b/include/netlink/route/tc.h
index 51d670a..5cfa7a0 100644
--- a/include/netlink/route/tc.h
+++ b/include/netlink/route/tc.h
@@ -100,8 +100,8 @@ extern uint64_t rtnl_tc_get_stat(struct rtnl_tc *, enum rtnl_tc_stat);
extern char * rtnl_tc_stat2str(enum rtnl_tc_stat, char *, size_t);
extern int rtnl_tc_str2stat(const char *);
-extern int rtnl_tc_calc_txtime(int, int);
-extern int rtnl_tc_calc_bufsize(int, int);
+extern int rtnl_tc_calc_txtime(int, uint64_t);
+extern int rtnl_tc_calc_bufsize(int, uint64_t);
extern int rtnl_tc_calc_cell_log(int);
extern int rtnl_tc_read_classid_file(void);
diff --git a/lib/route/qdisc/htb.c b/lib/route/qdisc/htb.c
index c1e3230..eb500a3 100644
--- a/lib/route/qdisc/htb.c
+++ b/lib/route/qdisc/htb.c
@@ -45,6 +45,8 @@
static struct nla_policy htb_policy[TCA_HTB_MAX+1] = {
[TCA_HTB_INIT] = { .minlen = sizeof(struct tc_htb_glob) },
[TCA_HTB_PARMS] = { .minlen = sizeof(struct tc_htb_opt) },
+ [TCA_HTB_RATE64] = { .minlen = sizeof(uint64_t) },
+ [TCA_HTB_CEIL64] = { .minlen = sizeof(uint64_t) },
};
static int htb_qdisc_msg_parser(struct rtnl_tc *tc, void *data)
@@ -86,10 +88,20 @@ static int htb_class_msg_parser(struct rtnl_tc *tc, void *data)
htb->ch_prio = opts.prio;
rtnl_copy_ratespec(&htb->ch_rate, &opts.rate);
rtnl_copy_ratespec(&htb->ch_ceil, &opts.ceil);
+
+ if (tb[TCA_HTB_RATE64])
+ nla_memcpy(&htb->ch_rate64, tb[TCA_HTB_RATE64], sizeof(uint64_t));
+ else
+ htb->ch_rate64 = htb->ch_rate.rs_rate;
+ if (tb[TCA_HTB_CEIL64])
+ nla_memcpy(&htb->ch_ceil64, tb[TCA_HTB_CEIL64], sizeof(uint64_t));
+ else
+ htb->ch_ceil64 = htb->ch_ceil.rs_rate;
+
htb->ch_rbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.buffer),
- opts.rate.rate);
+ htb->ch_rate64);
htb->ch_cbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.cbuffer),
- opts.ceil.rate);
+ htb->ch_ceil64);
htb->ch_quantum = opts.quantum;
htb->ch_level = opts.level;
@@ -135,8 +147,8 @@ static void htb_class_dump_line(struct rtnl_tc *tc, void *data,
double r, rbit;
char *ru, *rubit;
- r = nl_cancel_down_bytes(htb->ch_rate.rs_rate, &ru);
- rbit = nl_cancel_down_bits(htb->ch_rate.rs_rate*8, &rubit);
+ r = nl_cancel_down_bytes(htb->ch_rate64, &ru);
+ rbit = nl_cancel_down_bits(htb->ch_rate64*8, &rubit);
nl_dump(p, " rate %.2f%s/s (%.0f%s) log %u",
r, ru, rbit, rubit, 1<<htb->ch_rate.rs_cell_log);
@@ -156,8 +168,8 @@ static void htb_class_dump_details(struct rtnl_tc *tc, void *data,
double r, rbit;
char *ru, *rubit;
- r = nl_cancel_down_bytes(htb->ch_ceil.rs_rate, &ru);
- rbit = nl_cancel_down_bits(htb->ch_ceil.rs_rate*8, &rubit);
+ r = nl_cancel_down_bytes(htb->ch_ceil64, &ru);
+ rbit = nl_cancel_down_bits(htb->ch_ceil64*8, &rubit);
nl_dump(p, " ceil %.2f%s/s (%.0f%s) log %u",
r, ru, rbit, rubit, 1<<htb->ch_ceil.rs_cell_log);
@@ -242,21 +254,25 @@ static int htb_class_msg_fill(struct rtnl_tc *tc, void *data,
if (htb->ch_mask & SCH_HTB_HAS_RBUFFER)
buffer = htb->ch_rbuffer;
else
- buffer = opts.rate.rate / nl_get_psched_hz() + mtu; /* XXX */
+ buffer = htb->ch_rate64 / nl_get_psched_hz() + mtu; /* XXX */
- opts.buffer = nl_us2ticks(rtnl_tc_calc_txtime(buffer, opts.rate.rate));
+ opts.buffer = nl_us2ticks(rtnl_tc_calc_txtime(buffer, htb->ch_rate64));
if (htb->ch_mask & SCH_HTB_HAS_CBUFFER)
cbuffer = htb->ch_cbuffer;
else
- cbuffer = opts.ceil.rate / nl_get_psched_hz() + mtu; /* XXX */
+ cbuffer = htb->ch_ceil64 / nl_get_psched_hz() + mtu; /* XXX */
- opts.cbuffer = nl_us2ticks(rtnl_tc_calc_txtime(cbuffer, opts.ceil.rate));
+ opts.cbuffer = nl_us2ticks(rtnl_tc_calc_txtime(cbuffer, htb->ch_ceil64));
if (htb->ch_mask & SCH_HTB_HAS_QUANTUM)
opts.quantum = htb->ch_quantum;
NLA_PUT(msg, TCA_HTB_PARMS, sizeof(opts), &opts);
+ if (htb->ch_rate64 >= (1ULL << 32))
+ NLA_PUT(msg, TCA_HTB_RATE64, sizeof(uint64_t), &htb->ch_rate64);
+ if (htb->ch_ceil64 >= (1ULL << 32))
+ NLA_PUT(msg, TCA_HTB_CEIL64, sizeof(uint64_t), &htb->ch_ceil64);
NLA_PUT(msg, TCA_HTB_RTAB, sizeof(rtable), &rtable);
NLA_PUT(msg, TCA_HTB_CTAB, sizeof(ctable), &ctable);
@@ -385,13 +401,13 @@ int rtnl_htb_set_prio(struct rtnl_class *class, uint32_t prio)
*
* @return Rate in bytes/s or 0 if unspecified.
*/
-uint32_t rtnl_htb_get_rate(struct rtnl_class *class)
+uint64_t rtnl_htb_get_rate(struct rtnl_class *class)
{
struct rtnl_htb_class *htb;
if ((htb = htb_class_data(class, NULL)) &&
(htb->ch_mask & SCH_HTB_HAS_RATE))
- return htb->ch_rate.rs_rate;
+ return htb->ch_rate64;
return 0;
}
@@ -403,7 +419,7 @@ uint32_t rtnl_htb_get_rate(struct rtnl_class *class)
*
* @return 0 on success or a negative error code.
*/
-int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
+int rtnl_htb_set_rate(struct rtnl_class *class, uint64_t rate)
{
struct rtnl_htb_class *htb;
int err;
@@ -412,7 +428,8 @@ int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
return err;
htb->ch_rate.rs_cell_log = UINT8_MAX; /* use default value */
- htb->ch_rate.rs_rate = rate;
+ htb->ch_rate.rs_rate = (rate >= (1ULL << 32)) ? ~0U : rate;
+ htb->ch_rate64 = rate;
htb->ch_mask |= SCH_HTB_HAS_RATE;
return 0;
@@ -424,13 +441,13 @@ int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
*
* @return Ceil rate in bytes/s or 0 if unspecified
*/
-uint32_t rtnl_htb_get_ceil(struct rtnl_class *class)
+uint64_t rtnl_htb_get_ceil(struct rtnl_class *class)
{
struct rtnl_htb_class *htb;
if ((htb = htb_class_data(class, NULL)) &&
(htb->ch_mask & SCH_HTB_HAS_CEIL))
- return htb->ch_ceil.rs_rate;
+ return htb->ch_ceil64;
return 0;
}
@@ -442,7 +459,7 @@ uint32_t rtnl_htb_get_ceil(struct rtnl_class *class)
*
* @return 0 on success or a negative error code.
*/
-int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil)
+int rtnl_htb_set_ceil(struct rtnl_class *class, uint64_t ceil)
{
struct rtnl_htb_class *htb;
int err;
@@ -451,7 +468,8 @@ int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil)
return err;
htb->ch_ceil.rs_cell_log = UINT8_MAX; /* use default value */
- htb->ch_ceil.rs_rate = ceil;
+ htb->ch_ceil.rs_rate = (ceil >= (1ULL << 32)) ? ~0U : ceil;
+ htb->ch_ceil64 = ceil;
htb->ch_mask |= SCH_HTB_HAS_CEIL;
return 0;
diff --git a/lib/route/tc.c b/lib/route/tc.c
index f9a533c..2e1d590 100644
--- a/lib/route/tc.c
+++ b/lib/route/tc.c
@@ -646,7 +646,7 @@ int rtnl_tc_str2stat(const char *name)
*
* @return Required transmit time in micro seconds.
*/
-int rtnl_tc_calc_txtime(int bufsize, int rate)
+int rtnl_tc_calc_txtime(int bufsize, uint64_t rate)
{
double tx_time_secs;
@@ -669,7 +669,7 @@ int rtnl_tc_calc_txtime(int bufsize, int rate)
*
* @return Size of buffer in bytes.
*/
-int rtnl_tc_calc_bufsize(int txtime, int rate)
+int rtnl_tc_calc_bufsize(int txtime, uint64_t rate)
{
double bufsize;
diff --git a/python/netlink/route/capi.i b/python/netlink/route/capi.i
index 2d72bd7..570e700 100644
--- a/python/netlink/route/capi.i
+++ b/python/netlink/route/capi.i
@@ -417,10 +417,10 @@ extern int rtnl_htb_set_defcls(struct rtnl_qdisc *, uint32_t);
extern uint32_t rtnl_htb_get_prio(struct rtnl_class *);
extern int rtnl_htb_set_prio(struct rtnl_class *, uint32_t);
-extern uint32_t rtnl_htb_get_rate(struct rtnl_class *);
-extern int rtnl_htb_set_rate(struct rtnl_class *, uint32_t);
-extern uint32_t rtnl_htb_get_ceil(struct rtnl_class *);
-extern int rtnl_htb_set_ceil(struct rtnl_class *, uint32_t);
+extern uint64_t rtnl_htb_get_rate(struct rtnl_class *);
+extern int rtnl_htb_set_rate(struct rtnl_class *, uint64_t);
+extern uint64_t rtnl_htb_get_ceil(struct rtnl_class *);
+extern int rtnl_htb_set_ceil(struct rtnl_class *, uint64_t);
extern uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *);
extern int rtnl_htb_set_rbuffer(struct rtnl_class *, uint32_t);
extern uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *);