diff options
-rw-r--r-- | net/tipc/group.c | 95 | ||||
-rw-r--r-- | net/tipc/group.h | 2 | ||||
-rw-r--r-- | net/tipc/socket.c | 3 |
3 files changed, 56 insertions, 44 deletions
diff --git a/net/tipc/group.c b/net/tipc/group.c index a352e098f0e7..e08b7acc7b2d 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c | |||
@@ -64,7 +64,6 @@ struct tipc_member { | |||
64 | struct rb_node tree_node; | 64 | struct rb_node tree_node; |
65 | struct list_head list; | 65 | struct list_head list; |
66 | struct list_head small_win; | 66 | struct list_head small_win; |
67 | struct sk_buff *event_msg; | ||
68 | struct sk_buff_head deferredq; | 67 | struct sk_buff_head deferredq; |
69 | struct tipc_group *group; | 68 | struct tipc_group *group; |
70 | u32 node; | 69 | u32 node; |
@@ -632,6 +631,40 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
632 | } | 631 | } |
633 | } | 632 | } |
634 | 633 | ||
634 | static void tipc_group_create_event(struct tipc_group *grp, | ||
635 | struct tipc_member *m, | ||
636 | u32 event, u16 seqno, | ||
637 | struct sk_buff_head *inputq) | ||
638 | { u32 dnode = tipc_own_addr(grp->net); | ||
639 | struct tipc_event evt; | ||
640 | struct sk_buff *skb; | ||
641 | struct tipc_msg *hdr; | ||
642 | |||
643 | evt.event = event; | ||
644 | evt.found_lower = m->instance; | ||
645 | evt.found_upper = m->instance; | ||
646 | evt.port.ref = m->port; | ||
647 | evt.port.node = m->node; | ||
648 | evt.s.seq.type = grp->type; | ||
649 | evt.s.seq.lower = m->instance; | ||
650 | evt.s.seq.upper = m->instance; | ||
651 | |||
652 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_GRP_MEMBER_EVT, | ||
653 | GROUP_H_SIZE, sizeof(evt), dnode, m->node, | ||
654 | grp->portid, m->port, 0); | ||
655 | if (!skb) | ||
656 | return; | ||
657 | |||
658 | hdr = buf_msg(skb); | ||
659 | msg_set_nametype(hdr, grp->type); | ||
660 | msg_set_grp_evt(hdr, event); | ||
661 | msg_set_dest_droppable(hdr, true); | ||
662 | msg_set_grp_bc_seqno(hdr, seqno); | ||
663 | memcpy(msg_data(hdr), &evt, sizeof(evt)); | ||
664 | TIPC_SKB_CB(skb)->orig_member = m->instance; | ||
665 | __skb_queue_tail(inputq, skb); | ||
666 | } | ||
667 | |||
635 | static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, | 668 | static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, |
636 | int mtyp, struct sk_buff_head *xmitq) | 669 | int mtyp, struct sk_buff_head *xmitq) |
637 | { | 670 | { |
@@ -677,7 +710,6 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
677 | u32 node = msg_orignode(hdr); | 710 | u32 node = msg_orignode(hdr); |
678 | u32 port = msg_origport(hdr); | 711 | u32 port = msg_origport(hdr); |
679 | struct tipc_member *m, *pm; | 712 | struct tipc_member *m, *pm; |
680 | struct tipc_msg *ehdr; | ||
681 | u16 remitted, in_flight; | 713 | u16 remitted, in_flight; |
682 | 714 | ||
683 | if (!grp) | 715 | if (!grp) |
@@ -704,9 +736,8 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
704 | *usr_wakeup = true; | 736 | *usr_wakeup = true; |
705 | m->usr_pending = false; | 737 | m->usr_pending = false; |
706 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 738 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
707 | ehdr = buf_msg(m->event_msg); | 739 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, |
708 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); | 740 | m->bc_syncpt, inputq); |
709 | __skb_queue_tail(inputq, m->event_msg); | ||
710 | } | 741 | } |
711 | list_del_init(&m->small_win); | 742 | list_del_init(&m->small_win); |
712 | tipc_group_update_member(m, 0); | 743 | tipc_group_update_member(m, 0); |
@@ -725,10 +756,9 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
725 | m->state = MBR_LEAVING; | 756 | m->state = MBR_LEAVING; |
726 | return; | 757 | return; |
727 | } | 758 | } |
728 | /* Otherwise deliver already received WITHDRAW event */ | 759 | /* Otherwise deliver member WITHDRAW event */ |
729 | ehdr = buf_msg(m->event_msg); | 760 | tipc_group_create_event(grp, m, TIPC_WITHDRAWN, |
730 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); | 761 | m->bc_syncpt, inputq); |
731 | __skb_queue_tail(inputq, m->event_msg); | ||
732 | return; | 762 | return; |
733 | case GRP_ADV_MSG: | 763 | case GRP_ADV_MSG: |
734 | if (!m) | 764 | if (!m) |
@@ -797,11 +827,10 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
797 | void tipc_group_member_evt(struct tipc_group *grp, | 827 | void tipc_group_member_evt(struct tipc_group *grp, |
798 | bool *usr_wakeup, | 828 | bool *usr_wakeup, |
799 | int *sk_rcvbuf, | 829 | int *sk_rcvbuf, |
800 | struct sk_buff *skb, | 830 | struct tipc_msg *hdr, |
801 | struct sk_buff_head *inputq, | 831 | struct sk_buff_head *inputq, |
802 | struct sk_buff_head *xmitq) | 832 | struct sk_buff_head *xmitq) |
803 | { | 833 | { |
804 | struct tipc_msg *hdr = buf_msg(skb); | ||
805 | struct tipc_event *evt = (void *)msg_data(hdr); | 834 | struct tipc_event *evt = (void *)msg_data(hdr); |
806 | u32 instance = evt->found_lower; | 835 | u32 instance = evt->found_lower; |
807 | u32 node = evt->port.node; | 836 | u32 node = evt->port.node; |
@@ -813,21 +842,12 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
813 | u32 self; | 842 | u32 self; |
814 | 843 | ||
815 | if (!grp) | 844 | if (!grp) |
816 | goto drop; | 845 | return; |
817 | 846 | ||
818 | net = grp->net; | 847 | net = grp->net; |
819 | self = tipc_own_addr(net); | 848 | self = tipc_own_addr(net); |
820 | if (!grp->loopback && node == self && port == grp->portid) | 849 | if (!grp->loopback && node == self && port == grp->portid) |
821 | goto drop; | 850 | return; |
822 | |||
823 | /* Convert message before delivery to user */ | ||
824 | msg_set_hdr_sz(hdr, GROUP_H_SIZE); | ||
825 | msg_set_user(hdr, TIPC_CRITICAL_IMPORTANCE); | ||
826 | msg_set_type(hdr, TIPC_GRP_MEMBER_EVT); | ||
827 | msg_set_origport(hdr, port); | ||
828 | msg_set_orignode(hdr, node); | ||
829 | msg_set_nametype(hdr, grp->type); | ||
830 | msg_set_grp_evt(hdr, event); | ||
831 | 851 | ||
832 | m = tipc_group_find_member(grp, node, port); | 852 | m = tipc_group_find_member(grp, node, port); |
833 | 853 | ||
@@ -836,59 +856,52 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
836 | m = tipc_group_create_member(grp, node, port, | 856 | m = tipc_group_create_member(grp, node, port, |
837 | MBR_DISCOVERED); | 857 | MBR_DISCOVERED); |
838 | if (!m) | 858 | if (!m) |
839 | goto drop; | 859 | return; |
860 | |||
861 | m->instance = instance; | ||
840 | 862 | ||
841 | /* Hold back event if JOIN message not yet received */ | 863 | /* Hold back event if JOIN message not yet received */ |
842 | if (m->state == MBR_DISCOVERED) { | 864 | if (m->state == MBR_DISCOVERED) { |
843 | m->event_msg = skb; | ||
844 | m->state = MBR_PUBLISHED; | 865 | m->state = MBR_PUBLISHED; |
845 | } else { | 866 | } else { |
846 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | 867 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, |
847 | __skb_queue_tail(inputq, skb); | 868 | m->bc_syncpt, inputq); |
848 | m->state = MBR_JOINED; | 869 | m->state = MBR_JOINED; |
849 | *usr_wakeup = true; | 870 | *usr_wakeup = true; |
850 | m->usr_pending = false; | 871 | m->usr_pending = false; |
851 | } | 872 | } |
852 | m->instance = instance; | ||
853 | TIPC_SKB_CB(skb)->orig_member = m->instance; | ||
854 | tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq); | 873 | tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq); |
855 | tipc_group_update_member(m, 0); | 874 | tipc_group_update_member(m, 0); |
856 | } else if (event == TIPC_WITHDRAWN) { | 875 | } else if (event == TIPC_WITHDRAWN) { |
857 | if (!m) | 876 | if (!m) |
858 | goto drop; | 877 | return; |
859 | |||
860 | TIPC_SKB_CB(skb)->orig_member = m->instance; | ||
861 | 878 | ||
862 | *usr_wakeup = true; | 879 | *usr_wakeup = true; |
863 | m->usr_pending = false; | 880 | m->usr_pending = false; |
864 | node_up = tipc_node_is_up(net, node); | 881 | node_up = tipc_node_is_up(net, node); |
865 | m->event_msg = NULL; | ||
866 | 882 | ||
867 | if (node_up) { | 883 | if (node_up) { |
868 | /* Hold back event if a LEAVE msg should be expected */ | 884 | /* Hold back event if a LEAVE msg should be expected */ |
869 | if (m->state != MBR_LEAVING) { | 885 | if (m->state != MBR_LEAVING) { |
870 | m->event_msg = skb; | ||
871 | tipc_group_decr_active(grp, m); | 886 | tipc_group_decr_active(grp, m); |
872 | m->state = MBR_LEAVING; | 887 | m->state = MBR_LEAVING; |
873 | } else { | 888 | } else { |
874 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | 889 | tipc_group_create_event(grp, m, TIPC_WITHDRAWN, |
875 | __skb_queue_tail(inputq, skb); | 890 | m->bc_syncpt, inputq); |
876 | } | 891 | } |
877 | } else { | 892 | } else { |
878 | if (m->state != MBR_LEAVING) { | 893 | if (m->state != MBR_LEAVING) { |
879 | tipc_group_decr_active(grp, m); | 894 | tipc_group_decr_active(grp, m); |
880 | m->state = MBR_LEAVING; | 895 | m->state = MBR_LEAVING; |
881 | msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); | 896 | tipc_group_create_event(grp, m, TIPC_WITHDRAWN, |
897 | m->bc_rcv_nxt, inputq); | ||
882 | } else { | 898 | } else { |
883 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | 899 | tipc_group_create_event(grp, m, TIPC_WITHDRAWN, |
900 | m->bc_syncpt, inputq); | ||
884 | } | 901 | } |
885 | __skb_queue_tail(inputq, skb); | ||
886 | } | 902 | } |
887 | list_del_init(&m->list); | 903 | list_del_init(&m->list); |
888 | list_del_init(&m->small_win); | 904 | list_del_init(&m->small_win); |
889 | } | 905 | } |
890 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); | 906 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); |
891 | return; | ||
892 | drop: | ||
893 | kfree_skb(skb); | ||
894 | } | 907 | } |
diff --git a/net/tipc/group.h b/net/tipc/group.h index d525e1cd7de5..5ffffd0121a2 100644 --- a/net/tipc/group.h +++ b/net/tipc/group.h | |||
@@ -54,7 +54,7 @@ void tipc_group_filter_msg(struct tipc_group *grp, | |||
54 | struct sk_buff_head *inputq, | 54 | struct sk_buff_head *inputq, |
55 | struct sk_buff_head *xmitq); | 55 | struct sk_buff_head *xmitq); |
56 | void tipc_group_member_evt(struct tipc_group *grp, bool *wakeup, | 56 | void tipc_group_member_evt(struct tipc_group *grp, bool *wakeup, |
57 | int *sk_rcvbuf, struct sk_buff *skb, | 57 | int *sk_rcvbuf, struct tipc_msg *hdr, |
58 | struct sk_buff_head *inputq, | 58 | struct sk_buff_head *inputq, |
59 | struct sk_buff_head *xmitq); | 59 | struct sk_buff_head *xmitq); |
60 | void tipc_group_proto_rcv(struct tipc_group *grp, bool *wakeup, | 60 | void tipc_group_proto_rcv(struct tipc_group *grp, bool *wakeup, |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index b51d5cba5094..36744ebef74f 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1933,8 +1933,7 @@ static void tipc_sk_proto_rcv(struct sock *sk, | |||
1933 | break; | 1933 | break; |
1934 | case TOP_SRV: | 1934 | case TOP_SRV: |
1935 | tipc_group_member_evt(tsk->group, &wakeup, &sk->sk_rcvbuf, | 1935 | tipc_group_member_evt(tsk->group, &wakeup, &sk->sk_rcvbuf, |
1936 | skb, inputq, xmitq); | 1936 | hdr, inputq, xmitq); |
1937 | skb = NULL; | ||
1938 | break; | 1937 | break; |
1939 | default: | 1938 | default: |
1940 | break; | 1939 | break; |