All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses
@ 2013-11-11 14:49 Jiri Pirko
  2013-11-11 14:49 ` [patch net-next RFC 1/2] ipv6 addrconf: extend ifa_flags to u32 Jiri Pirko
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Jiri Pirko @ 2013-11-11 14:49 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

Jiri Pirko (2):
  ipv6 addrconf: extend ifa_flags to u32
  ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage
    temporary addresses

 include/net/if_inet6.h       |   2 +-
 include/uapi/linux/if_addr.h |   5 ++
 net/ipv6/addrconf.c          | 181 +++++++++++++++++++++++++------------------
 3 files changed, 110 insertions(+), 78 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [patch net-next RFC 1/2] ipv6 addrconf: extend ifa_flags to u32
  2013-11-11 14:49 [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses Jiri Pirko
@ 2013-11-11 14:49 ` Jiri Pirko
  2013-11-11 15:07   ` David Laight
  2013-11-11 14:49 ` [patch net-next RFC 2/2] ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses Jiri Pirko
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: Jiri Pirko @ 2013-11-11 14:49 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

There is no more space in u8 ifa_flags. So do what davem suffested and
add another netlink attr called IFA_FLAGS for carry more flags.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Thomas Haller <thaller@redhat.com>
---
 include/net/if_inet6.h       |  2 +-
 include/uapi/linux/if_addr.h |  4 ++++
 net/ipv6/addrconf.c          | 22 +++++++++++++++-------
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 76d5427..1c765f7 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -51,7 +51,7 @@ struct inet6_ifaddr {
 	int			state;
 
 	__u8			dad_probes;
-	__u8			flags;
+	__u32			flags;
 
 	__u16			scope;
 
diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h
index 23357ab..8ab0c2c 100644
--- a/include/uapi/linux/if_addr.h
+++ b/include/uapi/linux/if_addr.h
@@ -18,6 +18,9 @@ struct ifaddrmsg {
  * It makes no difference for normally configured broadcast interfaces,
  * but for point-to-point IFA_ADDRESS is DESTINATION address,
  * local address is supplied in IFA_LOCAL attribute.
+ *
+ * IFA_FLAGS is a u32 attribute that extends the u8 field ifa_flags.
+ * If present, the value from struct ifaddrmsg will be ignored.
  */
 enum {
 	IFA_UNSPEC,
@@ -28,6 +31,7 @@ enum {
 	IFA_ANYCAST,
 	IFA_CACHEINFO,
 	IFA_MULTICAST,
+	IFA_FLAGS,
 	__IFA_MAX,
 };
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 542d095..896aaa0 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2366,10 +2366,11 @@ err_exit:
 /*
  *	Manual configuration of address on an interface
  */
-static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx,
+static int inet6_addr_add(struct net *net, int ifindex,
+			  const struct in6_addr *pfx,
 			  const struct in6_addr *peer_pfx,
-			  unsigned int plen, __u8 ifa_flags, __u32 prefered_lft,
-			  __u32 valid_lft)
+			  unsigned int plen, __u32 ifa_flags,
+			  __u32 prefered_lft, __u32 valid_lft)
 {
 	struct inet6_ifaddr *ifp;
 	struct inet6_dev *idev;
@@ -3578,6 +3579,7 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
 	[IFA_ADDRESS]		= { .len = sizeof(struct in6_addr) },
 	[IFA_LOCAL]		= { .len = sizeof(struct in6_addr) },
 	[IFA_CACHEINFO]		= { .len = sizeof(struct ifa_cacheinfo) },
+	[IFA_FLAGS]		= { .len = sizeof(u32) },
 };
 
 static int
@@ -3601,7 +3603,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen);
 }
 
-static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
+static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
 			     u32 prefered_lft, u32 valid_lft)
 {
 	u32 flags;
@@ -3656,7 +3658,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	struct inet6_ifaddr *ifa;
 	struct net_device *dev;
 	u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME;
-	u8 ifa_flags;
+	u32 ifa_flags;
 	int err;
 
 	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
@@ -3683,8 +3685,10 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	if (dev == NULL)
 		return -ENODEV;
 
+	ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags;
+
 	/* We ignore other flags so far. */
-	ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS);
+	ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS;
 
 	ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
 	if (ifa == NULL) {
@@ -3751,7 +3755,8 @@ static inline int inet6_ifaddr_msgsize(void)
 	return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
 	       + nla_total_size(16) /* IFA_LOCAL */
 	       + nla_total_size(16) /* IFA_ADDRESS */
-	       + nla_total_size(sizeof(struct ifa_cacheinfo));
+	       + nla_total_size(sizeof(struct ifa_cacheinfo))
+	       + nla_total_size(4)  /* IFA_FLAGS */;
 }
 
 static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
@@ -3799,6 +3804,9 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
 	if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0)
 		goto error;
 
+	if (nla_put_u32(skb, IFA_FLAGS, ifa->flags) < 0)
+		goto error;
+
 	return nlmsg_end(skb, nlh);
 
 error:
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [patch net-next RFC 2/2] ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses
  2013-11-11 14:49 [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses Jiri Pirko
  2013-11-11 14:49 ` [patch net-next RFC 1/2] ipv6 addrconf: extend ifa_flags to u32 Jiri Pirko
@ 2013-11-11 14:49 ` Jiri Pirko
  2013-11-15 17:48   ` [PATCH 1/1] fixup! " Thomas Haller
  2013-11-15 18:04   ` [patch net-next RFC 2/2] " Thomas Haller
  2013-11-11 14:50 ` [patch iproute2 RFC 1/2] add support for extended ifa_flags Jiri Pirko
  2013-11-11 18:42 ` [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses David Miller
  3 siblings, 2 replies; 15+ messages in thread
From: Jiri Pirko @ 2013-11-11 14:49 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

Creating an address with this flag set will result in kernel taking care
of temporary addresses in the same way as if the address was created by
kernel itself (after RA receive). This allows userspace applications
implementing the autoconfiguration (NetworkManager for example) to
implement ipv6 addresses privacy.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Thomas Haller <thaller@redhat.com>
---
 include/uapi/linux/if_addr.h |   1 +
 net/ipv6/addrconf.c          | 161 ++++++++++++++++++++++++-------------------
 2 files changed, 91 insertions(+), 71 deletions(-)

diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h
index 8ab0c2c..cfed10b 100644
--- a/include/uapi/linux/if_addr.h
+++ b/include/uapi/linux/if_addr.h
@@ -48,6 +48,7 @@ enum {
 #define IFA_F_DEPRECATED	0x20
 #define IFA_F_TENTATIVE		0x40
 #define IFA_F_PERMANENT		0x80
+#define IFA_F_MANAGETEMPADDR	0x100
 
 struct ifa_cacheinfo {
 	__u32	ifa_prefered;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 896aaa0..c79b63e 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1010,7 +1010,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
 	u32 addr_flags;
 	unsigned long now = jiffies;
 
-	write_lock(&idev->lock);
+	write_lock_bh(&idev->lock);
 	if (ift) {
 		spin_lock_bh(&ift->lock);
 		memcpy(&addr.s6_addr[8], &ift->addr.s6_addr[8], 8);
@@ -1022,7 +1022,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
 retry:
 	in6_dev_hold(idev);
 	if (idev->cnf.use_tempaddr <= 0) {
-		write_unlock(&idev->lock);
+		write_unlock_bh(&idev->lock);
 		pr_info("%s: use_tempaddr is disabled\n", __func__);
 		in6_dev_put(idev);
 		ret = -1;
@@ -1032,7 +1032,7 @@ retry:
 	if (ifp->regen_count++ >= idev->cnf.regen_max_retry) {
 		idev->cnf.use_tempaddr = -1;	/*XXX*/
 		spin_unlock_bh(&ifp->lock);
-		write_unlock(&idev->lock);
+		write_unlock_bh(&idev->lock);
 		pr_warn("%s: regeneration time exceeded - disabled temporary address support\n",
 			__func__);
 		in6_dev_put(idev);
@@ -1058,7 +1058,7 @@ retry:
 	regen_advance = idev->cnf.regen_max_retry *
 	                idev->cnf.dad_transmits *
 	                idev->nd_parms->retrans_time / HZ;
-	write_unlock(&idev->lock);
+	write_unlock_bh(&idev->lock);
 
 	/* A temporary address is created only if this calculated Preferred
 	 * Lifetime is greater than REGEN_ADVANCE time units.  In particular,
@@ -1085,7 +1085,7 @@ retry:
 		in6_dev_put(idev);
 		pr_info("%s: retry temporary address regeneration\n", __func__);
 		tmpaddr = &addr;
-		write_lock(&idev->lock);
+		write_lock_bh(&idev->lock);
 		goto retry;
 	}
 
@@ -2019,6 +2019,73 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
 	return idev;
 }
 
+static void manage_tempaddrs(struct inet6_dev *idev,
+			     struct inet6_ifaddr *ifp,
+			     __u32 valid_lft, __u32 prefered_lft,
+			     bool create, unsigned long now)
+{
+	u32 flags;
+	struct inet6_ifaddr *ift;
+
+	read_lock_bh(&idev->lock);
+	/* update all temporary addresses in the list */
+	list_for_each_entry(ift, &idev->tempaddr_list, tmp_list) {
+		int age, max_valid, max_prefered;
+
+		if (ifp != ift->ifpub)
+			continue;
+
+		/* RFC 4941 section 3.3:
+		 * If a received option will extend the lifetime of a public
+		 * address, the lifetimes of temporary addresses should
+		 * be extended, subject to the overall constraint that no
+		 * temporary addresses should ever remain "valid" or "preferred"
+		 * for a time longer than (TEMP_VALID_LIFETIME) or
+		 * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), respectively.
+		 */
+		age = (now - ift->cstamp) / HZ;
+		max_valid = idev->cnf.temp_valid_lft - age;
+		if (max_valid < 0)
+			max_valid = 0;
+
+		max_prefered = idev->cnf.temp_prefered_lft -
+			       idev->cnf.max_desync_factor - age;
+		if (max_prefered < 0)
+			max_prefered = 0;
+
+		if (valid_lft > max_valid)
+			valid_lft = max_valid;
+
+		if (prefered_lft > max_prefered)
+			prefered_lft = max_prefered;
+
+		spin_lock(&ift->lock);
+		flags = ift->flags;
+		ift->valid_lft = valid_lft;
+		ift->prefered_lft = prefered_lft;
+		ift->tstamp = now;
+		if (prefered_lft > 0)
+			ift->flags &= ~IFA_F_DEPRECATED;
+
+		spin_unlock(&ift->lock);
+		if (!(flags&IFA_F_TENTATIVE))
+			ipv6_ifa_notify(0, ift);
+	}
+
+	if ((create || list_empty(&idev->tempaddr_list)) &&
+	    idev->cnf.use_tempaddr > 0) {
+		/* When a new public address is created as described
+		 * in [ADDRCONF], also create a new temporary address.
+		 * Also create a temporary address if it's enabled but
+		 * no temporary address currently exists.
+		 */
+		read_unlock_bh(&idev->lock);
+		ipv6_create_tempaddr(ifp, NULL);
+	} else {
+		read_unlock_bh(&idev->lock);
+	}
+}
+
 void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
 {
 	struct prefix_info *pinfo;
@@ -2173,6 +2240,7 @@ ok:
 				return;
 			}
 
+			ifp->flags |= IFA_F_MANAGETEMPADDR;
 			update_lft = 0;
 			create = 1;
 			ifp->cstamp = jiffies;
@@ -2183,7 +2251,6 @@ ok:
 		if (ifp) {
 			int flags;
 			unsigned long now;
-			struct inet6_ifaddr *ift;
 			u32 stored_lft;
 
 			/* update lifetime (RFC2462 5.5.3 e) */
@@ -2224,70 +2291,8 @@ ok:
 			} else
 				spin_unlock(&ifp->lock);
 
-			read_lock_bh(&in6_dev->lock);
-			/* update all temporary addresses in the list */
-			list_for_each_entry(ift, &in6_dev->tempaddr_list,
-					    tmp_list) {
-				int age, max_valid, max_prefered;
-
-				if (ifp != ift->ifpub)
-					continue;
-
-				/*
-				 * RFC 4941 section 3.3:
-				 * If a received option will extend the lifetime
-				 * of a public address, the lifetimes of
-				 * temporary addresses should be extended,
-				 * subject to the overall constraint that no
-				 * temporary addresses should ever remain
-				 * "valid" or "preferred" for a time longer than
-				 * (TEMP_VALID_LIFETIME) or
-				 * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR),
-				 * respectively.
-				 */
-				age = (now - ift->cstamp) / HZ;
-				max_valid = in6_dev->cnf.temp_valid_lft - age;
-				if (max_valid < 0)
-					max_valid = 0;
-
-				max_prefered = in6_dev->cnf.temp_prefered_lft -
-					       in6_dev->cnf.max_desync_factor -
-					       age;
-				if (max_prefered < 0)
-					max_prefered = 0;
-
-				if (valid_lft > max_valid)
-					valid_lft = max_valid;
-
-				if (prefered_lft > max_prefered)
-					prefered_lft = max_prefered;
-
-				spin_lock(&ift->lock);
-				flags = ift->flags;
-				ift->valid_lft = valid_lft;
-				ift->prefered_lft = prefered_lft;
-				ift->tstamp = now;
-				if (prefered_lft > 0)
-					ift->flags &= ~IFA_F_DEPRECATED;
-
-				spin_unlock(&ift->lock);
-				if (!(flags&IFA_F_TENTATIVE))
-					ipv6_ifa_notify(0, ift);
-			}
-
-			if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) {
-				/*
-				 * When a new public address is created as
-				 * described in [ADDRCONF], also create a new
-				 * temporary address. Also create a temporary
-				 * address if it's enabled but no temporary
-				 * address currently exists.
-				 */
-				read_unlock_bh(&in6_dev->lock);
-				ipv6_create_tempaddr(ifp, NULL);
-			} else {
-				read_unlock_bh(&in6_dev->lock);
-			}
+			manage_tempaddrs(in6_dev, ifp, valid_lft, prefered_lft,
+					 create, now);
 
 			in6_ifa_put(ifp);
 			addrconf_verify(0);
@@ -2382,6 +2387,9 @@ static int inet6_addr_add(struct net *net, int ifindex,
 
 	ASSERT_RTNL();
 
+	if (ifa_flags & IFA_F_MANAGETEMPADDR && plen != 64)
+		return -EINVAL;
+
 	if (plen > 128)
 		return -EINVAL;
 
@@ -2429,6 +2437,9 @@ static int inet6_addr_add(struct net *net, int ifindex,
 		 * manually configured addresses
 		 */
 		addrconf_dad_start(ifp);
+		if (ifa_flags & IFA_F_MANAGETEMPADDR)
+			manage_tempaddrs(idev, ifp, valid_lft, prefered_lft,
+					 true, jiffies);
 		in6_ifa_put(ifp);
 		addrconf_verify(0);
 		return 0;
@@ -3643,6 +3654,11 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
 
 	addrconf_prefix_route(&ifp->addr, ifp->prefix_len, ifp->idev->dev,
 			      expires, flags);
+
+	if (ifp->flags & IFA_F_MANAGETEMPADDR)
+		manage_tempaddrs(ifp->idev, ifp, valid_lft, prefered_lft,
+				 false, jiffies);
+
 	addrconf_verify(0);
 
 	return 0;
@@ -3688,7 +3704,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags;
 
 	/* We ignore other flags so far. */
-	ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS;
+	ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR;
 
 	ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
 	if (ifa == NULL) {
@@ -3701,6 +3717,9 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 				      preferred_lft, valid_lft);
 	}
 
+	/* We ignore IFA_F_MANAGETEMPADDR for modify. */
+	ifa_flags &= ~IFA_F_MANAGETEMPADDR;
+
 	if (nlh->nlmsg_flags & NLM_F_EXCL ||
 	    !(nlh->nlmsg_flags & NLM_F_REPLACE))
 		err = -EEXIST;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [patch iproute2 RFC 1/2] add support for extended ifa_flags
  2013-11-11 14:49 [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses Jiri Pirko
  2013-11-11 14:49 ` [patch net-next RFC 1/2] ipv6 addrconf: extend ifa_flags to u32 Jiri Pirko
  2013-11-11 14:49 ` [patch net-next RFC 2/2] ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses Jiri Pirko
@ 2013-11-11 14:50 ` Jiri Pirko
  2013-11-11 14:50   ` [patch iproute2 RFC 2/2] add support for IFA_F_MANAGETEMPADDR Jiri Pirko
  2013-11-11 18:42 ` [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses David Miller
  3 siblings, 1 reply; 15+ messages in thread
From: Jiri Pirko @ 2013-11-11 14:50 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 include/linux/if_addr.h |  1 +
 ip/ipaddress.c          | 44 ++++++++++++++++++++++++++++++--------------
 2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h
index 58b39f4..cced59f 100644
--- a/include/linux/if_addr.h
+++ b/include/linux/if_addr.h
@@ -28,6 +28,7 @@ enum {
 	IFA_ANYCAST,
 	IFA_CACHEINFO,
 	IFA_MULTICAST,
+	IFA_FLAGS,
 	__IFA_MAX,
 };
 
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 1c3e4da..59dbd71 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -541,6 +541,13 @@ static int set_lifetime(unsigned int *lifetime, char *argv)
 	return 0;
 }
 
+static unsigned int get_ifa_flags(struct ifaddrmsg *ifa,
+				  struct rtattr *ifa_flags_attr)
+{
+	return ifa_flags_attr ? rta_getattr_u32(ifa_flags_attr) :
+				ifa->ifa_flags;
+}
+
 int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
 		   void *arg)
 {
@@ -567,6 +574,8 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
 
 	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
 
+	ifa_flags = get_ifa_flags(ifa, rta_tb[IFA_FLAGS]);
+
 	if (!rta_tb[IFA_LOCAL])
 		rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
 	if (!rta_tb[IFA_ADDRESS])
@@ -576,7 +585,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
 		return 0;
 	if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
 		return 0;
-	if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
+	if ((filter.flags ^ ifa_flags) & filter.flagmask)
 		return 0;
 	if (filter.label) {
 		SPRINT_BUF(b1);
@@ -670,36 +679,35 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
 				    abuf, sizeof(abuf)));
 	}
 	fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
-	ifa_flags = ifa->ifa_flags;
-	if (ifa->ifa_flags&IFA_F_SECONDARY) {
+	if (ifa_flags & IFA_F_SECONDARY) {
 		ifa_flags &= ~IFA_F_SECONDARY;
 		if (ifa->ifa_family == AF_INET6)
 			fprintf(fp, "temporary ");
 		else
 			fprintf(fp, "secondary ");
 	}
-	if (ifa->ifa_flags&IFA_F_TENTATIVE) {
+	if (ifa_flags & IFA_F_TENTATIVE) {
 		ifa_flags &= ~IFA_F_TENTATIVE;
 		fprintf(fp, "tentative ");
 	}
-	if (ifa->ifa_flags&IFA_F_DEPRECATED) {
+	if (ifa_flags & IFA_F_DEPRECATED) {
 		ifa_flags &= ~IFA_F_DEPRECATED;
 		deprecated = 1;
 		fprintf(fp, "deprecated ");
 	}
-	if (ifa->ifa_flags&IFA_F_HOMEADDRESS) {
+	if (ifa_flags & IFA_F_HOMEADDRESS) {
 		ifa_flags &= ~IFA_F_HOMEADDRESS;
 		fprintf(fp, "home ");
 	}
-	if (ifa->ifa_flags&IFA_F_NODAD) {
+	if (ifa_flags & IFA_F_NODAD) {
 		ifa_flags &= ~IFA_F_NODAD;
 		fprintf(fp, "nodad ");
 	}
-	if (!(ifa->ifa_flags&IFA_F_PERMANENT)) {
+	if (!(ifa_flags & IFA_F_PERMANENT)) {
 		fprintf(fp, "dynamic ");
 	} else
 		ifa_flags &= ~IFA_F_PERMANENT;
-	if (ifa->ifa_flags&IFA_F_DADFAILED) {
+	if (ifa_flags & IFA_F_DADFAILED) {
 		ifa_flags &= ~IFA_F_DADFAILED;
 		fprintf(fp, "dadfailed ");
 	}
@@ -926,6 +934,8 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
 		for (a = ainfo->head; a; a = a->next) {
 			struct nlmsghdr *n = &a->h;
 			struct ifaddrmsg *ifa = NLMSG_DATA(n);
+			struct rtattr *tb[IFA_MAX + 1];
+			unsigned int ifa_flags;
 
 			if (ifa->ifa_index != ifi->ifi_index)
 				continue;
@@ -934,11 +944,13 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
 				continue;
 			if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
 				continue;
-			if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
+
+			parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
+			ifa_flags = get_ifa_flags(ifa, tb[IFA_FLAGS]);
+
+			if ((filter.flags ^ ifa_flags) & filter.flagmask)
 				continue;
 			if (filter.pfx.family || filter.label) {
-				struct rtattr *tb[IFA_MAX+1];
-				parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
 				if (!tb[IFA_LOCAL])
 					tb[IFA_LOCAL] = tb[IFA_ADDRESS];
 
@@ -1252,6 +1264,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
 	__u32 preferred_lft = INFINITY_LIFE_TIME;
 	__u32 valid_lft = INFINITY_LIFE_TIME;
 	struct ifa_cacheinfo cinfo;
+	unsigned int ifa_flags = 0;
 
 	memset(&req, 0, sizeof(req));
 
@@ -1329,9 +1342,9 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
 			if (set_lifetime(&preferred_lft, *argv))
 				invarg("preferred_lft value", *argv);
 		} else if (strcmp(*argv, "home") == 0) {
-			req.ifa.ifa_flags |= IFA_F_HOMEADDRESS;
+			ifa_flags |= IFA_F_HOMEADDRESS;
 		} else if (strcmp(*argv, "nodad") == 0) {
-			req.ifa.ifa_flags |= IFA_F_NODAD;
+			ifa_flags |= IFA_F_NODAD;
 		} else {
 			if (strcmp(*argv, "local") == 0) {
 				NEXT_ARG();
@@ -1349,6 +1362,9 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
 		}
 		argc--; argv++;
 	}
+	req.ifa.ifa_flags = ifa_flags & 0xff;
+	addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags);
+
 	if (d == NULL) {
 		fprintf(stderr, "Not enough information: \"dev\" argument is required.\n");
 		return -1;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [patch iproute2 RFC 2/2] add support for IFA_F_MANAGETEMPADDR
  2013-11-11 14:50 ` [patch iproute2 RFC 1/2] add support for extended ifa_flags Jiri Pirko
@ 2013-11-11 14:50   ` Jiri Pirko
  0 siblings, 0 replies; 15+ messages in thread
From: Jiri Pirko @ 2013-11-11 14:50 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 include/linux/if_addr.h | 1 +
 ip/ipaddress.c          | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h
index cced59f..e1e95ce 100644
--- a/include/linux/if_addr.h
+++ b/include/linux/if_addr.h
@@ -45,6 +45,7 @@ enum {
 #define IFA_F_DEPRECATED	0x20
 #define IFA_F_TENTATIVE		0x40
 #define IFA_F_PERMANENT		0x80
+#define IFA_F_MANAGETEMPADDR	0x0100
 
 struct ifa_cacheinfo {
 	__u32	ifa_prefered;
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 59dbd71..fa6417d 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -703,6 +703,10 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
 		ifa_flags &= ~IFA_F_NODAD;
 		fprintf(fp, "nodad ");
 	}
+	if (ifa_flags & IFA_F_MANAGETEMPADDR) {
+		ifa_flags &= ~IFA_F_MANAGETEMPADDR;
+		fprintf(fp, "mngtmpaddr ");
+	}
 	if (!(ifa_flags & IFA_F_PERMANENT)) {
 		fprintf(fp, "dynamic ");
 	} else
@@ -1345,6 +1349,8 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
 			ifa_flags |= IFA_F_HOMEADDRESS;
 		} else if (strcmp(*argv, "nodad") == 0) {
 			ifa_flags |= IFA_F_NODAD;
+		} else if (strcmp(*argv, "mngtmpaddr") == 0) {
+			ifa_flags |= IFA_F_MANAGETEMPADDR;
 		} else {
 			if (strcmp(*argv, "local") == 0) {
 				NEXT_ARG();
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* RE: [patch net-next RFC 1/2] ipv6 addrconf: extend ifa_flags to u32
  2013-11-11 14:49 ` [patch net-next RFC 1/2] ipv6 addrconf: extend ifa_flags to u32 Jiri Pirko
@ 2013-11-11 15:07   ` David Laight
  2013-11-11 15:12     ` Jiri Pirko
  0 siblings, 1 reply; 15+ messages in thread
From: David Laight @ 2013-11-11 15:07 UTC (permalink / raw)
  To: Jiri Pirko, netdev
  Cc: davem, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

> --- a/include/net/if_inet6.h
> +++ b/include/net/if_inet6.h
> @@ -51,7 +51,7 @@ struct inet6_ifaddr {
>  	int			state;
> 
>  	__u8			dad_probes;
> -	__u8			flags;
> +	__u32			flags;
> 
>  	__u16			scope;

That is adding a lot of padding.

	David

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch net-next RFC 1/2] ipv6 addrconf: extend ifa_flags to u32
  2013-11-11 15:07   ` David Laight
@ 2013-11-11 15:12     ` Jiri Pirko
  0 siblings, 0 replies; 15+ messages in thread
From: Jiri Pirko @ 2013-11-11 15:12 UTC (permalink / raw)
  To: David Laight
  Cc: netdev, davem, kuznet, jmorris, yoshfuji, kaber, thaller,
	stephen, hannes, vyasevich, dcbw

Mon, Nov 11, 2013 at 04:07:20PM CET, David.Laight@ACULAB.COM wrote:
>> --- a/include/net/if_inet6.h
>> +++ b/include/net/if_inet6.h
>> @@ -51,7 +51,7 @@ struct inet6_ifaddr {
>>  	int			state;
>> 
>>  	__u8			dad_probes;
>> -	__u8			flags;
>> +	__u32			flags;
>> 
>>  	__u16			scope;
>
>That is adding a lot of padding.

Allright. Will reorder. Thanks

>
>	David
>
>
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses
  2013-11-11 14:49 [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses Jiri Pirko
                   ` (2 preceding siblings ...)
  2013-11-11 14:50 ` [patch iproute2 RFC 1/2] add support for extended ifa_flags Jiri Pirko
@ 2013-11-11 18:42 ` David Miller
  2013-11-11 19:49   ` Jiri Pirko
  3 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2013-11-11 18:42 UTC (permalink / raw)
  To: jiri
  Cc: netdev, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw


I'm not really going to read patches not properly at least CC:'d to
netdev, sorry Jiri.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses
  2013-11-11 18:42 ` [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses David Miller
@ 2013-11-11 19:49   ` Jiri Pirko
  2013-11-11 20:01     ` David Miller
  0 siblings, 1 reply; 15+ messages in thread
From: Jiri Pirko @ 2013-11-11 19:49 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

Mon, Nov 11, 2013 at 07:42:43PM CET, davem@davemloft.net wrote:
>
>I'm not really going to read patches not properly at least CC:'d to
>netdev, sorry Jiri.

netdev is in "To:"

I marked the patches as "RFC" on patchwork. Maybe I should not do it
next time, right?

Thanks

Jiri

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses
  2013-11-11 19:49   ` Jiri Pirko
@ 2013-11-11 20:01     ` David Miller
  2013-11-11 21:04       ` Jiri Pirko
  0 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2013-11-11 20:01 UTC (permalink / raw)
  To: jiri
  Cc: netdev, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

From: Jiri Pirko <jiri@resnulli.us>
Date: Mon, 11 Nov 2013 20:49:01 +0100

> Mon, Nov 11, 2013 at 07:42:43PM CET, davem@davemloft.net wrote:
>>
>>I'm not really going to read patches not properly at least CC:'d to
>>netdev, sorry Jiri.
> 
> netdev is in "To:"
> 
> I marked the patches as "RFC" on patchwork. Maybe I should not do it
> next time, right?

I think you sent this multiple times, once without netdev in the CC: and
then again with it present.

In any event you did the right thing in the end, sorry about that :)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses
  2013-11-11 20:01     ` David Miller
@ 2013-11-11 21:04       ` Jiri Pirko
  2013-11-11 23:03         ` David Miller
  0 siblings, 1 reply; 15+ messages in thread
From: Jiri Pirko @ 2013-11-11 21:04 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

Mon, Nov 11, 2013 at 09:01:52PM CET, davem@davemloft.net wrote:
>From: Jiri Pirko <jiri@resnulli.us>
>Date: Mon, 11 Nov 2013 20:49:01 +0100
>
>> Mon, Nov 11, 2013 at 07:42:43PM CET, davem@davemloft.net wrote:
>>>
>>>I'm not really going to read patches not properly at least CC:'d to
>>>netdev, sorry Jiri.
>> 
>> netdev is in "To:"
>> 
>> I marked the patches as "RFC" on patchwork. Maybe I should not do it
>> next time, right?
>
>I think you sent this multiple times, once without netdev in the CC: and
>then again with it present.
>
>In any event you did the right thing in the end, sorry about that :)

Nope, I sent this only once.

Anyway, should I touch the state in netdev patchwork or should I always
leave that to you?

I'm used to set "changes requested" before I send another patch version
and "RFC" when I send RFC patch.

Thanks.

Jiri

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses
  2013-11-11 21:04       ` Jiri Pirko
@ 2013-11-11 23:03         ` David Miller
  0 siblings, 0 replies; 15+ messages in thread
From: David Miller @ 2013-11-11 23:03 UTC (permalink / raw)
  To: jiri
  Cc: netdev, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

From: Jiri Pirko <jiri@resnulli.us>
Date: Mon, 11 Nov 2013 22:04:04 +0100

> Anyway, should I touch the state in netdev patchwork or should I always
> leave that to you?
> 
> I'm used to set "changes requested" before I send another patch version
> and "RFC" when I send RFC patch.

I'd rather others not touch the patchwork state.

You plan to send this again, so whether it's marked RFC or changes requested
is not all that important :-)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/1] fixup! ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses
  2013-11-11 14:49 ` [patch net-next RFC 2/2] ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses Jiri Pirko
@ 2013-11-15 17:48   ` Thomas Haller
  2013-11-18 10:23     ` Jiri Pirko
  2013-11-15 18:04   ` [patch net-next RFC 2/2] " Thomas Haller
  1 sibling, 1 reply; 15+ messages in thread
From: Thomas Haller @ 2013-11-15 17:48 UTC (permalink / raw)
  To: jiri, netdev
  Cc: davem, kuznet, jmorris, yoshfuji, kaber, thaller, stephen,
	hannes, vyasevich, dcbw

Handle IFA_F_MANAGETEMPADDR flag when modifying existing addresses too.

Signed-off-by: Thomas Haller <thaller@redhat.com>
---
Hi,

I'd like to suggest this change, I think it makes it easier for the user space
application to set this flag of (potentially) existing addresses.

Note, that if the flag gets cleared if the ifa had it set before
and the temporary addresses will exprire immediatly. This makes sense
for me.

Or if we don't want this, then the command should fail (EEXIST?) when trying
to set MANAGETEMPADDR for an existing address that doesn't have the flag already.

Thomas

 net/ipv6/addrconf.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 9e217b8..9e726c8 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3613,20 +3613,21 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
 
 	return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen);
 }
 
 static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
 			     u32 prefered_lft, u32 valid_lft)
 {
 	u32 flags;
 	clock_t expires;
 	unsigned long timeout;
+	int mngtmp;
 
 	if (!valid_lft || (prefered_lft > valid_lft))
 		return -EINVAL;
 
 	timeout = addrconf_timeout_fixup(valid_lft, HZ);
 	if (addrconf_finite_timeout(timeout)) {
 		expires = jiffies_to_clock_t(timeout * HZ);
 		valid_lft = timeout;
 		flags = RTF_EXPIRES;
 	} else {
@@ -3636,35 +3637,48 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
 	}
 
 	timeout = addrconf_timeout_fixup(prefered_lft, HZ);
 	if (addrconf_finite_timeout(timeout)) {
 		if (timeout == 0)
 			ifa_flags |= IFA_F_DEPRECATED;
 		prefered_lft = timeout;
 	}
 
 	spin_lock_bh(&ifp->lock);
-	ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS)) | ifa_flags;
+	if (ifa_flags & IFA_F_MANAGETEMPADDR &&
+	    (ifp->prefix_len != 64 || ifp->flags & IFA_F_TEMPORARY)) {
+		spin_unlock_bh(&ifp->lock);
+		return -EEXIST;
+	}
+	mngtmp = ifp->flags & IFA_F_MANAGETEMPADDR;
+	ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS |
+				     IFA_F_MANAGETEMPADDR)) | ifa_flags;
 	ifp->tstamp = jiffies;
 	ifp->valid_lft = valid_lft;
 	ifp->prefered_lft = prefered_lft;
 
 	spin_unlock_bh(&ifp->lock);
 	if (!(ifp->flags&IFA_F_TENTATIVE))
 		ipv6_ifa_notify(0, ifp);
 
 	addrconf_prefix_route(&ifp->addr, ifp->prefix_len, ifp->idev->dev,
 			      expires, flags);
 
-	if (ifp->flags & IFA_F_MANAGETEMPADDR)
-		manage_tempaddrs(ifp->idev, ifp, valid_lft, prefered_lft,
+	if (mngtmp && !(ifa_flags & IFA_F_MANAGETEMPADDR)) {
+		/* expire the life time of the temporary addresses */
+		manage_tempaddrs(ifp->idev, ifp, 0, 0,
 				 false, jiffies);
+	} else if (ifa_flags & IFA_F_MANAGETEMPADDR) {
+		/* if we did not yet mngtmp, create temporary addresses */
+		manage_tempaddrs(ifp->idev, ifp, valid_lft, prefered_lft,
+				 !mngtmp, jiffies);
+	}
 
 	addrconf_verify(0);
 
 	return 0;
 }
 
 static int
 inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
 	struct net *net = sock_net(skb->sk);
@@ -3710,23 +3724,20 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	if (ifa == NULL) {
 		/*
 		 * It would be best to check for !NLM_F_CREATE here but
 		 * userspace alreay relies on not having to provide this.
 		 */
 		return inet6_addr_add(net, ifm->ifa_index, pfx, peer_pfx,
 				      ifm->ifa_prefixlen, ifa_flags,
 				      preferred_lft, valid_lft);
 	}
 
-	/* We ignore IFA_F_MANAGETEMPADDR for modify. */
-	ifa_flags &= ~IFA_F_MANAGETEMPADDR;
-
 	if (nlh->nlmsg_flags & NLM_F_EXCL ||
 	    !(nlh->nlmsg_flags & NLM_F_REPLACE))
 		err = -EEXIST;
 	else
 		err = inet6_addr_modify(ifa, ifa_flags, preferred_lft, valid_lft);
 
 	in6_ifa_put(ifa);
 
 	return err;
 }
-- 
1.8.4.1.559.gdb9bdfb

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [patch net-next RFC 2/2] ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses
  2013-11-11 14:49 ` [patch net-next RFC 2/2] ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses Jiri Pirko
  2013-11-15 17:48   ` [PATCH 1/1] fixup! " Thomas Haller
@ 2013-11-15 18:04   ` Thomas Haller
  1 sibling, 0 replies; 15+ messages in thread
From: Thomas Haller @ 2013-11-15 18:04 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, kuznet, jmorris, yoshfuji, kaber, stephen, hannes,
	vyasevich, dcbw

[-- Attachment #1: Type: text/plain, Size: 895 bytes --]

On Mon, 2013-11-11 at 15:49 +0100, Jiri Pirko wrote:
> Creating an address with this flag set will result in kernel taking care
> of temporary addresses in the same way as if the address was created by
> kernel itself (after RA receive). This allows userspace applications
> implementing the autoconfiguration (NetworkManager for example) to
> implement ipv6 addresses privacy.

Hi,

I think, addrconf_prefix_rcv should not do anything if user created ones
already exist.

"Already exist" could mean, a user created address with:
- the same IP address and MANAGETEMPADDR flag
- the same IP address
- the same /64 prefix and MANAGETEMPADDR flag
- the same /64 prefix
(??)

Of course, the user should disable accept_ra, if he wants to manage
the temporary addresses himself. But it would still be more correct
to check that prefixes from RA do not interfere.


Thomas



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/1] fixup! ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses
  2013-11-15 17:48   ` [PATCH 1/1] fixup! " Thomas Haller
@ 2013-11-18 10:23     ` Jiri Pirko
  0 siblings, 0 replies; 15+ messages in thread
From: Jiri Pirko @ 2013-11-18 10:23 UTC (permalink / raw)
  To: Thomas Haller
  Cc: netdev, davem, kuznet, jmorris, yoshfuji, kaber, stephen, hannes,
	vyasevich, dcbw

Okay. I will try incorporate modify into my patch. Thanks.

Fri, Nov 15, 2013 at 06:48:46PM CET, thaller@redhat.com wrote:
>Handle IFA_F_MANAGETEMPADDR flag when modifying existing addresses too.
>
>Signed-off-by: Thomas Haller <thaller@redhat.com>
>---
>Hi,
>
>I'd like to suggest this change, I think it makes it easier for the user space
>application to set this flag of (potentially) existing addresses.
>
>Note, that if the flag gets cleared if the ifa had it set before
>and the temporary addresses will exprire immediatly. This makes sense
>for me.
>
>Or if we don't want this, then the command should fail (EEXIST?) when trying
>to set MANAGETEMPADDR for an existing address that doesn't have the flag already.
>
>Thomas
>
> net/ipv6/addrconf.c | 23 +++++++++++++++++------
> 1 file changed, 17 insertions(+), 6 deletions(-)
>
>diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
>index 9e217b8..9e726c8 100644
>--- a/net/ipv6/addrconf.c
>+++ b/net/ipv6/addrconf.c
>@@ -3613,20 +3613,21 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
> 
> 	return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen);
> }
> 
> static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
> 			     u32 prefered_lft, u32 valid_lft)
> {
> 	u32 flags;
> 	clock_t expires;
> 	unsigned long timeout;
>+	int mngtmp;
> 
> 	if (!valid_lft || (prefered_lft > valid_lft))
> 		return -EINVAL;
> 
> 	timeout = addrconf_timeout_fixup(valid_lft, HZ);
> 	if (addrconf_finite_timeout(timeout)) {
> 		expires = jiffies_to_clock_t(timeout * HZ);
> 		valid_lft = timeout;
> 		flags = RTF_EXPIRES;
> 	} else {
>@@ -3636,35 +3637,48 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
> 	}
> 
> 	timeout = addrconf_timeout_fixup(prefered_lft, HZ);
> 	if (addrconf_finite_timeout(timeout)) {
> 		if (timeout == 0)
> 			ifa_flags |= IFA_F_DEPRECATED;
> 		prefered_lft = timeout;
> 	}
> 
> 	spin_lock_bh(&ifp->lock);
>-	ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS)) | ifa_flags;
>+	if (ifa_flags & IFA_F_MANAGETEMPADDR &&
>+	    (ifp->prefix_len != 64 || ifp->flags & IFA_F_TEMPORARY)) {
>+		spin_unlock_bh(&ifp->lock);
>+		return -EEXIST;
>+	}
>+	mngtmp = ifp->flags & IFA_F_MANAGETEMPADDR;
>+	ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS |
>+				     IFA_F_MANAGETEMPADDR)) | ifa_flags;
> 	ifp->tstamp = jiffies;
> 	ifp->valid_lft = valid_lft;
> 	ifp->prefered_lft = prefered_lft;
> 
> 	spin_unlock_bh(&ifp->lock);
> 	if (!(ifp->flags&IFA_F_TENTATIVE))
> 		ipv6_ifa_notify(0, ifp);
> 
> 	addrconf_prefix_route(&ifp->addr, ifp->prefix_len, ifp->idev->dev,
> 			      expires, flags);
> 
>-	if (ifp->flags & IFA_F_MANAGETEMPADDR)
>-		manage_tempaddrs(ifp->idev, ifp, valid_lft, prefered_lft,
>+	if (mngtmp && !(ifa_flags & IFA_F_MANAGETEMPADDR)) {
>+		/* expire the life time of the temporary addresses */
>+		manage_tempaddrs(ifp->idev, ifp, 0, 0,
> 				 false, jiffies);
>+	} else if (ifa_flags & IFA_F_MANAGETEMPADDR) {
>+		/* if we did not yet mngtmp, create temporary addresses */
>+		manage_tempaddrs(ifp->idev, ifp, valid_lft, prefered_lft,
>+				 !mngtmp, jiffies);
>+	}
> 
> 	addrconf_verify(0);
> 
> 	return 0;
> }
> 
> static int
> inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
> {
> 	struct net *net = sock_net(skb->sk);
>@@ -3710,23 +3724,20 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
> 	if (ifa == NULL) {
> 		/*
> 		 * It would be best to check for !NLM_F_CREATE here but
> 		 * userspace alreay relies on not having to provide this.
> 		 */
> 		return inet6_addr_add(net, ifm->ifa_index, pfx, peer_pfx,
> 				      ifm->ifa_prefixlen, ifa_flags,
> 				      preferred_lft, valid_lft);
> 	}
> 
>-	/* We ignore IFA_F_MANAGETEMPADDR for modify. */
>-	ifa_flags &= ~IFA_F_MANAGETEMPADDR;
>-
> 	if (nlh->nlmsg_flags & NLM_F_EXCL ||
> 	    !(nlh->nlmsg_flags & NLM_F_REPLACE))
> 		err = -EEXIST;
> 	else
> 		err = inet6_addr_modify(ifa, ifa_flags, preferred_lft, valid_lft);
> 
> 	in6_ifa_put(ifa);
> 
> 	return err;
> }
>-- 
>1.8.4.1.559.gdb9bdfb
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2013-11-18 10:23 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-11 14:49 [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses Jiri Pirko
2013-11-11 14:49 ` [patch net-next RFC 1/2] ipv6 addrconf: extend ifa_flags to u32 Jiri Pirko
2013-11-11 15:07   ` David Laight
2013-11-11 15:12     ` Jiri Pirko
2013-11-11 14:49 ` [patch net-next RFC 2/2] ipv6 addrconf: introduce IFA_F_MANAGETEMPADDR to tell kernel to manage temporary addresses Jiri Pirko
2013-11-15 17:48   ` [PATCH 1/1] fixup! " Thomas Haller
2013-11-18 10:23     ` Jiri Pirko
2013-11-15 18:04   ` [patch net-next RFC 2/2] " Thomas Haller
2013-11-11 14:50 ` [patch iproute2 RFC 1/2] add support for extended ifa_flags Jiri Pirko
2013-11-11 14:50   ` [patch iproute2 RFC 2/2] add support for IFA_F_MANAGETEMPADDR Jiri Pirko
2013-11-11 18:42 ` [patch net-next RFC 0/2] ipv6: allow temporary address management for user-created addresses David Miller
2013-11-11 19:49   ` Jiri Pirko
2013-11-11 20:01     ` David Miller
2013-11-11 21:04       ` Jiri Pirko
2013-11-11 23:03         ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.