diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/bearer.c | 5 | ||||
-rw-r--r-- | net/tipc/group.c | 71 | ||||
-rw-r--r-- | net/tipc/monitor.c | 6 | ||||
-rw-r--r-- | net/tipc/server.c | 3 | ||||
-rw-r--r-- | net/tipc/socket.c | 4 | ||||
-rw-r--r-- | net/tipc/udp_media.c | 4 |
6 files changed, 61 insertions, 32 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 47ec121574ce..c8001471da6c 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -324,6 +324,7 @@ restart: | |||
324 | if (res) { | 324 | if (res) { |
325 | pr_warn("Bearer <%s> rejected, enable failure (%d)\n", | 325 | pr_warn("Bearer <%s> rejected, enable failure (%d)\n", |
326 | name, -res); | 326 | name, -res); |
327 | kfree(b); | ||
327 | return -EINVAL; | 328 | return -EINVAL; |
328 | } | 329 | } |
329 | 330 | ||
@@ -347,8 +348,10 @@ restart: | |||
347 | if (skb) | 348 | if (skb) |
348 | tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); | 349 | tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); |
349 | 350 | ||
350 | if (tipc_mon_create(net, bearer_id)) | 351 | if (tipc_mon_create(net, bearer_id)) { |
352 | bearer_disable(net, b); | ||
351 | return -ENOMEM; | 353 | return -ENOMEM; |
354 | } | ||
352 | 355 | ||
353 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", | 356 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", |
354 | name, | 357 | name, |
diff --git a/net/tipc/group.c b/net/tipc/group.c index 12777cac638a..5f4ffae807ee 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c | |||
@@ -109,7 +109,8 @@ static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, | |||
109 | static void tipc_group_decr_active(struct tipc_group *grp, | 109 | static void tipc_group_decr_active(struct tipc_group *grp, |
110 | struct tipc_member *m) | 110 | struct tipc_member *m) |
111 | { | 111 | { |
112 | if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING) | 112 | if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING || |
113 | m->state == MBR_REMITTED) | ||
113 | grp->active_cnt--; | 114 | grp->active_cnt--; |
114 | } | 115 | } |
115 | 116 | ||
@@ -351,8 +352,7 @@ void tipc_group_update_member(struct tipc_member *m, int len) | |||
351 | if (m->window >= ADV_IDLE) | 352 | if (m->window >= ADV_IDLE) |
352 | return; | 353 | return; |
353 | 354 | ||
354 | if (!list_empty(&m->congested)) | 355 | list_del_init(&m->congested); |
355 | return; | ||
356 | 356 | ||
357 | /* Sort member into congested members' list */ | 357 | /* Sort member into congested members' list */ |
358 | list_for_each_entry_safe(_m, tmp, &grp->congested, congested) { | 358 | list_for_each_entry_safe(_m, tmp, &grp->congested, congested) { |
@@ -369,18 +369,20 @@ void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack) | |||
369 | u16 prev = grp->bc_snd_nxt - 1; | 369 | u16 prev = grp->bc_snd_nxt - 1; |
370 | struct tipc_member *m; | 370 | struct tipc_member *m; |
371 | struct rb_node *n; | 371 | struct rb_node *n; |
372 | u16 ackers = 0; | ||
372 | 373 | ||
373 | for (n = rb_first(&grp->members); n; n = rb_next(n)) { | 374 | for (n = rb_first(&grp->members); n; n = rb_next(n)) { |
374 | m = container_of(n, struct tipc_member, tree_node); | 375 | m = container_of(n, struct tipc_member, tree_node); |
375 | if (tipc_group_is_enabled(m)) { | 376 | if (tipc_group_is_enabled(m)) { |
376 | tipc_group_update_member(m, len); | 377 | tipc_group_update_member(m, len); |
377 | m->bc_acked = prev; | 378 | m->bc_acked = prev; |
379 | ackers++; | ||
378 | } | 380 | } |
379 | } | 381 | } |
380 | 382 | ||
381 | /* Mark number of acknowledges to expect, if any */ | 383 | /* Mark number of acknowledges to expect, if any */ |
382 | if (ack) | 384 | if (ack) |
383 | grp->bc_ackers = grp->member_cnt; | 385 | grp->bc_ackers = ackers; |
384 | grp->bc_snd_nxt++; | 386 | grp->bc_snd_nxt++; |
385 | } | 387 | } |
386 | 388 | ||
@@ -497,6 +499,7 @@ void tipc_group_filter_msg(struct tipc_group *grp, struct sk_buff_head *inputq, | |||
497 | while ((skb = skb_peek(defq))) { | 499 | while ((skb = skb_peek(defq))) { |
498 | hdr = buf_msg(skb); | 500 | hdr = buf_msg(skb); |
499 | mtyp = msg_type(hdr); | 501 | mtyp = msg_type(hdr); |
502 | blks = msg_blocks(hdr); | ||
500 | deliver = true; | 503 | deliver = true; |
501 | ack = false; | 504 | ack = false; |
502 | update = false; | 505 | update = false; |
@@ -546,7 +549,6 @@ void tipc_group_filter_msg(struct tipc_group *grp, struct sk_buff_head *inputq, | |||
546 | if (!update) | 549 | if (!update) |
547 | continue; | 550 | continue; |
548 | 551 | ||
549 | blks = msg_blocks(hdr); | ||
550 | tipc_group_update_rcv_win(grp, blks, node, port, xmitq); | 552 | tipc_group_update_rcv_win(grp, blks, node, port, xmitq); |
551 | } | 553 | } |
552 | return; | 554 | return; |
@@ -561,7 +563,7 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
561 | int max_active = grp->max_active; | 563 | int max_active = grp->max_active; |
562 | int reclaim_limit = max_active * 3 / 4; | 564 | int reclaim_limit = max_active * 3 / 4; |
563 | int active_cnt = grp->active_cnt; | 565 | int active_cnt = grp->active_cnt; |
564 | struct tipc_member *m, *rm; | 566 | struct tipc_member *m, *rm, *pm; |
565 | 567 | ||
566 | m = tipc_group_find_member(grp, node, port); | 568 | m = tipc_group_find_member(grp, node, port); |
567 | if (!m) | 569 | if (!m) |
@@ -604,6 +606,17 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
604 | pr_warn_ratelimited("Rcv unexpected msg after REMIT\n"); | 606 | pr_warn_ratelimited("Rcv unexpected msg after REMIT\n"); |
605 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 607 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
606 | } | 608 | } |
609 | grp->active_cnt--; | ||
610 | list_del_init(&m->list); | ||
611 | if (list_empty(&grp->pending)) | ||
612 | return; | ||
613 | |||
614 | /* Set oldest pending member to active and advertise */ | ||
615 | pm = list_first_entry(&grp->pending, struct tipc_member, list); | ||
616 | pm->state = MBR_ACTIVE; | ||
617 | list_move_tail(&pm->list, &grp->active); | ||
618 | grp->active_cnt++; | ||
619 | tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq); | ||
607 | break; | 620 | break; |
608 | case MBR_RECLAIMING: | 621 | case MBR_RECLAIMING: |
609 | case MBR_DISCOVERED: | 622 | case MBR_DISCOVERED: |
@@ -648,6 +661,7 @@ static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, | |||
648 | } else if (mtyp == GRP_REMIT_MSG) { | 661 | } else if (mtyp == GRP_REMIT_MSG) { |
649 | msg_set_grp_remitted(hdr, m->window); | 662 | msg_set_grp_remitted(hdr, m->window); |
650 | } | 663 | } |
664 | msg_set_dest_droppable(hdr, true); | ||
651 | __skb_queue_tail(xmitq, skb); | 665 | __skb_queue_tail(xmitq, skb); |
652 | } | 666 | } |
653 | 667 | ||
@@ -689,15 +703,16 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
689 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); | 703 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); |
690 | __skb_queue_tail(inputq, m->event_msg); | 704 | __skb_queue_tail(inputq, m->event_msg); |
691 | } | 705 | } |
692 | if (m->window < ADV_IDLE) | 706 | list_del_init(&m->congested); |
693 | tipc_group_update_member(m, 0); | 707 | tipc_group_update_member(m, 0); |
694 | else | ||
695 | list_del_init(&m->congested); | ||
696 | return; | 708 | return; |
697 | case GRP_LEAVE_MSG: | 709 | case GRP_LEAVE_MSG: |
698 | if (!m) | 710 | if (!m) |
699 | return; | 711 | return; |
700 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); | 712 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); |
713 | list_del_init(&m->list); | ||
714 | list_del_init(&m->congested); | ||
715 | *usr_wakeup = true; | ||
701 | 716 | ||
702 | /* Wait until WITHDRAW event is received */ | 717 | /* Wait until WITHDRAW event is received */ |
703 | if (m->state != MBR_LEAVING) { | 718 | if (m->state != MBR_LEAVING) { |
@@ -709,8 +724,6 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
709 | ehdr = buf_msg(m->event_msg); | 724 | ehdr = buf_msg(m->event_msg); |
710 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); | 725 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); |
711 | __skb_queue_tail(inputq, m->event_msg); | 726 | __skb_queue_tail(inputq, m->event_msg); |
712 | *usr_wakeup = true; | ||
713 | list_del_init(&m->congested); | ||
714 | return; | 727 | return; |
715 | case GRP_ADV_MSG: | 728 | case GRP_ADV_MSG: |
716 | if (!m) | 729 | if (!m) |
@@ -741,14 +754,14 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
741 | if (!m || m->state != MBR_RECLAIMING) | 754 | if (!m || m->state != MBR_RECLAIMING) |
742 | return; | 755 | return; |
743 | 756 | ||
744 | list_del_init(&m->list); | ||
745 | grp->active_cnt--; | ||
746 | remitted = msg_grp_remitted(hdr); | 757 | remitted = msg_grp_remitted(hdr); |
747 | 758 | ||
748 | /* Messages preceding the REMIT still in receive queue */ | 759 | /* Messages preceding the REMIT still in receive queue */ |
749 | if (m->advertised > remitted) { | 760 | if (m->advertised > remitted) { |
750 | m->state = MBR_REMITTED; | 761 | m->state = MBR_REMITTED; |
751 | in_flight = m->advertised - remitted; | 762 | in_flight = m->advertised - remitted; |
763 | m->advertised = ADV_IDLE + in_flight; | ||
764 | return; | ||
752 | } | 765 | } |
753 | /* All messages preceding the REMIT have been read */ | 766 | /* All messages preceding the REMIT have been read */ |
754 | if (m->advertised <= remitted) { | 767 | if (m->advertised <= remitted) { |
@@ -760,6 +773,8 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
760 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 773 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
761 | 774 | ||
762 | m->advertised = ADV_IDLE + in_flight; | 775 | m->advertised = ADV_IDLE + in_flight; |
776 | grp->active_cnt--; | ||
777 | list_del_init(&m->list); | ||
763 | 778 | ||
764 | /* Set oldest pending member to active and advertise */ | 779 | /* Set oldest pending member to active and advertise */ |
765 | if (list_empty(&grp->pending)) | 780 | if (list_empty(&grp->pending)) |
@@ -849,19 +864,29 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
849 | *usr_wakeup = true; | 864 | *usr_wakeup = true; |
850 | m->usr_pending = false; | 865 | m->usr_pending = false; |
851 | node_up = tipc_node_is_up(net, node); | 866 | node_up = tipc_node_is_up(net, node); |
852 | 867 | m->event_msg = NULL; | |
853 | /* Hold back event if more messages might be expected */ | 868 | |
854 | if (m->state != MBR_LEAVING && node_up) { | 869 | if (node_up) { |
855 | m->event_msg = skb; | 870 | /* Hold back event if a LEAVE msg should be expected */ |
856 | tipc_group_decr_active(grp, m); | 871 | if (m->state != MBR_LEAVING) { |
857 | m->state = MBR_LEAVING; | 872 | m->event_msg = skb; |
858 | } else { | 873 | tipc_group_decr_active(grp, m); |
859 | if (node_up) | 874 | m->state = MBR_LEAVING; |
875 | } else { | ||
860 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | 876 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); |
861 | else | 877 | __skb_queue_tail(inputq, skb); |
878 | } | ||
879 | } else { | ||
880 | if (m->state != MBR_LEAVING) { | ||
881 | tipc_group_decr_active(grp, m); | ||
882 | m->state = MBR_LEAVING; | ||
862 | msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); | 883 | msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); |
884 | } else { | ||
885 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | ||
886 | } | ||
863 | __skb_queue_tail(inputq, skb); | 887 | __skb_queue_tail(inputq, skb); |
864 | } | 888 | } |
889 | list_del_init(&m->list); | ||
865 | list_del_init(&m->congested); | 890 | list_del_init(&m->congested); |
866 | } | 891 | } |
867 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); | 892 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); |
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 8e884ed06d4b..32dc33a94bc7 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c | |||
@@ -642,9 +642,13 @@ void tipc_mon_delete(struct net *net, int bearer_id) | |||
642 | { | 642 | { |
643 | struct tipc_net *tn = tipc_net(net); | 643 | struct tipc_net *tn = tipc_net(net); |
644 | struct tipc_monitor *mon = tipc_monitor(net, bearer_id); | 644 | struct tipc_monitor *mon = tipc_monitor(net, bearer_id); |
645 | struct tipc_peer *self = get_self(net, bearer_id); | 645 | struct tipc_peer *self; |
646 | struct tipc_peer *peer, *tmp; | 646 | struct tipc_peer *peer, *tmp; |
647 | 647 | ||
648 | if (!mon) | ||
649 | return; | ||
650 | |||
651 | self = get_self(net, bearer_id); | ||
648 | write_lock_bh(&mon->lock); | 652 | write_lock_bh(&mon->lock); |
649 | tn->monitors[bearer_id] = NULL; | 653 | tn->monitors[bearer_id] = NULL; |
650 | list_for_each_entry_safe(peer, tmp, &self->list, list) { | 654 | list_for_each_entry_safe(peer, tmp, &self->list, list) { |
diff --git a/net/tipc/server.c b/net/tipc/server.c index acaef80fb88c..d60c30342327 100644 --- a/net/tipc/server.c +++ b/net/tipc/server.c | |||
@@ -314,6 +314,7 @@ static int tipc_accept_from_sock(struct tipc_conn *con) | |||
314 | newcon->usr_data = s->tipc_conn_new(newcon->conid); | 314 | newcon->usr_data = s->tipc_conn_new(newcon->conid); |
315 | if (!newcon->usr_data) { | 315 | if (!newcon->usr_data) { |
316 | sock_release(newsock); | 316 | sock_release(newsock); |
317 | conn_put(newcon); | ||
317 | return -ENOMEM; | 318 | return -ENOMEM; |
318 | } | 319 | } |
319 | 320 | ||
@@ -511,7 +512,7 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, | |||
511 | s = con->server; | 512 | s = con->server; |
512 | scbr = s->tipc_conn_new(*conid); | 513 | scbr = s->tipc_conn_new(*conid); |
513 | if (!scbr) { | 514 | if (!scbr) { |
514 | tipc_close_conn(con); | 515 | conn_put(con); |
515 | return false; | 516 | return false; |
516 | } | 517 | } |
517 | 518 | ||
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 5d18c0caa92b..3b4084480377 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -727,11 +727,11 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
727 | 727 | ||
728 | switch (sk->sk_state) { | 728 | switch (sk->sk_state) { |
729 | case TIPC_ESTABLISHED: | 729 | case TIPC_ESTABLISHED: |
730 | case TIPC_CONNECTING: | ||
730 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) | 731 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) |
731 | revents |= POLLOUT; | 732 | revents |= POLLOUT; |
732 | /* fall thru' */ | 733 | /* fall thru' */ |
733 | case TIPC_LISTEN: | 734 | case TIPC_LISTEN: |
734 | case TIPC_CONNECTING: | ||
735 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 735 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
736 | revents |= POLLIN | POLLRDNORM; | 736 | revents |= POLLIN | POLLRDNORM; |
737 | break; | 737 | break; |
@@ -1140,7 +1140,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, | |||
1140 | __skb_dequeue(arrvq); | 1140 | __skb_dequeue(arrvq); |
1141 | __skb_queue_tail(inputq, skb); | 1141 | __skb_queue_tail(inputq, skb); |
1142 | } | 1142 | } |
1143 | refcount_dec(&skb->users); | 1143 | kfree_skb(skb); |
1144 | spin_unlock_bh(&inputq->lock); | 1144 | spin_unlock_bh(&inputq->lock); |
1145 | continue; | 1145 | continue; |
1146 | } | 1146 | } |
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index ecca64fc6a6f..3deabcab4882 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c | |||
@@ -371,10 +371,6 @@ static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb) | |||
371 | goto rcu_out; | 371 | goto rcu_out; |
372 | } | 372 | } |
373 | 373 | ||
374 | tipc_rcv(sock_net(sk), skb, b); | ||
375 | rcu_read_unlock(); | ||
376 | return 0; | ||
377 | |||
378 | rcu_out: | 374 | rcu_out: |
379 | rcu_read_unlock(); | 375 | rcu_read_unlock(); |
380 | out: | 376 | out: |