diff options
Diffstat (limited to 'net/tipc/netlink_compat.c')
| -rw-r--r-- | net/tipc/netlink_compat.c | 43 | 
1 files changed, 23 insertions, 20 deletions
| diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index e48f0b2c01b9..4492cda45566 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -285,10 +285,6 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,  	if (!trans_buf)  		return -ENOMEM; -	err = (*cmd->transcode)(cmd, trans_buf, msg); -	if (err) -		goto trans_out; -  	attrbuf = kmalloc((tipc_genl_family.maxattr + 1) *  			sizeof(struct nlattr *), GFP_KERNEL);  	if (!attrbuf) { @@ -296,27 +292,34 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,  		goto trans_out;  	} -	err = nla_parse(attrbuf, tipc_genl_family.maxattr, -			(const struct nlattr *)trans_buf->data, -			trans_buf->len, NULL, NULL); -	if (err) -		goto parse_out; -  	doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);  	if (!doit_buf) {  		err = -ENOMEM; -		goto parse_out; +		goto attrbuf_out;  	} -	doit_buf->sk = msg->dst_sk; -  	memset(&info, 0, sizeof(info));  	info.attrs = attrbuf; +	rtnl_lock(); +	err = (*cmd->transcode)(cmd, trans_buf, msg); +	if (err) +		goto doit_out; + +	err = nla_parse(attrbuf, tipc_genl_family.maxattr, +			(const struct nlattr *)trans_buf->data, +			trans_buf->len, NULL, NULL); +	if (err) +		goto doit_out; + +	doit_buf->sk = msg->dst_sk; +  	err = (*cmd->doit)(doit_buf, &info); +doit_out: +	rtnl_unlock();  	kfree_skb(doit_buf); -parse_out: +attrbuf_out:  	kfree(attrbuf);  trans_out:  	kfree_skb(trans_buf); @@ -722,13 +725,13 @@ static int tipc_nl_compat_link_set(struct tipc_nl_compat_cmd_doit *cmd,  	media = tipc_media_find(lc->name);  	if (media) { -		cmd->doit = &tipc_nl_media_set; +		cmd->doit = &__tipc_nl_media_set;  		return tipc_nl_compat_media_set(skb, msg);  	}  	bearer = tipc_bearer_find(msg->net, lc->name);  	if (bearer) { -		cmd->doit = &tipc_nl_bearer_set; +		cmd->doit = &__tipc_nl_bearer_set;  		return tipc_nl_compat_bearer_set(skb, msg);  	} @@ -1089,12 +1092,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg)  		return tipc_nl_compat_dumpit(&dump, msg);  	case TIPC_CMD_ENABLE_BEARER:  		msg->req_type = TIPC_TLV_BEARER_CONFIG; -		doit.doit = tipc_nl_bearer_enable; +		doit.doit = __tipc_nl_bearer_enable;  		doit.transcode = tipc_nl_compat_bearer_enable;  		return tipc_nl_compat_doit(&doit, msg);  	case TIPC_CMD_DISABLE_BEARER:  		msg->req_type = TIPC_TLV_BEARER_NAME; -		doit.doit = tipc_nl_bearer_disable; +		doit.doit = __tipc_nl_bearer_disable;  		doit.transcode = tipc_nl_compat_bearer_disable;  		return tipc_nl_compat_doit(&doit, msg);  	case TIPC_CMD_SHOW_LINK_STATS: @@ -1148,12 +1151,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg)  		return tipc_nl_compat_dumpit(&dump, msg);  	case TIPC_CMD_SET_NODE_ADDR:  		msg->req_type = TIPC_TLV_NET_ADDR; -		doit.doit = tipc_nl_net_set; +		doit.doit = __tipc_nl_net_set;  		doit.transcode = tipc_nl_compat_net_set;  		return tipc_nl_compat_doit(&doit, msg);  	case TIPC_CMD_SET_NETID:  		msg->req_type = TIPC_TLV_UNSIGNED; -		doit.doit = tipc_nl_net_set; +		doit.doit = __tipc_nl_net_set;  		doit.transcode = tipc_nl_compat_net_set;  		return tipc_nl_compat_doit(&doit, msg);  	case TIPC_CMD_GET_NETID: |