~ubuntu-branches/ubuntu/quantal/lxc/quantal-201208301614

« back to all changes in this revision

Viewing changes to src/lxc/genl.c

  • Committer: Bazaar Package Importer
  • Author(s): Guido Trotter
  • Date: 2009-04-29 17:49:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090429174913-jvahs1ykizqtodje
Tags: upstream-0.6.2
ImportĀ upstreamĀ versionĀ 0.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lxc: linux Container library
 
3
 *
 
4
 * (C) Copyright IBM Corp. 2007, 2008
 
5
 *
 
6
 * Authors:
 
7
 * Daniel Lezcano <dlezcano at fr.ibm.com>
 
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
 
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
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>
 
31
#include <nl.h>
 
32
#include <genl.h>
 
33
 
 
34
static int genetlink_resolve_family(const char *family)
 
35
{
 
36
        struct nl_handler handler;
 
37
        struct nlattr *attr;
 
38
        struct genlmsg *request, *reply;
 
39
        struct genlmsghdr *genlmsghdr;
 
40
 
 
41
        int len, ret;
 
42
 
 
43
        request = genlmsg_alloc(GENLMSG_GOOD_SIZE);
 
44
        if (!request)
 
45
                return -ENOMEM;
 
46
                
 
47
        reply = genlmsg_alloc(GENLMSG_GOOD_SIZE);
 
48
        if (!reply) {
 
49
                genlmsg_free(request);
 
50
                return -ENOMEM;
 
51
        }
 
52
 
 
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;
 
56
 
 
57
        genlmsghdr = NLMSG_DATA(&request->nlmsghdr);
 
58
        genlmsghdr->cmd = CTRL_CMD_GETFAMILY;
 
59
 
 
60
        ret = netlink_open(&handler, NETLINK_GENERIC);
 
61
        if (ret)
 
62
                return ret;
 
63
 
 
64
        ret = nla_put_string((struct nlmsg *)&request->nlmsghdr, 
 
65
                             CTRL_ATTR_FAMILY_NAME, family);
 
66
        if (ret)
 
67
                goto out;
 
68
 
 
69
        ret = netlink_transaction(&handler, (struct nlmsg *)&request->nlmsghdr,
 
70
                                  (struct nlmsg *)&reply->nlmsghdr);
 
71
        if (ret < 0)
 
72
                goto out;
 
73
 
 
74
        genlmsghdr = NLMSG_DATA(&reply->nlmsghdr);
 
75
        len = reply->nlmsghdr.nlmsg_len;
 
76
 
 
77
        ret = -ENOMSG;
 
78
        if (reply->nlmsghdr.nlmsg_type !=  GENL_ID_CTRL)
 
79
                goto out;
 
80
 
 
81
        if (genlmsghdr->cmd != CTRL_CMD_NEWFAMILY)
 
82
                goto out;
 
83
 
 
84
        ret = -EMSGSIZE;
 
85
        len -= NLMSG_LENGTH(GENL_HDRLEN);
 
86
        if (len < 0)
 
87
                goto out;
 
88
        
 
89
        attr = (struct nlattr *)GENLMSG_DATA(reply);
 
90
        attr = (struct nlattr *)((char *)attr + NLA_ALIGN(attr->nla_len));
 
91
        
 
92
        ret = -ENOMSG;
 
93
        if (attr->nla_type != CTRL_ATTR_FAMILY_ID)
 
94
                goto out;
 
95
 
 
96
        ret =  *(__u16 *) NLA_DATA(attr);
 
97
out:
 
98
        genlmsg_free(request);
 
99
        genlmsg_free(reply);
 
100
        netlink_close(&handler);
 
101
        return ret;
 
102
}
 
103
 
 
104
extern int genetlink_open(struct genl_handler *handler, const char *family)
 
105
{
 
106
        int ret;
 
107
        handler->family = genetlink_resolve_family(family);
 
108
        if (handler->family < 0)
 
109
                return handler->family;
 
110
 
 
111
        ret = netlink_open(&handler->nlh, NETLINK_GENERIC);
 
112
 
 
113
        return ret;
 
114
}
 
115
 
 
116
extern int genetlink_close(struct genl_handler *handler)
 
117
{
 
118
        return netlink_close(&handler->nlh);
 
119
}
 
120
 
 
121
extern int genetlink_rcv(struct genl_handler *handler, struct genlmsg *genlmsg)
 
122
{
 
123
        return netlink_rcv(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr);
 
124
}
 
125
 
 
126
extern int genetlink_send(struct genl_handler *handler, struct genlmsg *genlmsg)
 
127
{
 
128
 
 
129
        return netlink_send(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr);
 
130
}
 
131
 
 
132
extern int genetlink_transaction(struct genl_handler *handler, 
 
133
                          struct genlmsg *request, struct genlmsg *answer)
 
134
{
 
135
        return netlink_transaction(&handler->nlh, (struct nlmsg *)&request->nlmsghdr,
 
136
                                   (struct nlmsg *)&answer->nlmsghdr);
 
137
}
 
138
 
 
139
extern struct genlmsg *genlmsg_alloc(size_t size)
 
140
{
 
141
        size_t len = NLMSG_LENGTH(GENL_HDRLEN) + size;
 
142
        return  (struct genlmsg *)nlmsg_alloc(len);
 
143
}
 
144
 
 
145
extern void genlmsg_free(struct genlmsg *genlmsg)
 
146
{
 
147
        free(genlmsg);
 
148
}