Root/
1 | /* |
2 | * net/dccp/qpolicy.c |
3 | * |
4 | * Policy-based packet dequeueing interface for DCCP. |
5 | * |
6 | * Copyright (c) 2008 Tomasz Grobelny <tomasz@grobelny.oswiecenia.net> |
7 | * |
8 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License v2 |
10 | * as published by the Free Software Foundation. |
11 | */ |
12 | #include "dccp.h" |
13 | |
14 | /* |
15 | * Simple Dequeueing Policy: |
16 | * If tx_qlen is different from 0, enqueue up to tx_qlen elements. |
17 | */ |
18 | static void qpolicy_simple_push(struct sock *sk, struct sk_buff *skb) |
19 | { |
20 | skb_queue_tail(&sk->sk_write_queue, skb); |
21 | } |
22 | |
23 | static bool qpolicy_simple_full(struct sock *sk) |
24 | { |
25 | return dccp_sk(sk)->dccps_tx_qlen && |
26 | sk->sk_write_queue.qlen >= dccp_sk(sk)->dccps_tx_qlen; |
27 | } |
28 | |
29 | static struct sk_buff *qpolicy_simple_top(struct sock *sk) |
30 | { |
31 | return skb_peek(&sk->sk_write_queue); |
32 | } |
33 | |
34 | /* |
35 | * Priority-based Dequeueing Policy: |
36 | * If tx_qlen is different from 0 and the queue has reached its upper bound |
37 | * of tx_qlen elements, replace older packets lowest-priority-first. |
38 | */ |
39 | static struct sk_buff *qpolicy_prio_best_skb(struct sock *sk) |
40 | { |
41 | struct sk_buff *skb, *best = NULL; |
42 | |
43 | skb_queue_walk(&sk->sk_write_queue, skb) |
44 | if (best == NULL || skb->priority > best->priority) |
45 | best = skb; |
46 | return best; |
47 | } |
48 | |
49 | static struct sk_buff *qpolicy_prio_worst_skb(struct sock *sk) |
50 | { |
51 | struct sk_buff *skb, *worst = NULL; |
52 | |
53 | skb_queue_walk(&sk->sk_write_queue, skb) |
54 | if (worst == NULL || skb->priority < worst->priority) |
55 | worst = skb; |
56 | return worst; |
57 | } |
58 | |
59 | static bool qpolicy_prio_full(struct sock *sk) |
60 | { |
61 | if (qpolicy_simple_full(sk)) |
62 | dccp_qpolicy_drop(sk, qpolicy_prio_worst_skb(sk)); |
63 | return false; |
64 | } |
65 | |
66 | /** |
67 | * struct dccp_qpolicy_operations - TX Packet Dequeueing Interface |
68 | * @push: add a new @skb to the write queue |
69 | * @full: indicates that no more packets will be admitted |
70 | * @top: peeks at whatever the queueing policy defines as its `top' |
71 | */ |
72 | static struct dccp_qpolicy_operations { |
73 | void (*push) (struct sock *sk, struct sk_buff *skb); |
74 | bool (*full) (struct sock *sk); |
75 | struct sk_buff* (*top) (struct sock *sk); |
76 | __be32 params; |
77 | |
78 | } qpol_table[DCCPQ_POLICY_MAX] = { |
79 | [DCCPQ_POLICY_SIMPLE] = { |
80 | .push = qpolicy_simple_push, |
81 | .full = qpolicy_simple_full, |
82 | .top = qpolicy_simple_top, |
83 | .params = 0, |
84 | }, |
85 | [DCCPQ_POLICY_PRIO] = { |
86 | .push = qpolicy_simple_push, |
87 | .full = qpolicy_prio_full, |
88 | .top = qpolicy_prio_best_skb, |
89 | .params = DCCP_SCM_PRIORITY, |
90 | }, |
91 | }; |
92 | |
93 | /* |
94 | * Externally visible interface |
95 | */ |
96 | void dccp_qpolicy_push(struct sock *sk, struct sk_buff *skb) |
97 | { |
98 | qpol_table[dccp_sk(sk)->dccps_qpolicy].push(sk, skb); |
99 | } |
100 | |
101 | bool dccp_qpolicy_full(struct sock *sk) |
102 | { |
103 | return qpol_table[dccp_sk(sk)->dccps_qpolicy].full(sk); |
104 | } |
105 | |
106 | void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb) |
107 | { |
108 | if (skb != NULL) { |
109 | skb_unlink(skb, &sk->sk_write_queue); |
110 | kfree_skb(skb); |
111 | } |
112 | } |
113 | |
114 | struct sk_buff *dccp_qpolicy_top(struct sock *sk) |
115 | { |
116 | return qpol_table[dccp_sk(sk)->dccps_qpolicy].top(sk); |
117 | } |
118 | |
119 | struct sk_buff *dccp_qpolicy_pop(struct sock *sk) |
120 | { |
121 | struct sk_buff *skb = dccp_qpolicy_top(sk); |
122 | |
123 | if (skb != NULL) { |
124 | /* Clear any skb fields that we used internally */ |
125 | skb->priority = 0; |
126 | skb_unlink(skb, &sk->sk_write_queue); |
127 | } |
128 | return skb; |
129 | } |
130 | |
131 | bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param) |
132 | { |
133 | /* check if exactly one bit is set */ |
134 | if (!param || (param & (param - 1))) |
135 | return false; |
136 | return (qpol_table[dccp_sk(sk)->dccps_qpolicy].params & param) == param; |
137 | } |
138 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9