aboutsummaryrefslogtreecommitdiffstats
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.h150
1 files changed, 125 insertions, 25 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index becf86aa4ac6..e2ab13687fb9 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -71,6 +71,7 @@ struct Qdisc {
71 * qdisc_tree_decrease_qlen() should stop. 71 * qdisc_tree_decrease_qlen() should stop.
72 */ 72 */
73#define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */ 73#define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */
74#define TCQ_F_NOLOCK 0x100 /* qdisc does not require locking */
74#define TCQ_F_OFFLOADED 0x200 /* qdisc is offloaded to HW */ 75#define TCQ_F_OFFLOADED 0x200 /* qdisc is offloaded to HW */
75 u32 limit; 76 u32 limit;
76 const struct Qdisc_ops *ops; 77 const struct Qdisc_ops *ops;
@@ -88,14 +89,14 @@ struct Qdisc {
88 /* 89 /*
89 * For performance sake on SMP, we put highly modified fields at the end 90 * For performance sake on SMP, we put highly modified fields at the end
90 */ 91 */
91 struct sk_buff *gso_skb ____cacheline_aligned_in_smp; 92 struct sk_buff_head gso_skb ____cacheline_aligned_in_smp;
92 struct qdisc_skb_head q; 93 struct qdisc_skb_head q;
93 struct gnet_stats_basic_packed bstats; 94 struct gnet_stats_basic_packed bstats;
94 seqcount_t running; 95 seqcount_t running;
95 struct gnet_stats_queue qstats; 96 struct gnet_stats_queue qstats;
96 unsigned long state; 97 unsigned long state;
97 struct Qdisc *next_sched; 98 struct Qdisc *next_sched;
98 struct sk_buff *skb_bad_txq; 99 struct sk_buff_head skb_bad_txq;
99 int padded; 100 int padded;
100 refcount_t refcnt; 101 refcount_t refcnt;
101 102
@@ -150,19 +151,23 @@ struct Qdisc_class_ops {
150 /* Child qdisc manipulation */ 151 /* Child qdisc manipulation */
151 struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); 152 struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *);
152 int (*graft)(struct Qdisc *, unsigned long cl, 153 int (*graft)(struct Qdisc *, unsigned long cl,
153 struct Qdisc *, struct Qdisc **); 154 struct Qdisc *, struct Qdisc **,
155 struct netlink_ext_ack *extack);
154 struct Qdisc * (*leaf)(struct Qdisc *, unsigned long cl); 156 struct Qdisc * (*leaf)(struct Qdisc *, unsigned long cl);
155 void (*qlen_notify)(struct Qdisc *, unsigned long); 157 void (*qlen_notify)(struct Qdisc *, unsigned long);
156 158
157 /* Class manipulation routines */ 159 /* Class manipulation routines */
158 unsigned long (*find)(struct Qdisc *, u32 classid); 160 unsigned long (*find)(struct Qdisc *, u32 classid);
159 int (*change)(struct Qdisc *, u32, u32, 161 int (*change)(struct Qdisc *, u32, u32,
160 struct nlattr **, unsigned long *); 162 struct nlattr **, unsigned long *,
163 struct netlink_ext_ack *);
161 int (*delete)(struct Qdisc *, unsigned long); 164 int (*delete)(struct Qdisc *, unsigned long);
162 void (*walk)(struct Qdisc *, struct qdisc_walker * arg); 165 void (*walk)(struct Qdisc *, struct qdisc_walker * arg);
163 166
164 /* Filter manipulation */ 167 /* Filter manipulation */
165 struct tcf_block * (*tcf_block)(struct Qdisc *, unsigned long); 168 struct tcf_block * (*tcf_block)(struct Qdisc *sch,
169 unsigned long arg,
170 struct netlink_ext_ack *extack);
166 unsigned long (*bind_tcf)(struct Qdisc *, unsigned long, 171 unsigned long (*bind_tcf)(struct Qdisc *, unsigned long,
167 u32 classid); 172 u32 classid);
168 void (*unbind_tcf)(struct Qdisc *, unsigned long); 173 void (*unbind_tcf)(struct Qdisc *, unsigned long);
@@ -187,15 +192,26 @@ struct Qdisc_ops {
187 struct sk_buff * (*dequeue)(struct Qdisc *); 192 struct sk_buff * (*dequeue)(struct Qdisc *);
188 struct sk_buff * (*peek)(struct Qdisc *); 193 struct sk_buff * (*peek)(struct Qdisc *);
189 194
190 int (*init)(struct Qdisc *, struct nlattr *arg); 195 int (*init)(struct Qdisc *sch, struct nlattr *arg,
196 struct netlink_ext_ack *extack);
191 void (*reset)(struct Qdisc *); 197 void (*reset)(struct Qdisc *);
192 void (*destroy)(struct Qdisc *); 198 void (*destroy)(struct Qdisc *);
193 int (*change)(struct Qdisc *, struct nlattr *arg); 199 int (*change)(struct Qdisc *sch,
194 void (*attach)(struct Qdisc *); 200 struct nlattr *arg,
201 struct netlink_ext_ack *extack);
202 void (*attach)(struct Qdisc *sch);
203 int (*change_tx_queue_len)(struct Qdisc *, unsigned int);
195 204
196 int (*dump)(struct Qdisc *, struct sk_buff *); 205 int (*dump)(struct Qdisc *, struct sk_buff *);
197 int (*dump_stats)(struct Qdisc *, struct gnet_dump *); 206 int (*dump_stats)(struct Qdisc *, struct gnet_dump *);
198 207
208 void (*ingress_block_set)(struct Qdisc *sch,
209 u32 block_index);
210 void (*egress_block_set)(struct Qdisc *sch,
211 u32 block_index);
212 u32 (*ingress_block_get)(struct Qdisc *sch);
213 u32 (*egress_block_get)(struct Qdisc *sch);
214
199 struct module *owner; 215 struct module *owner;
200}; 216};
201 217
@@ -218,14 +234,18 @@ struct tcf_proto_ops {
218 const struct tcf_proto *, 234 const struct tcf_proto *,
219 struct tcf_result *); 235 struct tcf_result *);
220 int (*init)(struct tcf_proto*); 236 int (*init)(struct tcf_proto*);
221 void (*destroy)(struct tcf_proto*); 237 void (*destroy)(struct tcf_proto *tp,
238 struct netlink_ext_ack *extack);
222 239
223 void* (*get)(struct tcf_proto*, u32 handle); 240 void* (*get)(struct tcf_proto*, u32 handle);
224 int (*change)(struct net *net, struct sk_buff *, 241 int (*change)(struct net *net, struct sk_buff *,
225 struct tcf_proto*, unsigned long, 242 struct tcf_proto*, unsigned long,
226 u32 handle, struct nlattr **, 243 u32 handle, struct nlattr **,
227 void **, bool); 244 void **, bool,
228 int (*delete)(struct tcf_proto*, void *, bool*); 245 struct netlink_ext_ack *);
246 int (*delete)(struct tcf_proto *tp, void *arg,
247 bool *last,
248 struct netlink_ext_ack *);
229 void (*walk)(struct tcf_proto*, struct tcf_walker *arg); 249 void (*walk)(struct tcf_proto*, struct tcf_walker *arg);
230 void (*bind_class)(void *, u32, unsigned long); 250 void (*bind_class)(void *, u32, unsigned long);
231 251
@@ -247,8 +267,6 @@ struct tcf_proto {
247 267
248 /* All the rest */ 268 /* All the rest */
249 u32 prio; 269 u32 prio;
250 u32 classid;
251 struct Qdisc *q;
252 void *data; 270 void *data;
253 const struct tcf_proto_ops *ops; 271 const struct tcf_proto_ops *ops;
254 struct tcf_chain *chain; 272 struct tcf_chain *chain;
@@ -267,8 +285,7 @@ typedef void tcf_chain_head_change_t(struct tcf_proto *tp_head, void *priv);
267 285
268struct tcf_chain { 286struct tcf_chain {
269 struct tcf_proto __rcu *filter_chain; 287 struct tcf_proto __rcu *filter_chain;
270 tcf_chain_head_change_t *chain_head_change; 288 struct list_head filter_chain_list;
271 void *chain_head_change_priv;
272 struct list_head list; 289 struct list_head list;
273 struct tcf_block *block; 290 struct tcf_block *block;
274 u32 index; /* chain index */ 291 u32 index; /* chain index */
@@ -277,12 +294,33 @@ struct tcf_chain {
277 294
278struct tcf_block { 295struct tcf_block {
279 struct list_head chain_list; 296 struct list_head chain_list;
297 u32 index; /* block index for shared blocks */
298 unsigned int refcnt;
280 struct net *net; 299 struct net *net;
281 struct Qdisc *q; 300 struct Qdisc *q;
282 struct list_head cb_list; 301 struct list_head cb_list;
283 struct work_struct work; 302 struct list_head owner_list;
303 bool keep_dst;
304 unsigned int offloadcnt; /* Number of oddloaded filters */
305 unsigned int nooffloaddevcnt; /* Number of devs unable to do offload */
284}; 306};
285 307
308static inline void tcf_block_offload_inc(struct tcf_block *block, u32 *flags)
309{
310 if (*flags & TCA_CLS_FLAGS_IN_HW)
311 return;
312 *flags |= TCA_CLS_FLAGS_IN_HW;
313 block->offloadcnt++;
314}
315
316static inline void tcf_block_offload_dec(struct tcf_block *block, u32 *flags)
317{
318 if (!(*flags & TCA_CLS_FLAGS_IN_HW))
319 return;
320 *flags &= ~TCA_CLS_FLAGS_IN_HW;
321 block->offloadcnt--;
322}
323
286static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz) 324static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
287{ 325{
288 struct qdisc_skb_cb *qcb; 326 struct qdisc_skb_cb *qcb;
@@ -291,11 +329,31 @@ static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
291 BUILD_BUG_ON(sizeof(qcb->data) < sz); 329 BUILD_BUG_ON(sizeof(qcb->data) < sz);
292} 330}
293 331
332static inline int qdisc_qlen_cpu(const struct Qdisc *q)
333{
334 return this_cpu_ptr(q->cpu_qstats)->qlen;
335}
336
294static inline int qdisc_qlen(const struct Qdisc *q) 337static inline int qdisc_qlen(const struct Qdisc *q)
295{ 338{
296 return q->q.qlen; 339 return q->q.qlen;
297} 340}
298 341
342static inline int qdisc_qlen_sum(const struct Qdisc *q)
343{
344 __u32 qlen = 0;
345 int i;
346
347 if (q->flags & TCQ_F_NOLOCK) {
348 for_each_possible_cpu(i)
349 qlen += per_cpu_ptr(q->cpu_qstats, i)->qlen;
350 } else {
351 qlen = q->q.qlen;
352 }
353
354 return qlen;
355}
356
299static inline struct qdisc_skb_cb *qdisc_skb_cb(const struct sk_buff *skb) 357static inline struct qdisc_skb_cb *qdisc_skb_cb(const struct sk_buff *skb)
300{ 358{
301 return (struct qdisc_skb_cb *)skb->cb; 359 return (struct qdisc_skb_cb *)skb->cb;
@@ -432,6 +490,7 @@ void qdisc_class_hash_remove(struct Qdisc_class_hash *,
432void qdisc_class_hash_grow(struct Qdisc *, struct Qdisc_class_hash *); 490void qdisc_class_hash_grow(struct Qdisc *, struct Qdisc_class_hash *);
433void qdisc_class_hash_destroy(struct Qdisc_class_hash *); 491void qdisc_class_hash_destroy(struct Qdisc_class_hash *);
434 492
493int dev_qdisc_change_tx_queue_len(struct net_device *dev);
435void dev_init_scheduler(struct net_device *dev); 494void dev_init_scheduler(struct net_device *dev);
436void dev_shutdown(struct net_device *dev); 495void dev_shutdown(struct net_device *dev);
437void dev_activate(struct net_device *dev); 496void dev_activate(struct net_device *dev);
@@ -444,10 +503,12 @@ void qdisc_destroy(struct Qdisc *qdisc);
444void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, unsigned int n, 503void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, unsigned int n,
445 unsigned int len); 504 unsigned int len);
446struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, 505struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
447 const struct Qdisc_ops *ops); 506 const struct Qdisc_ops *ops,
507 struct netlink_ext_ack *extack);
448void qdisc_free(struct Qdisc *qdisc); 508void qdisc_free(struct Qdisc *qdisc);
449struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, 509struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
450 const struct Qdisc_ops *ops, u32 parentid); 510 const struct Qdisc_ops *ops, u32 parentid,
511 struct netlink_ext_ack *extack);
451void __qdisc_calculate_pkt_len(struct sk_buff *skb, 512void __qdisc_calculate_pkt_len(struct sk_buff *skb,
452 const struct qdisc_size_table *stab); 513 const struct qdisc_size_table *stab);
453int skb_do_redirect(struct sk_buff *); 514int skb_do_redirect(struct sk_buff *);
@@ -633,12 +694,39 @@ static inline void qdisc_qstats_backlog_dec(struct Qdisc *sch,
633 sch->qstats.backlog -= qdisc_pkt_len(skb); 694 sch->qstats.backlog -= qdisc_pkt_len(skb);
634} 695}
635 696
697static inline void qdisc_qstats_cpu_backlog_dec(struct Qdisc *sch,
698 const struct sk_buff *skb)
699{
700 this_cpu_sub(sch->cpu_qstats->backlog, qdisc_pkt_len(skb));
701}
702
636static inline void qdisc_qstats_backlog_inc(struct Qdisc *sch, 703static inline void qdisc_qstats_backlog_inc(struct Qdisc *sch,
637 const struct sk_buff *skb) 704 const struct sk_buff *skb)
638{ 705{
639 sch->qstats.backlog += qdisc_pkt_len(skb); 706 sch->qstats.backlog += qdisc_pkt_len(skb);
640} 707}
641 708
709static inline void qdisc_qstats_cpu_backlog_inc(struct Qdisc *sch,
710 const struct sk_buff *skb)
711{
712 this_cpu_add(sch->cpu_qstats->backlog, qdisc_pkt_len(skb));
713}
714
715static inline void qdisc_qstats_cpu_qlen_inc(struct Qdisc *sch)
716{
717 this_cpu_inc(sch->cpu_qstats->qlen);
718}
719
720static inline void qdisc_qstats_cpu_qlen_dec(struct Qdisc *sch)
721{
722 this_cpu_dec(sch->cpu_qstats->qlen);
723}
724
725static inline void qdisc_qstats_cpu_requeues_inc(struct Qdisc *sch)
726{
727 this_cpu_inc(sch->cpu_qstats->requeues);
728}
729
642static inline void __qdisc_qstats_drop(struct Qdisc *sch, int count) 730static inline void __qdisc_qstats_drop(struct Qdisc *sch, int count)
643{ 731{
644 sch->qstats.drops += count; 732 sch->qstats.drops += count;
@@ -769,26 +857,30 @@ static inline struct sk_buff *qdisc_peek_head(struct Qdisc *sch)
769/* generic pseudo peek method for non-work-conserving qdisc */ 857/* generic pseudo peek method for non-work-conserving qdisc */
770static inline struct sk_buff *qdisc_peek_dequeued(struct Qdisc *sch) 858static inline struct sk_buff *qdisc_peek_dequeued(struct Qdisc *sch)
771{ 859{
860 struct sk_buff *skb = skb_peek(&sch->gso_skb);
861
772 /* we can reuse ->gso_skb because peek isn't called for root qdiscs */ 862 /* we can reuse ->gso_skb because peek isn't called for root qdiscs */
773 if (!sch->gso_skb) { 863 if (!skb) {
774 sch->gso_skb = sch->dequeue(sch); 864 skb = sch->dequeue(sch);
775 if (sch->gso_skb) { 865
866 if (skb) {
867 __skb_queue_head(&sch->gso_skb, skb);
776 /* it's still part of the queue */ 868 /* it's still part of the queue */
777 qdisc_qstats_backlog_inc(sch, sch->gso_skb); 869 qdisc_qstats_backlog_inc(sch, skb);
778 sch->q.qlen++; 870 sch->q.qlen++;
779 } 871 }
780 } 872 }
781 873
782 return sch->gso_skb; 874 return skb;
783} 875}
784 876
785/* use instead of qdisc->dequeue() for all qdiscs queried with ->peek() */ 877/* use instead of qdisc->dequeue() for all qdiscs queried with ->peek() */
786static inline struct sk_buff *qdisc_dequeue_peeked(struct Qdisc *sch) 878static inline struct sk_buff *qdisc_dequeue_peeked(struct Qdisc *sch)
787{ 879{
788 struct sk_buff *skb = sch->gso_skb; 880 struct sk_buff *skb = skb_peek(&sch->gso_skb);
789 881
790 if (skb) { 882 if (skb) {
791 sch->gso_skb = NULL; 883 skb = __skb_dequeue(&sch->gso_skb);
792 qdisc_qstats_backlog_dec(sch, skb); 884 qdisc_qstats_backlog_dec(sch, skb);
793 sch->q.qlen--; 885 sch->q.qlen--;
794 } else { 886 } else {
@@ -846,6 +938,14 @@ static inline void rtnl_qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
846 qdisc_qstats_drop(sch); 938 qdisc_qstats_drop(sch);
847} 939}
848 940
941static inline int qdisc_drop_cpu(struct sk_buff *skb, struct Qdisc *sch,
942 struct sk_buff **to_free)
943{
944 __qdisc_drop(skb, to_free);
945 qdisc_qstats_cpu_drop(sch);
946
947 return NET_XMIT_DROP;
948}
849 949
850static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch, 950static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch,
851 struct sk_buff **to_free) 951 struct sk_buff **to_free)