summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-10-22 08:51:37 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-24 06:56:30 -0700
commit323019069e8d96d87e9dba51f897060f94999821 (patch)
tree02d0426143d9a89548a1e6f5a0d0e2ef8448db49
parent0e05498e9eae16a6d8c86543e77930ec152e655e (diff)
downloadlinux-323019069e8d96d87e9dba51f897060f94999821.tar.gz
linux-323019069e8d96d87e9dba51f897060f94999821.tar.bz2
linux-323019069e8d96d87e9dba51f897060f94999821.zip
tipc: use explicit allocation of broadcast send link
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>
-rw-r--r--net/tipc/bcast.c89
-rw-r--r--net/tipc/bcast.h2
-rw-r--r--net/tipc/link.c29
-rw-r--r--net/tipc/link.h4
4 files changed, 79 insertions, 45 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index c6f0d1dbfc3c..3b7bd2174330 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -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);
}
/**
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 041935d4ad6d..a378fdde9b7a 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -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);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 0d8fdc8fe6d4..f0cf768a59f3 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -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
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 06bf66df9469..9e4e3673da76 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -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,