diff options
Diffstat (limited to 'net/sched/sch_sfq.c')
-rw-r--r-- | net/sched/sch_sfq.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index c65762823f5e..534f33231c17 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -122,7 +122,11 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | |||
122 | switch (skb->protocol) { | 122 | switch (skb->protocol) { |
123 | case htons(ETH_P_IP): | 123 | case htons(ETH_P_IP): |
124 | { | 124 | { |
125 | const struct iphdr *iph = ip_hdr(skb); | 125 | const struct iphdr *iph; |
126 | |||
127 | if (!pskb_network_may_pull(skb, sizeof(*iph))) | ||
128 | goto err; | ||
129 | iph = ip_hdr(skb); | ||
126 | h = (__force u32)iph->daddr; | 130 | h = (__force u32)iph->daddr; |
127 | h2 = (__force u32)iph->saddr ^ iph->protocol; | 131 | h2 = (__force u32)iph->saddr ^ iph->protocol; |
128 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && | 132 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && |
@@ -131,25 +135,32 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | |||
131 | iph->protocol == IPPROTO_UDPLITE || | 135 | iph->protocol == IPPROTO_UDPLITE || |
132 | iph->protocol == IPPROTO_SCTP || | 136 | iph->protocol == IPPROTO_SCTP || |
133 | iph->protocol == IPPROTO_DCCP || | 137 | iph->protocol == IPPROTO_DCCP || |
134 | iph->protocol == IPPROTO_ESP)) | 138 | iph->protocol == IPPROTO_ESP) && |
139 | pskb_network_may_pull(skb, iph->ihl * 4 + 4)) | ||
135 | h2 ^= *(((u32*)iph) + iph->ihl); | 140 | h2 ^= *(((u32*)iph) + iph->ihl); |
136 | break; | 141 | break; |
137 | } | 142 | } |
138 | case htons(ETH_P_IPV6): | 143 | case htons(ETH_P_IPV6): |
139 | { | 144 | { |
140 | struct ipv6hdr *iph = ipv6_hdr(skb); | 145 | struct ipv6hdr *iph; |
146 | |||
147 | if (!pskb_network_may_pull(skb, sizeof(*iph))) | ||
148 | goto err; | ||
149 | iph = ipv6_hdr(skb); | ||
141 | h = (__force u32)iph->daddr.s6_addr32[3]; | 150 | h = (__force u32)iph->daddr.s6_addr32[3]; |
142 | h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; | 151 | h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; |
143 | if (iph->nexthdr == IPPROTO_TCP || | 152 | if ((iph->nexthdr == IPPROTO_TCP || |
144 | iph->nexthdr == IPPROTO_UDP || | 153 | iph->nexthdr == IPPROTO_UDP || |
145 | iph->nexthdr == IPPROTO_UDPLITE || | 154 | iph->nexthdr == IPPROTO_UDPLITE || |
146 | iph->nexthdr == IPPROTO_SCTP || | 155 | iph->nexthdr == IPPROTO_SCTP || |
147 | iph->nexthdr == IPPROTO_DCCP || | 156 | iph->nexthdr == IPPROTO_DCCP || |
148 | iph->nexthdr == IPPROTO_ESP) | 157 | iph->nexthdr == IPPROTO_ESP) && |
158 | pskb_network_may_pull(skb, sizeof(*iph) + 4)) | ||
149 | h2 ^= *(u32*)&iph[1]; | 159 | h2 ^= *(u32*)&iph[1]; |
150 | break; | 160 | break; |
151 | } | 161 | } |
152 | default: | 162 | default: |
163 | err: | ||
153 | h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol; | 164 | h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol; |
154 | h2 = (unsigned long)skb->sk; | 165 | h2 = (unsigned long)skb->sk; |
155 | } | 166 | } |
@@ -502,6 +513,12 @@ static unsigned long sfq_get(struct Qdisc *sch, u32 classid) | |||
502 | return 0; | 513 | return 0; |
503 | } | 514 | } |
504 | 515 | ||
516 | static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent, | ||
517 | u32 classid) | ||
518 | { | ||
519 | return 0; | ||
520 | } | ||
521 | |||
505 | static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl) | 522 | static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl) |
506 | { | 523 | { |
507 | struct sfq_sched_data *q = qdisc_priv(sch); | 524 | struct sfq_sched_data *q = qdisc_priv(sch); |
@@ -556,6 +573,7 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg) | |||
556 | static const struct Qdisc_class_ops sfq_class_ops = { | 573 | static const struct Qdisc_class_ops sfq_class_ops = { |
557 | .get = sfq_get, | 574 | .get = sfq_get, |
558 | .tcf_chain = sfq_find_tcf, | 575 | .tcf_chain = sfq_find_tcf, |
576 | .bind_tcf = sfq_bind, | ||
559 | .dump = sfq_dump_class, | 577 | .dump = sfq_dump_class, |
560 | .dump_stats = sfq_dump_class_stats, | 578 | .dump_stats = sfq_dump_class_stats, |
561 | .walk = sfq_walk, | 579 | .walk = sfq_walk, |