From 84ebe6715e663404ac17d4c76cee738f272f3488 Mon Sep 17 00:00:00 2001 From: Duan Jiong Date: Fri, 14 Dec 2012 02:59:59 +0000 Subject: [PATCH] --- yaml --- r: 347295 b: refs/heads/master c: 093d04d42fa094f6740bb188f0ad0c215ff61e2c h: refs/heads/master i: 347293: 96231c4e3a489b1fbbf61d1094ce468cfb1c3452 347291: efc915669ca53c792d6cee949d4faef331a3980a 347287: 517b1de9ddab8ecec74726897b18d7af3e4e7405 347279: bfc1b8b82d68e31fc777f07cde6ad59ea59fc3a4 347263: 448456cf7303aa7d74679ea06464a11a3e105468 v: v3 --- [refs] | 2 +- trunk/include/net/ndisc.h | 7 +++++++ trunk/net/ipv6/ndisc.c | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index c0d6fc43f599..6fc37a145563 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1e9f954516ee03251e0ac2e98cad2e4be6ce9958 +refs/heads/master: 093d04d42fa094f6740bb188f0ad0c215ff61e2c diff --git a/trunk/include/net/ndisc.h b/trunk/include/net/ndisc.h index 7af1ea893038..23b3a7c58783 100644 --- a/trunk/include/net/ndisc.h +++ b/trunk/include/net/ndisc.h @@ -78,6 +78,13 @@ struct ra_msg { __be32 retrans_timer; }; +struct rd_msg { + struct icmp6hdr icmph; + struct in6_addr target; + struct in6_addr dest; + __u8 opt[0]; +}; + struct nd_opt_hdr { __u8 nd_opt_type; __u8 nd_opt_len; diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index f2a007b7bde3..6574175795df 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -1314,6 +1314,12 @@ static void ndisc_router_discovery(struct sk_buff *skb) static void ndisc_redirect_rcv(struct sk_buff *skb) { + u8 *hdr; + struct ndisc_options ndopts; + struct rd_msg *msg = (struct rd_msg *)skb_transport_header(skb); + u32 ndoptlen = skb->tail - (skb->transport_header + + offsetof(struct rd_msg, opt)); + #ifdef CONFIG_IPV6_NDISC_NODETYPE switch (skb->ndisc_nodetype) { case NDISC_NODETYPE_HOST: @@ -1330,6 +1336,17 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) return; } + if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) + return; + + if (!ndopts.nd_opts_rh) + return; + + hdr = (u8 *)ndopts.nd_opts_rh; + hdr += 8; + if (!pskb_pull(skb, hdr - skb_transport_header(skb))) + return; + icmpv6_notify(skb, NDISC_REDIRECT, 0, 0); }