Merge tag 'fixes-non-critical-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / net / tipc / link.c
index 77c7ccd..a4cf364 100644 (file)
@@ -40,7 +40,6 @@
 #include "socket.h"
 #include "name_distr.h"
 #include "discover.h"
-#include "config.h"
 #include "netlink.h"
 
 #include <linux/pkt_sched.h>
@@ -101,23 +100,20 @@ static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
  */
 #define START_CHANGEOVER 100000u
 
-static void link_handle_out_of_seq_msg(struct net *net,
-                                      struct tipc_link *l_ptr,
-                                      struct sk_buff *buf);
-static void tipc_link_proto_rcv(struct net *net, struct tipc_link *l_ptr,
-                               struct sk_buff *buf);
-static int  tipc_link_tunnel_rcv(struct net *net, struct tipc_node *n_ptr,
-                                struct sk_buff **buf);
+static void link_handle_out_of_seq_msg(struct tipc_link *link,
+                                      struct sk_buff *skb);
+static void tipc_link_proto_rcv(struct tipc_link *link,
+                               struct sk_buff *skb);
+static int  tipc_link_tunnel_rcv(struct tipc_node *node,
+                                struct sk_buff **skb);
 static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tol);
 static void link_state_event(struct tipc_link *l_ptr, u32 event);
 static void link_reset_statistics(struct tipc_link *l_ptr);
 static void link_print(struct tipc_link *l_ptr, const char *str);
 static void tipc_link_sync_xmit(struct tipc_link *l);
 static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf);
-static int tipc_link_input(struct net *net, struct tipc_link *l,
-                          struct sk_buff *buf);
-static int tipc_link_prepare_input(struct net *net, struct tipc_link *l,
-                                  struct sk_buff **buf);
+static void tipc_link_input(struct tipc_link *l, struct sk_buff *skb);
+static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb);
 
 /*
  *  Simple link routines
@@ -303,7 +299,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
 
        l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg;
        msg = l_ptr->pmsg;
-       tipc_msg_init(n_ptr->net, msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE,
+       tipc_msg_init(tn->own_addr, msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE,
                      l_ptr->addr);
        msg_set_size(msg, sizeof(l_ptr->proto_msg));
        msg_set_session(msg, (tn->random & 0xffff));
@@ -319,8 +315,9 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
        l_ptr->next_out_no = 1;
        __skb_queue_head_init(&l_ptr->outqueue);
        __skb_queue_head_init(&l_ptr->deferred_queue);
-       skb_queue_head_init(&l_ptr->waiting_sks);
-
+       skb_queue_head_init(&l_ptr->wakeupq);
+       skb_queue_head_init(&l_ptr->inputq);
+       skb_queue_head_init(&l_ptr->namedq);
        link_reset_statistics(l_ptr);
        tipc_node_attach_link(n_ptr, l_ptr);
        setup_timer(&l_ptr->timer, link_timeout, (unsigned long)l_ptr);
@@ -379,17 +376,16 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id,
 static bool link_schedule_user(struct tipc_link *link, u32 oport,
                               uint chain_sz, uint imp)
 {
-       struct net *net = link->owner->net;
-       struct tipc_net *tn = net_generic(net, tipc_net_id);
        struct sk_buff *buf;
 
-       buf = tipc_msg_create(net, SOCK_WAKEUP, 0, INT_H_SIZE, 0, tn->own_addr,
-                             tn->own_addr, oport, 0, 0);
+       buf = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0,
+                             link_own_addr(link), link_own_addr(link),
+                             oport, 0, 0);
        if (!buf)
                return false;
        TIPC_SKB_CB(buf)->chain_sz = chain_sz;
        TIPC_SKB_CB(buf)->chain_imp = imp;
-       skb_queue_tail(&link->waiting_sks, buf);
+       skb_queue_tail(&link->wakeupq, buf);
        link->stats.link_congs++;
        return true;
 }
@@ -400,17 +396,19 @@ static bool link_schedule_user(struct tipc_link *link, u32 oport,
  * Move a number of waiting users, as permitted by available space in
  * the send queue, from link wait queue to node wait queue for wakeup
  */
-static void link_prepare_wakeup(struct tipc_link *link)
+void link_prepare_wakeup(struct tipc_link *link)
 {
        uint pend_qsz = skb_queue_len(&link->outqueue);
        struct sk_buff *skb, *tmp;
 
-       skb_queue_walk_safe(&link->waiting_sks, skb, tmp) {
+       skb_queue_walk_safe(&link->wakeupq, skb, tmp) {
                if (pend_qsz >= link->queue_limit[TIPC_SKB_CB(skb)->chain_imp])
                        break;
                pend_qsz += TIPC_SKB_CB(skb)->chain_sz;
-               skb_unlink(skb, &link->waiting_sks);
-               skb_queue_tail(&link->owner->waiting_sks, skb);
+               skb_unlink(skb, &link->wakeupq);
+               skb_queue_tail(&link->inputq, skb);
+               link->owner->inputq = &link->inputq;
+               link->owner->action_flags |= TIPC_MSG_EVT;
        }
 }
 
@@ -463,13 +461,13 @@ void tipc_link_reset(struct tipc_link *l_ptr)
                l_ptr->exp_msg_count = START_CHANGEOVER;
        }
 
-       /* Clean up all queues: */
+       /* Clean up all queues, except inputq: */
        __skb_queue_purge(&l_ptr->outqueue);
        __skb_queue_purge(&l_ptr->deferred_queue);
-       if (!skb_queue_empty(&l_ptr->waiting_sks)) {
-               skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks);
-               owner->action_flags |= TIPC_WAKEUP_USERS;
-       }
+       skb_queue_splice_init(&l_ptr->wakeupq, &l_ptr->inputq);
+       if (!skb_queue_empty(&l_ptr->inputq))
+               owner->action_flags |= TIPC_MSG_EVT;
+       owner->inputq = &l_ptr->inputq;
        l_ptr->next_out = NULL;
        l_ptr->unacked_window = 0;
        l_ptr->checkpoint = 1;
@@ -778,7 +776,7 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
                } else if (tipc_msg_bundle(outqueue, skb, mtu)) {
                        link->stats.sent_bundled++;
                        continue;
-               } else if (tipc_msg_make_bundle(net, outqueue, skb, mtu,
+               } else if (tipc_msg_make_bundle(outqueue, skb, mtu,
                                                link->addr)) {
                        link->stats.sent_bundled++;
                        link->stats.sent_bundles++;
@@ -797,7 +795,7 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
 
 static void skb2list(struct sk_buff *skb, struct sk_buff_head *list)
 {
-       __skb_queue_head_init(list);
+       skb_queue_head_init(list);
        __skb_queue_tail(list, skb);
 }
 
@@ -843,19 +841,13 @@ int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
                        rc = __tipc_link_xmit(net, link, list);
                tipc_node_unlock(node);
        }
-
        if (link)
                return rc;
 
-       if (likely(in_own_node(net, dnode))) {
-               /* As a node local message chain never contains more than one
-                * buffer, we just need to dequeue one SKB buffer from the
-                * head list.
-                */
-               return tipc_sk_rcv(net, __skb_dequeue(list));
-       }
-       __skb_queue_purge(list);
+       if (likely(in_own_node(net, dnode)))
+               return tipc_sk_rcv(net, list);
 
+       __skb_queue_purge(list);
        return rc;
 }
 
@@ -877,7 +869,7 @@ static void tipc_link_sync_xmit(struct tipc_link *link)
                return;
 
        msg = buf_msg(skb);
-       tipc_msg_init(link->owner->net, msg, BCAST_PROTOCOL, STATE_MSG,
+       tipc_msg_init(link_own_addr(link), msg, BCAST_PROTOCOL, STATE_MSG,
                      INT_H_SIZE, link->addr);
        msg_set_last_bcast(msg, link->owner->bclink.acked);
        __tipc_link_xmit_skb(link, skb);
@@ -1164,7 +1156,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
                /* Locate unicast link endpoint that should handle message */
                l_ptr = n_ptr->links[b_ptr->identity];
                if (unlikely(!l_ptr))
-                       goto unlock_discard;
+                       goto unlock;
 
                /* Verify that communication with node is currently allowed */
                if ((n_ptr->action_flags & TIPC_WAIT_PEER_LINKS_DOWN) &&
@@ -1175,7 +1167,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
                        n_ptr->action_flags &= ~TIPC_WAIT_PEER_LINKS_DOWN;
 
                if (tipc_node_blocked(n_ptr))
-                       goto unlock_discard;
+                       goto unlock;
 
                /* Validate message sequence number info */
                seq_no = msg_seqno(msg);
@@ -1199,18 +1191,16 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
                if (unlikely(l_ptr->next_out))
                        tipc_link_push_packets(l_ptr);
 
-               if (released && !skb_queue_empty(&l_ptr->waiting_sks)) {
+               if (released && !skb_queue_empty(&l_ptr->wakeupq))
                        link_prepare_wakeup(l_ptr);
-                       l_ptr->owner->action_flags |= TIPC_WAKEUP_USERS;
-               }
 
                /* Process the incoming packet */
                if (unlikely(!link_working_working(l_ptr))) {
                        if (msg_user(msg) == LINK_PROTOCOL) {
-                               tipc_link_proto_rcv(net, l_ptr, skb);
+                               tipc_link_proto_rcv(l_ptr, skb);
                                link_retrieve_defq(l_ptr, &head);
-                               tipc_node_unlock(n_ptr);
-                               continue;
+                               skb = NULL;
+                               goto unlock;
                        }
 
                        /* Traffic message. Conditionally activate link */
@@ -1219,18 +1209,18 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
                        if (link_working_working(l_ptr)) {
                                /* Re-insert buffer in front of queue */
                                __skb_queue_head(&head, skb);
-                               tipc_node_unlock(n_ptr);
-                               continue;
+                               skb = NULL;
+                               goto unlock;
                        }
-                       goto unlock_discard;
+                       goto unlock;
                }
 
                /* Link is now in state WORKING_WORKING */
                if (unlikely(seq_no != mod(l_ptr->next_in_no))) {
-                       link_handle_out_of_seq_msg(net, l_ptr, skb);
+                       link_handle_out_of_seq_msg(l_ptr, skb);
                        link_retrieve_defq(l_ptr, &head);
-                       tipc_node_unlock(n_ptr);
-                       continue;
+                       skb = NULL;
+                       goto unlock;
                }
                l_ptr->next_in_no++;
                if (unlikely(!skb_queue_empty(&l_ptr->deferred_queue)))
@@ -1240,97 +1230,102 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
                        l_ptr->stats.sent_acks++;
                        tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
                }
-
-               if (tipc_link_prepare_input(net, l_ptr, &skb)) {
-                       tipc_node_unlock(n_ptr);
-                       continue;
-               }
-               tipc_node_unlock(n_ptr);
-
-               if (tipc_link_input(net, l_ptr, skb) != 0)
-                       goto discard;
-               continue;
-unlock_discard:
+               tipc_link_input(l_ptr, skb);
+               skb = NULL;
+unlock:
                tipc_node_unlock(n_ptr);
 discard:
-               kfree_skb(skb);
+               if (unlikely(skb))
+                       kfree_skb(skb);
        }
 }
 
-/**
- * tipc_link_prepare_input - process TIPC link messages
- *
- * returns nonzero if the message was consumed
+/* tipc_data_input - deliver data and name distr msgs to upper layer
  *
+ * Consumes buffer if message is of right type
  * Node lock must be held
  */
-static int tipc_link_prepare_input(struct net *net, struct tipc_link *l,
-                                  struct sk_buff **buf)
+static bool tipc_data_input(struct tipc_link *link, struct sk_buff *skb)
 {
-       struct tipc_node *n;
-       struct tipc_msg *msg;
-       int res = -EINVAL;
+       struct tipc_node *node = link->owner;
+       struct tipc_msg *msg = buf_msg(skb);
+       u32 dport = msg_destport(msg);
 
-       n = l->owner;
-       msg = buf_msg(*buf);
        switch (msg_user(msg)) {
-       case CHANGEOVER_PROTOCOL:
-               if (tipc_link_tunnel_rcv(net, n, buf))
-                       res = 0;
-               break;
-       case MSG_FRAGMENTER:
-               l->stats.recv_fragments++;
-               if (tipc_buf_append(&l->reasm_buf, buf)) {
-                       l->stats.recv_fragmented++;
-                       res = 0;
-               } else if (!l->reasm_buf) {
-                       tipc_link_reset(l);
+       case TIPC_LOW_IMPORTANCE:
+       case TIPC_MEDIUM_IMPORTANCE:
+       case TIPC_HIGH_IMPORTANCE:
+       case TIPC_CRITICAL_IMPORTANCE:
+       case CONN_MANAGER:
+               if (tipc_skb_queue_tail(&link->inputq, skb, dport)) {
+                       node->inputq = &link->inputq;
+                       node->action_flags |= TIPC_MSG_EVT;
                }
-               break;
-       case MSG_BUNDLER:
-               l->stats.recv_bundles++;
-               l->stats.recv_bundled += msg_msgcnt(msg);
-               res = 0;
-               break;
+               return true;
        case NAME_DISTRIBUTOR:
-               n->bclink.recv_permitted = true;
-               res = 0;
-               break;
+               node->bclink.recv_permitted = true;
+               node->namedq = &link->namedq;
+               skb_queue_tail(&link->namedq, skb);
+               if (skb_queue_len(&link->namedq) == 1)
+                       node->action_flags |= TIPC_NAMED_MSG_EVT;
+               return true;
+       case MSG_BUNDLER:
+       case CHANGEOVER_PROTOCOL:
+       case MSG_FRAGMENTER:
        case BCAST_PROTOCOL:
-               tipc_link_sync_rcv(n, *buf);
-               break;
+               return false;
        default:
-               res = 0;
-       }
-       return res;
+               pr_warn("Dropping received illegal msg type\n");
+               kfree_skb(skb);
+               return false;
+       };
 }
-/**
- * tipc_link_input - Deliver message too higher layers
+
+/* tipc_link_input - process packet that has passed link protocol check
+ *
+ * Consumes buffer
+ * Node lock must be held
  */
-static int tipc_link_input(struct net *net, struct tipc_link *l,
-                          struct sk_buff *buf)
+static void tipc_link_input(struct tipc_link *link, struct sk_buff *skb)
 {
-       struct tipc_msg *msg = buf_msg(buf);
-       int res = 0;
+       struct tipc_node *node = link->owner;
+       struct tipc_msg *msg = buf_msg(skb);
+       struct sk_buff *iskb;
+       int pos = 0;
+
+       if (likely(tipc_data_input(link, skb)))
+               return;
 
        switch (msg_user(msg)) {
-       case TIPC_LOW_IMPORTANCE:
-       case TIPC_MEDIUM_IMPORTANCE:
-       case TIPC_HIGH_IMPORTANCE:
-       case TIPC_CRITICAL_IMPORTANCE:
-       case CONN_MANAGER:
-               tipc_sk_rcv(net, buf);
+       case CHANGEOVER_PROTOCOL:
+               if (!tipc_link_tunnel_rcv(node, &skb))
+                       break;
+               if (msg_user(buf_msg(skb)) != MSG_BUNDLER) {
+                       tipc_data_input(link, skb);
+                       break;
+               }
+       case MSG_BUNDLER:
+               link->stats.recv_bundles++;
+               link->stats.recv_bundled += msg_msgcnt(msg);
+
+               while (tipc_msg_extract(skb, &iskb, &pos))
+                       tipc_data_input(link, iskb);
                break;
-       case NAME_DISTRIBUTOR:
-               tipc_named_rcv(net, buf);
+       case MSG_FRAGMENTER:
+               link->stats.recv_fragments++;
+               if (tipc_buf_append(&link->reasm_buf, &skb)) {
+                       link->stats.recv_fragmented++;
+                       tipc_data_input(link, skb);
+               } else if (!link->reasm_buf) {
+                       tipc_link_reset(link);
+               }
                break;
-       case MSG_BUNDLER:
-               tipc_link_bundle_rcv(net, buf);
+       case BCAST_PROTOCOL:
+               tipc_link_sync_rcv(node, skb);
                break;
        default:
-               res = -EINVAL;
-       }
-       return res;
+               break;
+       };
 }
 
 /**
@@ -1375,14 +1370,13 @@ u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *skb)
 /*
  * link_handle_out_of_seq_msg - handle arrival of out-of-sequence packet
  */
-static void link_handle_out_of_seq_msg(struct net *net,
-                                      struct tipc_link *l_ptr,
+static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
                                       struct sk_buff *buf)
 {
        u32 seq_no = buf_seqno(buf);
 
        if (likely(msg_user(buf_msg(buf)) == LINK_PROTOCOL)) {
-               tipc_link_proto_rcv(net, l_ptr, buf);
+               tipc_link_proto_rcv(l_ptr, buf);
                return;
        }
 
@@ -1507,10 +1501,9 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
  * Note that network plane id propagates through the network, and may
  * change at any time. The node with lowest address rules
  */
-static void tipc_link_proto_rcv(struct net *net, struct tipc_link *l_ptr,
+static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
                                struct sk_buff *buf)
 {
-       struct tipc_net *tn = net_generic(net, tipc_net_id);
        u32 rec_gap = 0;
        u32 max_pkt_info;
        u32 max_pkt_ack;
@@ -1522,7 +1515,7 @@ static void tipc_link_proto_rcv(struct net *net, struct tipc_link *l_ptr,
                goto exit;
 
        if (l_ptr->net_plane != msg_net_plane(msg))
-               if (tn->own_addr > msg_prevnode(msg))
+               if (link_own_addr(l_ptr) > msg_prevnode(msg))
                        l_ptr->net_plane = msg_net_plane(msg);
 
        switch (msg_type(msg)) {
@@ -1625,7 +1618,7 @@ static void tipc_link_proto_rcv(struct net *net, struct tipc_link *l_ptr,
 
                /* Protocol message before retransmits, reduce loss risk */
                if (l_ptr->owner->bclink.recv_permitted)
-                       tipc_bclink_update_link_state(net, l_ptr->owner,
+                       tipc_bclink_update_link_state(l_ptr->owner,
                                                      msg_last_bcast(msg));
 
                if (rec_gap || (msg_probe(msg))) {
@@ -1690,7 +1683,7 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
        if (!tunnel)
                return;
 
-       tipc_msg_init(l_ptr->owner->net, &tunnel_hdr, CHANGEOVER_PROTOCOL,
+       tipc_msg_init(link_own_addr(l_ptr), &tunnel_hdr, CHANGEOVER_PROTOCOL,
                      ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr);
        msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
        msg_set_msgcnt(&tunnel_hdr, msgcount);
@@ -1748,7 +1741,7 @@ void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr,
        struct sk_buff *skb;
        struct tipc_msg tunnel_hdr;
 
-       tipc_msg_init(l_ptr->owner->net, &tunnel_hdr, CHANGEOVER_PROTOCOL,
+       tipc_msg_init(link_own_addr(l_ptr), &tunnel_hdr, CHANGEOVER_PROTOCOL,
                      DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr);
        msg_set_msgcnt(&tunnel_hdr, skb_queue_len(&l_ptr->outqueue));
        msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
@@ -1783,7 +1776,7 @@ void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr,
  * @from_pos: offset to extract from
  *
  * Returns a new message buffer containing an embedded message.  The
- * encapsulating message itself is left unchanged.
+ * encapsulating buffer is left unchanged.
  */
 static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos)
 {
@@ -1797,12 +1790,10 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos)
        return eb;
 }
 
-
-
 /* tipc_link_dup_rcv(): Receive a tunnelled DUPLICATE_MSG packet.
  * Owner node is locked.
  */
-static void tipc_link_dup_rcv(struct net *net, struct tipc_link *l_ptr,
+static void tipc_link_dup_rcv(struct tipc_link *l_ptr,
                              struct sk_buff *t_buf)
 {
        struct sk_buff *buf;
@@ -1817,7 +1808,7 @@ static void tipc_link_dup_rcv(struct net *net, struct tipc_link *l_ptr,
        }
 
        /* Add buffer to deferred queue, if applicable: */
-       link_handle_out_of_seq_msg(net, l_ptr, buf);
+       link_handle_out_of_seq_msg(l_ptr, buf);
 }
 
 /*  tipc_link_failover_rcv(): Receive a tunnelled ORIGINAL_MSG packet
@@ -1869,7 +1860,7 @@ exit:
  *  returned to the active link for delivery upwards.
  *  Owner node is locked.
  */
-static int tipc_link_tunnel_rcv(struct net *net, struct tipc_node *n_ptr,
+static int tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
                                struct sk_buff **buf)
 {
        struct sk_buff *t_buf = *buf;
@@ -1887,7 +1878,7 @@ static int tipc_link_tunnel_rcv(struct net *net, struct tipc_node *n_ptr,
                goto exit;
 
        if (msg_type(t_msg) == DUPLICATE_MSG)
-               tipc_link_dup_rcv(net, l_ptr, t_buf);
+               tipc_link_dup_rcv(l_ptr, t_buf);
        else if (msg_type(t_msg) == ORIGINAL_MSG)
                *buf = tipc_link_failover_rcv(l_ptr, t_buf);
        else
@@ -1897,41 +1888,6 @@ exit:
        return *buf != NULL;
 }
 
-/*
- *  Bundler functionality:
- */
-void tipc_link_bundle_rcv(struct net *net, struct sk_buff *buf)
-{
-       u32 msgcount = msg_msgcnt(buf_msg(buf));
-       u32 pos = INT_H_SIZE;
-       struct sk_buff *obuf;
-       struct tipc_msg *omsg;
-
-       while (msgcount--) {
-               obuf = buf_extract(buf, pos);
-               if (obuf == NULL) {
-                       pr_warn("Link unable to unbundle message(s)\n");
-                       break;
-               }
-               omsg = buf_msg(obuf);
-               pos += align(msg_size(omsg));
-               if (msg_isdata(omsg)) {
-                       if (unlikely(msg_type(omsg) == TIPC_MCAST_MSG))
-                               tipc_sk_mcast_rcv(net, obuf);
-                       else
-                               tipc_sk_rcv(net, obuf);
-               } else if (msg_user(omsg) == CONN_MANAGER) {
-                       tipc_sk_rcv(net, obuf);
-               } else if (msg_user(omsg) == NAME_DISTRIBUTOR) {
-                       tipc_named_rcv(net, obuf);
-               } else {
-                       pr_warn("Illegal bundled msg: %u\n", msg_user(omsg));
-                       kfree_skb(obuf);
-               }
-       }
-       kfree_skb(buf);
-}
-
 static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tol)
 {
        unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
@@ -2001,150 +1957,6 @@ static struct tipc_node *tipc_link_find_owner(struct net *net,
        return found_node;
 }
 
-/**
- * link_value_is_valid -- validate proposed link tolerance/priority/window
- *
- * @cmd: value type (TIPC_CMD_SET_LINK_*)
- * @new_value: the new value
- *
- * Returns 1 if value is within range, 0 if not.
- */
-static int link_value_is_valid(u16 cmd, u32 new_value)
-{
-       switch (cmd) {
-       case TIPC_CMD_SET_LINK_TOL:
-               return (new_value >= TIPC_MIN_LINK_TOL) &&
-                       (new_value <= TIPC_MAX_LINK_TOL);
-       case TIPC_CMD_SET_LINK_PRI:
-               return (new_value <= TIPC_MAX_LINK_PRI);
-       case TIPC_CMD_SET_LINK_WINDOW:
-               return (new_value >= TIPC_MIN_LINK_WIN) &&
-                       (new_value <= TIPC_MAX_LINK_WIN);
-       }
-       return 0;
-}
-
-/**
- * link_cmd_set_value - change priority/tolerance/window for link/bearer/media
- * @net: the applicable net namespace
- * @name: ptr to link, bearer, or media name
- * @new_value: new value of link, bearer, or media setting
- * @cmd: which link, bearer, or media attribute to set (TIPC_CMD_SET_LINK_*)
- *
- * Caller must hold RTNL lock to ensure link/bearer/media is not deleted.
- *
- * Returns 0 if value updated and negative value on error.
- */
-static int link_cmd_set_value(struct net *net, const char *name, u32 new_value,
-                             u16 cmd)
-{
-       struct tipc_node *node;
-       struct tipc_link *l_ptr;
-       struct tipc_bearer *b_ptr;
-       struct tipc_media *m_ptr;
-       int bearer_id;
-       int res = 0;
-
-       node = tipc_link_find_owner(net, name, &bearer_id);
-       if (node) {
-               tipc_node_lock(node);
-               l_ptr = node->links[bearer_id];
-
-               if (l_ptr) {
-                       switch (cmd) {
-                       case TIPC_CMD_SET_LINK_TOL:
-                               link_set_supervision_props(l_ptr, new_value);
-                               tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0,
-                                                    new_value, 0, 0);
-                               break;
-                       case TIPC_CMD_SET_LINK_PRI:
-                               l_ptr->priority = new_value;
-                               tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0,
-                                                    0, new_value, 0);
-                               break;
-                       case TIPC_CMD_SET_LINK_WINDOW:
-                               tipc_link_set_queue_limits(l_ptr, new_value);
-                               break;
-                       default:
-                               res = -EINVAL;
-                               break;
-                       }
-               }
-               tipc_node_unlock(node);
-               return res;
-       }
-
-       b_ptr = tipc_bearer_find(net, name);
-       if (b_ptr) {
-               switch (cmd) {
-               case TIPC_CMD_SET_LINK_TOL:
-                       b_ptr->tolerance = new_value;
-                       break;
-               case TIPC_CMD_SET_LINK_PRI:
-                       b_ptr->priority = new_value;
-                       break;
-               case TIPC_CMD_SET_LINK_WINDOW:
-                       b_ptr->window = new_value;
-                       break;
-               default:
-                       res = -EINVAL;
-                       break;
-               }
-               return res;
-       }
-
-       m_ptr = tipc_media_find(name);
-       if (!m_ptr)
-               return -ENODEV;
-       switch (cmd) {
-       case TIPC_CMD_SET_LINK_TOL:
-               m_ptr->tolerance = new_value;
-               break;
-       case TIPC_CMD_SET_LINK_PRI:
-               m_ptr->priority = new_value;
-               break;
-       case TIPC_CMD_SET_LINK_WINDOW:
-               m_ptr->window = new_value;
-               break;
-       default:
-               res = -EINVAL;
-               break;
-       }
-       return res;
-}
-
-struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area,
-                                    int req_tlv_space, u16 cmd)
-{
-       struct tipc_link_config *args;
-       u32 new_value;
-       int res;
-
-       if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_CONFIG))
-               return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
-
-       args = (struct tipc_link_config *)TLV_DATA(req_tlv_area);
-       new_value = ntohl(args->value);
-
-       if (!link_value_is_valid(cmd, new_value))
-               return tipc_cfg_reply_error_string(
-                       "cannot change, value invalid");
-
-       if (!strcmp(args->name, tipc_bclink_name)) {
-               if ((cmd == TIPC_CMD_SET_LINK_WINDOW) &&
-                   (tipc_bclink_set_queue_limits(net, new_value) == 0))
-                       return tipc_cfg_reply_none();
-               return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
-                                                  " (cannot change setting on broadcast link)");
-       }
-
-       res = link_cmd_set_value(net, args->name, new_value, cmd);
-       if (res)
-               return tipc_cfg_reply_error_string("cannot change link setting");
-
-       return tipc_cfg_reply_none();
-}
-
 /**
  * link_reset_statistics - reset link statistics
  * @l_ptr: pointer to link
@@ -2156,180 +1968,6 @@ static void link_reset_statistics(struct tipc_link *l_ptr)
        l_ptr->stats.recv_info = l_ptr->next_in_no;
 }
 
-struct sk_buff *tipc_link_cmd_reset_stats(struct net *net,
-                                         const void *req_tlv_area,
-                                         int req_tlv_space)
-{
-       char *link_name;
-       struct tipc_link *l_ptr;
-       struct tipc_node *node;
-       unsigned int bearer_id;
-
-       if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
-               return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
-
-       link_name = (char *)TLV_DATA(req_tlv_area);
-       if (!strcmp(link_name, tipc_bclink_name)) {
-               if (tipc_bclink_reset_stats(net))
-                       return tipc_cfg_reply_error_string("link not found");
-               return tipc_cfg_reply_none();
-       }
-       node = tipc_link_find_owner(net, link_name, &bearer_id);
-       if (!node)
-               return tipc_cfg_reply_error_string("link not found");
-
-       tipc_node_lock(node);
-       l_ptr = node->links[bearer_id];
-       if (!l_ptr) {
-               tipc_node_unlock(node);
-               return tipc_cfg_reply_error_string("link not found");
-       }
-       link_reset_statistics(l_ptr);
-       tipc_node_unlock(node);
-       return tipc_cfg_reply_none();
-}
-
-/**
- * percent - convert count to a percentage of total (rounding up or down)
- */
-static u32 percent(u32 count, u32 total)
-{
-       return (count * 100 + (total / 2)) / total;
-}
-
-/**
- * tipc_link_stats - print link statistics
- * @net: the applicable net namespace
- * @name: link name
- * @buf: print buffer area
- * @buf_size: size of print buffer area
- *
- * Returns length of print buffer data string (or 0 if error)
- */
-static int tipc_link_stats(struct net *net, const char *name, char *buf,
-                          const u32 buf_size)
-{
-       struct tipc_link *l;
-       struct tipc_stats *s;
-       struct tipc_node *node;
-       char *status;
-       u32 profile_total = 0;
-       unsigned int bearer_id;
-       int ret;
-
-       if (!strcmp(name, tipc_bclink_name))
-               return tipc_bclink_stats(net, buf, buf_size);
-
-       node = tipc_link_find_owner(net, name, &bearer_id);
-       if (!node)
-               return 0;
-
-       tipc_node_lock(node);
-
-       l = node->links[bearer_id];
-       if (!l) {
-               tipc_node_unlock(node);
-               return 0;
-       }
-
-       s = &l->stats;
-
-       if (tipc_link_is_active(l))
-               status = "ACTIVE";
-       else if (tipc_link_is_up(l))
-               status = "STANDBY";
-       else
-               status = "DEFUNCT";
-
-       ret = tipc_snprintf(buf, buf_size, "Link <%s>\n"
-                           "  %s  MTU:%u  Priority:%u  Tolerance:%u ms"
-                           "  Window:%u packets\n",
-                           l->name, status, l->max_pkt, l->priority,
-                           l->tolerance, l->queue_limit[0]);
-
-       ret += tipc_snprintf(buf + ret, buf_size - ret,
-                            "  RX packets:%u fragments:%u/%u bundles:%u/%u\n",
-                            l->next_in_no - s->recv_info, s->recv_fragments,
-                            s->recv_fragmented, s->recv_bundles,
-                            s->recv_bundled);
-
-       ret += tipc_snprintf(buf + ret, buf_size - ret,
-                            "  TX packets:%u fragments:%u/%u bundles:%u/%u\n",
-                            l->next_out_no - s->sent_info, s->sent_fragments,
-                            s->sent_fragmented, s->sent_bundles,
-                            s->sent_bundled);
-
-       profile_total = s->msg_length_counts;
-       if (!profile_total)
-               profile_total = 1;
-
-       ret += tipc_snprintf(buf + ret, buf_size - ret,
-                            "  TX profile sample:%u packets  average:%u octets\n"
-                            "  0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% "
-                            "-16384:%u%% -32768:%u%% -66000:%u%%\n",
-                            s->msg_length_counts,
-                            s->msg_lengths_total / profile_total,
-                            percent(s->msg_length_profile[0], profile_total),
-                            percent(s->msg_length_profile[1], profile_total),
-                            percent(s->msg_length_profile[2], profile_total),
-                            percent(s->msg_length_profile[3], profile_total),
-                            percent(s->msg_length_profile[4], profile_total),
-                            percent(s->msg_length_profile[5], profile_total),
-                            percent(s->msg_length_profile[6], profile_total));
-
-       ret += tipc_snprintf(buf + ret, buf_size - ret,
-                            "  RX states:%u probes:%u naks:%u defs:%u"
-                            " dups:%u\n", s->recv_states, s->recv_probes,
-                            s->recv_nacks, s->deferred_recv, s->duplicates);
-
-       ret += tipc_snprintf(buf + ret, buf_size - ret,
-                            "  TX states:%u probes:%u naks:%u acks:%u"
-                            " dups:%u\n", s->sent_states, s->sent_probes,
-                            s->sent_nacks, s->sent_acks, s->retransmitted);
-
-       ret += tipc_snprintf(buf + ret, buf_size - ret,
-                            "  Congestion link:%u  Send queue"
-                            " max:%u avg:%u\n", s->link_congs,
-                            s->max_queue_sz, s->queue_sz_counts ?
-                            (s->accu_queue_sz / s->queue_sz_counts) : 0);
-
-       tipc_node_unlock(node);
-       return ret;
-}
-
-struct sk_buff *tipc_link_cmd_show_stats(struct net *net,
-                                        const void *req_tlv_area,
-                                        int req_tlv_space)
-{
-       struct sk_buff *buf;
-       struct tlv_desc *rep_tlv;
-       int str_len;
-       int pb_len;
-       char *pb;
-
-       if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
-               return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
-
-       buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
-       if (!buf)
-               return NULL;
-
-       rep_tlv = (struct tlv_desc *)buf->data;
-       pb = TLV_DATA(rep_tlv);
-       pb_len = ULTRA_STRING_MAX_LEN;
-       str_len = tipc_link_stats(net, (char *)TLV_DATA(req_tlv_area),
-                                 pb, pb_len);
-       if (!str_len) {
-               kfree_skb(buf);
-               return tipc_cfg_reply_error_string("link not found");
-       }
-       str_len += 1;   /* for "\0" */
-       skb_put(buf, TLV_SPACE(str_len));
-       TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
-
-       return buf;
-}
-
 static void link_print(struct tipc_link *l_ptr, const char *str)
 {
        struct tipc_net *tn = net_generic(l_ptr->owner->net, tipc_net_id);
@@ -2400,7 +2038,7 @@ int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info)
        struct tipc_link *link;
        struct tipc_node *node;
        struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
-       struct net *net = genl_info_net(info);
+       struct net *net = sock_net(skb->sk);
 
        if (!info->attrs[TIPC_NLA_LINK])
                return -EINVAL;
@@ -2541,7 +2179,7 @@ static int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
        struct nlattr *prop;
        struct tipc_net *tn = net_generic(net, tipc_net_id);
 
-       hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family,
+       hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
                          NLM_F_MULTI, TIPC_NL_LINK_GET);
        if (!hdr)
                return -EMSGSIZE;
@@ -2752,7 +2390,7 @@ int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info)
        struct tipc_link *link;
        struct tipc_node *node;
        struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
-       struct net *net = genl_info_net(info);
+       struct net *net = sock_net(skb->sk);
 
        if (!info->attrs[TIPC_NLA_LINK])
                return -EINVAL;