[PATCH] policing for sch_prio (2.4,2.5)

From: Werner Almesberger (wa@almesberger.net)
Date: Fri Jun 21 2002 - 03:39:51 EST


I've attached a little patch that adds support for policing to the
"prio" queuing discipline (all other classful queuing disciplines
already support policing - "prio" is the odd exception that
silently ignores policing).

This patch is for 2.4.19-pre8 (tested by simulation), but it also
works with 2.5.24 (tested in the real kernel), and it should work
with 2.4.19-pre10 (untested). I also ran it by Alexey a few weeks
ago and he didn't notice any obvious problems.

I'd recommend including this patch in 2.5. I don't know if it is
important enough to warrant application to 2.4 too, but it would
certainly be nice to have consistency.

- Werner

---------------------------------- cut here -----------------------------------

--- net/sched/sch_prio.c.orig Sun May 26 05:24:29 2002
+++ net/sched/sch_prio.c Sun May 26 05:58:38 2002
@@ -42,12 +42,14 @@
 {
         int bands;
         struct tcf_proto *filter_list;
+ struct Qdisc *last_dequeued; /* remember for prio_requeue */
         u8 prio2band[TC_PRIO_MAX+1];
         struct Qdisc *queues[TCQ_PRIO_BANDS];
 };
 
 
-static __inline__ unsigned prio_classify(struct sk_buff *skb, struct Qdisc *sch)
+static __inline__ struct Qdisc *prio_classify(struct sk_buff *skb,
+ struct Qdisc *sch)
 {
         struct prio_sched_data *q = (struct prio_sched_data *)sch->data;
         struct tcf_result res;
@@ -55,27 +57,34 @@
 
         band = skb->priority;
         if (TC_H_MAJ(skb->priority) != sch->handle) {
- if (!q->filter_list || tc_classify(skb, q->filter_list, &res)) {
- if (TC_H_MAJ(band))
- band = 0;
- return q->prio2band[band&TC_PRIO_MAX];
+ switch (q->filter_list ? tc_classify(skb, q->filter_list, &res)
+ : TC_POLICE_UNSPEC) {
+ case TC_POLICE_SHOT:
+ kfree_skb(skb);
+ return NULL;
+ case TC_POLICE_OK:
+ break;
+ default:
+ if (TC_H_MAJ(band))
+ band = 0;
+ return q->queues[
+ q->prio2band[band&TC_PRIO_MAX]];
                 }
                 band = res.classid;
         }
         band = TC_H_MIN(band) - 1;
- return band < q->bands ? band : q->prio2band[0];
+ return q->queues[band < q->bands ? band : q->prio2band[0]];
 }
 
 static int
 prio_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 {
- struct prio_sched_data *q = (struct prio_sched_data *)sch->data;
         struct Qdisc *qdisc;
- int ret;
+ int ret = NET_XMIT_POLICED;
 
- qdisc = q->queues[prio_classify(skb, sch)];
+ qdisc = prio_classify(skb, sch);
 
- if ((ret = qdisc->enqueue(skb, qdisc)) == 0) {
+ if (qdisc && (ret = qdisc->enqueue(skb, qdisc)) == 0) {
                 sch->stats.bytes += skb->len;
                 sch->stats.packets++;
                 sch->q.qlen++;
@@ -93,7 +102,7 @@
         struct Qdisc *qdisc;
         int ret;
 
- qdisc = q->queues[prio_classify(skb, sch)];
+ qdisc = q->last_dequeued;
 
         if ((ret = qdisc->ops->requeue(skb, qdisc)) == 0) {
                 sch->q.qlen++;
@@ -116,6 +125,7 @@
                 qdisc = q->queues[prio];
                 skb = qdisc->dequeue(qdisc);
                 if (skb) {
+ q->last_dequeued = qdisc;
                         sch->q.qlen--;
                         return skb;
                 }

-- 
  _________________________________________________________________________
 / Werner Almesberger, Buenos Aires, Argentina         wa@almesberger.net /
/_http://icapeople.epfl.ch/almesber/_____________________________________/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Jun 23 2002 - 22:00:24 EST