Re: [RFC 07/12] addrconf: put prefix address add in an own function

2016-05-27 Thread Stefan Schmidt

Hello.

On 27/05/16 13:41, Alexander Aring wrote:

Hi,

On 05/27/2016 11:45 AM, Stefan Schmidt wrote:

Hello.


sorry, again I will change something on this patch which is buggy.


On 23/05/16 21:22, Alexander Aring wrote:

This patch moves the functionality to add a RA PIO prefix generated
address in an own function. This move prepares to add a hook for
adding a second address for a second link-layer address. E.g. short
address for 802.15.4 6LoWPAN.

Cc: David S. Miller
Cc: Alexey Kuznetsov
Cc: James Morris
Cc: Hideaki YOSHIFUJI
Cc: Patrick McHardy
Signed-off-by: Alexander Aring
---
   net/ipv6/addrconf.c | 191 

   1 file changed, 102 insertions(+), 89 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index beaad49..393cdbf 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2333,6 +2333,104 @@ static bool is_addr_mode_generate_stable(struct 
inet6_dev *idev)
  idev->addr_gen_mode == IN6_ADDR_GEN_MODE_RANDOM;
   }
   +static void addrconf_prefix_rcv_add_addr(struct net *net,

will change to return int here to indicates errors.


+ struct net_device *dev,
+ const struct prefix_info *pinfo,
+ struct inet6_dev *in6_dev,
+ const struct in6_addr *addr,
+ int addr_type, u32 addr_flags,
+ bool sllao, bool tokenized,
+ __u32 valid_lft, u32 prefered_lft)
+{
+struct inet6_ifaddr *ifp = ipv6_get_ifaddr(net, addr, dev, 1);
+int create = 0, update_lft = 0;
+
+if (!ifp && valid_lft) {
+int max_addresses = in6_dev->cnf.max_addresses;
+
+#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+if (in6_dev->cnf.optimistic_dad &&
+!net->ipv6.devconf_all->forwarding && sllao)
+addr_flags |= IFA_F_OPTIMISTIC;
+#endif
+
+/* Do not allow to create too much of autoconfigured
+ * addresses; this would be too easy way to crash kernel.
+ */
+if (!max_addresses ||
+ipv6_count_addresses(in6_dev) < max_addresses)
+ifp = ipv6_add_addr(in6_dev, addr, NULL,
+pinfo->prefix_len,
+addr_type_ADDR_SCOPE_MASK,
+addr_flags, valid_lft,
+prefered_lft);
+
+if (IS_ERR_OR_NULL(ifp)) {
+in6_dev_put(in6_dev);
+return;

return -1; and remove in6_dev_put stuff.


+}
+
+update_lft = 0;
+create = 1;
+spin_lock_bh(>lock);
+ifp->flags |= IFA_F_MANAGETEMPADDR;
+ifp->cstamp = jiffies;
+ifp->tokenized = tokenized;
+spin_unlock_bh(>lock);
+addrconf_dad_start(ifp);
+}
+
+if (ifp) {
+u32 flags;
+unsigned long now;
+u32 stored_lft;
+
+/* update lifetime (RFC2462 5.5.3 e) */
+spin_lock_bh(>lock);
+now = jiffies;
+if (ifp->valid_lft > (now - ifp->tstamp) / HZ)
+stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ;
+else
+stored_lft = 0;
+if (!update_lft && !create && stored_lft) {
+const u32 minimum_lft = min_t(u32,
+stored_lft, MIN_VALID_LIFETIME);
+valid_lft = max(valid_lft, minimum_lft);
+
+/* RFC4862 Section 5.5.3e:
+ * "Note that the preferred lifetime of the
+ *  corresponding address is always reset to
+ *  the Preferred Lifetime in the received
+ *  Prefix Information option, regardless of
+ *  whether the valid lifetime is also reset or
+ *  ignored."
+ *
+ * So we should always update prefered_lft here.
+ */
+update_lft = 1;
+}
+
+if (update_lft) {
+ifp->valid_lft = valid_lft;
+ifp->prefered_lft = prefered_lft;
+ifp->tstamp = now;
+flags = ifp->flags;
+ifp->flags &= ~IFA_F_DEPRECATED;
+spin_unlock_bh(>lock);
+
+if (!(flags_F_TENTATIVE))
+ipv6_ifa_notify(0, ifp);
+} else
+spin_unlock_bh(>lock);
+
+manage_tempaddrs(in6_dev, ifp, valid_lft, prefered_lft,
+ create, now);
+
+in6_ifa_put(ifp);
+addrconf_verify();
+}
+}
+
   void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool 
sllao)
   {
   struct prefix_info *pinfo;
@@ -2432,9 +2530,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, 
int len, bool sllao)
   /* Try to figure out our local address for this prefix */
 if (pinfo->autoconf && in6_dev->cnf.autoconf) {
-struct inet6_ifaddr *ifp;
   struct in6_addr addr;
-int create = 0, update_lft = 0;
  

Re: [RFC 07/12] addrconf: put prefix address add in an own function

2016-05-27 Thread Alexander Aring

Hi,

On 05/27/2016 11:45 AM, Stefan Schmidt wrote:
> Hello.
> 

sorry, again I will change something on this patch which is buggy.

> On 23/05/16 21:22, Alexander Aring wrote:
>> This patch moves the functionality to add a RA PIO prefix generated
>> address in an own function. This move prepares to add a hook for
>> adding a second address for a second link-layer address. E.g. short
>> address for 802.15.4 6LoWPAN.
>>
>> Cc: David S. Miller
>> Cc: Alexey Kuznetsov
>> Cc: James Morris
>> Cc: Hideaki YOSHIFUJI
>> Cc: Patrick McHardy
>> Signed-off-by: Alexander Aring
>> ---
>>   net/ipv6/addrconf.c | 191 
>> 
>>   1 file changed, 102 insertions(+), 89 deletions(-)
>>
>> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
>> index beaad49..393cdbf 100644
>> --- a/net/ipv6/addrconf.c
>> +++ b/net/ipv6/addrconf.c
>> @@ -2333,6 +2333,104 @@ static bool is_addr_mode_generate_stable(struct 
>> inet6_dev *idev)
>>  idev->addr_gen_mode == IN6_ADDR_GEN_MODE_RANDOM;
>>   }
>>   +static void addrconf_prefix_rcv_add_addr(struct net *net,

will change to return int here to indicates errors.

>> + struct net_device *dev,
>> + const struct prefix_info *pinfo,
>> + struct inet6_dev *in6_dev,
>> + const struct in6_addr *addr,
>> + int addr_type, u32 addr_flags,
>> + bool sllao, bool tokenized,
>> + __u32 valid_lft, u32 prefered_lft)
>> +{
>> +struct inet6_ifaddr *ifp = ipv6_get_ifaddr(net, addr, dev, 1);
>> +int create = 0, update_lft = 0;
>> +
>> +if (!ifp && valid_lft) {
>> +int max_addresses = in6_dev->cnf.max_addresses;
>> +
>> +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
>> +if (in6_dev->cnf.optimistic_dad &&
>> +!net->ipv6.devconf_all->forwarding && sllao)
>> +addr_flags |= IFA_F_OPTIMISTIC;
>> +#endif
>> +
>> +/* Do not allow to create too much of autoconfigured
>> + * addresses; this would be too easy way to crash kernel.
>> + */
>> +if (!max_addresses ||
>> +ipv6_count_addresses(in6_dev) < max_addresses)
>> +ifp = ipv6_add_addr(in6_dev, addr, NULL,
>> +pinfo->prefix_len,
>> +addr_type_ADDR_SCOPE_MASK,
>> +addr_flags, valid_lft,
>> +prefered_lft);
>> +
>> +if (IS_ERR_OR_NULL(ifp)) {
>> +in6_dev_put(in6_dev);
>> +return;

return -1; and remove in6_dev_put stuff.

>> +}
>> +
>> +update_lft = 0;
>> +create = 1;
>> +spin_lock_bh(>lock);
>> +ifp->flags |= IFA_F_MANAGETEMPADDR;
>> +ifp->cstamp = jiffies;
>> +ifp->tokenized = tokenized;
>> +spin_unlock_bh(>lock);
>> +addrconf_dad_start(ifp);
>> +}
>> +
>> +if (ifp) {
>> +u32 flags;
>> +unsigned long now;
>> +u32 stored_lft;
>> +
>> +/* update lifetime (RFC2462 5.5.3 e) */
>> +spin_lock_bh(>lock);
>> +now = jiffies;
>> +if (ifp->valid_lft > (now - ifp->tstamp) / HZ)
>> +stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ;
>> +else
>> +stored_lft = 0;
>> +if (!update_lft && !create && stored_lft) {
>> +const u32 minimum_lft = min_t(u32,
>> +stored_lft, MIN_VALID_LIFETIME);
>> +valid_lft = max(valid_lft, minimum_lft);
>> +
>> +/* RFC4862 Section 5.5.3e:
>> + * "Note that the preferred lifetime of the
>> + *  corresponding address is always reset to
>> + *  the Preferred Lifetime in the received
>> + *  Prefix Information option, regardless of
>> + *  whether the valid lifetime is also reset or
>> + *  ignored."
>> + *
>> + * So we should always update prefered_lft here.
>> + */
>> +update_lft = 1;
>> +}
>> +
>> +if (update_lft) {
>> +ifp->valid_lft = valid_lft;
>> +ifp->prefered_lft = prefered_lft;
>> +ifp->tstamp = now;
>> +flags = ifp->flags;
>> +ifp->flags &= ~IFA_F_DEPRECATED;
>> +spin_unlock_bh(>lock);
>> +
>> +if (!(flags_F_TENTATIVE))
>> +ipv6_ifa_notify(0, ifp);
>> +} else
>> +spin_unlock_bh(>lock);
>> +
>> +manage_tempaddrs(in6_dev, ifp, valid_lft, prefered_lft,
>> + create, now);
>> +
>> +in6_ifa_put(ifp);
>> +addrconf_verify();
>> +}
>> +}
>> +
>>   void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool 
>> sllao)
>>   {
>>   struct prefix_info *pinfo;
>> @@ -2432,9 +2530,7 @@ 

Re: [RFC 07/12] addrconf: put prefix address add in an own function

2016-05-27 Thread Stefan Schmidt

Hello.

On 23/05/16 21:22, Alexander Aring wrote:

This patch moves the functionality to add a RA PIO prefix generated
address in an own function. This move prepares to add a hook for
adding a second address for a second link-layer address. E.g. short
address for 802.15.4 6LoWPAN.

Cc: David S. Miller
Cc: Alexey Kuznetsov
Cc: James Morris
Cc: Hideaki YOSHIFUJI
Cc: Patrick McHardy
Signed-off-by: Alexander Aring
---
  net/ipv6/addrconf.c | 191 
  1 file changed, 102 insertions(+), 89 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index beaad49..393cdbf 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2333,6 +2333,104 @@ static bool is_addr_mode_generate_stable(struct 
inet6_dev *idev)
   idev->addr_gen_mode == IN6_ADDR_GEN_MODE_RANDOM;
  }
  
+static void addrconf_prefix_rcv_add_addr(struct net *net,

+struct net_device *dev,
+const struct prefix_info *pinfo,
+struct inet6_dev *in6_dev,
+const struct in6_addr *addr,
+int addr_type, u32 addr_flags,
+bool sllao, bool tokenized,
+__u32 valid_lft, u32 prefered_lft)
+{
+   struct inet6_ifaddr *ifp = ipv6_get_ifaddr(net, addr, dev, 1);
+   int create = 0, update_lft = 0;
+
+   if (!ifp && valid_lft) {
+   int max_addresses = in6_dev->cnf.max_addresses;
+
+#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+   if (in6_dev->cnf.optimistic_dad &&
+   !net->ipv6.devconf_all->forwarding && sllao)
+   addr_flags |= IFA_F_OPTIMISTIC;
+#endif
+
+   /* Do not allow to create too much of autoconfigured
+* addresses; this would be too easy way to crash kernel.
+*/
+   if (!max_addresses ||
+   ipv6_count_addresses(in6_dev) < max_addresses)
+   ifp = ipv6_add_addr(in6_dev, addr, NULL,
+   pinfo->prefix_len,
+   addr_type_ADDR_SCOPE_MASK,
+   addr_flags, valid_lft,
+   prefered_lft);
+
+   if (IS_ERR_OR_NULL(ifp)) {
+   in6_dev_put(in6_dev);
+   return;
+   }
+
+   update_lft = 0;
+   create = 1;
+   spin_lock_bh(>lock);
+   ifp->flags |= IFA_F_MANAGETEMPADDR;
+   ifp->cstamp = jiffies;
+   ifp->tokenized = tokenized;
+   spin_unlock_bh(>lock);
+   addrconf_dad_start(ifp);
+   }
+
+   if (ifp) {
+   u32 flags;
+   unsigned long now;
+   u32 stored_lft;
+
+   /* update lifetime (RFC2462 5.5.3 e) */
+   spin_lock_bh(>lock);
+   now = jiffies;
+   if (ifp->valid_lft > (now - ifp->tstamp) / HZ)
+   stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ;
+   else
+   stored_lft = 0;
+   if (!update_lft && !create && stored_lft) {
+   const u32 minimum_lft = min_t(u32,
+   stored_lft, MIN_VALID_LIFETIME);
+   valid_lft = max(valid_lft, minimum_lft);
+
+   /* RFC4862 Section 5.5.3e:
+* "Note that the preferred lifetime of the
+*  corresponding address is always reset to
+*  the Preferred Lifetime in the received
+*  Prefix Information option, regardless of
+*  whether the valid lifetime is also reset or
+*  ignored."
+*
+* So we should always update prefered_lft here.
+*/
+   update_lft = 1;
+   }
+
+   if (update_lft) {
+   ifp->valid_lft = valid_lft;
+   ifp->prefered_lft = prefered_lft;
+   ifp->tstamp = now;
+   flags = ifp->flags;
+   ifp->flags &= ~IFA_F_DEPRECATED;
+   spin_unlock_bh(>lock);
+
+   if (!(flags_F_TENTATIVE))
+   ipv6_ifa_notify(0, ifp);
+   } else
+   spin_unlock_bh(>lock);
+
+   manage_tempaddrs(in6_dev, ifp, valid_lft, prefered_lft,
+create, now);
+
+   

[RFC 07/12] addrconf: put prefix address add in an own function

2016-05-23 Thread Alexander Aring
This patch moves the functionality to add a RA PIO prefix generated
address in an own function. This move prepares to add a hook for
adding a second address for a second link-layer address. E.g. short
address for 802.15.4 6LoWPAN.

Cc: David S. Miller 
Cc: Alexey Kuznetsov 
Cc: James Morris 
Cc: Hideaki YOSHIFUJI 
Cc: Patrick McHardy 
Signed-off-by: Alexander Aring 
---
 net/ipv6/addrconf.c | 191 
 1 file changed, 102 insertions(+), 89 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index beaad49..393cdbf 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2333,6 +2333,104 @@ static bool is_addr_mode_generate_stable(struct 
inet6_dev *idev)
   idev->addr_gen_mode == IN6_ADDR_GEN_MODE_RANDOM;
 }
 
+static void addrconf_prefix_rcv_add_addr(struct net *net,
+struct net_device *dev,
+const struct prefix_info *pinfo,
+struct inet6_dev *in6_dev,
+const struct in6_addr *addr,
+int addr_type, u32 addr_flags,
+bool sllao, bool tokenized,
+__u32 valid_lft, u32 prefered_lft)
+{
+   struct inet6_ifaddr *ifp = ipv6_get_ifaddr(net, addr, dev, 1);
+   int create = 0, update_lft = 0;
+
+   if (!ifp && valid_lft) {
+   int max_addresses = in6_dev->cnf.max_addresses;
+
+#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+   if (in6_dev->cnf.optimistic_dad &&
+   !net->ipv6.devconf_all->forwarding && sllao)
+   addr_flags |= IFA_F_OPTIMISTIC;
+#endif
+
+   /* Do not allow to create too much of autoconfigured
+* addresses; this would be too easy way to crash kernel.
+*/
+   if (!max_addresses ||
+   ipv6_count_addresses(in6_dev) < max_addresses)
+   ifp = ipv6_add_addr(in6_dev, addr, NULL,
+   pinfo->prefix_len,
+   addr_type_ADDR_SCOPE_MASK,
+   addr_flags, valid_lft,
+   prefered_lft);
+
+   if (IS_ERR_OR_NULL(ifp)) {
+   in6_dev_put(in6_dev);
+   return;
+   }
+
+   update_lft = 0;
+   create = 1;
+   spin_lock_bh(>lock);
+   ifp->flags |= IFA_F_MANAGETEMPADDR;
+   ifp->cstamp = jiffies;
+   ifp->tokenized = tokenized;
+   spin_unlock_bh(>lock);
+   addrconf_dad_start(ifp);
+   }
+
+   if (ifp) {
+   u32 flags;
+   unsigned long now;
+   u32 stored_lft;
+
+   /* update lifetime (RFC2462 5.5.3 e) */
+   spin_lock_bh(>lock);
+   now = jiffies;
+   if (ifp->valid_lft > (now - ifp->tstamp) / HZ)
+   stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ;
+   else
+   stored_lft = 0;
+   if (!update_lft && !create && stored_lft) {
+   const u32 minimum_lft = min_t(u32,
+   stored_lft, MIN_VALID_LIFETIME);
+   valid_lft = max(valid_lft, minimum_lft);
+
+   /* RFC4862 Section 5.5.3e:
+* "Note that the preferred lifetime of the
+*  corresponding address is always reset to
+*  the Preferred Lifetime in the received
+*  Prefix Information option, regardless of
+*  whether the valid lifetime is also reset or
+*  ignored."
+*
+* So we should always update prefered_lft here.
+*/
+   update_lft = 1;
+   }
+
+   if (update_lft) {
+   ifp->valid_lft = valid_lft;
+   ifp->prefered_lft = prefered_lft;
+   ifp->tstamp = now;
+   flags = ifp->flags;
+   ifp->flags &= ~IFA_F_DEPRECATED;
+   spin_unlock_bh(>lock);
+
+   if (!(flags_F_TENTATIVE))
+   ipv6_ifa_notify(0, ifp);
+   } else
+   spin_unlock_bh(>lock);
+
+   manage_tempaddrs(in6_dev, ifp, valid_lft, prefered_lft,
+create, now);
+
+   in6_ifa_put(ifp);
+   addrconf_verify();
+