Commit de51ad08 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Paolo Abeni
Browse files

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: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 302fc6bb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);

+7 −3
Original line number Diff line number Diff line
@@ -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);
	}
}
+9 −7
Original line number Diff line number Diff line
@@ -200,7 +200,7 @@ static int fill_route(struct sk_buff *skb, u32 ifindex, u8 dst,
	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;
}