diff options
Diffstat (limited to 'net/tipc/msg.h')
-rw-r--r-- | net/tipc/msg.h | 143 |
1 files changed, 127 insertions, 16 deletions
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index d5c83d7ecb47..9ace47f44a69 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
@@ -37,7 +37,7 @@ | |||
37 | #ifndef _TIPC_MSG_H | 37 | #ifndef _TIPC_MSG_H |
38 | #define _TIPC_MSG_H | 38 | #define _TIPC_MSG_H |
39 | 39 | ||
40 | #include "bearer.h" | 40 | #include <linux/tipc.h> |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Constants and routines used to read and write TIPC payload message headers | 43 | * Constants and routines used to read and write TIPC payload message headers |
@@ -45,6 +45,7 @@ | |||
45 | * Note: Some items are also used with TIPC internal message headers | 45 | * Note: Some items are also used with TIPC internal message headers |
46 | */ | 46 | */ |
47 | #define TIPC_VERSION 2 | 47 | #define TIPC_VERSION 2 |
48 | struct plist; | ||
48 | 49 | ||
49 | /* | 50 | /* |
50 | * Payload message users are defined in TIPC's public API: | 51 | * Payload message users are defined in TIPC's public API: |
@@ -77,11 +78,37 @@ | |||
77 | 78 | ||
78 | #define TIPC_MEDIA_ADDR_OFFSET 5 | 79 | #define TIPC_MEDIA_ADDR_OFFSET 5 |
79 | 80 | ||
81 | /** | ||
82 | * TIPC message buffer code | ||
83 | * | ||
84 | * TIPC message buffer headroom reserves space for the worst-case | ||
85 | * link-level device header (in case the message is sent off-node). | ||
86 | * | ||
87 | * Note: Headroom should be a multiple of 4 to ensure the TIPC header fields | ||
88 | * are word aligned for quicker access | ||
89 | */ | ||
90 | #define BUF_HEADROOM LL_MAX_HEADER | ||
91 | |||
92 | struct tipc_skb_cb { | ||
93 | void *handle; | ||
94 | struct sk_buff *tail; | ||
95 | bool deferred; | ||
96 | bool wakeup_pending; | ||
97 | bool bundling; | ||
98 | u16 chain_sz; | ||
99 | u16 chain_imp; | ||
100 | }; | ||
101 | |||
102 | #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) | ||
80 | 103 | ||
81 | struct tipc_msg { | 104 | struct tipc_msg { |
82 | __be32 hdr[15]; | 105 | __be32 hdr[15]; |
83 | }; | 106 | }; |
84 | 107 | ||
108 | static inline struct tipc_msg *buf_msg(struct sk_buff *skb) | ||
109 | { | ||
110 | return (struct tipc_msg *)skb->data; | ||
111 | } | ||
85 | 112 | ||
86 | static inline u32 msg_word(struct tipc_msg *m, u32 pos) | 113 | static inline u32 msg_word(struct tipc_msg *m, u32 pos) |
87 | { | 114 | { |
@@ -721,27 +748,111 @@ static inline u32 msg_tot_origport(struct tipc_msg *m) | |||
721 | return msg_origport(m); | 748 | return msg_origport(m); |
722 | } | 749 | } |
723 | 750 | ||
724 | bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err); | 751 | struct sk_buff *tipc_buf_acquire(u32 size); |
725 | 752 | bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode, | |
726 | int tipc_msg_eval(struct sk_buff *buf, u32 *dnode); | 753 | int err); |
727 | 754 | void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type, | |
728 | void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, | 755 | u32 hsize, u32 destnode); |
729 | u32 destnode); | ||
730 | |||
731 | struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz, | 756 | struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz, |
732 | uint data_sz, u32 dnode, u32 onode, | 757 | uint data_sz, u32 dnode, u32 onode, |
733 | u32 dport, u32 oport, int errcode); | 758 | u32 dport, u32 oport, int errcode); |
734 | |||
735 | int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf); | 759 | int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf); |
736 | |||
737 | bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu); | 760 | bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu); |
761 | bool tipc_msg_make_bundle(struct sk_buff_head *list, | ||
762 | struct sk_buff *skb, u32 mtu, u32 dnode); | ||
763 | bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos); | ||
764 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, | ||
765 | int offset, int dsz, int mtu, struct sk_buff_head *list); | ||
766 | bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, u32 *dnode, | ||
767 | int *err); | ||
768 | struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list); | ||
738 | 769 | ||
739 | bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb, | 770 | /* tipc_skb_peek(): peek and reserve first buffer in list |
740 | u32 mtu, u32 dnode); | 771 | * @list: list to be peeked in |
741 | 772 | * Returns pointer to first buffer in list, if any | |
742 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, | 773 | */ |
743 | int dsz, int mtu, struct sk_buff_head *list); | 774 | static inline struct sk_buff *tipc_skb_peek(struct sk_buff_head *list, |
775 | spinlock_t *lock) | ||
776 | { | ||
777 | struct sk_buff *skb; | ||
778 | |||
779 | spin_lock_bh(lock); | ||
780 | skb = skb_peek(list); | ||
781 | if (skb) | ||
782 | skb_get(skb); | ||
783 | spin_unlock_bh(lock); | ||
784 | return skb; | ||
785 | } | ||
786 | |||
787 | /* tipc_skb_peek_port(): find a destination port, ignoring all destinations | ||
788 | * up to and including 'filter'. | ||
789 | * Note: ignoring previously tried destinations minimizes the risk of | ||
790 | * contention on the socket lock | ||
791 | * @list: list to be peeked in | ||
792 | * @filter: last destination to be ignored from search | ||
793 | * Returns a destination port number, of applicable. | ||
794 | */ | ||
795 | static inline u32 tipc_skb_peek_port(struct sk_buff_head *list, u32 filter) | ||
796 | { | ||
797 | struct sk_buff *skb; | ||
798 | u32 dport = 0; | ||
799 | bool ignore = true; | ||
800 | |||
801 | spin_lock_bh(&list->lock); | ||
802 | skb_queue_walk(list, skb) { | ||
803 | dport = msg_destport(buf_msg(skb)); | ||
804 | if (!filter || skb_queue_is_last(list, skb)) | ||
805 | break; | ||
806 | if (dport == filter) | ||
807 | ignore = false; | ||
808 | else if (!ignore) | ||
809 | break; | ||
810 | } | ||
811 | spin_unlock_bh(&list->lock); | ||
812 | return dport; | ||
813 | } | ||
814 | |||
815 | /* tipc_skb_dequeue(): unlink first buffer with dest 'dport' from list | ||
816 | * @list: list to be unlinked from | ||
817 | * @dport: selection criteria for buffer to unlink | ||
818 | */ | ||
819 | static inline struct sk_buff *tipc_skb_dequeue(struct sk_buff_head *list, | ||
820 | u32 dport) | ||
821 | { | ||
822 | struct sk_buff *_skb, *tmp, *skb = NULL; | ||
823 | |||
824 | spin_lock_bh(&list->lock); | ||
825 | skb_queue_walk_safe(list, _skb, tmp) { | ||
826 | if (msg_destport(buf_msg(_skb)) == dport) { | ||
827 | __skb_unlink(_skb, list); | ||
828 | skb = _skb; | ||
829 | break; | ||
830 | } | ||
831 | } | ||
832 | spin_unlock_bh(&list->lock); | ||
833 | return skb; | ||
834 | } | ||
835 | |||
836 | /* tipc_skb_queue_tail(): add buffer to tail of list; | ||
837 | * @list: list to be appended to | ||
838 | * @skb: buffer to append. Always appended | ||
839 | * @dport: the destination port of the buffer | ||
840 | * returns true if dport differs from previous destination | ||
841 | */ | ||
842 | static inline bool tipc_skb_queue_tail(struct sk_buff_head *list, | ||
843 | struct sk_buff *skb, u32 dport) | ||
844 | { | ||
845 | struct sk_buff *_skb = NULL; | ||
846 | bool rv = false; | ||
744 | 847 | ||
745 | struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list); | 848 | spin_lock_bh(&list->lock); |
849 | _skb = skb_peek_tail(list); | ||
850 | if (!_skb || (msg_destport(buf_msg(_skb)) != dport) || | ||
851 | (skb_queue_len(list) > 32)) | ||
852 | rv = true; | ||
853 | __skb_queue_tail(list, skb); | ||
854 | spin_unlock_bh(&list->lock); | ||
855 | return rv; | ||
856 | } | ||
746 | 857 | ||
747 | #endif | 858 | #endif |