aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bearer.c5
-rw-r--r--net/tipc/group.c71
-rw-r--r--net/tipc/monitor.c6
-rw-r--r--net/tipc/server.c3
-rw-r--r--net/tipc/socket.c4
-rw-r--r--net/tipc/udp_media.c4
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,
109static void tipc_group_decr_active(struct tipc_group *grp, 109static 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
378rcu_out: 374rcu_out:
379 rcu_read_unlock(); 375 rcu_read_unlock();
380out: 376out: