]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
veth: implement ->io_alloc
authorCong Wang <xiyou.wangcong@gmail.com>
Wed, 2 Apr 2014 01:03:30 +0000 (18:03 -0700)
committerThomas Haller <thaller@redhat.com>
Wed, 9 Apr 2014 07:10:19 +0000 (09:10 +0200)
Users don't have to call rtnl_link_veth_alloc(), instead
use generic rtnl_link_set_type().

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Thomas Haller <thaller@redhat.com>
lib/route/link/veth.c

index 4ce1f10c7846c0e81c381817c36188af3189e12f..5282ccb51fb16779ec1137da7d7685e2f36adf38 100644 (file)
@@ -140,6 +140,31 @@ 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;
+
+       /* return early if we are in recursion */
+       if (link->l_info)
+               return 0;
+
+       if (!(peer = rtnl_link_alloc()))
+               return -NLE_NOMEM;
+
+       /* We don't need to hold a reference here, as link and
+        * its peer should always be freed together.
+        */
+       peer->l_info = link;
+       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 +172,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 +198,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;
 }