diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 645bf317019f58e4eb60a8c336c9f8af14f16f16..713ebe303f6150c124a62957308e92ac962cea44 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) static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) { - struct in6_addr ll_addr; struct inet6_ifaddr *ifp; struct net_device *dev = idev->dev; + bool update_rs = false; if (token == NULL) return -EINVAL; @@ -4306,8 +4306,6 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) return -EINVAL; if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) return -EINVAL; - if (idev->dead || !(idev->if_flags & IF_READY)) - return -EINVAL; if (!ipv6_accept_ra(idev)) return -EINVAL; if (idev->cnf.rtr_solicits <= 0) @@ -4320,11 +4318,23 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) write_unlock_bh(&idev->lock); - ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE | IFA_F_OPTIMISTIC); - ndisc_send_rs(dev, &ll_addr, &in6addr_linklocal_allrouters); + if (!idev->dead && (idev->if_flags & IF_READY)) { + struct in6_addr ll_addr; + + ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE | + IFA_F_OPTIMISTIC); + + /* If we're not ready, then normal ifup will take care + * of this. Otherwise, we need to request our rs here. + */ + ndisc_send_rs(dev, &ll_addr, &in6addr_linklocal_allrouters); + update_rs = true; + } write_lock_bh(&idev->lock); - idev->if_flags |= IF_RS_SENT; + + if (update_rs) + idev->if_flags |= IF_RS_SENT; /* Well, that's kinda nasty ... */ list_for_each_entry(ifp, &idev->addr_list, if_list) {