]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/genl.c
licensing: Add missing headers and FSF address
[mirror_lxc.git] / src / lxc / genl.c
CommitLineData
0ad19a3f 1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
9afe19d6 7 * Daniel Lezcano <daniel.lezcano at free.fr>
0ad19a3f 8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
250b1eec 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0ad19a3f 22 */
23#include <string.h>
24#include <stdio.h>
25#include <sys/socket.h>
26#include <stdlib.h>
27#include <errno.h>
28#include <unistd.h>
29#include <linux/genetlink.h>
30#include <linux/rtnetlink.h>
f549edcc
GK
31
32#include "nl.h"
33#include "genl.h"
0ad19a3f 34
35static int genetlink_resolve_family(const char *family)
36{
37 struct nl_handler handler;
38 struct nlattr *attr;
39 struct genlmsg *request, *reply;
40 struct genlmsghdr *genlmsghdr;
41
42 int len, ret;
43
44 request = genlmsg_alloc(GENLMSG_GOOD_SIZE);
45 if (!request)
46 return -ENOMEM;
47
48 reply = genlmsg_alloc(GENLMSG_GOOD_SIZE);
49 if (!reply) {
50 genlmsg_free(request);
51 return -ENOMEM;
52 }
53
54 request->nlmsghdr.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
55 request->nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
56 request->nlmsghdr.nlmsg_type = GENL_ID_CTRL;
57
58 genlmsghdr = NLMSG_DATA(&request->nlmsghdr);
59 genlmsghdr->cmd = CTRL_CMD_GETFAMILY;
60
61 ret = netlink_open(&handler, NETLINK_GENERIC);
62 if (ret)
a6537fbb 63 goto out;
0ad19a3f 64
f79d43bb 65 ret = nla_put_string((struct nlmsg *)&request->nlmsghdr,
0ad19a3f 66 CTRL_ATTR_FAMILY_NAME, family);
67 if (ret)
a6537fbb 68 goto out_close;
0ad19a3f 69
70 ret = netlink_transaction(&handler, (struct nlmsg *)&request->nlmsghdr,
71 (struct nlmsg *)&reply->nlmsghdr);
72 if (ret < 0)
a6537fbb 73 goto out_close;
0ad19a3f 74
75 genlmsghdr = NLMSG_DATA(&reply->nlmsghdr);
76 len = reply->nlmsghdr.nlmsg_len;
77
78 ret = -ENOMSG;
79 if (reply->nlmsghdr.nlmsg_type != GENL_ID_CTRL)
a6537fbb 80 goto out_close;
0ad19a3f 81
82 if (genlmsghdr->cmd != CTRL_CMD_NEWFAMILY)
a6537fbb 83 goto out_close;
0ad19a3f 84
85 ret = -EMSGSIZE;
86 len -= NLMSG_LENGTH(GENL_HDRLEN);
87 if (len < 0)
a6537fbb 88 goto out_close;
0ad19a3f 89
90 attr = (struct nlattr *)GENLMSG_DATA(reply);
91 attr = (struct nlattr *)((char *)attr + NLA_ALIGN(attr->nla_len));
92
93 ret = -ENOMSG;
94 if (attr->nla_type != CTRL_ATTR_FAMILY_ID)
a6537fbb 95 goto out_close;
0ad19a3f 96
97 ret = *(__u16 *) NLA_DATA(attr);
a6537fbb
SH
98out_close:
99 netlink_close(&handler);
0ad19a3f 100out:
101 genlmsg_free(request);
102 genlmsg_free(reply);
0ad19a3f 103 return ret;
104}
105
106extern int genetlink_open(struct genl_handler *handler, const char *family)
107{
108 int ret;
109 handler->family = genetlink_resolve_family(family);
110 if (handler->family < 0)
111 return handler->family;
112
113 ret = netlink_open(&handler->nlh, NETLINK_GENERIC);
114
115 return ret;
116}
117
118extern int genetlink_close(struct genl_handler *handler)
119{
120 return netlink_close(&handler->nlh);
121}
122
123extern int genetlink_rcv(struct genl_handler *handler, struct genlmsg *genlmsg)
124{
125 return netlink_rcv(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr);
126}
127
128extern int genetlink_send(struct genl_handler *handler, struct genlmsg *genlmsg)
129{
130
131 return netlink_send(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr);
132}
133
f79d43bb 134extern int genetlink_transaction(struct genl_handler *handler,
0ad19a3f 135 struct genlmsg *request, struct genlmsg *answer)
136{
137 return netlink_transaction(&handler->nlh, (struct nlmsg *)&request->nlmsghdr,
138 (struct nlmsg *)&answer->nlmsghdr);
139}
140
141extern struct genlmsg *genlmsg_alloc(size_t size)
142{
143 size_t len = NLMSG_LENGTH(GENL_HDRLEN) + size;
144 return (struct genlmsg *)nlmsg_alloc(len);
145}
146
147extern void genlmsg_free(struct genlmsg *genlmsg)
148{
149 free(genlmsg);
150}