Skip to content

Commit 331fe31

Browse files
q2venPaolo Abeni
authored andcommitted
rtnetlink: Move rtnl_link_ops_get() and retry to rtnl_newlink().
Currently, if neither dev nor rtnl_link_ops is found in __rtnl_newlink(), we release RTNL and redo the whole process after request_module(), which complicates the logic. The ops will be RTNL-independent later. Let's move the ops lookup to rtnl_newlink() and do the retry earlier. Signed-off-by: Kuniyuki Iwashima <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 7fea1a8 commit 331fe31

File tree

1 file changed

+18
-24
lines changed

1 file changed

+18
-24
lines changed

net/core/rtnetlink.c

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3690,23 +3690,19 @@ static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
36903690
}
36913691

36923692
static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
3693+
const struct rtnl_link_ops *ops,
36933694
struct rtnl_newlink_tbs *tbs,
36943695
struct netlink_ext_ack *extack)
36953696
{
36963697
struct nlattr ** const linkinfo = tbs->linkinfo;
36973698
struct nlattr ** const tb = tbs->tb;
36983699
struct net *net = sock_net(skb->sk);
3699-
const struct rtnl_link_ops *ops;
3700-
char kind[MODULE_NAME_LEN];
37013700
struct net_device *dev;
37023701
struct ifinfomsg *ifm;
37033702
struct nlattr **data;
37043703
bool link_specified;
37053704
int err;
37063705

3707-
#ifdef CONFIG_MODULES
3708-
replay:
3709-
#endif
37103706
ifm = nlmsg_data(nlh);
37113707
if (ifm->ifi_index > 0) {
37123708
link_specified = true;
@@ -3722,14 +3718,6 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
37223718
dev = NULL;
37233719
}
37243720

3725-
if (linkinfo[IFLA_INFO_KIND]) {
3726-
nla_strscpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
3727-
ops = rtnl_link_ops_get(kind);
3728-
} else {
3729-
kind[0] = '\0';
3730-
ops = NULL;
3731-
}
3732-
37333721
data = NULL;
37343722
if (ops) {
37353723
if (ops->maxtype > RTNL_MAX_TYPE)
@@ -3770,16 +3758,6 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
37703758
return -EOPNOTSUPP;
37713759

37723760
if (!ops) {
3773-
#ifdef CONFIG_MODULES
3774-
if (kind[0]) {
3775-
__rtnl_unlock();
3776-
request_module("rtnl-link-%s", kind);
3777-
rtnl_lock();
3778-
ops = rtnl_link_ops_get(kind);
3779-
if (ops)
3780-
goto replay;
3781-
}
3782-
#endif
37833761
NL_SET_ERR_MSG(extack, "Unknown device type");
37843762
return -EOPNOTSUPP;
37853763
}
@@ -3790,6 +3768,7 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
37903768
static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
37913769
struct netlink_ext_ack *extack)
37923770
{
3771+
const struct rtnl_link_ops *ops = NULL;
37933772
struct nlattr **tb, **linkinfo;
37943773
struct rtnl_newlink_tbs *tbs;
37953774
int ret;
@@ -3819,7 +3798,22 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
38193798
memset(linkinfo, 0, sizeof(tbs->linkinfo));
38203799
}
38213800

3822-
ret = __rtnl_newlink(skb, nlh, tbs, extack);
3801+
if (linkinfo[IFLA_INFO_KIND]) {
3802+
char kind[MODULE_NAME_LEN];
3803+
3804+
nla_strscpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
3805+
ops = rtnl_link_ops_get(kind);
3806+
#ifdef CONFIG_MODULES
3807+
if (!ops) {
3808+
__rtnl_unlock();
3809+
request_module("rtnl-link-%s", kind);
3810+
rtnl_lock();
3811+
ops = rtnl_link_ops_get(kind);
3812+
}
3813+
#endif
3814+
}
3815+
3816+
ret = __rtnl_newlink(skb, nlh, ops, tbs, extack);
38233817

38243818
free:
38253819
kfree(tbs);

0 commit comments

Comments
 (0)