[Patch v2 2/4] veth: implement io_alloc()

Thomas Graf tgraf at suug.ch
Mon Mar 31 07:04:44 EDT 2014


On 03/28/14 at 06:08pm, Cong Wang wrote:
> Users don't have to call rtnl_link_veth_alloc(), instead
> use generic rtnl_link_set_type().
> 
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> ---
>  lib/route/link/veth.c | 39 +++++++++++++++++++++++++--------------
>  1 file changed, 25 insertions(+), 14 deletions(-)
> 
> diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
> index 4ce1f10..cf2e513 100644
> --- a/lib/route/link/veth.c
> +++ b/lib/route/link/veth.c
> @@ -140,6 +140,29 @@ static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
>  	return 0;
>  }
>  
> +static int veth_alloc(struct rtnl_link *link)
> +{
> +	struct rtnl_link *peer;
> +	int err;
> +
> +	if (link->l_info)
> +		return 0;

Can you put a comment above to explain that the return is needed
to break the recursion loop?

> +
> +	if (!(peer = rtnl_link_alloc())) {
> +		rtnl_link_put(link);

This put looks wrong. It could free the link object beneath
the caller.

> +		return -NLE_NOMEM;
> +	}
> +
> +	peer->l_info = link;

You need to acquire a refcnt to link to make sure link is
not freed while you hold that reference.

nl_object_get(OBJ_CAST(link));
peer->l_info = link;

And then release it again in io_free


> +	if ((err = rtnl_link_set_type(peer, "veth")) < 0) {
> +		rtnl_link_put(peer);
> +		return err;
> +	}
> +
> +	link->l_info = peer;
> +	return 0;
> +}
> +
>  static struct rtnl_link_info_ops veth_info_ops = {
>  	.io_name		= "veth",
>  	.io_parse		= veth_parse,
> @@ -147,6 +170,7 @@ static struct rtnl_link_info_ops veth_info_ops = {
>  	    [NL_DUMP_LINE]	= veth_dump_line,
>  	    [NL_DUMP_DETAILS]	= veth_dump_details,
>  	},
> +	.io_alloc		= veth_alloc,
>  	.io_clone		= veth_clone,
>  	.io_put_attrs		= veth_put_attrs,
>  };
> @@ -172,29 +196,16 @@ static struct rtnl_link_info_ops veth_info_ops = {
>   */
>  struct rtnl_link *rtnl_link_veth_alloc(void)
>  {
> -	struct rtnl_link *link, *peer;
> +	struct rtnl_link *link;
>  	int err;
>  
>  	if (!(link = rtnl_link_alloc()))
>  		return NULL;
> -	if (!(peer = rtnl_link_alloc())) {
> -		rtnl_link_put(link);
> -		return NULL;
> -	}
> -
>  	if ((err = rtnl_link_set_type(link, "veth")) < 0) {
> -		rtnl_link_put(peer);
> -		rtnl_link_put(link);
> -		return NULL;
> -	}
> -	if ((err = rtnl_link_set_type(peer, "veth")) < 0) {
> -		rtnl_link_put(peer);
>  		rtnl_link_put(link);
>  		return NULL;
>  	}
>  
> -	link->l_info = peer;
> -	peer->l_info = link;
>  	return link;
>  }

This part looks good.



More information about the libnl mailing list