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