📄 netlink.h
字号:
return -EINVAL; return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen), policy);}/** * nlmsg_find_attr - find a specific attribute in a netlink message * @nlh: netlink message header * @hdrlen: length of familiy specific header * @attrtype: type of attribute to look for * * Returns the first attribute which matches the specified type. */static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, int hdrlen, int attrtype){ return nla_find(nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen), attrtype);}/** * nlmsg_validate - validate a netlink message including attributes * @nlh: netlinket message header * @hdrlen: length of familiy specific header * @maxtype: maximum attribute type to be expected * @policy: validation policy */static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, const struct nla_policy *policy){ if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) return -EINVAL; return nla_validate(nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen), maxtype, policy);}/** * nlmsg_report - need to report back to application? * @nlh: netlink message header * * Returns 1 if a report back to the application is requested. */static inline int nlmsg_report(struct nlmsghdr *nlh){ return !!(nlh->nlmsg_flags & NLM_F_ECHO);}/** * nlmsg_for_each_attr - iterate over a stream of attributes * @pos: loop counter, set to current attribute * @nlh: netlink message header * @hdrlen: length of familiy specific header * @rem: initialized to len, holds bytes currently remaining in stream */#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \ nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \ nlmsg_attrlen(nlh, hdrlen), rem)#if 0/* FIXME: Enable once all users have been converted *//** * __nlmsg_put - Add a new netlink message to an skb * @skb: socket buffer to store message in * @pid: netlink process id * @seq: sequence number of message * @type: message type * @payload: length of message payload * @flags: message flags * * The caller is responsible to ensure that the skb provides enough * tailroom for both the netlink header and payload. */static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int payload, int flags){ struct nlmsghdr *nlh; nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload)); nlh->nlmsg_type = type; nlh->nlmsg_len = nlmsg_msg_size(payload); nlh->nlmsg_flags = flags; nlh->nlmsg_pid = pid; nlh->nlmsg_seq = seq; memset((unsigned char *) nlmsg_data(nlh) + payload, 0, nlmsg_padlen(payload)); return nlh;}#endif/** * nlmsg_put - Add a new netlink message to an skb * @skb: socket buffer to store message in * @pid: netlink process id * @seq: sequence number of message * @type: message type * @payload: length of message payload * @flags: message flags * * Returns NULL if the tailroom of the skb is insufficient to store * the message header and payload. */static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int payload, int flags){ if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload))) return NULL; return __nlmsg_put(skb, pid, seq, type, payload, flags);}/** * nlmsg_put_answer - Add a new callback based netlink message to an skb * @skb: socket buffer to store message in * @cb: netlink callback * @type: message type * @payload: length of message payload * @flags: message flags * * Returns NULL if the tailroom of the skb is insufficient to store * the message header and payload. */static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb, struct netlink_callback *cb, int type, int payload, int flags){ return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, type, payload, flags);}/** * nlmsg_new - Allocate a new netlink message * @payload: size of the message payload * @flags: the type of memory to allocate. * * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known * and a good default is needed. */static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags){ return alloc_skb(nlmsg_total_size(payload), flags);}/** * nlmsg_end - Finalize a netlink message * @skb: socket buffer the message is stored in * @nlh: netlink message header * * Corrects the netlink message header to include the appeneded * attributes. Only necessary if attributes have been added to * the message. * * Returns the total data length of the skb. */static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh){ nlh->nlmsg_len = skb_tail_pointer(skb) - (unsigned char *)nlh; return skb->len;}/** * nlmsg_get_pos - return current position in netlink message * @skb: socket buffer the message is stored in * * Returns a pointer to the current tail of the message. */static inline void *nlmsg_get_pos(struct sk_buff *skb){ return skb_tail_pointer(skb);}/** * nlmsg_trim - Trim message to a mark * @skb: socket buffer the message is stored in * @mark: mark to trim to * * Trims the message to the provided mark. Returns -1. */static inline int nlmsg_trim(struct sk_buff *skb, const void *mark){ if (mark) skb_trim(skb, (unsigned char *) mark - skb->data); return -1;}/** * nlmsg_cancel - Cancel construction of a netlink message * @skb: socket buffer the message is stored in * @nlh: netlink message header * * Removes the complete netlink message including all * attributes from the socket buffer again. Returns -1. */static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh){ return nlmsg_trim(skb, nlh);}/** * nlmsg_free - free a netlink message * @skb: socket buffer of netlink message */static inline void nlmsg_free(struct sk_buff *skb){ kfree_skb(skb);}/** * nlmsg_multicast - multicast a netlink message * @sk: netlink socket to spread messages to * @skb: netlink message as socket buffer * @pid: own netlink pid to avoid sending to yourself * @group: multicast group id * @flags: allocation flags */static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb, u32 pid, unsigned int group, gfp_t flags){ int err; NETLINK_CB(skb).dst_group = group; err = netlink_broadcast(sk, skb, pid, group, flags); if (err > 0) err = 0; return err;}/** * nlmsg_unicast - unicast a netlink message * @sk: netlink socket to spread message to * @skb: netlink message as socket buffer * @pid: netlink pid of the destination socket */static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid){ int err; err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT); if (err > 0) err = 0; return err;}/** * nlmsg_for_each_msg - iterate over a stream of messages * @pos: loop counter, set to current message * @head: head of message stream * @len: length of message stream * @rem: initialized to len, holds bytes currently remaining in stream */#define nlmsg_for_each_msg(pos, head, len, rem) \ for (pos = head, rem = len; \ nlmsg_ok(pos, rem); \ pos = nlmsg_next(pos, &(rem)))/************************************************************************** * Netlink Attributes **************************************************************************//** * nla_attr_size - length of attribute not including padding * @payload: length of payload */static inline int nla_attr_size(int payload){ return NLA_HDRLEN + payload;}/** * nla_total_size - total length of attribute including padding * @payload: length of payload */static inline int nla_total_size(int payload){ return NLA_ALIGN(nla_attr_size(payload));}/** * nla_padlen - length of padding at the tail of attribute * @payload: length of payload */static inline int nla_padlen(int payload){ return nla_total_size(payload) - nla_attr_size(payload);}/** * nla_type - attribute type * @nla: netlink attribute */static inline int nla_type(const struct nlattr *nla){ return nla->nla_type & NLA_TYPE_MASK;}/** * nla_data - head of payload * @nla: netlink attribute */static inline void *nla_data(const struct nlattr *nla){ return (char *) nla + NLA_HDRLEN;}/** * nla_len - length of payload * @nla: netlink attribute */static inline int nla_len(const struct nlattr *nla){ return nla->nla_len - NLA_HDRLEN;}/** * nla_ok - check if the netlink attribute fits into the remaining bytes * @nla: netlink attribute * @remaining: number of bytes remaining in attribute stream */static inline int nla_ok(const struct nlattr *nla, int remaining){ return remaining >= sizeof(*nla) && nla->nla_len >= sizeof(*nla) && nla->nla_len <= remaining;}/** * nla_next - next netlink attribute in attribute stream * @nla: netlink attribute * @remaining: number of bytes remaining in attribute stream * * Returns the next netlink attribute in the attribute stream and * decrements remaining by the size of the current attribute. */static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining){ int totlen = NLA_ALIGN(nla->nla_len); *remaining -= totlen; return (struct nlattr *) ((char *) nla + totlen);}/** * nla_find_nested - find attribute in a set of nested attributes * @nla: attribute containing the nested attributes * @attrtype: type of attribute to look for * * Returns the first attribute which matches the specified type. */static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype){ return nla_find(nla_data(nla), nla_len(nla), attrtype);}/** * nla_parse_nested - parse nested attributes * @tb: destination array with maxtype+1 elements * @maxtype: maximum attribute type to be expected * @nla: attribute containing the nested attributes * @policy: validation policy *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -