aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-04-08 23:47:15 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-09 13:12:23 -0400
commitfc403832f7bd94014fe3d965e0652a857160f1c9 (patch)
treed05ae6821dbd6a46db1fee600aa04b6b871ce186 /net/ipv6
parent914faa147bd2d086ed7257ad785d74cfe48d30ad (diff)
net: ipv6: also allow token to be set when device not ready
When we set the iftoken in inet6_set_iftoken(), we return -EINVAL when the device does not have flag IF_READY. This is however not necessary and rather an artificial usability barrier, since we simply can set the token despite that, and in case the device is ready, we just send out our rs, otherwise ifup et al. will do this for us anyway. Suggested-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 645bf317019f..713ebe303f61 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4296,9 +4296,9 @@ static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
4296 4296
4297static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) 4297static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
4298{ 4298{
4299 struct in6_addr ll_addr;
4300 struct inet6_ifaddr *ifp; 4299 struct inet6_ifaddr *ifp;
4301 struct net_device *dev = idev->dev; 4300 struct net_device *dev = idev->dev;
4301 bool update_rs = false;
4302 4302
4303 if (token == NULL) 4303 if (token == NULL)
4304 return -EINVAL; 4304 return -EINVAL;
@@ -4306,8 +4306,6 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
4306 return -EINVAL; 4306 return -EINVAL;
4307 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) 4307 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP))
4308 return -EINVAL; 4308 return -EINVAL;
4309 if (idev->dead || !(idev->if_flags & IF_READY))
4310 return -EINVAL;
4311 if (!ipv6_accept_ra(idev)) 4309 if (!ipv6_accept_ra(idev))
4312 return -EINVAL; 4310 return -EINVAL;
4313 if (idev->cnf.rtr_solicits <= 0) 4311 if (idev->cnf.rtr_solicits <= 0)
@@ -4320,11 +4318,23 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
4320 4318
4321 write_unlock_bh(&idev->lock); 4319 write_unlock_bh(&idev->lock);
4322 4320
4323 ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE | IFA_F_OPTIMISTIC); 4321 if (!idev->dead && (idev->if_flags & IF_READY)) {
4324 ndisc_send_rs(dev, &ll_addr, &in6addr_linklocal_allrouters); 4322 struct in6_addr ll_addr;
4323
4324 ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE |
4325 IFA_F_OPTIMISTIC);
4326
4327 /* If we're not ready, then normal ifup will take care
4328 * of this. Otherwise, we need to request our rs here.
4329 */
4330 ndisc_send_rs(dev, &ll_addr, &in6addr_linklocal_allrouters);
4331 update_rs = true;
4332 }
4325 4333
4326 write_lock_bh(&idev->lock); 4334 write_lock_bh(&idev->lock);
4327 idev->if_flags |= IF_RS_SENT; 4335
4336 if (update_rs)
4337 idev->if_flags |= IF_RS_SENT;
4328 4338
4329 /* Well, that's kinda nasty ... */ 4339 /* Well, that's kinda nasty ... */
4330 list_for_each_entry(ifp, &idev->addr_list, if_list) { 4340 list_for_each_entry(ifp, &idev->addr_list, if_list) {