Commit 32301906 authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

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: default avatarJon Maloy <jon.maloy@ericsson.com>
Reviewed-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0e05498e
...@@ -98,10 +98,11 @@ struct tipc_bcbearer { ...@@ -98,10 +98,11 @@ struct tipc_bcbearer {
* Handles sequence numbering, fragmentation, bundling, etc. * Handles sequence numbering, fragmentation, bundling, etc.
*/ */
struct tipc_bc_base { struct tipc_bc_base {
struct tipc_link link; struct tipc_link *link;
struct tipc_node node; struct tipc_node node;
struct sk_buff_head arrvq; struct sk_buff_head arrvq;
struct sk_buff_head inputq; struct sk_buff_head inputq;
struct sk_buff_head namedq;
struct tipc_node_map bcast_nodes; struct tipc_node_map bcast_nodes;
struct tipc_node *retransmit_to; struct tipc_node *retransmit_to;
}; };
...@@ -180,7 +181,7 @@ void tipc_bclink_remove_node(struct net *net, u32 addr) ...@@ -180,7 +181,7 @@ void tipc_bclink_remove_node(struct net *net, u32 addr)
/* Last node? => reset backlog queue */ /* Last node? => reset backlog queue */
if (!tn->bcbase->bcast_nodes.count) if (!tn->bcbase->bcast_nodes.count)
tipc_link_purge_backlog(&tn->bcbase->link); tipc_link_purge_backlog(tn->bcbase->link);
tipc_bclink_unlock(net); tipc_bclink_unlock(net);
} }
...@@ -1010,55 +1011,56 @@ int tipc_nl_bc_link_set(struct net *net, struct nlattr *attrs[]) ...@@ -1010,55 +1011,56 @@ int tipc_nl_bc_link_set(struct net *net, struct nlattr *attrs[])
int tipc_bcast_init(struct net *net) int tipc_bcast_init(struct net *net)
{ {
struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_net *tn = tipc_net(net);
struct tipc_bcbearer *bcbearer; struct tipc_bcbearer *bcb = NULL;
struct tipc_bc_base *bclink; struct tipc_bc_base *bb = NULL;
struct tipc_link *bcl; struct tipc_link *l = NULL;
bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); bcb = kzalloc(sizeof(*bcb), GFP_ATOMIC);
if (!bcbearer) if (!bcb)
return -ENOMEM; goto enomem;
tn->bcbearer = bcb;
bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
if (!bclink) { bcb->bearer.window = BCLINK_WIN_DEFAULT;
kfree(bcbearer); bcb->bearer.mtu = MAX_PKT_DEFAULT_MCAST;
return -ENOMEM; bcb->bearer.identity = MAX_BEARERS;
}
bcb->bearer.media = &bcb->media;
bcl = &bclink->link; bcb->media.send_msg = tipc_bcbearer_send;
bcbearer->bearer.media = &bcbearer->media; sprintf(bcb->media.name, "tipc-broadcast");
bcbearer->media.send_msg = tipc_bcbearer_send; strcpy(bcb->bearer.name, bcb->media.name);
sprintf(bcbearer->media.name, "tipc-broadcast");
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); spin_lock_init(&tipc_net(net)->bclock);
__skb_queue_head_init(&bcl->transmq); bb->node.net = net;
__skb_queue_head_init(&bcl->backlogq);
__skb_queue_head_init(&bcl->deferdq); if (!tipc_link_bc_create(&bb->node,
skb_queue_head_init(&bcl->wakeupq); MAX_PKT_DEFAULT_MCAST,
bcl->snd_nxt = 1; BCLINK_WIN_DEFAULT,
spin_lock_init(&bclink->node.lock); &bb->inputq,
__skb_queue_head_init(&bclink->arrvq); &bb->namedq,
skb_queue_head_init(&bclink->inputq); &l))
bcl->owner = &bclink->node; goto enomem;
bcl->owner->net = net; bb->link = l;
bcl->mtu = MAX_PKT_DEFAULT_MCAST; tn->bcl = l;
tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcb->bearer);
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;
return 0; return 0;
enomem:
kfree(bcb);
kfree(bb);
kfree(l);
return -ENOMEM;
} }
void tipc_bcast_reinit(struct net *net) void tipc_bcast_reinit(struct net *net)
{ {
struct tipc_bc_base *b = tipc_bc_base(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) void tipc_bcast_stop(struct net *net)
...@@ -1072,6 +1074,7 @@ void tipc_bcast_stop(struct net *net) ...@@ -1072,6 +1074,7 @@ void tipc_bcast_stop(struct net *net)
synchronize_net(); synchronize_net();
kfree(tn->bcbearer); kfree(tn->bcbearer);
kfree(tn->bcbase); kfree(tn->bcbase);
kfree(tn->bcl);
} }
/** /**
......
...@@ -44,8 +44,6 @@ struct tipc_msg; ...@@ -44,8 +44,6 @@ struct tipc_msg;
struct tipc_nl_msg; struct tipc_nl_msg;
struct tipc_node_map; struct tipc_node_map;
extern const char tipc_bclink_name[];
int tipc_bcast_init(struct net *net); int tipc_bcast_init(struct net *net);
void tipc_bcast_reinit(struct net *net); void tipc_bcast_reinit(struct net *net);
void tipc_bcast_stop(struct net *net); void tipc_bcast_stop(struct net *net);
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
*/ */
static const char *link_co_err = "Link tunneling error, "; static const char *link_co_err = "Link tunneling error, ";
static const char *link_rst_msg = "Resetting link "; 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] = { static const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
[TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC }, [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, ...@@ -231,6 +232,34 @@ bool tipc_link_create(struct tipc_node *n, char *if_name, int bearer_id,
return true; 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. /* tipc_link_build_bcast_sync_msg() - synchronize broadcast link endpoints.
* *
* Give a newly added peer node the sequence number where it should * Give a newly added peer node the sequence number where it should
......
...@@ -211,6 +211,10 @@ bool tipc_link_create(struct tipc_node *n, char *if_name, int bearer_id, ...@@ -211,6 +211,10 @@ bool tipc_link_create(struct tipc_node *n, char *if_name, int bearer_id,
struct tipc_media_addr *maddr, struct tipc_media_addr *maddr,
struct sk_buff_head *inputq, struct sk_buff_head *namedq, struct sk_buff_head *inputq, struct sk_buff_head *namedq,
struct tipc_link **link); 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, void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
int mtyp, struct sk_buff_head *xmitq); int mtyp, struct sk_buff_head *xmitq);
void tipc_link_build_bcast_sync_msg(struct tipc_link *l, void tipc_link_build_bcast_sync_msg(struct tipc_link *l,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment