]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/ipv6/addrconf.c
net: Convert LIMIT_NETDEBUG to net_dbg_ratelimited
[mirror_ubuntu-bionic-kernel.git] / net / ipv6 / addrconf.c
index 725c763270a067e3945ec3056c4f5893cf9f7060..251fcb48b216054298b93c558c56402d804841b2 100644 (file)
@@ -1170,6 +1170,9 @@ enum {
        IPV6_SADDR_RULE_PRIVACY,
        IPV6_SADDR_RULE_ORCHID,
        IPV6_SADDR_RULE_PREFIX,
+#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+       IPV6_SADDR_RULE_NOT_OPTIMISTIC,
+#endif
        IPV6_SADDR_RULE_MAX
 };
 
@@ -1197,6 +1200,15 @@ static inline int ipv6_saddr_preferred(int type)
        return 0;
 }
 
+static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev)
+{
+#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+       return idev && idev->cnf.optimistic_dad && idev->cnf.use_optimistic;
+#else
+       return false;
+#endif
+}
+
 static int ipv6_get_saddr_eval(struct net *net,
                               struct ipv6_saddr_score *score,
                               struct ipv6_saddr_dst *dst,
@@ -1257,10 +1269,16 @@ static int ipv6_get_saddr_eval(struct net *net,
                score->scopedist = ret;
                break;
        case IPV6_SADDR_RULE_PREFERRED:
+           {
                /* Rule 3: Avoid deprecated and optimistic addresses */
+               u8 avoid = IFA_F_DEPRECATED;
+
+               if (!ipv6_use_optimistic_addr(score->ifa->idev))
+                       avoid |= IFA_F_OPTIMISTIC;
                ret = ipv6_saddr_preferred(score->addr_type) ||
-                     !(score->ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC));
+                     !(score->ifa->flags & avoid);
                break;
+           }
 #ifdef CONFIG_IPV6_MIP6
        case IPV6_SADDR_RULE_HOA:
            {
@@ -1306,6 +1324,14 @@ static int ipv6_get_saddr_eval(struct net *net,
                        ret = score->ifa->prefix_len;
                score->matchlen = ret;
                break;
+#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+       case IPV6_SADDR_RULE_NOT_OPTIMISTIC:
+               /* Optimistic addresses still have lower precedence than other
+                * preferred addresses.
+                */
+               ret = !(score->ifa->flags & IFA_F_OPTIMISTIC);
+               break;
+#endif
        default:
                ret = 0;
        }
@@ -1385,10 +1411,8 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
 
                        if (unlikely(score->addr_type == IPV6_ADDR_ANY ||
                                     score->addr_type & IPV6_ADDR_MULTICAST)) {
-                               LIMIT_NETDEBUG(KERN_DEBUG
-                                              "ADDRCONF: unspecified / multicast address "
-                                              "assigned as unicast address on %s",
-                                              dev->name);
+                               net_dbg_ratelimited("ADDRCONF: unspecified / multicast address assigned as unicast address on %s",
+                                                   dev->name);
                                continue;
                        }
 
@@ -2315,8 +2339,8 @@ ok:
                        else
                                stored_lft = 0;
                        if (!update_lft && !create && stored_lft) {
-                               const u32 minimum_lft = min(
-                                       stored_lft, (u32)MIN_VALID_LIFETIME);
+                               const u32 minimum_lft = min_t(u32,
+                                       stored_lft, MIN_VALID_LIFETIME);
                                valid_lft = max(valid_lft, minimum_lft);
 
                                /* RFC4862 Section 5.5.3e:
@@ -3222,8 +3246,15 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
         * Optimistic nodes can start receiving
         * Frames right away
         */
-       if (ifp->flags & IFA_F_OPTIMISTIC)
+       if (ifp->flags & IFA_F_OPTIMISTIC) {
                ip6_ins_rt(ifp->rt);
+               if (ipv6_use_optimistic_addr(idev)) {
+                       /* Because optimistic nodes can use this address,
+                        * notify listeners. If DAD fails, RTM_DELADDR is sent.
+                        */
+                       ipv6_ifa_notify(RTM_NEWADDR, ifp);
+               }
+       }
 
        addrconf_dad_kick(ifp);
 out:
@@ -4330,6 +4361,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
        array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
        array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad;
+       array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic;
 #endif
 #ifdef CONFIG_IPV6_MROUTE
        array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
@@ -4531,6 +4563,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
        }
 
        write_unlock_bh(&idev->lock);
+       inet6_ifinfo_notify(RTM_NEWLINK, idev);
        addrconf_verify_rtnl();
        return 0;
 }
@@ -5155,6 +5188,14 @@ static struct addrconf_sysctl_table
                        .proc_handler   = proc_dointvec,
 
                },
+               {
+                       .procname       = "use_optimistic",
+                       .data           = &ipv6_devconf.use_optimistic,
+                       .maxlen         = sizeof(int),
+                       .mode           = 0644,
+                       .proc_handler   = proc_dointvec,
+
+               },
 #endif
 #ifdef CONFIG_IPV6_MROUTE
                {