summaryrefslogtreecommitdiffstats
path: root/include/net/sch_generic.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/sch_generic.h')
-rw-r--r--include/net/sch_generic.h35
1 files changed, 35 insertions, 0 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 3fe49d8..64ae1ba 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -111,6 +111,7 @@ struct Qdisc_ops
int (*enqueue)(struct sk_buff *, struct Qdisc *);
struct sk_buff * (*dequeue)(struct Qdisc *);
+ struct sk_buff * (*peek)(struct Qdisc *);
int (*requeue)(struct sk_buff *, struct Qdisc *);
unsigned int (*drop)(struct Qdisc *);
@@ -432,6 +433,40 @@ static inline struct sk_buff *qdisc_dequeue_tail(struct Qdisc *sch)
return __qdisc_dequeue_tail(sch, &sch->q);
}
+static inline struct sk_buff *qdisc_peek_head(struct Qdisc *sch)
+{
+ return skb_peek(&sch->q);
+}
+
+/* generic pseudo peek method for non-work-conserving qdisc */
+static inline struct sk_buff *qdisc_peek_dequeued(struct Qdisc *sch)
+{
+ /* we can reuse ->gso_skb because peek isn't called for root qdiscs */
+ if (!sch->gso_skb) {
+ sch->gso_skb = sch->dequeue(sch);
+ if (sch->gso_skb)
+ /* it's still part of the queue */
+ sch->q.qlen++;
+ }
+
+ return sch->gso_skb;
+}
+
+/* use instead of qdisc->dequeue() for all qdiscs queried with ->peek() */
+static inline struct sk_buff *qdisc_dequeue_peeked(struct Qdisc *sch)
+{
+ struct sk_buff *skb = sch->gso_skb;
+
+ if (skb) {
+ sch->gso_skb = NULL;
+ sch->q.qlen--;
+ } else {
+ skb = sch->dequeue(sch);
+ }
+
+ return skb;
+}
+
static inline int __qdisc_requeue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff_head *list)
{
OpenPOWER on IntegriCloud