tipc: eliminate link's reference to owner node

With the recent commit series, we have established a one-way dependency
between the link aggregation (struct tipc_node) instances and their
pertaining tipc_link instances. This has enabled quite significant code
and structure simplifications.

In this commit, we eliminate the field 'owner', which points to an
instance of struct tipc_node, from struct tipc_link, and replace it with
a pointer to struct net, which is the only external reference now needed
by a link instance.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index d8c399d..c012ce9 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -1226,7 +1226,7 @@
 	spin_lock_init(&tipc_net(net)->bclock);
 	bb->node.net = net;
 
-	if (!tipc_link_bc_create(&bb->node, 0, 0,
+	if (!tipc_link_bc_create(net, 0, 0,
 				 U16_MAX,
 				 BCLINK_WIN_DEFAULT,
 				 0,
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 7d3b6e7..819fb71 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -175,9 +175,12 @@
 
 int tipc_link_is_active(struct tipc_link *l)
 {
-	struct tipc_node *n = l->owner;
+	return l->active;
+}
 
-	return (node_active_link(n, 0) == l) || (node_active_link(n, 1) == l);
+void tipc_link_set_active(struct tipc_link *l, bool active)
+{
+	l->active = active;
 }
 
 void tipc_link_add_bc_peer(struct tipc_link *snd_l,
@@ -250,7 +253,7 @@
  *
  * Returns true if link was created, otherwise false
  */
-bool tipc_link_create(struct tipc_node *n, char *if_name, int bearer_id,
+bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
 		      int tolerance, char net_plane, u32 mtu, int priority,
 		      int window, u32 session, u32 ownnode, u32 peer,
 		      u16 peer_caps,
@@ -284,7 +287,7 @@
 	l->addr = peer;
 	l->peer_caps = peer_caps;
 	l->media_addr = maddr;
-	l->owner = n;
+	l->net = net;
 	l->peer_session = WILDCARD_SESSION;
 	l->bearer_id = bearer_id;
 	l->tolerance = tolerance;
@@ -318,7 +321,7 @@
  *
  * Returns true if link was created, otherwise false
  */
-bool tipc_link_bc_create(struct tipc_node *n, u32 ownnode, u32 peer,
+bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer,
 			 int mtu, int window, u16 peer_caps,
 			 struct sk_buff_head *inputq,
 			 struct sk_buff_head *namedq,
@@ -327,7 +330,7 @@
 {
 	struct tipc_link *l;
 
-	if (!tipc_link_create(n, "", MAX_BEARERS, 0, 'Z', mtu, 0, window,
+	if (!tipc_link_create(net, "", MAX_BEARERS, 0, 'Z', mtu, 0, window,
 			      0, ownnode, peer, peer_caps, NULL, bc_sndlink,
 			      NULL, inputq, namedq, link))
 		return false;
@@ -889,10 +892,10 @@
 		msg_set_ack(msg, ack);
 		msg_set_seqno(msg, seqno);
 		seqno = mod(seqno + 1);
-		msg_set_bcast_ack(msg, link->owner->bclink.last_in);
+		/* msg_set_bcast_ack(msg, link->owner->bclink.last_in); */
 		link->rcv_unacked = 0;
 		__skb_queue_tail(&link->transmq, skb);
-		tipc_bearer_send(link->owner->net, link->bearer_id,
+		tipc_bearer_send(link->net, link->bearer_id,
 				 skb, link->media_addr);
 	}
 	link->snd_nxt = seqno;
@@ -966,8 +969,8 @@
 			break;
 		msg = buf_msg(skb);
 		msg_set_ack(msg, mod(l_ptr->rcv_nxt - 1));
-		msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
-		tipc_bearer_send(l_ptr->owner->net, l_ptr->bearer_id, skb,
+		/* msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); */
+		tipc_bearer_send(l_ptr->net, l_ptr->bearer_id, skb,
 				 l_ptr->media_addr);
 		retransmits--;
 		l_ptr->stats.retransmitted++;
@@ -1102,9 +1105,9 @@
 		}
 		return 0;
 	} else if (usr == BCAST_PROTOCOL) {
-		tipc_bcast_lock(l->owner->net);
+		tipc_bcast_lock(l->net);
 		tipc_link_bc_init_rcv(l->bc_rcvlink, hdr);
-		tipc_bcast_unlock(l->owner->net);
+		tipc_bcast_unlock(l->net);
 	}
 drop:
 	kfree_skb(skb);
@@ -1300,7 +1303,7 @@
 	skb = __skb_dequeue(&xmitq);
 	if (!skb)
 		return;
-	tipc_bearer_xmit_skb(l->owner->net, l->bearer_id, skb, l->media_addr);
+	tipc_bearer_xmit_skb(l->net, l->bearer_id, skb, l->media_addr);
 	l->rcv_unacked = 0;
 }
 
@@ -2004,7 +2007,7 @@
 	if (tipc_link_is_up(link))
 		if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP))
 			goto attr_msg_full;
-	if (tipc_link_is_active(link))
+	if (link->active)
 		if (nla_put_flag(msg->skb, TIPC_NLA_LINK_ACTIVE))
 			goto attr_msg_full;
 
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 9b5198e9..eb1d7f9 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -111,7 +111,7 @@
  * @name: link name character string
  * @media_addr: media address to use when sending messages over link
  * @timer: link timer
- * @owner: pointer to peer node
+ * @net: pointer to namespace struct
  * @refcnt: reference counter for permanent references (owner node & timer)
  * @peer_session: link session # being used by peer end of link
  * @peer_bearer_id: bearer id used by link's peer endpoint
@@ -154,7 +154,7 @@
 	u32 addr;
 	char name[TIPC_MAX_LINK_NAME];
 	struct tipc_media_addr *media_addr;
-	struct tipc_node *owner;
+	struct net *net;
 
 	/* Management and link supervision data */
 	u32 peer_session;
@@ -165,6 +165,7 @@
 	u32 abort_limit;
 	u32 state;
 	u16 peer_caps;
+	bool active;
 	u32 silent_intv_cnt;
 	struct {
 		unchar hdr[INT_H_SIZE];
@@ -219,7 +220,7 @@
 	struct tipc_stats stats;
 };
 
-bool tipc_link_create(struct tipc_node *n, char *if_name, int bearer_id,
+bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
 		      int tolerance, char net_plane, u32 mtu, int priority,
 		      int window, u32 session, u32 ownnode, u32 peer,
 		      u16 peer_caps,
@@ -229,7 +230,7 @@
 		      struct sk_buff_head *inputq,
 		      struct sk_buff_head *namedq,
 		      struct tipc_link **link);
-bool tipc_link_bc_create(struct tipc_node *n, u32 ownnode, u32 peer,
+bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer,
 			 int mtu, int window, u16 peer_caps,
 			 struct sk_buff_head *inputq,
 			 struct sk_buff_head *namedq,
@@ -247,7 +248,7 @@
 bool tipc_link_is_synching(struct tipc_link *l);
 bool tipc_link_is_failingover(struct tipc_link *l);
 bool tipc_link_is_blocked(struct tipc_link *l);
-int tipc_link_is_active(struct tipc_link *l_ptr);
+void tipc_link_set_active(struct tipc_link *l, bool active);
 void tipc_link_purge_queues(struct tipc_link *l_ptr);
 void tipc_link_purge_backlog(struct tipc_link *l);
 void tipc_link_reset(struct tipc_link *l_ptr);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index b274390..eb739d2 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -178,7 +178,7 @@
 	n_ptr->signature = INVALID_NODE_SIG;
 	n_ptr->active_links[0] = INVALID_BEARER_ID;
 	n_ptr->active_links[1] = INVALID_BEARER_ID;
-	if (!tipc_link_bc_create(n_ptr, tipc_own_addr(net), n_ptr->addr,
+	if (!tipc_link_bc_create(net, tipc_own_addr(net), n_ptr->addr,
 				 U16_MAX, tipc_bc_sndlink(net)->window,
 				 n_ptr->capabilities,
 				 &n_ptr->bc_entry.inputq1,
@@ -366,7 +366,10 @@
 		pr_debug("Old link <%s> becomes standby\n", ol->name);
 		*slot0 = bearer_id;
 		*slot1 = bearer_id;
+		tipc_link_set_active(nl, true);
+		tipc_link_set_active(ol, false);
 	} else if (nl->priority == ol->priority) {
+		tipc_link_set_active(nl, true);
 		*slot0 = bearer_id;
 	} else {
 		pr_debug("New link <%s> is standby\n", nl->name);
@@ -599,7 +602,7 @@
 			goto exit;
 		}
 		if_name = strchr(b->name, ':') + 1;
-		if (!tipc_link_create(n, if_name, b->identity, b->tolerance,
+		if (!tipc_link_create(net, if_name, b->identity, b->tolerance,
 				      b->net_plane, b->mtu, b->priority,
 				      b->window, mod(tipc_net(net)->random),
 				      tipc_own_addr(net), onode,