]>
Commit | Line | Data |
---|---|---|
cc73685d CB |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | ||
f1a4a029 ÇO |
3 | #ifndef __LXC_NL_H |
4 | #define __LXC_NL_H | |
0ad19a3f | 5 | |
cc6119a0 CB |
6 | #include <stdio.h> |
7 | ||
0ad19a3f | 8 | /* |
9 | * Use this as a good size to allocate generic netlink messages | |
10 | */ | |
11 | #ifndef PAGE_SIZE | |
12 | #define PAGE_SIZE 4096 | |
13 | #endif | |
14 | #define NLMSG_GOOD_SIZE (2*PAGE_SIZE) | |
eab15c1e | 15 | #define NLMSG_TAIL(nmsg) ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) |
0ad19a3f | 16 | #define NLA_DATA(na) ((void *)((char*)(na) + NLA_HDRLEN)) |
17 | #define NLA_NEXT_ATTR(attr) ((void *)((char *)attr) + NLA_ALIGN(attr->nla_len)) | |
18 | ||
19 | /* | |
20 | * struct nl_handler : the handler for netlink sockets, this structure | |
21 | * is used all along the netlink socket life cycle to specify the | |
22 | * netlink socket to be used. | |
f79d43bb | 23 | * |
0ad19a3f | 24 | * @fd: the file descriptor of the netlink socket |
25 | * @seq: the sequence number of the netlink messages | |
26 | * @local: the bind address | |
27 | * @peer: the peer address | |
28 | */ | |
29 | struct nl_handler { | |
d028235d | 30 | int fd; |
0ad19a3f | 31 | int seq; |
d028235d SG |
32 | struct sockaddr_nl local; |
33 | struct sockaddr_nl peer; | |
0ad19a3f | 34 | }; |
35 | ||
36 | /* | |
06f976ca | 37 | * struct nlmsg : the netlink message structure. This message is to be used to |
0ad19a3f | 38 | * be allocated with netlink_alloc. |
06f976ca SZ |
39 | * |
40 | * @nlmsghdr: a pointer to a netlink message header | |
41 | * @cap: capacity of the netlink message, this is the initially allocated size | |
42 | * and later operations (e.g. reserve and put) can not exceed this limit. | |
0ad19a3f | 43 | */ |
44 | struct nlmsg { | |
06f976ca SZ |
45 | struct nlmsghdr *nlmsghdr; |
46 | ssize_t cap; | |
0ad19a3f | 47 | }; |
48 | ||
49 | /* | |
50 | * netlink_open : open a netlink socket, the function will | |
51 | * fill the handler with the right value | |
52 | * | |
53 | * @handler: a netlink handler to be used all along the netlink | |
54 | * socket life cycle | |
55 | * @protocol: specify the protocol to be used when opening the | |
56 | * netlink socket | |
57 | * | |
58 | * Return 0 on success, < 0 otherwise | |
59 | */ | |
60 | int netlink_open(struct nl_handler *handler, int protocol); | |
61 | ||
62 | /* | |
f79d43bb | 63 | * netlink_close : close a netlink socket, after this call, |
0ad19a3f | 64 | * the handler is no longer valid |
65 | * | |
66 | * @handler: a handler to the netlink socket | |
67 | * | |
68 | * Returns 0 on success, < 0 otherwise | |
69 | */ | |
70 | int netlink_close(struct nl_handler *handler); | |
71 | ||
72 | /* | |
f79d43bb SG |
73 | * netlink_rcv : receive a netlink message from the kernel. |
74 | * It is up to the caller to manage the allocation of the | |
0ad19a3f | 75 | * netlink message |
76 | * | |
77 | * @handler: a handler to the netlink socket | |
78 | * @nlmsg: a netlink message | |
79 | * | |
80 | * Returns 0 on success, < 0 otherwise | |
81 | */ | |
82 | int netlink_rcv(struct nl_handler *handler, struct nlmsg *nlmsg); | |
9fbbc427 | 83 | int __netlink_recv(struct nl_handler *handler, struct nlmsghdr *nlmsg); |
0ad19a3f | 84 | |
85 | /* | |
86 | * netlink_send: send a netlink message to the kernel. It is up | |
87 | * to the caller to manage the allocate of the netlink message | |
88 | * | |
89 | * @handler: a handler to the netlink socket | |
90 | * @nlmsg: a netlink message | |
91 | * | |
92 | * Returns 0 on success, < 0 otherwise | |
93 | */ | |
94 | int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg); | |
9fbbc427 | 95 | int __netlink_send(struct nl_handler *handler, struct nlmsghdr *nlmsg); |
0ad19a3f | 96 | |
97 | /* | |
f79d43bb SG |
98 | * netlink_transaction: send a request to the kernel and read the response. |
99 | * This is useful for transactional protocol. It is up to the caller | |
0ad19a3f | 100 | * to manage the allocation of the netlink message. |
101 | * | |
102 | * @handler: a handler to a opened netlink socket | |
103 | * @request: a netlink message pointer containing the request | |
104 | * @answer: a netlink message pointer to receive the result | |
105 | * | |
106 | * Returns 0 on success, < 0 otherwise | |
107 | */ | |
f79d43bb | 108 | int netlink_transaction(struct nl_handler *handler, |
b3b5b0ff | 109 | struct nlmsg *request, struct nlmsg *answer); |
9fbbc427 | 110 | int __netlink_transaction(struct nl_handler *handler, struct nlmsghdr *request, |
b3b5b0ff | 111 | struct nlmsghdr *answer); |
0ad19a3f | 112 | |
113 | /* | |
f79d43bb | 114 | * nla_put_string: copy a null terminated string to a netlink message |
0ad19a3f | 115 | * attribute |
116 | * | |
117 | * @nlmsg: the netlink message to be filled | |
118 | * @attr: the attribute name of the string | |
119 | * @string: a null terminated string to be copied to the netlink message | |
120 | * | |
121 | * Returns 0 on success, < 0 otherwise | |
122 | */ | |
123 | int nla_put_string(struct nlmsg *nlmsg, int attr, const char *string); | |
124 | ||
125 | /* | |
126 | * nla_put_buffer: copy a buffer with a specified size to a netlink | |
127 | * message attribute | |
128 | * | |
129 | * @nlmsg: the netlink message to be filled | |
130 | * @attr: the attribute name of the string | |
131 | * @data: a pointer to a buffer | |
132 | * @size: the size of the buffer | |
133 | * | |
134 | * Returns 0 on success, < 0 otherwise | |
135 | */ | |
f79d43bb | 136 | int nla_put_buffer(struct nlmsg *nlmsg, int attr, |
0ad19a3f | 137 | const void *data, size_t size); |
138 | ||
139 | /* | |
140 | * nla_put_u32: copy an integer to a netlink message attribute | |
141 | * | |
142 | * @nlmsg: the netlink message to be filled | |
143 | * @attr: the attribute name of the integer | |
144 | * @string: an integer to be copied to the netlink message | |
145 | * | |
146 | * Returns 0 on success, < 0 otherwise | |
147 | */ | |
148 | int nla_put_u32(struct nlmsg *nlmsg, int attr, int value); | |
149 | ||
9ddaf3bf JHS |
150 | /* |
151 | * nla_put_u16: copy an integer to a netlink message attribute | |
152 | * | |
153 | * @nlmsg: the netlink message to be filled | |
154 | * @attr: the attribute name of the unsigned 16-bit value | |
155 | * @value: 16-bit attribute data value to be copied to the netlink message | |
156 | * | |
157 | * Returns 0 on success, < 0 otherwise | |
158 | */ | |
7c11d57a | 159 | int nla_put_u16(struct nlmsg *nlmsg, int attr, unsigned short value); |
9ddaf3bf | 160 | |
0ad19a3f | 161 | /* |
f79d43bb | 162 | * nla_put_attr: add an attribute name to a netlink |
0ad19a3f | 163 | * |
164 | * @nlmsg: the netlink message to be filled | |
165 | * @attr: the attribute name of the integer | |
166 | * | |
167 | * Returns 0 on success, < 0 otherwise | |
168 | */ | |
169 | int nla_put_attr(struct nlmsg *nlmsg, int attr); | |
170 | ||
171 | /* | |
172 | * nla_begin_nested: begin the nesting attribute | |
173 | * | |
174 | * @nlmsg: the netlink message to be filled | |
f79d43bb | 175 | * @attr: the netsted attribute name |
0ad19a3f | 176 | * |
177 | * Returns current nested pointer to be reused | |
178 | * to nla_end_nested. | |
179 | */ | |
180 | struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr); | |
181 | ||
182 | /* | |
183 | * nla_end_nested: end the nesting attribute | |
184 | * | |
185 | * @nlmsg: the netlink message | |
186 | * @nested: the nested pointer | |
187 | * | |
f79d43bb | 188 | * Returns the current |
0ad19a3f | 189 | */ |
190 | void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr); | |
191 | ||
192 | /* | |
f79d43bb | 193 | * nlmsg_allocate : allocate a netlink message. The netlink format message |
0ad19a3f | 194 | * is a header, a padding, a payload and a padding again. |
f79d43bb | 195 | * When a netlink message is allocated, the size specify the |
0ad19a3f | 196 | * payload we want. So the real size of the allocated message |
197 | * is sizeof(header) + sizeof(padding) + payloadsize + sizeof(padding), | |
f79d43bb | 198 | * in other words, the function will allocate more than specified. When |
0ad19a3f | 199 | * the buffer is allocated, the content is zeroed. |
06f976ca | 200 | * The function will also fill the field nlmsg_len with NLMSG_HDRLEN. |
0ad19a3f | 201 | * If the allocation must be for the specified size, just use malloc. |
202 | * | |
06f976ca | 203 | * @size: the capacity of the payload to be allocated |
0ad19a3f | 204 | * |
205 | * Returns a pointer to the newly allocated netlink message, NULL otherwise | |
206 | */ | |
207 | struct nlmsg *nlmsg_alloc(size_t size); | |
208 | ||
06f976ca SZ |
209 | /* |
210 | * nlmsg_alloc_reserve: like nlmsg_alloc(), but reserve the whole payload | |
211 | * after allocated, that is, the field nlmsg_len be set to the capacity | |
212 | * of nlmsg. Often used to allocate a message for the reply. | |
213 | * | |
214 | * @size: the capacity of the payload to be allocated. | |
215 | */ | |
216 | struct nlmsg *nlmsg_alloc_reserve(size_t size); | |
217 | ||
218 | /* | |
219 | * Reserve room for additional data at the tail of a netlink message | |
220 | * | |
221 | * @nlmsg: the netlink message | |
222 | * @len: length of additional data to reserve room for | |
223 | * | |
224 | * Returns a pointer to newly reserved room or NULL | |
225 | */ | |
226 | void *nlmsg_reserve(struct nlmsg *nlmsg, size_t len); | |
227 | ||
0ad19a3f | 228 | /* |
229 | * nlmsg_free : free a previously allocate message | |
230 | * | |
231 | * @nlmsg: the netlink message to be freed | |
232 | */ | |
233 | void nlmsg_free(struct nlmsg *nlmsg); | |
234 | ||
235 | /* | |
236 | * nlmsg_data : returns a pointer to the data contained in the netlink message | |
f79d43bb | 237 | * |
0ad19a3f | 238 | * @nlmsg : the netlink message to get the data |
239 | * | |
240 | * Returns a pointer to the netlink data or NULL if there is no data | |
241 | */ | |
242 | void *nlmsg_data(struct nlmsg *nlmsg); | |
243 | ||
cc6119a0 CB |
244 | extern int addattr(struct nlmsghdr *n, size_t maxlen, int type, |
245 | const void *data, size_t alen); | |
0ad19a3f | 246 | |
247 | #endif |