2
0

attr.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. /*
  2. * netlink/attr.h 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-2008 Thomas Graf <tgraf@suug.ch>
  10. */
  11. #ifndef NETLINK_ATTR_H_
  12. #define NETLINK_ATTR_H_
  13. #include <netlink/netlink.h>
  14. #include <netlink/object.h>
  15. #include <netlink/addr.h>
  16. #include <netlink/data.h>
  17. #include <netlink/msg.h>
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21. struct nl_msg;
  22. /**
  23. * @name Basic Attribute Data Types
  24. * @{
  25. */
  26. /**
  27. * @ingroup attr
  28. * Basic attribute data types
  29. *
  30. * See \ref attr_datatypes for more details.
  31. */
  32. enum {
  33. NLA_UNSPEC, /**< Unspecified type, binary data chunk */
  34. NLA_U8, /**< 8 bit integer */
  35. NLA_U16, /**< 16 bit integer */
  36. NLA_U32, /**< 32 bit integer */
  37. NLA_U64, /**< 64 bit integer */
  38. NLA_STRING, /**< NUL terminated character string */
  39. NLA_FLAG, /**< Flag */
  40. NLA_MSECS, /**< Micro seconds (64bit) */
  41. NLA_NESTED, /**< Nested attributes */
  42. NLA_NESTED_ARRAY,
  43. NLA_NUL_STRING,
  44. NLA_BINARY,
  45. NLA_S8,
  46. NLA_S16,
  47. NLA_S32,
  48. NLA_S64,
  49. __NLA_TYPE_MAX,
  50. };
  51. #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
  52. /** @} */
  53. /**
  54. * @ingroup attr
  55. * Attribute validation policy.
  56. *
  57. * See \ref attr_datatypes for more details.
  58. */
  59. struct nla_policy {
  60. /** Type of attribute or NLA_UNSPEC */
  61. uint16_t type;
  62. /** Minimal length of payload required */
  63. uint16_t minlen;
  64. /** Maximal length of payload allowed */
  65. uint16_t maxlen;
  66. };
  67. /* Attribute parsing */
  68. extern int nla_ok(const struct nlattr *, int);
  69. extern struct nlattr * nla_next(const struct nlattr *, int *);
  70. extern int nla_parse(struct nlattr **, int, struct nlattr *,
  71. int, const struct nla_policy *);
  72. extern int nla_validate(const struct nlattr *, int, int,
  73. const struct nla_policy *);
  74. extern struct nlattr * nla_find(struct nlattr *, int, int);
  75. /* Unspecific attribute */
  76. extern struct nlattr * nla_reserve(struct nl_msg *, int, int);
  77. extern int nla_put(struct nl_msg *, int, int, const void *);
  78. /**
  79. * nlmsg_find_attr - find a specific attribute in a netlink message
  80. * @arg nlh netlink message header
  81. * @arg hdrlen length of familiy specific header
  82. * @arg attrtype type of attribute to look for
  83. *
  84. * Returns the first attribute which matches the specified type.
  85. */
  86. static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, int hdrlen, int attrtype)
  87. {
  88. return nla_find(nlmsg_attrdata(nlh, hdrlen),
  89. nlmsg_attrlen(nlh, hdrlen), attrtype);
  90. }
  91. /**
  92. * Return size of attribute whithout padding.
  93. * @arg payload Payload length of attribute.
  94. *
  95. * @code
  96. * <-------- nla_attr_size(payload) --------->
  97. * +------------------+- - -+- - - - - - - - - +- - -+
  98. * | Attribute Header | Pad | Payload | Pad |
  99. * +------------------+- - -+- - - - - - - - - +- - -+
  100. * @endcode
  101. *
  102. * @return Size of attribute in bytes without padding.
  103. */
  104. static inline int nla_attr_size(int payload)
  105. {
  106. return NLA_HDRLEN + payload;
  107. }
  108. /**
  109. * Return size of attribute including padding.
  110. * @arg payload Payload length of attribute.
  111. *
  112. * @code
  113. * <----------- nla_total_size(payload) ----------->
  114. * +------------------+- - -+- - - - - - - - - +- - -+
  115. * | Attribute Header | Pad | Payload | Pad |
  116. * +------------------+- - -+- - - - - - - - - +- - -+
  117. * @endcode
  118. *
  119. * @return Size of attribute in bytes.
  120. */
  121. static inline int nla_total_size(int payload)
  122. {
  123. return NLA_ALIGN(nla_attr_size(payload));
  124. }
  125. /**
  126. * Return length of padding at the tail of the attribute.
  127. * @arg payload Payload length of attribute.
  128. *
  129. * @code
  130. * +------------------+- - -+- - - - - - - - - +- - -+
  131. * | Attribute Header | Pad | Payload | Pad |
  132. * +------------------+- - -+- - - - - - - - - +- - -+
  133. * <--->
  134. * @endcode
  135. *
  136. * @return Length of padding in bytes.
  137. */
  138. static inline int nla_padlen(int payload)
  139. {
  140. return nla_total_size(payload) - nla_attr_size(payload);
  141. }
  142. /**
  143. * Return type of the attribute.
  144. * @arg nla Attribute.
  145. *
  146. * @return Type of attribute.
  147. */
  148. static inline int nla_type(const struct nlattr *nla)
  149. {
  150. return nla->nla_type & NLA_TYPE_MASK;
  151. }
  152. /**
  153. * Return pointer to the payload section.
  154. * @arg nla Attribute.
  155. *
  156. * @return Pointer to start of payload section.
  157. */
  158. static inline void *nla_data(const struct nlattr *nla)
  159. {
  160. return (char *) nla + NLA_HDRLEN;
  161. }
  162. /**
  163. * Return length of the payload .
  164. * @arg nla Attribute
  165. *
  166. * @return Length of payload in bytes.
  167. */
  168. static inline int nla_len(const struct nlattr *nla)
  169. {
  170. return nla->nla_len - NLA_HDRLEN;
  171. }
  172. /**
  173. * Copy attribute payload to another memory area.
  174. * @arg dest Pointer to destination memory area.
  175. * @arg src Attribute
  176. * @arg count Number of bytes to copy at most.
  177. *
  178. * Note: The number of bytes copied is limited by the length of
  179. * the attribute payload.
  180. *
  181. * @return The number of bytes copied to dest.
  182. */
  183. static inline int nla_memcpy(void *dest, const struct nlattr *src, int count)
  184. {
  185. int minlen;
  186. if (!src)
  187. return 0;
  188. minlen = min_t(int, count, nla_len(src));
  189. memcpy(dest, nla_data(src), minlen);
  190. return minlen;
  191. }
  192. /**
  193. * Add abstract data as unspecific attribute to netlink message.
  194. * @arg msg Netlink message.
  195. * @arg attrtype Attribute type.
  196. * @arg data Abstract data object.
  197. *
  198. * Equivalent to nla_put() except that the length of the payload is
  199. * derived from the abstract data object.
  200. *
  201. * @see nla_put
  202. * @return 0 on success or a negative error code.
  203. */
  204. static inline int nla_put_data(struct nl_msg *msg, int attrtype, struct nl_data *data)
  205. {
  206. return nla_put(msg, attrtype, nl_data_get_size(data),
  207. nl_data_get(data));
  208. }
  209. /**
  210. * Add abstract address as unspecific attribute to netlink message.
  211. * @arg msg Netlink message.
  212. * @arg attrtype Attribute type.
  213. * @arg addr Abstract address object.
  214. *
  215. * @see nla_put
  216. * @return 0 on success or a negative error code.
  217. */
  218. static inline int nla_put_addr(struct nl_msg *msg, int attrtype, struct nl_addr *addr)
  219. {
  220. return nla_put(msg, attrtype, nl_addr_get_len(addr),
  221. nl_addr_get_binary_addr(addr));
  222. }
  223. /** @} */
  224. /**
  225. * @name Integer Attributes
  226. */
  227. /**
  228. * Add 8 bit signed integer attribute to netlink message.
  229. * @arg msg Netlink message.
  230. * @arg attrtype Attribute type.
  231. * @arg value Numeric value to store as payload.
  232. *
  233. * @see nla_put
  234. * @return 0 on success or a negative error code.
  235. */
  236. static inline int nla_put_s8(struct nl_msg *msg, int attrtype, int8_t value)
  237. {
  238. return nla_put(msg, attrtype, sizeof(int8_t), &value);
  239. }
  240. /**
  241. * Return value of 8 bit signed integer attribute.
  242. * @arg nla 8 bit integer attribute
  243. *
  244. * @return Payload as 8 bit integer.
  245. */
  246. static inline int8_t nla_get_s8(const struct nlattr *nla)
  247. {
  248. return *(const int8_t *) nla_data(nla);
  249. }
  250. /**
  251. * Add 8 bit integer attribute to netlink message.
  252. * @arg msg Netlink message.
  253. * @arg attrtype Attribute type.
  254. * @arg value Numeric value to store as payload.
  255. *
  256. * @see nla_put
  257. * @return 0 on success or a negative error code.
  258. */
  259. static inline int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value)
  260. {
  261. return nla_put(msg, attrtype, sizeof(uint8_t), &value);
  262. }
  263. /**
  264. * Return value of 8 bit integer attribute.
  265. * @arg nla 8 bit integer attribute
  266. *
  267. * @return Payload as 8 bit integer.
  268. */
  269. static inline uint8_t nla_get_u8(const struct nlattr *nla)
  270. {
  271. return *(const uint8_t *) nla_data(nla);
  272. }
  273. /**
  274. * Add 16 bit signed integer attribute to netlink message.
  275. * @arg msg Netlink message.
  276. * @arg attrtype Attribute type.
  277. * @arg value Numeric value to store as payload.
  278. *
  279. * @see nla_put
  280. * @return 0 on success or a negative error code.
  281. */
  282. static inline int nla_put_s16(struct nl_msg *msg, int attrtype, int16_t value)
  283. {
  284. return nla_put(msg, attrtype, sizeof(int16_t), &value);
  285. }
  286. /**
  287. * Return payload of 16 bit signed integer attribute.
  288. * @arg nla 16 bit integer attribute
  289. *
  290. * @return Payload as 16 bit integer.
  291. */
  292. static inline int16_t nla_get_s16(const struct nlattr *nla)
  293. {
  294. return *(const int16_t *) nla_data(nla);
  295. }
  296. /**
  297. * Add 16 bit integer attribute to netlink message.
  298. * @arg msg Netlink message.
  299. * @arg attrtype Attribute type.
  300. * @arg value Numeric value to store as payload.
  301. *
  302. * @see nla_put
  303. * @return 0 on success or a negative error code.
  304. */
  305. static inline int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value)
  306. {
  307. return nla_put(msg, attrtype, sizeof(uint16_t), &value);
  308. }
  309. /**
  310. * Return payload of 16 bit integer attribute.
  311. * @arg nla 16 bit integer attribute
  312. *
  313. * @return Payload as 16 bit integer.
  314. */
  315. static inline uint16_t nla_get_u16(const struct nlattr *nla)
  316. {
  317. return *(const uint16_t *) nla_data(nla);
  318. }
  319. /**
  320. * Add 32 bit signed integer attribute to netlink message.
  321. * @arg msg Netlink message.
  322. * @arg attrtype Attribute type.
  323. * @arg value Numeric value to store as payload.
  324. *
  325. * @see nla_put
  326. * @return 0 on success or a negative error code.
  327. */
  328. static inline int nla_put_s32(struct nl_msg *msg, int attrtype, int32_t value)
  329. {
  330. return nla_put(msg, attrtype, sizeof(int32_t), &value);
  331. }
  332. /**
  333. * Return payload of 32 bit signed integer attribute.
  334. * @arg nla 32 bit integer attribute.
  335. *
  336. * @return Payload as 32 bit integer.
  337. */
  338. static inline int32_t nla_get_s32(const struct nlattr *nla)
  339. {
  340. return *(const int32_t *) nla_data(nla);
  341. }
  342. /**
  343. * Add 32 bit integer attribute to netlink message.
  344. * @arg msg Netlink message.
  345. * @arg attrtype Attribute type.
  346. * @arg value Numeric value to store as payload.
  347. *
  348. * @see nla_put
  349. * @return 0 on success or a negative error code.
  350. */
  351. static inline int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value)
  352. {
  353. return nla_put(msg, attrtype, sizeof(uint32_t), &value);
  354. }
  355. /**
  356. * Return payload of 32 bit integer attribute.
  357. * @arg nla 32 bit integer attribute.
  358. *
  359. * @return Payload as 32 bit integer.
  360. */
  361. static inline uint32_t nla_get_u32(const struct nlattr *nla)
  362. {
  363. return *(const uint32_t *) nla_data(nla);
  364. }
  365. /**
  366. * Add 64 bit signed integer attribute to netlink message.
  367. * @arg msg Netlink message.
  368. * @arg attrtype Attribute type.
  369. * @arg value Numeric value to store as payload.
  370. *
  371. * @see nla_put
  372. * @return 0 on success or a negative error code.
  373. */
  374. static inline int nla_put_s64(struct nl_msg *msg, int attrtype, int64_t value)
  375. {
  376. return nla_put(msg, attrtype, sizeof(int64_t), &value);
  377. }
  378. /**
  379. * Return payload of s64 attribute
  380. * @arg nla s64 netlink attribute
  381. *
  382. * @return Payload as 64 bit integer.
  383. */
  384. static inline int64_t nla_get_s64(const struct nlattr *nla)
  385. {
  386. int64_t tmp;
  387. nla_memcpy(&tmp, nla, sizeof(tmp));
  388. return tmp;
  389. }
  390. /**
  391. * Add 64 bit integer attribute to netlink message.
  392. * @arg msg Netlink message.
  393. * @arg attrtype Attribute type.
  394. * @arg value Numeric value to store as payload.
  395. *
  396. * @see nla_put
  397. * @return 0 on success or a negative error code.
  398. */
  399. static inline int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value)
  400. {
  401. return nla_put(msg, attrtype, sizeof(uint64_t), &value);
  402. }
  403. /**
  404. * Return payload of u64 attribute
  405. * @arg nla u64 netlink attribute
  406. *
  407. * @return Payload as 64 bit integer.
  408. */
  409. static inline uint64_t nla_get_u64(const struct nlattr *nla)
  410. {
  411. uint64_t tmp;
  412. nla_memcpy(&tmp, nla, sizeof(tmp));
  413. return tmp;
  414. }
  415. /**
  416. * Add string attribute to netlink message.
  417. * @arg msg Netlink message.
  418. * @arg attrtype Attribute type.
  419. * @arg str NUL terminated string.
  420. *
  421. * @see nla_put
  422. * @return 0 on success or a negative error code.
  423. */
  424. static inline int nla_put_string(struct nl_msg *msg, int attrtype, const char *str)
  425. {
  426. return nla_put(msg, attrtype, strlen(str) + 1, str);
  427. }
  428. /**
  429. * Return payload of string attribute.
  430. * @arg nla String attribute.
  431. *
  432. * @return Pointer to attribute payload.
  433. */
  434. static inline char *nla_get_string(const struct nlattr *nla)
  435. {
  436. return (char *) nla_data(nla);
  437. }
  438. static inline char *nla_strdup(const struct nlattr *nla)
  439. {
  440. return strdup(nla_get_string(nla));
  441. }
  442. /** @} */
  443. /**
  444. * @name Flag Attribute
  445. */
  446. /**
  447. * Add flag netlink attribute to netlink message.
  448. * @arg msg Netlink message.
  449. * @arg attrtype Attribute type.
  450. *
  451. * @see nla_put
  452. * @return 0 on success or a negative error code.
  453. */
  454. static inline int nla_put_flag(struct nl_msg *msg, int attrtype)
  455. {
  456. return nla_put(msg, attrtype, 0, NULL);
  457. }
  458. /**
  459. * Return true if flag attribute is set.
  460. * @arg nla Flag netlink attribute.
  461. *
  462. * @return True if flag is set, otherwise false.
  463. */
  464. static inline int nla_get_flag(const struct nlattr *nla)
  465. {
  466. return !!nla;
  467. }
  468. /** @} */
  469. /**
  470. * @name Microseconds Attribute
  471. */
  472. /**
  473. * Add a msecs netlink attribute to a netlink message
  474. * @arg n netlink message
  475. * @arg attrtype attribute type
  476. * @arg msecs number of msecs
  477. */
  478. static inline int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
  479. {
  480. return nla_put_u64(n, attrtype, msecs);
  481. }
  482. /**
  483. * Return payload of msecs attribute
  484. * @arg nla msecs netlink attribute
  485. *
  486. * @return the number of milliseconds.
  487. */
  488. static inline unsigned long nla_get_msecs(const struct nlattr *nla)
  489. {
  490. return nla_get_u64(nla);
  491. }
  492. /**
  493. * Add nested attributes to netlink message.
  494. * @arg msg Netlink message.
  495. * @arg attrtype Attribute type.
  496. * @arg nested Message containing attributes to be nested.
  497. *
  498. * Takes the attributes found in the \a nested message and appends them
  499. * to the message \a msg nested in a container of the type \a attrtype.
  500. * The \a nested message may not have a family specific header.
  501. *
  502. * @see nla_put
  503. * @return 0 on success or a negative error code.
  504. */
  505. static inline int nla_put_nested(struct nl_msg *msg, int attrtype, const struct nl_msg *nested)
  506. {
  507. return nla_put(msg, attrtype, nlmsg_len(nested->nm_nlh),
  508. nlmsg_data(nested->nm_nlh));
  509. }
  510. /**
  511. * Start a new level of nested attributes.
  512. * @arg msg Netlink message.
  513. * @arg attrtype Attribute type of container.
  514. *
  515. * @return Pointer to container attribute.
  516. */
  517. static inline struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype)
  518. {
  519. struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
  520. if (nla_put(msg, attrtype | NLA_F_NESTED, 0, NULL) < 0)
  521. return NULL;
  522. return start;
  523. }
  524. /**
  525. * Finalize nesting of attributes.
  526. * @arg msg Netlink message.
  527. * @arg start Container attribute as returned from nla_nest_start().
  528. *
  529. * Corrects the container attribute header to include the appeneded attributes.
  530. *
  531. * @return 0
  532. */
  533. static inline int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
  534. {
  535. start->nla_len = (unsigned char *) nlmsg_tail(msg->nm_nlh) -
  536. (unsigned char *) start;
  537. return 0;
  538. }
  539. /**
  540. * Create attribute index based on nested attribute
  541. * @arg tb Index array to be filled (maxtype+1 elements).
  542. * @arg maxtype Maximum attribute type expected and accepted.
  543. * @arg nla Nested Attribute.
  544. * @arg policy Attribute validation policy.
  545. *
  546. * Feeds the stream of attributes nested into the specified attribute
  547. * to nla_parse().
  548. *
  549. * @see nla_parse
  550. * @return 0 on success or a negative error code.
  551. */
  552. static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
  553. const struct nla_policy *policy)
  554. {
  555. return nla_parse(tb, maxtype, (struct nlattr *)nla_data(nla), nla_len(nla), policy);
  556. }
  557. /**
  558. * Compare attribute payload with memory area.
  559. * @arg nla Attribute.
  560. * @arg data Memory area to compare to.
  561. * @arg size Number of bytes to compare.
  562. *
  563. * @see memcmp(3)
  564. * @return An integer less than, equal to, or greater than zero.
  565. */
  566. static inline int nla_memcmp(const struct nlattr *nla, const void *data, size_t size)
  567. {
  568. int d = nla_len(nla) - size;
  569. if (d == 0)
  570. d = memcmp(nla_data(nla), data, size);
  571. return d;
  572. }
  573. /**
  574. * Compare string attribute payload with string
  575. * @arg nla Attribute of type NLA_STRING.
  576. * @arg str NUL terminated string.
  577. *
  578. * @see strcmp(3)
  579. * @return An integer less than, equal to, or greater than zero.
  580. */
  581. static inline int nla_strcmp(const struct nlattr *nla, const char *str)
  582. {
  583. int len = strlen(str) + 1;
  584. int d = nla_len(nla) - len;
  585. if (d == 0)
  586. d = memcmp(nla_data(nla), str, len);
  587. return d;
  588. }
  589. /**
  590. * Copy string attribute payload to a buffer.
  591. * @arg dst Pointer to destination buffer.
  592. * @arg nla Attribute of type NLA_STRING.
  593. * @arg dstsize Size of destination buffer in bytes.
  594. *
  595. * Copies at most dstsize - 1 bytes to the destination buffer.
  596. * The result is always a valid NUL terminated string. Unlike
  597. * strlcpy the destination buffer is always padded out.
  598. *
  599. * @return The length of string attribute without the terminating NUL.
  600. */
  601. static inline size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
  602. {
  603. size_t srclen = (size_t)nla_len(nla);
  604. char *src = (char*)nla_data(nla);
  605. if (srclen > 0 && src[srclen - 1] == '\0')
  606. srclen--;
  607. if (dstsize > 0) {
  608. size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
  609. memset(dst, 0, dstsize);
  610. memcpy(dst, src, len);
  611. }
  612. return srclen;
  613. }
  614. /**
  615. * @name Attribute Construction (Exception Based)
  616. * @{
  617. */
  618. /**
  619. * @ingroup attr
  620. * Add unspecific attribute to netlink message.
  621. * @arg msg Netlink message.
  622. * @arg attrtype Attribute type.
  623. * @arg attrlen Length of attribute payload.
  624. * @arg data Head of attribute payload.
  625. */
  626. #define NLA_PUT(msg, attrtype, attrlen, data) \
  627. do { \
  628. if (nla_put(msg, attrtype, attrlen, data) < 0) \
  629. goto nla_put_failure; \
  630. } while(0)
  631. /**
  632. * @ingroup attr
  633. * Add atomic type attribute to netlink message.
  634. * @arg msg Netlink message.
  635. * @arg type Atomic type.
  636. * @arg attrtype Attribute type.
  637. * @arg value Head of attribute payload.
  638. */
  639. #define NLA_PUT_TYPE(msg, type, attrtype, value) \
  640. do { \
  641. type __tmp = value; \
  642. NLA_PUT(msg, attrtype, sizeof(type), &__tmp); \
  643. } while(0)
  644. /**
  645. * Add 8 bit signed integer attribute to netlink message.
  646. * @arg msg Netlink message.
  647. * @arg attrtype Attribute type.
  648. * @arg value Numeric value.
  649. */
  650. #define NLA_PUT_S8(msg, attrtype, value) \
  651. NLA_PUT_TYPE(msg, int8_t, attrtype, value)
  652. /**
  653. * Add 8 bit signed integer attribute to netlink message.
  654. * @arg msg Netlink message.
  655. * @arg attrtype Attribute type.
  656. * @arg value Numeric value.
  657. */
  658. #define NLA_PUT_S8(msg, attrtype, value) \
  659. NLA_PUT_TYPE(msg, int8_t, attrtype, value)
  660. /**
  661. * Add 8 bit integer attribute to netlink message.
  662. * @arg msg Netlink message.
  663. * @arg attrtype Attribute type.
  664. * @arg value Numeric value.
  665. */
  666. #define NLA_PUT_U8(msg, attrtype, value) \
  667. NLA_PUT_TYPE(msg, uint8_t, attrtype, value)
  668. /**
  669. * Add 16 bit signed integer attribute to netlink message.
  670. * @arg msg Netlink message.
  671. * @arg attrtype Attribute type.
  672. * @arg value Numeric value.
  673. */
  674. #define NLA_PUT_S16(msg, attrtype, value) \
  675. NLA_PUT_TYPE(msg, int16_t, attrtype, value)
  676. /**
  677. * Add 16 bit integer attribute to netlink message.
  678. * @arg msg Netlink message.
  679. * @arg attrtype Attribute type.
  680. * @arg value Numeric value.
  681. */
  682. #define NLA_PUT_U16(msg, attrtype, value) \
  683. NLA_PUT_TYPE(msg, uint16_t, attrtype, value)
  684. /**
  685. * Add 32 bit signed integer attribute to netlink message.
  686. * @arg msg Netlink message.
  687. * @arg attrtype Attribute type.
  688. * @arg value Numeric value.
  689. */
  690. #define NLA_PUT_S32(msg, attrtype, value) \
  691. NLA_PUT_TYPE(msg, int32_t, attrtype, value)
  692. /**
  693. * Add 32 bit integer attribute to netlink message.
  694. * @arg msg Netlink message.
  695. * @arg attrtype Attribute type.
  696. * @arg value Numeric value.
  697. */
  698. #define NLA_PUT_U32(msg, attrtype, value) \
  699. NLA_PUT_TYPE(msg, uint32_t, attrtype, value)
  700. /**
  701. * Add 64 bit signed integer attribute to netlink message.
  702. * @arg msg Netlink message.
  703. * @arg attrtype Attribute type.
  704. * @arg value Numeric value.
  705. */
  706. #define NLA_PUT_S64(msg, attrtype, value) \
  707. NLA_PUT_TYPE(msg, int64_t, attrtype, value)
  708. /**
  709. * Add 64 bit integer attribute to netlink message.
  710. * @arg msg Netlink message.
  711. * @arg attrtype Attribute type.
  712. * @arg value Numeric value.
  713. */
  714. #define NLA_PUT_U64(msg, attrtype, value) \
  715. NLA_PUT_TYPE(msg, uint64_t, attrtype, value)
  716. /**
  717. * Add string attribute to netlink message.
  718. * @arg msg Netlink message.
  719. * @arg attrtype Attribute type.
  720. * @arg value NUL terminated character string.
  721. */
  722. #define NLA_PUT_STRING(msg, attrtype, value) \
  723. NLA_PUT(msg, attrtype, strlen(value) + 1, value)
  724. /**
  725. * Add flag attribute to netlink message.
  726. * @arg msg Netlink message.
  727. * @arg attrtype Attribute type.
  728. */
  729. #define NLA_PUT_FLAG(msg, attrtype) \
  730. NLA_PUT(msg, attrtype, 0, NULL)
  731. /**
  732. * Add msecs attribute to netlink message.
  733. * @arg msg Netlink message.
  734. * @arg attrtype Attribute type.
  735. * @arg msecs Numeric value in micro seconds.
  736. */
  737. #define NLA_PUT_MSECS(msg, attrtype, msecs) \
  738. NLA_PUT_U64(msg, attrtype, msecs)
  739. /**
  740. * Add address attribute to netlink message.
  741. * @arg msg Netlink message.
  742. * @arg attrtype Attribute type.
  743. * @arg addr Abstract address object.
  744. */
  745. #define NLA_PUT_ADDR(msg, attrtype, addr) \
  746. NLA_PUT(msg, attrtype, nl_addr_get_len(addr), \
  747. nl_addr_get_binary_addr(addr))
  748. /** @} */
  749. /**
  750. * @name Iterators
  751. * @{
  752. */
  753. /**
  754. * @ingroup attr
  755. * Iterate over a stream of attributes
  756. * @arg pos loop counter, set to current attribute
  757. * @arg head head of attribute stream
  758. * @arg len length of attribute stream
  759. * @arg rem initialized to len, holds bytes currently remaining in stream
  760. */
  761. #define nla_for_each_attr(pos, head, len, rem) \
  762. for (pos = head, rem = len; \
  763. nla_ok(pos, rem); \
  764. pos = nla_next(pos, &(rem)))
  765. /**
  766. * @ingroup attr
  767. * Iterate over a stream of nested attributes
  768. * @arg pos loop counter, set to current attribute
  769. * @arg nla attribute containing the nested attributes
  770. * @arg rem initialized to len, holds bytes currently remaining in stream
  771. */
  772. #define nla_for_each_nested(pos, nla, rem) \
  773. for (pos = (struct nlattr *)nla_data(nla), rem = nla_len(nla); \
  774. nla_ok(pos, rem); \
  775. pos = nla_next(pos, &(rem)))
  776. /** @} */
  777. #ifdef __cplusplus
  778. }
  779. #endif
  780. #endif