diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-11-08 05:45:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-08 16:41:31 -0500 |
commit | 9ecd04bc04af7df98b3a93c571e31b6ef6a90681 (patch) | |
tree | 3850ea9ffad64f46cfa20ac7b9a2c8e0f4b56517 /net/sched | |
parent | 8d8bdfe8034399357df58b5f3e4da638a9e9a257 (diff) |
sch_choke: use skb_header_pointer()
Remove the assumption that skb_get_rxhash() makes IP header and ports
linear, and use skb_header_pointer() instead in choke_match_flow()
This permits __skb_get_rxhash() to use skb_header_pointer() eventually.
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_choke.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index 3422b25df9e4..061bcb744bbd 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c | |||
@@ -152,15 +152,14 @@ static bool choke_match_flow(struct sk_buff *skb1, | |||
152 | { | 152 | { |
153 | int off1, off2, poff; | 153 | int off1, off2, poff; |
154 | const u32 *ports1, *ports2; | 154 | const u32 *ports1, *ports2; |
155 | u32 _ports1, _ports2; | ||
155 | u8 ip_proto; | 156 | u8 ip_proto; |
156 | __u32 hash1; | 157 | __u32 hash1; |
157 | 158 | ||
158 | if (skb1->protocol != skb2->protocol) | 159 | if (skb1->protocol != skb2->protocol) |
159 | return false; | 160 | return false; |
160 | 161 | ||
161 | /* Use hash value as quick check | 162 | /* Use rxhash value as quick check */ |
162 | * Assumes that __skb_get_rxhash makes IP header and ports linear | ||
163 | */ | ||
164 | hash1 = skb_get_rxhash(skb1); | 163 | hash1 = skb_get_rxhash(skb1); |
165 | if (!hash1 || hash1 != skb_get_rxhash(skb2)) | 164 | if (!hash1 || hash1 != skb_get_rxhash(skb2)) |
166 | return false; | 165 | return false; |
@@ -172,10 +171,12 @@ static bool choke_match_flow(struct sk_buff *skb1, | |||
172 | switch (skb1->protocol) { | 171 | switch (skb1->protocol) { |
173 | case __constant_htons(ETH_P_IP): { | 172 | case __constant_htons(ETH_P_IP): { |
174 | const struct iphdr *ip1, *ip2; | 173 | const struct iphdr *ip1, *ip2; |
174 | struct iphdr _ip1, _ip2; | ||
175 | 175 | ||
176 | ip1 = (const struct iphdr *) (skb1->data + off1); | 176 | ip1 = skb_header_pointer(skb1, off1, sizeof(_ip1), &_ip1); |
177 | ip2 = (const struct iphdr *) (skb2->data + off2); | 177 | ip2 = skb_header_pointer(skb2, off2, sizeof(_ip2), &_ip2); |
178 | 178 | if (!ip1 || !ip2) | |
179 | return false; | ||
179 | ip_proto = ip1->protocol; | 180 | ip_proto = ip1->protocol; |
180 | if (ip_proto != ip2->protocol || | 181 | if (ip_proto != ip2->protocol || |
181 | ip1->saddr != ip2->saddr || ip1->daddr != ip2->daddr) | 182 | ip1->saddr != ip2->saddr || ip1->daddr != ip2->daddr) |
@@ -190,9 +191,12 @@ static bool choke_match_flow(struct sk_buff *skb1, | |||
190 | 191 | ||
191 | case __constant_htons(ETH_P_IPV6): { | 192 | case __constant_htons(ETH_P_IPV6): { |
192 | const struct ipv6hdr *ip1, *ip2; | 193 | const struct ipv6hdr *ip1, *ip2; |
194 | struct ipv6hdr _ip1, _ip2; | ||
193 | 195 | ||
194 | ip1 = (const struct ipv6hdr *) (skb1->data + off1); | 196 | ip1 = skb_header_pointer(skb1, off1, sizeof(_ip1), &_ip1); |
195 | ip2 = (const struct ipv6hdr *) (skb2->data + off2); | 197 | ip2 = skb_header_pointer(skb2, off2, sizeof(_ip2), &_ip2); |
198 | if (!ip1 || !ip2) | ||
199 | return false; | ||
196 | 200 | ||
197 | ip_proto = ip1->nexthdr; | 201 | ip_proto = ip1->nexthdr; |
198 | if (ip_proto != ip2->nexthdr || | 202 | if (ip_proto != ip2->nexthdr || |
@@ -214,8 +218,11 @@ static bool choke_match_flow(struct sk_buff *skb1, | |||
214 | off1 += poff; | 218 | off1 += poff; |
215 | off2 += poff; | 219 | off2 += poff; |
216 | 220 | ||
217 | ports1 = (__force u32 *)(skb1->data + off1); | 221 | ports1 = skb_header_pointer(skb1, off1, sizeof(_ports1), &_ports1); |
218 | ports2 = (__force u32 *)(skb2->data + off2); | 222 | ports2 = skb_header_pointer(skb2, off2, sizeof(_ports2), &_ports2); |
223 | if (!ports1 || !ports2) | ||
224 | return false; | ||
225 | |||
219 | return *ports1 == *ports2; | 226 | return *ports1 == *ports2; |
220 | } | 227 | } |
221 | 228 | ||