aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c20
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 }