aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-07-30 18:24:26 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-30 20:25:15 -0400
commit440d8963cd590ec9387d76a36e60c02da9ed944d (patch)
tree7d1135b020321fd3bd06f9bd6dbc1837380858f8 /net/tipc
parent9073fb8be3ee6f89492b8ea8f6d3902913a9fc91 (diff)
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: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/core.h5
-rw-r--r--net/tipc/link.c136
-rw-r--r--net/tipc/link.h18
-rw-r--r--net/tipc/node.c48
4 files changed, 86 insertions, 121 deletions
diff --git a/net/tipc/core.h b/net/tipc/core.h
index f4ed67778c54..b96b41eabf12 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -109,6 +109,11 @@ struct tipc_net {
109 atomic_t subscription_count; 109 atomic_t subscription_count;
110}; 110};
111 111
112static inline struct tipc_net *tipc_net(struct net *net)
113{
114 return net_generic(net, tipc_net_id);
115}
116
112static inline u16 mod(u16 x) 117static inline u16 mod(u16 x)
113{ 118{
114 return x & 0xffffu; 119 return x & 0xffffu;
diff --git a/net/tipc/link.c b/net/tipc/link.c
index d683fe9f68c8..f067e5425560 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -147,87 +147,71 @@ int tipc_link_is_active(struct tipc_link *l)
147 return (node_active_link(n, 0) == l) || (node_active_link(n, 1) == l); 147 return (node_active_link(n, 0) == l) || (node_active_link(n, 1) == l);
148} 148}
149 149
150static u32 link_own_addr(struct tipc_link *l)
151{
152 return msg_prevnode(l->pmsg);
153}
154
150/** 155/**
151 * tipc_link_create - create a new link 156 * tipc_link_create - create a new link
152 * @n_ptr: pointer to associated node 157 * @n: pointer to associated node
153 * @b_ptr: pointer to associated bearer 158 * @b: pointer to associated bearer
154 * @media_addr: media address to use when sending messages over link 159 * @ownnode: identity of own node
160 * @peer: identity of peer node
161 * @maddr: media address to be used
162 * @inputq: queue to put messages ready for delivery
163 * @namedq: queue to put binding table update messages ready for delivery
164 * @link: return value, pointer to put the created link
155 * 165 *
156 * Returns pointer to link. 166 * Returns true if link was created, otherwise false
157 */ 167 */
158struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, 168bool tipc_link_create(struct tipc_node *n, struct tipc_bearer *b, u32 session,
159 struct tipc_bearer *b_ptr, 169 u32 ownnode, u32 peer, struct tipc_media_addr *maddr,
160 const struct tipc_media_addr *media_addr, 170 struct sk_buff_head *inputq, struct sk_buff_head *namedq,
161 struct sk_buff_head *inputq, 171 struct tipc_link **link)
162 struct sk_buff_head *namedq)
163{ 172{
164 struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id); 173 struct tipc_link *l;
165 struct tipc_link *l_ptr; 174 struct tipc_msg *hdr;
166 struct tipc_msg *msg;
167 char *if_name; 175 char *if_name;
168 char addr_string[16];
169 u32 peer = n_ptr->addr;
170 176
171 if (n_ptr->link_cnt >= MAX_BEARERS) { 177 l = kzalloc(sizeof(*l), GFP_ATOMIC);
172 tipc_addr_string_fill(addr_string, n_ptr->addr); 178 if (!l)
173 pr_err("Cannot establish %uth link to %s. Max %u allowed.\n", 179 return false;
174 n_ptr->link_cnt, addr_string, MAX_BEARERS); 180 *link = l;
175 return NULL;
176 }
177 181
178 if (n_ptr->links[b_ptr->identity].link) { 182 /* Note: peer i/f name is completed by reset/activate message */
179 tipc_addr_string_fill(addr_string, n_ptr->addr); 183 if_name = strchr(b->name, ':') + 1;
180 pr_err("Attempt to establish second link on <%s> to %s\n", 184 sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
181 b_ptr->name, addr_string); 185 tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode),
182 return NULL; 186 if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
183 }
184 187
185 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); 188 l->addr = peer;
186 if (!l_ptr) { 189 l->media_addr = maddr;
187 pr_warn("Link creation failed, no memory\n"); 190 l->owner = n;
188 return NULL; 191 l->peer_session = WILDCARD_SESSION;
189 } 192 l->bearer_id = b->identity;
190 l_ptr->addr = peer; 193 l->tolerance = b->tolerance;
191 if_name = strchr(b_ptr->name, ':') + 1; 194 l->net_plane = b->net_plane;
192 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown", 195 l->advertised_mtu = b->mtu;
193 tipc_zone(tn->own_addr), tipc_cluster(tn->own_addr), 196 l->mtu = b->mtu;
194 tipc_node(tn->own_addr), 197 l->priority = b->priority;
195 if_name, 198 tipc_link_set_queue_limits(l, b->window);
196 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 199 l->inputq = inputq;
197 /* note: peer i/f name is updated by reset/activate message */ 200 l->namedq = namedq;
198 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 201 l->state = LINK_RESETTING;
199 l_ptr->owner = n_ptr; 202 l->pmsg = (struct tipc_msg *)&l->proto_msg;
200 l_ptr->peer_session = WILDCARD_SESSION; 203 hdr = l->pmsg;
201 l_ptr->bearer_id = b_ptr->identity; 204 tipc_msg_init(ownnode, hdr, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, peer);
202 l_ptr->tolerance = b_ptr->tolerance; 205 msg_set_size(hdr, sizeof(l->proto_msg));
203 l_ptr->snd_nxt = 1; 206 msg_set_session(hdr, session);
204 l_ptr->rcv_nxt = 1; 207 msg_set_bearer_id(hdr, l->bearer_id);
205 l_ptr->state = LINK_RESET; 208 strcpy((char *)msg_data(hdr), if_name);
206 209 __skb_queue_head_init(&l->transmq);
207 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; 210 __skb_queue_head_init(&l->backlogq);
208 msg = l_ptr->pmsg; 211 __skb_queue_head_init(&l->deferdq);
209 tipc_msg_init(tn->own_addr, msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, 212 skb_queue_head_init(&l->wakeupq);
210 l_ptr->addr); 213 skb_queue_head_init(l->inputq);
211 msg_set_size(msg, sizeof(l_ptr->proto_msg)); 214 return true;
212 msg_set_session(msg, (tn->random & 0xffff));
213 msg_set_bearer_id(msg, b_ptr->identity);
214 strcpy((char *)msg_data(msg), if_name);
215 l_ptr->net_plane = b_ptr->net_plane;
216 l_ptr->advertised_mtu = b_ptr->mtu;
217 l_ptr->mtu = l_ptr->advertised_mtu;
218 l_ptr->priority = b_ptr->priority;
219 tipc_link_set_queue_limits(l_ptr, b_ptr->window);
220 l_ptr->snd_nxt = 1;
221 __skb_queue_head_init(&l_ptr->transmq);
222 __skb_queue_head_init(&l_ptr->backlogq);
223 __skb_queue_head_init(&l_ptr->deferdq);
224 skb_queue_head_init(&l_ptr->wakeupq);
225 l_ptr->inputq = inputq;
226 l_ptr->namedq = namedq;
227 skb_queue_head_init(l_ptr->inputq);
228 link_reset_statistics(l_ptr);
229 tipc_node_attach_link(n_ptr, l_ptr);
230 return l_ptr;
231} 215}
232 216
233/* tipc_link_build_bcast_sync_msg() - synchronize broadcast link endpoints. 217/* 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 u16 ack = mod(link->rcv_nxt - 1); 627 u16 ack = mod(link->rcv_nxt - 1);
644 u16 seqno = link->snd_nxt; 628 u16 seqno = link->snd_nxt;
645 u16 bc_last_in = link->owner->bclink.last_in; 629 u16 bc_last_in = link->owner->bclink.last_in;
646 struct tipc_media_addr *addr = &link->media_addr; 630 struct tipc_media_addr *addr = link->media_addr;
647 struct sk_buff_head *transmq = &link->transmq; 631 struct sk_buff_head *transmq = &link->transmq;
648 struct sk_buff_head *backlogq = &link->backlogq; 632 struct sk_buff_head *backlogq = &link->backlogq;
649 struct sk_buff *skb, *bskb; 633 struct sk_buff *skb, *bskb;
@@ -809,7 +793,7 @@ void tipc_link_push_packets(struct tipc_link *link)
809 link->rcv_unacked = 0; 793 link->rcv_unacked = 0;
810 __skb_queue_tail(&link->transmq, skb); 794 __skb_queue_tail(&link->transmq, skb);
811 tipc_bearer_send(link->owner->net, link->bearer_id, 795 tipc_bearer_send(link->owner->net, link->bearer_id,
812 skb, &link->media_addr); 796 skb, link->media_addr);
813 } 797 }
814 link->snd_nxt = seqno; 798 link->snd_nxt = seqno;
815} 799}
@@ -912,7 +896,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb,
912 msg_set_ack(msg, mod(l_ptr->rcv_nxt - 1)); 896 msg_set_ack(msg, mod(l_ptr->rcv_nxt - 1));
913 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 897 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
914 tipc_bearer_send(l_ptr->owner->net, l_ptr->bearer_id, skb, 898 tipc_bearer_send(l_ptr->owner->net, l_ptr->bearer_id, skb,
915 &l_ptr->media_addr); 899 l_ptr->media_addr);
916 retransmits--; 900 retransmits--;
917 l_ptr->stats.retransmitted++; 901 l_ptr->stats.retransmitted++;
918 } 902 }
@@ -1200,7 +1184,7 @@ void tipc_link_proto_xmit(struct tipc_link *l, u32 msg_typ, int probe_msg,
1200 skb = __skb_dequeue(&xmitq); 1184 skb = __skb_dequeue(&xmitq);
1201 if (!skb) 1185 if (!skb)
1202 return; 1186 return;
1203 tipc_bearer_send(l->owner->net, l->bearer_id, skb, &l->media_addr); 1187 tipc_bearer_send(l->owner->net, l->bearer_id, skb, l->media_addr);
1204 l->rcv_unacked = 0; 1188 l->rcv_unacked = 0;
1205 kfree_skb(skb); 1189 kfree_skb(skb);
1206} 1190}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 39b8c4c5121e..39ff8b6919a4 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -148,7 +148,7 @@ struct tipc_stats {
148struct tipc_link { 148struct tipc_link {
149 u32 addr; 149 u32 addr;
150 char name[TIPC_MAX_LINK_NAME]; 150 char name[TIPC_MAX_LINK_NAME];
151 struct tipc_media_addr media_addr; 151 struct tipc_media_addr *media_addr;
152 struct tipc_node *owner; 152 struct tipc_node *owner;
153 153
154 /* Management and link supervision data */ 154 /* Management and link supervision data */
@@ -205,13 +205,10 @@ struct tipc_link {
205 struct tipc_stats stats; 205 struct tipc_stats stats;
206}; 206};
207 207
208struct tipc_port; 208bool tipc_link_create(struct tipc_node *n, struct tipc_bearer *b, u32 session,
209 209 u32 ownnode, u32 peer, struct tipc_media_addr *maddr,
210struct tipc_link *tipc_link_create(struct tipc_node *n, 210 struct sk_buff_head *inputq, struct sk_buff_head *namedq,
211 struct tipc_bearer *b, 211 struct tipc_link **link);
212 const struct tipc_media_addr *maddr,
213 struct sk_buff_head *inputq,
214 struct sk_buff_head *namedq);
215void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, 212void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
216 int mtyp, struct sk_buff_head *xmitq); 213 int mtyp, struct sk_buff_head *xmitq);
217void tipc_link_build_bcast_sync_msg(struct tipc_link *l, 214void 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);
246int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info); 243int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info);
247int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info); 244int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info);
248int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); 245int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
249void link_prepare_wakeup(struct tipc_link *l);
250int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq); 246int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq);
251int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, 247int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
252 struct sk_buff_head *xmitq); 248 struct sk_buff_head *xmitq);
253static inline u32 link_own_addr(struct tipc_link *l)
254{
255 return msg_prevnode(l->pmsg);
256}
257 249
258#endif 250#endif
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 9e9b0938bd17..7c191641b44f 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -320,10 +320,6 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
320 if (!nl || !tipc_link_is_up(nl)) 320 if (!nl || !tipc_link_is_up(nl))
321 return; 321 return;
322 322
323 if (n->working_links > 1) {
324 pr_warn("Attempt to establish 3rd link to %x\n", n->addr);
325 return;
326 }
327 n->working_links++; 323 n->working_links++;
328 n->action_flags |= TIPC_NOTIFY_LINK_UP; 324 n->action_flags |= TIPC_NOTIFY_LINK_UP;
329 n->link_id = nl->peer_bearer_id << 16 | bearer_id; 325 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{ 466{
471 struct tipc_node *n; 467 struct tipc_node *n;
472 struct tipc_link *l; 468 struct tipc_link *l;
473 struct tipc_media_addr *curr_maddr; 469 struct tipc_link_entry *le;
474 struct sk_buff_head *inputq;
475 bool addr_match = false; 470 bool addr_match = false;
476 bool sign_match = false; 471 bool sign_match = false;
477 bool link_up = false; 472 bool link_up = false;
478 bool accept_addr = false; 473 bool accept_addr = false;
479 bool reset = true; 474 bool reset = true;
475
480 *dupl_addr = false; 476 *dupl_addr = false;
481 *respond = false; 477 *respond = false;
482 478
@@ -486,13 +482,12 @@ void tipc_node_check_dest(struct net *net, u32 onode,
486 482
487 tipc_node_lock(n); 483 tipc_node_lock(n);
488 484
489 curr_maddr = &n->links[b->identity].maddr; 485 le = &n->links[b->identity];
490 inputq = &n->links[b->identity].inputq;
491 486
492 /* Prepare to validate requesting node's signature and media address */ 487 /* Prepare to validate requesting node's signature and media address */
493 l = n->links[b->identity].link; 488 l = le->link;
494 link_up = l && tipc_link_is_up(l); 489 link_up = l && tipc_link_is_up(l);
495 addr_match = l && !memcmp(curr_maddr, maddr, sizeof(*maddr)); 490 addr_match = l && !memcmp(&le->maddr, maddr, sizeof(*maddr));
496 sign_match = (signature == n->signature); 491 sign_match = (signature == n->signature);
497 492
498 /* These three flags give us eight permutations: */ 493 /* These three flags give us eight permutations: */
@@ -559,18 +554,25 @@ void tipc_node_check_dest(struct net *net, u32 onode,
559 554
560 /* Now create new link if not already existing */ 555 /* Now create new link if not already existing */
561 if (!l) { 556 if (!l) {
562 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq); 557 if (n->link_cnt == 2) {
563 if (!l) { 558 pr_warn("Cannot establish 3rd link to %x\n", n->addr);
559 goto exit;
560 }
561 if (!tipc_link_create(n, b, mod(tipc_net(net)->random),
562 tipc_own_addr(net), onode, &le->maddr,
563 &le->inputq, &n->bclink.namedq, &l)) {
564 *respond = false; 564 *respond = false;
565 goto exit; 565 goto exit;
566 } 566 }
567 tipc_link_reset(l);
568 le->link = l;
569 n->link_cnt++;
567 tipc_node_calculate_timer(n, l); 570 tipc_node_calculate_timer(n, l);
568 if (n->link_cnt == 1) 571 if (n->link_cnt == 1)
569 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv)) 572 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv))
570 tipc_node_get(n); 573 tipc_node_get(n);
571 } 574 }
572 memcpy(&l->media_addr, maddr, sizeof(*maddr)); 575 memcpy(&le->maddr, maddr, sizeof(*maddr));
573 memcpy(curr_maddr, maddr, sizeof(*maddr));
574exit: 576exit:
575 tipc_node_unlock(n); 577 tipc_node_unlock(n);
576 if (reset) 578 if (reset)
@@ -603,24 +605,6 @@ static void tipc_node_reset_links(struct tipc_node *n)
603 } 605 }
604} 606}
605 607
606void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
607{
608 n_ptr->links[l_ptr->bearer_id].link = l_ptr;
609 n_ptr->link_cnt++;
610}
611
612void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
613{
614 int i;
615
616 for (i = 0; i < MAX_BEARERS; i++) {
617 if (l_ptr != n_ptr->links[i].link)
618 continue;
619 n_ptr->links[i].link = NULL;
620 n_ptr->link_cnt--;
621 }
622}
623
624/* tipc_node_fsm_evt - node finite state machine 608/* tipc_node_fsm_evt - node finite state machine
625 * Determines when contact is allowed with peer node 609 * Determines when contact is allowed with peer node
626 */ 610 */