diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 664 | 
1 files changed, 284 insertions, 380 deletions
| diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 4731cad99d1c..679a22082fcb 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -34,22 +34,25 @@ | |||
| 34 | * POSSIBILITY OF SUCH DAMAGE. | 34 | * POSSIBILITY OF SUCH DAMAGE. | 
| 35 | */ | 35 | */ | 
| 36 | 36 | ||
| 37 | #include <linux/rhashtable.h> | ||
| 38 | #include <linux/jhash.h> | ||
| 37 | #include "core.h" | 39 | #include "core.h" | 
| 38 | #include "name_table.h" | 40 | #include "name_table.h" | 
| 39 | #include "node.h" | 41 | #include "node.h" | 
| 40 | #include "link.h" | 42 | #include "link.h" | 
| 41 | #include <linux/export.h> | ||
| 42 | #include "config.h" | 43 | #include "config.h" | 
| 43 | #include "socket.h" | 44 | #include "socket.h" | 
| 44 | 45 | ||
| 45 | #define SS_LISTENING -1 /* socket is listening */ | 46 | #define SS_LISTENING -1 /* socket is listening */ | 
| 46 | #define SS_READY -2 /* socket is connectionless */ | 47 | #define SS_READY -2 /* socket is connectionless */ | 
| 47 | 48 | ||
| 48 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 49 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 
| 49 | #define CONN_PROBING_INTERVAL 3600000 /* [ms] => 1 h */ | 50 | #define CONN_PROBING_INTERVAL msecs_to_jiffies(3600000) /* [ms] => 1 h */ | 
| 50 | #define TIPC_FWD_MSG 1 | 51 | #define TIPC_FWD_MSG 1 | 
| 51 | #define TIPC_CONN_OK 0 | 52 | #define TIPC_CONN_OK 0 | 
| 52 | #define TIPC_CONN_PROBING 1 | 53 | #define TIPC_CONN_PROBING 1 | 
| 54 | #define TIPC_MAX_PORT 0xffffffff | ||
| 55 | #define TIPC_MIN_PORT 1 | ||
| 53 | 56 | ||
| 54 | /** | 57 | /** | 
| 55 | * struct tipc_sock - TIPC socket structure | 58 | * struct tipc_sock - TIPC socket structure | 
| @@ -59,14 +62,13 @@ | |||
| 59 | * @conn_instance: TIPC instance used when connection was established | 62 | * @conn_instance: TIPC instance used when connection was established | 
| 60 | * @published: non-zero if port has one or more associated names | 63 | * @published: non-zero if port has one or more associated names | 
| 61 | * @max_pkt: maximum packet size "hint" used when building messages sent by port | 64 | * @max_pkt: maximum packet size "hint" used when building messages sent by port | 
| 62 | * @ref: unique reference to port in TIPC object registry | 65 | * @portid: unique port identity in TIPC socket hash table | 
| 63 | * @phdr: preformatted message header used when sending messages | 66 | * @phdr: preformatted message header used when sending messages | 
| 64 | * @port_list: adjacent ports in TIPC's global list of ports | 67 | * @port_list: adjacent ports in TIPC's global list of ports | 
| 65 | * @publications: list of publications for port | 68 | * @publications: list of publications for port | 
| 66 | * @pub_count: total # of publications port has made during its lifetime | 69 | * @pub_count: total # of publications port has made during its lifetime | 
| 67 | * @probing_state: | 70 | * @probing_state: | 
| 68 | * @probing_interval: | 71 | * @probing_intv: | 
| 69 | * @timer: | ||
| 70 | * @port: port - interacts with 'sk' and with the rest of the TIPC stack | 72 | * @port: port - interacts with 'sk' and with the rest of the TIPC stack | 
| 71 | * @peer_name: the peer of the connection, if any | 73 | * @peer_name: the peer of the connection, if any | 
| 72 | * @conn_timeout: the time we can wait for an unresponded setup request | 74 | * @conn_timeout: the time we can wait for an unresponded setup request | 
| @@ -74,6 +76,8 @@ | |||
| 74 | * @link_cong: non-zero if owner must sleep because of link congestion | 76 | * @link_cong: non-zero if owner must sleep because of link congestion | 
| 75 | * @sent_unacked: # messages sent by socket, and not yet acked by peer | 77 | * @sent_unacked: # messages sent by socket, and not yet acked by peer | 
| 76 | * @rcv_unacked: # messages read by user, but not yet acked back to peer | 78 | * @rcv_unacked: # messages read by user, but not yet acked back to peer | 
| 79 | * @node: hash table node | ||
| 80 | * @rcu: rcu struct for tipc_sock | ||
| 77 | */ | 81 | */ | 
| 78 | struct tipc_sock { | 82 | struct tipc_sock { | 
| 79 | struct sock sk; | 83 | struct sock sk; | 
| @@ -82,19 +86,20 @@ struct tipc_sock { | |||
| 82 | u32 conn_instance; | 86 | u32 conn_instance; | 
| 83 | int published; | 87 | int published; | 
| 84 | u32 max_pkt; | 88 | u32 max_pkt; | 
| 85 | u32 ref; | 89 | u32 portid; | 
| 86 | struct tipc_msg phdr; | 90 | struct tipc_msg phdr; | 
| 87 | struct list_head sock_list; | 91 | struct list_head sock_list; | 
| 88 | struct list_head publications; | 92 | struct list_head publications; | 
| 89 | u32 pub_count; | 93 | u32 pub_count; | 
| 90 | u32 probing_state; | 94 | u32 probing_state; | 
| 91 | u32 probing_interval; | 95 | unsigned long probing_intv; | 
| 92 | struct timer_list timer; | ||
| 93 | uint conn_timeout; | 96 | uint conn_timeout; | 
| 94 | atomic_t dupl_rcvcnt; | 97 | atomic_t dupl_rcvcnt; | 
| 95 | bool link_cong; | 98 | bool link_cong; | 
| 96 | uint sent_unacked; | 99 | uint sent_unacked; | 
| 97 | uint rcv_unacked; | 100 | uint rcv_unacked; | 
| 101 | struct rhash_head node; | ||
| 102 | struct rcu_head rcu; | ||
| 98 | }; | 103 | }; | 
| 99 | 104 | ||
| 100 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); | 105 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); | 
| @@ -103,16 +108,14 @@ static void tipc_write_space(struct sock *sk); | |||
| 103 | static int tipc_release(struct socket *sock); | 108 | static int tipc_release(struct socket *sock); | 
| 104 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); | 109 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); | 
| 105 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); | 110 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); | 
| 106 | static void tipc_sk_timeout(unsigned long ref); | 111 | static void tipc_sk_timeout(unsigned long data); | 
| 107 | static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, | 112 | static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, | 
| 108 | struct tipc_name_seq const *seq); | 113 | struct tipc_name_seq const *seq); | 
| 109 | static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | 114 | static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | 
| 110 | struct tipc_name_seq const *seq); | 115 | struct tipc_name_seq const *seq); | 
| 111 | static u32 tipc_sk_ref_acquire(struct tipc_sock *tsk); | 116 | static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid); | 
| 112 | static void tipc_sk_ref_discard(u32 ref); | 117 | static int tipc_sk_insert(struct tipc_sock *tsk); | 
| 113 | static struct tipc_sock *tipc_sk_get(u32 ref); | 118 | static void tipc_sk_remove(struct tipc_sock *tsk); | 
| 114 | static struct tipc_sock *tipc_sk_get_next(u32 *ref); | ||
| 115 | static void tipc_sk_put(struct tipc_sock *tsk); | ||
| 116 | 119 | ||
| 117 | static const struct proto_ops packet_ops; | 120 | static const struct proto_ops packet_ops; | 
| 118 | static const struct proto_ops stream_ops; | 121 | static const struct proto_ops stream_ops; | 
| @@ -246,10 +249,11 @@ static void tsk_rej_rx_queue(struct sock *sk) | |||
| 246 | { | 249 | { | 
| 247 | struct sk_buff *skb; | 250 | struct sk_buff *skb; | 
| 248 | u32 dnode; | 251 | u32 dnode; | 
| 252 | struct net *net = sock_net(sk); | ||
| 249 | 253 | ||
| 250 | while ((skb = __skb_dequeue(&sk->sk_receive_queue))) { | 254 | while ((skb = __skb_dequeue(&sk->sk_receive_queue))) { | 
| 251 | if (tipc_msg_reverse(skb, &dnode, TIPC_ERR_NO_PORT)) | 255 | if (tipc_msg_reverse(net, skb, &dnode, TIPC_ERR_NO_PORT)) | 
| 252 | tipc_link_xmit_skb(skb, dnode, 0); | 256 | tipc_link_xmit_skb(net, skb, dnode, 0); | 
| 253 | } | 257 | } | 
| 254 | } | 258 | } | 
| 255 | 259 | ||
| @@ -260,6 +264,7 @@ static void tsk_rej_rx_queue(struct sock *sk) | |||
| 260 | */ | 264 | */ | 
| 261 | static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg) | 265 | static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg) | 
| 262 | { | 266 | { | 
| 267 | struct tipc_net *tn = net_generic(sock_net(&tsk->sk), tipc_net_id); | ||
| 263 | u32 peer_port = tsk_peer_port(tsk); | 268 | u32 peer_port = tsk_peer_port(tsk); | 
| 264 | u32 orig_node; | 269 | u32 orig_node; | 
| 265 | u32 peer_node; | 270 | u32 peer_node; | 
| @@ -276,10 +281,10 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg) | |||
| 276 | if (likely(orig_node == peer_node)) | 281 | if (likely(orig_node == peer_node)) | 
| 277 | return true; | 282 | return true; | 
| 278 | 283 | ||
| 279 | if (!orig_node && (peer_node == tipc_own_addr)) | 284 | if (!orig_node && (peer_node == tn->own_addr)) | 
| 280 | return true; | 285 | return true; | 
| 281 | 286 | ||
| 282 | if (!peer_node && (orig_node == tipc_own_addr)) | 287 | if (!peer_node && (orig_node == tn->own_addr)) | 
| 283 | return true; | 288 | return true; | 
| 284 | 289 | ||
| 285 | return false; | 290 | return false; | 
| @@ -305,7 +310,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
| 305 | struct sock *sk; | 310 | struct sock *sk; | 
| 306 | struct tipc_sock *tsk; | 311 | struct tipc_sock *tsk; | 
| 307 | struct tipc_msg *msg; | 312 | struct tipc_msg *msg; | 
| 308 | u32 ref; | ||
| 309 | 313 | ||
| 310 | /* Validate arguments */ | 314 | /* Validate arguments */ | 
| 311 | if (unlikely(protocol != 0)) | 315 | if (unlikely(protocol != 0)) | 
| @@ -339,24 +343,22 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
| 339 | return -ENOMEM; | 343 | return -ENOMEM; | 
| 340 | 344 | ||
| 341 | tsk = tipc_sk(sk); | 345 | tsk = tipc_sk(sk); | 
| 342 | ref = tipc_sk_ref_acquire(tsk); | ||
| 343 | if (!ref) { | ||
| 344 | pr_warn("Socket create failed; reference table exhausted\n"); | ||
| 345 | return -ENOMEM; | ||
| 346 | } | ||
| 347 | tsk->max_pkt = MAX_PKT_DEFAULT; | 346 | tsk->max_pkt = MAX_PKT_DEFAULT; | 
| 348 | tsk->ref = ref; | ||
| 349 | INIT_LIST_HEAD(&tsk->publications); | 347 | INIT_LIST_HEAD(&tsk->publications); | 
| 350 | msg = &tsk->phdr; | 348 | msg = &tsk->phdr; | 
| 351 | tipc_msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, | 349 | tipc_msg_init(net, msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, | 
| 352 | NAMED_H_SIZE, 0); | 350 | NAMED_H_SIZE, 0); | 
| 353 | msg_set_origport(msg, ref); | ||
| 354 | 351 | ||
| 355 | /* Finish initializing socket data structures */ | 352 | /* Finish initializing socket data structures */ | 
| 356 | sock->ops = ops; | 353 | sock->ops = ops; | 
| 357 | sock->state = state; | 354 | sock->state = state; | 
| 358 | sock_init_data(sock, sk); | 355 | sock_init_data(sock, sk); | 
| 359 | k_init_timer(&tsk->timer, (Handler)tipc_sk_timeout, ref); | 356 | if (tipc_sk_insert(tsk)) { | 
| 357 | pr_warn("Socket create failed; port numbrer exhausted\n"); | ||
| 358 | return -EINVAL; | ||
| 359 | } | ||
| 360 | msg_set_origport(msg, tsk->portid); | ||
| 361 | setup_timer(&sk->sk_timer, tipc_sk_timeout, (unsigned long)tsk); | ||
| 360 | sk->sk_backlog_rcv = tipc_backlog_rcv; | 362 | sk->sk_backlog_rcv = tipc_backlog_rcv; | 
| 361 | sk->sk_rcvbuf = sysctl_tipc_rmem[1]; | 363 | sk->sk_rcvbuf = sysctl_tipc_rmem[1]; | 
| 362 | sk->sk_data_ready = tipc_data_ready; | 364 | sk->sk_data_ready = tipc_data_ready; | 
| @@ -384,7 +386,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
| 384 | * | 386 | * | 
| 385 | * Returns 0 on success, errno otherwise | 387 | * Returns 0 on success, errno otherwise | 
| 386 | */ | 388 | */ | 
| 387 | int tipc_sock_create_local(int type, struct socket **res) | 389 | int tipc_sock_create_local(struct net *net, int type, struct socket **res) | 
| 388 | { | 390 | { | 
| 389 | int rc; | 391 | int rc; | 
| 390 | 392 | ||
| @@ -393,7 +395,7 @@ int tipc_sock_create_local(int type, struct socket **res) | |||
| 393 | pr_err("Failed to create kernel socket\n"); | 395 | pr_err("Failed to create kernel socket\n"); | 
| 394 | return rc; | 396 | return rc; | 
| 395 | } | 397 | } | 
| 396 | tipc_sk_create(&init_net, *res, 0, 1); | 398 | tipc_sk_create(net, *res, 0, 1); | 
| 397 | 399 | ||
| 398 | return 0; | 400 | return 0; | 
| 399 | } | 401 | } | 
| @@ -442,6 +444,13 @@ int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, | |||
| 442 | return ret; | 444 | return ret; | 
| 443 | } | 445 | } | 
| 444 | 446 | ||
| 447 | static void tipc_sk_callback(struct rcu_head *head) | ||
| 448 | { | ||
| 449 | struct tipc_sock *tsk = container_of(head, struct tipc_sock, rcu); | ||
| 450 | |||
| 451 | sock_put(&tsk->sk); | ||
| 452 | } | ||
| 453 | |||
| 445 | /** | 454 | /** | 
| 446 | * tipc_release - destroy a TIPC socket | 455 | * tipc_release - destroy a TIPC socket | 
| 447 | * @sock: socket to destroy | 456 | * @sock: socket to destroy | 
| @@ -461,9 +470,11 @@ int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, | |||
| 461 | static int tipc_release(struct socket *sock) | 470 | static int tipc_release(struct socket *sock) | 
| 462 | { | 471 | { | 
| 463 | struct sock *sk = sock->sk; | 472 | struct sock *sk = sock->sk; | 
| 473 | struct net *net; | ||
| 474 | struct tipc_net *tn; | ||
| 464 | struct tipc_sock *tsk; | 475 | struct tipc_sock *tsk; | 
| 465 | struct sk_buff *skb; | 476 | struct sk_buff *skb; | 
| 466 | u32 dnode; | 477 | u32 dnode, probing_state; | 
| 467 | 478 | ||
| 468 | /* | 479 | /* | 
| 469 | * Exit if socket isn't fully initialized (occurs when a failed accept() | 480 | * Exit if socket isn't fully initialized (occurs when a failed accept() | 
| @@ -472,6 +483,9 @@ static int tipc_release(struct socket *sock) | |||
| 472 | if (sk == NULL) | 483 | if (sk == NULL) | 
| 473 | return 0; | 484 | return 0; | 
| 474 | 485 | ||
| 486 | net = sock_net(sk); | ||
| 487 | tn = net_generic(net, tipc_net_id); | ||
| 488 | |||
| 475 | tsk = tipc_sk(sk); | 489 | tsk = tipc_sk(sk); | 
| 476 | lock_sock(sk); | 490 | lock_sock(sk); | 
| 477 | 491 | ||
| @@ -491,26 +505,29 @@ static int tipc_release(struct socket *sock) | |||
| 491 | (sock->state == SS_CONNECTED)) { | 505 | (sock->state == SS_CONNECTED)) { | 
| 492 | sock->state = SS_DISCONNECTING; | 506 | sock->state = SS_DISCONNECTING; | 
| 493 | tsk->connected = 0; | 507 | tsk->connected = 0; | 
| 494 | tipc_node_remove_conn(dnode, tsk->ref); | 508 | tipc_node_remove_conn(net, dnode, tsk->portid); | 
| 495 | } | 509 | } | 
| 496 | if (tipc_msg_reverse(skb, &dnode, TIPC_ERR_NO_PORT)) | 510 | if (tipc_msg_reverse(net, skb, &dnode, | 
| 497 | tipc_link_xmit_skb(skb, dnode, 0); | 511 | TIPC_ERR_NO_PORT)) | 
| 512 | tipc_link_xmit_skb(net, skb, dnode, 0); | ||
| 498 | } | 513 | } | 
| 499 | } | 514 | } | 
| 500 | 515 | ||
| 501 | tipc_sk_withdraw(tsk, 0, NULL); | 516 | tipc_sk_withdraw(tsk, 0, NULL); | 
| 502 | tipc_sk_ref_discard(tsk->ref); | 517 | probing_state = tsk->probing_state; | 
| 503 | k_cancel_timer(&tsk->timer); | 518 | if (del_timer_sync(&sk->sk_timer) && | 
| 519 | probing_state != TIPC_CONN_PROBING) | ||
| 520 | sock_put(sk); | ||
| 521 | tipc_sk_remove(tsk); | ||
| 504 | if (tsk->connected) { | 522 | if (tsk->connected) { | 
| 505 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, | 523 | skb = tipc_msg_create(net, TIPC_CRITICAL_IMPORTANCE, | 
| 506 | SHORT_H_SIZE, 0, dnode, tipc_own_addr, | 524 | TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode, | 
| 507 | tsk_peer_port(tsk), | 525 | tn->own_addr, tsk_peer_port(tsk), | 
| 508 | tsk->ref, TIPC_ERR_NO_PORT); | 526 | tsk->portid, TIPC_ERR_NO_PORT); | 
| 509 | if (skb) | 527 | if (skb) | 
| 510 | tipc_link_xmit_skb(skb, dnode, tsk->ref); | 528 | tipc_link_xmit_skb(net, skb, dnode, tsk->portid); | 
| 511 | tipc_node_remove_conn(dnode, tsk->ref); | 529 | tipc_node_remove_conn(net, dnode, tsk->portid); | 
| 512 | } | 530 | } | 
| 513 | k_term_timer(&tsk->timer); | ||
| 514 | 531 | ||
| 515 | /* Discard any remaining (connection-based) messages in receive queue */ | 532 | /* Discard any remaining (connection-based) messages in receive queue */ | 
| 516 | __skb_queue_purge(&sk->sk_receive_queue); | 533 | __skb_queue_purge(&sk->sk_receive_queue); | 
| @@ -518,7 +535,8 @@ static int tipc_release(struct socket *sock) | |||
| 518 | /* Reject any messages that accumulated in backlog queue */ | 535 | /* Reject any messages that accumulated in backlog queue */ | 
| 519 | sock->state = SS_DISCONNECTING; | 536 | sock->state = SS_DISCONNECTING; | 
| 520 | release_sock(sk); | 537 | release_sock(sk); | 
| 521 | sock_put(sk); | 538 | |
| 539 | call_rcu(&tsk->rcu, tipc_sk_callback); | ||
| 522 | sock->sk = NULL; | 540 | sock->sk = NULL; | 
| 523 | 541 | ||
| 524 | return 0; | 542 | return 0; | 
| @@ -602,6 +620,7 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr, | |||
| 602 | { | 620 | { | 
| 603 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 621 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 
| 604 | struct tipc_sock *tsk = tipc_sk(sock->sk); | 622 | struct tipc_sock *tsk = tipc_sk(sock->sk); | 
| 623 | struct tipc_net *tn = net_generic(sock_net(sock->sk), tipc_net_id); | ||
| 605 | 624 | ||
| 606 | memset(addr, 0, sizeof(*addr)); | 625 | memset(addr, 0, sizeof(*addr)); | 
| 607 | if (peer) { | 626 | if (peer) { | 
| @@ -611,8 +630,8 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr, | |||
| 611 | addr->addr.id.ref = tsk_peer_port(tsk); | 630 | addr->addr.id.ref = tsk_peer_port(tsk); | 
| 612 | addr->addr.id.node = tsk_peer_node(tsk); | 631 | addr->addr.id.node = tsk_peer_node(tsk); | 
| 613 | } else { | 632 | } else { | 
| 614 | addr->addr.id.ref = tsk->ref; | 633 | addr->addr.id.ref = tsk->portid; | 
| 615 | addr->addr.id.node = tipc_own_addr; | 634 | addr->addr.id.node = tn->own_addr; | 
| 616 | } | 635 | } | 
| 617 | 636 | ||
| 618 | *uaddr_len = sizeof(*addr); | 637 | *uaddr_len = sizeof(*addr); | 
| @@ -711,6 +730,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, | |||
| 711 | struct msghdr *msg, size_t dsz, long timeo) | 730 | struct msghdr *msg, size_t dsz, long timeo) | 
| 712 | { | 731 | { | 
| 713 | struct sock *sk = sock->sk; | 732 | struct sock *sk = sock->sk; | 
| 733 | struct net *net = sock_net(sk); | ||
| 714 | struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; | 734 | struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; | 
| 715 | struct sk_buff_head head; | 735 | struct sk_buff_head head; | 
| 716 | uint mtu; | 736 | uint mtu; | 
| @@ -728,12 +748,12 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, | |||
| 728 | new_mtu: | 748 | new_mtu: | 
| 729 | mtu = tipc_bclink_get_mtu(); | 749 | mtu = tipc_bclink_get_mtu(); | 
| 730 | __skb_queue_head_init(&head); | 750 | __skb_queue_head_init(&head); | 
| 731 | rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &head); | 751 | rc = tipc_msg_build(net, mhdr, msg, 0, dsz, mtu, &head); | 
| 732 | if (unlikely(rc < 0)) | 752 | if (unlikely(rc < 0)) | 
| 733 | return rc; | 753 | return rc; | 
| 734 | 754 | ||
| 735 | do { | 755 | do { | 
| 736 | rc = tipc_bclink_xmit(&head); | 756 | rc = tipc_bclink_xmit(net, &head); | 
| 737 | if (likely(rc >= 0)) { | 757 | if (likely(rc >= 0)) { | 
| 738 | rc = dsz; | 758 | rc = dsz; | 
| 739 | break; | 759 | break; | 
| @@ -752,7 +772,7 @@ new_mtu: | |||
| 752 | 772 | ||
| 753 | /* tipc_sk_mcast_rcv - Deliver multicast message to all destination sockets | 773 | /* tipc_sk_mcast_rcv - Deliver multicast message to all destination sockets | 
| 754 | */ | 774 | */ | 
| 755 | void tipc_sk_mcast_rcv(struct sk_buff *buf) | 775 | void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf) | 
| 756 | { | 776 | { | 
| 757 | struct tipc_msg *msg = buf_msg(buf); | 777 | struct tipc_msg *msg = buf_msg(buf); | 
| 758 | struct tipc_port_list dports = {0, NULL, }; | 778 | struct tipc_port_list dports = {0, NULL, }; | 
| @@ -761,15 +781,12 @@ void tipc_sk_mcast_rcv(struct sk_buff *buf) | |||
| 761 | uint i, last, dst = 0; | 781 | uint i, last, dst = 0; | 
| 762 | u32 scope = TIPC_CLUSTER_SCOPE; | 782 | u32 scope = TIPC_CLUSTER_SCOPE; | 
| 763 | 783 | ||
| 764 | if (in_own_node(msg_orignode(msg))) | 784 | if (in_own_node(net, msg_orignode(msg))) | 
| 765 | scope = TIPC_NODE_SCOPE; | 785 | scope = TIPC_NODE_SCOPE; | 
| 766 | 786 | ||
| 767 | /* Create destination port list: */ | 787 | /* Create destination port list: */ | 
| 768 | tipc_nametbl_mc_translate(msg_nametype(msg), | 788 | tipc_nametbl_mc_translate(net, msg_nametype(msg), msg_namelower(msg), | 
| 769 | msg_namelower(msg), | 789 | msg_nameupper(msg), scope, &dports); | 
| 770 | msg_nameupper(msg), | ||
| 771 | scope, | ||
| 772 | &dports); | ||
| 773 | last = dports.count; | 790 | last = dports.count; | 
| 774 | if (!last) { | 791 | if (!last) { | 
| 775 | kfree_skb(buf); | 792 | kfree_skb(buf); | 
| @@ -784,7 +801,7 @@ void tipc_sk_mcast_rcv(struct sk_buff *buf) | |||
| 784 | continue; | 801 | continue; | 
| 785 | } | 802 | } | 
| 786 | msg_set_destport(msg, item->ports[i]); | 803 | msg_set_destport(msg, item->ports[i]); | 
| 787 | tipc_sk_rcv(b); | 804 | tipc_sk_rcv(net, b); | 
| 788 | } | 805 | } | 
| 789 | } | 806 | } | 
| 790 | tipc_port_list_free(&dports); | 807 | tipc_port_list_free(&dports); | 
| @@ -816,7 +833,7 @@ static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode, | |||
| 816 | if (conn_cong) | 833 | if (conn_cong) | 
| 817 | tsk->sk.sk_write_space(&tsk->sk); | 834 | tsk->sk.sk_write_space(&tsk->sk); | 
| 818 | } else if (msg_type(msg) == CONN_PROBE) { | 835 | } else if (msg_type(msg) == CONN_PROBE) { | 
| 819 | if (!tipc_msg_reverse(buf, dnode, TIPC_OK)) | 836 | if (!tipc_msg_reverse(sock_net(&tsk->sk), buf, dnode, TIPC_OK)) | 
| 820 | return TIPC_OK; | 837 | return TIPC_OK; | 
| 821 | msg_set_type(msg, CONN_PROBE_REPLY); | 838 | msg_set_type(msg, CONN_PROBE_REPLY); | 
| 822 | return TIPC_FWD_MSG; | 839 | return TIPC_FWD_MSG; | 
| @@ -872,6 +889,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 872 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | 889 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | 
| 873 | struct sock *sk = sock->sk; | 890 | struct sock *sk = sock->sk; | 
| 874 | struct tipc_sock *tsk = tipc_sk(sk); | 891 | struct tipc_sock *tsk = tipc_sk(sk); | 
| 892 | struct net *net = sock_net(sk); | ||
| 875 | struct tipc_msg *mhdr = &tsk->phdr; | 893 | struct tipc_msg *mhdr = &tsk->phdr; | 
| 876 | u32 dnode, dport; | 894 | u32 dnode, dport; | 
| 877 | struct sk_buff_head head; | 895 | struct sk_buff_head head; | 
| @@ -929,7 +947,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 929 | msg_set_nametype(mhdr, type); | 947 | msg_set_nametype(mhdr, type); | 
| 930 | msg_set_nameinst(mhdr, inst); | 948 | msg_set_nameinst(mhdr, inst); | 
| 931 | msg_set_lookup_scope(mhdr, tipc_addr_scope(domain)); | 949 | msg_set_lookup_scope(mhdr, tipc_addr_scope(domain)); | 
| 932 | dport = tipc_nametbl_translate(type, inst, &dnode); | 950 | dport = tipc_nametbl_translate(net, type, inst, &dnode); | 
| 933 | msg_set_destnode(mhdr, dnode); | 951 | msg_set_destnode(mhdr, dnode); | 
| 934 | msg_set_destport(mhdr, dport); | 952 | msg_set_destport(mhdr, dport); | 
| 935 | if (unlikely(!dport && !dnode)) { | 953 | if (unlikely(!dport && !dnode)) { | 
| @@ -946,16 +964,16 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 946 | } | 964 | } | 
| 947 | 965 | ||
| 948 | new_mtu: | 966 | new_mtu: | 
| 949 | mtu = tipc_node_get_mtu(dnode, tsk->ref); | 967 | mtu = tipc_node_get_mtu(net, dnode, tsk->portid); | 
| 950 | __skb_queue_head_init(&head); | 968 | __skb_queue_head_init(&head); | 
| 951 | rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &head); | 969 | rc = tipc_msg_build(net, mhdr, m, 0, dsz, mtu, &head); | 
| 952 | if (rc < 0) | 970 | if (rc < 0) | 
| 953 | goto exit; | 971 | goto exit; | 
| 954 | 972 | ||
| 955 | do { | 973 | do { | 
| 956 | skb = skb_peek(&head); | 974 | skb = skb_peek(&head); | 
| 957 | TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong; | 975 | TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong; | 
| 958 | rc = tipc_link_xmit(&head, dnode, tsk->ref); | 976 | rc = tipc_link_xmit(net, &head, dnode, tsk->portid); | 
| 959 | if (likely(rc >= 0)) { | 977 | if (likely(rc >= 0)) { | 
| 960 | if (sock->state != SS_READY) | 978 | if (sock->state != SS_READY) | 
| 961 | sock->state = SS_CONNECTING; | 979 | sock->state = SS_CONNECTING; | 
| @@ -1024,11 +1042,12 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1024 | struct msghdr *m, size_t dsz) | 1042 | struct msghdr *m, size_t dsz) | 
| 1025 | { | 1043 | { | 
| 1026 | struct sock *sk = sock->sk; | 1044 | struct sock *sk = sock->sk; | 
| 1045 | struct net *net = sock_net(sk); | ||
| 1027 | struct tipc_sock *tsk = tipc_sk(sk); | 1046 | struct tipc_sock *tsk = tipc_sk(sk); | 
| 1028 | struct tipc_msg *mhdr = &tsk->phdr; | 1047 | struct tipc_msg *mhdr = &tsk->phdr; | 
| 1029 | struct sk_buff_head head; | 1048 | struct sk_buff_head head; | 
| 1030 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | 1049 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | 
| 1031 | u32 ref = tsk->ref; | 1050 | u32 portid = tsk->portid; | 
| 1032 | int rc = -EINVAL; | 1051 | int rc = -EINVAL; | 
| 1033 | long timeo; | 1052 | long timeo; | 
| 1034 | u32 dnode; | 1053 | u32 dnode; | 
| @@ -1062,12 +1081,12 @@ next: | |||
| 1062 | mtu = tsk->max_pkt; | 1081 | mtu = tsk->max_pkt; | 
| 1063 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); | 1082 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); | 
| 1064 | __skb_queue_head_init(&head); | 1083 | __skb_queue_head_init(&head); | 
| 1065 | rc = tipc_msg_build(mhdr, m, sent, send, mtu, &head); | 1084 | rc = tipc_msg_build(net, mhdr, m, sent, send, mtu, &head); | 
| 1066 | if (unlikely(rc < 0)) | 1085 | if (unlikely(rc < 0)) | 
| 1067 | goto exit; | 1086 | goto exit; | 
| 1068 | do { | 1087 | do { | 
| 1069 | if (likely(!tsk_conn_cong(tsk))) { | 1088 | if (likely(!tsk_conn_cong(tsk))) { | 
| 1070 | rc = tipc_link_xmit(&head, dnode, ref); | 1089 | rc = tipc_link_xmit(net, &head, dnode, portid); | 
| 1071 | if (likely(!rc)) { | 1090 | if (likely(!rc)) { | 
| 1072 | tsk->sent_unacked++; | 1091 | tsk->sent_unacked++; | 
| 1073 | sent += send; | 1092 | sent += send; | 
| @@ -1076,7 +1095,8 @@ next: | |||
| 1076 | goto next; | 1095 | goto next; | 
| 1077 | } | 1096 | } | 
| 1078 | if (rc == -EMSGSIZE) { | 1097 | if (rc == -EMSGSIZE) { | 
| 1079 | tsk->max_pkt = tipc_node_get_mtu(dnode, ref); | 1098 | tsk->max_pkt = tipc_node_get_mtu(net, dnode, | 
| 1099 | portid); | ||
| 1080 | goto next; | 1100 | goto next; | 
| 1081 | } | 1101 | } | 
| 1082 | if (rc != -ELINKCONG) | 1102 | if (rc != -ELINKCONG) | 
| @@ -1118,6 +1138,8 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock, | |||
| 1118 | static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port, | 1138 | static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port, | 
| 1119 | u32 peer_node) | 1139 | u32 peer_node) | 
| 1120 | { | 1140 | { | 
| 1141 | struct sock *sk = &tsk->sk; | ||
| 1142 | struct net *net = sock_net(sk); | ||
| 1121 | struct tipc_msg *msg = &tsk->phdr; | 1143 | struct tipc_msg *msg = &tsk->phdr; | 
| 1122 | 1144 | ||
| 1123 | msg_set_destnode(msg, peer_node); | 1145 | msg_set_destnode(msg, peer_node); | 
| @@ -1126,12 +1148,12 @@ static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port, | |||
| 1126 | msg_set_lookup_scope(msg, 0); | 1148 | msg_set_lookup_scope(msg, 0); | 
| 1127 | msg_set_hdr_sz(msg, SHORT_H_SIZE); | 1149 | msg_set_hdr_sz(msg, SHORT_H_SIZE); | 
| 1128 | 1150 | ||
| 1129 | tsk->probing_interval = CONN_PROBING_INTERVAL; | 1151 | tsk->probing_intv = CONN_PROBING_INTERVAL; | 
| 1130 | tsk->probing_state = TIPC_CONN_OK; | 1152 | tsk->probing_state = TIPC_CONN_OK; | 
| 1131 | tsk->connected = 1; | 1153 | tsk->connected = 1; | 
| 1132 | k_start_timer(&tsk->timer, tsk->probing_interval); | 1154 | sk_reset_timer(sk, &sk->sk_timer, jiffies + tsk->probing_intv); | 
| 1133 | tipc_node_add_conn(peer_node, tsk->ref, peer_port); | 1155 | tipc_node_add_conn(net, peer_node, tsk->portid, peer_port); | 
| 1134 | tsk->max_pkt = tipc_node_get_mtu(peer_node, tsk->ref); | 1156 | tsk->max_pkt = tipc_node_get_mtu(net, peer_node, tsk->portid); | 
| 1135 | } | 1157 | } | 
| 1136 | 1158 | ||
| 1137 | /** | 1159 | /** | 
| @@ -1230,6 +1252,8 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
| 1230 | 1252 | ||
| 1231 | static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack) | 1253 | static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack) | 
| 1232 | { | 1254 | { | 
| 1255 | struct net *net = sock_net(&tsk->sk); | ||
| 1256 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 1233 | struct sk_buff *skb = NULL; | 1257 | struct sk_buff *skb = NULL; | 
| 1234 | struct tipc_msg *msg; | 1258 | struct tipc_msg *msg; | 
| 1235 | u32 peer_port = tsk_peer_port(tsk); | 1259 | u32 peer_port = tsk_peer_port(tsk); | 
| @@ -1237,13 +1261,14 @@ static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack) | |||
| 1237 | 1261 | ||
| 1238 | if (!tsk->connected) | 1262 | if (!tsk->connected) | 
| 1239 | return; | 1263 | return; | 
| 1240 | skb = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode, | 1264 | skb = tipc_msg_create(net, CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, | 
| 1241 | tipc_own_addr, peer_port, tsk->ref, TIPC_OK); | 1265 | dnode, tn->own_addr, peer_port, tsk->portid, | 
| 1266 | TIPC_OK); | ||
| 1242 | if (!skb) | 1267 | if (!skb) | 
| 1243 | return; | 1268 | return; | 
| 1244 | msg = buf_msg(skb); | 1269 | msg = buf_msg(skb); | 
| 1245 | msg_set_msgcnt(msg, ack); | 1270 | msg_set_msgcnt(msg, ack); | 
| 1246 | tipc_link_xmit_skb(skb, dnode, msg_link_selector(msg)); | 1271 | tipc_link_xmit_skb(net, skb, dnode, msg_link_selector(msg)); | 
| 1247 | } | 1272 | } | 
| 1248 | 1273 | ||
| 1249 | static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | 1274 | static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | 
| @@ -1536,6 +1561,7 @@ static void tipc_data_ready(struct sock *sk) | |||
| 1536 | static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) | 1561 | static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) | 
| 1537 | { | 1562 | { | 
| 1538 | struct sock *sk = &tsk->sk; | 1563 | struct sock *sk = &tsk->sk; | 
| 1564 | struct net *net = sock_net(sk); | ||
| 1539 | struct socket *sock = sk->sk_socket; | 1565 | struct socket *sock = sk->sk_socket; | 
| 1540 | struct tipc_msg *msg = buf_msg(*buf); | 1566 | struct tipc_msg *msg = buf_msg(*buf); | 
| 1541 | int retval = -TIPC_ERR_NO_PORT; | 1567 | int retval = -TIPC_ERR_NO_PORT; | 
| @@ -1551,8 +1577,8 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) | |||
| 1551 | sock->state = SS_DISCONNECTING; | 1577 | sock->state = SS_DISCONNECTING; | 
| 1552 | tsk->connected = 0; | 1578 | tsk->connected = 0; | 
| 1553 | /* let timer expire on it's own */ | 1579 | /* let timer expire on it's own */ | 
| 1554 | tipc_node_remove_conn(tsk_peer_node(tsk), | 1580 | tipc_node_remove_conn(net, tsk_peer_node(tsk), | 
| 1555 | tsk->ref); | 1581 | tsk->portid); | 
| 1556 | } | 1582 | } | 
| 1557 | retval = TIPC_OK; | 1583 | retval = TIPC_OK; | 
| 1558 | } | 1584 | } | 
| @@ -1709,6 +1735,7 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1709 | int rc; | 1735 | int rc; | 
| 1710 | u32 onode; | 1736 | u32 onode; | 
| 1711 | struct tipc_sock *tsk = tipc_sk(sk); | 1737 | struct tipc_sock *tsk = tipc_sk(sk); | 
| 1738 | struct net *net = sock_net(sk); | ||
| 1712 | uint truesize = skb->truesize; | 1739 | uint truesize = skb->truesize; | 
| 1713 | 1740 | ||
| 1714 | rc = filter_rcv(sk, skb); | 1741 | rc = filter_rcv(sk, skb); | 
| @@ -1719,10 +1746,10 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1719 | return 0; | 1746 | return 0; | 
| 1720 | } | 1747 | } | 
| 1721 | 1748 | ||
| 1722 | if ((rc < 0) && !tipc_msg_reverse(skb, &onode, -rc)) | 1749 | if ((rc < 0) && !tipc_msg_reverse(net, skb, &onode, -rc)) | 
| 1723 | return 0; | 1750 | return 0; | 
| 1724 | 1751 | ||
| 1725 | tipc_link_xmit_skb(skb, onode, 0); | 1752 | tipc_link_xmit_skb(net, skb, onode, 0); | 
| 1726 | 1753 | ||
| 1727 | return 0; | 1754 | return 0; | 
| 1728 | } | 1755 | } | 
| @@ -1733,7 +1760,7 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1733 | * Consumes buffer | 1760 | * Consumes buffer | 
| 1734 | * Returns 0 if success, or errno: -EHOSTUNREACH | 1761 | * Returns 0 if success, or errno: -EHOSTUNREACH | 
| 1735 | */ | 1762 | */ | 
| 1736 | int tipc_sk_rcv(struct sk_buff *skb) | 1763 | int tipc_sk_rcv(struct net *net, struct sk_buff *skb) | 
| 1737 | { | 1764 | { | 
| 1738 | struct tipc_sock *tsk; | 1765 | struct tipc_sock *tsk; | 
| 1739 | struct sock *sk; | 1766 | struct sock *sk; | 
| @@ -1743,9 +1770,9 @@ int tipc_sk_rcv(struct sk_buff *skb) | |||
| 1743 | u32 dnode; | 1770 | u32 dnode; | 
| 1744 | 1771 | ||
| 1745 | /* Validate destination and message */ | 1772 | /* Validate destination and message */ | 
| 1746 | tsk = tipc_sk_get(dport); | 1773 | tsk = tipc_sk_lookup(net, dport); | 
| 1747 | if (unlikely(!tsk)) { | 1774 | if (unlikely(!tsk)) { | 
| 1748 | rc = tipc_msg_eval(skb, &dnode); | 1775 | rc = tipc_msg_eval(net, skb, &dnode); | 
| 1749 | goto exit; | 1776 | goto exit; | 
| 1750 | } | 1777 | } | 
| 1751 | sk = &tsk->sk; | 1778 | sk = &tsk->sk; | 
| @@ -1763,14 +1790,14 @@ int tipc_sk_rcv(struct sk_buff *skb) | |||
| 1763 | rc = -TIPC_ERR_OVERLOAD; | 1790 | rc = -TIPC_ERR_OVERLOAD; | 
| 1764 | } | 1791 | } | 
| 1765 | spin_unlock_bh(&sk->sk_lock.slock); | 1792 | spin_unlock_bh(&sk->sk_lock.slock); | 
| 1766 | tipc_sk_put(tsk); | 1793 | sock_put(sk); | 
| 1767 | if (likely(!rc)) | 1794 | if (likely(!rc)) | 
| 1768 | return 0; | 1795 | return 0; | 
| 1769 | exit: | 1796 | exit: | 
| 1770 | if ((rc < 0) && !tipc_msg_reverse(skb, &dnode, -rc)) | 1797 | if ((rc < 0) && !tipc_msg_reverse(net, skb, &dnode, -rc)) | 
| 1771 | return -EHOSTUNREACH; | 1798 | return -EHOSTUNREACH; | 
| 1772 | 1799 | ||
| 1773 | tipc_link_xmit_skb(skb, dnode, 0); | 1800 | tipc_link_xmit_skb(net, skb, dnode, 0); | 
| 1774 | return (rc < 0) ? -EHOSTUNREACH : 0; | 1801 | return (rc < 0) ? -EHOSTUNREACH : 0; | 
| 1775 | } | 1802 | } | 
| 1776 | 1803 | ||
| @@ -2027,6 +2054,8 @@ exit: | |||
| 2027 | static int tipc_shutdown(struct socket *sock, int how) | 2054 | static int tipc_shutdown(struct socket *sock, int how) | 
| 2028 | { | 2055 | { | 
| 2029 | struct sock *sk = sock->sk; | 2056 | struct sock *sk = sock->sk; | 
| 2057 | struct net *net = sock_net(sk); | ||
| 2058 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 2030 | struct tipc_sock *tsk = tipc_sk(sk); | 2059 | struct tipc_sock *tsk = tipc_sk(sk); | 
| 2031 | struct sk_buff *skb; | 2060 | struct sk_buff *skb; | 
| 2032 | u32 dnode; | 2061 | u32 dnode; | 
| @@ -2049,21 +2078,23 @@ restart: | |||
| 2049 | kfree_skb(skb); | 2078 | kfree_skb(skb); | 
| 2050 | goto restart; | 2079 | goto restart; | 
| 2051 | } | 2080 | } | 
| 2052 | if (tipc_msg_reverse(skb, &dnode, TIPC_CONN_SHUTDOWN)) | 2081 | if (tipc_msg_reverse(net, skb, &dnode, | 
| 2053 | tipc_link_xmit_skb(skb, dnode, tsk->ref); | 2082 | TIPC_CONN_SHUTDOWN)) | 
| 2054 | tipc_node_remove_conn(dnode, tsk->ref); | 2083 | tipc_link_xmit_skb(net, skb, dnode, | 
| 2084 | tsk->portid); | ||
| 2085 | tipc_node_remove_conn(net, dnode, tsk->portid); | ||
| 2055 | } else { | 2086 | } else { | 
| 2056 | dnode = tsk_peer_node(tsk); | 2087 | dnode = tsk_peer_node(tsk); | 
| 2057 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, | 2088 | skb = tipc_msg_create(net, TIPC_CRITICAL_IMPORTANCE, | 
| 2058 | TIPC_CONN_MSG, SHORT_H_SIZE, | 2089 | TIPC_CONN_MSG, SHORT_H_SIZE, | 
| 2059 | 0, dnode, tipc_own_addr, | 2090 | 0, dnode, tn->own_addr, | 
| 2060 | tsk_peer_port(tsk), | 2091 | tsk_peer_port(tsk), | 
| 2061 | tsk->ref, TIPC_CONN_SHUTDOWN); | 2092 | tsk->portid, TIPC_CONN_SHUTDOWN); | 
| 2062 | tipc_link_xmit_skb(skb, dnode, tsk->ref); | 2093 | tipc_link_xmit_skb(net, skb, dnode, tsk->portid); | 
| 2063 | } | 2094 | } | 
| 2064 | tsk->connected = 0; | 2095 | tsk->connected = 0; | 
| 2065 | sock->state = SS_DISCONNECTING; | 2096 | sock->state = SS_DISCONNECTING; | 
| 2066 | tipc_node_remove_conn(dnode, tsk->ref); | 2097 | tipc_node_remove_conn(net, dnode, tsk->portid); | 
| 2067 | /* fall through */ | 2098 | /* fall through */ | 
| 2068 | 2099 | ||
| 2069 | case SS_DISCONNECTING: | 2100 | case SS_DISCONNECTING: | 
| @@ -2084,18 +2115,15 @@ restart: | |||
| 2084 | return res; | 2115 | return res; | 
| 2085 | } | 2116 | } | 
| 2086 | 2117 | ||
| 2087 | static void tipc_sk_timeout(unsigned long ref) | 2118 | static void tipc_sk_timeout(unsigned long data) | 
| 2088 | { | 2119 | { | 
| 2089 | struct tipc_sock *tsk; | 2120 | struct tipc_sock *tsk = (struct tipc_sock *)data; | 
| 2090 | struct sock *sk; | 2121 | struct sock *sk = &tsk->sk; | 
| 2122 | struct net *net = sock_net(sk); | ||
| 2123 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 2091 | struct sk_buff *skb = NULL; | 2124 | struct sk_buff *skb = NULL; | 
| 2092 | u32 peer_port, peer_node; | 2125 | u32 peer_port, peer_node; | 
| 2093 | 2126 | ||
| 2094 | tsk = tipc_sk_get(ref); | ||
| 2095 | if (!tsk) | ||
| 2096 | return; | ||
| 2097 | |||
| 2098 | sk = &tsk->sk; | ||
| 2099 | bh_lock_sock(sk); | 2127 | bh_lock_sock(sk); | 
| 2100 | if (!tsk->connected) { | 2128 | if (!tsk->connected) { | 
| 2101 | bh_unlock_sock(sk); | 2129 | bh_unlock_sock(sk); | 
| @@ -2106,38 +2134,39 @@ static void tipc_sk_timeout(unsigned long ref) | |||
| 2106 | 2134 | ||
| 2107 | if (tsk->probing_state == TIPC_CONN_PROBING) { | 2135 | if (tsk->probing_state == TIPC_CONN_PROBING) { | 
| 2108 | /* Previous probe not answered -> self abort */ | 2136 | /* Previous probe not answered -> self abort */ | 
| 2109 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, | 2137 | skb = tipc_msg_create(net, TIPC_CRITICAL_IMPORTANCE, | 
| 2110 | SHORT_H_SIZE, 0, tipc_own_addr, | 2138 | TIPC_CONN_MSG, SHORT_H_SIZE, 0, | 
| 2111 | peer_node, ref, peer_port, | 2139 | tn->own_addr, peer_node, tsk->portid, | 
| 2112 | TIPC_ERR_NO_PORT); | 2140 | peer_port, TIPC_ERR_NO_PORT); | 
| 2113 | } else { | 2141 | } else { | 
| 2114 | skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE, | 2142 | skb = tipc_msg_create(net, CONN_MANAGER, CONN_PROBE, INT_H_SIZE, | 
| 2115 | 0, peer_node, tipc_own_addr, | 2143 | 0, peer_node, tn->own_addr, | 
| 2116 | peer_port, ref, TIPC_OK); | 2144 | peer_port, tsk->portid, TIPC_OK); | 
| 2117 | tsk->probing_state = TIPC_CONN_PROBING; | 2145 | tsk->probing_state = TIPC_CONN_PROBING; | 
| 2118 | k_start_timer(&tsk->timer, tsk->probing_interval); | 2146 | sk_reset_timer(sk, &sk->sk_timer, jiffies + tsk->probing_intv); | 
| 2119 | } | 2147 | } | 
| 2120 | bh_unlock_sock(sk); | 2148 | bh_unlock_sock(sk); | 
| 2121 | if (skb) | 2149 | if (skb) | 
| 2122 | tipc_link_xmit_skb(skb, peer_node, ref); | 2150 | tipc_link_xmit_skb(sock_net(sk), skb, peer_node, tsk->portid); | 
| 2123 | exit: | 2151 | exit: | 
| 2124 | tipc_sk_put(tsk); | 2152 | sock_put(sk); | 
| 2125 | } | 2153 | } | 
| 2126 | 2154 | ||
| 2127 | static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, | 2155 | static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, | 
| 2128 | struct tipc_name_seq const *seq) | 2156 | struct tipc_name_seq const *seq) | 
| 2129 | { | 2157 | { | 
| 2158 | struct net *net = sock_net(&tsk->sk); | ||
| 2130 | struct publication *publ; | 2159 | struct publication *publ; | 
| 2131 | u32 key; | 2160 | u32 key; | 
| 2132 | 2161 | ||
| 2133 | if (tsk->connected) | 2162 | if (tsk->connected) | 
| 2134 | return -EINVAL; | 2163 | return -EINVAL; | 
| 2135 | key = tsk->ref + tsk->pub_count + 1; | 2164 | key = tsk->portid + tsk->pub_count + 1; | 
| 2136 | if (key == tsk->ref) | 2165 | if (key == tsk->portid) | 
| 2137 | return -EADDRINUSE; | 2166 | return -EADDRINUSE; | 
| 2138 | 2167 | ||
| 2139 | publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, | 2168 | publ = tipc_nametbl_publish(net, seq->type, seq->lower, seq->upper, | 
| 2140 | scope, tsk->ref, key); | 2169 | scope, tsk->portid, key); | 
| 2141 | if (unlikely(!publ)) | 2170 | if (unlikely(!publ)) | 
| 2142 | return -EINVAL; | 2171 | return -EINVAL; | 
| 2143 | 2172 | ||
| @@ -2150,6 +2179,7 @@ static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, | |||
| 2150 | static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | 2179 | static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | 
| 2151 | struct tipc_name_seq const *seq) | 2180 | struct tipc_name_seq const *seq) | 
| 2152 | { | 2181 | { | 
| 2182 | struct net *net = sock_net(&tsk->sk); | ||
| 2153 | struct publication *publ; | 2183 | struct publication *publ; | 
| 2154 | struct publication *safe; | 2184 | struct publication *safe; | 
| 2155 | int rc = -EINVAL; | 2185 | int rc = -EINVAL; | 
| @@ -2164,12 +2194,12 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | |||
| 2164 | continue; | 2194 | continue; | 
| 2165 | if (publ->upper != seq->upper) | 2195 | if (publ->upper != seq->upper) | 
| 2166 | break; | 2196 | break; | 
| 2167 | tipc_nametbl_withdraw(publ->type, publ->lower, | 2197 | tipc_nametbl_withdraw(net, publ->type, publ->lower, | 
| 2168 | publ->ref, publ->key); | 2198 | publ->ref, publ->key); | 
| 2169 | rc = 0; | 2199 | rc = 0; | 
| 2170 | break; | 2200 | break; | 
| 2171 | } | 2201 | } | 
| 2172 | tipc_nametbl_withdraw(publ->type, publ->lower, | 2202 | tipc_nametbl_withdraw(net, publ->type, publ->lower, | 
| 2173 | publ->ref, publ->key); | 2203 | publ->ref, publ->key); | 
| 2174 | rc = 0; | 2204 | rc = 0; | 
| 2175 | } | 2205 | } | 
| @@ -2181,16 +2211,18 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | |||
| 2181 | static int tipc_sk_show(struct tipc_sock *tsk, char *buf, | 2211 | static int tipc_sk_show(struct tipc_sock *tsk, char *buf, | 
| 2182 | int len, int full_id) | 2212 | int len, int full_id) | 
| 2183 | { | 2213 | { | 
| 2214 | struct net *net = sock_net(&tsk->sk); | ||
| 2215 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 2184 | struct publication *publ; | 2216 | struct publication *publ; | 
| 2185 | int ret; | 2217 | int ret; | 
| 2186 | 2218 | ||
| 2187 | if (full_id) | 2219 | if (full_id) | 
| 2188 | ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:", | 2220 | ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:", | 
| 2189 | tipc_zone(tipc_own_addr), | 2221 | tipc_zone(tn->own_addr), | 
| 2190 | tipc_cluster(tipc_own_addr), | 2222 | tipc_cluster(tn->own_addr), | 
| 2191 | tipc_node(tipc_own_addr), tsk->ref); | 2223 | tipc_node(tn->own_addr), tsk->portid); | 
| 2192 | else | 2224 | else | 
| 2193 | ret = tipc_snprintf(buf, len, "%-10u:", tsk->ref); | 2225 | ret = tipc_snprintf(buf, len, "%-10u:", tsk->portid); | 
| 2194 | 2226 | ||
| 2195 | if (tsk->connected) { | 2227 | if (tsk->connected) { | 
| 2196 | u32 dport = tsk_peer_port(tsk); | 2228 | u32 dport = tsk_peer_port(tsk); | 
| @@ -2222,15 +2254,18 @@ static int tipc_sk_show(struct tipc_sock *tsk, char *buf, | |||
| 2222 | return ret; | 2254 | return ret; | 
| 2223 | } | 2255 | } | 
| 2224 | 2256 | ||
| 2225 | struct sk_buff *tipc_sk_socks_show(void) | 2257 | struct sk_buff *tipc_sk_socks_show(struct net *net) | 
| 2226 | { | 2258 | { | 
| 2259 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 2260 | const struct bucket_table *tbl; | ||
| 2261 | struct rhash_head *pos; | ||
| 2227 | struct sk_buff *buf; | 2262 | struct sk_buff *buf; | 
| 2228 | struct tlv_desc *rep_tlv; | 2263 | struct tlv_desc *rep_tlv; | 
| 2229 | char *pb; | 2264 | char *pb; | 
| 2230 | int pb_len; | 2265 | int pb_len; | 
| 2231 | struct tipc_sock *tsk; | 2266 | struct tipc_sock *tsk; | 
| 2232 | int str_len = 0; | 2267 | int str_len = 0; | 
| 2233 | u32 ref = 0; | 2268 | int i; | 
| 2234 | 2269 | ||
| 2235 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); | 2270 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); | 
| 2236 | if (!buf) | 2271 | if (!buf) | 
| @@ -2239,14 +2274,18 @@ struct sk_buff *tipc_sk_socks_show(void) | |||
| 2239 | pb = TLV_DATA(rep_tlv); | 2274 | pb = TLV_DATA(rep_tlv); | 
| 2240 | pb_len = ULTRA_STRING_MAX_LEN; | 2275 | pb_len = ULTRA_STRING_MAX_LEN; | 
| 2241 | 2276 | ||
| 2242 | tsk = tipc_sk_get_next(&ref); | 2277 | rcu_read_lock(); | 
| 2243 | for (; tsk; tsk = tipc_sk_get_next(&ref)) { | 2278 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); | 
| 2244 | lock_sock(&tsk->sk); | 2279 | for (i = 0; i < tbl->size; i++) { | 
| 2245 | str_len += tipc_sk_show(tsk, pb + str_len, | 2280 | rht_for_each_entry_rcu(tsk, pos, tbl, i, node) { | 
| 2246 | pb_len - str_len, 0); | 2281 | spin_lock_bh(&tsk->sk.sk_lock.slock); | 
| 2247 | release_sock(&tsk->sk); | 2282 | str_len += tipc_sk_show(tsk, pb + str_len, | 
| 2248 | tipc_sk_put(tsk); | 2283 | pb_len - str_len, 0); | 
| 2284 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | ||
| 2285 | } | ||
| 2249 | } | 2286 | } | 
| 2287 | rcu_read_unlock(); | ||
| 2288 | |||
| 2250 | str_len += 1; /* for "\0" */ | 2289 | str_len += 1; /* for "\0" */ | 
| 2251 | skb_put(buf, TLV_SPACE(str_len)); | 2290 | skb_put(buf, TLV_SPACE(str_len)); | 
| 2252 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | 2291 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | 
| @@ -2257,257 +2296,102 @@ struct sk_buff *tipc_sk_socks_show(void) | |||
| 2257 | /* tipc_sk_reinit: set non-zero address in all existing sockets | 2296 | /* tipc_sk_reinit: set non-zero address in all existing sockets | 
| 2258 | * when we go from standalone to network mode. | 2297 | * when we go from standalone to network mode. | 
| 2259 | */ | 2298 | */ | 
| 2260 | void tipc_sk_reinit(void) | 2299 | void tipc_sk_reinit(struct net *net) | 
| 2261 | { | 2300 | { | 
| 2301 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 2302 | const struct bucket_table *tbl; | ||
| 2303 | struct rhash_head *pos; | ||
| 2304 | struct tipc_sock *tsk; | ||
| 2262 | struct tipc_msg *msg; | 2305 | struct tipc_msg *msg; | 
| 2263 | u32 ref = 0; | 2306 | int i; | 
| 2264 | struct tipc_sock *tsk = tipc_sk_get_next(&ref); | ||
| 2265 | 2307 | ||
| 2266 | for (; tsk; tsk = tipc_sk_get_next(&ref)) { | 2308 | rcu_read_lock(); | 
| 2267 | lock_sock(&tsk->sk); | 2309 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); | 
| 2268 | msg = &tsk->phdr; | 2310 | for (i = 0; i < tbl->size; i++) { | 
| 2269 | msg_set_prevnode(msg, tipc_own_addr); | 2311 | rht_for_each_entry_rcu(tsk, pos, tbl, i, node) { | 
| 2270 | msg_set_orignode(msg, tipc_own_addr); | 2312 | spin_lock_bh(&tsk->sk.sk_lock.slock); | 
| 2271 | release_sock(&tsk->sk); | 2313 | msg = &tsk->phdr; | 
| 2272 | tipc_sk_put(tsk); | 2314 | msg_set_prevnode(msg, tn->own_addr); | 
| 2315 | msg_set_orignode(msg, tn->own_addr); | ||
| 2316 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | ||
| 2317 | } | ||
| 2273 | } | 2318 | } | 
| 2319 | rcu_read_unlock(); | ||
| 2274 | } | 2320 | } | 
| 2275 | 2321 | ||
| 2276 | /** | 2322 | static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid) | 
| 2277 | * struct reference - TIPC socket reference entry | ||
| 2278 | * @tsk: pointer to socket associated with reference entry | ||
| 2279 | * @ref: reference value for socket (combines instance & array index info) | ||
| 2280 | */ | ||
| 2281 | struct reference { | ||
| 2282 | struct tipc_sock *tsk; | ||
| 2283 | u32 ref; | ||
| 2284 | }; | ||
| 2285 | |||
| 2286 | /** | ||
| 2287 | * struct tipc_ref_table - table of TIPC socket reference entries | ||
| 2288 | * @entries: pointer to array of reference entries | ||
| 2289 | * @capacity: array index of first unusable entry | ||
| 2290 | * @init_point: array index of first uninitialized entry | ||
| 2291 | * @first_free: array index of first unused socket reference entry | ||
| 2292 | * @last_free: array index of last unused socket reference entry | ||
| 2293 | * @index_mask: bitmask for array index portion of reference values | ||
| 2294 | * @start_mask: initial value for instance value portion of reference values | ||
| 2295 | */ | ||
| 2296 | struct ref_table { | ||
| 2297 | struct reference *entries; | ||
| 2298 | u32 capacity; | ||
| 2299 | u32 init_point; | ||
| 2300 | u32 first_free; | ||
| 2301 | u32 last_free; | ||
| 2302 | u32 index_mask; | ||
| 2303 | u32 start_mask; | ||
| 2304 | }; | ||
| 2305 | |||
| 2306 | /* Socket reference table consists of 2**N entries. | ||
| 2307 | * | ||
| 2308 | * State Socket ptr Reference | ||
| 2309 | * ----- ---------- --------- | ||
| 2310 | * In use non-NULL XXXX|own index | ||
| 2311 | * (XXXX changes each time entry is acquired) | ||
| 2312 | * Free NULL YYYY|next free index | ||
| 2313 | * (YYYY is one more than last used XXXX) | ||
| 2314 | * Uninitialized NULL 0 | ||
| 2315 | * | ||
| 2316 | * Entry 0 is not used; this allows index 0 to denote the end of the free list. | ||
| 2317 | * | ||
| 2318 | * Note that a reference value of 0 does not necessarily indicate that an | ||
| 2319 | * entry is uninitialized, since the last entry in the free list could also | ||
| 2320 | * have a reference value of 0 (although this is unlikely). | ||
| 2321 | */ | ||
| 2322 | |||
| 2323 | static struct ref_table tipc_ref_table; | ||
| 2324 | |||
| 2325 | static DEFINE_RWLOCK(ref_table_lock); | ||
| 2326 | |||
| 2327 | /** | ||
| 2328 | * tipc_ref_table_init - create reference table for sockets | ||
| 2329 | */ | ||
| 2330 | int tipc_sk_ref_table_init(u32 req_sz, u32 start) | ||
| 2331 | { | 2323 | { | 
| 2332 | struct reference *table; | 2324 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 
| 2333 | u32 actual_sz; | 2325 | struct tipc_sock *tsk; | 
| 2334 | |||
| 2335 | /* account for unused entry, then round up size to a power of 2 */ | ||
| 2336 | |||
| 2337 | req_sz++; | ||
| 2338 | for (actual_sz = 16; actual_sz < req_sz; actual_sz <<= 1) { | ||
| 2339 | /* do nothing */ | ||
| 2340 | }; | ||
| 2341 | |||
| 2342 | /* allocate table & mark all entries as uninitialized */ | ||
| 2343 | table = vzalloc(actual_sz * sizeof(struct reference)); | ||
| 2344 | if (table == NULL) | ||
| 2345 | return -ENOMEM; | ||
| 2346 | |||
| 2347 | tipc_ref_table.entries = table; | ||
| 2348 | tipc_ref_table.capacity = req_sz; | ||
| 2349 | tipc_ref_table.init_point = 1; | ||
| 2350 | tipc_ref_table.first_free = 0; | ||
| 2351 | tipc_ref_table.last_free = 0; | ||
| 2352 | tipc_ref_table.index_mask = actual_sz - 1; | ||
| 2353 | tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask; | ||
| 2354 | 2326 | ||
| 2355 | return 0; | 2327 | rcu_read_lock(); | 
| 2356 | } | 2328 | tsk = rhashtable_lookup(&tn->sk_rht, &portid); | 
| 2329 | if (tsk) | ||
| 2330 | sock_hold(&tsk->sk); | ||
| 2331 | rcu_read_unlock(); | ||
| 2357 | 2332 | ||
| 2358 | /** | 2333 | return tsk; | 
| 2359 | * tipc_ref_table_stop - destroy reference table for sockets | ||
| 2360 | */ | ||
| 2361 | void tipc_sk_ref_table_stop(void) | ||
| 2362 | { | ||
| 2363 | if (!tipc_ref_table.entries) | ||
| 2364 | return; | ||
| 2365 | vfree(tipc_ref_table.entries); | ||
| 2366 | tipc_ref_table.entries = NULL; | ||
| 2367 | } | 2334 | } | 
| 2368 | 2335 | ||
| 2369 | /* tipc_ref_acquire - create reference to a socket | 2336 | static int tipc_sk_insert(struct tipc_sock *tsk) | 
| 2370 | * | ||
| 2371 | * Register an socket pointer in the reference table. | ||
| 2372 | * Returns a unique reference value that is used from then on to retrieve the | ||
| 2373 | * socket pointer, or to determine if the socket has been deregistered. | ||
| 2374 | */ | ||
| 2375 | u32 tipc_sk_ref_acquire(struct tipc_sock *tsk) | ||
| 2376 | { | 2337 | { | 
| 2377 | u32 index; | 2338 | struct sock *sk = &tsk->sk; | 
| 2378 | u32 index_mask; | 2339 | struct net *net = sock_net(sk); | 
| 2379 | u32 next_plus_upper; | 2340 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 
| 2380 | u32 ref = 0; | 2341 | u32 remaining = (TIPC_MAX_PORT - TIPC_MIN_PORT) + 1; | 
| 2381 | struct reference *entry; | 2342 | u32 portid = prandom_u32() % remaining + TIPC_MIN_PORT; | 
| 2382 | 2343 | ||
| 2383 | if (unlikely(!tsk)) { | 2344 | while (remaining--) { | 
| 2384 | pr_err("Attempt to acquire ref. to non-existent obj\n"); | 2345 | portid++; | 
| 2385 | return 0; | 2346 | if ((portid < TIPC_MIN_PORT) || (portid > TIPC_MAX_PORT)) | 
| 2386 | } | 2347 | portid = TIPC_MIN_PORT; | 
| 2387 | if (unlikely(!tipc_ref_table.entries)) { | 2348 | tsk->portid = portid; | 
| 2388 | pr_err("Ref. table not found in acquisition attempt\n"); | 2349 | sock_hold(&tsk->sk); | 
| 2389 | return 0; | 2350 | if (rhashtable_lookup_insert(&tn->sk_rht, &tsk->node)) | 
| 2390 | } | 2351 | return 0; | 
| 2391 | 2352 | sock_put(&tsk->sk); | |
| 2392 | /* Take a free entry, if available; otherwise initialize a new one */ | ||
| 2393 | write_lock_bh(&ref_table_lock); | ||
| 2394 | index = tipc_ref_table.first_free; | ||
| 2395 | entry = &tipc_ref_table.entries[index]; | ||
| 2396 | |||
| 2397 | if (likely(index)) { | ||
| 2398 | index = tipc_ref_table.first_free; | ||
| 2399 | entry = &tipc_ref_table.entries[index]; | ||
| 2400 | index_mask = tipc_ref_table.index_mask; | ||
| 2401 | next_plus_upper = entry->ref; | ||
| 2402 | tipc_ref_table.first_free = next_plus_upper & index_mask; | ||
| 2403 | ref = (next_plus_upper & ~index_mask) + index; | ||
| 2404 | entry->tsk = tsk; | ||
| 2405 | } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { | ||
| 2406 | index = tipc_ref_table.init_point++; | ||
| 2407 | entry = &tipc_ref_table.entries[index]; | ||
| 2408 | ref = tipc_ref_table.start_mask + index; | ||
| 2409 | } | 2353 | } | 
| 2410 | 2354 | ||
| 2411 | if (ref) { | 2355 | return -1; | 
| 2412 | entry->ref = ref; | ||
| 2413 | entry->tsk = tsk; | ||
| 2414 | } | ||
| 2415 | write_unlock_bh(&ref_table_lock); | ||
| 2416 | return ref; | ||
| 2417 | } | 2356 | } | 
| 2418 | 2357 | ||
| 2419 | /* tipc_sk_ref_discard - invalidate reference to an socket | 2358 | static void tipc_sk_remove(struct tipc_sock *tsk) | 
| 2420 | * | ||
| 2421 | * Disallow future references to an socket and free up the entry for re-use. | ||
| 2422 | */ | ||
| 2423 | void tipc_sk_ref_discard(u32 ref) | ||
| 2424 | { | 2359 | { | 
| 2425 | struct reference *entry; | 2360 | struct sock *sk = &tsk->sk; | 
| 2426 | u32 index; | 2361 | struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id); | 
| 2427 | u32 index_mask; | ||
| 2428 | |||
| 2429 | if (unlikely(!tipc_ref_table.entries)) { | ||
| 2430 | pr_err("Ref. table not found during discard attempt\n"); | ||
| 2431 | return; | ||
| 2432 | } | ||
| 2433 | |||
| 2434 | index_mask = tipc_ref_table.index_mask; | ||
| 2435 | index = ref & index_mask; | ||
| 2436 | entry = &tipc_ref_table.entries[index]; | ||
| 2437 | |||
| 2438 | write_lock_bh(&ref_table_lock); | ||
| 2439 | 2362 | ||
| 2440 | if (unlikely(!entry->tsk)) { | 2363 | if (rhashtable_remove(&tn->sk_rht, &tsk->node)) { | 
| 2441 | pr_err("Attempt to discard ref. to non-existent socket\n"); | 2364 | WARN_ON(atomic_read(&sk->sk_refcnt) == 1); | 
| 2442 | goto exit; | 2365 | __sock_put(sk); | 
| 2443 | } | 2366 | } | 
| 2444 | if (unlikely(entry->ref != ref)) { | ||
| 2445 | pr_err("Attempt to discard non-existent reference\n"); | ||
| 2446 | goto exit; | ||
| 2447 | } | ||
| 2448 | |||
| 2449 | /* Mark entry as unused; increment instance part of entry's | ||
| 2450 | * reference to invalidate any subsequent references | ||
| 2451 | */ | ||
| 2452 | |||
| 2453 | entry->tsk = NULL; | ||
| 2454 | entry->ref = (ref & ~index_mask) + (index_mask + 1); | ||
| 2455 | |||
| 2456 | /* Append entry to free entry list */ | ||
| 2457 | if (unlikely(tipc_ref_table.first_free == 0)) | ||
| 2458 | tipc_ref_table.first_free = index; | ||
| 2459 | else | ||
| 2460 | tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index; | ||
| 2461 | tipc_ref_table.last_free = index; | ||
| 2462 | exit: | ||
| 2463 | write_unlock_bh(&ref_table_lock); | ||
| 2464 | } | 2367 | } | 
| 2465 | 2368 | ||
| 2466 | /* tipc_sk_get - find referenced socket and return pointer to it | 2369 | int tipc_sk_rht_init(struct net *net) | 
| 2467 | */ | ||
| 2468 | struct tipc_sock *tipc_sk_get(u32 ref) | ||
| 2469 | { | 2370 | { | 
| 2470 | struct reference *entry; | 2371 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 
| 2471 | struct tipc_sock *tsk; | 2372 | struct rhashtable_params rht_params = { | 
| 2373 | .nelem_hint = 192, | ||
| 2374 | .head_offset = offsetof(struct tipc_sock, node), | ||
| 2375 | .key_offset = offsetof(struct tipc_sock, portid), | ||
| 2376 | .key_len = sizeof(u32), /* portid */ | ||
| 2377 | .hashfn = jhash, | ||
| 2378 | .max_shift = 20, /* 1M */ | ||
| 2379 | .min_shift = 8, /* 256 */ | ||
| 2380 | .grow_decision = rht_grow_above_75, | ||
| 2381 | .shrink_decision = rht_shrink_below_30, | ||
| 2382 | }; | ||
| 2472 | 2383 | ||
| 2473 | if (unlikely(!tipc_ref_table.entries)) | 2384 | return rhashtable_init(&tn->sk_rht, &rht_params); | 
| 2474 | return NULL; | ||
| 2475 | read_lock_bh(&ref_table_lock); | ||
| 2476 | entry = &tipc_ref_table.entries[ref & tipc_ref_table.index_mask]; | ||
| 2477 | tsk = entry->tsk; | ||
| 2478 | if (likely(tsk && (entry->ref == ref))) | ||
| 2479 | sock_hold(&tsk->sk); | ||
| 2480 | else | ||
| 2481 | tsk = NULL; | ||
| 2482 | read_unlock_bh(&ref_table_lock); | ||
| 2483 | return tsk; | ||
| 2484 | } | 2385 | } | 
| 2485 | 2386 | ||
| 2486 | /* tipc_sk_get_next - lock & return next socket after referenced one | 2387 | void tipc_sk_rht_destroy(struct net *net) | 
| 2487 | */ | ||
| 2488 | struct tipc_sock *tipc_sk_get_next(u32 *ref) | ||
| 2489 | { | 2388 | { | 
| 2490 | struct reference *entry; | 2389 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 
| 2491 | struct tipc_sock *tsk = NULL; | ||
| 2492 | uint index = *ref & tipc_ref_table.index_mask; | ||
| 2493 | 2390 | ||
| 2494 | read_lock_bh(&ref_table_lock); | 2391 | /* Wait for socket readers to complete */ | 
| 2495 | while (++index < tipc_ref_table.capacity) { | 2392 | synchronize_net(); | 
| 2496 | entry = &tipc_ref_table.entries[index]; | ||
| 2497 | if (!entry->tsk) | ||
| 2498 | continue; | ||
| 2499 | tsk = entry->tsk; | ||
| 2500 | sock_hold(&tsk->sk); | ||
| 2501 | *ref = entry->ref; | ||
| 2502 | break; | ||
| 2503 | } | ||
| 2504 | read_unlock_bh(&ref_table_lock); | ||
| 2505 | return tsk; | ||
| 2506 | } | ||
| 2507 | 2393 | ||
| 2508 | static void tipc_sk_put(struct tipc_sock *tsk) | 2394 | rhashtable_destroy(&tn->sk_rht); | 
| 2509 | { | ||
| 2510 | sock_put(&tsk->sk); | ||
| 2511 | } | 2395 | } | 
| 2512 | 2396 | ||
| 2513 | /** | 2397 | /** | 
| @@ -2639,8 +2523,9 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt, | |||
| 2639 | return put_user(sizeof(value), ol); | 2523 | return put_user(sizeof(value), ol); | 
| 2640 | } | 2524 | } | 
| 2641 | 2525 | ||
| 2642 | static int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg) | 2526 | static int tipc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 
| 2643 | { | 2527 | { | 
| 2528 | struct sock *sk = sock->sk; | ||
| 2644 | struct tipc_sioc_ln_req lnr; | 2529 | struct tipc_sioc_ln_req lnr; | 
| 2645 | void __user *argp = (void __user *)arg; | 2530 | void __user *argp = (void __user *)arg; | 
| 2646 | 2531 | ||
| @@ -2648,7 +2533,8 @@ static int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg) | |||
| 2648 | case SIOCGETLINKNAME: | 2533 | case SIOCGETLINKNAME: | 
| 2649 | if (copy_from_user(&lnr, argp, sizeof(lnr))) | 2534 | if (copy_from_user(&lnr, argp, sizeof(lnr))) | 
| 2650 | return -EFAULT; | 2535 | return -EFAULT; | 
| 2651 | if (!tipc_node_get_linkname(lnr.bearer_id & 0xffff, lnr.peer, | 2536 | if (!tipc_node_get_linkname(sock_net(sk), | 
| 2537 | lnr.bearer_id & 0xffff, lnr.peer, | ||
| 2652 | lnr.linkname, TIPC_MAX_LINK_NAME)) { | 2538 | lnr.linkname, TIPC_MAX_LINK_NAME)) { | 
| 2653 | if (copy_to_user(argp, &lnr, sizeof(lnr))) | 2539 | if (copy_to_user(argp, &lnr, sizeof(lnr))) | 
| 2654 | return -EFAULT; | 2540 | return -EFAULT; | 
| @@ -2820,6 +2706,8 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, | |||
| 2820 | int err; | 2706 | int err; | 
| 2821 | void *hdr; | 2707 | void *hdr; | 
| 2822 | struct nlattr *attrs; | 2708 | struct nlattr *attrs; | 
| 2709 | struct net *net = sock_net(skb->sk); | ||
| 2710 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 2823 | 2711 | ||
| 2824 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | 2712 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | 
| 2825 | &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); | 2713 | &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); | 
| @@ -2829,9 +2717,9 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, | |||
| 2829 | attrs = nla_nest_start(skb, TIPC_NLA_SOCK); | 2717 | attrs = nla_nest_start(skb, TIPC_NLA_SOCK); | 
| 2830 | if (!attrs) | 2718 | if (!attrs) | 
| 2831 | goto genlmsg_cancel; | 2719 | goto genlmsg_cancel; | 
| 2832 | if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->ref)) | 2720 | if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->portid)) | 
| 2833 | goto attr_msg_cancel; | 2721 | goto attr_msg_cancel; | 
| 2834 | if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tipc_own_addr)) | 2722 | if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tn->own_addr)) | 
| 2835 | goto attr_msg_cancel; | 2723 | goto attr_msg_cancel; | 
| 2836 | 2724 | ||
| 2837 | if (tsk->connected) { | 2725 | if (tsk->connected) { | 
| @@ -2859,22 +2747,37 @@ int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2859 | { | 2747 | { | 
| 2860 | int err; | 2748 | int err; | 
| 2861 | struct tipc_sock *tsk; | 2749 | struct tipc_sock *tsk; | 
| 2862 | u32 prev_ref = cb->args[0]; | 2750 | const struct bucket_table *tbl; | 
| 2863 | u32 ref = prev_ref; | 2751 | struct rhash_head *pos; | 
| 2864 | 2752 | struct net *net = sock_net(skb->sk); | |
| 2865 | tsk = tipc_sk_get_next(&ref); | 2753 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 
| 2866 | for (; tsk; tsk = tipc_sk_get_next(&ref)) { | 2754 | u32 tbl_id = cb->args[0]; | 
| 2867 | lock_sock(&tsk->sk); | 2755 | u32 prev_portid = cb->args[1]; | 
| 2868 | err = __tipc_nl_add_sk(skb, cb, tsk); | ||
| 2869 | release_sock(&tsk->sk); | ||
| 2870 | tipc_sk_put(tsk); | ||
| 2871 | if (err) | ||
| 2872 | break; | ||
| 2873 | 2756 | ||
| 2874 | prev_ref = ref; | 2757 | rcu_read_lock(); | 
| 2875 | } | 2758 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); | 
| 2759 | for (; tbl_id < tbl->size; tbl_id++) { | ||
| 2760 | rht_for_each_entry_rcu(tsk, pos, tbl, tbl_id, node) { | ||
| 2761 | spin_lock_bh(&tsk->sk.sk_lock.slock); | ||
| 2762 | if (prev_portid && prev_portid != tsk->portid) { | ||
| 2763 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | ||
| 2764 | continue; | ||
| 2765 | } | ||
| 2876 | 2766 | ||
| 2877 | cb->args[0] = prev_ref; | 2767 | err = __tipc_nl_add_sk(skb, cb, tsk); | 
| 2768 | if (err) { | ||
| 2769 | prev_portid = tsk->portid; | ||
| 2770 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | ||
| 2771 | goto out; | ||
| 2772 | } | ||
| 2773 | prev_portid = 0; | ||
| 2774 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | ||
| 2775 | } | ||
| 2776 | } | ||
| 2777 | out: | ||
| 2778 | rcu_read_unlock(); | ||
| 2779 | cb->args[0] = tbl_id; | ||
| 2780 | cb->args[1] = prev_portid; | ||
| 2878 | 2781 | ||
| 2879 | return skb->len; | 2782 | return skb->len; | 
| 2880 | } | 2783 | } | 
| @@ -2962,12 +2865,13 @@ static int __tipc_nl_list_sk_publ(struct sk_buff *skb, | |||
| 2962 | int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb) | 2865 | int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb) | 
| 2963 | { | 2866 | { | 
| 2964 | int err; | 2867 | int err; | 
| 2965 | u32 tsk_ref = cb->args[0]; | 2868 | u32 tsk_portid = cb->args[0]; | 
| 2966 | u32 last_publ = cb->args[1]; | 2869 | u32 last_publ = cb->args[1]; | 
| 2967 | u32 done = cb->args[2]; | 2870 | u32 done = cb->args[2]; | 
| 2871 | struct net *net = sock_net(skb->sk); | ||
| 2968 | struct tipc_sock *tsk; | 2872 | struct tipc_sock *tsk; | 
| 2969 | 2873 | ||
| 2970 | if (!tsk_ref) { | 2874 | if (!tsk_portid) { | 
| 2971 | struct nlattr **attrs; | 2875 | struct nlattr **attrs; | 
| 2972 | struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1]; | 2876 | struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1]; | 
| 2973 | 2877 | ||
| @@ -2984,13 +2888,13 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2984 | if (!sock[TIPC_NLA_SOCK_REF]) | 2888 | if (!sock[TIPC_NLA_SOCK_REF]) | 
| 2985 | return -EINVAL; | 2889 | return -EINVAL; | 
| 2986 | 2890 | ||
| 2987 | tsk_ref = nla_get_u32(sock[TIPC_NLA_SOCK_REF]); | 2891 | tsk_portid = nla_get_u32(sock[TIPC_NLA_SOCK_REF]); | 
| 2988 | } | 2892 | } | 
| 2989 | 2893 | ||
| 2990 | if (done) | 2894 | if (done) | 
| 2991 | return 0; | 2895 | return 0; | 
| 2992 | 2896 | ||
| 2993 | tsk = tipc_sk_get(tsk_ref); | 2897 | tsk = tipc_sk_lookup(net, tsk_portid); | 
| 2994 | if (!tsk) | 2898 | if (!tsk) | 
| 2995 | return -EINVAL; | 2899 | return -EINVAL; | 
| 2996 | 2900 | ||
| @@ -2999,9 +2903,9 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2999 | if (!err) | 2903 | if (!err) | 
| 3000 | done = 1; | 2904 | done = 1; | 
| 3001 | release_sock(&tsk->sk); | 2905 | release_sock(&tsk->sk); | 
| 3002 | tipc_sk_put(tsk); | 2906 | sock_put(&tsk->sk); | 
| 3003 | 2907 | ||
| 3004 | cb->args[0] = tsk_ref; | 2908 | cb->args[0] = tsk_portid; | 
| 3005 | cb->args[1] = last_publ; | 2909 | cb->args[1] = last_publ; | 
| 3006 | cb->args[2] = done; | 2910 | cb->args[2] = done; | 
| 3007 | 2911 | ||
