net_sched: sch_sfq: use proto_ports_offset() to support AH message
authorChangli Gao <xiaosuo@gmail.com>
Tue, 17 Aug 2010 19:07:35 +0000 (19:07 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Aug 2010 00:16:25 +0000 (17:16 -0700)
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sched/sch_sfq.c

index 201cbac2b32ce0ccd8375b066005b6ba69759ddd..3cf478d012dd4f29b7a67f951c2cfa901b64248f 100644 (file)
@@ -123,40 +123,39 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
        case htons(ETH_P_IP):
        {
                const struct iphdr *iph;
+               int poff;
 
                if (!pskb_network_may_pull(skb, sizeof(*iph)))
                        goto err;
                iph = ip_hdr(skb);
                h = (__force u32)iph->daddr;
                h2 = (__force u32)iph->saddr ^ iph->protocol;
-               if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
-                   (iph->protocol == IPPROTO_TCP ||
-                    iph->protocol == IPPROTO_UDP ||
-                    iph->protocol == IPPROTO_UDPLITE ||
-                    iph->protocol == IPPROTO_SCTP ||
-                    iph->protocol == IPPROTO_DCCP ||
-                    iph->protocol == IPPROTO_ESP) &&
-                    pskb_network_may_pull(skb, iph->ihl * 4 + 4))
-                       h2 ^= *(((u32*)iph) + iph->ihl);
+               if (iph->frag_off & htons(IP_MF|IP_OFFSET))
+                       break;
+               poff = proto_ports_offset(iph->protocol);
+               if (poff >= 0 &&
+                   pskb_network_may_pull(skb, iph->ihl * 4 + 4 + poff)) {
+                       iph = ip_hdr(skb);
+                       h2 ^= *(u32*)((void *)iph + iph->ihl * 4 + poff);
+               }
                break;
        }
        case htons(ETH_P_IPV6):
        {
                struct ipv6hdr *iph;
+               int poff;
 
                if (!pskb_network_may_pull(skb, sizeof(*iph)))
                        goto err;
                iph = ipv6_hdr(skb);
                h = (__force u32)iph->daddr.s6_addr32[3];
                h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr;
-               if ((iph->nexthdr == IPPROTO_TCP ||
-                    iph->nexthdr == IPPROTO_UDP ||
-                    iph->nexthdr == IPPROTO_UDPLITE ||
-                    iph->nexthdr == IPPROTO_SCTP ||
-                    iph->nexthdr == IPPROTO_DCCP ||
-                    iph->nexthdr == IPPROTO_ESP) &&
-                   pskb_network_may_pull(skb, sizeof(*iph) + 4))
-                       h2 ^= *(u32*)&iph[1];
+               poff = proto_ports_offset(iph->nexthdr);
+               if (poff >= 0 &&
+                   pskb_network_may_pull(skb, sizeof(*iph) + 4 + poff)) {
+                       iph = ipv6_hdr(skb);
+                       h2 ^= *(u32*)((void *)iph + sizeof(*iph) + poff);
+               }
                break;
        }
        default: