@@ -400,6 +400,8 @@ seg_y2x(u64 y, u64 ism)
{
u64 x;
+ /* callers guarantee that ism is not infinity */
+#if 0
if (y == 0)
x = 0;
else if (ism == HT_INFINITY)
@@ -408,6 +410,8 @@ seg_y2x(u64 y, u64 ism)
x = (y >> ISM_SHIFT) * ism
+ (((y & ISM_MASK) * ism) >> ISM_SHIFT);
}
+#endif
+ x = (y >> ISM_SHIFT) * ism + (((y & ISM_MASK) * ism) >> ISM_SHIFT);
return x;
}
@@ -509,7 +513,7 @@ rtsc_y2x(struct runtime_sc *rtsc, u64 y)
{
u64 x;
- if (y < rtsc->y)
+ if (y < rtsc->y && rtsc->dy != 0)
x = rtsc->x;
else if (y <= rtsc->y + rtsc->dy) {
/* x belongs to the 1st segment */
@@ -985,22 +989,40 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
if (tb[TCA_HFSC_RSC]) {
rsc = nla_data(tb[TCA_HFSC_RSC]);
- if (rsc->m1 == 0 && rsc->m2 == 0)
- rsc = NULL;
+ if (rsc->m2 == 0) {
+ if (rsc->m1 != 0)
+ return -EINVAL;
+ else
+ rsc = NULL;
+ }
}
if (tb[TCA_HFSC_FSC]) {
fsc = nla_data(tb[TCA_HFSC_FSC]);
- if (fsc->m1 == 0 && fsc->m2 == 0)
- fsc = NULL;
+ if (fsc->m2 == 0) {
+ if (fsc->m1 != 0)
+ return -EINVAL;
+ else
+ fsc = NULL;
+ }
}
if (tb[TCA_HFSC_USC]) {
usc = nla_data(tb[TCA_HFSC_USC]);
- if (usc->m1 == 0 && usc->m2 == 0)
- usc = NULL;
+ if (usc->m2 == 0) {
+ if (usc->m1 != 0)
+ return -EINVAL;
+ else
+ usc = NULL;
+ }
}
+ if (rsc == NULL && fsc == NULL)
+ return -EINVAL;
+
+ if (fsc == NULL && usc != NULL)
+ return -EINVAL;
+
if (cl != NULL) {
if (parentid) {
if (cl->cl_parent &&
@@ -1053,9 +1075,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
if (hfsc_find_class(classid, sch))
return -EEXIST;
- if (rsc == NULL && fsc == NULL)
- return -EINVAL;
-
cl = kzalloc(sizeof(struct hfsc_class), GFP_KERNEL);
if (cl == NULL)
return -ENOBUFS;