]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/sched/act_police.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
[linux.git] / net / sched / act_police.c
index 6315e0f8d26e3abfb96101bec5f9048db9619c21..89c04c52af3dab3d7fc1fbd1d08a3f112c33ac72 100644 (file)
@@ -40,6 +40,8 @@ static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
        [TCA_POLICE_PEAKRATE]   = { .len = TC_RTAB_SIZE },
        [TCA_POLICE_AVRATE]     = { .type = NLA_U32 },
        [TCA_POLICE_RESULT]     = { .type = NLA_U32 },
+       [TCA_POLICE_RATE64]     = { .type = NLA_U64 },
+       [TCA_POLICE_PEAKRATE64] = { .type = NLA_U64 },
 };
 
 static int tcf_police_init(struct net *net, struct nlattr *nla,
@@ -58,6 +60,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
        struct tcf_police_params *new;
        bool exists = false;
        u32 index;
+       u64 rate64, prate64;
 
        if (nla == NULL)
                return -EINVAL;
@@ -155,14 +158,18 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
        }
        if (R_tab) {
                new->rate_present = true;
-               psched_ratecfg_precompute(&new->rate, &R_tab->rate, 0);
+               rate64 = tb[TCA_POLICE_RATE64] ?
+                        nla_get_u64(tb[TCA_POLICE_RATE64]) : 0;
+               psched_ratecfg_precompute(&new->rate, &R_tab->rate, rate64);
                qdisc_put_rtab(R_tab);
        } else {
                new->rate_present = false;
        }
        if (P_tab) {
                new->peak_present = true;
-               psched_ratecfg_precompute(&new->peak, &P_tab->rate, 0);
+               prate64 = tb[TCA_POLICE_PEAKRATE64] ?
+                         nla_get_u64(tb[TCA_POLICE_PEAKRATE64]) : 0;
+               psched_ratecfg_precompute(&new->peak, &P_tab->rate, prate64);
                qdisc_put_rtab(P_tab);
        } else {
                new->peak_present = false;
@@ -313,10 +320,22 @@ static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a,
                                      lockdep_is_held(&police->tcf_lock));
        opt.mtu = p->tcfp_mtu;
        opt.burst = PSCHED_NS2TICKS(p->tcfp_burst);
-       if (p->rate_present)
+       if (p->rate_present) {
                psched_ratecfg_getrate(&opt.rate, &p->rate);
-       if (p->peak_present)
+               if ((police->params->rate.rate_bytes_ps >= (1ULL << 32)) &&
+                   nla_put_u64_64bit(skb, TCA_POLICE_RATE64,
+                                     police->params->rate.rate_bytes_ps,
+                                     TCA_POLICE_PAD))
+                       goto nla_put_failure;
+       }
+       if (p->peak_present) {
                psched_ratecfg_getrate(&opt.peakrate, &p->peak);
+               if ((police->params->peak.rate_bytes_ps >= (1ULL << 32)) &&
+                   nla_put_u64_64bit(skb, TCA_POLICE_PEAKRATE64,
+                                     police->params->peak.rate_bytes_ps,
+                                     TCA_POLICE_PAD))
+                       goto nla_put_failure;
+       }
        if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt))
                goto nla_put_failure;
        if (p->tcfp_result &&