summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-09-01 15:57:12 +0200
committerThomas Haller <thaller@redhat.com>2019-09-01 15:57:12 +0200
commit2c862a606bc18a9e17bc764db1d3ef2cc1b2e368 (patch)
treeefc06edc5443569864f6b7b0904a176bee0f99a6
parent2154891180bbae40af2f1abab5f6c4f7040de81a (diff)
parent03ee05d97565da9ef935ebbdd6d56f7ab3da5bfc (diff)
downloadlibnl-2c862a606bc18a9e17bc764db1d3ef2cc1b2e368.tar.gz
route/qdisc: merge branch 'd0u9/htb_64'
https://github.com/thom311/libnl/pull/205
-rw-r--r--include/netlink-private/netlink.h14
-rw-r--r--include/netlink-private/types.h4
-rw-r--r--include/netlink/route/qdisc/htb.h15
-rw-r--r--lib/route/qdisc/htb.c135
-rw-r--r--lib/route/qdisc/tbf.c42
-rw-r--r--lib/route/tc.c14
-rw-r--r--libnl-route-3.sym4
7 files changed, 166 insertions, 62 deletions
diff --git a/include/netlink-private/netlink.h b/include/netlink-private/netlink.h
index 0d831cf6..5f6e3f79 100644
--- a/include/netlink-private/netlink.h
+++ b/include/netlink-private/netlink.h
@@ -186,7 +186,7 @@ static inline void rtnl_copy_ratespec(struct rtnl_ratespec *dst,
dst->rs_overhead = src->overhead;
dst->rs_cell_align = src->cell_align;
dst->rs_mpu = src->mpu;
- dst->rs_rate = src->rate;
+ dst->rs_rate64 = src->rate;
}
static inline void rtnl_rcopy_ratespec(struct tc_ratespec *dst,
@@ -196,7 +196,7 @@ static inline void rtnl_rcopy_ratespec(struct tc_ratespec *dst,
dst->overhead = src->rs_overhead;
dst->cell_align = src->rs_cell_align;
dst->mpu = src->rs_mpu;
- dst->rate = src->rs_rate;
+ dst->rate = src->rs_rate64 > 0xFFFFFFFFull ? 0xFFFFFFFFull : (uint32_t) src->rs_rate64;
}
static inline const char *nl_cache_name(struct nl_cache *cache)
@@ -276,4 +276,14 @@ static inline void nl_write_unlock(pthread_rwlock_t *lock)
#define nl_write_unlock(LOCK) do { } while(0)
#endif
+static inline int rtnl_tc_calc_txtime64(int bufsize, uint64_t rate)
+{
+ return ((double) bufsize / (double) rate) * 1000000.0;
+}
+
+static inline int rtnl_tc_calc_bufsize64(int txtime, uint64_t rate)
+{
+ return ((double) txtime * (double) rate) / 1000000.0;
+}
+
#endif
diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h
index 209f0999..97af3e51 100644
--- a/include/netlink-private/types.h
+++ b/include/netlink-private/types.h
@@ -495,11 +495,11 @@ struct rtnl_neightbl
struct rtnl_ratespec
{
- uint8_t rs_cell_log;
+ uint64_t rs_rate64;
uint16_t rs_overhead;
int16_t rs_cell_align;
uint16_t rs_mpu;
- uint32_t rs_rate;
+ uint8_t rs_cell_log;
};
struct rtnl_tstats
diff --git a/include/netlink/route/qdisc/htb.h b/include/netlink/route/qdisc/htb.h
index c5065f40..5d7ca452 100644
--- a/include/netlink/route/qdisc/htb.h
+++ b/include/netlink/route/qdisc/htb.h
@@ -30,10 +30,17 @@ 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 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 int rtnl_htb_get_rate64(struct rtnl_class *, uint64_t *);
+extern int rtnl_htb_set_rate64(struct rtnl_class *, uint64_t);
+extern int rtnl_htb_get_ceil64(struct rtnl_class *, uint64_t *);
+extern int rtnl_htb_set_ceil64(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/lib/route/qdisc/htb.c b/lib/route/qdisc/htb.c
index c1e32307..e426a149 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,16 @@ 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);
- htb->ch_rbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.buffer),
- opts.rate.rate);
- htb->ch_cbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.cbuffer),
- opts.ceil.rate);
+
+ if (tb[TCA_HTB_RATE64])
+ nla_memcpy(&htb->ch_rate.rs_rate64, tb[TCA_HTB_RATE64], sizeof(uint64_t));
+ if (tb[TCA_HTB_CEIL64])
+ nla_memcpy(&htb->ch_ceil.rs_rate64, tb[TCA_HTB_CEIL64], sizeof(uint64_t));
+
+ htb->ch_rbuffer = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.buffer),
+ htb->ch_rate.rs_rate64);
+ htb->ch_cbuffer = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.cbuffer),
+ htb->ch_ceil.rs_rate64);
htb->ch_quantum = opts.quantum;
htb->ch_level = opts.level;
@@ -135,8 +143,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_rate.rs_rate64, &ru);
+ rbit = nl_cancel_down_bits(htb->ch_rate.rs_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 +164,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_ceil.rs_rate64, &ru);
+ rbit = nl_cancel_down_bits(htb->ch_ceil.rs_rate64*8, &rubit);
nl_dump(p, " ceil %.2f%s/s (%.0f%s) log %u",
r, ru, rbit, rubit, 1<<htb->ch_ceil.rs_cell_log);
@@ -213,6 +221,8 @@ static int htb_class_msg_fill(struct rtnl_tc *tc, void *data,
uint32_t mtu, rtable[RTNL_TC_RTABLE_SIZE], ctable[RTNL_TC_RTABLE_SIZE];
struct tc_htb_opt opts;
int buffer, cbuffer;
+ uint64_t rate64;
+ uint64_t ceil64;
if (!htb || !(htb->ch_mask & SCH_HTB_HAS_RATE))
BUG();
@@ -227,36 +237,43 @@ static int htb_class_msg_fill(struct rtnl_tc *tc, void *data,
rtnl_tc_build_rate_table(tc, &htb->ch_rate, rtable);
rtnl_rcopy_ratespec(&opts.rate, &htb->ch_rate);
+ rate64 = htb->ch_rate.rs_rate64;
if (htb->ch_mask & SCH_HTB_HAS_CEIL) {
rtnl_tc_build_rate_table(tc, &htb->ch_ceil, ctable);
rtnl_rcopy_ratespec(&opts.ceil, &htb->ch_ceil);
+ ceil64 = htb->ch_ceil.rs_rate64;
} else {
/*
* If not set, configured rate is used as ceil, which implies
* no borrowing.
*/
memcpy(&opts.ceil, &opts.rate, sizeof(struct tc_ratespec));
+ ceil64 = rate64;
}
if (htb->ch_mask & SCH_HTB_HAS_RBUFFER)
buffer = htb->ch_rbuffer;
else
- buffer = opts.rate.rate / nl_get_psched_hz() + mtu; /* XXX */
+ buffer = 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_txtime64(buffer, 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 = 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_txtime64(cbuffer, ceil64));
if (htb->ch_mask & SCH_HTB_HAS_QUANTUM)
opts.quantum = htb->ch_quantum;
NLA_PUT(msg, TCA_HTB_PARMS, sizeof(opts), &opts);
+ if (rate64 > 0xFFFFFFFFull)
+ NLA_PUT(msg, TCA_HTB_RATE64, sizeof(uint64_t), &rate64);
+ if (ceil64 > 0xFFFFFFFFull)
+ NLA_PUT(msg, TCA_HTB_CEIL64, sizeof(uint64_t), &ceil64);
NLA_PUT(msg, TCA_HTB_RTAB, sizeof(rtable), &rtable);
NLA_PUT(msg, TCA_HTB_CTAB, sizeof(ctable), &ctable);
@@ -383,16 +400,41 @@ int rtnl_htb_set_prio(struct rtnl_class *class, uint32_t prio)
* Return rate of HTB class
* @arg class htb class object
*
- * @return Rate in bytes/s or 0 if unspecified.
+ * @return Rate in bytes/s or 0 if unspecified. If the value
+ * cannot be represented as 32 bit integer, (1<<32) is returned.
+ * Use rtnl_htb_get_rate64() instead.
*/
uint32_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;
+ if ( !(htb = htb_class_data(class, NULL))
+ || !(htb->ch_mask & SCH_HTB_HAS_RATE))
+ return 0;
+
+ if (htb->ch_rate.rs_rate64 > 0xFFFFFFFFull)
+ return 0xFFFFFFFFull;
+ return htb->ch_rate.rs_rate64;
+}
+
+/**
+ * Return rate of HTB class
+ * @arg class htb class object
+ * @arg out_rate64 on success, the set rate.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_htb_get_rate64(struct rtnl_class *class, uint64_t *out_rate64)
+{
+ struct rtnl_htb_class *htb;
+
+ if (!(htb = htb_class_data(class, NULL)))
+ return -NLE_INVAL;
+ if (!(htb->ch_mask & SCH_HTB_HAS_RATE))
+ return -NLE_NOATTR;
+
+ *out_rate64 = htb->ch_rate.rs_rate64;
return 0;
}
@@ -405,6 +447,18 @@ uint32_t rtnl_htb_get_rate(struct rtnl_class *class)
*/
int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
{
+ return rtnl_htb_set_rate64(class, rate);
+}
+
+/**
+ * Set rate of HTB class
+ * @arg class htb class object
+ * @arg rate new rate in bytes per second
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_htb_set_rate64(struct rtnl_class *class, uint64_t rate)
+{
struct rtnl_htb_class *htb;
int err;
@@ -412,7 +466,7 @@ 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_rate64 = rate;
htb->ch_mask |= SCH_HTB_HAS_RATE;
return 0;
@@ -422,16 +476,41 @@ int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
* Return ceil rate of HTB class
* @arg class htb class object
*
- * @return Ceil rate in bytes/s or 0 if unspecified
+ * @return Ceil rate in bytes/s or 0 if unspecified. If the value
+ * cannot be represented as 32 bit integer, (1<<32) is returned.
+ * Use rtnl_htb_get_ceil64() instead.
*/
uint32_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;
+ if ( !(htb = htb_class_data(class, NULL))
+ || !(htb->ch_mask & SCH_HTB_HAS_CEIL))
+ return 0;
+
+ if (htb->ch_ceil.rs_rate64 > 0xFFFFFFFFull)
+ return 0xFFFFFFFFull;
+
+ return htb->ch_ceil.rs_rate64;
+}
+
+/**
+ * Return ceil rate of HTB class
+ * @arg class htb class object
+ * @arg out_ceil64 on success, the set ceil value.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_htb_get_ceil64(struct rtnl_class *class, uint64_t *out_ceil64)
+{
+ struct rtnl_htb_class *htb;
+
+ if (!(htb = htb_class_data(class, NULL)))
+ return -NLE_INVAL;
+ if (!(htb->ch_mask & SCH_HTB_HAS_CEIL))
+ return -NLE_NOATTR;
+ *out_ceil64 = htb->ch_ceil.rs_rate64;
return 0;
}
@@ -444,6 +523,18 @@ uint32_t rtnl_htb_get_ceil(struct rtnl_class *class)
*/
int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil)
{
+ return rtnl_htb_set_ceil64(class, ceil);
+}
+
+/**
+ * Set ceil rate of HTB class
+ * @arg class htb class object
+ * @arg ceil64 new ceil rate number of bytes per second
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_htb_set_ceil64(struct rtnl_class *class, uint64_t ceil64)
+{
struct rtnl_htb_class *htb;
int err;
@@ -451,7 +542,7 @@ 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_rate64 = ceil64;
htb->ch_mask |= SCH_HTB_HAS_CEIL;
return 0;
diff --git a/lib/route/qdisc/tbf.c b/lib/route/qdisc/tbf.c
index eb574d95..23cc8454 100644
--- a/lib/route/qdisc/tbf.c
+++ b/lib/route/qdisc/tbf.c
@@ -44,24 +44,24 @@ static int tbf_msg_parser(struct rtnl_tc *tc, void *data)
if ((err = tca_parse(tb, TCA_TBF_MAX, tc, tbf_policy)) < 0)
return err;
-
+
if (tb[TCA_TBF_PARMS]) {
struct tc_tbf_qopt opts;
int bufsize;
nla_memcpy(&opts, tb[TCA_TBF_PARMS], sizeof(opts));
tbf->qt_limit = opts.limit;
-
+
rtnl_copy_ratespec(&tbf->qt_rate, &opts.rate);
tbf->qt_rate_txtime = opts.buffer;
- bufsize = rtnl_tc_calc_bufsize(nl_ticks2us(opts.buffer),
- opts.rate.rate);
+ bufsize = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.buffer),
+ tbf->qt_rate.rs_rate64);
tbf->qt_rate_bucket = bufsize;
rtnl_copy_ratespec(&tbf->qt_peakrate, &opts.peakrate);
tbf->qt_peakrate_txtime = opts.mtu;
- bufsize = rtnl_tc_calc_bufsize(nl_ticks2us(opts.mtu),
- opts.peakrate.rate);
+ bufsize = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.mtu),
+ tbf->qt_peakrate.rs_rate64);
tbf->qt_peakrate_bucket = bufsize;
rtnl_tc_set_mpu(tc, tbf->qt_rate.rs_mpu);
@@ -83,8 +83,8 @@ static void tbf_dump_line(struct rtnl_tc *tc, void *data,
if (!tbf)
return;
- r = nl_cancel_down_bytes(tbf->qt_rate.rs_rate, &ru);
- rbit = nl_cancel_down_bits(tbf->qt_rate.rs_rate*8, &rubit);
+ r = nl_cancel_down_bytes(tbf->qt_rate.rs_rate64, &ru);
+ rbit = nl_cancel_down_bits(tbf->qt_rate.rs_rate64*8, &rubit);
lim = nl_cancel_down_bytes(tbf->qt_limit, &limu);
nl_dump(p, " rate %.2f%s/s (%.0f%s) limit %.2f%s",
@@ -114,9 +114,9 @@ static void tbf_dump_details(struct rtnl_tc *tc, void *data,
if (tbf->qt_mask & TBF_ATTR_PEAKRATE) {
char *pru, *prbu, *bsu, *clu;
double pr, prb, bs, cl;
-
- pr = nl_cancel_down_bytes(tbf->qt_peakrate.rs_rate, &pru);
- prb = nl_cancel_down_bits(tbf->qt_peakrate.rs_rate * 8, &prbu);
+
+ pr = nl_cancel_down_bytes(tbf->qt_peakrate.rs_rate64, &pru);
+ prb = nl_cancel_down_bits(tbf->qt_peakrate.rs_rate64 * 8, &prbu);
bs = nl_cancel_down_bits(tbf->qt_peakrate_bucket, &bsu);
cl = nl_cancel_down_bits(1 << tbf->qt_peakrate.rs_cell_log,
&clu);
@@ -191,7 +191,7 @@ static inline double calc_limit(struct rtnl_ratespec *spec, int latency,
{
double limit;
- limit = (double) spec->rs_rate * ((double) latency / 1000000.);
+ limit = (double) spec->rs_rate64 * ((double) latency / 1000000.);
limit += bucket;
return limit;
@@ -278,7 +278,7 @@ void rtnl_qdisc_tbf_set_rate(struct rtnl_qdisc *qdisc, int rate, int bucket,
{
struct rtnl_tbf *tbf;
int cell_log;
-
+
if (!(tbf = rtnl_tc_data(TC_CAST(qdisc))))
BUG();
@@ -287,10 +287,10 @@ void rtnl_qdisc_tbf_set_rate(struct rtnl_qdisc *qdisc, int rate, int bucket,
else
cell_log = rtnl_tc_calc_cell_log(cell);
- tbf->qt_rate.rs_rate = rate;
+ tbf->qt_rate.rs_rate64 = (uint32_t)rate;
tbf->qt_rate_bucket = bucket;
tbf->qt_rate.rs_cell_log = cell_log;
- tbf->qt_rate_txtime = nl_us2ticks(rtnl_tc_calc_txtime(bucket, rate));
+ tbf->qt_rate_txtime = nl_us2ticks(rtnl_tc_calc_txtime64(bucket, tbf->qt_rate.rs_rate64));
tbf->qt_mask |= TBF_ATTR_RATE;
}
@@ -307,7 +307,7 @@ int rtnl_qdisc_tbf_get_rate(struct rtnl_qdisc *qdisc)
BUG();
if (tbf->qt_mask & TBF_ATTR_RATE)
- return tbf->qt_rate.rs_rate;
+ return tbf->qt_rate.rs_rate64;
else
return -1;
}
@@ -361,7 +361,7 @@ int rtnl_qdisc_tbf_set_peakrate(struct rtnl_qdisc *qdisc, int rate, int bucket,
{
struct rtnl_tbf *tbf;
int cell_log;
-
+
if (!(tbf = rtnl_tc_data(TC_CAST(qdisc))))
BUG();
@@ -369,11 +369,11 @@ int rtnl_qdisc_tbf_set_peakrate(struct rtnl_qdisc *qdisc, int rate, int bucket,
if (cell_log < 0)
return cell_log;
- tbf->qt_peakrate.rs_rate = rate;
+ tbf->qt_peakrate.rs_rate64 = (uint32_t)rate;
tbf->qt_peakrate_bucket = bucket;
tbf->qt_peakrate.rs_cell_log = cell_log;
- tbf->qt_peakrate_txtime = nl_us2ticks(rtnl_tc_calc_txtime(bucket, rate));
-
+ tbf->qt_peakrate_txtime = nl_us2ticks(rtnl_tc_calc_txtime64(bucket, tbf->qt_peakrate.rs_rate64));
+
tbf->qt_mask |= TBF_ATTR_PEAKRATE;
return 0;
@@ -392,7 +392,7 @@ int rtnl_qdisc_tbf_get_peakrate(struct rtnl_qdisc *qdisc)
BUG();
if (tbf->qt_mask & TBF_ATTR_PEAKRATE)
- return tbf->qt_peakrate.rs_rate;
+ return tbf->qt_peakrate.rs_rate64;
else
return -1;
}
diff --git a/lib/route/tc.c b/lib/route/tc.c
index f9a533cf..35303f59 100644
--- a/lib/route/tc.c
+++ b/lib/route/tc.c
@@ -648,11 +648,7 @@ int rtnl_tc_str2stat(const char *name)
*/
int rtnl_tc_calc_txtime(int bufsize, int rate)
{
- double tx_time_secs;
-
- tx_time_secs = (double) bufsize / (double) rate;
-
- return tx_time_secs * 1000000.;
+ return ((double) bufsize / (double) rate) * 1000000.0;
}
/**
@@ -671,11 +667,7 @@ int rtnl_tc_calc_txtime(int bufsize, int rate)
*/
int rtnl_tc_calc_bufsize(int txtime, int rate)
{
- double bufsize;
-
- bufsize = (double) txtime * (double) rate;
-
- return bufsize / 1000000.;
+ return ((double) txtime * (double) rate) / 1000000.0;
}
/**
@@ -784,7 +776,7 @@ int rtnl_tc_build_rate_table(struct rtnl_tc *tc, struct rtnl_ratespec *spec,
for (i = 0; i < RTNL_TC_RTABLE_SIZE; i++) {
size = adjust_size((i + 1) << cell_log, spec->rs_mpu, linktype);
- dst[i] = nl_us2ticks(rtnl_tc_calc_txtime(size, spec->rs_rate));
+ dst[i] = nl_us2ticks(rtnl_tc_calc_txtime64(size, spec->rs_rate64));
}
spec->rs_cell_align = -1;
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index 67334abb..4a65503f 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -1066,6 +1066,10 @@ global:
rtnl_class_get_by_parent;
rtnl_cls_cache_set_tc_params;
rtnl_ematch_tree_clone;
+ rtnl_htb_get_ceil64;
+ rtnl_htb_get_rate64;
+ rtnl_htb_set_ceil64;
+ rtnl_htb_set_rate64;
rtnl_link_geneve_alloc;
rtnl_link_geneve_get_flags;
rtnl_link_geneve_get_id;