diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-11-28 22:40:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-29 13:17:03 -0500 |
commit | 11fca931d35a34d01ce209eb8d51ff667c9f5e7c (patch) | |
tree | 540b10f69a7a6c5249674cc1c67f231443fb6c47 /net/sched | |
parent | f07d960df33c5aef8f513efce0fd201f962f94a1 (diff) |
sch_sfq: use skb_flow_dissect()
Instead of using a custom flow dissector, use skb_flow_dissect() and
benefit from tunnelling support.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/sch_sfq.c | 65 |
1 files changed, 10 insertions, 55 deletions
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 4f5510e2bd6f..30cda707e400 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -17,14 +17,13 @@ | |||
17 | #include <linux/in.h> | 17 | #include <linux/in.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/ipv6.h> | ||
21 | #include <linux/skbuff.h> | 20 | #include <linux/skbuff.h> |
22 | #include <linux/jhash.h> | 21 | #include <linux/jhash.h> |
23 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
24 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
25 | #include <net/ip.h> | ||
26 | #include <net/netlink.h> | 24 | #include <net/netlink.h> |
27 | #include <net/pkt_sched.h> | 25 | #include <net/pkt_sched.h> |
26 | #include <net/flow_keys.h> | ||
28 | 27 | ||
29 | 28 | ||
30 | /* Stochastic Fairness Queuing algorithm. | 29 | /* Stochastic Fairness Queuing algorithm. |
@@ -137,61 +136,17 @@ static inline struct sfq_head *sfq_dep_head(struct sfq_sched_data *q, sfq_index | |||
137 | return &q->dep[val - SFQ_SLOTS]; | 136 | return &q->dep[val - SFQ_SLOTS]; |
138 | } | 137 | } |
139 | 138 | ||
140 | static unsigned int sfq_fold_hash(struct sfq_sched_data *q, u32 h, u32 h1) | 139 | static unsigned int sfq_hash(const struct sfq_sched_data *q, |
140 | const struct sk_buff *skb) | ||
141 | { | 141 | { |
142 | return jhash_2words(h, h1, q->perturbation) & (q->divisor - 1); | 142 | struct flow_keys keys; |
143 | } | 143 | unsigned int hash; |
144 | |||
145 | static unsigned int sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | ||
146 | { | ||
147 | u32 h, h2; | ||
148 | |||
149 | switch (skb->protocol) { | ||
150 | case htons(ETH_P_IP): | ||
151 | { | ||
152 | const struct iphdr *iph; | ||
153 | int poff; | ||
154 | |||
155 | if (!pskb_network_may_pull(skb, sizeof(*iph))) | ||
156 | goto err; | ||
157 | iph = ip_hdr(skb); | ||
158 | h = (__force u32)iph->daddr; | ||
159 | h2 = (__force u32)iph->saddr ^ iph->protocol; | ||
160 | if (ip_is_fragment(iph)) | ||
161 | break; | ||
162 | poff = proto_ports_offset(iph->protocol); | ||
163 | if (poff >= 0 && | ||
164 | pskb_network_may_pull(skb, iph->ihl * 4 + 4 + poff)) { | ||
165 | iph = ip_hdr(skb); | ||
166 | h2 ^= *(u32 *)((void *)iph + iph->ihl * 4 + poff); | ||
167 | } | ||
168 | break; | ||
169 | } | ||
170 | case htons(ETH_P_IPV6): | ||
171 | { | ||
172 | const struct ipv6hdr *iph; | ||
173 | int poff; | ||
174 | |||
175 | if (!pskb_network_may_pull(skb, sizeof(*iph))) | ||
176 | goto err; | ||
177 | iph = ipv6_hdr(skb); | ||
178 | h = (__force u32)iph->daddr.s6_addr32[3]; | ||
179 | h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; | ||
180 | poff = proto_ports_offset(iph->nexthdr); | ||
181 | if (poff >= 0 && | ||
182 | pskb_network_may_pull(skb, sizeof(*iph) + 4 + poff)) { | ||
183 | iph = ipv6_hdr(skb); | ||
184 | h2 ^= *(u32 *)((void *)iph + sizeof(*iph) + poff); | ||
185 | } | ||
186 | break; | ||
187 | } | ||
188 | default: | ||
189 | err: | ||
190 | h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol; | ||
191 | h2 = (unsigned long)skb->sk; | ||
192 | } | ||
193 | 144 | ||
194 | return sfq_fold_hash(q, h, h2); | 145 | skb_flow_dissect(skb, &keys); |
146 | hash = jhash_3words((__force u32)keys.dst, | ||
147 | (__force u32)keys.src ^ keys.ip_proto, | ||
148 | (__force u32)keys.ports, q->perturbation); | ||
149 | return hash & (q->divisor - 1); | ||
195 | } | 150 | } |
196 | 151 | ||
197 | static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch, | 152 | static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch, |