summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authord0u9 <d0u9.su@outlook.com>2018-10-31 13:13:13 +0800
committerThomas Haller <thaller@redhat.com>2019-09-01 14:44:42 +0200
commit4cf69a1b7b2518d18e1a62c79a461bca109132fc (patch)
treed9d746c7dfbe661c3759ed85882c01b3a5fbef04 /lib
parent2154891180bbae40af2f1abab5f6c4f7040de81a (diff)
downloadlibnl-4cf69a1b7b2518d18e1a62c79a461bca109132fc.tar.gz
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/route/qdisc/htb.c54
-rw-r--r--lib/route/tc.c4
2 files changed, 38 insertions, 20 deletions
diff --git a/lib/route/qdisc/htb.c b/lib/route/qdisc/htb.c
index c1e32307..eb500a3b 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 f9a533cf..2e1d590f 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;