Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phonet: Pass net and ifindex to rtm_phonet_notify().

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>

authored by

Kuniyuki Iwashima and committed by
Paolo Abeni
de51ad08 302fc6bb

+17 -11
+1 -1
include/net/phonet/pn_dev.h
··· 43 43 44 44 int phonet_route_add(struct net_device *dev, u8 daddr); 45 45 int phonet_route_del(struct net_device *dev, u8 daddr); 46 - void rtm_phonet_notify(int event, struct net_device *dev, u8 dst); 46 + void rtm_phonet_notify(struct net *net, int event, u32 ifindex, u8 dst); 47 47 struct net_device *phonet_route_get_rcu(struct net *net, u8 daddr); 48 48 struct net_device *phonet_route_output(struct net *net, u8 daddr); 49 49
+7 -3
net/phonet/pn_dev.c
··· 263 263 264 264 static void phonet_route_autodel(struct net_device *dev) 265 265 { 266 - struct phonet_net *pnn = phonet_pernet(dev_net(dev)); 267 - unsigned int i; 266 + struct net *net = dev_net(dev); 268 267 DECLARE_BITMAP(deleted, 64); 268 + u32 ifindex = dev->ifindex; 269 + struct phonet_net *pnn; 270 + unsigned int i; 271 + 272 + pnn = phonet_pernet(net); 269 273 270 274 /* Remove left-over Phonet routes */ 271 275 bitmap_zero(deleted, 64); ··· 285 281 return; /* short-circuit RCU */ 286 282 synchronize_rcu(); 287 283 for_each_set_bit(i, deleted, 64) { 288 - rtm_phonet_notify(RTM_DELROUTE, dev, i); 284 + rtm_phonet_notify(net, RTM_DELROUTE, ifindex, i); 289 285 dev_put(dev); 290 286 } 291 287 }
+9 -7
net/phonet/pn_netlink.c
··· 200 200 return -EMSGSIZE; 201 201 } 202 202 203 - void rtm_phonet_notify(int event, struct net_device *dev, u8 dst) 203 + void rtm_phonet_notify(struct net *net, int event, u32 ifindex, u8 dst) 204 204 { 205 205 struct sk_buff *skb; 206 206 int err = -ENOBUFS; ··· 210 210 if (skb == NULL) 211 211 goto errout; 212 212 213 - err = fill_route(skb, dev->ifindex, dst, 0, 0, event); 213 + err = fill_route(skb, ifindex, dst, 0, 0, event); 214 214 if (err < 0) { 215 215 WARN_ON(err == -EMSGSIZE); 216 216 kfree_skb(skb); 217 217 goto errout; 218 218 } 219 - rtnl_notify(skb, dev_net(dev), 0, 220 - RTNLGRP_PHONET_ROUTE, NULL, GFP_KERNEL); 219 + 220 + rtnl_notify(skb, net, 0, RTNLGRP_PHONET_ROUTE, NULL, GFP_KERNEL); 221 221 return; 222 222 errout: 223 - rtnl_set_sk_err(dev_net(dev), RTNLGRP_PHONET_ROUTE, err); 223 + rtnl_set_sk_err(net, RTNLGRP_PHONET_ROUTE, err); 224 224 } 225 225 226 226 static const struct nla_policy rtm_phonet_policy[RTA_MAX+1] = { ··· 235 235 struct nlattr *tb[RTA_MAX+1]; 236 236 struct net_device *dev; 237 237 struct rtmsg *rtm; 238 + u32 ifindex; 238 239 int err; 239 240 u8 dst; 240 241 ··· 261 260 if (dst & 3) /* Phonet addresses only have 6 high-order bits */ 262 261 return -EINVAL; 263 262 264 - dev = __dev_get_by_index(net, nla_get_u32(tb[RTA_OIF])); 263 + ifindex = nla_get_u32(tb[RTA_OIF]); 264 + dev = __dev_get_by_index(net, ifindex); 265 265 if (dev == NULL) 266 266 return -ENODEV; 267 267 ··· 271 269 else 272 270 err = phonet_route_del(dev, dst); 273 271 if (!err) 274 - rtm_phonet_notify(nlh->nlmsg_type, dev, dst); 272 + rtm_phonet_notify(net, nlh->nlmsg_type, ifindex, dst); 275 273 return err; 276 274 } 277 275