aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorLi Yewang2007-01-30 14:33:20 -0800
committerDavid S. Miller2007-01-30 14:33:20 -0800
commit29556526b970c2e7d4ca808b6082c33981adfdff (patch)
tree4fea5d6ae1fbacc36219e9801dba0dd7a9e68650 /net
parentfa03ef38e1516c1f35f6a189100186dded0f8f8c (diff)
[IPV6]: fix BUG of ndisc_send_redirect()
When I tested IPv6 redirect function about kernel 2.6.19.1, and found that the kernel can send redirect packets whose target address is global address, and the target is not the actual endpoint of communication. But the criteria conform to RFC2461, the target address defines as following: Target Address An IP address that is a better first hop to use for he ICMP Destination Address. When the target is the actual endpoint of communication, i.e., the destination is a neighbor, the Target Address field MUST contain the same value as the ICMP Destination Address field. Otherwise the target is a better first-hop router and the Target Address MUST be the router's link-local address so that hosts can uniquely identify routers. According to this definition, when a router redirect to a host, the target address either the better first-hop router's link-local address or the same as the ICMP destination address field. But the function of ndisc_send_redirect() in net/ipv6/ndisc.c, does not check the target address correctly. There is another definition about receive Redirect message in RFC2461: 8.1. Validation of Redirect Messages A host MUST silently discard any received Redirect message that does not satisfy all of the following validity checks: ...... - The ICMP Target Address is either a link-local address (when redirected to a router) or the same as the ICMP Destination Address (when redirected to the on-link destination). ...... And the receive redirect function of ndisc_redirect_rcv() implemented this definition, checks the target address correctly. if (ipv6_addr_equal(dest, target)) { on_link = 1; } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) { ND_PRINTK2(KERN_WARNING "ICMPv6 Redirect: target address is not link-local.\n"); return; } So, I think the send redirect function must check the target address also. Signed-off-by: Li Yewang <lyw@nanjing-fnst.com> Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/ndisc.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 6a9f616de37d..39bb658f3c44 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1413,6 +1413,13 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
return;
}
+ if (!ipv6_addr_equal(&skb->nh.ipv6h->daddr, target) &&
+ !(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
+ ND_PRINTK2(KERN_WARNING
+ "ICMPv6 Redirect: target address is not link-local.\n");
+ return;
+ }
+
ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr,
dev->ifindex);