aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
authorVille Nuorvala <vnuorval@tcs.hut.fi>2006-09-22 17:41:44 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:20:21 -0400
commite21e0b5f19ac7835a244c2016f7ed726f971b3e9 (patch)
tree93c12a003ed5a86caf0fe28ade960da219835cd3 /net/ipv6/ip6_output.c
parent4c5de695cf7f71c85ad8cfff509f6475b8bd4d27 (diff)
[IPV6] NDISC: Handle NDP messages to proxied addresses.
It is required to respond to NDP messages sent directly to the "target" unicast address. Proxying node (router) is required to handle such messages. To achieve this, check if the packet in forwarding patch is NDP message. With this patch, the proxy neighbor entries are always looked up in forwarding path. We may want to optimize further. Based on MIPL2 kernel patch. Signed-off-by: Ville Nuorvala <vnuorval@tcs.hut.fi> Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
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;