Commit 6046d5b4 authored by Heiner Kallweit's avatar Heiner Kallweit Committed by David S. Miller

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: default avatarHeiner Kallweit <heiner.kallweit@web.de>
Reviewed-by: default avatarJiri Pirko <jiri@resnulli.us>
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0080d4f5
...@@ -2504,8 +2504,8 @@ static int inet6_addr_add(struct net *net, int ifindex, ...@@ -2504,8 +2504,8 @@ static int inet6_addr_add(struct net *net, int ifindex,
return PTR_ERR(ifp); return PTR_ERR(ifp);
} }
static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *pfx, static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
unsigned int plen) const struct in6_addr *pfx, unsigned int plen)
{ {
struct inet6_ifaddr *ifp; struct inet6_ifaddr *ifp;
struct inet6_dev *idev; struct inet6_dev *idev;
...@@ -2528,7 +2528,12 @@ static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *p ...@@ -2528,7 +2528,12 @@ static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *p
in6_ifa_hold(ifp); in6_ifa_hold(ifp);
read_unlock_bh(&idev->lock); read_unlock_bh(&idev->lock);
if (!(ifp->flags & IFA_F_TEMPORARY) &&
(ifa_flags & IFA_F_MANAGETEMPADDR))
manage_tempaddrs(idev, ifp, 0, 0, false,
jiffies);
ipv6_del_addr(ifp); ipv6_del_addr(ifp);
addrconf_verify_rtnl();
return 0; return 0;
} }
} }
...@@ -2568,7 +2573,7 @@ int addrconf_del_ifaddr(struct net *net, void __user *arg) ...@@ -2568,7 +2573,7 @@ int addrconf_del_ifaddr(struct net *net, void __user *arg)
return -EFAULT; return -EFAULT;
rtnl_lock(); rtnl_lock();
err = inet6_addr_del(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, err = inet6_addr_del(net, ireq.ifr6_ifindex, 0, &ireq.ifr6_addr,
ireq.ifr6_prefixlen); ireq.ifr6_prefixlen);
rtnl_unlock(); rtnl_unlock();
return err; return err;
...@@ -3743,6 +3748,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -3743,6 +3748,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
struct ifaddrmsg *ifm; struct ifaddrmsg *ifm;
struct nlattr *tb[IFA_MAX+1]; struct nlattr *tb[IFA_MAX+1];
struct in6_addr *pfx, *peer_pfx; struct in6_addr *pfx, *peer_pfx;
u32 ifa_flags;
int err; int err;
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 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,7 +3760,13 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
if (pfx == NULL) if (pfx == NULL)
return -EINVAL; return -EINVAL;
return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags;
/* We ignore other flags so far. */
ifa_flags &= IFA_F_MANAGETEMPADDR;
return inet6_addr_del(net, ifm->ifa_index, ifa_flags, pfx,
ifm->ifa_prefixlen);
} }
static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment