[NETLINK] af_netlink: kill some bloat
[linux-2.6.git] / net / netlink / attr.c
1 /*
2  * NETLINK      Netlink attributes
3  *
4  *              Authors:        Thomas Graf <tgraf@suug.ch>
5  *                              Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
6  */
7
8 #include <linux/module.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/jiffies.h>
12 #include <linux/netdevice.h>
13 #include <linux/skbuff.h>
14 #include <linux/string.h>
15 #include <linux/types.h>
16 #include <net/netlink.h>
17
18 static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
19         [NLA_U8]        = sizeof(u8),
20         [NLA_U16]       = sizeof(u16),
21         [NLA_U32]       = sizeof(u32),
22         [NLA_U64]       = sizeof(u64),
23         [NLA_NESTED]    = NLA_HDRLEN,
24 };
25
26 static int validate_nla(struct nlattr *nla, int maxtype,
27                         const struct nla_policy *policy)
28 {
29         const struct nla_policy *pt;
30         int minlen = 0, attrlen = nla_len(nla), type = nla_type(nla);
31
32         if (type <= 0 || type > maxtype)
33                 return 0;
34
35         pt = &policy[type];
36
37         BUG_ON(pt->type > NLA_TYPE_MAX);
38
39         switch (pt->type) {
40         case NLA_FLAG:
41                 if (attrlen > 0)
42                         return -ERANGE;
43                 break;
44
45         case NLA_NUL_STRING:
46                 if (pt->len)
47                         minlen = min_t(int, attrlen, pt->len + 1);
48                 else
49                         minlen = attrlen;
50
51                 if (!minlen || memchr(nla_data(nla), '\0', minlen) == NULL)
52                         return -EINVAL;
53                 /* fall through */
54
55         case NLA_STRING:
56                 if (attrlen < 1)
57                         return -ERANGE;
58
59                 if (pt->len) {
60                         char *buf = nla_data(nla);
61
62                         if (buf[attrlen - 1] == '\0')
63                                 attrlen--;
64
65                         if (attrlen > pt->len)
66                                 return -ERANGE;
67                 }
68                 break;
69
70         case NLA_BINARY:
71                 if (pt->len && attrlen > pt->len)
72                         return -ERANGE;
73                 break;
74
75         case NLA_NESTED_COMPAT:
76                 if (attrlen < pt->len)
77                         return -ERANGE;
78                 if (attrlen < NLA_ALIGN(pt->len))
79                         break;
80                 if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN)
81                         return -ERANGE;
82                 nla = nla_data(nla) + NLA_ALIGN(pt->len);
83                 if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla))
84                         return -ERANGE;
85                 break;
86         default:
87                 if (pt->len)
88                         minlen = pt->len;
89                 else if (pt->type != NLA_UNSPEC)
90                         minlen = nla_attr_minlen[pt->type];
91
92                 if (attrlen < minlen)
93                         return -ERANGE;
94         }
95
96         return 0;
97 }
98
99 /**
100  * nla_validate - Validate a stream of attributes
101  * @head: head of attribute stream
102  * @len: length of attribute stream
103  * @maxtype: maximum attribute type to be expected
104  * @policy: validation policy
105  *
106  * Validates all attributes in the specified attribute stream against the
107  * specified policy. Attributes with a type exceeding maxtype will be
108  * ignored. See documenation of struct nla_policy for more details.
109  *
110  * Returns 0 on success or a negative error code.
111  */
112 int nla_validate(struct nlattr *head, int len, int maxtype,
113                  const struct nla_policy *policy)
114 {
115         struct nlattr *nla;
116         int rem, err;
117
118         nla_for_each_attr(nla, head, len, rem) {
119                 err = validate_nla(nla, maxtype, policy);
120                 if (err < 0)
121                         goto errout;
122         }
123
124         err = 0;
125 errout:
126         return err;
127 }
128
129 /**
130  * nla_parse - Parse a stream of attributes into a tb buffer
131  * @tb: destination array with maxtype+1 elements
132  * @maxtype: maximum attribute type to be expected
133  * @head: head of attribute stream
134  * @len: length of attribute stream
135  *
136  * Parses a stream of attributes and stores a pointer to each attribute in
137  * the tb array accessable via the attribute type. Attributes with a type
138  * exceeding maxtype will be silently ignored for backwards compatibility
139  * reasons. policy may be set to NULL if no validation is required.
140  *
141  * Returns 0 on success or a negative error code.
142  */
143 int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
144               const struct nla_policy *policy)
145 {
146         struct nlattr *nla;
147         int rem, err;
148
149         memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
150
151         nla_for_each_attr(nla, head, len, rem) {
152                 u16 type = nla_type(nla);
153
154                 if (type > 0 && type <= maxtype) {
155                         if (policy) {
156                                 err = validate_nla(nla, maxtype, policy);
157                                 if (err < 0)
158                                         goto errout;
159                         }
160
161                         tb[type] = nla;
162                 }
163         }
164
165         if (unlikely(rem > 0))
166                 printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
167                        "attributes.\n", rem);
168
169         err = 0;
170 errout:
171         return err;
172 }
173
174 /**
175  * nla_find - Find a specific attribute in a stream of attributes
176  * @head: head of attribute stream
177  * @len: length of attribute stream
178  * @attrtype: type of attribute to look for
179  *
180  * Returns the first attribute in the stream matching the specified type.
181  */
182 struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
183 {
184         struct nlattr *nla;
185         int rem;
186
187         nla_for_each_attr(nla, head, len, rem)
188                 if (nla_type(nla) == attrtype)
189                         return nla;
190
191         return NULL;
192 }
193
194 /**
195  * nla_strlcpy - Copy string attribute payload into a sized buffer
196  * @dst: where to copy the string to
197  * @src: attribute to copy the string from
198  * @dstsize: size of destination buffer
199  *
200  * Copies at most dstsize - 1 bytes into the destination buffer.
201  * The result is always a valid NUL-terminated string. Unlike
202  * strlcpy the destination buffer is always padded out.
203  *
204  * Returns the length of the source buffer.
205  */
206 size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
207 {
208         size_t srclen = nla_len(nla);
209         char *src = nla_data(nla);
210
211         if (srclen > 0 && src[srclen - 1] == '\0')
212                 srclen--;
213
214         if (dstsize > 0) {
215                 size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
216
217                 memset(dst, 0, dstsize);
218                 memcpy(dst, src, len);
219         }
220
221         return srclen;
222 }
223
224 /**
225  * nla_memcpy - Copy a netlink attribute into another memory area
226  * @dest: where to copy to memcpy
227  * @src: netlink attribute to copy from
228  * @count: size of the destination area
229  *
230  * Note: The number of bytes copied is limited by the length of
231  *       attribute's payload. memcpy
232  *
233  * Returns the number of bytes copied.
234  */
235 int nla_memcpy(void *dest, struct nlattr *src, int count)
236 {
237         int minlen = min_t(int, count, nla_len(src));
238
239         memcpy(dest, nla_data(src), minlen);
240
241         return minlen;
242 }
243
244 /**
245  * nla_memcmp - Compare an attribute with sized memory area
246  * @nla: netlink attribute
247  * @data: memory area
248  * @size: size of memory area
249  */
250 int nla_memcmp(const struct nlattr *nla, const void *data,
251                              size_t size)
252 {
253         int d = nla_len(nla) - size;
254
255         if (d == 0)
256                 d = memcmp(nla_data(nla), data, size);
257
258         return d;
259 }
260
261 /**
262  * nla_strcmp - Compare a string attribute against a string
263  * @nla: netlink string attribute
264  * @str: another string
265  */
266 int nla_strcmp(const struct nlattr *nla, const char *str)
267 {
268         int len = strlen(str) + 1;
269         int d = nla_len(nla) - len;
270
271         if (d == 0)
272                 d = memcmp(nla_data(nla), str, len);
273
274         return d;
275 }
276
277 /**
278  * __nla_reserve - reserve room for attribute on the skb
279  * @skb: socket buffer to reserve room on
280  * @attrtype: attribute type
281  * @attrlen: length of attribute payload
282  *
283  * Adds a netlink attribute header to a socket buffer and reserves
284  * room for the payload but does not copy it.
285  *
286  * The caller is responsible to ensure that the skb provides enough
287  * tailroom for the attribute header and payload.
288  */
289 struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
290 {
291         struct nlattr *nla;
292
293         nla = (struct nlattr *) skb_put(skb, nla_total_size(attrlen));
294         nla->nla_type = attrtype;
295         nla->nla_len = nla_attr_size(attrlen);
296
297         memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
298
299         return nla;
300 }
301
302 /**
303  * __nla_reserve_nohdr - reserve room for attribute without header
304  * @skb: socket buffer to reserve room on
305  * @attrlen: length of attribute payload
306  *
307  * Reserves room for attribute payload without a header.
308  *
309  * The caller is responsible to ensure that the skb provides enough
310  * tailroom for the payload.
311  */
312 void *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen)
313 {
314         void *start;
315
316         start = skb_put(skb, NLA_ALIGN(attrlen));
317         memset(start, 0, NLA_ALIGN(attrlen));
318
319         return start;
320 }
321
322 /**
323  * nla_reserve - reserve room for attribute on the skb
324  * @skb: socket buffer to reserve room on
325  * @attrtype: attribute type
326  * @attrlen: length of attribute payload
327  *
328  * Adds a netlink attribute header to a socket buffer and reserves
329  * room for the payload but does not copy it.
330  *
331  * Returns NULL if the tailroom of the skb is insufficient to store
332  * the attribute header and payload.
333  */
334 struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
335 {
336         if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
337                 return NULL;
338
339         return __nla_reserve(skb, attrtype, attrlen);
340 }
341
342 /**
343  * nla_reserve - reserve room for attribute without header
344  * @skb: socket buffer to reserve room on
345  * @len: length of attribute payload
346  *
347  * Reserves room for attribute payload without a header.
348  *
349  * Returns NULL if the tailroom of the skb is insufficient to store
350  * the attribute payload.
351  */
352 void *nla_reserve_nohdr(struct sk_buff *skb, int attrlen)
353 {
354         if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
355                 return NULL;
356
357         return __nla_reserve_nohdr(skb, attrlen);
358 }
359
360 /**
361  * __nla_put - Add a netlink attribute to a socket buffer
362  * @skb: socket buffer to add attribute to
363  * @attrtype: attribute type
364  * @attrlen: length of attribute payload
365  * @data: head of attribute payload
366  *
367  * The caller is responsible to ensure that the skb provides enough
368  * tailroom for the attribute header and payload.
369  */
370 void __nla_put(struct sk_buff *skb, int attrtype, int attrlen,
371                              const void *data)
372 {
373         struct nlattr *nla;
374
375         nla = __nla_reserve(skb, attrtype, attrlen);
376         memcpy(nla_data(nla), data, attrlen);
377 }
378
379 /**
380  * __nla_put_nohdr - Add a netlink attribute without header
381  * @skb: socket buffer to add attribute to
382  * @attrlen: length of attribute payload
383  * @data: head of attribute payload
384  *
385  * The caller is responsible to ensure that the skb provides enough
386  * tailroom for the attribute payload.
387  */
388 void __nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)
389 {
390         void *start;
391
392         start = __nla_reserve_nohdr(skb, attrlen);
393         memcpy(start, data, attrlen);
394 }
395
396 /**
397  * nla_put - Add a netlink attribute to a socket buffer
398  * @skb: socket buffer to add attribute to
399  * @attrtype: attribute type
400  * @attrlen: length of attribute payload
401  * @data: head of attribute payload
402  *
403  * Returns -1 if the tailroom of the skb is insufficient to store
404  * the attribute header and payload.
405  */
406 int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
407 {
408         if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
409                 return -1;
410
411         __nla_put(skb, attrtype, attrlen, data);
412         return 0;
413 }
414
415 /**
416  * nla_put_nohdr - Add a netlink attribute without header
417  * @skb: socket buffer to add attribute to
418  * @attrlen: length of attribute payload
419  * @data: head of attribute payload
420  *
421  * Returns -1 if the tailroom of the skb is insufficient to store
422  * the attribute payload.
423  */
424 int nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)
425 {
426         if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
427                 return -1;
428
429         __nla_put_nohdr(skb, attrlen, data);
430         return 0;
431 }
432
433 EXPORT_SYMBOL(nla_validate);
434 EXPORT_SYMBOL(nla_parse);
435 EXPORT_SYMBOL(nla_find);
436 EXPORT_SYMBOL(nla_strlcpy);
437 EXPORT_SYMBOL(__nla_reserve);
438 EXPORT_SYMBOL(__nla_reserve_nohdr);
439 EXPORT_SYMBOL(nla_reserve);
440 EXPORT_SYMBOL(nla_reserve_nohdr);
441 EXPORT_SYMBOL(__nla_put);
442 EXPORT_SYMBOL(__nla_put_nohdr);
443 EXPORT_SYMBOL(nla_put);
444 EXPORT_SYMBOL(nla_put_nohdr);
445 EXPORT_SYMBOL(nla_memcpy);
446 EXPORT_SYMBOL(nla_memcmp);
447 EXPORT_SYMBOL(nla_strcmp);