attr.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. /*
  2. * lib/attr.c Netlink Attributes
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation version 2.1
  7. * of the License.
  8. *
  9. * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
  10. */
  11. #include <netlink-private/netlink.h>
  12. #include <netlink/netlink.h>
  13. #include <netlink/utils.h>
  14. #include <netlink/addr.h>
  15. #include <netlink/attr.h>
  16. #include <netlink/msg.h>
  17. #include <linux/socket.h>
  18. /**
  19. * @ingroup msg
  20. * @defgroup attr Attributes
  21. * Netlink Attributes Construction/Parsing Interface
  22. *
  23. * Related sections in the development guide:
  24. * - @core_doc{core_attr,Netlink Attributes}
  25. *
  26. * @{
  27. *
  28. * Header
  29. * ------
  30. * ~~~~{.c}
  31. * #include <netlink/attr.h>
  32. * ~~~~
  33. */
  34. /**
  35. * @name Attribute Size Calculation
  36. * @{
  37. */
  38. /**
  39. * Return size of attribute whithout padding.
  40. * @arg payload Payload length of attribute.
  41. *
  42. * @code
  43. * <-------- nla_attr_size(payload) --------->
  44. * +------------------+- - -+- - - - - - - - - +- - -+
  45. * | Attribute Header | Pad | Payload | Pad |
  46. * +------------------+- - -+- - - - - - - - - +- - -+
  47. * @endcode
  48. *
  49. * @return Size of attribute in bytes without padding.
  50. */
  51. int nla_attr_size(int payload)
  52. {
  53. return NLA_HDRLEN + payload;
  54. }
  55. /**
  56. * Return size of attribute including padding.
  57. * @arg payload Payload length of attribute.
  58. *
  59. * @code
  60. * <----------- nla_total_size(payload) ----------->
  61. * +------------------+- - -+- - - - - - - - - +- - -+
  62. * | Attribute Header | Pad | Payload | Pad |
  63. * +------------------+- - -+- - - - - - - - - +- - -+
  64. * @endcode
  65. *
  66. * @return Size of attribute in bytes.
  67. */
  68. int nla_total_size(int payload)
  69. {
  70. return NLA_ALIGN(nla_attr_size(payload));
  71. }
  72. /**
  73. * Return length of padding at the tail of the attribute.
  74. * @arg payload Payload length of attribute.
  75. *
  76. * @code
  77. * +------------------+- - -+- - - - - - - - - +- - -+
  78. * | Attribute Header | Pad | Payload | Pad |
  79. * +------------------+- - -+- - - - - - - - - +- - -+
  80. * <--->
  81. * @endcode
  82. *
  83. * @return Length of padding in bytes.
  84. */
  85. int nla_padlen(int payload)
  86. {
  87. return nla_total_size(payload) - nla_attr_size(payload);
  88. }
  89. /** @} */
  90. /**
  91. * @name Parsing Attributes
  92. * @{
  93. */
  94. /**
  95. * Return type of the attribute.
  96. * @arg nla Attribute.
  97. *
  98. * @return Type of attribute.
  99. */
  100. int nla_type(const struct nlattr *nla)
  101. {
  102. return nla->nla_type & NLA_TYPE_MASK;
  103. }
  104. /**
  105. * Return pointer to the payload section.
  106. * @arg nla Attribute.
  107. *
  108. * @return Pointer to start of payload section.
  109. */
  110. void *nla_data(const struct nlattr *nla)
  111. {
  112. return (char *) nla + NLA_HDRLEN;
  113. }
  114. /**
  115. * Return length of the payload .
  116. * @arg nla Attribute
  117. *
  118. * @return Length of payload in bytes.
  119. */
  120. int nla_len(const struct nlattr *nla)
  121. {
  122. return nla->nla_len - NLA_HDRLEN;
  123. }
  124. /**
  125. * Check if the attribute header and payload can be accessed safely.
  126. * @arg nla Attribute of any kind.
  127. * @arg remaining Number of bytes remaining in attribute stream.
  128. *
  129. * Verifies that the header and payload do not exceed the number of
  130. * bytes left in the attribute stream. This function must be called
  131. * before access the attribute header or payload when iterating over
  132. * the attribute stream using nla_next().
  133. *
  134. * @return True if the attribute can be accessed safely, false otherwise.
  135. */
  136. int nla_ok(const struct nlattr *nla, int remaining)
  137. {
  138. return remaining >= sizeof(*nla) &&
  139. nla->nla_len >= sizeof(*nla) &&
  140. nla->nla_len <= remaining;
  141. }
  142. /**
  143. * Return next attribute in a stream of attributes.
  144. * @arg nla Attribute of any kind.
  145. * @arg remaining Variable to count remaining bytes in stream.
  146. *
  147. * Calculates the offset to the next attribute based on the attribute
  148. * given. The attribute provided is assumed to be accessible, the
  149. * caller is responsible to use nla_ok() beforehand. The offset (length
  150. * of specified attribute including padding) is then subtracted from
  151. * the remaining bytes variable and a pointer to the next attribute is
  152. * returned.
  153. *
  154. * nla_next() can be called as long as remainig is >0.
  155. *
  156. * @return Pointer to next attribute.
  157. */
  158. struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
  159. {
  160. int totlen = NLA_ALIGN(nla->nla_len);
  161. *remaining -= totlen;
  162. return (struct nlattr *) ((char *) nla + totlen);
  163. }
  164. static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
  165. [NLA_U8] = sizeof(uint8_t),
  166. [NLA_U16] = sizeof(uint16_t),
  167. [NLA_U32] = sizeof(uint32_t),
  168. [NLA_U64] = sizeof(uint64_t),
  169. [NLA_STRING] = 1,
  170. [NLA_FLAG] = 0,
  171. };
  172. static int validate_nla(struct nlattr *nla, int maxtype,
  173. struct nla_policy *policy)
  174. {
  175. struct nla_policy *pt;
  176. unsigned int minlen = 0;
  177. int type = nla_type(nla);
  178. if (type < 0 || type > maxtype)
  179. return 0;
  180. pt = &policy[type];
  181. if (pt->type > NLA_TYPE_MAX)
  182. BUG();
  183. if (pt->minlen)
  184. minlen = pt->minlen;
  185. else if (pt->type != NLA_UNSPEC)
  186. minlen = nla_attr_minlen[pt->type];
  187. if (nla_len(nla) < minlen)
  188. return -NLE_RANGE;
  189. if (pt->maxlen && nla_len(nla) > pt->maxlen)
  190. return -NLE_RANGE;
  191. if (pt->type == NLA_STRING) {
  192. char *data = nla_data(nla);
  193. if (data[nla_len(nla) - 1] != '\0')
  194. return -NLE_INVAL;
  195. }
  196. return 0;
  197. }
  198. /**
  199. * Create attribute index based on a stream of attributes.
  200. * @arg tb Index array to be filled (maxtype+1 elements).
  201. * @arg maxtype Maximum attribute type expected and accepted.
  202. * @arg head Head of attribute stream.
  203. * @arg len Length of attribute stream.
  204. * @arg policy Attribute validation policy.
  205. *
  206. * Iterates over the stream of attributes and stores a pointer to each
  207. * attribute in the index array using the attribute type as index to
  208. * the array. Attribute with a type greater than the maximum type
  209. * specified will be silently ignored in order to maintain backwards
  210. * compatibility. If \a policy is not NULL, the attribute will be
  211. * validated using the specified policy.
  212. *
  213. * @see nla_validate
  214. * @return 0 on success or a negative error code.
  215. */
  216. int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
  217. struct nla_policy *policy)
  218. {
  219. struct nlattr *nla;
  220. int rem, err;
  221. memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
  222. nla_for_each_attr(nla, head, len, rem) {
  223. int type = nla_type(nla);
  224. if (type > maxtype)
  225. continue;
  226. if (policy) {
  227. err = validate_nla(nla, maxtype, policy);
  228. if (err < 0)
  229. goto errout;
  230. }
  231. if (tb[type])
  232. NL_DBG(1, "Attribute of type %#x found multiple times in message, "
  233. "previous attribute is being ignored.\n", type);
  234. tb[type] = nla;
  235. }
  236. if (rem > 0)
  237. NL_DBG(1, "netlink: %d bytes leftover after parsing "
  238. "attributes.\n", rem);
  239. err = 0;
  240. errout:
  241. return err;
  242. }
  243. /**
  244. * Validate a stream of attributes.
  245. * @arg head Head of attributes stream.
  246. * @arg len Length of attributes stream.
  247. * @arg maxtype Maximum attribute type expected and accepted.
  248. * @arg policy Validation policy.
  249. *
  250. * Iterates over the stream of attributes and validates each attribute
  251. * one by one using the specified policy. Attributes with a type greater
  252. * than the maximum type specified will be silently ignored in order to
  253. * maintain backwards compatibility.
  254. *
  255. * See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
  256. *
  257. * @return 0 on success or a negative error code.
  258. */
  259. int nla_validate(struct nlattr *head, int len, int maxtype,
  260. struct nla_policy *policy)
  261. {
  262. struct nlattr *nla;
  263. int rem, err;
  264. nla_for_each_attr(nla, head, len, rem) {
  265. err = validate_nla(nla, maxtype, policy);
  266. if (err < 0)
  267. goto errout;
  268. }
  269. err = 0;
  270. errout:
  271. return err;
  272. }
  273. /**
  274. * Find a single attribute in a stream of attributes.
  275. * @arg head Head of attributes stream.
  276. * @arg len Length of attributes stream.
  277. * @arg attrtype Attribute type to look for.
  278. *
  279. * Iterates over the stream of attributes and compares each type with
  280. * the type specified. Returns the first attribute which matches the
  281. * type.
  282. *
  283. * @return Pointer to attribute found or NULL.
  284. */
  285. struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
  286. {
  287. struct nlattr *nla;
  288. int rem;
  289. nla_for_each_attr(nla, head, len, rem)
  290. if (nla_type(nla) == attrtype)
  291. return nla;
  292. return NULL;
  293. }
  294. /** @} */
  295. /**
  296. * @name Helper Functions
  297. * @{
  298. */
  299. /**
  300. * Copy attribute payload to another memory area.
  301. * @arg dest Pointer to destination memory area.
  302. * @arg src Attribute
  303. * @arg count Number of bytes to copy at most.
  304. *
  305. * Note: The number of bytes copied is limited by the length of
  306. * the attribute payload.
  307. *
  308. * @return The number of bytes copied to dest.
  309. */
  310. int nla_memcpy(void *dest, struct nlattr *src, int count)
  311. {
  312. int minlen;
  313. if (!src)
  314. return 0;
  315. minlen = min_t(int, count, nla_len(src));
  316. memcpy(dest, nla_data(src), minlen);
  317. return minlen;
  318. }
  319. /**
  320. * Copy string attribute payload to a buffer.
  321. * @arg dst Pointer to destination buffer.
  322. * @arg nla Attribute of type NLA_STRING.
  323. * @arg dstsize Size of destination buffer in bytes.
  324. *
  325. * Copies at most dstsize - 1 bytes to the destination buffer.
  326. * The result is always a valid NUL terminated string. Unlike
  327. * strlcpy the destination buffer is always padded out.
  328. *
  329. * @return The length of string attribute without the terminating NUL.
  330. */
  331. size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
  332. {
  333. size_t srclen = nla_len(nla);
  334. char *src = nla_data(nla);
  335. if (srclen > 0 && src[srclen - 1] == '\0')
  336. srclen--;
  337. if (dstsize > 0) {
  338. size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
  339. memset(dst, 0, dstsize);
  340. memcpy(dst, src, len);
  341. }
  342. return srclen;
  343. }
  344. /**
  345. * Compare attribute payload with memory area.
  346. * @arg nla Attribute.
  347. * @arg data Memory area to compare to.
  348. * @arg size Number of bytes to compare.
  349. *
  350. * @see memcmp(3)
  351. * @return An integer less than, equal to, or greater than zero.
  352. */
  353. int nla_memcmp(const struct nlattr *nla, const void *data, size_t size)
  354. {
  355. int d = nla_len(nla) - size;
  356. if (d == 0)
  357. d = memcmp(nla_data(nla), data, size);
  358. return d;
  359. }
  360. /**
  361. * Compare string attribute payload with string
  362. * @arg nla Attribute of type NLA_STRING.
  363. * @arg str NUL terminated string.
  364. *
  365. * @see strcmp(3)
  366. * @return An integer less than, equal to, or greater than zero.
  367. */
  368. int nla_strcmp(const struct nlattr *nla, const char *str)
  369. {
  370. int len = strlen(str) + 1;
  371. int d = nla_len(nla) - len;
  372. if (d == 0)
  373. d = memcmp(nla_data(nla), str, len);
  374. return d;
  375. }
  376. /** @} */
  377. /**
  378. * @name Unspecific Attribute
  379. * @{
  380. */
  381. /**
  382. * Reserve space for a attribute.
  383. * @arg msg Netlink Message.
  384. * @arg attrtype Attribute Type.
  385. * @arg attrlen Length of payload.
  386. *
  387. * Reserves room for a attribute in the specified netlink message and
  388. * fills in the attribute header (type, length). Returns NULL if there
  389. * is unsuficient space for the attribute.
  390. *
  391. * Any padding between payload and the start of the next attribute is
  392. * zeroed out.
  393. *
  394. * @return Pointer to start of attribute or NULL on failure.
  395. */
  396. struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen)
  397. {
  398. struct nlattr *nla;
  399. int tlen;
  400. tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
  401. if (tlen > msg->nm_size)
  402. return NULL;
  403. nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
  404. nla->nla_type = attrtype;
  405. nla->nla_len = nla_attr_size(attrlen);
  406. if (attrlen)
  407. memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
  408. msg->nm_nlh->nlmsg_len = tlen;
  409. NL_DBG(2, "msg %p: attr <%p> %d: Reserved %d (%d) bytes at offset +%td "
  410. "nlmsg_len=%d\n", msg, nla, nla->nla_type,
  411. nla_total_size(attrlen), attrlen,
  412. (void *) nla - nlmsg_data(msg->nm_nlh),
  413. msg->nm_nlh->nlmsg_len);
  414. return nla;
  415. }
  416. /**
  417. * Add a unspecific attribute to netlink message.
  418. * @arg msg Netlink message.
  419. * @arg attrtype Attribute type.
  420. * @arg datalen Length of data to be used as payload.
  421. * @arg data Pointer to data to be used as attribute payload.
  422. *
  423. * Reserves room for a unspecific attribute and copies the provided data
  424. * into the message as payload of the attribute. Returns an error if there
  425. * is insufficient space for the attribute.
  426. *
  427. * @see nla_reserve
  428. * @return 0 on success or a negative error code.
  429. */
  430. int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
  431. {
  432. struct nlattr *nla;
  433. nla = nla_reserve(msg, attrtype, datalen);
  434. if (!nla)
  435. return -NLE_NOMEM;
  436. if (datalen > 0) {
  437. memcpy(nla_data(nla), data, datalen);
  438. NL_DBG(2, "msg %p: attr <%p> %d: Wrote %d bytes at offset +%td\n",
  439. msg, nla, nla->nla_type, datalen,
  440. (void *) nla - nlmsg_data(msg->nm_nlh));
  441. }
  442. return 0;
  443. }
  444. /**
  445. * Add abstract data as unspecific attribute to netlink message.
  446. * @arg msg Netlink message.
  447. * @arg attrtype Attribute type.
  448. * @arg data Abstract data object.
  449. *
  450. * Equivalent to nla_put() except that the length of the payload is
  451. * derived from the abstract data object.
  452. *
  453. * @see nla_put
  454. * @return 0 on success or a negative error code.
  455. */
  456. int nla_put_data(struct nl_msg *msg, int attrtype, struct nl_data *data)
  457. {
  458. return nla_put(msg, attrtype, nl_data_get_size(data),
  459. nl_data_get(data));
  460. }
  461. /**
  462. * Add abstract address as unspecific attribute to netlink message.
  463. * @arg msg Netlink message.
  464. * @arg attrtype Attribute type.
  465. * @arg addr Abstract address object.
  466. *
  467. * @see nla_put
  468. * @return 0 on success or a negative error code.
  469. */
  470. int nla_put_addr(struct nl_msg *msg, int attrtype, struct nl_addr *addr)
  471. {
  472. return nla_put(msg, attrtype, nl_addr_get_len(addr),
  473. nl_addr_get_binary_addr(addr));
  474. }
  475. /** @} */
  476. /**
  477. * @name Integer Attributes
  478. */
  479. /**
  480. * Add 8 bit integer attribute to netlink message.
  481. * @arg msg Netlink message.
  482. * @arg attrtype Attribute type.
  483. * @arg value Numeric value to store as payload.
  484. *
  485. * @see nla_put
  486. * @return 0 on success or a negative error code.
  487. */
  488. int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value)
  489. {
  490. return nla_put(msg, attrtype, sizeof(uint8_t), &value);
  491. }
  492. /**
  493. * Return value of 8 bit integer attribute.
  494. * @arg nla 8 bit integer attribute
  495. *
  496. * @return Payload as 8 bit integer.
  497. */
  498. uint8_t nla_get_u8(struct nlattr *nla)
  499. {
  500. return *(uint8_t *) nla_data(nla);
  501. }
  502. /**
  503. * Add 16 bit integer attribute to netlink message.
  504. * @arg msg Netlink message.
  505. * @arg attrtype Attribute type.
  506. * @arg value Numeric value to store as payload.
  507. *
  508. * @see nla_put
  509. * @return 0 on success or a negative error code.
  510. */
  511. int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value)
  512. {
  513. return nla_put(msg, attrtype, sizeof(uint16_t), &value);
  514. }
  515. /**
  516. * Return payload of 16 bit integer attribute.
  517. * @arg nla 16 bit integer attribute
  518. *
  519. * @return Payload as 16 bit integer.
  520. */
  521. uint16_t nla_get_u16(struct nlattr *nla)
  522. {
  523. return *(uint16_t *) nla_data(nla);
  524. }
  525. /**
  526. * Add 32 bit integer attribute to netlink message.
  527. * @arg msg Netlink message.
  528. * @arg attrtype Attribute type.
  529. * @arg value Numeric value to store as payload.
  530. *
  531. * @see nla_put
  532. * @return 0 on success or a negative error code.
  533. */
  534. int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value)
  535. {
  536. return nla_put(msg, attrtype, sizeof(uint32_t), &value);
  537. }
  538. /**
  539. * Return payload of 32 bit integer attribute.
  540. * @arg nla 32 bit integer attribute.
  541. *
  542. * @return Payload as 32 bit integer.
  543. */
  544. uint32_t nla_get_u32(struct nlattr *nla)
  545. {
  546. return *(uint32_t *) nla_data(nla);
  547. }
  548. /**
  549. * Add 64 bit integer attribute to netlink message.
  550. * @arg msg Netlink message.
  551. * @arg attrtype Attribute type.
  552. * @arg value Numeric value to store as payload.
  553. *
  554. * @see nla_put
  555. * @return 0 on success or a negative error code.
  556. */
  557. int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value)
  558. {
  559. return nla_put(msg, attrtype, sizeof(uint64_t), &value);
  560. }
  561. /**
  562. * Return payload of u64 attribute
  563. * @arg nla u64 netlink attribute
  564. *
  565. * @return Payload as 64 bit integer.
  566. */
  567. uint64_t nla_get_u64(struct nlattr *nla)
  568. {
  569. uint64_t tmp = 0;
  570. if (nla && nla_len(nla) >= sizeof(tmp))
  571. memcpy(&tmp, nla_data(nla), sizeof(tmp));
  572. return tmp;
  573. }
  574. /** @} */
  575. /**
  576. * @name String Attribute
  577. */
  578. /**
  579. * Add string attribute to netlink message.
  580. * @arg msg Netlink message.
  581. * @arg attrtype Attribute type.
  582. * @arg str NUL terminated string.
  583. *
  584. * @see nla_put
  585. * @return 0 on success or a negative error code.
  586. */
  587. int nla_put_string(struct nl_msg *msg, int attrtype, const char *str)
  588. {
  589. return nla_put(msg, attrtype, strlen(str) + 1, str);
  590. }
  591. /**
  592. * Return payload of string attribute.
  593. * @arg nla String attribute.
  594. *
  595. * @return Pointer to attribute payload.
  596. */
  597. char *nla_get_string(struct nlattr *nla)
  598. {
  599. return (char *) nla_data(nla);
  600. }
  601. char *nla_strdup(struct nlattr *nla)
  602. {
  603. return strdup(nla_get_string(nla));
  604. }
  605. /** @} */
  606. /**
  607. * @name Flag Attribute
  608. */
  609. /**
  610. * Add flag netlink attribute to netlink message.
  611. * @arg msg Netlink message.
  612. * @arg attrtype Attribute type.
  613. *
  614. * @see nla_put
  615. * @return 0 on success or a negative error code.
  616. */
  617. int nla_put_flag(struct nl_msg *msg, int attrtype)
  618. {
  619. return nla_put(msg, attrtype, 0, NULL);
  620. }
  621. /**
  622. * Return true if flag attribute is set.
  623. * @arg nla Flag netlink attribute.
  624. *
  625. * @return True if flag is set, otherwise false.
  626. */
  627. int nla_get_flag(struct nlattr *nla)
  628. {
  629. return !!nla;
  630. }
  631. /** @} */
  632. /**
  633. * @name Microseconds Attribute
  634. */
  635. /**
  636. * Add a msecs netlink attribute to a netlink message
  637. * @arg n netlink message
  638. * @arg attrtype attribute type
  639. * @arg msecs number of msecs
  640. */
  641. int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
  642. {
  643. return nla_put_u64(n, attrtype, msecs);
  644. }
  645. /**
  646. * Return payload of msecs attribute
  647. * @arg nla msecs netlink attribute
  648. *
  649. * @return the number of milliseconds.
  650. */
  651. unsigned long nla_get_msecs(struct nlattr *nla)
  652. {
  653. return nla_get_u64(nla);
  654. }
  655. /** @} */
  656. /**
  657. * @name Nested Attribute
  658. */
  659. /**
  660. * Add nested attributes to netlink message.
  661. * @arg msg Netlink message.
  662. * @arg attrtype Attribute type.
  663. * @arg nested Message containing attributes to be nested.
  664. *
  665. * Takes the attributes found in the \a nested message and appends them
  666. * to the message \a msg nested in a container of the type \a attrtype.
  667. * The \a nested message may not have a family specific header.
  668. *
  669. * @see nla_put
  670. * @return 0 on success or a negative error code.
  671. */
  672. int nla_put_nested(struct nl_msg *msg, int attrtype, struct nl_msg *nested)
  673. {
  674. NL_DBG(2, "msg %p: attr <> %d: adding msg %p as nested attribute\n",
  675. msg, attrtype, nested);
  676. return nla_put(msg, attrtype, nlmsg_datalen(nested->nm_nlh),
  677. nlmsg_data(nested->nm_nlh));
  678. }
  679. /**
  680. * Start a new level of nested attributes.
  681. * @arg msg Netlink message.
  682. * @arg attrtype Attribute type of container.
  683. *
  684. * @return Pointer to container attribute.
  685. */
  686. struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype)
  687. {
  688. struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
  689. if (nla_put(msg, attrtype, 0, NULL) < 0)
  690. return NULL;
  691. NL_DBG(2, "msg %p: attr <%p> %d: starting nesting\n",
  692. msg, start, start->nla_type);
  693. return start;
  694. }
  695. /**
  696. * Finalize nesting of attributes.
  697. * @arg msg Netlink message.
  698. * @arg start Container attribute as returned from nla_nest_start().
  699. *
  700. * Corrects the container attribute header to include the appeneded attributes.
  701. *
  702. * @return 0
  703. */
  704. int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
  705. {
  706. size_t pad, len;
  707. len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) start;
  708. if (len == NLA_HDRLEN) {
  709. /*
  710. * Kernel can't handle empty nested attributes, trim the
  711. * attribute header again
  712. */
  713. nla_nest_cancel(msg, start);
  714. return 0;
  715. }
  716. start->nla_len = len;
  717. pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len;
  718. if (pad > 0) {
  719. /*
  720. * Data inside attribute does not end at a alignment boundry.
  721. * Pad accordingly and accoun for the additional space in
  722. * the message. nlmsg_reserve() may never fail in this situation,
  723. * the allocate message buffer must be a multiple of NLMSG_ALIGNTO.
  724. */
  725. if (!nlmsg_reserve(msg, pad, 0))
  726. BUG();
  727. NL_DBG(2, "msg %p: attr <%p> %d: added %zu bytes of padding\n",
  728. msg, start, start->nla_type, pad);
  729. }
  730. NL_DBG(2, "msg %p: attr <%p> %d: closing nesting, len=%u\n",
  731. msg, start, start->nla_type, start->nla_len);
  732. return 0;
  733. }
  734. /**
  735. * Cancel the addition of a nested attribute
  736. * @arg msg Netlink message
  737. * @arg attr Nested netlink attribute
  738. *
  739. * Removes any partially added nested Netlink attribute from the message
  740. * by resetting the message to the size before the call to nla_nest_start()
  741. * and by overwriting any potentially touched message segments with 0.
  742. */
  743. void nla_nest_cancel(struct nl_msg *msg, struct nlattr *attr)
  744. {
  745. ssize_t len;
  746. len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) attr;
  747. if (len < 0)
  748. BUG();
  749. else if (len > 0) {
  750. msg->nm_nlh->nlmsg_len -= len;
  751. memset(nlmsg_tail(msg->nm_nlh), 0, len);
  752. }
  753. }
  754. /**
  755. * Create attribute index based on nested attribute
  756. * @arg tb Index array to be filled (maxtype+1 elements).
  757. * @arg maxtype Maximum attribute type expected and accepted.
  758. * @arg nla Nested Attribute.
  759. * @arg policy Attribute validation policy.
  760. *
  761. * Feeds the stream of attributes nested into the specified attribute
  762. * to nla_parse().
  763. *
  764. * @see nla_parse
  765. * @return 0 on success or a negative error code.
  766. */
  767. int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
  768. struct nla_policy *policy)
  769. {
  770. return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
  771. }
  772. /**
  773. * Return true if attribute has NLA_F_NESTED flag set
  774. * @arg attr Netlink attribute
  775. *
  776. * @return True if attribute has NLA_F_NESTED flag set, oterhwise False.
  777. */
  778. int nla_is_nested(struct nlattr *attr)
  779. {
  780. return !!(attr->nla_type & NLA_F_NESTED);
  781. }
  782. /** @} */
  783. /** @} */