diff options
author | Thomas Graf <tgraf@suug.ch> | 2005-06-19 01:50:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-06-19 01:50:38 -0400 |
commit | 00768244923f66801958a8d2d103f7b65608c9b6 (patch) | |
tree | 8d4ec56bd4edd9e3bb47938d01ef809d60a83aa3 | |
parent | f88a10d65620d97b6d0a7e352a3493c1b7e7409b (diff) |
[NETLINK] Routing attribute related shortcuts
RTA_GET_U(32|64)(tlv)
Assumes TLV is a u32/u64 field and returns its value.
RTA_GET_[M]SECS(tlv)
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: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/rtnetlink.h | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 91ac97c20777..a09b5d42babf 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
@@ -789,6 +789,51 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi | |||
789 | ({ if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \ | 789 | ({ if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \ |
790 | goto rtattr_failure; \ | 790 | goto rtattr_failure; \ |
791 | memcpy(skb_put(skb, RTA_ALIGN(attrlen)), data, attrlen); }) | 791 | memcpy(skb_put(skb, RTA_ALIGN(attrlen)), data, attrlen); }) |
792 | |||
793 | #define RTA_PUT_U32(skb, attrtype, value) \ | ||
794 | ({ u32 _tmp = (value); \ | ||
795 | RTA_PUT(skb, attrtype, sizeof(u32), &_tmp); }) | ||
796 | |||
797 | #define RTA_PUT_U64(skb, attrtype, value) \ | ||
798 | ({ u64 _tmp = (value); \ | ||
799 | RTA_PUT(skb, attrtype, sizeof(u64), &_tmp); }) | ||
800 | |||
801 | #define RTA_PUT_SECS(skb, attrtype, value) \ | ||
802 | RTA_PUT_U64(skb, attrtype, (value) / HZ) | ||
803 | |||
804 | #define RTA_PUT_MSECS(skb, attrtype, value) \ | ||
805 | RTA_PUT_U64(skb, attrtype, jiffies_to_msecs(value)) | ||
806 | |||
807 | #define RTA_PUT_STRING(skb, attrtype, value) \ | ||
808 | RTA_PUT(skb, attrtype, strlen(value) + 1, value) | ||
809 | |||
810 | #define RTA_NEST(skb, type) \ | ||
811 | ({ struct rtattr *__start = (struct rtattr *) (skb)->tail; \ | ||
812 | RTA_PUT(skb, type, 0, NULL); \ | ||
813 | __start; }) | ||
814 | |||
815 | #define RTA_NEST_END(skb, start) \ | ||
816 | ({ (start)->rta_len = ((skb)->tail - (unsigned char *) (start)); \ | ||
817 | (skb)->len; }) | ||
818 | |||
819 | #define RTA_NEST_CANCEL(skb, start) \ | ||
820 | ({ skb_trim(skb, (unsigned char *) (start) - (skb)->data); \ | ||
821 | -1; }) | ||
822 | |||
823 | #define RTA_GET_U32(rta) \ | ||
824 | ({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u32)) \ | ||
825 | goto rtattr_failure; \ | ||
826 | *(u32 *) RTA_DATA(rta); }) | ||
827 | |||
828 | #define RTA_GET_U64(rta) \ | ||
829 | ({ u64 _tmp; \ | ||
830 | if (!rta || RTA_PAYLOAD(rta) < sizeof(u64)) \ | ||
831 | goto rtattr_failure; \ | ||
832 | memcpy(&_tmp, RTA_DATA(rta), sizeof(_tmp)); \ | ||
833 | _tmp; }) | ||
834 | |||
835 | #define RTA_GET_SECS(rta) ((unsigned long) RTA_GET_U64(rta) * HZ) | ||
836 | #define RTA_GET_MSECS(rta) (msecs_to_jiffies((unsigned long) RTA_GET_U64(rta))) | ||
792 | 837 | ||
793 | static inline struct rtattr * | 838 | static inline struct rtattr * |
794 | __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen) | 839 | __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen) |