diff options
Diffstat (limited to 'net/tipc')
| -rw-r--r-- | net/tipc/node.c | 46 | ||||
| -rw-r--r-- | net/tipc/node.h | 7 | ||||
| -rw-r--r-- | net/tipc/socket.c | 6 |
3 files changed, 37 insertions, 22 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 90cee4a6fce4..5781634e957d 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
| @@ -219,11 +219,11 @@ void tipc_node_abort_sock_conns(struct list_head *conns) | |||
| 219 | void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr) | 219 | void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr) |
| 220 | { | 220 | { |
| 221 | struct tipc_link **active = &n_ptr->active_links[0]; | 221 | struct tipc_link **active = &n_ptr->active_links[0]; |
| 222 | u32 addr = n_ptr->addr; | ||
| 223 | 222 | ||
| 224 | n_ptr->working_links++; | 223 | n_ptr->working_links++; |
| 225 | tipc_nametbl_publish(TIPC_LINK_STATE, addr, addr, TIPC_NODE_SCOPE, | 224 | n_ptr->action_flags |= TIPC_NOTIFY_LINK_UP; |
| 226 | l_ptr->bearer_id, addr); | 225 | n_ptr->link_id = l_ptr->peer_bearer_id << 16 | l_ptr->bearer_id; |
| 226 | |||
| 227 | pr_info("Established link <%s> on network plane %c\n", | 227 | pr_info("Established link <%s> on network plane %c\n", |
| 228 | l_ptr->name, l_ptr->net_plane); | 228 | l_ptr->name, l_ptr->net_plane); |
| 229 | 229 | ||
| @@ -284,10 +284,10 @@ static void node_select_active_links(struct tipc_node *n_ptr) | |||
| 284 | void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr) | 284 | void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr) |
| 285 | { | 285 | { |
| 286 | struct tipc_link **active; | 286 | struct tipc_link **active; |
| 287 | u32 addr = n_ptr->addr; | ||
| 288 | 287 | ||
| 289 | n_ptr->working_links--; | 288 | n_ptr->working_links--; |
| 290 | tipc_nametbl_withdraw(TIPC_LINK_STATE, addr, l_ptr->bearer_id, addr); | 289 | n_ptr->action_flags |= TIPC_NOTIFY_LINK_DOWN; |
| 290 | n_ptr->link_id = l_ptr->peer_bearer_id << 16 | l_ptr->bearer_id; | ||
| 291 | 291 | ||
| 292 | if (!tipc_link_is_active(l_ptr)) { | 292 | if (!tipc_link_is_active(l_ptr)) { |
| 293 | pr_info("Lost standby link <%s> on network plane %c\n", | 293 | pr_info("Lost standby link <%s> on network plane %c\n", |
| @@ -552,28 +552,30 @@ void tipc_node_unlock(struct tipc_node *node) | |||
| 552 | LIST_HEAD(conn_sks); | 552 | LIST_HEAD(conn_sks); |
| 553 | struct sk_buff_head waiting_sks; | 553 | struct sk_buff_head waiting_sks; |
| 554 | u32 addr = 0; | 554 | u32 addr = 0; |
| 555 | unsigned int flags = node->action_flags; | 555 | int flags = node->action_flags; |
| 556 | u32 link_id = 0; | ||
| 556 | 557 | ||
| 557 | if (likely(!node->action_flags)) { | 558 | if (likely(!flags)) { |
| 558 | spin_unlock_bh(&node->lock); | 559 | spin_unlock_bh(&node->lock); |
| 559 | return; | 560 | return; |
| 560 | } | 561 | } |
| 561 | 562 | ||
| 563 | addr = node->addr; | ||
| 564 | link_id = node->link_id; | ||
| 562 | __skb_queue_head_init(&waiting_sks); | 565 | __skb_queue_head_init(&waiting_sks); |
| 563 | if (node->action_flags & TIPC_WAKEUP_USERS) { | 566 | |
| 567 | if (flags & TIPC_WAKEUP_USERS) | ||
| 564 | skb_queue_splice_init(&node->waiting_sks, &waiting_sks); | 568 | skb_queue_splice_init(&node->waiting_sks, &waiting_sks); |
| 565 | node->action_flags &= ~TIPC_WAKEUP_USERS; | 569 | |
| 566 | } | 570 | if (flags & TIPC_NOTIFY_NODE_DOWN) { |
| 567 | if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) { | ||
| 568 | list_replace_init(&node->nsub, &nsub_list); | 571 | list_replace_init(&node->nsub, &nsub_list); |
| 569 | list_replace_init(&node->conn_sks, &conn_sks); | 572 | list_replace_init(&node->conn_sks, &conn_sks); |
| 570 | node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN; | ||
| 571 | } | 573 | } |
| 572 | if (node->action_flags & TIPC_NOTIFY_NODE_UP) { | 574 | node->action_flags &= ~(TIPC_WAKEUP_USERS | TIPC_NOTIFY_NODE_DOWN | |
| 573 | node->action_flags &= ~TIPC_NOTIFY_NODE_UP; | 575 | TIPC_NOTIFY_NODE_UP | TIPC_NOTIFY_LINK_UP | |
| 574 | addr = node->addr; | 576 | TIPC_NOTIFY_LINK_DOWN | |
| 575 | } | 577 | TIPC_WAKEUP_BCAST_USERS); |
| 576 | node->action_flags &= ~TIPC_WAKEUP_BCAST_USERS; | 578 | |
| 577 | spin_unlock_bh(&node->lock); | 579 | spin_unlock_bh(&node->lock); |
| 578 | 580 | ||
| 579 | while (!skb_queue_empty(&waiting_sks)) | 581 | while (!skb_queue_empty(&waiting_sks)) |
| @@ -588,6 +590,14 @@ void tipc_node_unlock(struct tipc_node *node) | |||
| 588 | if (flags & TIPC_WAKEUP_BCAST_USERS) | 590 | if (flags & TIPC_WAKEUP_BCAST_USERS) |
| 589 | tipc_bclink_wakeup_users(); | 591 | tipc_bclink_wakeup_users(); |
| 590 | 592 | ||
| 591 | if (addr) | 593 | if (flags & TIPC_NOTIFY_NODE_UP) |
| 592 | tipc_named_node_up(addr); | 594 | tipc_named_node_up(addr); |
| 595 | |||
| 596 | if (flags & TIPC_NOTIFY_LINK_UP) | ||
| 597 | tipc_nametbl_publish(TIPC_LINK_STATE, addr, addr, | ||
| 598 | TIPC_NODE_SCOPE, link_id, addr); | ||
| 599 | |||
| 600 | if (flags & TIPC_NOTIFY_LINK_DOWN) | ||
| 601 | tipc_nametbl_withdraw(TIPC_LINK_STATE, addr, | ||
| 602 | link_id, addr); | ||
| 593 | } | 603 | } |
diff --git a/net/tipc/node.h b/net/tipc/node.h index 67513c3c852c..04e91458bb29 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | * TIPC_WAIT_OWN_LINKS_DOWN: wait until peer node is declared down | 53 | * TIPC_WAIT_OWN_LINKS_DOWN: wait until peer node is declared down |
| 54 | * TIPC_NOTIFY_NODE_DOWN: notify node is down | 54 | * TIPC_NOTIFY_NODE_DOWN: notify node is down |
| 55 | * TIPC_NOTIFY_NODE_UP: notify node is up | 55 | * TIPC_NOTIFY_NODE_UP: notify node is up |
| 56 | * TIPC_DISTRIBUTE_NAME: publish or withdraw link state name type | ||
| 56 | */ | 57 | */ |
| 57 | enum { | 58 | enum { |
| 58 | TIPC_WAIT_PEER_LINKS_DOWN = (1 << 1), | 59 | TIPC_WAIT_PEER_LINKS_DOWN = (1 << 1), |
| @@ -60,7 +61,9 @@ enum { | |||
| 60 | TIPC_NOTIFY_NODE_DOWN = (1 << 3), | 61 | TIPC_NOTIFY_NODE_DOWN = (1 << 3), |
| 61 | TIPC_NOTIFY_NODE_UP = (1 << 4), | 62 | TIPC_NOTIFY_NODE_UP = (1 << 4), |
| 62 | TIPC_WAKEUP_USERS = (1 << 5), | 63 | TIPC_WAKEUP_USERS = (1 << 5), |
| 63 | TIPC_WAKEUP_BCAST_USERS = (1 << 6) | 64 | TIPC_WAKEUP_BCAST_USERS = (1 << 6), |
| 65 | TIPC_NOTIFY_LINK_UP = (1 << 7), | ||
| 66 | TIPC_NOTIFY_LINK_DOWN = (1 << 8) | ||
| 64 | }; | 67 | }; |
| 65 | 68 | ||
| 66 | /** | 69 | /** |
| @@ -100,6 +103,7 @@ struct tipc_node_bclink { | |||
| 100 | * @working_links: number of working links to node (both active and standby) | 103 | * @working_links: number of working links to node (both active and standby) |
| 101 | * @link_cnt: number of links to node | 104 | * @link_cnt: number of links to node |
| 102 | * @signature: node instance identifier | 105 | * @signature: node instance identifier |
| 106 | * @link_id: local and remote bearer ids of changing link, if any | ||
| 103 | * @nsub: list of "node down" subscriptions monitoring node | 107 | * @nsub: list of "node down" subscriptions monitoring node |
| 104 | * @rcu: rcu struct for tipc_node | 108 | * @rcu: rcu struct for tipc_node |
| 105 | */ | 109 | */ |
| @@ -116,6 +120,7 @@ struct tipc_node { | |||
| 116 | int link_cnt; | 120 | int link_cnt; |
| 117 | int working_links; | 121 | int working_links; |
| 118 | u32 signature; | 122 | u32 signature; |
| 123 | u32 link_id; | ||
| 119 | struct list_head nsub; | 124 | struct list_head nsub; |
| 120 | struct sk_buff_head waiting_sks; | 125 | struct sk_buff_head waiting_sks; |
| 121 | struct list_head conn_sks; | 126 | struct list_head conn_sks; |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 75275c5cf929..51bddc236a15 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -1776,7 +1776,7 @@ int tipc_sk_rcv(struct sk_buff *buf) | |||
| 1776 | sk = &tsk->sk; | 1776 | sk = &tsk->sk; |
| 1777 | 1777 | ||
| 1778 | /* Queue message */ | 1778 | /* Queue message */ |
| 1779 | bh_lock_sock(sk); | 1779 | spin_lock_bh(&sk->sk_lock.slock); |
| 1780 | 1780 | ||
| 1781 | if (!sock_owned_by_user(sk)) { | 1781 | if (!sock_owned_by_user(sk)) { |
| 1782 | rc = filter_rcv(sk, buf); | 1782 | rc = filter_rcv(sk, buf); |
| @@ -1787,7 +1787,7 @@ int tipc_sk_rcv(struct sk_buff *buf) | |||
| 1787 | if (sk_add_backlog(sk, buf, limit)) | 1787 | if (sk_add_backlog(sk, buf, limit)) |
| 1788 | rc = -TIPC_ERR_OVERLOAD; | 1788 | rc = -TIPC_ERR_OVERLOAD; |
| 1789 | } | 1789 | } |
| 1790 | bh_unlock_sock(sk); | 1790 | spin_unlock_bh(&sk->sk_lock.slock); |
| 1791 | tipc_sk_put(tsk); | 1791 | tipc_sk_put(tsk); |
| 1792 | if (likely(!rc)) | 1792 | if (likely(!rc)) |
| 1793 | return 0; | 1793 | return 0; |
| @@ -2673,7 +2673,7 @@ static int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg) | |||
| 2673 | case SIOCGETLINKNAME: | 2673 | case SIOCGETLINKNAME: |
| 2674 | if (copy_from_user(&lnr, argp, sizeof(lnr))) | 2674 | if (copy_from_user(&lnr, argp, sizeof(lnr))) |
| 2675 | return -EFAULT; | 2675 | return -EFAULT; |
| 2676 | if (!tipc_node_get_linkname(lnr.bearer_id, lnr.peer, | 2676 | if (!tipc_node_get_linkname(lnr.bearer_id & 0xffff, lnr.peer, |
| 2677 | lnr.linkname, TIPC_MAX_LINK_NAME)) { | 2677 | lnr.linkname, TIPC_MAX_LINK_NAME)) { |
| 2678 | if (copy_to_user(argp, &lnr, sizeof(lnr))) | 2678 | if (copy_to_user(argp, &lnr, sizeof(lnr))) |
| 2679 | return -EFAULT; | 2679 | return -EFAULT; |
