1bfa83a9eSThomas Graf #ifndef __NET_NETLINK_H 2bfa83a9eSThomas Graf #define __NET_NETLINK_H 3bfa83a9eSThomas Graf 4bfa83a9eSThomas Graf #include <linux/types.h> 5bfa83a9eSThomas Graf #include <linux/netlink.h> 6bfa83a9eSThomas Graf 7bfa83a9eSThomas Graf /* ======================================================================== 8bfa83a9eSThomas Graf * Netlink Messages and Attributes Interface (As Seen On TV) 9bfa83a9eSThomas Graf * ------------------------------------------------------------------------ 10bfa83a9eSThomas Graf * Messages Interface 11bfa83a9eSThomas Graf * ------------------------------------------------------------------------ 12bfa83a9eSThomas Graf * 13bfa83a9eSThomas Graf * Message Format: 14bfa83a9eSThomas Graf * <--- nlmsg_total_size(payload) ---> 15bfa83a9eSThomas Graf * <-- nlmsg_msg_size(payload) -> 16bfa83a9eSThomas Graf * +----------+- - -+-------------+- - -+-------- - - 17bfa83a9eSThomas Graf * | nlmsghdr | Pad | Payload | Pad | nlmsghdr 18bfa83a9eSThomas Graf * +----------+- - -+-------------+- - -+-------- - - 19bfa83a9eSThomas Graf * nlmsg_data(nlh)---^ ^ 20bfa83a9eSThomas Graf * nlmsg_next(nlh)-----------------------+ 21bfa83a9eSThomas Graf * 22bfa83a9eSThomas Graf * Payload Format: 23bfa83a9eSThomas Graf * <---------------------- nlmsg_len(nlh) ---------------------> 24bfa83a9eSThomas Graf * <------ hdrlen ------> <- nlmsg_attrlen(nlh, hdrlen) -> 25bfa83a9eSThomas Graf * +----------------------+- - -+--------------------------------+ 26bfa83a9eSThomas Graf * | Family Header | Pad | Attributes | 27bfa83a9eSThomas Graf * +----------------------+- - -+--------------------------------+ 28bfa83a9eSThomas Graf * nlmsg_attrdata(nlh, hdrlen)---^ 29bfa83a9eSThomas Graf * 30bfa83a9eSThomas Graf * Data Structures: 31bfa83a9eSThomas Graf * struct nlmsghdr netlink message header 32bfa83a9eSThomas Graf * 33bfa83a9eSThomas Graf * Message Construction: 34bfa83a9eSThomas Graf * nlmsg_new() create a new netlink message 35bfa83a9eSThomas Graf * nlmsg_put() add a netlink message to an skb 36bfa83a9eSThomas Graf * nlmsg_put_answer() callback based nlmsg_put() 37bfa83a9eSThomas Graf * nlmsg_end() finanlize netlink message 38fe4944e5SThomas Graf * nlmsg_get_pos() return current position in message 39fe4944e5SThomas Graf * nlmsg_trim() trim part of message 40bfa83a9eSThomas Graf * nlmsg_cancel() cancel message construction 41bfa83a9eSThomas Graf * nlmsg_free() free a netlink message 42bfa83a9eSThomas Graf * 43bfa83a9eSThomas Graf * Message Sending: 44bfa83a9eSThomas Graf * nlmsg_multicast() multicast message to several groups 45bfa83a9eSThomas Graf * nlmsg_unicast() unicast a message to a single socket 46bfa83a9eSThomas Graf * 47bfa83a9eSThomas Graf * Message Length Calculations: 48bfa83a9eSThomas Graf * nlmsg_msg_size(payload) length of message w/o padding 49bfa83a9eSThomas Graf * nlmsg_total_size(payload) length of message w/ padding 50bfa83a9eSThomas Graf * nlmsg_padlen(payload) length of padding at tail 51bfa83a9eSThomas Graf * 52bfa83a9eSThomas Graf * Message Payload Access: 53bfa83a9eSThomas Graf * nlmsg_data(nlh) head of message payload 54bfa83a9eSThomas Graf * nlmsg_len(nlh) length of message payload 55bfa83a9eSThomas Graf * nlmsg_attrdata(nlh, hdrlen) head of attributes data 56bfa83a9eSThomas Graf * nlmsg_attrlen(nlh, hdrlen) length of attributes data 57bfa83a9eSThomas Graf * 58bfa83a9eSThomas Graf * Message Parsing: 59bfa83a9eSThomas Graf * nlmsg_ok(nlh, remaining) does nlh fit into remaining bytes? 60bfa83a9eSThomas Graf * nlmsg_next(nlh, remaining) get next netlink message 61bfa83a9eSThomas Graf * nlmsg_parse() parse attributes of a message 62bfa83a9eSThomas Graf * nlmsg_find_attr() find an attribute in a message 63bfa83a9eSThomas Graf * nlmsg_for_each_msg() loop over all messages 64bfa83a9eSThomas Graf * nlmsg_validate() validate netlink message incl. attrs 65bfa83a9eSThomas Graf * nlmsg_for_each_attr() loop over all attributes 66bfa83a9eSThomas Graf * 67bfa83a9eSThomas Graf * ------------------------------------------------------------------------ 68bfa83a9eSThomas Graf * Attributes Interface 69bfa83a9eSThomas Graf * ------------------------------------------------------------------------ 70bfa83a9eSThomas Graf * 71bfa83a9eSThomas Graf * Attribute Format: 72bfa83a9eSThomas Graf * <------- nla_total_size(payload) -------> 73bfa83a9eSThomas Graf * <---- nla_attr_size(payload) -----> 74bfa83a9eSThomas Graf * +----------+- - -+- - - - - - - - - +- - -+-------- - - 75bfa83a9eSThomas Graf * | Header | Pad | Payload | Pad | Header 76bfa83a9eSThomas Graf * +----------+- - -+- - - - - - - - - +- - -+-------- - - 77bfa83a9eSThomas Graf * <- nla_len(nla) -> ^ 78bfa83a9eSThomas Graf * nla_data(nla)----^ | 79bfa83a9eSThomas Graf * nla_next(nla)-----------------------------' 80bfa83a9eSThomas Graf * 81bfa83a9eSThomas Graf * Data Structures: 82bfa83a9eSThomas Graf * struct nlattr netlink attribtue header 83bfa83a9eSThomas Graf * 84bfa83a9eSThomas Graf * Attribute Construction: 85fe4944e5SThomas Graf * nla_reserve(skb, type, len) reserve room for an attribute 86fe4944e5SThomas Graf * nla_reserve_nohdr(skb, len) reserve room for an attribute w/o hdr 87bfa83a9eSThomas Graf * nla_put(skb, type, len, data) add attribute to skb 88fe4944e5SThomas Graf * nla_put_nohdr(skb, len, data) add attribute w/o hdr 89bfa83a9eSThomas Graf * 90bfa83a9eSThomas Graf * Attribute Construction for Basic Types: 91bfa83a9eSThomas Graf * nla_put_u8(skb, type, value) add u8 attribute to skb 92bfa83a9eSThomas Graf * nla_put_u16(skb, type, value) add u16 attribute to skb 93bfa83a9eSThomas Graf * nla_put_u32(skb, type, value) add u32 attribute to skb 94bfa83a9eSThomas Graf * nla_put_u64(skb, type, value) add u64 attribute to skb 95bfa83a9eSThomas Graf * nla_put_string(skb, type, str) add string attribute to skb 96bfa83a9eSThomas Graf * nla_put_flag(skb, type) add flag attribute to skb 97bfa83a9eSThomas Graf * nla_put_msecs(skb, type, jiffies) add msecs attribute to skb 98bfa83a9eSThomas Graf * 99bfa83a9eSThomas Graf * Exceptions Based Attribute Construction: 100bfa83a9eSThomas Graf * NLA_PUT(skb, type, len, data) add attribute to skb 101bfa83a9eSThomas Graf * NLA_PUT_U8(skb, type, value) add u8 attribute to skb 102bfa83a9eSThomas Graf * NLA_PUT_U16(skb, type, value) add u16 attribute to skb 103bfa83a9eSThomas Graf * NLA_PUT_U32(skb, type, value) add u32 attribute to skb 104bfa83a9eSThomas Graf * NLA_PUT_U64(skb, type, value) add u64 attribute to skb 105bfa83a9eSThomas Graf * NLA_PUT_STRING(skb, type, str) add string attribute to skb 106bfa83a9eSThomas Graf * NLA_PUT_FLAG(skb, type) add flag attribute to skb 107bfa83a9eSThomas Graf * NLA_PUT_MSECS(skb, type, jiffies) add msecs attribute to skb 108bfa83a9eSThomas Graf * 109bfa83a9eSThomas Graf * The meaning of these functions is equal to their lower case 110bfa83a9eSThomas Graf * variants but they jump to the label nla_put_failure in case 111bfa83a9eSThomas Graf * of a failure. 112bfa83a9eSThomas Graf * 113bfa83a9eSThomas Graf * Nested Attributes Construction: 114bfa83a9eSThomas Graf * nla_nest_start(skb, type) start a nested attribute 115bfa83a9eSThomas Graf * nla_nest_end(skb, nla) finalize a nested attribute 116bfa83a9eSThomas Graf * nla_nest_cancel(skb, nla) cancel nested attribute construction 117bfa83a9eSThomas Graf * 118bfa83a9eSThomas Graf * Attribute Length Calculations: 119bfa83a9eSThomas Graf * nla_attr_size(payload) length of attribute w/o padding 120bfa83a9eSThomas Graf * nla_total_size(payload) length of attribute w/ padding 121bfa83a9eSThomas Graf * nla_padlen(payload) length of padding 122bfa83a9eSThomas Graf * 123bfa83a9eSThomas Graf * Attribute Payload Access: 124bfa83a9eSThomas Graf * nla_data(nla) head of attribute payload 125bfa83a9eSThomas Graf * nla_len(nla) length of attribute payload 126bfa83a9eSThomas Graf * 127bfa83a9eSThomas Graf * Attribute Payload Access for Basic Types: 128bfa83a9eSThomas Graf * nla_get_u8(nla) get payload for a u8 attribute 129bfa83a9eSThomas Graf * nla_get_u16(nla) get payload for a u16 attribute 130bfa83a9eSThomas Graf * nla_get_u32(nla) get payload for a u32 attribute 131bfa83a9eSThomas Graf * nla_get_u64(nla) get payload for a u64 attribute 132bfa83a9eSThomas Graf * nla_get_flag(nla) return 1 if flag is true 133bfa83a9eSThomas Graf * nla_get_msecs(nla) get payload for a msecs attribute 134bfa83a9eSThomas Graf * 135bfa83a9eSThomas Graf * Attribute Misc: 136bfa83a9eSThomas Graf * nla_memcpy(dest, nla, count) copy attribute into memory 137bfa83a9eSThomas Graf * nla_memcmp(nla, data, size) compare attribute with memory area 138bfa83a9eSThomas Graf * nla_strlcpy(dst, nla, size) copy attribute to a sized string 139bfa83a9eSThomas Graf * nla_strcmp(nla, str) compare attribute with string 140bfa83a9eSThomas Graf * 141bfa83a9eSThomas Graf * Attribute Parsing: 142bfa83a9eSThomas Graf * nla_ok(nla, remaining) does nla fit into remaining bytes? 143bfa83a9eSThomas Graf * nla_next(nla, remaining) get next netlink attribute 144bfa83a9eSThomas Graf * nla_validate() validate a stream of attributes 145bfa83a9eSThomas Graf * nla_find() find attribute in stream of attributes 146fe4944e5SThomas Graf * nla_find_nested() find attribute in nested attributes 147bfa83a9eSThomas Graf * nla_parse() parse and validate stream of attrs 148bfa83a9eSThomas Graf * nla_parse_nested() parse nested attribuets 149bfa83a9eSThomas Graf * nla_for_each_attr() loop over all attributes 150bfa83a9eSThomas Graf *========================================================================= 151bfa83a9eSThomas Graf */ 152bfa83a9eSThomas Graf 153bfa83a9eSThomas Graf /** 154bfa83a9eSThomas Graf * Standard attribute types to specify validation policy 155bfa83a9eSThomas Graf */ 156bfa83a9eSThomas Graf enum { 157bfa83a9eSThomas Graf NLA_UNSPEC, 158bfa83a9eSThomas Graf NLA_U8, 159bfa83a9eSThomas Graf NLA_U16, 160bfa83a9eSThomas Graf NLA_U32, 161bfa83a9eSThomas Graf NLA_U64, 162bfa83a9eSThomas Graf NLA_STRING, 163bfa83a9eSThomas Graf NLA_FLAG, 164bfa83a9eSThomas Graf NLA_MSECS, 165bfa83a9eSThomas Graf NLA_NESTED, 166bfa83a9eSThomas Graf __NLA_TYPE_MAX, 167bfa83a9eSThomas Graf }; 168bfa83a9eSThomas Graf 169bfa83a9eSThomas Graf #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) 170bfa83a9eSThomas Graf 171bfa83a9eSThomas Graf /** 172bfa83a9eSThomas Graf * struct nla_policy - attribute validation policy 173bfa83a9eSThomas Graf * @type: Type of attribute or NLA_UNSPEC 174bfa83a9eSThomas Graf * @minlen: Minimal length of payload required to be available 175bfa83a9eSThomas Graf * 176bfa83a9eSThomas Graf * Policies are defined as arrays of this struct, the array must be 177bfa83a9eSThomas Graf * accessible by attribute type up to the highest identifier to be expected. 178bfa83a9eSThomas Graf * 179bfa83a9eSThomas Graf * Example: 180bfa83a9eSThomas Graf * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = { 181bfa83a9eSThomas Graf * [ATTR_FOO] = { .type = NLA_U16 }, 182bfa83a9eSThomas Graf * [ATTR_BAR] = { .type = NLA_STRING }, 183bfa83a9eSThomas Graf * [ATTR_BAZ] = { .minlen = sizeof(struct mystruct) }, 184bfa83a9eSThomas Graf * }; 185bfa83a9eSThomas Graf */ 186bfa83a9eSThomas Graf struct nla_policy { 187bfa83a9eSThomas Graf u16 type; 188bfa83a9eSThomas Graf u16 minlen; 189bfa83a9eSThomas Graf }; 190bfa83a9eSThomas Graf 19182ace47aSThomas Graf extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, 19282ace47aSThomas Graf int (*cb)(struct sk_buff *, 19382ace47aSThomas Graf struct nlmsghdr *, int *)); 19482ace47aSThomas Graf extern void netlink_queue_skip(struct nlmsghdr *nlh, 19582ace47aSThomas Graf struct sk_buff *skb); 19682ace47aSThomas Graf 197bfa83a9eSThomas Graf extern int nla_validate(struct nlattr *head, int len, int maxtype, 198bfa83a9eSThomas Graf struct nla_policy *policy); 199bfa83a9eSThomas Graf extern int nla_parse(struct nlattr *tb[], int maxtype, 200bfa83a9eSThomas Graf struct nlattr *head, int len, 201bfa83a9eSThomas Graf struct nla_policy *policy); 202bfa83a9eSThomas Graf extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype); 203bfa83a9eSThomas Graf extern size_t nla_strlcpy(char *dst, const struct nlattr *nla, 204bfa83a9eSThomas Graf size_t dstsize); 205bfa83a9eSThomas Graf extern int nla_memcpy(void *dest, struct nlattr *src, int count); 206bfa83a9eSThomas Graf extern int nla_memcmp(const struct nlattr *nla, const void *data, 207bfa83a9eSThomas Graf size_t size); 208bfa83a9eSThomas Graf extern int nla_strcmp(const struct nlattr *nla, const char *str); 209bfa83a9eSThomas Graf extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype, 210bfa83a9eSThomas Graf int attrlen); 211fe4944e5SThomas Graf extern void * __nla_reserve_nohdr(struct sk_buff *skb, int attrlen); 212bfa83a9eSThomas Graf extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype, 213bfa83a9eSThomas Graf int attrlen); 214fe4944e5SThomas Graf extern void * nla_reserve_nohdr(struct sk_buff *skb, int attrlen); 215bfa83a9eSThomas Graf extern void __nla_put(struct sk_buff *skb, int attrtype, 216bfa83a9eSThomas Graf int attrlen, const void *data); 217fe4944e5SThomas Graf extern void __nla_put_nohdr(struct sk_buff *skb, int attrlen, 218fe4944e5SThomas Graf const void *data); 219bfa83a9eSThomas Graf extern int nla_put(struct sk_buff *skb, int attrtype, 220bfa83a9eSThomas Graf int attrlen, const void *data); 221fe4944e5SThomas Graf extern int nla_put_nohdr(struct sk_buff *skb, int attrlen, 222fe4944e5SThomas Graf const void *data); 223bfa83a9eSThomas Graf 224bfa83a9eSThomas Graf /************************************************************************** 225bfa83a9eSThomas Graf * Netlink Messages 226bfa83a9eSThomas Graf **************************************************************************/ 227bfa83a9eSThomas Graf 228bfa83a9eSThomas Graf /** 229bfa83a9eSThomas Graf * nlmsg_msg_size - length of netlink message not including padding 230bfa83a9eSThomas Graf * @payload: length of message payload 231bfa83a9eSThomas Graf */ 232bfa83a9eSThomas Graf static inline int nlmsg_msg_size(int payload) 233bfa83a9eSThomas Graf { 234bfa83a9eSThomas Graf return NLMSG_HDRLEN + payload; 235bfa83a9eSThomas Graf } 236bfa83a9eSThomas Graf 237bfa83a9eSThomas Graf /** 238bfa83a9eSThomas Graf * nlmsg_total_size - length of netlink message including padding 239bfa83a9eSThomas Graf * @payload: length of message payload 240bfa83a9eSThomas Graf */ 241bfa83a9eSThomas Graf static inline int nlmsg_total_size(int payload) 242bfa83a9eSThomas Graf { 243bfa83a9eSThomas Graf return NLMSG_ALIGN(nlmsg_msg_size(payload)); 244bfa83a9eSThomas Graf } 245bfa83a9eSThomas Graf 246bfa83a9eSThomas Graf /** 247bfa83a9eSThomas Graf * nlmsg_padlen - length of padding at the message's tail 248bfa83a9eSThomas Graf * @payload: length of message payload 249bfa83a9eSThomas Graf */ 250bfa83a9eSThomas Graf static inline int nlmsg_padlen(int payload) 251bfa83a9eSThomas Graf { 252bfa83a9eSThomas Graf return nlmsg_total_size(payload) - nlmsg_msg_size(payload); 253bfa83a9eSThomas Graf } 254bfa83a9eSThomas Graf 255bfa83a9eSThomas Graf /** 256bfa83a9eSThomas Graf * nlmsg_data - head of message payload 257bfa83a9eSThomas Graf * @nlh: netlink messsage header 258bfa83a9eSThomas Graf */ 259bfa83a9eSThomas Graf static inline void *nlmsg_data(const struct nlmsghdr *nlh) 260bfa83a9eSThomas Graf { 261bfa83a9eSThomas Graf return (unsigned char *) nlh + NLMSG_HDRLEN; 262bfa83a9eSThomas Graf } 263bfa83a9eSThomas Graf 264bfa83a9eSThomas Graf /** 265bfa83a9eSThomas Graf * nlmsg_len - length of message payload 266bfa83a9eSThomas Graf * @nlh: netlink message header 267bfa83a9eSThomas Graf */ 268bfa83a9eSThomas Graf static inline int nlmsg_len(const struct nlmsghdr *nlh) 269bfa83a9eSThomas Graf { 270bfa83a9eSThomas Graf return nlh->nlmsg_len - NLMSG_HDRLEN; 271bfa83a9eSThomas Graf } 272bfa83a9eSThomas Graf 273bfa83a9eSThomas Graf /** 274bfa83a9eSThomas Graf * nlmsg_attrdata - head of attributes data 275bfa83a9eSThomas Graf * @nlh: netlink message header 276bfa83a9eSThomas Graf * @hdrlen: length of family specific header 277bfa83a9eSThomas Graf */ 278bfa83a9eSThomas Graf static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh, 279bfa83a9eSThomas Graf int hdrlen) 280bfa83a9eSThomas Graf { 281bfa83a9eSThomas Graf unsigned char *data = nlmsg_data(nlh); 282bfa83a9eSThomas Graf return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen)); 283bfa83a9eSThomas Graf } 284bfa83a9eSThomas Graf 285bfa83a9eSThomas Graf /** 286bfa83a9eSThomas Graf * nlmsg_attrlen - length of attributes data 287bfa83a9eSThomas Graf * @nlh: netlink message header 288bfa83a9eSThomas Graf * @hdrlen: length of family specific header 289bfa83a9eSThomas Graf */ 290bfa83a9eSThomas Graf static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen) 291bfa83a9eSThomas Graf { 292bfa83a9eSThomas Graf return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen); 293bfa83a9eSThomas Graf } 294bfa83a9eSThomas Graf 295bfa83a9eSThomas Graf /** 296bfa83a9eSThomas Graf * nlmsg_ok - check if the netlink message fits into the remaining bytes 297bfa83a9eSThomas Graf * @nlh: netlink message header 298bfa83a9eSThomas Graf * @remaining: number of bytes remaining in message stream 299bfa83a9eSThomas Graf */ 300bfa83a9eSThomas Graf static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining) 301bfa83a9eSThomas Graf { 302bfa83a9eSThomas Graf return (remaining >= sizeof(struct nlmsghdr) && 303bfa83a9eSThomas Graf nlh->nlmsg_len >= sizeof(struct nlmsghdr) && 304bfa83a9eSThomas Graf nlh->nlmsg_len <= remaining); 305bfa83a9eSThomas Graf } 306bfa83a9eSThomas Graf 307bfa83a9eSThomas Graf /** 308bfa83a9eSThomas Graf * nlmsg_next - next netlink message in message stream 309bfa83a9eSThomas Graf * @nlh: netlink message header 310bfa83a9eSThomas Graf * @remaining: number of bytes remaining in message stream 311bfa83a9eSThomas Graf * 312bfa83a9eSThomas Graf * Returns the next netlink message in the message stream and 313bfa83a9eSThomas Graf * decrements remaining by the size of the current message. 314bfa83a9eSThomas Graf */ 315bfa83a9eSThomas Graf static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining) 316bfa83a9eSThomas Graf { 317bfa83a9eSThomas Graf int totlen = NLMSG_ALIGN(nlh->nlmsg_len); 318bfa83a9eSThomas Graf 319bfa83a9eSThomas Graf *remaining -= totlen; 320bfa83a9eSThomas Graf 321bfa83a9eSThomas Graf return (struct nlmsghdr *) ((unsigned char *) nlh + totlen); 322bfa83a9eSThomas Graf } 323bfa83a9eSThomas Graf 324bfa83a9eSThomas Graf /** 325bfa83a9eSThomas Graf * nlmsg_parse - parse attributes of a netlink message 326bfa83a9eSThomas Graf * @nlh: netlink message header 327bfa83a9eSThomas Graf * @hdrlen: length of family specific header 328bfa83a9eSThomas Graf * @tb: destination array with maxtype+1 elements 329bfa83a9eSThomas Graf * @maxtype: maximum attribute type to be expected 330bfa83a9eSThomas Graf * @policy: validation policy 331bfa83a9eSThomas Graf * 332bfa83a9eSThomas Graf * See nla_parse() 333bfa83a9eSThomas Graf */ 334bfa83a9eSThomas Graf static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, 335bfa83a9eSThomas Graf struct nlattr *tb[], int maxtype, 336bfa83a9eSThomas Graf struct nla_policy *policy) 337bfa83a9eSThomas Graf { 338bfa83a9eSThomas Graf if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 339bfa83a9eSThomas Graf return -EINVAL; 340bfa83a9eSThomas Graf 341bfa83a9eSThomas Graf return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen), 342bfa83a9eSThomas Graf nlmsg_attrlen(nlh, hdrlen), policy); 343bfa83a9eSThomas Graf } 344bfa83a9eSThomas Graf 345bfa83a9eSThomas Graf /** 346bfa83a9eSThomas Graf * nlmsg_find_attr - find a specific attribute in a netlink message 347bfa83a9eSThomas Graf * @nlh: netlink message header 348bfa83a9eSThomas Graf * @hdrlen: length of familiy specific header 349bfa83a9eSThomas Graf * @attrtype: type of attribute to look for 350bfa83a9eSThomas Graf * 351bfa83a9eSThomas Graf * Returns the first attribute which matches the specified type. 352bfa83a9eSThomas Graf */ 353bfa83a9eSThomas Graf static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, 354bfa83a9eSThomas Graf int hdrlen, int attrtype) 355bfa83a9eSThomas Graf { 356bfa83a9eSThomas Graf return nla_find(nlmsg_attrdata(nlh, hdrlen), 357bfa83a9eSThomas Graf nlmsg_attrlen(nlh, hdrlen), attrtype); 358bfa83a9eSThomas Graf } 359bfa83a9eSThomas Graf 360bfa83a9eSThomas Graf /** 361bfa83a9eSThomas Graf * nlmsg_validate - validate a netlink message including attributes 362bfa83a9eSThomas Graf * @nlh: netlinket message header 363bfa83a9eSThomas Graf * @hdrlen: length of familiy specific header 364bfa83a9eSThomas Graf * @maxtype: maximum attribute type to be expected 365bfa83a9eSThomas Graf * @policy: validation policy 366bfa83a9eSThomas Graf */ 367bfa83a9eSThomas Graf static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, 368bfa83a9eSThomas Graf struct nla_policy *policy) 369bfa83a9eSThomas Graf { 370bfa83a9eSThomas Graf if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 371bfa83a9eSThomas Graf return -EINVAL; 372bfa83a9eSThomas Graf 373bfa83a9eSThomas Graf return nla_validate(nlmsg_attrdata(nlh, hdrlen), 374bfa83a9eSThomas Graf nlmsg_attrlen(nlh, hdrlen), maxtype, policy); 375bfa83a9eSThomas Graf } 376bfa83a9eSThomas Graf 377bfa83a9eSThomas Graf /** 378bfa83a9eSThomas Graf * nlmsg_for_each_attr - iterate over a stream of attributes 379bfa83a9eSThomas Graf * @pos: loop counter, set to current attribute 380bfa83a9eSThomas Graf * @nlh: netlink message header 381bfa83a9eSThomas Graf * @hdrlen: length of familiy specific header 382bfa83a9eSThomas Graf * @rem: initialized to len, holds bytes currently remaining in stream 383bfa83a9eSThomas Graf */ 384bfa83a9eSThomas Graf #define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \ 385bfa83a9eSThomas Graf nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \ 386bfa83a9eSThomas Graf nlmsg_attrlen(nlh, hdrlen), rem) 387bfa83a9eSThomas Graf 388bfa83a9eSThomas Graf #if 0 389bfa83a9eSThomas Graf /* FIXME: Enable once all users have been converted */ 390bfa83a9eSThomas Graf 391bfa83a9eSThomas Graf /** 392bfa83a9eSThomas Graf * __nlmsg_put - Add a new netlink message to an skb 393bfa83a9eSThomas Graf * @skb: socket buffer to store message in 394bfa83a9eSThomas Graf * @pid: netlink process id 395bfa83a9eSThomas Graf * @seq: sequence number of message 396bfa83a9eSThomas Graf * @type: message type 397bfa83a9eSThomas Graf * @payload: length of message payload 398bfa83a9eSThomas Graf * @flags: message flags 399bfa83a9eSThomas Graf * 400bfa83a9eSThomas Graf * The caller is responsible to ensure that the skb provides enough 401bfa83a9eSThomas Graf * tailroom for both the netlink header and payload. 402bfa83a9eSThomas Graf */ 403bfa83a9eSThomas Graf static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid, 404bfa83a9eSThomas Graf u32 seq, int type, int payload, 405bfa83a9eSThomas Graf int flags) 406bfa83a9eSThomas Graf { 407bfa83a9eSThomas Graf struct nlmsghdr *nlh; 408bfa83a9eSThomas Graf 409bfa83a9eSThomas Graf nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload)); 410bfa83a9eSThomas Graf nlh->nlmsg_type = type; 411bfa83a9eSThomas Graf nlh->nlmsg_len = nlmsg_msg_size(payload); 412bfa83a9eSThomas Graf nlh->nlmsg_flags = flags; 413bfa83a9eSThomas Graf nlh->nlmsg_pid = pid; 414bfa83a9eSThomas Graf nlh->nlmsg_seq = seq; 415bfa83a9eSThomas Graf 416bfa83a9eSThomas Graf memset((unsigned char *) nlmsg_data(nlh) + payload, 0, 417bfa83a9eSThomas Graf nlmsg_padlen(payload)); 418bfa83a9eSThomas Graf 419bfa83a9eSThomas Graf return nlh; 420bfa83a9eSThomas Graf } 421bfa83a9eSThomas Graf #endif 422bfa83a9eSThomas Graf 423bfa83a9eSThomas Graf /** 424bfa83a9eSThomas Graf * nlmsg_put - Add a new netlink message to an skb 425bfa83a9eSThomas Graf * @skb: socket buffer to store message in 426bfa83a9eSThomas Graf * @pid: netlink process id 427bfa83a9eSThomas Graf * @seq: sequence number of message 428bfa83a9eSThomas Graf * @type: message type 429bfa83a9eSThomas Graf * @payload: length of message payload 430bfa83a9eSThomas Graf * @flags: message flags 431bfa83a9eSThomas Graf * 432bfa83a9eSThomas Graf * Returns NULL if the tailroom of the skb is insufficient to store 433bfa83a9eSThomas Graf * the message header and payload. 434bfa83a9eSThomas Graf */ 435bfa83a9eSThomas Graf static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, 436bfa83a9eSThomas Graf int type, int payload, int flags) 437bfa83a9eSThomas Graf { 438bfa83a9eSThomas Graf if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload))) 439bfa83a9eSThomas Graf return NULL; 440bfa83a9eSThomas Graf 441bfa83a9eSThomas Graf return __nlmsg_put(skb, pid, seq, type, payload, flags); 442bfa83a9eSThomas Graf } 443bfa83a9eSThomas Graf 444bfa83a9eSThomas Graf /** 445bfa83a9eSThomas Graf * nlmsg_put_answer - Add a new callback based netlink message to an skb 446bfa83a9eSThomas Graf * @skb: socket buffer to store message in 447bfa83a9eSThomas Graf * @cb: netlink callback 448bfa83a9eSThomas Graf * @type: message type 449bfa83a9eSThomas Graf * @payload: length of message payload 450bfa83a9eSThomas Graf * @flags: message flags 451bfa83a9eSThomas Graf * 452bfa83a9eSThomas Graf * Returns NULL if the tailroom of the skb is insufficient to store 453bfa83a9eSThomas Graf * the message header and payload. 454bfa83a9eSThomas Graf */ 455bfa83a9eSThomas Graf static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb, 456bfa83a9eSThomas Graf struct netlink_callback *cb, 457bfa83a9eSThomas Graf int type, int payload, 458bfa83a9eSThomas Graf int flags) 459bfa83a9eSThomas Graf { 460bfa83a9eSThomas Graf return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 461bfa83a9eSThomas Graf type, payload, flags); 462bfa83a9eSThomas Graf } 463bfa83a9eSThomas Graf 464bfa83a9eSThomas Graf /** 465bfa83a9eSThomas Graf * nlmsg_new - Allocate a new netlink message 466bfa83a9eSThomas Graf * @size: maximum size of message 467fe4944e5SThomas Graf * @flags: the type of memory to allocate. 468bfa83a9eSThomas Graf * 469bfa83a9eSThomas Graf * Use NLMSG_GOODSIZE if size isn't know and you need a good default size. 470bfa83a9eSThomas Graf */ 471fe4944e5SThomas Graf static inline struct sk_buff *nlmsg_new(int size, gfp_t flags) 472bfa83a9eSThomas Graf { 473fe4944e5SThomas Graf return alloc_skb(size, flags); 474bfa83a9eSThomas Graf } 475bfa83a9eSThomas Graf 476bfa83a9eSThomas Graf /** 477bfa83a9eSThomas Graf * nlmsg_end - Finalize a netlink message 478bfa83a9eSThomas Graf * @skb: socket buffer the message is stored in 479bfa83a9eSThomas Graf * @nlh: netlink message header 480bfa83a9eSThomas Graf * 481bfa83a9eSThomas Graf * Corrects the netlink message header to include the appeneded 482bfa83a9eSThomas Graf * attributes. Only necessary if attributes have been added to 483bfa83a9eSThomas Graf * the message. 484bfa83a9eSThomas Graf * 485bfa83a9eSThomas Graf * Returns the total data length of the skb. 486bfa83a9eSThomas Graf */ 487bfa83a9eSThomas Graf static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh) 488bfa83a9eSThomas Graf { 489bfa83a9eSThomas Graf nlh->nlmsg_len = skb->tail - (unsigned char *) nlh; 490bfa83a9eSThomas Graf 491bfa83a9eSThomas Graf return skb->len; 492bfa83a9eSThomas Graf } 493bfa83a9eSThomas Graf 494bfa83a9eSThomas Graf /** 495fe4944e5SThomas Graf * nlmsg_get_pos - return current position in netlink message 496fe4944e5SThomas Graf * @skb: socket buffer the message is stored in 497fe4944e5SThomas Graf * 498fe4944e5SThomas Graf * Returns a pointer to the current tail of the message. 499fe4944e5SThomas Graf */ 500fe4944e5SThomas Graf static inline void *nlmsg_get_pos(struct sk_buff *skb) 501fe4944e5SThomas Graf { 502fe4944e5SThomas Graf return skb->tail; 503fe4944e5SThomas Graf } 504fe4944e5SThomas Graf 505fe4944e5SThomas Graf /** 506fe4944e5SThomas Graf * nlmsg_trim - Trim message to a mark 507fe4944e5SThomas Graf * @skb: socket buffer the message is stored in 508fe4944e5SThomas Graf * @mark: mark to trim to 509fe4944e5SThomas Graf * 510fe4944e5SThomas Graf * Trims the message to the provided mark. Returns -1. 511fe4944e5SThomas Graf */ 512fe4944e5SThomas Graf static inline int nlmsg_trim(struct sk_buff *skb, void *mark) 513fe4944e5SThomas Graf { 514fe4944e5SThomas Graf if (mark) 515fe4944e5SThomas Graf skb_trim(skb, (unsigned char *) mark - skb->data); 516fe4944e5SThomas Graf 517fe4944e5SThomas Graf return -1; 518fe4944e5SThomas Graf } 519fe4944e5SThomas Graf 520fe4944e5SThomas Graf /** 521bfa83a9eSThomas Graf * nlmsg_cancel - Cancel construction of a netlink message 522bfa83a9eSThomas Graf * @skb: socket buffer the message is stored in 523bfa83a9eSThomas Graf * @nlh: netlink message header 524bfa83a9eSThomas Graf * 525bfa83a9eSThomas Graf * Removes the complete netlink message including all 526bfa83a9eSThomas Graf * attributes from the socket buffer again. Returns -1. 527bfa83a9eSThomas Graf */ 528bfa83a9eSThomas Graf static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh) 529bfa83a9eSThomas Graf { 530fe4944e5SThomas Graf return nlmsg_trim(skb, nlh); 531bfa83a9eSThomas Graf } 532bfa83a9eSThomas Graf 533bfa83a9eSThomas Graf /** 534bfa83a9eSThomas Graf * nlmsg_free - free a netlink message 535bfa83a9eSThomas Graf * @skb: socket buffer of netlink message 536bfa83a9eSThomas Graf */ 537bfa83a9eSThomas Graf static inline void nlmsg_free(struct sk_buff *skb) 538bfa83a9eSThomas Graf { 539bfa83a9eSThomas Graf kfree_skb(skb); 540bfa83a9eSThomas Graf } 541bfa83a9eSThomas Graf 542bfa83a9eSThomas Graf /** 543bfa83a9eSThomas Graf * nlmsg_multicast - multicast a netlink message 544bfa83a9eSThomas Graf * @sk: netlink socket to spread messages to 545bfa83a9eSThomas Graf * @skb: netlink message as socket buffer 546bfa83a9eSThomas Graf * @pid: own netlink pid to avoid sending to yourself 547bfa83a9eSThomas Graf * @group: multicast group id 548bfa83a9eSThomas Graf */ 549bfa83a9eSThomas Graf static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb, 550bfa83a9eSThomas Graf u32 pid, unsigned int group) 551bfa83a9eSThomas Graf { 552bfa83a9eSThomas Graf int err; 553bfa83a9eSThomas Graf 554bfa83a9eSThomas Graf NETLINK_CB(skb).dst_group = group; 555bfa83a9eSThomas Graf 556bfa83a9eSThomas Graf err = netlink_broadcast(sk, skb, pid, group, GFP_KERNEL); 557bfa83a9eSThomas Graf if (err > 0) 558bfa83a9eSThomas Graf err = 0; 559bfa83a9eSThomas Graf 560bfa83a9eSThomas Graf return err; 561bfa83a9eSThomas Graf } 562bfa83a9eSThomas Graf 563bfa83a9eSThomas Graf /** 564bfa83a9eSThomas Graf * nlmsg_unicast - unicast a netlink message 565bfa83a9eSThomas Graf * @sk: netlink socket to spread message to 566bfa83a9eSThomas Graf * @skb: netlink message as socket buffer 567bfa83a9eSThomas Graf * @pid: netlink pid of the destination socket 568bfa83a9eSThomas Graf */ 569bfa83a9eSThomas Graf static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid) 570bfa83a9eSThomas Graf { 571bfa83a9eSThomas Graf int err; 572bfa83a9eSThomas Graf 573bfa83a9eSThomas Graf err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT); 574bfa83a9eSThomas Graf if (err > 0) 575bfa83a9eSThomas Graf err = 0; 576bfa83a9eSThomas Graf 577bfa83a9eSThomas Graf return err; 578bfa83a9eSThomas Graf } 579bfa83a9eSThomas Graf 580bfa83a9eSThomas Graf /** 581bfa83a9eSThomas Graf * nlmsg_for_each_msg - iterate over a stream of messages 582bfa83a9eSThomas Graf * @pos: loop counter, set to current message 583bfa83a9eSThomas Graf * @head: head of message stream 584bfa83a9eSThomas Graf * @len: length of message stream 585bfa83a9eSThomas Graf * @rem: initialized to len, holds bytes currently remaining in stream 586bfa83a9eSThomas Graf */ 587bfa83a9eSThomas Graf #define nlmsg_for_each_msg(pos, head, len, rem) \ 588bfa83a9eSThomas Graf for (pos = head, rem = len; \ 589bfa83a9eSThomas Graf nlmsg_ok(pos, rem); \ 590bfa83a9eSThomas Graf pos = nlmsg_next(pos, &(rem))) 591bfa83a9eSThomas Graf 592bfa83a9eSThomas Graf /************************************************************************** 593bfa83a9eSThomas Graf * Netlink Attributes 594bfa83a9eSThomas Graf **************************************************************************/ 595bfa83a9eSThomas Graf 596bfa83a9eSThomas Graf /** 597bfa83a9eSThomas Graf * nla_attr_size - length of attribute not including padding 598bfa83a9eSThomas Graf * @payload: length of payload 599bfa83a9eSThomas Graf */ 600bfa83a9eSThomas Graf static inline int nla_attr_size(int payload) 601bfa83a9eSThomas Graf { 602bfa83a9eSThomas Graf return NLA_HDRLEN + payload; 603bfa83a9eSThomas Graf } 604bfa83a9eSThomas Graf 605bfa83a9eSThomas Graf /** 606bfa83a9eSThomas Graf * nla_total_size - total length of attribute including padding 607bfa83a9eSThomas Graf * @payload: length of payload 608bfa83a9eSThomas Graf */ 609bfa83a9eSThomas Graf static inline int nla_total_size(int payload) 610bfa83a9eSThomas Graf { 611bfa83a9eSThomas Graf return NLA_ALIGN(nla_attr_size(payload)); 612bfa83a9eSThomas Graf } 613bfa83a9eSThomas Graf 614bfa83a9eSThomas Graf /** 615bfa83a9eSThomas Graf * nla_padlen - length of padding at the tail of attribute 616bfa83a9eSThomas Graf * @payload: length of payload 617bfa83a9eSThomas Graf */ 618bfa83a9eSThomas Graf static inline int nla_padlen(int payload) 619bfa83a9eSThomas Graf { 620bfa83a9eSThomas Graf return nla_total_size(payload) - nla_attr_size(payload); 621bfa83a9eSThomas Graf } 622bfa83a9eSThomas Graf 623bfa83a9eSThomas Graf /** 624bfa83a9eSThomas Graf * nla_data - head of payload 625bfa83a9eSThomas Graf * @nla: netlink attribute 626bfa83a9eSThomas Graf */ 627bfa83a9eSThomas Graf static inline void *nla_data(const struct nlattr *nla) 628bfa83a9eSThomas Graf { 629bfa83a9eSThomas Graf return (char *) nla + NLA_HDRLEN; 630bfa83a9eSThomas Graf } 631bfa83a9eSThomas Graf 632bfa83a9eSThomas Graf /** 633bfa83a9eSThomas Graf * nla_len - length of payload 634bfa83a9eSThomas Graf * @nla: netlink attribute 635bfa83a9eSThomas Graf */ 636bfa83a9eSThomas Graf static inline int nla_len(const struct nlattr *nla) 637bfa83a9eSThomas Graf { 638bfa83a9eSThomas Graf return nla->nla_len - NLA_HDRLEN; 639bfa83a9eSThomas Graf } 640bfa83a9eSThomas Graf 641bfa83a9eSThomas Graf /** 642bfa83a9eSThomas Graf * nla_ok - check if the netlink attribute fits into the remaining bytes 643bfa83a9eSThomas Graf * @nla: netlink attribute 644bfa83a9eSThomas Graf * @remaining: number of bytes remaining in attribute stream 645bfa83a9eSThomas Graf */ 646bfa83a9eSThomas Graf static inline int nla_ok(const struct nlattr *nla, int remaining) 647bfa83a9eSThomas Graf { 648bfa83a9eSThomas Graf return remaining >= sizeof(*nla) && 649bfa83a9eSThomas Graf nla->nla_len >= sizeof(*nla) && 650bfa83a9eSThomas Graf nla->nla_len <= remaining; 651bfa83a9eSThomas Graf } 652bfa83a9eSThomas Graf 653bfa83a9eSThomas Graf /** 654bfa83a9eSThomas Graf * nla_next - next netlink attribte in attribute stream 655bfa83a9eSThomas Graf * @nla: netlink attribute 656bfa83a9eSThomas Graf * @remaining: number of bytes remaining in attribute stream 657bfa83a9eSThomas Graf * 658bfa83a9eSThomas Graf * Returns the next netlink attribute in the attribute stream and 659bfa83a9eSThomas Graf * decrements remaining by the size of the current attribute. 660bfa83a9eSThomas Graf */ 661bfa83a9eSThomas Graf static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining) 662bfa83a9eSThomas Graf { 663bfa83a9eSThomas Graf int totlen = NLA_ALIGN(nla->nla_len); 664bfa83a9eSThomas Graf 665bfa83a9eSThomas Graf *remaining -= totlen; 666bfa83a9eSThomas Graf return (struct nlattr *) ((char *) nla + totlen); 667bfa83a9eSThomas Graf } 668bfa83a9eSThomas Graf 669bfa83a9eSThomas Graf /** 670fe4944e5SThomas Graf * nla_find_nested - find attribute in a set of nested attributes 671fe4944e5SThomas Graf * @nla: attribute containing the nested attributes 672fe4944e5SThomas Graf * @attrtype: type of attribute to look for 673fe4944e5SThomas Graf * 674fe4944e5SThomas Graf * Returns the first attribute which matches the specified type. 675fe4944e5SThomas Graf */ 676fe4944e5SThomas Graf static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype) 677fe4944e5SThomas Graf { 678fe4944e5SThomas Graf return nla_find(nla_data(nla), nla_len(nla), attrtype); 679fe4944e5SThomas Graf } 680fe4944e5SThomas Graf 681fe4944e5SThomas Graf /** 682bfa83a9eSThomas Graf * nla_parse_nested - parse nested attributes 683bfa83a9eSThomas Graf * @tb: destination array with maxtype+1 elements 684bfa83a9eSThomas Graf * @maxtype: maximum attribute type to be expected 685bfa83a9eSThomas Graf * @nla: attribute containing the nested attributes 686bfa83a9eSThomas Graf * @policy: validation policy 687bfa83a9eSThomas Graf * 688bfa83a9eSThomas Graf * See nla_parse() 689bfa83a9eSThomas Graf */ 690bfa83a9eSThomas Graf static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, 691bfa83a9eSThomas Graf struct nlattr *nla, 692bfa83a9eSThomas Graf struct nla_policy *policy) 693bfa83a9eSThomas Graf { 694bfa83a9eSThomas Graf return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); 695bfa83a9eSThomas Graf } 696bfa83a9eSThomas Graf /** 697bfa83a9eSThomas Graf * nla_put_u8 - Add a u16 netlink attribute to a socket buffer 698bfa83a9eSThomas Graf * @skb: socket buffer to add attribute to 699bfa83a9eSThomas Graf * @attrtype: attribute type 700bfa83a9eSThomas Graf * @value: numeric value 701bfa83a9eSThomas Graf */ 702bfa83a9eSThomas Graf static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value) 703bfa83a9eSThomas Graf { 704bfa83a9eSThomas Graf return nla_put(skb, attrtype, sizeof(u8), &value); 705bfa83a9eSThomas Graf } 706bfa83a9eSThomas Graf 707bfa83a9eSThomas Graf /** 708bfa83a9eSThomas Graf * nla_put_u16 - Add a u16 netlink attribute to a socket buffer 709bfa83a9eSThomas Graf * @skb: socket buffer to add attribute to 710bfa83a9eSThomas Graf * @attrtype: attribute type 711bfa83a9eSThomas Graf * @value: numeric value 712bfa83a9eSThomas Graf */ 713bfa83a9eSThomas Graf static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value) 714bfa83a9eSThomas Graf { 715bfa83a9eSThomas Graf return nla_put(skb, attrtype, sizeof(u16), &value); 716bfa83a9eSThomas Graf } 717bfa83a9eSThomas Graf 718bfa83a9eSThomas Graf /** 719bfa83a9eSThomas Graf * nla_put_u32 - Add a u32 netlink attribute to a socket buffer 720bfa83a9eSThomas Graf * @skb: socket buffer to add attribute to 721bfa83a9eSThomas Graf * @attrtype: attribute type 722bfa83a9eSThomas Graf * @value: numeric value 723bfa83a9eSThomas Graf */ 724bfa83a9eSThomas Graf static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value) 725bfa83a9eSThomas Graf { 726bfa83a9eSThomas Graf return nla_put(skb, attrtype, sizeof(u32), &value); 727bfa83a9eSThomas Graf } 728bfa83a9eSThomas Graf 729bfa83a9eSThomas Graf /** 730bfa83a9eSThomas Graf * nla_put_64 - Add a u64 netlink attribute to a socket buffer 731bfa83a9eSThomas Graf * @skb: socket buffer to add attribute to 732bfa83a9eSThomas Graf * @attrtype: attribute type 733bfa83a9eSThomas Graf * @value: numeric value 734bfa83a9eSThomas Graf */ 735bfa83a9eSThomas Graf static inline int nla_put_u64(struct sk_buff *skb, int attrtype, u64 value) 736bfa83a9eSThomas Graf { 737bfa83a9eSThomas Graf return nla_put(skb, attrtype, sizeof(u64), &value); 738bfa83a9eSThomas Graf } 739bfa83a9eSThomas Graf 740bfa83a9eSThomas Graf /** 741bfa83a9eSThomas Graf * nla_put_string - Add a string netlink attribute to a socket buffer 742bfa83a9eSThomas Graf * @skb: socket buffer to add attribute to 743bfa83a9eSThomas Graf * @attrtype: attribute type 744bfa83a9eSThomas Graf * @str: NUL terminated string 745bfa83a9eSThomas Graf */ 746bfa83a9eSThomas Graf static inline int nla_put_string(struct sk_buff *skb, int attrtype, 747bfa83a9eSThomas Graf const char *str) 748bfa83a9eSThomas Graf { 749bfa83a9eSThomas Graf return nla_put(skb, attrtype, strlen(str) + 1, str); 750bfa83a9eSThomas Graf } 751bfa83a9eSThomas Graf 752bfa83a9eSThomas Graf /** 753bfa83a9eSThomas Graf * nla_put_flag - Add a flag netlink attribute to a socket buffer 754bfa83a9eSThomas Graf * @skb: socket buffer to add attribute to 755bfa83a9eSThomas Graf * @attrtype: attribute type 756bfa83a9eSThomas Graf */ 757bfa83a9eSThomas Graf static inline int nla_put_flag(struct sk_buff *skb, int attrtype) 758bfa83a9eSThomas Graf { 759bfa83a9eSThomas Graf return nla_put(skb, attrtype, 0, NULL); 760bfa83a9eSThomas Graf } 761bfa83a9eSThomas Graf 762bfa83a9eSThomas Graf /** 763bfa83a9eSThomas Graf * nla_put_msecs - Add a msecs netlink attribute to a socket buffer 764bfa83a9eSThomas Graf * @skb: socket buffer to add attribute to 765bfa83a9eSThomas Graf * @attrtype: attribute type 766bfa83a9eSThomas Graf * @jiffies: number of msecs in jiffies 767bfa83a9eSThomas Graf */ 768bfa83a9eSThomas Graf static inline int nla_put_msecs(struct sk_buff *skb, int attrtype, 769bfa83a9eSThomas Graf unsigned long jiffies) 770bfa83a9eSThomas Graf { 771bfa83a9eSThomas Graf u64 tmp = jiffies_to_msecs(jiffies); 772bfa83a9eSThomas Graf return nla_put(skb, attrtype, sizeof(u64), &tmp); 773bfa83a9eSThomas Graf } 774bfa83a9eSThomas Graf 775bfa83a9eSThomas Graf #define NLA_PUT(skb, attrtype, attrlen, data) \ 776bfa83a9eSThomas Graf do { \ 777bfa83a9eSThomas Graf if (nla_put(skb, attrtype, attrlen, data) < 0) \ 778bfa83a9eSThomas Graf goto nla_put_failure; \ 779bfa83a9eSThomas Graf } while(0) 780bfa83a9eSThomas Graf 781bfa83a9eSThomas Graf #define NLA_PUT_TYPE(skb, type, attrtype, value) \ 782bfa83a9eSThomas Graf do { \ 783bfa83a9eSThomas Graf type __tmp = value; \ 784bfa83a9eSThomas Graf NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ 785bfa83a9eSThomas Graf } while(0) 786bfa83a9eSThomas Graf 787bfa83a9eSThomas Graf #define NLA_PUT_U8(skb, attrtype, value) \ 788bfa83a9eSThomas Graf NLA_PUT_TYPE(skb, u8, attrtype, value) 789bfa83a9eSThomas Graf 790bfa83a9eSThomas Graf #define NLA_PUT_U16(skb, attrtype, value) \ 791bfa83a9eSThomas Graf NLA_PUT_TYPE(skb, u16, attrtype, value) 792bfa83a9eSThomas Graf 793bfa83a9eSThomas Graf #define NLA_PUT_U32(skb, attrtype, value) \ 794bfa83a9eSThomas Graf NLA_PUT_TYPE(skb, u32, attrtype, value) 795bfa83a9eSThomas Graf 796bfa83a9eSThomas Graf #define NLA_PUT_U64(skb, attrtype, value) \ 797bfa83a9eSThomas Graf NLA_PUT_TYPE(skb, u64, attrtype, value) 798bfa83a9eSThomas Graf 799bfa83a9eSThomas Graf #define NLA_PUT_STRING(skb, attrtype, value) \ 800bfa83a9eSThomas Graf NLA_PUT(skb, attrtype, strlen(value) + 1, value) 801bfa83a9eSThomas Graf 802bfa83a9eSThomas Graf #define NLA_PUT_FLAG(skb, attrtype, value) \ 803bfa83a9eSThomas Graf NLA_PUT(skb, attrtype, 0, NULL) 804bfa83a9eSThomas Graf 805bfa83a9eSThomas Graf #define NLA_PUT_MSECS(skb, attrtype, jiffies) \ 806bfa83a9eSThomas Graf NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies)) 807bfa83a9eSThomas Graf 808bfa83a9eSThomas Graf /** 809bfa83a9eSThomas Graf * nla_get_u32 - return payload of u32 attribute 810bfa83a9eSThomas Graf * @nla: u32 netlink attribute 811bfa83a9eSThomas Graf */ 812bfa83a9eSThomas Graf static inline u32 nla_get_u32(struct nlattr *nla) 813bfa83a9eSThomas Graf { 814bfa83a9eSThomas Graf return *(u32 *) nla_data(nla); 815bfa83a9eSThomas Graf } 816bfa83a9eSThomas Graf 817bfa83a9eSThomas Graf /** 818bfa83a9eSThomas Graf * nla_get_u16 - return payload of u16 attribute 819bfa83a9eSThomas Graf * @nla: u16 netlink attribute 820bfa83a9eSThomas Graf */ 821bfa83a9eSThomas Graf static inline u16 nla_get_u16(struct nlattr *nla) 822bfa83a9eSThomas Graf { 823bfa83a9eSThomas Graf return *(u16 *) nla_data(nla); 824bfa83a9eSThomas Graf } 825bfa83a9eSThomas Graf 826bfa83a9eSThomas Graf /** 827bfa83a9eSThomas Graf * nla_get_u8 - return payload of u8 attribute 828bfa83a9eSThomas Graf * @nla: u8 netlink attribute 829bfa83a9eSThomas Graf */ 830bfa83a9eSThomas Graf static inline u8 nla_get_u8(struct nlattr *nla) 831bfa83a9eSThomas Graf { 832bfa83a9eSThomas Graf return *(u8 *) nla_data(nla); 833bfa83a9eSThomas Graf } 834bfa83a9eSThomas Graf 835bfa83a9eSThomas Graf /** 836bfa83a9eSThomas Graf * nla_get_u64 - return payload of u64 attribute 837bfa83a9eSThomas Graf * @nla: u64 netlink attribute 838bfa83a9eSThomas Graf */ 839bfa83a9eSThomas Graf static inline u64 nla_get_u64(struct nlattr *nla) 840bfa83a9eSThomas Graf { 841bfa83a9eSThomas Graf u64 tmp; 842bfa83a9eSThomas Graf 843bfa83a9eSThomas Graf nla_memcpy(&tmp, nla, sizeof(tmp)); 844bfa83a9eSThomas Graf 845bfa83a9eSThomas Graf return tmp; 846bfa83a9eSThomas Graf } 847bfa83a9eSThomas Graf 848bfa83a9eSThomas Graf /** 849bfa83a9eSThomas Graf * nla_get_flag - return payload of flag attribute 850bfa83a9eSThomas Graf * @nla: flag netlink attribute 851bfa83a9eSThomas Graf */ 852bfa83a9eSThomas Graf static inline int nla_get_flag(struct nlattr *nla) 853bfa83a9eSThomas Graf { 854bfa83a9eSThomas Graf return !!nla; 855bfa83a9eSThomas Graf } 856bfa83a9eSThomas Graf 857bfa83a9eSThomas Graf /** 858bfa83a9eSThomas Graf * nla_get_msecs - return payload of msecs attribute 859bfa83a9eSThomas Graf * @nla: msecs netlink attribute 860bfa83a9eSThomas Graf * 861bfa83a9eSThomas Graf * Returns the number of milliseconds in jiffies. 862bfa83a9eSThomas Graf */ 863bfa83a9eSThomas Graf static inline unsigned long nla_get_msecs(struct nlattr *nla) 864bfa83a9eSThomas Graf { 865bfa83a9eSThomas Graf u64 msecs = nla_get_u64(nla); 866bfa83a9eSThomas Graf 867bfa83a9eSThomas Graf return msecs_to_jiffies((unsigned long) msecs); 868bfa83a9eSThomas Graf } 869bfa83a9eSThomas Graf 870bfa83a9eSThomas Graf /** 871bfa83a9eSThomas Graf * nla_nest_start - Start a new level of nested attributes 872bfa83a9eSThomas Graf * @skb: socket buffer to add attributes to 873bfa83a9eSThomas Graf * @attrtype: attribute type of container 874bfa83a9eSThomas Graf * 875bfa83a9eSThomas Graf * Returns the container attribute 876bfa83a9eSThomas Graf */ 877bfa83a9eSThomas Graf static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype) 878bfa83a9eSThomas Graf { 879bfa83a9eSThomas Graf struct nlattr *start = (struct nlattr *) skb->tail; 880bfa83a9eSThomas Graf 881bfa83a9eSThomas Graf if (nla_put(skb, attrtype, 0, NULL) < 0) 882bfa83a9eSThomas Graf return NULL; 883bfa83a9eSThomas Graf 884bfa83a9eSThomas Graf return start; 885bfa83a9eSThomas Graf } 886bfa83a9eSThomas Graf 887bfa83a9eSThomas Graf /** 888bfa83a9eSThomas Graf * nla_nest_end - Finalize nesting of attributes 889bfa83a9eSThomas Graf * @skb: socket buffer the attribtues are stored in 890bfa83a9eSThomas Graf * @start: container attribute 891bfa83a9eSThomas Graf * 892bfa83a9eSThomas Graf * Corrects the container attribute header to include the all 893bfa83a9eSThomas Graf * appeneded attributes. 894bfa83a9eSThomas Graf * 895bfa83a9eSThomas Graf * Returns the total data length of the skb. 896bfa83a9eSThomas Graf */ 897bfa83a9eSThomas Graf static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start) 898bfa83a9eSThomas Graf { 899bfa83a9eSThomas Graf start->nla_len = skb->tail - (unsigned char *) start; 900bfa83a9eSThomas Graf return skb->len; 901bfa83a9eSThomas Graf } 902bfa83a9eSThomas Graf 903bfa83a9eSThomas Graf /** 904bfa83a9eSThomas Graf * nla_nest_cancel - Cancel nesting of attributes 905bfa83a9eSThomas Graf * @skb: socket buffer the message is stored in 906bfa83a9eSThomas Graf * @start: container attribute 907bfa83a9eSThomas Graf * 908bfa83a9eSThomas Graf * Removes the container attribute and including all nested 909bfa83a9eSThomas Graf * attributes. Returns -1. 910bfa83a9eSThomas Graf */ 911bfa83a9eSThomas Graf static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) 912bfa83a9eSThomas Graf { 913fe4944e5SThomas Graf return nlmsg_trim(skb, start); 914bfa83a9eSThomas Graf } 915bfa83a9eSThomas Graf 916bfa83a9eSThomas Graf /** 917bfa83a9eSThomas Graf * nla_for_each_attr - iterate over a stream of attributes 918bfa83a9eSThomas Graf * @pos: loop counter, set to current attribute 919bfa83a9eSThomas Graf * @head: head of attribute stream 920bfa83a9eSThomas Graf * @len: length of attribute stream 921bfa83a9eSThomas Graf * @rem: initialized to len, holds bytes currently remaining in stream 922bfa83a9eSThomas Graf */ 923bfa83a9eSThomas Graf #define nla_for_each_attr(pos, head, len, rem) \ 924bfa83a9eSThomas Graf for (pos = head, rem = len; \ 925bfa83a9eSThomas Graf nla_ok(pos, rem); \ 926bfa83a9eSThomas Graf pos = nla_next(pos, &(rem))) 927bfa83a9eSThomas Graf 928fe4944e5SThomas Graf /** 929fe4944e5SThomas Graf * nla_for_each_nested - iterate over nested attributes 930fe4944e5SThomas Graf * @pos: loop counter, set to current attribute 931fe4944e5SThomas Graf * @nla: attribute containing the nested attributes 932fe4944e5SThomas Graf * @rem: initialized to len, holds bytes currently remaining in stream 933fe4944e5SThomas Graf */ 934fe4944e5SThomas Graf #define nla_for_each_nested(pos, nla, rem) \ 935fe4944e5SThomas Graf nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem) 936fe4944e5SThomas Graf 937bfa83a9eSThomas Graf #endif 938