diff options
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 198dbc7adbe1..507017fe0f1b 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -153,11 +153,11 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, | |||
153 | bool delete); | 153 | bool delete); |
154 | static void node_lost_contact(struct tipc_node *n, struct sk_buff_head *inputq); | 154 | static void node_lost_contact(struct tipc_node *n, struct sk_buff_head *inputq); |
155 | static void tipc_node_delete(struct tipc_node *node); | 155 | static void tipc_node_delete(struct tipc_node *node); |
156 | static void tipc_node_timeout(unsigned long data); | 156 | static void tipc_node_timeout(struct timer_list *t); |
157 | static void tipc_node_fsm_evt(struct tipc_node *n, int evt); | 157 | static void tipc_node_fsm_evt(struct tipc_node *n, int evt); |
158 | static struct tipc_node *tipc_node_find(struct net *net, u32 addr); | 158 | static struct tipc_node *tipc_node_find(struct net *net, u32 addr); |
159 | static void tipc_node_put(struct tipc_node *node); | 159 | static void tipc_node_put(struct tipc_node *node); |
160 | static bool tipc_node_is_up(struct tipc_node *n); | 160 | static bool node_is_up(struct tipc_node *n); |
161 | 161 | ||
162 | struct tipc_sock_conn { | 162 | struct tipc_sock_conn { |
163 | u32 port; | 163 | u32 port; |
@@ -361,7 +361,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities) | |||
361 | goto exit; | 361 | goto exit; |
362 | } | 362 | } |
363 | tipc_node_get(n); | 363 | tipc_node_get(n); |
364 | setup_timer(&n->timer, tipc_node_timeout, (unsigned long)n); | 364 | timer_setup(&n->timer, tipc_node_timeout, 0); |
365 | n->keepalive_intv = U32_MAX; | 365 | n->keepalive_intv = U32_MAX; |
366 | hlist_add_head_rcu(&n->hash, &tn->node_htable[tipc_hashfn(addr)]); | 366 | hlist_add_head_rcu(&n->hash, &tn->node_htable[tipc_hashfn(addr)]); |
367 | list_for_each_entry_rcu(temp_node, &tn->node_list, list) { | 367 | list_for_each_entry_rcu(temp_node, &tn->node_list, list) { |
@@ -500,9 +500,9 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port) | |||
500 | 500 | ||
501 | /* tipc_node_timeout - handle expiration of node timer | 501 | /* tipc_node_timeout - handle expiration of node timer |
502 | */ | 502 | */ |
503 | static void tipc_node_timeout(unsigned long data) | 503 | static void tipc_node_timeout(struct timer_list *t) |
504 | { | 504 | { |
505 | struct tipc_node *n = (struct tipc_node *)data; | 505 | struct tipc_node *n = from_timer(n, t, timer); |
506 | struct tipc_link_entry *le; | 506 | struct tipc_link_entry *le; |
507 | struct sk_buff_head xmitq; | 507 | struct sk_buff_head xmitq; |
508 | int bearer_id; | 508 | int bearer_id; |
@@ -657,7 +657,7 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id, | |||
657 | *slot1 = i; | 657 | *slot1 = i; |
658 | } | 658 | } |
659 | 659 | ||
660 | if (!tipc_node_is_up(n)) { | 660 | if (!node_is_up(n)) { |
661 | if (tipc_link_peer_is_down(l)) | 661 | if (tipc_link_peer_is_down(l)) |
662 | tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT); | 662 | tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT); |
663 | tipc_node_fsm_evt(n, SELF_LOST_CONTACT_EVT); | 663 | tipc_node_fsm_evt(n, SELF_LOST_CONTACT_EVT); |
@@ -717,11 +717,27 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) | |||
717 | tipc_sk_rcv(n->net, &le->inputq); | 717 | tipc_sk_rcv(n->net, &le->inputq); |
718 | } | 718 | } |
719 | 719 | ||
720 | static bool tipc_node_is_up(struct tipc_node *n) | 720 | static bool node_is_up(struct tipc_node *n) |
721 | { | 721 | { |
722 | return n->active_links[0] != INVALID_BEARER_ID; | 722 | return n->active_links[0] != INVALID_BEARER_ID; |
723 | } | 723 | } |
724 | 724 | ||
725 | bool tipc_node_is_up(struct net *net, u32 addr) | ||
726 | { | ||
727 | struct tipc_node *n; | ||
728 | bool retval = false; | ||
729 | |||
730 | if (in_own_node(net, addr)) | ||
731 | return true; | ||
732 | |||
733 | n = tipc_node_find(net, addr); | ||
734 | if (!n) | ||
735 | return false; | ||
736 | retval = node_is_up(n); | ||
737 | tipc_node_put(n); | ||
738 | return retval; | ||
739 | } | ||
740 | |||
725 | void tipc_node_check_dest(struct net *net, u32 onode, | 741 | void tipc_node_check_dest(struct net *net, u32 onode, |
726 | struct tipc_bearer *b, | 742 | struct tipc_bearer *b, |
727 | u16 capabilities, u32 signature, | 743 | u16 capabilities, u32 signature, |
@@ -1149,7 +1165,7 @@ static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node) | |||
1149 | 1165 | ||
1150 | if (nla_put_u32(msg->skb, TIPC_NLA_NODE_ADDR, node->addr)) | 1166 | if (nla_put_u32(msg->skb, TIPC_NLA_NODE_ADDR, node->addr)) |
1151 | goto attr_msg_full; | 1167 | goto attr_msg_full; |
1152 | if (tipc_node_is_up(node)) | 1168 | if (node_is_up(node)) |
1153 | if (nla_put_flag(msg->skb, TIPC_NLA_NODE_UP)) | 1169 | if (nla_put_flag(msg->skb, TIPC_NLA_NODE_UP)) |
1154 | goto attr_msg_full; | 1170 | goto attr_msg_full; |
1155 | 1171 | ||
@@ -1238,6 +1254,22 @@ int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode, | |||
1238 | return 0; | 1254 | return 0; |
1239 | } | 1255 | } |
1240 | 1256 | ||
1257 | /* tipc_node_distr_xmit(): send single buffer msgs to individual destinations | ||
1258 | * Note: this is only for SYSTEM_IMPORTANCE messages, which cannot be rejected | ||
1259 | */ | ||
1260 | int tipc_node_distr_xmit(struct net *net, struct sk_buff_head *xmitq) | ||
1261 | { | ||
1262 | struct sk_buff *skb; | ||
1263 | u32 selector, dnode; | ||
1264 | |||
1265 | while ((skb = __skb_dequeue(xmitq))) { | ||
1266 | selector = msg_origport(buf_msg(skb)); | ||
1267 | dnode = msg_destnode(buf_msg(skb)); | ||
1268 | tipc_node_xmit_skb(net, skb, dnode, selector); | ||
1269 | } | ||
1270 | return 0; | ||
1271 | } | ||
1272 | |||
1241 | void tipc_node_broadcast(struct net *net, struct sk_buff *skb) | 1273 | void tipc_node_broadcast(struct net *net, struct sk_buff *skb) |
1242 | { | 1274 | { |
1243 | struct sk_buff *txskb; | 1275 | struct sk_buff *txskb; |
@@ -1249,7 +1281,7 @@ void tipc_node_broadcast(struct net *net, struct sk_buff *skb) | |||
1249 | dst = n->addr; | 1281 | dst = n->addr; |
1250 | if (in_own_node(net, dst)) | 1282 | if (in_own_node(net, dst)) |
1251 | continue; | 1283 | continue; |
1252 | if (!tipc_node_is_up(n)) | 1284 | if (!node_is_up(n)) |
1253 | continue; | 1285 | continue; |
1254 | txskb = pskb_copy(skb, GFP_ATOMIC); | 1286 | txskb = pskb_copy(skb, GFP_ATOMIC); |
1255 | if (!txskb) | 1287 | if (!txskb) |
@@ -1507,7 +1539,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | |||
1507 | __skb_queue_head_init(&xmitq); | 1539 | __skb_queue_head_init(&xmitq); |
1508 | 1540 | ||
1509 | /* Ensure message is well-formed before touching the header */ | 1541 | /* Ensure message is well-formed before touching the header */ |
1510 | if (unlikely(!tipc_msg_validate(skb))) | 1542 | if (unlikely(!tipc_msg_validate(&skb))) |
1511 | goto discard; | 1543 | goto discard; |
1512 | hdr = buf_msg(skb); | 1544 | hdr = buf_msg(skb); |
1513 | usr = msg_user(hdr); | 1545 | usr = msg_user(hdr); |