/** * struct nla_policy - attribute validation policy * @type: Type of attribute or NLA_UNSPEC * @validation_type: type of attribute validation done in addition to * type-specific validation (e.g. range, function call), see * &enum nla_policy_validation * @len: Type specific length of payload * * Policies are defined as arrays of this struct, the array must be * accessible by attribute type up to the highest identifier to be expected. * * Meaning of `len' field: * NLA_STRING Maximum length of string * NLA_NUL_STRING Maximum length of string (excluding NUL) * NLA_FLAG Unused * NLA_BINARY Maximum length of attribute payload * (but see also below with the validation type) * NLA_NESTED, * NLA_NESTED_ARRAY Length verification is done by checking len of * nested header (or empty); len field is used if * nested_policy is also used, for the max attr * number in the nested policy. * NLA_SINT, NLA_UINT, * NLA_U8, NLA_U16, * NLA_U32, NLA_U64, * NLA_S8, NLA_S16, * NLA_S32, NLA_S64, * NLA_BE16, NLA_BE32, * NLA_MSECS Leaving the length field zero will verify the * given type fits, using it verifies minimum length * just like "All other" * NLA_BITFIELD32 Unused * NLA_REJECT Unused * All other Minimum length of attribute payload * * Meaning of validation union: * NLA_BITFIELD32 This is a 32-bit bitmap/bitselector attribute and * `bitfield32_valid' is the u32 value of valid flags * NLA_REJECT This attribute is always rejected and `reject_message' * may point to a string to report as the error instead * of the generic one in extended ACK. * NLA_NESTED `nested_policy' to a nested policy to validate, must * also set `len' to the max attribute number. Use the * provided NLA_POLICY_NESTED() macro. * Note that nla_parse() will validate, but of course not * parse, the nested sub-policies. * NLA_NESTED_ARRAY `nested_policy' points to a nested policy to validate, * must also set `len' to the max attribute number. Use * the provided NLA_POLICY_NESTED_ARRAY() macro. * The difference to NLA_NESTED is the structure: * NLA_NESTED has the nested attributes directly inside * while an array has the nested attributes at another * level down and the attribute types directly in the * nesting don't matter. * NLA_UINT, * NLA_U8, * NLA_U16, * NLA_U32, * NLA_U64, * NLA_BE16, * NLA_BE32, * NLA_SINT, * NLA_S8, * NLA_S16, * NLA_S32, * NLA_S64 The `min' and `max' fields are used depending on the * validation_type field, if that is min/max/range then * the min, max or both are used (respectively) to check * the value of the integer attribute. * Note that in the interest of code simplicity and * struct size both limits are s16, so you cannot * enforce a range that doesn't fall within the range * of s16 - do that using the NLA_POLICY_FULL_RANGE() * or NLA_POLICY_FULL_RANGE_SIGNED() macros instead. * Use the NLA_POLICY_MIN(), NLA_POLICY_MAX() and * NLA_POLICY_RANGE() macros. * NLA_UINT, * NLA_U8, * NLA_U16, * NLA_U32, * NLA_U64 If the validation_type field instead is set to * NLA_VALIDATE_RANGE_PTR, `range' must be a pointer * to a struct netlink_range_validation that indicates * the min/max values. * Use NLA_POLICY_FULL_RANGE(). * NLA_SINT, * NLA_S8, * NLA_S16, * NLA_S32, * NLA_S64 If the validation_type field instead is set to * NLA_VALIDATE_RANGE_PTR, `range_signed' must be a * pointer to a struct netlink_range_validation_signed * that indicates the min/max values. * Use NLA_POLICY_FULL_RANGE_SIGNED(). * * NLA_BINARY If the validation type is like the ones for integers * above, then the min/max length (not value like for * integers) of the attribute is enforced. * * All other Unused - but note that it's a union * * Meaning of `validate' field, use via NLA_POLICY_VALIDATE_FN: * NLA_U8, NLA_U16, * NLA_U32, NLA_U64, * NLA_S8, NLA_S16, * NLA_S32, NLA_S64, * NLA_MSECS, * NLA_BINARY Validation function called for the attribute. * * All other Unused - but note that it's a union * * Example: * * static const u32 myvalidflags = 0xff231023; * * static const struct nla_policy my_policy[ATTR_MAX+1] = { * [ATTR_FOO] = { .type = NLA_U16 }, * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, * [ATTR_BAZ] = NLA_POLICY_EXACT_LEN(sizeof(struct mystruct)), * [ATTR_GOO] = NLA_POLICY_BITFIELD32(myvalidflags), * };
*/ struct nla_policy {
u8 type;
u8 validation_type;
u16 len; union { /** * @strict_start_type: first attribute to validate strictly * * This entry is special, and used for the attribute at index 0 * only, and specifies special data about the policy, namely it * specifies the "boundary type" where strict length validation * starts for any attribute types >= this value, also, strict * nesting validation starts here. * * Additionally, it means that NLA_UNSPEC is actually NLA_REJECT * for any types >= this, so need to use NLA_POLICY_MIN_LEN() to * get the previous pure { .len = xyz } behaviour. The advantage * of this is that types not specified in the policy will be * rejected. * * For completely new families it should be set to 1 so that the * validation is enforced for all attributes. For existing ones * it should be set at least when new attributes are added to * the enum used by the policy, and be set to the new value that * was added to enforce strict validation from thereon.
*/
u16 strict_start_type;
/* private: use NLA_POLICY_*() to set */ const u32 bitfield32_valid; const u32 mask; constchar *reject_message; conststruct nla_policy *nested_policy; conststruct netlink_range_validation *range; conststruct netlink_range_validation_signed *range_signed; struct {
s16 min, max;
}; int (*validate)(conststruct nlattr *attr, struct netlink_ext_ack *extack);
};
};
/** * struct nl_info - netlink source information * @nlh: Netlink message header of original request * @nl_net: Network namespace * @portid: Netlink PORTID of requesting application * @skip_notify: Skip netlink notifications to user space * @skip_notify_kernel: Skip selected in-kernel notifications
*/ struct nl_info { struct nlmsghdr *nlh; struct net *nl_net;
u32 portid;
u8 skip_notify:1,
skip_notify_kernel:1;
};
/** * enum netlink_validation - netlink message/attribute validation levels * @NL_VALIDATE_LIBERAL: Old-style "be liberal" validation, not caring about * extra data at the end of the message, attributes being longer than * they should be, or unknown attributes being present. * @NL_VALIDATE_TRAILING: Reject junk data encountered after attribute parsing. * @NL_VALIDATE_MAXTYPE: Reject attributes > max type; Together with _TRAILING * this is equivalent to the old nla_parse_strict()/nlmsg_parse_strict(). * @NL_VALIDATE_UNSPEC: Reject attributes with NLA_UNSPEC in the policy. * This can safely be set by the kernel when the given policy has no * NLA_UNSPEC anymore, and can thus be used to ensure policy entries * are enforced going forward. * @NL_VALIDATE_STRICT_ATTRS: strict attribute policy parsing (e.g. * U8, U16, U32 must have exact size, etc.) * @NL_VALIDATE_NESTED: Check that NLA_F_NESTED is set for NLA_NESTED(_ARRAY) * and unset for other policies.
*/ enum netlink_validation {
NL_VALIDATE_LIBERAL = 0,
NL_VALIDATE_TRAILING = BIT(0),
NL_VALIDATE_MAXTYPE = BIT(1),
NL_VALIDATE_UNSPEC = BIT(2),
NL_VALIDATE_STRICT_ATTRS = BIT(3),
NL_VALIDATE_NESTED = BIT(4),
};
int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, struct nlmsghdr *, struct netlink_ext_ack *)); int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid, unsignedint group, int report, gfp_t flags);
int __nla_validate(conststruct nlattr *head, int len, int maxtype, conststruct nla_policy *policy, unsignedint validate, struct netlink_ext_ack *extack); int __nla_parse(struct nlattr **tb, int maxtype, conststruct nlattr *head, int len, conststruct nla_policy *policy, unsignedint validate, struct netlink_ext_ack *extack); int nla_policy_len(conststruct nla_policy *, int); struct nlattr *nla_find(conststruct nlattr *head, int len, int attrtype);
ssize_t nla_strscpy(char *dst, conststruct nlattr *nla, size_t dstsize); char *nla_strdup(conststruct nlattr *nla, gfp_t flags); int nla_memcpy(void *dest, conststruct nlattr *src, int count); int nla_memcmp(conststruct nlattr *nla, constvoid *data, size_t size); int nla_strcmp(conststruct nlattr *nla, constchar *str); struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen); struct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype, int attrlen, int padattr); void *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen); struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen); struct nlattr *nla_reserve_64bit(struct sk_buff *skb, int attrtype, int attrlen, int padattr); void *nla_reserve_nohdr(struct sk_buff *skb, int attrlen); void __nla_put(struct sk_buff *skb, int attrtype, int attrlen, constvoid *data); void __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen, constvoid *data, int padattr); void __nla_put_nohdr(struct sk_buff *skb, int attrlen, constvoid *data); int nla_put(struct sk_buff *skb, int attrtype, int attrlen, constvoid *data); int nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen, constvoid *data, int padattr); int nla_put_nohdr(struct sk_buff *skb, int attrlen, constvoid *data); int nla_append(struct sk_buff *skb, int attrlen, constvoid *data);
/** * nlmsg_payload - message payload if the data fits in the len * @nlh: netlink message header * @len: struct length * * Returns: The netlink message payload/data if the length is sufficient, * otherwise NULL.
*/ staticinlinevoid *nlmsg_payload(conststruct nlmsghdr *nlh, size_t len)
{ if (nlh->nlmsg_len < nlmsg_msg_size(len)) return NULL;
return nlmsg_data(nlh);
}
/** * nlmsg_attrdata - head of attributes data * @nlh: netlink message header * @hdrlen: length of family specific header
*/ staticinlinestruct nlattr *nlmsg_attrdata(conststruct nlmsghdr *nlh, int hdrlen)
{ unsignedchar *data = nlmsg_data(nlh); return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
}
/** * nlmsg_attrlen - length of attributes data * @nlh: netlink message header * @hdrlen: length of family specific header
*/ staticinlineint nlmsg_attrlen(conststruct nlmsghdr *nlh, int hdrlen)
{ return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
}
/** * nlmsg_ok - check if the netlink message fits into the remaining bytes * @nlh: netlink message header * @remaining: number of bytes remaining in message stream
*/ staticinlineint nlmsg_ok(conststruct nlmsghdr *nlh, int remaining)
{ return (remaining >= (int) sizeof(struct nlmsghdr) &&
nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
nlh->nlmsg_len <= remaining);
}
/** * nlmsg_next - next netlink message in message stream * @nlh: netlink message header * @remaining: number of bytes remaining in message stream * * Returns: the next netlink message in the message stream and * decrements remaining by the size of the current message.
*/ staticinlinestruct nlmsghdr *
nlmsg_next(conststruct nlmsghdr *nlh, int *remaining)
{ int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
/** * nla_parse - Parse a stream of attributes into a tb buffer * @tb: destination array with maxtype+1 elements * @maxtype: maximum attribute type to be expected * @head: head of attribute stream * @len: length of attribute stream * @policy: validation policy * @extack: extended ACK pointer * * Parses a stream of attributes and stores a pointer to each attribute in * the tb array accessible via the attribute type. Attributes with a type * exceeding maxtype will be rejected, policy must be specified, attributes * will be validated in the strictest way possible. * * Returns: 0 on success or a negative error code.
*/ staticinlineint nla_parse(struct nlattr **tb, int maxtype, conststruct nlattr *head, int len, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ return __nla_parse(tb, maxtype, head, len, policy,
NL_VALIDATE_STRICT, extack);
}
/** * nla_parse_deprecated - Parse a stream of attributes into a tb buffer * @tb: destination array with maxtype+1 elements * @maxtype: maximum attribute type to be expected * @head: head of attribute stream * @len: length of attribute stream * @policy: validation policy * @extack: extended ACK pointer * * Parses a stream of attributes and stores a pointer to each attribute in * the tb array accessible via the attribute type. Attributes with a type * exceeding maxtype will be ignored and attributes from the policy are not * always strictly validated (only for new attributes). * * Returns: 0 on success or a negative error code.
*/ staticinlineint nla_parse_deprecated(struct nlattr **tb, int maxtype, conststruct nlattr *head, int len, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ return __nla_parse(tb, maxtype, head, len, policy,
NL_VALIDATE_LIBERAL, extack);
}
/** * nla_parse_deprecated_strict - Parse a stream of attributes into a tb buffer * @tb: destination array with maxtype+1 elements * @maxtype: maximum attribute type to be expected * @head: head of attribute stream * @len: length of attribute stream * @policy: validation policy * @extack: extended ACK pointer * * Parses a stream of attributes and stores a pointer to each attribute in * the tb array accessible via the attribute type. Attributes with a type * exceeding maxtype will be rejected as well as trailing data, but the * policy is not completely strictly validated (only for new attributes). * * Returns: 0 on success or a negative error code.
*/ staticinlineint nla_parse_deprecated_strict(struct nlattr **tb, int maxtype, conststruct nlattr *head, int len, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ return __nla_parse(tb, maxtype, head, len, policy,
NL_VALIDATE_DEPRECATED_STRICT, extack);
}
/** * __nlmsg_parse - parse attributes of a netlink message * @nlh: netlink message header * @hdrlen: length of family specific header * @tb: destination array with maxtype+1 elements * @maxtype: maximum attribute type to be expected * @policy: validation policy * @validate: validation strictness * @extack: extended ACK report struct * * See nla_parse()
*/ staticinlineint __nlmsg_parse(conststruct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, conststruct nla_policy *policy, unsignedint validate, struct netlink_ext_ack *extack)
{ if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) {
NL_SET_ERR_MSG(extack, "Invalid header length"); return -EINVAL;
}
/** * nlmsg_parse - parse attributes of a netlink message * @nlh: netlink message header * @hdrlen: length of family specific header * @tb: destination array with maxtype+1 elements * @maxtype: maximum attribute type to be expected * @policy: validation policy * @extack: extended ACK report struct * * See nla_parse()
*/ staticinlineint nlmsg_parse(conststruct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy,
NL_VALIDATE_STRICT, extack);
}
/** * nlmsg_parse_deprecated - parse attributes of a netlink message * @nlh: netlink message header * @hdrlen: length of family specific header * @tb: destination array with maxtype+1 elements * @maxtype: maximum attribute type to be expected * @policy: validation policy * @extack: extended ACK report struct * * See nla_parse_deprecated()
*/ staticinlineint nlmsg_parse_deprecated(conststruct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy,
NL_VALIDATE_LIBERAL, extack);
}
/** * nlmsg_parse_deprecated_strict - parse attributes of a netlink message * @nlh: netlink message header * @hdrlen: length of family specific header * @tb: destination array with maxtype+1 elements * @maxtype: maximum attribute type to be expected * @policy: validation policy * @extack: extended ACK report struct * * See nla_parse_deprecated_strict()
*/ staticinlineint
nlmsg_parse_deprecated_strict(conststruct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy,
NL_VALIDATE_DEPRECATED_STRICT, extack);
}
/** * nlmsg_find_attr - find a specific attribute in a netlink message * @nlh: netlink message header * @hdrlen: length of family specific header * @attrtype: type of attribute to look for * * Returns: the first attribute which matches the specified type.
*/ staticinlinestruct nlattr *nlmsg_find_attr(conststruct nlmsghdr *nlh, int hdrlen, int attrtype)
{ return nla_find(nlmsg_attrdata(nlh, hdrlen),
nlmsg_attrlen(nlh, hdrlen), attrtype);
}
/** * nla_validate_deprecated - Validate a stream of attributes * @head: head of attribute stream * @len: length of attribute stream * @maxtype: maximum attribute type to be expected * @policy: validation policy * @extack: extended ACK report struct * * Validates all attributes in the specified attribute stream against the * specified policy. Validation is done in liberal mode. * See documentation of struct nla_policy for more details. * * Returns: 0 on success or a negative error code.
*/ staticinlineint nla_validate_deprecated(conststruct nlattr *head, int len, int maxtype, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ return __nla_validate(head, len, maxtype, policy, NL_VALIDATE_LIBERAL,
extack);
}
/** * nla_validate - Validate a stream of attributes * @head: head of attribute stream * @len: length of attribute stream * @maxtype: maximum attribute type to be expected * @policy: validation policy * @extack: extended ACK report struct * * Validates all attributes in the specified attribute stream against the * specified policy. Validation is done in strict mode. * See documentation of struct nla_policy for more details. * * Returns: 0 on success or a negative error code.
*/ staticinlineint nla_validate(conststruct nlattr *head, int len, int maxtype, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ return __nla_validate(head, len, maxtype, policy, NL_VALIDATE_STRICT,
extack);
}
/** * nlmsg_validate_deprecated - validate a netlink message including attributes * @nlh: netlinket message header * @hdrlen: length of family specific header * @maxtype: maximum attribute type to be expected * @policy: validation policy * @extack: extended ACK report struct
*/ staticinlineint nlmsg_validate_deprecated(conststruct nlmsghdr *nlh, int hdrlen, int maxtype, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) return -EINVAL;
/** * nlmsg_report - need to report back to application? * @nlh: netlink message header * * Returns: 1 if a report back to the application is requested.
*/ staticinlineint nlmsg_report(conststruct nlmsghdr *nlh)
{ return nlh ? !!(nlh->nlmsg_flags & NLM_F_ECHO) : 0;
}
/** * nlmsg_seq - return the seq number of netlink message * @nlh: netlink message header * * Returns: 0 if netlink message is NULL
*/ staticinline u32 nlmsg_seq(conststruct nlmsghdr *nlh)
{ return nlh ? nlh->nlmsg_seq : 0;
}
/** * nlmsg_for_each_attr - iterate over a stream of attributes * @pos: loop counter, set to current attribute * @nlh: netlink message header * @hdrlen: length of family 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)
/** * nlmsg_for_each_attr_type - iterate over a stream of attributes * @pos: loop counter, set to the current attribute * @type: required attribute type for @pos * @nlh: netlink message header * @hdrlen: length of the family specific header * @rem: initialized to len, holds bytes currently remaining in stream
*/ #define nlmsg_for_each_attr_type(pos, type, nlh, hdrlen, rem) \
nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \ if (nla_type(pos) == type)
/** * nlmsg_put - Add a new netlink message to an skb * @skb: socket buffer to store message in * @portid: netlink PORTID of requesting application * @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.
*/ staticinlinestruct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int payload, int flags)
{ if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload))) return NULL;
/** * nlmsg_append - Add more data to a nlmsg in a skb * @skb: socket buffer to store message in * @size: length of message payload * * Append data to an existing nlmsg, used when constructing a message * with multiple fixed-format headers (which is rare). * Returns: NULL if the tailroom of the skb is insufficient to store * the extra payload.
*/ staticinlinevoid *nlmsg_append(struct sk_buff *skb, u32 size)
{ if (unlikely(skb_tailroom(skb) < NLMSG_ALIGN(size))) return NULL;
/** * 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.
*/ staticinlinestruct 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).portid, 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.
*/ staticinlinestruct sk_buff *nlmsg_new(size_t payload, gfp_t flags)
{ return alloc_skb(nlmsg_total_size(payload), flags);
}
/** * nlmsg_new_large - Allocate a new netlink message with non-contiguous * physical memory * @payload: size of the message payload * * The allocated skb is unable to have frag page for shinfo->frags*, * as the NULL setting for skb->head in netlink_skb_destructor() will * bypass most of the handling in skb_release_data()
*/ staticinlinestruct sk_buff *nlmsg_new_large(size_t payload)
{ return netlink_alloc_large_skb(nlmsg_total_size(payload), 0);
}
/** * 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 appended * attributes. Only necessary if attributes have been added to * the message.
*/ staticinlinevoid nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
{
nlh->nlmsg_len = skb_tail_pointer(skb) - (unsignedchar *)nlh;
}
/** * 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.
*/ staticinlinevoid *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.
*/ staticinlinevoid nlmsg_trim(struct sk_buff *skb, constvoid *mark)
{ if (mark) {
WARN_ON((unsignedchar *) mark < skb->data);
skb_trim(skb, (unsignedchar *) mark - skb->data);
}
}
/** * 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.
*/ staticinlinevoid nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
{
nlmsg_trim(skb, nlh);
}
/** * nlmsg_free - drop a netlink message * @skb: socket buffer of netlink message
*/ staticinlinevoid nlmsg_free(struct sk_buff *skb)
{
kfree_skb(skb);
}
/** * 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)))
/** * nl_dump_check_consistent - check if sequence is consistent and advertise if not * @cb: netlink callback structure that stores the sequence number * @nlh: netlink message header to write the flag to * * This function checks if the sequence (generation) number changed during dump * and if it did, advertises it in the netlink message header. * * The correct way to use it is to set cb->seq to the generation counter when * all locks for dumping have been acquired, and then call this function for * each message that is generated. * * Note that due to initialisation concerns, 0 is an invalid sequence number * and must not be used by code that uses this functionality.
*/ staticinlinevoid
nl_dump_check_consistent(struct netlink_callback *cb, struct nlmsghdr *nlh)
{ if (cb->prev_seq && cb->seq != cb->prev_seq)
nlh->nlmsg_flags |= NLM_F_DUMP_INTR;
cb->prev_seq = cb->seq;
}
/** * nla_ok - check if the netlink attribute fits into the remaining bytes * @nla: netlink attribute * @remaining: number of bytes remaining in attribute stream
*/ staticinlineint nla_ok(conststruct nlattr *nla, int remaining)
{ return remaining >= (int) 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.
*/ staticinlinestruct nlattr *nla_next(conststruct nlattr *nla, int *remaining)
{ unsignedint totlen = NLA_ALIGN(nla->nla_len);
/** * 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.
*/ staticinlinestruct nlattr *
nla_find_nested(conststruct 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 * @extack: extended ACK report struct * * See nla_parse()
*/ staticinlineint nla_parse_nested(struct nlattr *tb[], int maxtype, conststruct nlattr *nla, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ if (!(nla->nla_type & NLA_F_NESTED)) {
NL_SET_ERR_MSG_ATTR(extack, nla, "NLA_F_NESTED is missing"); return -EINVAL;
}
/** * nla_parse_nested_deprecated - 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 * @extack: extended ACK report struct * * See nla_parse_deprecated()
*/ staticinlineint nla_parse_nested_deprecated(struct nlattr *tb[], int maxtype, conststruct nlattr *nla, conststruct nla_policy *policy, struct netlink_ext_ack *extack)
{ return __nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy,
NL_VALIDATE_LIBERAL, extack);
}
/** * nla_put_u8 - Add a u8 netlink attribute to a socket buffer * @skb: socket buffer to add attribute to * @attrtype: attribute type * @value: numeric value
*/ staticinlineint nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
{ /* temporary variables to work around GCC PR81715 with asan-stack=1 */
u8 tmp = value;
/** * nla_put_u64_64bit - Add a u64 netlink attribute to a skb and align it * @skb: socket buffer to add attribute to * @attrtype: attribute type * @value: numeric value * @padattr: attribute type for the padding
*/ staticinlineint nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
u64 value, int padattr)
{
u64 tmp = value;
/** * nla_put_be64 - Add a __be64 netlink attribute to a socket buffer and align it * @skb: socket buffer to add attribute to * @attrtype: attribute type * @value: numeric value * @padattr: attribute type for the padding
*/ staticinlineint nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value, int padattr)
{
__be64 tmp = value;
/** * nla_put_net64 - Add 64-bit network byte order nlattr to a skb and align it * @skb: socket buffer to add attribute to * @attrtype: attribute type * @value: numeric value * @padattr: attribute type for the padding
*/ staticinlineint nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value, int padattr)
{
__be64 tmp = value;
/** * nla_put_le64 - Add a __le64 netlink attribute to a socket buffer and align it * @skb: socket buffer to add attribute to * @attrtype: attribute type * @value: numeric value * @padattr: attribute type for the padding
*/ staticinlineint nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value, int padattr)
{
__le64 tmp = value;
/** * nla_put_s64 - Add a s64 netlink attribute to a socket buffer and align it * @skb: socket buffer to add attribute to * @attrtype: attribute type * @value: numeric value * @padattr: attribute type for the padding
*/ staticinlineint nla_put_s64(struct sk_buff *skb, int attrtype, s64 value, int padattr)
{
s64 tmp = value;
/** * nla_put_sint - Add a variable-size signed int to a socket buffer * @skb: socket buffer to add attribute to * @attrtype: attribute type * @value: numeric value
*/ staticinlineint nla_put_sint(struct sk_buff *skb, int attrtype, s64 value)
{
s64 tmp64 = value;
s32 tmp32 = value;
/** * nla_put_string - Add a string netlink attribute to a socket buffer * @skb: socket buffer to add attribute to * @attrtype: attribute type * @str: NUL terminated string
*/ staticinlineint nla_put_string(struct sk_buff *skb, int attrtype, constchar *str)
{ return nla_put(skb, attrtype, strlen(str) + 1, str);
}
/** * nla_put_flag - Add a flag netlink attribute to a socket buffer * @skb: socket buffer to add attribute to * @attrtype: attribute type
*/ staticinlineint nla_put_flag(struct sk_buff *skb, int attrtype)
{ return nla_put(skb, attrtype, 0, NULL);
}
/** * nla_put_msecs - Add a msecs netlink attribute to a skb and align it * @skb: socket buffer to add attribute to * @attrtype: attribute type * @njiffies: number of jiffies to convert to msecs * @padattr: attribute type for the padding
*/ staticinlineint nla_put_msecs(struct sk_buff *skb, int attrtype, unsignedlong njiffies, int padattr)
{
u64 tmp = jiffies_to_msecs(njiffies);
/** * nla_get_u32_default - return payload of u32 attribute or default * @nla: u32 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline u32 nla_get_u32_default(conststruct nlattr *nla, u32 defvalue)
{ if (!nla) return defvalue; return nla_get_u32(nla);
}
/** * nla_get_be32_default - return payload of be32 attribute or default * @nla: __be32 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline __be32 nla_get_be32_default(conststruct nlattr *nla,
__be32 defvalue)
{ if (!nla) return defvalue; return nla_get_be32(nla);
}
/** * nla_get_le32_default - return payload of le32 attribute or default * @nla: __le32 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline __le32 nla_get_le32_default(conststruct nlattr *nla,
__le32 defvalue)
{ if (!nla) return defvalue; return nla_get_le32(nla);
}
/** * nla_get_u16_default - return payload of u16 attribute or default * @nla: u16 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline u16 nla_get_u16_default(conststruct nlattr *nla, u16 defvalue)
{ if (!nla) return defvalue; return nla_get_u16(nla);
}
/** * nla_get_be16_default - return payload of be16 attribute or default * @nla: __be16 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline __be16 nla_get_be16_default(conststruct nlattr *nla,
__be16 defvalue)
{ if (!nla) return defvalue; return nla_get_be16(nla);
}
/** * nla_get_le16_default - return payload of le16 attribute or default * @nla: __le16 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline __le16 nla_get_le16_default(conststruct nlattr *nla,
__le16 defvalue)
{ if (!nla) return defvalue; return nla_get_le16(nla);
}
/** * nla_get_u8_default - return payload of u8 attribute or default * @nla: u8 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline u8 nla_get_u8_default(conststruct nlattr *nla, u8 defvalue)
{ if (!nla) return defvalue; return nla_get_u8(nla);
}
/** * nla_get_u64_default - return payload of u64 attribute or default * @nla: u64 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline u64 nla_get_u64_default(conststruct nlattr *nla, u64 defvalue)
{ if (!nla) return defvalue; return nla_get_u64(nla);
}
/** * nla_get_uint_default - return payload of uint attribute or default * @nla: uint netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline u64 nla_get_uint_default(conststruct nlattr *nla, u64 defvalue)
{ if (!nla) return defvalue; return nla_get_uint(nla);
}
/** * nla_get_be64_default - return payload of be64 attribute or default * @nla: __be64 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline __be64 nla_get_be64_default(conststruct nlattr *nla,
__be64 defvalue)
{ if (!nla) return defvalue; return nla_get_be64(nla);
}
/** * nla_get_le64_default - return payload of le64 attribute or default * @nla: __le64 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline __le64 nla_get_le64_default(conststruct nlattr *nla,
__le64 defvalue)
{ if (!nla) return defvalue; return nla_get_le64(nla);
}
/** * nla_get_s32_default - return payload of s32 attribute or default * @nla: s32 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline s32 nla_get_s32_default(conststruct nlattr *nla, s32 defvalue)
{ if (!nla) return defvalue; return nla_get_s32(nla);
}
/** * nla_get_s16_default - return payload of s16 attribute or default * @nla: s16 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline s16 nla_get_s16_default(conststruct nlattr *nla, s16 defvalue)
{ if (!nla) return defvalue; return nla_get_s16(nla);
}
/** * nla_get_s8_default - return payload of s8 attribute or default * @nla: s8 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline s8 nla_get_s8_default(conststruct nlattr *nla, s8 defvalue)
{ if (!nla) return defvalue; return nla_get_s8(nla);
}
/** * nla_get_s64_default - return payload of s64 attribute or default * @nla: s64 netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline s64 nla_get_s64_default(conststruct nlattr *nla, s64 defvalue)
{ if (!nla) return defvalue; return nla_get_s64(nla);
}
/** * nla_get_sint_default - return payload of sint attribute or default * @nla: sint netlink attribute, may be %NULL * @defvalue: default value to use if @nla is %NULL * * Return: the value of the attribute, or the default value if not present
*/ staticinline s64 nla_get_sint_default(conststruct nlattr *nla, s64 defvalue)
{ if (!nla) return defvalue; return nla_get_sint(nla);
}
/** * nla_get_flag - return payload of flag attribute * @nla: flag netlink attribute
*/
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.53 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.