Commit e6bff995 authored by Neil Horman's avatar Neil Horman Committed by David S. Miller

ipv6: Check RA for sllao when configuring optimistic ipv6 address (v2)

Recently Dave noticed that a test we did in ipv6_add_addr to see if we next hop
route for the interface we're adding an addres to was wrong (see commit
7ffbcecb).  for one, it never triggers, and two,
it was completely wrong to begin with.  This test was meant to cover this
section of RFC 4429:

3.3 Modifications to RFC 2462 Stateless Address Autoconfiguration

   * (modifies section 5.5) A host MAY choose to configure a new address
        as an Optimistic Address.  A host that does not know the SLLAO
        of its router SHOULD NOT configure a new address as Optimistic.
        A router SHOULD NOT configure an Optimistic Address.

This patch should bring us into proper compliance with the above clause.  Since
we only add a SLAAC address after we've received a RA which may or may not
contain a source link layer address option, we can pass a pointer to that option
to addrconf_prefix_rcv (which may be null if the option is not present), and
only set the optimistic flag if the option was found in the RA.

Change notes:
(v2) modified the new parameter to addrconf_prefix_rcv to be a bool rather than
a pointer to make its use more clear as per request from davem.
Signed-off-by: default avatarNeil Horman <nhorman@tuxdriver.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 02a9098e
...@@ -151,7 +151,8 @@ extern int ipv6_chk_mcast_addr(struct net_device *dev, ...@@ -151,7 +151,8 @@ extern int ipv6_chk_mcast_addr(struct net_device *dev,
const struct in6_addr *src_addr); const struct in6_addr *src_addr);
extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr); extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr);
extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len); extern void addrconf_prefix_rcv(struct net_device *dev,
u8 *opt, int len, bool sllao);
/* /*
* anycast prototypes (anycast.c) * anycast prototypes (anycast.c)
......
...@@ -1803,7 +1803,7 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev) ...@@ -1803,7 +1803,7 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
return idev; return idev;
} }
void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
{ {
struct prefix_info *pinfo; struct prefix_info *pinfo;
__u32 valid_lft; __u32 valid_lft;
...@@ -1934,7 +1934,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) ...@@ -1934,7 +1934,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
if (in6_dev->cnf.optimistic_dad && if (in6_dev->cnf.optimistic_dad &&
!net->ipv6.devconf_all->forwarding) !net->ipv6.devconf_all->forwarding && sllao)
addr_flags = IFA_F_OPTIMISTIC; addr_flags = IFA_F_OPTIMISTIC;
#endif #endif
......
...@@ -1368,7 +1368,9 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1368,7 +1368,9 @@ static void ndisc_router_discovery(struct sk_buff *skb)
for (p = ndopts.nd_opts_pi; for (p = ndopts.nd_opts_pi;
p; p;
p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) { p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3); addrconf_prefix_rcv(skb->dev, (u8 *)p,
(p->nd_opt_len) << 3,
ndopts.nd_opts_src_lladdr != NULL);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment