aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index c14ea1ecf379..0f56e9e69a8f 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -308,6 +308,46 @@ static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
308 return 0; 308 return 0;
309} 309}
310 310
311static int ip6_forward_proxy_check(struct sk_buff *skb)
312{
313 struct ipv6hdr *hdr = skb->nh.ipv6h;
314 u8 nexthdr = hdr->nexthdr;
315 int offset;
316
317 if (ipv6_ext_hdr(nexthdr)) {
318 offset = ipv6_skip_exthdr(skb, sizeof(*hdr), &nexthdr);
319 if (offset < 0)
320 return 0;
321 } else
322 offset = sizeof(struct ipv6hdr);
323
324 if (nexthdr == IPPROTO_ICMPV6) {
325 struct icmp6hdr *icmp6;
326
327 if (!pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data))
328 return 0;
329
330 icmp6 = (struct icmp6hdr *)(skb->nh.raw + offset);
331
332 switch (icmp6->icmp6_type) {
333 case NDISC_ROUTER_SOLICITATION:
334 case NDISC_ROUTER_ADVERTISEMENT:
335 case NDISC_NEIGHBOUR_SOLICITATION:
336 case NDISC_NEIGHBOUR_ADVERTISEMENT:
337 case NDISC_REDIRECT:
338 /* For reaction involving unicast neighbor discovery
339 * message destined to the proxied address, pass it to
340 * input function.
341 */
342 return 1;
343 default:
344 break;
345 }
346 }
347
348 return 0;
349}
350
311static inline int ip6_forward_finish(struct sk_buff *skb) 351static inline int ip6_forward_finish(struct sk_buff *skb)
312{ 352{
313 return dst_output(skb); 353 return dst_output(skb);
@@ -362,6 +402,11 @@ int ip6_forward(struct sk_buff *skb)
362 return -ETIMEDOUT; 402 return -ETIMEDOUT;
363 } 403 }
364 404
405 if (pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) {
406 if (ip6_forward_proxy_check(skb))
407 return ip6_input(skb);
408 }
409
365 if (!xfrm6_route_forward(skb)) { 410 if (!xfrm6_route_forward(skb)) {
366 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); 411 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS);
367 goto drop; 412 goto drop;