summaryrefslogtreecommitdiffstats
path: root/lib/route
diff options
context:
space:
mode:
authorCong Wang <xiyou.wangcong@gmail.com>2014-04-02 01:03:30 (GMT)
committerThomas Haller <thaller@redhat.com>2014-04-09 07:10:19 (GMT)
commit12bd035b053f2df4369da47f893fefcdeec6389d (patch)
treeee82f808853158e7320cfa43d09c4869a55af223 /lib/route
parentab55ea80a4fbad94c75e31e4107bbb48406ec999 (diff)
downloadlibnl-12bd035b053f2df4369da47f893fefcdeec6389d.zip
libnl-12bd035b053f2df4369da47f893fefcdeec6389d.tar.gz
libnl-12bd035b053f2df4369da47f893fefcdeec6389d.tar.bz2
veth: implement ->io_alloc
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>
Diffstat (limited to 'lib/route')
-rw-r--r--lib/route/link/veth.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index 4ce1f10..5282ccb 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -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;
}