Commit 78d3307e authored by Changli Gao's avatar Changli Gao Committed by David S. Miller

net_sched: cls_flow: use proto_ports_offset() to support AH message

Signed-off-by: default avatarChangli Gao <xiaosuo@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 12fcdefb
...@@ -111,44 +111,41 @@ static u32 flow_get_proto(struct sk_buff *skb) ...@@ -111,44 +111,41 @@ static u32 flow_get_proto(struct sk_buff *skb)
} }
} }
static int has_ports(u8 protocol)
{
switch (protocol) {
case IPPROTO_TCP:
case IPPROTO_UDP:
case IPPROTO_UDPLITE:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
case IPPROTO_ESP:
return 1;
default:
return 0;
}
}
static u32 flow_get_proto_src(struct sk_buff *skb) static u32 flow_get_proto_src(struct sk_buff *skb)
{ {
switch (skb->protocol) { switch (skb->protocol) {
case htons(ETH_P_IP): { case htons(ETH_P_IP): {
struct iphdr *iph; struct iphdr *iph;
int poff;
if (!pskb_network_may_pull(skb, sizeof(*iph))) if (!pskb_network_may_pull(skb, sizeof(*iph)))
break; break;
iph = ip_hdr(skb); iph = ip_hdr(skb);
if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && if (iph->frag_off & htons(IP_MF|IP_OFFSET))
has_ports(iph->protocol) && break;
pskb_network_may_pull(skb, iph->ihl * 4 + 2)) poff = proto_ports_offset(iph->protocol);
return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); if (poff >= 0 &&
pskb_network_may_pull(skb, iph->ihl * 4 + 2 + poff)) {
iph = ip_hdr(skb);
return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 +
poff));
}
break; break;
} }
case htons(ETH_P_IPV6): { case htons(ETH_P_IPV6): {
struct ipv6hdr *iph; struct ipv6hdr *iph;
int poff;
if (!pskb_network_may_pull(skb, sizeof(*iph) + 2)) if (!pskb_network_may_pull(skb, sizeof(*iph)))
break; break;
iph = ipv6_hdr(skb); iph = ipv6_hdr(skb);
if (has_ports(iph->nexthdr)) poff = proto_ports_offset(iph->nexthdr);
return ntohs(*(__be16 *)&iph[1]); if (poff >= 0 &&
pskb_network_may_pull(skb, sizeof(*iph) + poff + 2)) {
iph = ipv6_hdr(skb);
return ntohs(*(__be16 *)((void *)iph + sizeof(*iph) +
poff));
}
break; break;
} }
} }
...@@ -161,24 +158,36 @@ static u32 flow_get_proto_dst(struct sk_buff *skb) ...@@ -161,24 +158,36 @@ static u32 flow_get_proto_dst(struct sk_buff *skb)
switch (skb->protocol) { switch (skb->protocol) {
case htons(ETH_P_IP): { case htons(ETH_P_IP): {
struct iphdr *iph; struct iphdr *iph;
int poff;
if (!pskb_network_may_pull(skb, sizeof(*iph))) if (!pskb_network_may_pull(skb, sizeof(*iph)))
break; break;
iph = ip_hdr(skb); iph = ip_hdr(skb);
if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && if (iph->frag_off & htons(IP_MF|IP_OFFSET))
has_ports(iph->protocol) && break;
pskb_network_may_pull(skb, iph->ihl * 4 + 4)) poff = proto_ports_offset(iph->protocol);
return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); if (poff >= 0 &&
pskb_network_may_pull(skb, iph->ihl * 4 + 4 + poff)) {
iph = ip_hdr(skb);
return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 +
2 + poff));
}
break; break;
} }
case htons(ETH_P_IPV6): { case htons(ETH_P_IPV6): {
struct ipv6hdr *iph; struct ipv6hdr *iph;
int poff;
if (!pskb_network_may_pull(skb, sizeof(*iph) + 4)) if (!pskb_network_may_pull(skb, sizeof(*iph)))
break; break;
iph = ipv6_hdr(skb); iph = ipv6_hdr(skb);
if (has_ports(iph->nexthdr)) poff = proto_ports_offset(iph->nexthdr);
return ntohs(*(__be16 *)((void *)&iph[1] + 2)); if (poff >= 0 &&
pskb_network_may_pull(skb, sizeof(*iph) + poff + 4)) {
iph = ipv6_hdr(skb);
return ntohs(*(__be16 *)((void *)iph + sizeof(*iph) +
poff + 2));
}
break; break;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment