diff options
author | Duan Jiong <djduanjiong@gmail.com> | 2012-12-13 21:59:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-14 13:14:07 -0500 |
commit | 093d04d42fa094f6740bb188f0ad0c215ff61e2c (patch) | |
tree | 7231c8fddcc6157dce7ecde4491c355fc284824c /net/ipv6 | |
parent | 1e9f954516ee03251e0ac2e98cad2e4be6ce9958 (diff) |
ipv6: Change skb->data before using icmpv6_notify() to propagate redirect
In function ndisc_redirect_rcv(), the skb->data points to the transport
header, but function icmpv6_notify() need the skb->data points to the
inner IP packet. So before using icmpv6_notify() to propagate redirect,
change skb->data to point the inner IP packet that triggered the sending
of the Redirect, and introduce struct rd_msg to make it easy.
Signed-off-by: Duan Jiong <djduanjiong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ndisc.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f2a007b7bde..6574175795d 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -1314,6 +1314,12 @@ out: | |||
1314 | 1314 | ||
1315 | static void ndisc_redirect_rcv(struct sk_buff *skb) | 1315 | static void ndisc_redirect_rcv(struct sk_buff *skb) |
1316 | { | 1316 | { |
1317 | u8 *hdr; | ||
1318 | struct ndisc_options ndopts; | ||
1319 | struct rd_msg *msg = (struct rd_msg *)skb_transport_header(skb); | ||
1320 | u32 ndoptlen = skb->tail - (skb->transport_header + | ||
1321 | offsetof(struct rd_msg, opt)); | ||
1322 | |||
1317 | #ifdef CONFIG_IPV6_NDISC_NODETYPE | 1323 | #ifdef CONFIG_IPV6_NDISC_NODETYPE |
1318 | switch (skb->ndisc_nodetype) { | 1324 | switch (skb->ndisc_nodetype) { |
1319 | case NDISC_NODETYPE_HOST: | 1325 | case NDISC_NODETYPE_HOST: |
@@ -1330,6 +1336,17 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) | |||
1330 | return; | 1336 | return; |
1331 | } | 1337 | } |
1332 | 1338 | ||
1339 | if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) | ||
1340 | return; | ||
1341 | |||
1342 | if (!ndopts.nd_opts_rh) | ||
1343 | return; | ||
1344 | |||
1345 | hdr = (u8 *)ndopts.nd_opts_rh; | ||
1346 | hdr += 8; | ||
1347 | if (!pskb_pull(skb, hdr - skb_transport_header(skb))) | ||
1348 | return; | ||
1349 | |||
1333 | icmpv6_notify(skb, NDISC_REDIRECT, 0, 0); | 1350 | icmpv6_notify(skb, NDISC_REDIRECT, 0, 0); |
1334 | } | 1351 | } |
1335 | 1352 | ||