struct sk_buff_head *queue = &l->transmq;
        struct sk_buff_head tmpxq, tnlq;
        u16 pktlen, pktcnt, seqno = l->snd_nxt;
+       u16 syncpt;
 
        if (!tnl)
                return;
        tipc_link_xmit(l, &tnlq, &tmpxq);
        __skb_queue_purge(&tmpxq);
 
+       /* Link Synching:
+        * From now on, send only one single ("dummy") SYNCH message
+        * to peer. The SYNCH message does not contain any data, just
+        * a header conveying the synch point to the peer.
+        */
+       if (mtyp == SYNCH_MSG && (tnl->peer_caps & TIPC_TUNNEL_ENHANCED)) {
+               tnlskb = tipc_msg_create(TUNNEL_PROTOCOL, SYNCH_MSG,
+                                        INT_H_SIZE, 0, l->addr,
+                                        tipc_own_addr(l->net),
+                                        0, 0, 0);
+               if (!tnlskb) {
+                       pr_warn("%sunable to create dummy SYNCH_MSG\n",
+                               link_co_err);
+                       return;
+               }
+
+               hdr = buf_msg(tnlskb);
+               syncpt = l->snd_nxt + skb_queue_len(&l->backlogq) - 1;
+               msg_set_syncpt(hdr, syncpt);
+               msg_set_bearer_id(hdr, l->peer_bearer_id);
+               __skb_queue_tail(&tnlq, tnlskb);
+               tipc_link_xmit(tnl, &tnlq, xmitq);
+               return;
+       }
+
        /* Initialize reusable tunnel packet header */
        tipc_msg_init(tipc_own_addr(l->net), &tnlhdr, TUNNEL_PROTOCOL,
                      mtyp, INT_H_SIZE, l->addr);
 
        msg_set_bits(m, 9, 16, 0xffff, n);
 }
 
+static inline u16 msg_syncpt(struct tipc_msg *m)
+{
+       return msg_bits(m, 9, 16, 0xffff);
+}
+
+static inline void msg_set_syncpt(struct tipc_msg *m, u16 n)
+{
+       msg_set_bits(m, 9, 16, 0xffff, n);
+}
+
 static inline u32 msg_conn_ack(struct tipc_msg *m)
 {
        return msg_bits(m, 9, 16, 0xffff);
 
        int usr = msg_user(hdr);
        int mtyp = msg_type(hdr);
        u16 oseqno = msg_seqno(hdr);
-       u16 iseqno = msg_seqno(msg_inner_hdr(hdr));
        u16 exp_pkts = msg_msgcnt(hdr);
        u16 rcv_nxt, syncpt, dlv_nxt, inputq_len;
        int state = n->state;
 
        /* Initiate synch mode if applicable */
        if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG) && (oseqno == 1)) {
-               syncpt = iseqno + exp_pkts - 1;
+               if (n->capabilities & TIPC_TUNNEL_ENHANCED)
+                       syncpt = msg_syncpt(hdr);
+               else
+                       syncpt = msg_seqno(msg_inner_hdr(hdr)) + exp_pkts - 1;
                if (!tipc_link_is_up(l))
                        __tipc_node_link_up(n, bearer_id, xmitq);
                if (n->state == SELF_UP_PEER_UP) {
 
        TIPC_NODE_ID128       = (1 << 5),
        TIPC_LINK_PROTO_SEQNO = (1 << 6),
        TIPC_MCAST_RBCTL      = (1 << 7),
-       TIPC_GAP_ACK_BLOCK    = (1 << 8)
+       TIPC_GAP_ACK_BLOCK    = (1 << 8),
+       TIPC_TUNNEL_ENHANCED  = (1 << 9)
 };
 
 #define TIPC_NODE_CAPABILITIES (TIPC_SYN_BIT           |  \
                                TIPC_NODE_ID128        |   \
                                TIPC_LINK_PROTO_SEQNO  |   \
                                TIPC_MCAST_RBCTL       |   \
-                               TIPC_GAP_ACK_BLOCK)
+                               TIPC_GAP_ACK_BLOCK     |   \
+                               TIPC_TUNNEL_ENHANCED)
 #define INVALID_BEARER_ID -1
 
 void tipc_node_stop(struct net *net);