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>
This commit is contained in:
parent
0080d4f5f2
commit
6046d5b4e4
|
@ -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
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
|
|
Loading…
Reference in a new issue