]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
phonet: Pass net and ifindex to rtm_phonet_notify().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Thu, 17 Oct 2024 18:31:38 +0000 (11:31 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 24 Oct 2024 14:03:40 +0000 (16:03 +0200)
Currently, rtm_phonet_notify() fetches netns and ifindex from dev.

Once route_doit() is converted to RCU, rtm_phonet_notify() will be
called outside of RCU due to GFP_KERNEL, and dev will be unavailable
there.

Let's pass net and ifindex to rtm_phonet_notify().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
include/net/phonet/pn_dev.h
net/phonet/pn_dev.c
net/phonet/pn_netlink.c

index ac0331d83a810b9791f7f02bd06071589420351a..021e524fd20a873ee1766dddced1701963e69361 100644 (file)
@@ -43,7 +43,7 @@ void phonet_address_notify(struct net *net, int event, u32 ifindex, u8 addr);
 
 int phonet_route_add(struct net_device *dev, u8 daddr);
 int phonet_route_del(struct net_device *dev, u8 daddr);
-void rtm_phonet_notify(int event, struct net_device *dev, u8 dst);
+void rtm_phonet_notify(struct net *net, int event, u32 ifindex, u8 dst);
 struct net_device *phonet_route_get_rcu(struct net *net, u8 daddr);
 struct net_device *phonet_route_output(struct net *net, u8 daddr);
 
index 545279ef591082cd5996c02545f09f974377e86e..6ded0d347b9fd4fef0082a12871cce4d6d1e736d 100644 (file)
@@ -263,9 +263,13 @@ static int phonet_device_autoconf(struct net_device *dev)
 
 static void phonet_route_autodel(struct net_device *dev)
 {
-       struct phonet_net *pnn = phonet_pernet(dev_net(dev));
-       unsigned int i;
+       struct net *net = dev_net(dev);
        DECLARE_BITMAP(deleted, 64);
+       u32 ifindex = dev->ifindex;
+       struct phonet_net *pnn;
+       unsigned int i;
+
+       pnn = phonet_pernet(net);
 
        /* Remove left-over Phonet routes */
        bitmap_zero(deleted, 64);
@@ -281,7 +285,7 @@ static void phonet_route_autodel(struct net_device *dev)
                return; /* short-circuit RCU */
        synchronize_rcu();
        for_each_set_bit(i, deleted, 64) {
-               rtm_phonet_notify(RTM_DELROUTE, dev, i);
+               rtm_phonet_notify(net, RTM_DELROUTE, ifindex, i);
                dev_put(dev);
        }
 }
index c9a4215ec560cd22890d4f650dee9cf85e891183..bfec5bd639b64043b979d1e8f52e8f4561d660f6 100644 (file)
@@ -200,7 +200,7 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
-void rtm_phonet_notify(int event, struct net_device *dev, u8 dst)
+void rtm_phonet_notify(struct net *net, int event, u32 ifindex, u8 dst)
 {
        struct sk_buff *skb;
        int err = -ENOBUFS;
@@ -210,17 +210,17 @@ void rtm_phonet_notify(int event, struct net_device *dev, u8 dst)
        if (skb == NULL)
                goto errout;
 
-       err = fill_route(skb, dev->ifindex, dst, 0, 0, event);
+       err = fill_route(skb, ifindex, dst, 0, 0, event);
        if (err < 0) {
                WARN_ON(err == -EMSGSIZE);
                kfree_skb(skb);
                goto errout;
        }
-       rtnl_notify(skb, dev_net(dev), 0,
-                         RTNLGRP_PHONET_ROUTE, NULL, GFP_KERNEL);
+
+       rtnl_notify(skb, net, 0, RTNLGRP_PHONET_ROUTE, NULL, GFP_KERNEL);
        return;
 errout:
-       rtnl_set_sk_err(dev_net(dev), RTNLGRP_PHONET_ROUTE, err);
+       rtnl_set_sk_err(net, RTNLGRP_PHONET_ROUTE, err);
 }
 
 static const struct nla_policy rtm_phonet_policy[RTA_MAX+1] = {
@@ -235,6 +235,7 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct nlattr *tb[RTA_MAX+1];
        struct net_device *dev;
        struct rtmsg *rtm;
+       u32 ifindex;
        int err;
        u8 dst;
 
@@ -260,7 +261,8 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
        if (dst & 3) /* Phonet addresses only have 6 high-order bits */
                return -EINVAL;
 
-       dev = __dev_get_by_index(net, nla_get_u32(tb[RTA_OIF]));
+       ifindex = nla_get_u32(tb[RTA_OIF]);
+       dev = __dev_get_by_index(net, ifindex);
        if (dev == NULL)
                return -ENODEV;
 
@@ -269,7 +271,7 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
        else
                err = phonet_route_del(dev, dst);
        if (!err)
-               rtm_phonet_notify(nlh->nlmsg_type, dev, dst);
+               rtm_phonet_notify(net, nlh->nlmsg_type, ifindex, dst);
        return err;
 }