mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
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>
This commit is contained in:
parent
8d8bdfe803
commit
9ecd04bc04
1 changed files with 17 additions and 10 deletions
|
@ -152,15 +152,14 @@ static bool choke_match_flow(struct sk_buff *skb1,
|
|||
{
|
||||
int off1, off2, poff;
|
||||
const u32 *ports1, *ports2;
|
||||
u32 _ports1, _ports2;
|
||||
u8 ip_proto;
|
||||
__u32 hash1;
|
||||
|
||||
if (skb1->protocol != skb2->protocol)
|
||||
return false;
|
||||
|
||||
/* Use hash value as quick check
|
||||
* Assumes that __skb_get_rxhash makes IP header and ports linear
|
||||
*/
|
||||
/* Use rxhash value as quick check */
|
||||
hash1 = skb_get_rxhash(skb1);
|
||||
if (!hash1 || hash1 != skb_get_rxhash(skb2))
|
||||
return false;
|
||||
|
@ -172,10 +171,12 @@ static bool choke_match_flow(struct sk_buff *skb1,
|
|||
switch (skb1->protocol) {
|
||||
case __constant_htons(ETH_P_IP): {
|
||||
const struct iphdr *ip1, *ip2;
|
||||
struct iphdr _ip1, _ip2;
|
||||
|
||||
ip1 = (const struct iphdr *) (skb1->data + off1);
|
||||
ip2 = (const struct iphdr *) (skb2->data + off2);
|
||||
|
||||
ip1 = skb_header_pointer(skb1, off1, sizeof(_ip1), &_ip1);
|
||||
ip2 = skb_header_pointer(skb2, off2, sizeof(_ip2), &_ip2);
|
||||
if (!ip1 || !ip2)
|
||||
return false;
|
||||
ip_proto = ip1->protocol;
|
||||
if (ip_proto != ip2->protocol ||
|
||||
ip1->saddr != ip2->saddr || ip1->daddr != ip2->daddr)
|
||||
|
@ -190,9 +191,12 @@ static bool choke_match_flow(struct sk_buff *skb1,
|
|||
|
||||
case __constant_htons(ETH_P_IPV6): {
|
||||
const struct ipv6hdr *ip1, *ip2;
|
||||
struct ipv6hdr _ip1, _ip2;
|
||||
|
||||
ip1 = (const struct ipv6hdr *) (skb1->data + off1);
|
||||
ip2 = (const struct ipv6hdr *) (skb2->data + off2);
|
||||
ip1 = skb_header_pointer(skb1, off1, sizeof(_ip1), &_ip1);
|
||||
ip2 = skb_header_pointer(skb2, off2, sizeof(_ip2), &_ip2);
|
||||
if (!ip1 || !ip2)
|
||||
return false;
|
||||
|
||||
ip_proto = ip1->nexthdr;
|
||||
if (ip_proto != ip2->nexthdr ||
|
||||
|
@ -214,8 +218,11 @@ static bool choke_match_flow(struct sk_buff *skb1,
|
|||
off1 += poff;
|
||||
off2 += poff;
|
||||
|
||||
ports1 = (__force u32 *)(skb1->data + off1);
|
||||
ports2 = (__force u32 *)(skb2->data + off2);
|
||||
ports1 = skb_header_pointer(skb1, off1, sizeof(_ports1), &_ports1);
|
||||
ports2 = skb_header_pointer(skb2, off2, sizeof(_ports2), &_ports2);
|
||||
if (!ports1 || !ports2)
|
||||
return false;
|
||||
|
||||
return *ports1 == *ports2;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue