Skip to content

Commit

Permalink
Bonding: force user to add HWTSTAMP_FLAG_BONDED_PHC_INDEX when get/se…
Browse files Browse the repository at this point in the history
…t 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: Jakub Kicinski <[email protected]>
Fixes: 94dd016 ("bond: pass get_ts_info and SIOC[SG]HWTSTAMP ioctl to active device")
Signed-off-by: Hangbin Liu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
liuhangbin authored and davem330 committed Dec 14, 2021
1 parent 9c9211a commit 085d610
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
const struct net_device_ops *ops;
struct net_device *real_dev;
struct hwtstamp_config cfg;
struct ifreq ifrr;
int res = 0;

Expand Down Expand Up @@ -4124,21 +4125,29 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm
break;
case SIOCSHWTSTAMP:
case SIOCGHWTSTAMP:
rcu_read_lock();
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;
if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
return -EFAULT;

if (cfg.flags & HWTSTAMP_FLAG_BONDED_PHC_INDEX) {
rcu_read_lock();
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 (netif_device_present(real_dev) && ops->ndo_eth_ioctl)
res = ops->ndo_eth_ioctl(real_dev, &ifrr, cmd);
if (!res)
ifr->ifr_ifru = ifrr.ifr_ifru;

if (!res)
ifr->ifr_ifru = ifrr.ifr_ifru;
return res;
}
}
}
break;
fallthrough;
default:
res = -EOPNOTSUPP;
}
Expand Down

0 comments on commit 085d610

Please sign in to comment.