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

tipc: clean up link creation

We simplify the link creation function tipc_link_create() and the way
the link struct it is connected to the node struct. In particular, we
remove the duplicate initialization of some fields which are anyway set
in tipc_link_reset().
Tested-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9073fb8b
...@@ -109,6 +109,11 @@ struct tipc_net { ...@@ -109,6 +109,11 @@ struct tipc_net {
atomic_t subscription_count; atomic_t subscription_count;
}; };
static inline struct tipc_net *tipc_net(struct net *net)
{
return net_generic(net, tipc_net_id);
}
static inline u16 mod(u16 x) static inline u16 mod(u16 x)
{ {
return x & 0xffffu; return x & 0xffffu;
......
...@@ -147,87 +147,71 @@ int tipc_link_is_active(struct tipc_link *l) ...@@ -147,87 +147,71 @@ int tipc_link_is_active(struct tipc_link *l)
return (node_active_link(n, 0) == l) || (node_active_link(n, 1) == l); return (node_active_link(n, 0) == l) || (node_active_link(n, 1) == l);
} }
static u32 link_own_addr(struct tipc_link *l)
{
return msg_prevnode(l->pmsg);
}
/** /**
* tipc_link_create - create a new link * tipc_link_create - create a new link
* @n_ptr: pointer to associated node * @n: pointer to associated node
* @b_ptr: pointer to associated bearer * @b: pointer to associated bearer
* @media_addr: media address to use when sending messages over link * @ownnode: identity of own node
* @peer: identity of peer node
* @maddr: media address 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 pointer to link. * Returns true if link was created, otherwise false
*/ */
struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, bool tipc_link_create(struct tipc_node *n, struct tipc_bearer *b, u32 session,
struct tipc_bearer *b_ptr, u32 ownnode, u32 peer, struct tipc_media_addr *maddr,
const struct tipc_media_addr *media_addr, struct sk_buff_head *inputq, struct sk_buff_head *namedq,
struct sk_buff_head *inputq, struct tipc_link **link)
struct sk_buff_head *namedq)
{ {
struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id); struct tipc_link *l;
struct tipc_link *l_ptr; struct tipc_msg *hdr;
struct tipc_msg *msg;
char *if_name; char *if_name;
char addr_string[16];
u32 peer = n_ptr->addr;
if (n_ptr->link_cnt >= MAX_BEARERS) { l = kzalloc(sizeof(*l), GFP_ATOMIC);
tipc_addr_string_fill(addr_string, n_ptr->addr); if (!l)
pr_err("Cannot establish %uth link to %s. Max %u allowed.\n", return false;
n_ptr->link_cnt, addr_string, MAX_BEARERS); *link = l;
return NULL;
}
if (n_ptr->links[b_ptr->identity].link) { /* Note: peer i/f name is completed by reset/activate message */
tipc_addr_string_fill(addr_string, n_ptr->addr); if_name = strchr(b->name, ':') + 1;
pr_err("Attempt to establish second link on <%s> to %s\n", sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
b_ptr->name, addr_string); tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode),
return NULL; if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
}
l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); l->addr = peer;
if (!l_ptr) { l->media_addr = maddr;
pr_warn("Link creation failed, no memory\n"); l->owner = n;
return NULL; l->peer_session = WILDCARD_SESSION;
} l->bearer_id = b->identity;
l_ptr->addr = peer; l->tolerance = b->tolerance;
if_name = strchr(b_ptr->name, ':') + 1; l->net_plane = b->net_plane;
sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown", l->advertised_mtu = b->mtu;
tipc_zone(tn->own_addr), tipc_cluster(tn->own_addr), l->mtu = b->mtu;
tipc_node(tn->own_addr), l->priority = b->priority;
if_name, tipc_link_set_queue_limits(l, b->window);
tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); l->inputq = inputq;
/* note: peer i/f name is updated by reset/activate message */ l->namedq = namedq;
memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); l->state = LINK_RESETTING;
l_ptr->owner = n_ptr; l->pmsg = (struct tipc_msg *)&l->proto_msg;
l_ptr->peer_session = WILDCARD_SESSION; hdr = l->pmsg;
l_ptr->bearer_id = b_ptr->identity; tipc_msg_init(ownnode, hdr, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, peer);
l_ptr->tolerance = b_ptr->tolerance; msg_set_size(hdr, sizeof(l->proto_msg));
l_ptr->snd_nxt = 1; msg_set_session(hdr, session);
l_ptr->rcv_nxt = 1; msg_set_bearer_id(hdr, l->bearer_id);
l_ptr->state = LINK_RESET; strcpy((char *)msg_data(hdr), if_name);
__skb_queue_head_init(&l->transmq);
l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; __skb_queue_head_init(&l->backlogq);
msg = l_ptr->pmsg; __skb_queue_head_init(&l->deferdq);
tipc_msg_init(tn->own_addr, msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, skb_queue_head_init(&l->wakeupq);
l_ptr->addr); skb_queue_head_init(l->inputq);
msg_set_size(msg, sizeof(l_ptr->proto_msg)); return true;
msg_set_session(msg, (tn->random & 0xffff));
msg_set_bearer_id(msg, b_ptr->identity);
strcpy((char *)msg_data(msg), if_name);
l_ptr->net_plane = b_ptr->net_plane;
l_ptr->advertised_mtu = b_ptr->mtu;
l_ptr->mtu = l_ptr->advertised_mtu;
l_ptr->priority = b_ptr->priority;
tipc_link_set_queue_limits(l_ptr, b_ptr->window);
l_ptr->snd_nxt = 1;
__skb_queue_head_init(&l_ptr->transmq);
__skb_queue_head_init(&l_ptr->backlogq);
__skb_queue_head_init(&l_ptr->deferdq);
skb_queue_head_init(&l_ptr->wakeupq);
l_ptr->inputq = inputq;
l_ptr->namedq = namedq;
skb_queue_head_init(l_ptr->inputq);
link_reset_statistics(l_ptr);
tipc_node_attach_link(n_ptr, l_ptr);
return l_ptr;
} }
/* tipc_link_build_bcast_sync_msg() - synchronize broadcast link endpoints. /* tipc_link_build_bcast_sync_msg() - synchronize broadcast link endpoints.
...@@ -643,7 +627,7 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link, ...@@ -643,7 +627,7 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
u16 ack = mod(link->rcv_nxt - 1); u16 ack = mod(link->rcv_nxt - 1);
u16 seqno = link->snd_nxt; u16 seqno = link->snd_nxt;
u16 bc_last_in = link->owner->bclink.last_in; u16 bc_last_in = link->owner->bclink.last_in;
struct tipc_media_addr *addr = &link->media_addr; struct tipc_media_addr *addr = link->media_addr;
struct sk_buff_head *transmq = &link->transmq; struct sk_buff_head *transmq = &link->transmq;
struct sk_buff_head *backlogq = &link->backlogq; struct sk_buff_head *backlogq = &link->backlogq;
struct sk_buff *skb, *bskb; struct sk_buff *skb, *bskb;
...@@ -809,7 +793,7 @@ void tipc_link_push_packets(struct tipc_link *link) ...@@ -809,7 +793,7 @@ void tipc_link_push_packets(struct tipc_link *link)
link->rcv_unacked = 0; link->rcv_unacked = 0;
__skb_queue_tail(&link->transmq, skb); __skb_queue_tail(&link->transmq, skb);
tipc_bearer_send(link->owner->net, link->bearer_id, tipc_bearer_send(link->owner->net, link->bearer_id,
skb, &link->media_addr); skb, link->media_addr);
} }
link->snd_nxt = seqno; link->snd_nxt = seqno;
} }
...@@ -912,7 +896,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb, ...@@ -912,7 +896,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb,
msg_set_ack(msg, mod(l_ptr->rcv_nxt - 1)); msg_set_ack(msg, mod(l_ptr->rcv_nxt - 1));
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
tipc_bearer_send(l_ptr->owner->net, l_ptr->bearer_id, skb, tipc_bearer_send(l_ptr->owner->net, l_ptr->bearer_id, skb,
&l_ptr->media_addr); l_ptr->media_addr);
retransmits--; retransmits--;
l_ptr->stats.retransmitted++; l_ptr->stats.retransmitted++;
} }
...@@ -1200,7 +1184,7 @@ void tipc_link_proto_xmit(struct tipc_link *l, u32 msg_typ, int probe_msg, ...@@ -1200,7 +1184,7 @@ void tipc_link_proto_xmit(struct tipc_link *l, u32 msg_typ, int probe_msg,
skb = __skb_dequeue(&xmitq); skb = __skb_dequeue(&xmitq);
if (!skb) if (!skb)
return; return;
tipc_bearer_send(l->owner->net, l->bearer_id, skb, &l->media_addr); tipc_bearer_send(l->owner->net, l->bearer_id, skb, l->media_addr);
l->rcv_unacked = 0; l->rcv_unacked = 0;
kfree_skb(skb); kfree_skb(skb);
} }
......
...@@ -148,7 +148,7 @@ struct tipc_stats { ...@@ -148,7 +148,7 @@ struct tipc_stats {
struct tipc_link { struct tipc_link {
u32 addr; u32 addr;
char name[TIPC_MAX_LINK_NAME]; char name[TIPC_MAX_LINK_NAME];
struct tipc_media_addr media_addr; struct tipc_media_addr *media_addr;
struct tipc_node *owner; struct tipc_node *owner;
/* Management and link supervision data */ /* Management and link supervision data */
...@@ -205,13 +205,10 @@ struct tipc_link { ...@@ -205,13 +205,10 @@ struct tipc_link {
struct tipc_stats stats; struct tipc_stats stats;
}; };
struct tipc_port; bool tipc_link_create(struct tipc_node *n, struct tipc_bearer *b, u32 session,
u32 ownnode, u32 peer, struct tipc_media_addr *maddr,
struct tipc_link *tipc_link_create(struct tipc_node *n, struct sk_buff_head *inputq, struct sk_buff_head *namedq,
struct tipc_bearer *b, struct tipc_link **link);
const struct tipc_media_addr *maddr,
struct sk_buff_head *inputq,
struct sk_buff_head *namedq);
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,
...@@ -246,13 +243,8 @@ int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info); ...@@ -246,13 +243,8 @@ int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info); int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info); int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
void link_prepare_wakeup(struct tipc_link *l);
int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq); int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq);
int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
struct sk_buff_head *xmitq); struct sk_buff_head *xmitq);
static inline u32 link_own_addr(struct tipc_link *l)
{
return msg_prevnode(l->pmsg);
}
#endif #endif
...@@ -320,10 +320,6 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id, ...@@ -320,10 +320,6 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
if (!nl || !tipc_link_is_up(nl)) if (!nl || !tipc_link_is_up(nl))
return; return;
if (n->working_links > 1) {
pr_warn("Attempt to establish 3rd link to %x\n", n->addr);
return;
}
n->working_links++; n->working_links++;
n->action_flags |= TIPC_NOTIFY_LINK_UP; n->action_flags |= TIPC_NOTIFY_LINK_UP;
n->link_id = nl->peer_bearer_id << 16 | bearer_id; n->link_id = nl->peer_bearer_id << 16 | bearer_id;
...@@ -470,13 +466,13 @@ void tipc_node_check_dest(struct net *net, u32 onode, ...@@ -470,13 +466,13 @@ void tipc_node_check_dest(struct net *net, u32 onode,
{ {
struct tipc_node *n; struct tipc_node *n;
struct tipc_link *l; struct tipc_link *l;
struct tipc_media_addr *curr_maddr; struct tipc_link_entry *le;
struct sk_buff_head *inputq;
bool addr_match = false; bool addr_match = false;
bool sign_match = false; bool sign_match = false;
bool link_up = false; bool link_up = false;
bool accept_addr = false; bool accept_addr = false;
bool reset = true; bool reset = true;
*dupl_addr = false; *dupl_addr = false;
*respond = false; *respond = false;
...@@ -486,13 +482,12 @@ void tipc_node_check_dest(struct net *net, u32 onode, ...@@ -486,13 +482,12 @@ void tipc_node_check_dest(struct net *net, u32 onode,
tipc_node_lock(n); tipc_node_lock(n);
curr_maddr = &n->links[b->identity].maddr; le = &n->links[b->identity];
inputq = &n->links[b->identity].inputq;
/* Prepare to validate requesting node's signature and media address */ /* Prepare to validate requesting node's signature and media address */
l = n->links[b->identity].link; l = le->link;
link_up = l && tipc_link_is_up(l); link_up = l && tipc_link_is_up(l);
addr_match = l && !memcmp(curr_maddr, maddr, sizeof(*maddr)); addr_match = l && !memcmp(&le->maddr, maddr, sizeof(*maddr));
sign_match = (signature == n->signature); sign_match = (signature == n->signature);
/* These three flags give us eight permutations: */ /* These three flags give us eight permutations: */
...@@ -559,18 +554,25 @@ void tipc_node_check_dest(struct net *net, u32 onode, ...@@ -559,18 +554,25 @@ void tipc_node_check_dest(struct net *net, u32 onode,
/* Now create new link if not already existing */ /* Now create new link if not already existing */
if (!l) { if (!l) {
l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq); if (n->link_cnt == 2) {
if (!l) { pr_warn("Cannot establish 3rd link to %x\n", n->addr);
goto exit;
}
if (!tipc_link_create(n, b, mod(tipc_net(net)->random),
tipc_own_addr(net), onode, &le->maddr,
&le->inputq, &n->bclink.namedq, &l)) {
*respond = false; *respond = false;
goto exit; goto exit;
} }
tipc_link_reset(l);
le->link = l;
n->link_cnt++;
tipc_node_calculate_timer(n, l); tipc_node_calculate_timer(n, l);
if (n->link_cnt == 1) if (n->link_cnt == 1)
if (!mod_timer(&n->timer, jiffies + n->keepalive_intv)) if (!mod_timer(&n->timer, jiffies + n->keepalive_intv))
tipc_node_get(n); tipc_node_get(n);
} }
memcpy(&l->media_addr, maddr, sizeof(*maddr)); memcpy(&le->maddr, maddr, sizeof(*maddr));
memcpy(curr_maddr, maddr, sizeof(*maddr));
exit: exit:
tipc_node_unlock(n); tipc_node_unlock(n);
if (reset) if (reset)
...@@ -603,24 +605,6 @@ static void tipc_node_reset_links(struct tipc_node *n) ...@@ -603,24 +605,6 @@ static void tipc_node_reset_links(struct tipc_node *n)
} }
} }
void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
{
n_ptr->links[l_ptr->bearer_id].link = l_ptr;
n_ptr->link_cnt++;
}
void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
{
int i;
for (i = 0; i < MAX_BEARERS; i++) {
if (l_ptr != n_ptr->links[i].link)
continue;
n_ptr->links[i].link = NULL;
n_ptr->link_cnt--;
}
}
/* tipc_node_fsm_evt - node finite state machine /* tipc_node_fsm_evt - node finite state machine
* Determines when contact is allowed with peer node * Determines when contact is allowed with peer node
*/ */
......
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