tipc: use explicit allocation of broadcast send link
authorJon Paul Maloy <jon.maloy@ericsson.com>
Thu, 22 Oct 2015 12:51:37 +0000 (08:51 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sat, 24 Oct 2015 13:56:30 +0000 (06:56 -0700)
The broadcast link instance (struct tipc_link) used for sending is
currently aggregated into struct tipc_bclink. This means that we cannot
use the regular tipc_link_create() function for initiating the link, but
do instead have to initiate numerous fields directly from the
bcast_init() function.

We want to reduce dependencies between the broadcast functionality
and the inner workings of tipc_link. In this commit, we introduce
a new function tipc_bclink_create() to link.c, and allocate the
instance of the link separately using this function.

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>
net/tipc/bcast.c
net/tipc/bcast.h
net/tipc/link.c
net/tipc/link.h

index c6f0d1dbfc3cb91f9d1645bf87447398dfaed6ef..3b7bd2174330d226b34a94badea0f8a64745e13c 100644 (file)
@@ -98,10 +98,11 @@ struct tipc_bcbearer {
  * Handles sequence numbering, fragmentation, bundling, etc.
  */
 struct tipc_bc_base {
-       struct tipc_link link;
+       struct tipc_link *link;
        struct tipc_node node;
        struct sk_buff_head arrvq;
        struct sk_buff_head inputq;
+       struct sk_buff_head namedq;
        struct tipc_node_map bcast_nodes;
        struct tipc_node *retransmit_to;
 };
@@ -180,7 +181,7 @@ void tipc_bclink_remove_node(struct net *net, u32 addr)
 
        /* Last node? => reset backlog queue */
        if (!tn->bcbase->bcast_nodes.count)
-               tipc_link_purge_backlog(&tn->bcbase->link);
+               tipc_link_purge_backlog(tn->bcbase->link);
 
        tipc_bclink_unlock(net);
 }
@@ -1010,55 +1011,56 @@ int tipc_nl_bc_link_set(struct net *net, struct nlattr *attrs[])
 
 int tipc_bcast_init(struct net *net)
 {
-       struct tipc_net *tn = net_generic(net, tipc_net_id);
-       struct tipc_bcbearer *bcbearer;
-       struct tipc_bc_base *bclink;
-       struct tipc_link *bcl;
-
-       bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
-       if (!bcbearer)
-               return -ENOMEM;
-
-       bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
-       if (!bclink) {
-               kfree(bcbearer);
-               return -ENOMEM;
-       }
-
-       bcl = &bclink->link;
-       bcbearer->bearer.media = &bcbearer->media;
-       bcbearer->media.send_msg = tipc_bcbearer_send;
-       sprintf(bcbearer->media.name, "tipc-broadcast");
-
+       struct tipc_net *tn = tipc_net(net);
+       struct tipc_bcbearer *bcb = NULL;
+       struct tipc_bc_base *bb = NULL;
+       struct tipc_link *l = NULL;
+
+       bcb = kzalloc(sizeof(*bcb), GFP_ATOMIC);
+       if (!bcb)
+               goto enomem;
+       tn->bcbearer = bcb;
+
+       bcb->bearer.window = BCLINK_WIN_DEFAULT;
+       bcb->bearer.mtu = MAX_PKT_DEFAULT_MCAST;
+       bcb->bearer.identity = MAX_BEARERS;
+
+       bcb->bearer.media = &bcb->media;
+       bcb->media.send_msg = tipc_bcbearer_send;
+       sprintf(bcb->media.name, "tipc-broadcast");
+       strcpy(bcb->bearer.name, bcb->media.name);
+
+       bb = kzalloc(sizeof(*bb), GFP_ATOMIC);
+       if (!bb)
+               goto enomem;
+       tn->bcbase = bb;
+       __skb_queue_head_init(&bb->arrvq);
        spin_lock_init(&tipc_net(net)->bclock);
-       __skb_queue_head_init(&bcl->transmq);
-       __skb_queue_head_init(&bcl->backlogq);
-       __skb_queue_head_init(&bcl->deferdq);
-       skb_queue_head_init(&bcl->wakeupq);
-       bcl->snd_nxt = 1;
-       spin_lock_init(&bclink->node.lock);
-       __skb_queue_head_init(&bclink->arrvq);
-       skb_queue_head_init(&bclink->inputq);
-       bcl->owner = &bclink->node;
-       bcl->owner->net = net;
-       bcl->mtu = MAX_PKT_DEFAULT_MCAST;
-       tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
-       bcl->bearer_id = MAX_BEARERS;
-       rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcbearer->bearer);
-       bcl->pmsg = (struct tipc_msg *)&bcl->proto_msg;
-
-       strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
-       tn->bcbearer = bcbearer;
-       tn->bcbase = bclink;
-       tn->bcl = bcl;
+       bb->node.net = net;
+
+       if (!tipc_link_bc_create(&bb->node,
+                                MAX_PKT_DEFAULT_MCAST,
+                                BCLINK_WIN_DEFAULT,
+                                &bb->inputq,
+                                &bb->namedq,
+                                &l))
+               goto enomem;
+       bb->link = l;
+       tn->bcl = l;
+       rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcb->bearer);
        return 0;
+enomem:
+       kfree(bcb);
+       kfree(bb);
+       kfree(l);
+       return -ENOMEM;
 }
 
 void tipc_bcast_reinit(struct net *net)
 {
        struct tipc_bc_base *b = tipc_bc_base(net);
 
-       msg_set_prevnode(b->link.pmsg, tipc_own_addr(net));
+       msg_set_prevnode(b->link->pmsg, tipc_own_addr(net));
 }
 
 void tipc_bcast_stop(struct net *net)
@@ -1072,6 +1074,7 @@ void tipc_bcast_stop(struct net *net)
        synchronize_net();
        kfree(tn->bcbearer);
        kfree(tn->bcbase);
+       kfree(tn->bcl);
 }
 
 /**
index 041935d4ad6d98e2ffaf93da7701c55cbef2234f..a378fdde9b7abce770b05f9c90d3f40b13178385 100644 (file)
@@ -44,8 +44,6 @@ struct tipc_msg;
 struct tipc_nl_msg;
 struct tipc_node_map;
 
-extern const char tipc_bclink_name[];
-
 int tipc_bcast_init(struct net *net);
 void tipc_bcast_reinit(struct net *net);
 void tipc_bcast_stop(struct net *net);
index 0d8fdc8fe6d4f1a556e63f9c778db4499c15d1ab..f0cf768a59f3acbf93871a04e431825e090d8f9e 100644 (file)
@@ -50,6 +50,7 @@
  */
 static const char *link_co_err = "Link tunneling error, ";
 static const char *link_rst_msg = "Resetting link ";
+static const char tipc_bclink_name[] = "broadcast-link";
 
 static const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
        [TIPC_NLA_LINK_UNSPEC]          = { .type = NLA_UNSPEC },
@@ -231,6 +232,34 @@ bool tipc_link_create(struct tipc_node *n, char *if_name, int bearer_id,
        return true;
 }
 
+/**
+ * tipc_link_bc_create - create new link to be used for broadcast
+ * @n: pointer to associated node
+ * @mtu: mtu to be used
+ * @window: send window to be used
+ * @inputq: queue to put messages ready for delivery
+ * @namedq: queue to put binding table update messages ready for delivery
+ * @link: return value, pointer to put the created link
+ *
+ * Returns true if link was created, otherwise false
+ */
+bool tipc_link_bc_create(struct tipc_node *n, int mtu, int window,
+                        struct sk_buff_head *inputq,
+                        struct sk_buff_head *namedq,
+                        struct tipc_link **link)
+{
+       struct tipc_link *l;
+
+       if (!tipc_link_create(n, "", MAX_BEARERS, 0, 'Z', mtu, 0, window,
+                             0, 0, 0, NULL, inputq, namedq, link))
+               return false;
+
+       l = *link;
+       strcpy(l->name, tipc_bclink_name);
+       tipc_link_reset(l);
+       return true;
+}
+
 /* tipc_link_build_bcast_sync_msg() - synchronize broadcast link endpoints.
  *
  * Give a newly added peer node the sequence number where it should
index 06bf66df94693d6935f5880a13a31fcc897ca17e..9e4e3673da760271239f0c1ffa9519273734c597 100644 (file)
@@ -211,6 +211,10 @@ bool tipc_link_create(struct tipc_node *n, char *if_name, int bearer_id,
                      struct tipc_media_addr *maddr,
                      struct sk_buff_head *inputq, struct sk_buff_head *namedq,
                      struct tipc_link **link);
+bool tipc_link_bc_create(struct tipc_node *n, int mtu, int window,
+                        struct sk_buff_head *inputq,
+                        struct sk_buff_head *namedq,
+                        struct tipc_link **link);
 void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
                           int mtyp, struct sk_buff_head *xmitq);
 void tipc_link_build_bcast_sync_msg(struct tipc_link *l,