Commit 085d6100 authored by Hangbin Liu's avatar Hangbin Liu Committed by David S. Miller

Bonding: force user to add HWTSTAMP_FLAG_BONDED_PHC_INDEX when get/set HWTSTAMP

When there is a failover, the PHC index of bond active interface will be
changed. This may break the user space program if the author didn't aware.

By setting this flag, the user should aware that the PHC index get/set
by syscall is not stable. And the user space is able to deal with it.
Without this flag, the kernel will reject the request forwarding to
bonding.
Reported-by: default avatarJakub Kicinski <kuba@kernel.org>
Fixes: 94dd016a ("bond: pass get_ts_info and SIOC[SG]HWTSTAMP ioctl to active device")
Signed-off-by: default avatarHangbin Liu <liuhangbin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9c9211a3
...@@ -4094,6 +4094,7 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm ...@@ -4094,6 +4094,7 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm
struct mii_ioctl_data *mii = NULL; struct mii_ioctl_data *mii = NULL;
const struct net_device_ops *ops; const struct net_device_ops *ops;
struct net_device *real_dev; struct net_device *real_dev;
struct hwtstamp_config cfg;
struct ifreq ifrr; struct ifreq ifrr;
int res = 0; int res = 0;
...@@ -4124,21 +4125,29 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm ...@@ -4124,21 +4125,29 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm
break; break;
case SIOCSHWTSTAMP: case SIOCSHWTSTAMP:
case SIOCGHWTSTAMP: case SIOCGHWTSTAMP:
rcu_read_lock(); if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
real_dev = bond_option_active_slave_get_rcu(bond); return -EFAULT;
rcu_read_unlock();
if (real_dev) { if (cfg.flags & HWTSTAMP_FLAG_BONDED_PHC_INDEX) {
strscpy_pad(ifrr.ifr_name, real_dev->name, IFNAMSIZ); rcu_read_lock();
ifrr.ifr_ifru = ifr->ifr_ifru; real_dev = bond_option_active_slave_get_rcu(bond);
rcu_read_unlock();
if (real_dev) {
strscpy_pad(ifrr.ifr_name, real_dev->name, IFNAMSIZ);
ifrr.ifr_ifru = ifr->ifr_ifru;
ops = real_dev->netdev_ops;
if (netif_device_present(real_dev) && ops->ndo_eth_ioctl) {
res = ops->ndo_eth_ioctl(real_dev, &ifrr, cmd);
ops = real_dev->netdev_ops; if (!res)
if (netif_device_present(real_dev) && ops->ndo_eth_ioctl) ifr->ifr_ifru = ifrr.ifr_ifru;
res = ops->ndo_eth_ioctl(real_dev, &ifrr, cmd);
if (!res) return res;
ifr->ifr_ifru = ifrr.ifr_ifru; }
}
} }
break; fallthrough;
default: default:
res = -EOPNOTSUPP; res = -EOPNOTSUPP;
} }
......
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