diff options
author | Heiner Kallweit <heiner.kallweit@web.de> | 2014-04-20 15:29:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-04-22 21:27:57 -0400 |
commit | 6046d5b4e464ba9b2cc8f0407069456624598dd5 (patch) | |
tree | 5f853f7c19f01d8a3c780995c85717ee8cd708a0 /net/ipv6/addrconf.c | |
parent | 0080d4f5f21861da5d5c0bf443e6ba1222c6af7b (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.c | 20 |
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 | ||
2507 | static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *pfx, | 2507 | static 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 | ||
3760 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, | 3772 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, |