]> granicus.if.org Git - libnl/commitdiff
route/qdisc: adjust API for 64 bit rate/ceil support for htb class
authorThomas Haller <thaller@redhat.com>
Sun, 1 Sep 2019 12:56:19 +0000 (14:56 +0200)
committerThomas Haller <thaller@redhat.com>
Sun, 1 Sep 2019 13:54:33 +0000 (15:54 +0200)
- existing API/ABI must stay unchanged. We cannot change parameter
  types. Ad most we can add new variants that support 64 bit integers.

- rtnl_tc_calc_txtime64() and rtnl_tc_calc_bufsize64() are trivial.
  We should not blow up the public API of libnl for such a thing.
  If the users needs it, they can just reimplement it.

- getters should return an error code. Especially if the return type
  does not support encoding an error there.

- don't add separate rs_rate64/rs_ceil64 field. Instead, extend the
  "rs_rate" field of "struct rtnl_ratespec" to 64 bits. It's internal
  API.

doc/route.txt
include/netlink-private/netlink.h
include/netlink-private/types.h
include/netlink/route/qdisc/htb.h
include/netlink/route/tc.h
lib/route/qdisc/htb.c
lib/route/qdisc/tbf.c
lib/route/tc.c
libnl-route-3.sym
python/netlink/route/capi.i

index c2a3b1b6a48ecb4ebe13e7acc8795f4f9db3b3d9..9d4c23aacfa449488c4b645494f318888722d103 100644 (file)
@@ -1886,8 +1886,8 @@ or erqual than the rate of its children.
 +
 [source,c]
 -----
-uint64_t rtnl_htb_get_rate(struct rtnl_class *class);
-int rtnl_htb_set_rate(struct rtnl_class *class, uint64_t ceil);
+uint32_t rtnl_htb_get_rate(struct rtnl_class *class);
+int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t ceil);
 -----
 
 Ceil Rate::
@@ -1899,8 +1899,8 @@ be greater or erqual than the ceil rate of its children.
 +
 [source,c]
 -----
-uint64_t rtnl_htb_get_ceil(struct rtnl_class *class);
-int rtnl_htb_set_ceil(struct rtnl_class *class, uint64_t ceil);
+uint32_t rtnl_htb_get_ceil(struct rtnl_class *class);
+int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil);
 -----
 
 Burst::
index 0d831cf66a8cdff0e6c36f344cd829c820d3814a..5f6e3f7910d9bd45520d26c2575c562f571ebee3 100644 (file)
@@ -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
index f1923797ac17054ae2ab87044c7e58e74c61aa6f..97af3e51bd74d2e11d93f4fffb104c61e428634e 100644 (file)
@@ -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
@@ -776,8 +776,6 @@ 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
index 72f7f75641f32b2ea4f16a7728a8b7b8be91153c..5d7ca452f7496870db7682f978136dd3bb396326 100644 (file)
@@ -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 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_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 *);
index 5cfa7a0256957e652da7875892fcf456adb1e0c4..51d670ae7566192636c6c52bb35fa8426f23e2da 100644 (file)
@@ -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, uint64_t);
-extern int             rtnl_tc_calc_bufsize(int, uint64_t);
+extern int             rtnl_tc_calc_txtime(int, int);
+extern int             rtnl_tc_calc_bufsize(int, int);
 extern int             rtnl_tc_calc_cell_log(int);
 
 extern int             rtnl_tc_read_classid_file(void);
index eb500a3b8324d6635c9b7fe740a032bc6b13f6d5..e426a149d4320b33ed07a840d7383c1bb4582e39 100644 (file)
@@ -90,18 +90,14 @@ static int htb_class_msg_parser(struct rtnl_tc *tc, void *data)
                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;
+                       nla_memcpy(&htb->ch_rate.rs_rate64, tb[TCA_HTB_RATE64], sizeof(uint64_t));
                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),
-                                                      htb->ch_rate64);
-               htb->ch_cbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.cbuffer),
-                                                      htb->ch_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;
 
@@ -147,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_rate64, &ru);
-               rbit = nl_cancel_down_bits(htb->ch_rate64*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);
@@ -168,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_ceil64, &ru);
-               rbit = nl_cancel_down_bits(htb->ch_ceil64*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);
@@ -225,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();
@@ -239,40 +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 = htb->ch_rate64 / nl_get_psched_hz() + mtu; /* XXX */
+               buffer = rate64 / nl_get_psched_hz() + mtu; /* XXX */
 
-       opts.buffer = nl_us2ticks(rtnl_tc_calc_txtime(buffer, htb->ch_rate64));
+       opts.buffer = nl_us2ticks(rtnl_tc_calc_txtime64(buffer, rate64));
 
        if (htb->ch_mask & SCH_HTB_HAS_CBUFFER)
                cbuffer = htb->ch_cbuffer;
        else
-               cbuffer = htb->ch_ceil64 / nl_get_psched_hz() + mtu; /* XXX */
+               cbuffer = ceil64 / nl_get_psched_hz() + mtu; /* XXX */
 
-       opts.cbuffer = nl_us2ticks(rtnl_tc_calc_txtime(cbuffer, htb->ch_ceil64));
+       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 (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);
+       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);
 
@@ -399,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.
  */
-uint64_t rtnl_htb_get_rate(struct rtnl_class *class)
+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_rate64;
+       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;
 }
 
@@ -419,7 +445,19 @@ uint64_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, uint64_t rate)
+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;
@@ -428,8 +466,7 @@ int rtnl_htb_set_rate(struct rtnl_class *class, uint64_t rate)
                return err;
 
        htb->ch_rate.rs_cell_log = UINT8_MAX; /* use default value */
-       htb->ch_rate.rs_rate = (rate >= (1ULL << 32)) ? ~0U : rate;
-       htb->ch_rate64 = rate;
+       htb->ch_rate.rs_rate64 = rate;
        htb->ch_mask |= SCH_HTB_HAS_RATE;
 
        return 0;
@@ -439,16 +476,41 @@ int rtnl_htb_set_rate(struct rtnl_class *class, uint64_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.
  */
-uint64_t rtnl_htb_get_ceil(struct rtnl_class *class)
+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_ceil64;
+       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;
 }
 
@@ -459,7 +521,19 @@ uint64_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, uint64_t ceil)
+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;
@@ -468,8 +542,7 @@ int rtnl_htb_set_ceil(struct rtnl_class *class, uint64_t ceil)
                return err;
 
        htb->ch_ceil.rs_cell_log = UINT8_MAX; /* use default value */
-       htb->ch_ceil.rs_rate = (ceil >= (1ULL << 32)) ? ~0U : ceil;
-       htb->ch_ceil64 = ceil;
+       htb->ch_ceil.rs_rate64 = ceil64;
        htb->ch_mask |= SCH_HTB_HAS_CEIL;
 
        return 0;
index eb574d957c0e3e1cbca913f3d091446d58fc4d82..23cc8454088392d32fc7eea6f172de189f58364c 100644 (file)
@@ -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;
 }
index 2e1d590f4245f60ae77d4a12b9e8d338cf06ad5b..35303f5914a9405b47aaf83a03e7d22dca1ada12 100644 (file)
@@ -646,13 +646,9 @@ int rtnl_tc_str2stat(const char *name)
  * 
  * @return Required transmit time in micro seconds.
  */
-int rtnl_tc_calc_txtime(int bufsize, uint64_t rate)
+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;
 }
 
 /**
@@ -669,13 +665,9 @@ int rtnl_tc_calc_txtime(int bufsize, uint64_t rate)
  *
  * @return Size of buffer in bytes.
  */
-int rtnl_tc_calc_bufsize(int txtime, uint64_t 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;
index 67334abb1363b81665802d15e0dbf4562eb591f1..4a65503f1616681aceb8ca4d3b2ab731c950d391 100644 (file)
@@ -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;
index 570e70024dd59d19d9133fb8c0923dc00c4acb40..2d72bd72b7c2c856734cc16838ec8cc5781845be 100644 (file)
@@ -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 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_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_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 *);