Skip to content

Commit 9ecd04b

Browse files
Eric Dumazetdavem330
authored andcommitted
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>
1 parent 8d8bdfe commit 9ecd04b

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

net/sched/sch_choke.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,14 @@ static bool choke_match_flow(struct sk_buff *skb1,
152152
{
153153
int off1, off2, poff;
154154
const u32 *ports1, *ports2;
155+
u32 _ports1, _ports2;
155156
u8 ip_proto;
156157
__u32 hash1;
157158

158159
if (skb1->protocol != skb2->protocol)
159160
return false;
160161

161-
/* Use hash value as quick check
162-
* Assumes that __skb_get_rxhash makes IP header and ports linear
163-
*/
162+
/* Use rxhash value as quick check */
164163
hash1 = skb_get_rxhash(skb1);
165164
if (!hash1 || hash1 != skb_get_rxhash(skb2))
166165
return false;
@@ -172,10 +171,12 @@ static bool choke_match_flow(struct sk_buff *skb1,
172171
switch (skb1->protocol) {
173172
case __constant_htons(ETH_P_IP): {
174173
const struct iphdr *ip1, *ip2;
174+
struct iphdr _ip1, _ip2;
175175

176-
ip1 = (const struct iphdr *) (skb1->data + off1);
177-
ip2 = (const struct iphdr *) (skb2->data + off2);
178-
176+
ip1 = skb_header_pointer(skb1, off1, sizeof(_ip1), &_ip1);
177+
ip2 = skb_header_pointer(skb2, off2, sizeof(_ip2), &_ip2);
178+
if (!ip1 || !ip2)
179+
return false;
179180
ip_proto = ip1->protocol;
180181
if (ip_proto != ip2->protocol ||
181182
ip1->saddr != ip2->saddr || ip1->daddr != ip2->daddr)
@@ -190,9 +191,12 @@ static bool choke_match_flow(struct sk_buff *skb1,
190191

191192
case __constant_htons(ETH_P_IPV6): {
192193
const struct ipv6hdr *ip1, *ip2;
194+
struct ipv6hdr _ip1, _ip2;
193195

194-
ip1 = (const struct ipv6hdr *) (skb1->data + off1);
195-
ip2 = (const struct ipv6hdr *) (skb2->data + off2);
196+
ip1 = skb_header_pointer(skb1, off1, sizeof(_ip1), &_ip1);
197+
ip2 = skb_header_pointer(skb2, off2, sizeof(_ip2), &_ip2);
198+
if (!ip1 || !ip2)
199+
return false;
196200

197201
ip_proto = ip1->nexthdr;
198202
if (ip_proto != ip2->nexthdr ||
@@ -214,8 +218,11 @@ static bool choke_match_flow(struct sk_buff *skb1,
214218
off1 += poff;
215219
off2 += poff;
216220

217-
ports1 = (__force u32 *)(skb1->data + off1);
218-
ports2 = (__force u32 *)(skb2->data + off2);
221+
ports1 = skb_header_pointer(skb1, off1, sizeof(_ports1), &_ports1);
222+
ports2 = skb_header_pointer(skb2, off2, sizeof(_ports2), &_ports2);
223+
if (!ports1 || !ports2)
224+
return false;
225+
219226
return *ports1 == *ports2;
220227
}
221228

0 commit comments

Comments
 (0)