diff options
| -rw-r--r-- | drivers/net/ipvlan/ipvlan_core.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 4476425b1033..11c1e7950fe5 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c | |||
| @@ -165,8 +165,26 @@ static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int | |||
| 165 | /* Only Neighbour Solicitation pkts need different treatment */ | 165 | /* Only Neighbour Solicitation pkts need different treatment */ |
| 166 | if (ipv6_addr_any(&ip6h->saddr) && | 166 | if (ipv6_addr_any(&ip6h->saddr) && |
| 167 | ip6h->nexthdr == NEXTHDR_ICMP) { | 167 | ip6h->nexthdr == NEXTHDR_ICMP) { |
| 168 | struct icmp6hdr *icmph; | ||
| 169 | |||
| 170 | if (unlikely(!pskb_may_pull(skb, sizeof(*ip6h) + sizeof(*icmph)))) | ||
| 171 | return NULL; | ||
| 172 | |||
| 173 | ip6h = ipv6_hdr(skb); | ||
| 174 | icmph = (struct icmp6hdr *)(ip6h + 1); | ||
| 175 | |||
| 176 | if (icmph->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) { | ||
| 177 | /* Need to access the ipv6 address in body */ | ||
| 178 | if (unlikely(!pskb_may_pull(skb, sizeof(*ip6h) + sizeof(*icmph) | ||
| 179 | + sizeof(struct in6_addr)))) | ||
| 180 | return NULL; | ||
| 181 | |||
| 182 | ip6h = ipv6_hdr(skb); | ||
| 183 | icmph = (struct icmp6hdr *)(ip6h + 1); | ||
| 184 | } | ||
| 185 | |||
| 168 | *type = IPVL_ICMPV6; | 186 | *type = IPVL_ICMPV6; |
| 169 | lyr3h = ip6h + 1; | 187 | lyr3h = icmph; |
| 170 | } | 188 | } |
| 171 | break; | 189 | break; |
| 172 | } | 190 | } |
