Skip to content

Commit

Permalink
tc: policing requires a rate estimator
Browse files Browse the repository at this point in the history
Found that while trying average rate policing, it was possible to
request average rate policing without a rate estimator. This results
in no policing which is harmless but incorrect.

Since policing could be setup in two steps, need to check
in the kernel.

Signed-off-by: Stephen Hemminger <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Stephen Hemminger authored and davem330 committed Nov 26, 2008
1 parent 71bcb09 commit c1b5687
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/net/gen_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@ extern void gen_kill_estimator(struct gnet_stats_basic *bstats,
extern int gen_replace_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est,
spinlock_t *stats_lock, struct nlattr *opt);
extern int gen_estimator_active(const struct gnet_stats_rate_est *rate_est);

#endif
30 changes: 27 additions & 3 deletions net/core/gen_estimator.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,

return 0;
}
EXPORT_SYMBOL(gen_new_estimator);

static void __gen_kill_estimator(struct rcu_head *head)
{
Expand Down Expand Up @@ -275,6 +276,7 @@ void gen_kill_estimator(struct gnet_stats_basic *bstats,
call_rcu(&e->e_rcu, __gen_kill_estimator);
}
}
EXPORT_SYMBOL(gen_kill_estimator);

/**
* gen_replace_estimator - replace rate estimator configuration
Expand All @@ -295,8 +297,30 @@ int gen_replace_estimator(struct gnet_stats_basic *bstats,
gen_kill_estimator(bstats, rate_est);
return gen_new_estimator(bstats, rate_est, stats_lock, opt);
}
EXPORT_SYMBOL(gen_replace_estimator);

/**
* gen_estimator_active - test if estimator is currently in use
* @rate_est: rate estimator statistics
*
* Returns 1 if estimator is active, and 0 if not.
*/
int gen_estimator_active(const struct gnet_stats_rate_est *rate_est)
{
int idx;
struct gen_estimator *e;

ASSERT_RTNL();

EXPORT_SYMBOL(gen_kill_estimator);
EXPORT_SYMBOL(gen_new_estimator);
EXPORT_SYMBOL(gen_replace_estimator);
for (idx=0; idx <= EST_MAX_INTERVAL; idx++) {
if (!elist[idx].timer.function)
continue;

list_for_each_entry(e, &elist[idx].list, list) {
if (e->rate_est == rate_est)
return 1;
}
}
return 0;
}
EXPORT_SYMBOL(gen_estimator_active);
6 changes: 6 additions & 0 deletions net/sched/act_police.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est,
R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE]);
if (R_tab == NULL)
goto failure;

if (!est && !gen_estimator_active(&police->tcf_rate_est)) {
err = -EINVAL;
goto failure;
}

if (parm->peakrate.rate) {
P_tab = qdisc_get_rtab(&parm->peakrate,
tb[TCA_POLICE_PEAKRATE]);
Expand Down

0 comments on commit c1b5687

Please sign in to comment.