mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
ipv4: Set ifa->ifa_dev in inet_alloc_ifa().
When a new IPv4 address is assigned via ioctl(SIOCSIFADDR), inet_set_ifa() sets ifa->ifa_dev if it's different from in_dev passed as an argument. In this case, ifa is always a newly allocated object, and ifa->ifa_dev is NULL. inet_set_ifa() can be called for an existing reused ifa, then, this check is always false. Let's set ifa_dev in inet_alloc_ifa() and remove the check in inet_set_ifa(). Now, inet_alloc_ifa() is symmetric with inet_rcu_free_ifa(). Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20240809235406.50187-3-kuniyu@amazon.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
e3af3d3c5b
commit
6e701eb914
|
|
@ -216,9 +216,18 @@ static void devinet_sysctl_unregister(struct in_device *idev)
|
|||
|
||||
/* Locks all the inet devices. */
|
||||
|
||||
static struct in_ifaddr *inet_alloc_ifa(void)
|
||||
static struct in_ifaddr *inet_alloc_ifa(struct in_device *in_dev)
|
||||
{
|
||||
return kzalloc(sizeof(struct in_ifaddr), GFP_KERNEL_ACCOUNT);
|
||||
struct in_ifaddr *ifa;
|
||||
|
||||
ifa = kzalloc(sizeof(*ifa), GFP_KERNEL_ACCOUNT);
|
||||
if (!ifa)
|
||||
return NULL;
|
||||
|
||||
in_dev_hold(in_dev);
|
||||
ifa->ifa_dev = in_dev;
|
||||
|
||||
return ifa;
|
||||
}
|
||||
|
||||
static void inet_rcu_free_ifa(struct rcu_head *head)
|
||||
|
|
@ -576,11 +585,7 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
|
|||
|
||||
ipv4_devconf_setall(in_dev);
|
||||
neigh_parms_data_state_setall(in_dev->arp_parms);
|
||||
if (ifa->ifa_dev != in_dev) {
|
||||
WARN_ON(ifa->ifa_dev);
|
||||
in_dev_hold(in_dev);
|
||||
ifa->ifa_dev = in_dev;
|
||||
}
|
||||
|
||||
if (ipv4_is_loopback(ifa->ifa_local))
|
||||
ifa->ifa_scope = RT_SCOPE_HOST;
|
||||
return inet_insert_ifa(ifa);
|
||||
|
|
@ -871,7 +876,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
|
|||
if (!in_dev)
|
||||
goto errout;
|
||||
|
||||
ifa = inet_alloc_ifa();
|
||||
ifa = inet_alloc_ifa(in_dev);
|
||||
if (!ifa)
|
||||
/*
|
||||
* A potential indev allocation can be left alive, it stays
|
||||
|
|
@ -881,7 +886,6 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
|
|||
|
||||
ipv4_devconf_setall(in_dev);
|
||||
neigh_parms_data_state_setall(in_dev->arp_parms);
|
||||
in_dev_hold(in_dev);
|
||||
|
||||
if (!tb[IFA_ADDRESS])
|
||||
tb[IFA_ADDRESS] = tb[IFA_LOCAL];
|
||||
|
|
@ -892,8 +896,6 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
|
|||
ifa->ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) :
|
||||
ifm->ifa_flags;
|
||||
ifa->ifa_scope = ifm->ifa_scope;
|
||||
ifa->ifa_dev = in_dev;
|
||||
|
||||
ifa->ifa_local = nla_get_in_addr(tb[IFA_LOCAL]);
|
||||
ifa->ifa_address = nla_get_in_addr(tb[IFA_ADDRESS]);
|
||||
|
||||
|
|
@ -1182,7 +1184,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr)
|
|||
ret = -ENOBUFS;
|
||||
if (!in_dev)
|
||||
break;
|
||||
ifa = inet_alloc_ifa();
|
||||
ifa = inet_alloc_ifa(in_dev);
|
||||
if (!ifa)
|
||||
break;
|
||||
INIT_HLIST_NODE(&ifa->hash);
|
||||
|
|
@ -1584,7 +1586,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
|
|||
if (!inetdev_valid_mtu(dev->mtu))
|
||||
break;
|
||||
if (dev->flags & IFF_LOOPBACK) {
|
||||
struct in_ifaddr *ifa = inet_alloc_ifa();
|
||||
struct in_ifaddr *ifa = inet_alloc_ifa(in_dev);
|
||||
|
||||
if (ifa) {
|
||||
INIT_HLIST_NODE(&ifa->hash);
|
||||
|
|
@ -1592,8 +1594,6 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
|
|||
ifa->ifa_address = htonl(INADDR_LOOPBACK);
|
||||
ifa->ifa_prefixlen = 8;
|
||||
ifa->ifa_mask = inet_make_mask(8);
|
||||
in_dev_hold(in_dev);
|
||||
ifa->ifa_dev = in_dev;
|
||||
ifa->ifa_scope = RT_SCOPE_HOST;
|
||||
memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
|
||||
set_ifa_lifetime(ifa, INFINITY_LIFE_TIME,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user