Skip to content

Commit

Permalink
rtnetlink: place link af dump into own helper
Browse files Browse the repository at this point in the history
next patch will rcu-ify rtnl af_ops, i.e. allow af_ops
lookup and function calls with rcu read lock held instead
of rtnl mutex.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Florian Westphal authored and David S. Miller committed Oct 16, 2017
1 parent d85969f commit 070cbf5
Showing 1 changed file with 42 additions and 30 deletions.
72 changes: 42 additions & 30 deletions net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1382,15 +1382,54 @@ static int rtnl_fill_link_netnsid(struct sk_buff *skb,
return 0;
}

static int rtnl_fill_link_af(struct sk_buff *skb,
const struct net_device *dev,
u32 ext_filter_mask)
{
const struct rtnl_af_ops *af_ops;
struct nlattr *af_spec;

af_spec = nla_nest_start(skb, IFLA_AF_SPEC);
if (!af_spec)
return -EMSGSIZE;

list_for_each_entry(af_ops, &rtnl_af_ops, list) {
struct nlattr *af;
int err;

if (!af_ops->fill_link_af)
continue;

af = nla_nest_start(skb, af_ops->family);
if (!af)
return -EMSGSIZE;

err = af_ops->fill_link_af(skb, dev, ext_filter_mask);
/*
* Caller may return ENODATA to indicate that there
* was no data to be dumped. This is not an error, it
* means we should trim the attribute header and
* continue.
*/
if (err == -ENODATA)
nla_nest_cancel(skb, af);
else if (err < 0)
return -EMSGSIZE;

nla_nest_end(skb, af);
}

nla_nest_end(skb, af_spec);
return 0;
}

static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
int type, u32 pid, u32 seq, u32 change,
unsigned int flags, u32 ext_filter_mask,
u32 event, int *new_nsid)
{
struct ifinfomsg *ifm;
struct nlmsghdr *nlh;
struct nlattr *af_spec;
struct rtnl_af_ops *af_ops;

ASSERT_RTNL();
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
Expand Down Expand Up @@ -1477,36 +1516,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0)
goto nla_put_failure;

if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC)))
if (rtnl_fill_link_af(skb, dev, ext_filter_mask))
goto nla_put_failure;

list_for_each_entry(af_ops, &rtnl_af_ops, list) {
if (af_ops->fill_link_af) {
struct nlattr *af;
int err;

if (!(af = nla_nest_start(skb, af_ops->family)))
goto nla_put_failure;

err = af_ops->fill_link_af(skb, dev, ext_filter_mask);

/*
* Caller may return ENODATA to indicate that there
* was no data to be dumped. This is not an error, it
* means we should trim the attribute header and
* continue.
*/
if (err == -ENODATA)
nla_nest_cancel(skb, af);
else if (err < 0)
goto nla_put_failure;

nla_nest_end(skb, af);
}
}

nla_nest_end(skb, af_spec);

nlmsg_end(skb, nlh);
return 0;

Expand Down

0 comments on commit 070cbf5

Please sign in to comment.