dev_put(dev);
                return -EINVAL;
        }
+       if (dev == net->loopback_dev) {
+               dev_put(dev);
+               pr_info("Enabling <%s> not permitted\n", b->name);
+               return -EINVAL;
+       }
 
        /* Autoconfigure own node identity if needed */
        if (!tipc_own_id(net) && hwaddr_len <= NODE_ID_LEN) {
        }
 }
 
+void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts)
+{
+       struct net_device *dev = net->loopback_dev;
+       struct sk_buff *skb, *_skb;
+       int exp;
+
+       skb_queue_walk(pkts, _skb) {
+               skb = pskb_copy(_skb, GFP_ATOMIC);
+               if (!skb)
+                       continue;
+
+               exp = SKB_DATA_ALIGN(dev->hard_header_len - skb_headroom(skb));
+               if (exp > 0 && pskb_expand_head(skb, exp, 0, GFP_ATOMIC)) {
+                       kfree_skb(skb);
+                       continue;
+               }
+
+               skb_reset_network_header(skb);
+               dev_hard_header(skb, dev, ETH_P_TIPC, dev->dev_addr,
+                               dev->dev_addr, skb->len);
+               skb->dev = dev;
+               skb->pkt_type = PACKET_HOST;
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+               skb->protocol = eth_type_trans(skb, dev);
+               netif_rx_ni(skb);
+       }
+}
+
+static int tipc_loopback_rcv_pkt(struct sk_buff *skb, struct net_device *dev,
+                                struct packet_type *pt, struct net_device *od)
+{
+       consume_skb(skb);
+       return NET_RX_SUCCESS;
+}
+
+int tipc_attach_loopback(struct net *net)
+{
+       struct net_device *dev = net->loopback_dev;
+       struct tipc_net *tn = tipc_net(net);
+
+       if (!dev)
+               return -ENODEV;
+
+       dev_hold(dev);
+       tn->loopback_pt.dev = dev;
+       tn->loopback_pt.type = htons(ETH_P_TIPC);
+       tn->loopback_pt.func = tipc_loopback_rcv_pkt;
+       dev_add_pack(&tn->loopback_pt);
+       return 0;
+}
+
+void tipc_detach_loopback(struct net *net)
+{
+       struct tipc_net *tn = tipc_net(net);
+
+       dev_remove_pack(&tn->loopback_pt);
+       dev_put(net->loopback_dev);
+}
+
 /* Caller should hold rtnl_lock to protect the bearer */
 static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg,
                                struct tipc_bearer *bearer, int nlflags)
 
                      struct tipc_media_addr *dst);
 void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
                         struct sk_buff_head *xmitq);
+void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts);
+int tipc_attach_loopback(struct net *net);
+void tipc_detach_loopback(struct net *net);
+
+static inline void tipc_loopback_trace(struct net *net,
+                                      struct sk_buff_head *pkts)
+{
+       if (unlikely(dev_nit_active(net->loopback_dev)))
+               tipc_clone_to_loopback(net, pkts);
+}
 
 /* check if device MTU is too low for tipc headers */
 static inline bool tipc_mtu_bad(struct net_device *dev, unsigned int reserve)