Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jon Paul Maloy and committed by
David S. Miller
440d8963 9073fb8b

+86 -121
+5
net/tipc/core.h
··· 109 109 atomic_t subscription_count; 110 110 }; 111 111 112 + static inline struct tipc_net *tipc_net(struct net *net) 113 + { 114 + return net_generic(net, tipc_net_id); 115 + } 116 + 112 117 static inline u16 mod(u16 x) 113 118 { 114 119 return x & 0xffffu;
+60 -76
net/tipc/link.c
··· 147 147 return (node_active_link(n, 0) == l) || (node_active_link(n, 1) == l); 148 148 } 149 149 150 + static u32 link_own_addr(struct tipc_link *l) 151 + { 152 + return msg_prevnode(l->pmsg); 153 + } 154 + 150 155 /** 151 156 * tipc_link_create - create a new link 152 - * @n_ptr: pointer to associated node 153 - * @b_ptr: pointer to associated bearer 154 - * @media_addr: media address to use when sending messages over link 157 + * @n: pointer to associated node 158 + * @b: pointer to associated bearer 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 */ 158 - struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, 159 - struct tipc_bearer *b_ptr, 160 - const struct tipc_media_addr *media_addr, 161 - struct sk_buff_head *inputq, 162 - struct sk_buff_head *namedq) 168 + bool tipc_link_create(struct tipc_node *n, struct tipc_bearer *b, u32 session, 169 + u32 ownnode, u32 peer, struct tipc_media_addr *maddr, 170 + struct sk_buff_head *inputq, struct sk_buff_head *namedq, 171 + struct tipc_link **link) 163 172 { 164 - struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id); 165 - struct tipc_link *l_ptr; 166 - struct tipc_msg *msg; 173 + struct tipc_link *l; 174 + struct tipc_msg *hdr; 167 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) { 172 - tipc_addr_string_fill(addr_string, n_ptr->addr); 173 - pr_err("Cannot establish %uth link to %s. Max %u allowed.\n", 174 - n_ptr->link_cnt, addr_string, MAX_BEARERS); 175 - return NULL; 176 - } 177 + l = kzalloc(sizeof(*l), GFP_ATOMIC); 178 + if (!l) 179 + return false; 180 + *link = l; 177 181 178 - if (n_ptr->links[b_ptr->identity].link) { 179 - tipc_addr_string_fill(addr_string, n_ptr->addr); 180 - pr_err("Attempt to establish second link on <%s> to %s\n", 181 - b_ptr->name, addr_string); 182 - return NULL; 183 - } 182 + /* Note: peer i/f name is completed by reset/activate message */ 183 + if_name = strchr(b->name, ':') + 1; 184 + sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown", 185 + tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode), 186 + if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 184 187 185 - l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); 186 - if (!l_ptr) { 187 - pr_warn("Link creation failed, no memory\n"); 188 - return NULL; 189 - } 190 - l_ptr->addr = peer; 191 - if_name = strchr(b_ptr->name, ':') + 1; 192 - sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown", 193 - tipc_zone(tn->own_addr), tipc_cluster(tn->own_addr), 194 - tipc_node(tn->own_addr), 195 - if_name, 196 - tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 197 - /* note: peer i/f name is updated by reset/activate message */ 198 - memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 199 - l_ptr->owner = n_ptr; 200 - l_ptr->peer_session = WILDCARD_SESSION; 201 - l_ptr->bearer_id = b_ptr->identity; 202 - l_ptr->tolerance = b_ptr->tolerance; 203 - l_ptr->snd_nxt = 1; 204 - l_ptr->rcv_nxt = 1; 205 - l_ptr->state = LINK_RESET; 206 - 207 - l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; 208 - msg = l_ptr->pmsg; 209 - tipc_msg_init(tn->own_addr, msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, 210 - l_ptr->addr); 211 - msg_set_size(msg, sizeof(l_ptr->proto_msg)); 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; 188 + l->addr = peer; 189 + l->media_addr = maddr; 190 + l->owner = n; 191 + l->peer_session = WILDCARD_SESSION; 192 + l->bearer_id = b->identity; 193 + l->tolerance = b->tolerance; 194 + l->net_plane = b->net_plane; 195 + l->advertised_mtu = b->mtu; 196 + l->mtu = b->mtu; 197 + l->priority = b->priority; 198 + tipc_link_set_queue_limits(l, b->window); 199 + l->inputq = inputq; 200 + l->namedq = namedq; 201 + l->state = LINK_RESETTING; 202 + l->pmsg = (struct tipc_msg *)&l->proto_msg; 203 + hdr = l->pmsg; 204 + tipc_msg_init(ownnode, hdr, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, peer); 205 + msg_set_size(hdr, sizeof(l->proto_msg)); 206 + msg_set_session(hdr, session); 207 + msg_set_bearer_id(hdr, l->bearer_id); 208 + strcpy((char *)msg_data(hdr), if_name); 209 + __skb_queue_head_init(&l->transmq); 210 + __skb_queue_head_init(&l->backlogq); 211 + __skb_queue_head_init(&l->deferdq); 212 + skb_queue_head_init(&l->wakeupq); 213 + skb_queue_head_init(l->inputq); 214 + return true; 231 215 } 232 216 233 217 /* tipc_link_build_bcast_sync_msg() - synchronize broadcast link endpoints. ··· 627 643 u16 ack = mod(link->rcv_nxt - 1); 628 644 u16 seqno = link->snd_nxt; 629 645 u16 bc_last_in = link->owner->bclink.last_in; 630 - struct tipc_media_addr *addr = &link->media_addr; 646 + struct tipc_media_addr *addr = link->media_addr; 631 647 struct sk_buff_head *transmq = &link->transmq; 632 648 struct sk_buff_head *backlogq = &link->backlogq; 633 649 struct sk_buff *skb, *bskb; ··· 793 809 link->rcv_unacked = 0; 794 810 __skb_queue_tail(&link->transmq, skb); 795 811 tipc_bearer_send(link->owner->net, link->bearer_id, 796 - skb, &link->media_addr); 812 + skb, link->media_addr); 797 813 } 798 814 link->snd_nxt = seqno; 799 815 } ··· 896 912 msg_set_ack(msg, mod(l_ptr->rcv_nxt - 1)); 897 913 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 898 914 tipc_bearer_send(l_ptr->owner->net, l_ptr->bearer_id, skb, 899 - &l_ptr->media_addr); 915 + l_ptr->media_addr); 900 916 retransmits--; 901 917 l_ptr->stats.retransmitted++; 902 918 } ··· 1184 1200 skb = __skb_dequeue(&xmitq); 1185 1201 if (!skb) 1186 1202 return; 1187 - tipc_bearer_send(l->owner->net, l->bearer_id, skb, &l->media_addr); 1203 + tipc_bearer_send(l->owner->net, l->bearer_id, skb, l->media_addr); 1188 1204 l->rcv_unacked = 0; 1189 1205 kfree_skb(skb); 1190 1206 }
+5 -13
net/tipc/link.h
··· 148 148 struct tipc_link { 149 149 u32 addr; 150 150 char name[TIPC_MAX_LINK_NAME]; 151 - struct tipc_media_addr media_addr; 151 + struct tipc_media_addr *media_addr; 152 152 struct tipc_node *owner; 153 153 154 154 /* Management and link supervision data */ ··· 205 205 struct tipc_stats stats; 206 206 }; 207 207 208 - struct tipc_port; 209 - 210 - struct tipc_link *tipc_link_create(struct tipc_node *n, 211 - struct tipc_bearer *b, 212 - const struct tipc_media_addr *maddr, 213 - struct sk_buff_head *inputq, 214 - struct sk_buff_head *namedq); 208 + bool tipc_link_create(struct tipc_node *n, struct tipc_bearer *b, u32 session, 209 + u32 ownnode, u32 peer, struct tipc_media_addr *maddr, 210 + struct sk_buff_head *inputq, struct sk_buff_head *namedq, 211 + struct tipc_link **link); 215 212 void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, 216 213 int mtyp, struct sk_buff_head *xmitq); 217 214 void tipc_link_build_bcast_sync_msg(struct tipc_link *l, ··· 243 246 int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info); 244 247 int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info); 245 248 int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); 246 - void link_prepare_wakeup(struct tipc_link *l); 247 249 int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq); 248 250 int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, 249 251 struct sk_buff_head *xmitq); 250 - static inline u32 link_own_addr(struct tipc_link *l) 251 - { 252 - return msg_prevnode(l->pmsg); 253 - } 254 252 255 253 #endif
+16 -32
net/tipc/node.c
··· 320 320 if (!nl || !tipc_link_is_up(nl)) 321 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 323 n->working_links++; 328 324 n->action_flags |= TIPC_NOTIFY_LINK_UP; 329 325 n->link_id = nl->peer_bearer_id << 16 | bearer_id; ··· 466 470 { 467 471 struct tipc_node *n; 468 472 struct tipc_link *l; 469 - struct tipc_media_addr *curr_maddr; 470 - struct sk_buff_head *inputq; 473 + struct tipc_link_entry *le; 471 474 bool addr_match = false; 472 475 bool sign_match = false; 473 476 bool link_up = false; 474 477 bool accept_addr = false; 475 478 bool reset = true; 479 + 476 480 *dupl_addr = false; 477 481 *respond = false; 478 482 ··· 482 486 483 487 tipc_node_lock(n); 484 488 485 - curr_maddr = &n->links[b->identity].maddr; 486 - inputq = &n->links[b->identity].inputq; 489 + le = &n->links[b->identity]; 487 490 488 491 /* Prepare to validate requesting node's signature and media address */ 489 - l = n->links[b->identity].link; 492 + l = le->link; 490 493 link_up = l && tipc_link_is_up(l); 491 - addr_match = l && !memcmp(curr_maddr, maddr, sizeof(*maddr)); 494 + addr_match = l && !memcmp(&le->maddr, maddr, sizeof(*maddr)); 492 495 sign_match = (signature == n->signature); 493 496 494 497 /* These three flags give us eight permutations: */ ··· 554 559 555 560 /* Now create new link if not already existing */ 556 561 if (!l) { 557 - l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq); 558 - if (!l) { 562 + if (n->link_cnt == 2) { 563 + pr_warn("Cannot establish 3rd link to %x\n", n->addr); 564 + goto exit; 565 + } 566 + if (!tipc_link_create(n, b, mod(tipc_net(net)->random), 567 + tipc_own_addr(net), onode, &le->maddr, 568 + &le->inputq, &n->bclink.namedq, &l)) { 559 569 *respond = false; 560 570 goto exit; 561 571 } 572 + tipc_link_reset(l); 573 + le->link = l; 574 + n->link_cnt++; 562 575 tipc_node_calculate_timer(n, l); 563 576 if (n->link_cnt == 1) 564 577 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv)) 565 578 tipc_node_get(n); 566 579 } 567 - memcpy(&l->media_addr, maddr, sizeof(*maddr)); 568 - memcpy(curr_maddr, maddr, sizeof(*maddr)); 580 + memcpy(&le->maddr, maddr, sizeof(*maddr)); 569 581 exit: 570 582 tipc_node_unlock(n); 571 583 if (reset) ··· 602 600 603 601 for (i = 0; i < MAX_BEARERS; i++) { 604 602 tipc_node_link_down(n, i, false); 605 - } 606 - } 607 - 608 - void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 609 - { 610 - n_ptr->links[l_ptr->bearer_id].link = l_ptr; 611 - n_ptr->link_cnt++; 612 - } 613 - 614 - void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 615 - { 616 - int i; 617 - 618 - for (i = 0; i < MAX_BEARERS; i++) { 619 - if (l_ptr != n_ptr->links[i].link) 620 - continue; 621 - n_ptr->links[i].link = NULL; 622 - n_ptr->link_cnt--; 623 603 } 624 604 } 625 605