From 089bf1a6a924b97a7e9f920bae6253a8ad581cf3 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Thu, 21 Apr 2016 18:58:24 +0200 Subject: libnl: add more helpers to align attributes on 64-bit Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller --- lib/nlattr.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) (limited to 'lib/nlattr.c') diff --git a/lib/nlattr.c b/lib/nlattr.c index f5907d23272d4..2b82f1e2ebc2c 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -354,6 +354,29 @@ struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen) } EXPORT_SYMBOL(__nla_reserve); +/** + * __nla_reserve_64bit - reserve room for attribute on the skb and align it + * @skb: socket buffer to reserve room on + * @attrtype: attribute type + * @attrlen: length of attribute payload + * + * Adds a netlink attribute header to a socket buffer and reserves + * room for the payload but does not copy it. It also ensure that this + * attribute will be 64-bit aign. + * + * The caller is responsible to ensure that the skb provides enough + * tailroom for the attribute header and payload. + */ +struct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype, + int attrlen, int padattr) +{ + if (nla_need_padding_for_64bit(skb)) + nla_align_64bit(skb, padattr); + + return __nla_reserve(skb, attrtype, attrlen); +} +EXPORT_SYMBOL(__nla_reserve_64bit); + /** * __nla_reserve_nohdr - reserve room for attribute without header * @skb: socket buffer to reserve room on @@ -396,6 +419,35 @@ struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen) } EXPORT_SYMBOL(nla_reserve); +/** + * nla_reserve_64bit - reserve room for attribute on the skb and align it + * @skb: socket buffer to reserve room on + * @attrtype: attribute type + * @attrlen: length of attribute payload + * + * Adds a netlink attribute header to a socket buffer and reserves + * room for the payload but does not copy it. It also ensure that this + * attribute will be 64-bit aign. + * + * Returns NULL if the tailroom of the skb is insufficient to store + * the attribute header and payload. + */ +struct nlattr *nla_reserve_64bit(struct sk_buff *skb, int attrtype, int attrlen, + int padattr) +{ + size_t len; + + if (nla_need_padding_for_64bit(skb)) + len = nla_total_size_64bit(attrlen); + else + len = nla_total_size(attrlen); + if (unlikely(skb_tailroom(skb) < len)) + return NULL; + + return __nla_reserve_64bit(skb, attrtype, attrlen, padattr); +} +EXPORT_SYMBOL(nla_reserve_64bit); + /** * nla_reserve_nohdr - reserve room for attribute without header * @skb: socket buffer to reserve room on @@ -435,6 +487,26 @@ void __nla_put(struct sk_buff *skb, int attrtype, int attrlen, } EXPORT_SYMBOL(__nla_put); +/** + * __nla_put_64bit - Add a netlink attribute to a socket buffer and align it + * @skb: socket buffer to add attribute to + * @attrtype: attribute type + * @attrlen: length of attribute payload + * @data: head of attribute payload + * + * The caller is responsible to ensure that the skb provides enough + * tailroom for the attribute header and payload. + */ +void __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen, + const void *data, int padattr) +{ + struct nlattr *nla; + + nla = __nla_reserve_64bit(skb, attrtype, attrlen, padattr); + memcpy(nla_data(nla), data, attrlen); +} +EXPORT_SYMBOL(__nla_put_64bit); + /** * __nla_put_nohdr - Add a netlink attribute without header * @skb: socket buffer to add attribute to @@ -473,6 +545,33 @@ int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data) } EXPORT_SYMBOL(nla_put); +/** + * nla_put_64bit - Add a netlink attribute to a socket buffer and align it + * @skb: socket buffer to add attribute to + * @attrtype: attribute type + * @attrlen: length of attribute payload + * @data: head of attribute payload + * + * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store + * the attribute header and payload. + */ +int nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen, + const void *data, int padattr) +{ + size_t len; + + if (nla_need_padding_for_64bit(skb)) + len = nla_total_size_64bit(attrlen); + else + len = nla_total_size(attrlen); + if (unlikely(skb_tailroom(skb) < len)) + return -EMSGSIZE; + + __nla_put_64bit(skb, attrtype, attrlen, data, padattr); + return 0; +} +EXPORT_SYMBOL(nla_put_64bit); + /** * nla_put_nohdr - Add a netlink attribute without header * @skb: socket buffer to add attribute to -- cgit v1.2.3