struct sk_buff *next;
        unsigned int released = 0;
 
-       if (less_eq(acked, n_ptr->bclink.acked))
-               return;
-
        spin_lock_bh(&bc_lock);
 
-       /* Skip over packets that node has previously acknowledged */
-
+       /* Bail out if tx queue is empty (no clean up is required) */
        crs = bcl->first_out;
+       if (!crs)
+               goto exit;
+
+       /* Determine which messages need to be acknowledged */
+       if (acked == INVALID_LINK_SEQ) {
+               /*
+                * Contact with specified node has been lost, so need to
+                * acknowledge sent messages only (if other nodes still exist)
+                * or both sent and unsent messages (otherwise)
+                */
+               if (bclink->bcast_nodes.count)
+                       acked = bcl->fsm_msg_cnt;
+               else
+                       acked = bcl->next_out_no;
+       } else {
+               /*
+                * Bail out if specified sequence number does not correspond
+                * to a message that has been sent and not yet acknowledged
+                */
+               if (less(acked, buf_seqno(crs)) ||
+                   less(bcl->fsm_msg_cnt, acked) ||
+                   less_eq(acked, n_ptr->bclink.acked))
+                       goto exit;
+       }
+
+       /* Skip over packets that node has previously acknowledged */
        while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked))
                crs = crs->next;
 
 
                if (crs != bcl->next_out)
                        bcbuf_decr_acks(crs);
-               else if (bclink->bcast_nodes.count)
-                       break;
                else {
                        bcbuf_set_acks(crs, 0);
                        bcl->next_out = next;
        }
        if (unlikely(released && !list_empty(&bcl->waiting_ports)))
                tipc_link_wakeup_ports(bcl, 0);
+exit:
        spin_unlock_bh(&bc_lock);
 }
 
 
 
                /* Release acked messages */
 
-               if (less(n_ptr->bclink.acked, msg_bcast_ack(msg))) {
-                       if (tipc_node_is_up(n_ptr) && n_ptr->bclink.supported)
-                               tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg));
-               }
+               if (tipc_node_is_up(n_ptr) && n_ptr->bclink.supported)
+                       tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg));
 
                crs = l_ptr->first_out;
                while ((crs != l_ptr->next_out) &&
 
                }
 
                tipc_bclink_remove_node(n_ptr->addr);
-               tipc_bclink_acknowledge(n_ptr,
-                                       mod(n_ptr->bclink.acked + 10000));
+               tipc_bclink_acknowledge(n_ptr, INVALID_LINK_SEQ);
                if (n_ptr->addr < tipc_own_addr)
                        tipc_own_tag--;