Commit 00768244 authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller

[NETLINK] Routing attribute related shortcuts

   Assumes TLV is a u32/u64 field and returns its value.

   Assumes TLV is a u64 and transports jiffies converted
   to seconds or milliseconds and returns its value.

 RTA_PUT_U(32|64)(skb, type, value)
   Appends %value as fixed u32/u64 to %skb as TLV %type.

 RTA_PUT_[M]SECS(skb, type, jiffies)
   Converts %jiffies to secs/msecs and appends it as u64
   to %skb as TLV %type.

 RTA_PUT_STRING(skb, type, string)
   Appends %NUL terminated %string to %skb as TLV %type.

 RTA_NEST(skb, type)
   Starts a nested TLV %type and returns the nesting handle.

 RTA_NEST_END(skb, nesting_handle)
   Finishes the nested TLV %nesting_handle, must be called
   symmetric to RTA_NEST(). Returns skb->len

 RTA_NEST_CANCEL(skb, nesting_handle)
   Cancel the nested TLV %nesting_handle and trim nested TLV
   from skb again, returns -1.
Signed-off-by: default avatarThomas Graf <>
Signed-off-by: default avatarDavid S. Miller <>
parent f88a10d6
......@@ -789,6 +789,51 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi
({ if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \
goto rtattr_failure; \
memcpy(skb_put(skb, RTA_ALIGN(attrlen)), data, attrlen); })
#define RTA_PUT_U32(skb, attrtype, value) \
({ u32 _tmp = (value); \
RTA_PUT(skb, attrtype, sizeof(u32), &_tmp); })
#define RTA_PUT_U64(skb, attrtype, value) \
({ u64 _tmp = (value); \
RTA_PUT(skb, attrtype, sizeof(u64), &_tmp); })
#define RTA_PUT_SECS(skb, attrtype, value) \
RTA_PUT_U64(skb, attrtype, (value) / HZ)
#define RTA_PUT_MSECS(skb, attrtype, value) \
RTA_PUT_U64(skb, attrtype, jiffies_to_msecs(value))
#define RTA_PUT_STRING(skb, attrtype, value) \
RTA_PUT(skb, attrtype, strlen(value) + 1, value)
#define RTA_NEST(skb, type) \
({ struct rtattr *__start = (struct rtattr *) (skb)->tail; \
RTA_PUT(skb, type, 0, NULL); \
__start; })
#define RTA_NEST_END(skb, start) \
({ (start)->rta_len = ((skb)->tail - (unsigned char *) (start)); \
(skb)->len; })
#define RTA_NEST_CANCEL(skb, start) \
({ skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
-1; })
#define RTA_GET_U32(rta) \
({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u32)) \
goto rtattr_failure; \
*(u32 *) RTA_DATA(rta); })
#define RTA_GET_U64(rta) \
({ u64 _tmp; \
if (!rta || RTA_PAYLOAD(rta) < sizeof(u64)) \
goto rtattr_failure; \
memcpy(&_tmp, RTA_DATA(rta), sizeof(_tmp)); \
_tmp; })
#define RTA_GET_SECS(rta) ((unsigned long) RTA_GET_U64(rta) * HZ)
#define RTA_GET_MSECS(rta) (msecs_to_jiffies((unsigned long) RTA_GET_U64(rta)))
static inline struct rtattr *
__rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment