__skb_queue_purge(list);
                return -EHOSTUNREACH;
        }
-
        /* Broadcast to all nodes */
        if (likely(bclink)) {
                tipc_bclink_lock(net);
 
  */
 
 #include "core.h"
+#include "subscr.h"
 #include "link.h"
 #include "bcast.h"
 #include "socket.h"
        msg_set_session(msg, (tn->random & 0xffff));
        msg_set_bearer_id(msg, b_ptr->identity);
        strcpy((char *)msg_data(msg), if_name);
-
-       l_ptr->priority = b_ptr->priority;
-       tipc_link_set_queue_limits(l_ptr, b_ptr->window);
-
        l_ptr->net_plane = b_ptr->net_plane;
        link_init_max_pkt(l_ptr);
+       l_ptr->priority = b_ptr->priority;
+       tipc_link_set_queue_limits(l_ptr, b_ptr->window);
 
        l_ptr->next_out_no = 1;
        __skb_queue_head_init(&l_ptr->transmq);
 {
        struct sk_buff *skb = skb_peek(list);
        struct tipc_msg *msg = buf_msg(skb);
-       uint imp = tipc_msg_tot_importance(msg);
+       int imp = msg_importance(msg);
        u32 oport = msg_tot_origport(msg);
 
        if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) {
 {
        struct tipc_msg *msg = buf_msg(skb_peek(list));
        unsigned int maxwin = link->window;
-       uint imp = tipc_msg_tot_importance(msg);
+       unsigned int imp = msg_importance(msg);
        uint mtu = link->max_pkt;
        uint ack = mod(link->next_in_no - 1);
        uint seqno = link->next_out_no;
        struct sk_buff_head *backlogq = &link->backlogq;
        struct sk_buff *skb, *tmp;
 
-       /* Match queue limits against msg importance: */
+       /* Match queue limit against msg importance: */
        if (unlikely(skb_queue_len(backlogq) >= link->queue_limit[imp]))
                return tipc_link_cong(link, list);
 
        l_ptr->abort_limit = tol / (jiffies_to_msecs(l_ptr->cont_intv) / 4);
 }
 
-void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
+void tipc_link_set_queue_limits(struct tipc_link *l, u32 win)
 {
-       l_ptr->window = window;
-
-       /* Data messages from this node, inclusive FIRST_FRAGM */
-       l_ptr->queue_limit[TIPC_LOW_IMPORTANCE] = window;
-       l_ptr->queue_limit[TIPC_MEDIUM_IMPORTANCE] = (window / 3) * 4;
-       l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE] = (window / 3) * 5;
-       l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE] = (window / 3) * 6;
-       /* Transiting data messages,inclusive FIRST_FRAGM */
-       l_ptr->queue_limit[TIPC_LOW_IMPORTANCE + 4] = 300;
-       l_ptr->queue_limit[TIPC_MEDIUM_IMPORTANCE + 4] = 600;
-       l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900;
-       l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200;
-       l_ptr->queue_limit[CONN_MANAGER] = 1200;
-       l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500;
-       l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000;
-       /* FRAGMENT and LAST_FRAGMENT packets */
-       l_ptr->queue_limit[MSG_FRAGMENTER] = 4000;
+       int max_bulk = TIPC_MAX_PUBLICATIONS / (l->max_pkt / ITEM_SIZE);
+
+       l->window = win;
+       l->queue_limit[TIPC_LOW_IMPORTANCE]      = win / 2;
+       l->queue_limit[TIPC_MEDIUM_IMPORTANCE]   = win;
+       l->queue_limit[TIPC_HIGH_IMPORTANCE]     = win / 2 * 3;
+       l->queue_limit[TIPC_CRITICAL_IMPORTANCE] = win * 2;
+       l->queue_limit[TIPC_SYSTEM_IMPORTANCE]   = max_bulk;
 }
 
 /* tipc_link_find_owner - locate owner node of link by link's name
 
                      FIRST_FRAGMENT, INT_H_SIZE, msg_destnode(mhdr));
        msg_set_size(&pkthdr, pktmax);
        msg_set_fragm_no(&pkthdr, pktno);
+       msg_set_importance(&pkthdr, msg_importance(mhdr));
 
        /* Prepare first fragment */
        skb = tipc_buf_acquire(pktmax);
                      int err)
 {
        struct tipc_msg *msg = buf_msg(buf);
-       uint imp = msg_importance(msg);
        struct tipc_msg ohdr;
        uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE);
 
        if (msg_errcode(msg))
                goto exit;
        memcpy(&ohdr, msg, msg_hdr_sz(msg));
-       imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE);
-       if (msg_isdata(msg))
-               msg_set_importance(msg, imp);
        msg_set_errcode(msg, err);
        msg_set_origport(msg, msg_destport(&ohdr));
        msg_set_destport(msg, msg_origport(&ohdr));
 
  * - TIPC_HIGH_IMPORTANCE
  * - TIPC_CRITICAL_IMPORTANCE
  */
+#define TIPC_SYSTEM_IMPORTANCE 4
+
 
 /*
  * Payload message types
 #define TIPC_NAMED_MSG         2
 #define TIPC_DIRECT_MSG                3
 
+/*
+ * Internal message users
+ */
+#define  BCAST_PROTOCOL       5
+#define  MSG_BUNDLER          6
+#define  LINK_PROTOCOL        7
+#define  CONN_MANAGER         8
+#define  CHANGEOVER_PROTOCOL  10
+#define  NAME_DISTRIBUTOR     11
+#define  MSG_FRAGMENTER       12
+#define  LINK_CONFIG          13
+#define  SOCK_WAKEUP          14       /* pseudo user */
+
 /*
  * Message header sizes
  */
        msg_set_bits(m, 0, 25, 0xf, n);
 }
 
-static inline u32 msg_importance(struct tipc_msg *m)
-{
-       return msg_bits(m, 0, 25, 0xf);
-}
-
-static inline void msg_set_importance(struct tipc_msg *m, u32 i)
-{
-       msg_set_user(m, i);
-}
-
 static inline u32 msg_hdr_sz(struct tipc_msg *m)
 {
        return msg_bits(m, 0, 21, 0xf) << 2;
 /*
  * Words 3-10
  */
+static inline u32 msg_importance(struct tipc_msg *m)
+{
+       if (unlikely(msg_user(m) == MSG_FRAGMENTER))
+               return msg_bits(m, 5, 13, 0x7);
+       if (likely(msg_isdata(m) && !msg_errcode(m)))
+               return msg_user(m);
+       return TIPC_SYSTEM_IMPORTANCE;
+}
+
+static inline void msg_set_importance(struct tipc_msg *m, u32 i)
+{
+       if (unlikely(msg_user(m) == MSG_FRAGMENTER))
+               msg_set_bits(m, 5, 13, 0x7, i);
+       else if (likely(i < TIPC_SYSTEM_IMPORTANCE))
+               msg_set_user(m, i);
+       else
+               pr_warn("Trying to set illegal importance in message\n");
+}
+
 static inline u32 msg_prevnode(struct tipc_msg *m)
 {
        return msg_word(m, 3);
  * Constants and routines used to read and write TIPC internal message headers
  */
 
-/*
- * Internal message users
- */
-#define  BCAST_PROTOCOL       5
-#define  MSG_BUNDLER          6
-#define  LINK_PROTOCOL        7
-#define  CONN_MANAGER         8
-#define  ROUTE_DISTRIBUTOR    9                /* obsoleted */
-#define  CHANGEOVER_PROTOCOL  10
-#define  NAME_DISTRIBUTOR     11
-#define  MSG_FRAGMENTER       12
-#define  LINK_CONFIG          13
-#define  SOCK_WAKEUP          14       /* pseudo user */
-
 /*
  *  Connection management protocol message types
  */
        msg_set_bits(m, 9, 0, 0xffff, n);
 }
 
-static inline u32 tipc_msg_tot_importance(struct tipc_msg *m)
-{
-       if ((msg_user(m) == MSG_FRAGMENTER) && (msg_type(m) == FIRST_FRAGMENT))
-               return msg_importance(msg_get_wrapped(m));
-       return msg_importance(m);
-}
-
 static inline u32 msg_tot_origport(struct tipc_msg *m)
 {
        if ((msg_user(m) == MSG_FRAGMENTER) && (msg_type(m) == FIRST_FRAGMENT))