aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorHeiner Kallweit <heiner.kallweit@web.de>2014-04-20 15:29:36 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-22 21:27:57 -0400
commit6046d5b4e464ba9b2cc8f0407069456624598dd5 (patch)
tree5f853f7c19f01d8a3c780995c85717ee8cd708a0 /net/ipv6/addrconf.c
parent0080d4f5f21861da5d5c0bf443e6ba1222c6af7b (diff)
ipv6: support IFA_F_MANAGETEMPADDR for address deletion too
Userspace applications can use IFA_F_MANAGETEMPADDR with RTM_NEWADDR already to indicate that the kernel should take care of temporary address management. This patch adds related functionality to RTM_DELADDR. By setting IFA_F_MANAGETEMPADDR a userspace application can indicate that the kernel should delete all related temporary addresses as well. A corresponding patch for the "ip addr del" command has been applied to iproute2 already. Signed-off-by: Heiner Kallweit <heiner.kallweit@web.de> Reviewed-by: Jiri Pirko <jiri@resnulli.us> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6c7fa0853fc7..fc203db2211a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2504,8 +2504,8 @@ static int inet6_addr_add(struct net *net, int ifindex,
2504 return PTR_ERR(ifp); 2504 return PTR_ERR(ifp);
2505} 2505}
2506 2506
2507static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *pfx, 2507static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
2508 unsigned int plen) 2508 const struct in6_addr *pfx, unsigned int plen)
2509{ 2509{
2510 struct inet6_ifaddr *ifp; 2510 struct inet6_ifaddr *ifp;
2511 struct inet6_dev *idev; 2511 struct inet6_dev *idev;
@@ -2528,7 +2528,12 @@ static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *p
2528 in6_ifa_hold(ifp); 2528 in6_ifa_hold(ifp);
2529 read_unlock_bh(&idev->lock); 2529 read_unlock_bh(&idev->lock);
2530 2530
2531 if (!(ifp->flags & IFA_F_TEMPORARY) &&
2532 (ifa_flags & IFA_F_MANAGETEMPADDR))
2533 manage_tempaddrs(idev, ifp, 0, 0, false,
2534 jiffies);
2531 ipv6_del_addr(ifp); 2535 ipv6_del_addr(ifp);
2536 addrconf_verify_rtnl();
2532 return 0; 2537 return 0;
2533 } 2538 }
2534 } 2539 }
@@ -2568,7 +2573,7 @@ int addrconf_del_ifaddr(struct net *net, void __user *arg)
2568 return -EFAULT; 2573 return -EFAULT;
2569 2574
2570 rtnl_lock(); 2575 rtnl_lock();
2571 err = inet6_addr_del(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, 2576 err = inet6_addr_del(net, ireq.ifr6_ifindex, 0, &ireq.ifr6_addr,
2572 ireq.ifr6_prefixlen); 2577 ireq.ifr6_prefixlen);
2573 rtnl_unlock(); 2578 rtnl_unlock();
2574 return err; 2579 return err;
@@ -3743,6 +3748,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
3743 struct ifaddrmsg *ifm; 3748 struct ifaddrmsg *ifm;
3744 struct nlattr *tb[IFA_MAX+1]; 3749 struct nlattr *tb[IFA_MAX+1];
3745 struct in6_addr *pfx, *peer_pfx; 3750 struct in6_addr *pfx, *peer_pfx;
3751 u32 ifa_flags;
3746 int err; 3752 int err;
3747 3753
3748 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 3754 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
@@ -3754,7 +3760,13 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
3754 if (pfx == NULL) 3760 if (pfx == NULL)
3755 return -EINVAL; 3761 return -EINVAL;
3756 3762
3757 return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); 3763 ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags;
3764
3765 /* We ignore other flags so far. */
3766 ifa_flags &= IFA_F_MANAGETEMPADDR;
3767
3768 return inet6_addr_del(net, ifm->ifa_index, ifa_flags, pfx,
3769 ifm->ifa_prefixlen);
3758} 3770}
3759 3771
3760static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, 3772static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,