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 |
