tipc: refactor function tipc_enable_bearer()
As a preparation for the next commits we try to reduce the footprint of the function tipc_enable_bearer(), while hopefully making is simpler to follow. Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
594619497f
Коммит
cb30a63384
|
@ -230,88 +230,90 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
|
||||||
* tipc_enable_bearer - enable bearer with the given name
|
* tipc_enable_bearer - enable bearer with the given name
|
||||||
*/
|
*/
|
||||||
static int tipc_enable_bearer(struct net *net, const char *name,
|
static int tipc_enable_bearer(struct net *net, const char *name,
|
||||||
u32 disc_domain, u32 priority,
|
u32 disc_domain, u32 prio,
|
||||||
struct nlattr *attr[])
|
struct nlattr *attr[])
|
||||||
{
|
{
|
||||||
struct tipc_net *tn = net_generic(net, tipc_net_id);
|
struct tipc_net *tn = tipc_net(net);
|
||||||
|
struct tipc_bearer_names b_names;
|
||||||
|
u32 self = tipc_own_addr(net);
|
||||||
|
int with_this_prio = 1;
|
||||||
struct tipc_bearer *b;
|
struct tipc_bearer *b;
|
||||||
struct tipc_media *m;
|
struct tipc_media *m;
|
||||||
struct tipc_bearer_names b_names;
|
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
char addr_string[16];
|
char addr_string[16];
|
||||||
u32 bearer_id;
|
int bearer_id = 0;
|
||||||
u32 with_this_prio;
|
|
||||||
u32 i;
|
|
||||||
int res = -EINVAL;
|
int res = -EINVAL;
|
||||||
|
char *errstr = "";
|
||||||
|
|
||||||
if (!tn->own_addr) {
|
if (!self) {
|
||||||
pr_warn("Bearer <%s> rejected, not supported in standalone mode\n",
|
errstr = "not supported in standalone mode";
|
||||||
name);
|
res = -ENOPROTOOPT;
|
||||||
return -ENOPROTOOPT;
|
goto rejected;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bearer_name_validate(name, &b_names)) {
|
if (!bearer_name_validate(name, &b_names)) {
|
||||||
pr_warn("Bearer <%s> rejected, illegal name\n", name);
|
errstr = "illegal name";
|
||||||
return -EINVAL;
|
goto rejected;
|
||||||
}
|
}
|
||||||
if (tipc_addr_domain_valid(disc_domain) &&
|
|
||||||
(disc_domain != tn->own_addr)) {
|
if (tipc_addr_domain_valid(disc_domain) && disc_domain != self) {
|
||||||
if (tipc_in_scope(disc_domain, tn->own_addr)) {
|
if (tipc_in_scope(disc_domain, self)) {
|
||||||
disc_domain = tn->own_addr & TIPC_ZONE_CLUSTER_MASK;
|
/* Accept any node in own cluster */
|
||||||
res = 0; /* accept any node in own cluster */
|
disc_domain = self & TIPC_ZONE_CLUSTER_MASK;
|
||||||
} else if (in_own_cluster_exact(net, disc_domain))
|
res = 0;
|
||||||
res = 0; /* accept specified node in own cluster */
|
} else if (in_own_cluster_exact(net, disc_domain)) {
|
||||||
|
/* Accept specified node in own cluster */
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
pr_warn("Bearer <%s> rejected, illegal discovery domain\n",
|
errstr = "illegal discovery domain";
|
||||||
name);
|
goto rejected;
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
if ((priority > TIPC_MAX_LINK_PRI) &&
|
|
||||||
(priority != TIPC_MEDIA_LINK_PRI)) {
|
if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) {
|
||||||
pr_warn("Bearer <%s> rejected, illegal priority\n", name);
|
errstr = "illegal priority";
|
||||||
return -EINVAL;
|
goto rejected;
|
||||||
}
|
}
|
||||||
|
|
||||||
m = tipc_media_find(b_names.media_name);
|
m = tipc_media_find(b_names.media_name);
|
||||||
if (!m) {
|
if (!m) {
|
||||||
pr_warn("Bearer <%s> rejected, media <%s> not registered\n",
|
errstr = "media not registered";
|
||||||
name, b_names.media_name);
|
goto rejected;
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority == TIPC_MEDIA_LINK_PRI)
|
if (prio == TIPC_MEDIA_LINK_PRI)
|
||||||
priority = m->priority;
|
prio = m->priority;
|
||||||
|
|
||||||
restart:
|
/* Check new bearer vs existing ones and find free bearer id if any */
|
||||||
bearer_id = MAX_BEARERS;
|
while (bearer_id < MAX_BEARERS) {
|
||||||
with_this_prio = 1;
|
b = rtnl_dereference(tn->bearer_list[bearer_id]);
|
||||||
for (i = MAX_BEARERS; i-- != 0; ) {
|
if (!b)
|
||||||
b = rtnl_dereference(tn->bearer_list[i]);
|
break;
|
||||||
if (!b) {
|
|
||||||
bearer_id = i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(name, b->name)) {
|
if (!strcmp(name, b->name)) {
|
||||||
pr_warn("Bearer <%s> rejected, already enabled\n",
|
errstr = "already enabled";
|
||||||
name);
|
goto rejected;
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
if ((b->priority == priority) &&
|
bearer_id++;
|
||||||
(++with_this_prio > 2)) {
|
if (b->priority != prio)
|
||||||
if (priority-- == 0) {
|
continue;
|
||||||
pr_warn("Bearer <%s> rejected, duplicate priority\n",
|
if (++with_this_prio <= 2)
|
||||||
name);
|
continue;
|
||||||
return -EINVAL;
|
pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",
|
||||||
}
|
name, prio);
|
||||||
pr_warn("Bearer <%s> priority adjustment required %u->%u\n",
|
if (prio == TIPC_MIN_LINK_PRI) {
|
||||||
name, priority + 1, priority);
|
errstr = "cannot adjust to lower";
|
||||||
goto restart;
|
goto rejected;
|
||||||
}
|
}
|
||||||
|
pr_warn("Bearer <%s>: trying with adjusted priority\n", name);
|
||||||
|
prio--;
|
||||||
|
bearer_id = 0;
|
||||||
|
with_this_prio = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bearer_id >= MAX_BEARERS) {
|
if (bearer_id >= MAX_BEARERS) {
|
||||||
pr_warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
|
errstr = "max 3 bearers permitted";
|
||||||
name, MAX_BEARERS);
|
goto rejected;
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b = kzalloc(sizeof(*b), GFP_ATOMIC);
|
b = kzalloc(sizeof(*b), GFP_ATOMIC);
|
||||||
|
@ -322,10 +324,9 @@ restart:
|
||||||
b->media = m;
|
b->media = m;
|
||||||
res = m->enable_media(net, b, attr);
|
res = m->enable_media(net, b, attr);
|
||||||
if (res) {
|
if (res) {
|
||||||
pr_warn("Bearer <%s> rejected, enable failure (%d)\n",
|
|
||||||
name, -res);
|
|
||||||
kfree(b);
|
kfree(b);
|
||||||
return -EINVAL;
|
errstr = "failed to enable media";
|
||||||
|
goto rejected;
|
||||||
}
|
}
|
||||||
|
|
||||||
b->identity = bearer_id;
|
b->identity = bearer_id;
|
||||||
|
@ -333,15 +334,15 @@ restart:
|
||||||
b->window = m->window;
|
b->window = m->window;
|
||||||
b->domain = disc_domain;
|
b->domain = disc_domain;
|
||||||
b->net_plane = bearer_id + 'A';
|
b->net_plane = bearer_id + 'A';
|
||||||
b->priority = priority;
|
b->priority = prio;
|
||||||
test_and_set_bit_lock(0, &b->up);
|
test_and_set_bit_lock(0, &b->up);
|
||||||
|
|
||||||
res = tipc_disc_create(net, b, &b->bcast_addr, &skb);
|
res = tipc_disc_create(net, b, &b->bcast_addr, &skb);
|
||||||
if (res) {
|
if (res) {
|
||||||
bearer_disable(net, b);
|
bearer_disable(net, b);
|
||||||
pr_warn("Bearer <%s> rejected, discovery object creation failed\n",
|
kfree(b);
|
||||||
name);
|
errstr = "failed to create discoverer";
|
||||||
return -EINVAL;
|
goto rejected;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcu_assign_pointer(tn->bearer_list[bearer_id], b);
|
rcu_assign_pointer(tn->bearer_list[bearer_id], b);
|
||||||
|
@ -353,9 +354,12 @@ restart:
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
|
tipc_addr_string_fill(addr_string, disc_domain);
|
||||||
name,
|
pr_info("Enabled bearer <%s>, discovery scope %s, priority %u\n",
|
||||||
tipc_addr_string_fill(addr_string, disc_domain), priority);
|
name, addr_string, prio);
|
||||||
|
return res;
|
||||||
|
rejected:
|
||||||
|
pr_warn("Bearer <%s> rejected, %s\n", name, errstr);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче