rtnetlink: prepare nla_put_iflink() to run under RCU
We want to be able to run rtnl_fill_ifinfo() under RCU protection instead of RTNL in the future. This patch prepares dev_get_iflink() and nla_put_iflink() to run either with RTNL or RCU held. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5f6000aa24
commit
e353ea9ce4
|
@ -1272,10 +1272,10 @@ static int ipoib_get_iflink(const struct net_device *dev)
|
||||||
|
|
||||||
/* parent interface */
|
/* parent interface */
|
||||||
if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags))
|
if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags))
|
||||||
return dev->ifindex;
|
return READ_ONCE(dev->ifindex);
|
||||||
|
|
||||||
/* child/vlan interface */
|
/* child/vlan interface */
|
||||||
return priv->parent->ifindex;
|
return READ_ONCE(priv->parent->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 ipoib_addr_hash(struct ipoib_neigh_hash *htbl, u8 *daddr)
|
static u32 ipoib_addr_hash(struct ipoib_neigh_hash *htbl, u8 *daddr)
|
||||||
|
|
|
@ -119,7 +119,7 @@ static int vxcan_get_iflink(const struct net_device *dev)
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
peer = rcu_dereference(priv->peer);
|
peer = rcu_dereference(priv->peer);
|
||||||
iflink = peer ? peer->ifindex : 0;
|
iflink = peer ? READ_ONCE(peer->ifindex) : 0;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
return iflink;
|
return iflink;
|
||||||
|
|
|
@ -98,7 +98,7 @@ static int rmnet_vnd_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rmnet_priv *priv = netdev_priv(dev);
|
struct rmnet_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
return priv->real_dev->ifindex;
|
return READ_ONCE(priv->real_dev->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rmnet_vnd_init(struct net_device *dev)
|
static int rmnet_vnd_init(struct net_device *dev)
|
||||||
|
|
|
@ -349,7 +349,7 @@ static int ipvlan_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ipvl_dev *ipvlan = netdev_priv(dev);
|
struct ipvl_dev *ipvlan = netdev_priv(dev);
|
||||||
|
|
||||||
return ipvlan->phy_dev->ifindex;
|
return READ_ONCE(ipvlan->phy_dev->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct net_device_ops ipvlan_netdev_ops = {
|
static const struct net_device_ops ipvlan_netdev_ops = {
|
||||||
|
|
|
@ -3753,7 +3753,7 @@ static void macsec_get_stats64(struct net_device *dev,
|
||||||
|
|
||||||
static int macsec_get_iflink(const struct net_device *dev)
|
static int macsec_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
return macsec_priv(dev)->real_dev->ifindex;
|
return READ_ONCE(macsec_priv(dev)->real_dev->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct net_device_ops macsec_netdev_ops = {
|
static const struct net_device_ops macsec_netdev_ops = {
|
||||||
|
|
|
@ -1158,7 +1158,7 @@ static int macvlan_dev_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct macvlan_dev *vlan = netdev_priv(dev);
|
struct macvlan_dev *vlan = netdev_priv(dev);
|
||||||
|
|
||||||
return vlan->lowerdev->ifindex;
|
return READ_ONCE(vlan->lowerdev->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ethtool_ops macvlan_ethtool_ops = {
|
static const struct ethtool_ops macvlan_ethtool_ops = {
|
||||||
|
|
|
@ -145,7 +145,7 @@ static int netkit_get_iflink(const struct net_device *dev)
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
peer = rcu_dereference(nk->peer);
|
peer = rcu_dereference(nk->peer);
|
||||||
if (peer)
|
if (peer)
|
||||||
iflink = peer->ifindex;
|
iflink = READ_ONCE(peer->ifindex);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return iflink;
|
return iflink;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1461,7 +1461,7 @@ static int veth_get_iflink(const struct net_device *dev)
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
peer = rcu_dereference(priv->peer);
|
peer = rcu_dereference(priv->peer);
|
||||||
iflink = peer ? peer->ifindex : 0;
|
iflink = peer ? READ_ONCE(peer->ifindex) : 0;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
return iflink;
|
return iflink;
|
||||||
|
|
|
@ -453,7 +453,7 @@ static int virt_wifi_net_device_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
|
struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
return priv->lowerdev->ifindex;
|
return READ_ONCE(priv->lowerdev->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct net_device_ops virt_wifi_ops = {
|
static const struct net_device_ops virt_wifi_ops = {
|
||||||
|
|
|
@ -762,9 +762,9 @@ static void vlan_dev_netpoll_cleanup(struct net_device *dev)
|
||||||
|
|
||||||
static int vlan_dev_get_iflink(const struct net_device *dev)
|
static int vlan_dev_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
|
const struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
|
||||||
|
|
||||||
return real_dev->ifindex;
|
return READ_ONCE(real_dev->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vlan_dev_fill_forward_path(struct net_device_path_ctx *ctx,
|
static int vlan_dev_fill_forward_path(struct net_device_path_ctx *ctx,
|
||||||
|
|
|
@ -641,7 +641,7 @@ int dev_get_iflink(const struct net_device *dev)
|
||||||
if (dev->netdev_ops && dev->netdev_ops->ndo_get_iflink)
|
if (dev->netdev_ops && dev->netdev_ops->ndo_get_iflink)
|
||||||
return dev->netdev_ops->ndo_get_iflink(dev);
|
return dev->netdev_ops->ndo_get_iflink(dev);
|
||||||
|
|
||||||
return dev->ifindex;
|
return READ_ONCE(dev->ifindex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dev_get_iflink);
|
EXPORT_SYMBOL(dev_get_iflink);
|
||||||
|
|
||||||
|
|
|
@ -1611,10 +1611,10 @@ static int put_master_ifindex(struct sk_buff *skb, struct net_device *dev)
|
||||||
static int nla_put_iflink(struct sk_buff *skb, const struct net_device *dev,
|
static int nla_put_iflink(struct sk_buff *skb, const struct net_device *dev,
|
||||||
bool force)
|
bool force)
|
||||||
{
|
{
|
||||||
int ifindex = dev_get_iflink(dev);
|
int iflink = dev_get_iflink(dev);
|
||||||
|
|
||||||
if (force || dev->ifindex != ifindex)
|
if (force || READ_ONCE(dev->ifindex) != iflink)
|
||||||
return nla_put_u32(skb, IFLA_LINK, ifindex);
|
return nla_put_u32(skb, IFLA_LINK, iflink);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,7 +352,7 @@ void dsa_user_mii_bus_init(struct dsa_switch *ds)
|
||||||
/* user device handling ****************************************************/
|
/* user device handling ****************************************************/
|
||||||
static int dsa_user_get_iflink(const struct net_device *dev)
|
static int dsa_user_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
return dsa_user_to_conduit(dev)->ifindex;
|
return READ_ONCE(dsa_user_to_conduit(dev)->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsa_user_open(struct net_device *dev)
|
static int dsa_user_open(struct net_device *dev)
|
||||||
|
|
|
@ -93,7 +93,7 @@ static int lowpan_neigh_construct(struct net_device *dev, struct neighbour *n)
|
||||||
|
|
||||||
static int lowpan_get_iflink(const struct net_device *dev)
|
static int lowpan_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
return lowpan_802154_dev(dev)->wdev->ifindex;
|
return READ_ONCE(lowpan_802154_dev(dev)->wdev->ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct net_device_ops lowpan_netdev_ops = {
|
static const struct net_device_ops lowpan_netdev_ops = {
|
||||||
|
|
|
@ -1756,7 +1756,7 @@ int ip6_tnl_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ip6_tnl *t = netdev_priv(dev);
|
struct ip6_tnl *t = netdev_priv(dev);
|
||||||
|
|
||||||
return t->parms.link;
|
return READ_ONCE(t->parms.link);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ip6_tnl_get_iflink);
|
EXPORT_SYMBOL(ip6_tnl_get_iflink);
|
||||||
|
|
||||||
|
|
|
@ -727,7 +727,7 @@ static int xfrmi_get_iflink(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct xfrm_if *xi = netdev_priv(dev);
|
struct xfrm_if *xi = netdev_priv(dev);
|
||||||
|
|
||||||
return xi->p.link;
|
return READ_ONCE(xi->p.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct net_device_ops xfrmi_netdev_ops = {
|
static const struct net_device_ops xfrmi_netdev_ops = {
|
||||||
|
|
Loading…
Reference in New Issue