2
* lxc: linux Container library
4
* (C) Copyright IBM Corp. 2007, 2008
7
* Daniel Lezcano <dlezcano at fr.ibm.com>
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.
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.
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
21
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#include <sys/socket.h>
29
#include <linux/genetlink.h>
30
#include <linux/rtnetlink.h>
34
static int genetlink_resolve_family(const char *family)
36
struct nl_handler handler;
38
struct genlmsg *request, *reply;
39
struct genlmsghdr *genlmsghdr;
43
request = genlmsg_alloc(GENLMSG_GOOD_SIZE);
47
reply = genlmsg_alloc(GENLMSG_GOOD_SIZE);
49
genlmsg_free(request);
53
request->nlmsghdr.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
54
request->nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
55
request->nlmsghdr.nlmsg_type = GENL_ID_CTRL;
57
genlmsghdr = NLMSG_DATA(&request->nlmsghdr);
58
genlmsghdr->cmd = CTRL_CMD_GETFAMILY;
60
ret = netlink_open(&handler, NETLINK_GENERIC);
64
ret = nla_put_string((struct nlmsg *)&request->nlmsghdr,
65
CTRL_ATTR_FAMILY_NAME, family);
69
ret = netlink_transaction(&handler, (struct nlmsg *)&request->nlmsghdr,
70
(struct nlmsg *)&reply->nlmsghdr);
74
genlmsghdr = NLMSG_DATA(&reply->nlmsghdr);
75
len = reply->nlmsghdr.nlmsg_len;
78
if (reply->nlmsghdr.nlmsg_type != GENL_ID_CTRL)
81
if (genlmsghdr->cmd != CTRL_CMD_NEWFAMILY)
85
len -= NLMSG_LENGTH(GENL_HDRLEN);
89
attr = (struct nlattr *)GENLMSG_DATA(reply);
90
attr = (struct nlattr *)((char *)attr + NLA_ALIGN(attr->nla_len));
93
if (attr->nla_type != CTRL_ATTR_FAMILY_ID)
96
ret = *(__u16 *) NLA_DATA(attr);
98
genlmsg_free(request);
100
netlink_close(&handler);
104
extern int genetlink_open(struct genl_handler *handler, const char *family)
107
handler->family = genetlink_resolve_family(family);
108
if (handler->family < 0)
109
return handler->family;
111
ret = netlink_open(&handler->nlh, NETLINK_GENERIC);
116
extern int genetlink_close(struct genl_handler *handler)
118
return netlink_close(&handler->nlh);
121
extern int genetlink_rcv(struct genl_handler *handler, struct genlmsg *genlmsg)
123
return netlink_rcv(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr);
126
extern int genetlink_send(struct genl_handler *handler, struct genlmsg *genlmsg)
129
return netlink_send(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr);
132
extern int genetlink_transaction(struct genl_handler *handler,
133
struct genlmsg *request, struct genlmsg *answer)
135
return netlink_transaction(&handler->nlh, (struct nlmsg *)&request->nlmsghdr,
136
(struct nlmsg *)&answer->nlmsghdr);
139
extern struct genlmsg *genlmsg_alloc(size_t size)
141
size_t len = NLMSG_LENGTH(GENL_HDRLEN) + size;
142
return (struct genlmsg *)nlmsg_alloc(len);
145
extern void genlmsg_free(struct genlmsg *genlmsg)