diff options
author | James Morris <james.l.morris@oracle.com> | 2014-11-19 05:32:12 -0500 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2014-11-19 05:32:12 -0500 |
commit | b10778a00d40b3d9fdaaf5891e802794781ff71c (patch) | |
tree | 6ba4cbac86eecedc3f30650e7f764ecf00c83898 /net/tipc/socket.c | |
parent | 594081ee7145cc30a3977cb4e218f81213b63dc5 (diff) | |
parent | bfe01a5ba2490f299e1d2d5508cbbbadd897bbe9 (diff) |
Merge commit 'v3.17' into next
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 553 |
1 files changed, 342 insertions, 211 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index ef0475568f9e..ff8c8118d56e 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -36,20 +36,23 @@ | |||
36 | 36 | ||
37 | #include "core.h" | 37 | #include "core.h" |
38 | #include "port.h" | 38 | #include "port.h" |
39 | #include "name_table.h" | ||
39 | #include "node.h" | 40 | #include "node.h" |
40 | 41 | #include "link.h" | |
41 | #include <linux/export.h> | 42 | #include <linux/export.h> |
42 | 43 | ||
43 | #define SS_LISTENING -1 /* socket is listening */ | 44 | #define SS_LISTENING -1 /* socket is listening */ |
44 | #define SS_READY -2 /* socket is connectionless */ | 45 | #define SS_READY -2 /* socket is connectionless */ |
45 | 46 | ||
46 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 47 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ |
48 | #define TIPC_FWD_MSG 1 | ||
47 | 49 | ||
48 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); | 50 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); |
49 | static void tipc_data_ready(struct sock *sk); | 51 | static void tipc_data_ready(struct sock *sk); |
50 | static void tipc_write_space(struct sock *sk); | 52 | static void tipc_write_space(struct sock *sk); |
51 | static int tipc_release(struct socket *sock); | 53 | static int tipc_release(struct socket *sock); |
52 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); | 54 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); |
55 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); | ||
53 | 56 | ||
54 | static const struct proto_ops packet_ops; | 57 | static const struct proto_ops packet_ops; |
55 | static const struct proto_ops stream_ops; | 58 | static const struct proto_ops stream_ops; |
@@ -123,9 +126,12 @@ static void advance_rx_queue(struct sock *sk) | |||
123 | static void reject_rx_queue(struct sock *sk) | 126 | static void reject_rx_queue(struct sock *sk) |
124 | { | 127 | { |
125 | struct sk_buff *buf; | 128 | struct sk_buff *buf; |
129 | u32 dnode; | ||
126 | 130 | ||
127 | while ((buf = __skb_dequeue(&sk->sk_receive_queue))) | 131 | while ((buf = __skb_dequeue(&sk->sk_receive_queue))) { |
128 | tipc_reject_msg(buf, TIPC_ERR_NO_PORT); | 132 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) |
133 | tipc_link_xmit(buf, dnode, 0); | ||
134 | } | ||
129 | } | 135 | } |
130 | 136 | ||
131 | /** | 137 | /** |
@@ -201,6 +207,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
201 | sk->sk_data_ready = tipc_data_ready; | 207 | sk->sk_data_ready = tipc_data_ready; |
202 | sk->sk_write_space = tipc_write_space; | 208 | sk->sk_write_space = tipc_write_space; |
203 | tsk->conn_timeout = CONN_TIMEOUT_DEFAULT; | 209 | tsk->conn_timeout = CONN_TIMEOUT_DEFAULT; |
210 | tsk->sent_unacked = 0; | ||
204 | atomic_set(&tsk->dupl_rcvcnt, 0); | 211 | atomic_set(&tsk->dupl_rcvcnt, 0); |
205 | tipc_port_unlock(port); | 212 | tipc_port_unlock(port); |
206 | 213 | ||
@@ -303,6 +310,7 @@ static int tipc_release(struct socket *sock) | |||
303 | struct tipc_sock *tsk; | 310 | struct tipc_sock *tsk; |
304 | struct tipc_port *port; | 311 | struct tipc_port *port; |
305 | struct sk_buff *buf; | 312 | struct sk_buff *buf; |
313 | u32 dnode; | ||
306 | 314 | ||
307 | /* | 315 | /* |
308 | * Exit if socket isn't fully initialized (occurs when a failed accept() | 316 | * Exit if socket isn't fully initialized (occurs when a failed accept() |
@@ -331,7 +339,8 @@ static int tipc_release(struct socket *sock) | |||
331 | sock->state = SS_DISCONNECTING; | 339 | sock->state = SS_DISCONNECTING; |
332 | tipc_port_disconnect(port->ref); | 340 | tipc_port_disconnect(port->ref); |
333 | } | 341 | } |
334 | tipc_reject_msg(buf, TIPC_ERR_NO_PORT); | 342 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) |
343 | tipc_link_xmit(buf, dnode, 0); | ||
335 | } | 344 | } |
336 | } | 345 | } |
337 | 346 | ||
@@ -504,12 +513,12 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
504 | 513 | ||
505 | switch ((int)sock->state) { | 514 | switch ((int)sock->state) { |
506 | case SS_UNCONNECTED: | 515 | case SS_UNCONNECTED: |
507 | if (!tsk->port.congested) | 516 | if (!tsk->link_cong) |
508 | mask |= POLLOUT; | 517 | mask |= POLLOUT; |
509 | break; | 518 | break; |
510 | case SS_READY: | 519 | case SS_READY: |
511 | case SS_CONNECTED: | 520 | case SS_CONNECTED: |
512 | if (!tsk->port.congested) | 521 | if (!tsk->link_cong && !tipc_sk_conn_cong(tsk)) |
513 | mask |= POLLOUT; | 522 | mask |= POLLOUT; |
514 | /* fall thru' */ | 523 | /* fall thru' */ |
515 | case SS_CONNECTING: | 524 | case SS_CONNECTING: |
@@ -526,6 +535,136 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
526 | } | 535 | } |
527 | 536 | ||
528 | /** | 537 | /** |
538 | * tipc_sendmcast - send multicast message | ||
539 | * @sock: socket structure | ||
540 | * @seq: destination address | ||
541 | * @iov: message data to send | ||
542 | * @dsz: total length of message data | ||
543 | * @timeo: timeout to wait for wakeup | ||
544 | * | ||
545 | * Called from function tipc_sendmsg(), which has done all sanity checks | ||
546 | * Returns the number of bytes sent on success, or errno | ||
547 | */ | ||
548 | static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, | ||
549 | struct iovec *iov, size_t dsz, long timeo) | ||
550 | { | ||
551 | struct sock *sk = sock->sk; | ||
552 | struct tipc_msg *mhdr = &tipc_sk(sk)->port.phdr; | ||
553 | struct sk_buff *buf; | ||
554 | uint mtu; | ||
555 | int rc; | ||
556 | |||
557 | msg_set_type(mhdr, TIPC_MCAST_MSG); | ||
558 | msg_set_lookup_scope(mhdr, TIPC_CLUSTER_SCOPE); | ||
559 | msg_set_destport(mhdr, 0); | ||
560 | msg_set_destnode(mhdr, 0); | ||
561 | msg_set_nametype(mhdr, seq->type); | ||
562 | msg_set_namelower(mhdr, seq->lower); | ||
563 | msg_set_nameupper(mhdr, seq->upper); | ||
564 | msg_set_hdr_sz(mhdr, MCAST_H_SIZE); | ||
565 | |||
566 | new_mtu: | ||
567 | mtu = tipc_bclink_get_mtu(); | ||
568 | rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf); | ||
569 | if (unlikely(rc < 0)) | ||
570 | return rc; | ||
571 | |||
572 | do { | ||
573 | rc = tipc_bclink_xmit(buf); | ||
574 | if (likely(rc >= 0)) { | ||
575 | rc = dsz; | ||
576 | break; | ||
577 | } | ||
578 | if (rc == -EMSGSIZE) | ||
579 | goto new_mtu; | ||
580 | if (rc != -ELINKCONG) | ||
581 | break; | ||
582 | rc = tipc_wait_for_sndmsg(sock, &timeo); | ||
583 | if (rc) | ||
584 | kfree_skb_list(buf); | ||
585 | } while (!rc); | ||
586 | return rc; | ||
587 | } | ||
588 | |||
589 | /* tipc_sk_mcast_rcv - Deliver multicast message to all destination sockets | ||
590 | */ | ||
591 | void tipc_sk_mcast_rcv(struct sk_buff *buf) | ||
592 | { | ||
593 | struct tipc_msg *msg = buf_msg(buf); | ||
594 | struct tipc_port_list dports = {0, NULL, }; | ||
595 | struct tipc_port_list *item; | ||
596 | struct sk_buff *b; | ||
597 | uint i, last, dst = 0; | ||
598 | u32 scope = TIPC_CLUSTER_SCOPE; | ||
599 | |||
600 | if (in_own_node(msg_orignode(msg))) | ||
601 | scope = TIPC_NODE_SCOPE; | ||
602 | |||
603 | /* Create destination port list: */ | ||
604 | tipc_nametbl_mc_translate(msg_nametype(msg), | ||
605 | msg_namelower(msg), | ||
606 | msg_nameupper(msg), | ||
607 | scope, | ||
608 | &dports); | ||
609 | last = dports.count; | ||
610 | if (!last) { | ||
611 | kfree_skb(buf); | ||
612 | return; | ||
613 | } | ||
614 | |||
615 | for (item = &dports; item; item = item->next) { | ||
616 | for (i = 0; i < PLSIZE && ++dst <= last; i++) { | ||
617 | b = (dst != last) ? skb_clone(buf, GFP_ATOMIC) : buf; | ||
618 | if (!b) { | ||
619 | pr_warn("Failed do clone mcast rcv buffer\n"); | ||
620 | continue; | ||
621 | } | ||
622 | msg_set_destport(msg, item->ports[i]); | ||
623 | tipc_sk_rcv(b); | ||
624 | } | ||
625 | } | ||
626 | tipc_port_list_free(&dports); | ||
627 | } | ||
628 | |||
629 | /** | ||
630 | * tipc_sk_proto_rcv - receive a connection mng protocol message | ||
631 | * @tsk: receiving socket | ||
632 | * @dnode: node to send response message to, if any | ||
633 | * @buf: buffer containing protocol message | ||
634 | * Returns 0 (TIPC_OK) if message was consumed, 1 (TIPC_FWD_MSG) if | ||
635 | * (CONN_PROBE_REPLY) message should be forwarded. | ||
636 | */ | ||
637 | static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode, | ||
638 | struct sk_buff *buf) | ||
639 | { | ||
640 | struct tipc_msg *msg = buf_msg(buf); | ||
641 | struct tipc_port *port = &tsk->port; | ||
642 | int conn_cong; | ||
643 | |||
644 | /* Ignore if connection cannot be validated: */ | ||
645 | if (!port->connected || !tipc_port_peer_msg(port, msg)) | ||
646 | goto exit; | ||
647 | |||
648 | port->probing_state = TIPC_CONN_OK; | ||
649 | |||
650 | if (msg_type(msg) == CONN_ACK) { | ||
651 | conn_cong = tipc_sk_conn_cong(tsk); | ||
652 | tsk->sent_unacked -= msg_msgcnt(msg); | ||
653 | if (conn_cong) | ||
654 | tipc_sock_wakeup(tsk); | ||
655 | } else if (msg_type(msg) == CONN_PROBE) { | ||
656 | if (!tipc_msg_reverse(buf, dnode, TIPC_OK)) | ||
657 | return TIPC_OK; | ||
658 | msg_set_type(msg, CONN_PROBE_REPLY); | ||
659 | return TIPC_FWD_MSG; | ||
660 | } | ||
661 | /* Do nothing if msg_type() == CONN_PROBE_REPLY */ | ||
662 | exit: | ||
663 | kfree_skb(buf); | ||
664 | return TIPC_OK; | ||
665 | } | ||
666 | |||
667 | /** | ||
529 | * dest_name_check - verify user is permitted to send to specified port name | 668 | * dest_name_check - verify user is permitted to send to specified port name |
530 | * @dest: destination address | 669 | * @dest: destination address |
531 | * @m: descriptor for message to be sent | 670 | * @m: descriptor for message to be sent |
@@ -539,6 +678,8 @@ static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m) | |||
539 | { | 678 | { |
540 | struct tipc_cfg_msg_hdr hdr; | 679 | struct tipc_cfg_msg_hdr hdr; |
541 | 680 | ||
681 | if (unlikely(dest->addrtype == TIPC_ADDR_ID)) | ||
682 | return 0; | ||
542 | if (likely(dest->addr.name.name.type >= TIPC_RESERVED_TYPES)) | 683 | if (likely(dest->addr.name.name.type >= TIPC_RESERVED_TYPES)) |
543 | return 0; | 684 | return 0; |
544 | if (likely(dest->addr.name.name.type == TIPC_TOP_SRV)) | 685 | if (likely(dest->addr.name.name.type == TIPC_TOP_SRV)) |
@@ -575,19 +716,18 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) | |||
575 | return sock_intr_errno(*timeo_p); | 716 | return sock_intr_errno(*timeo_p); |
576 | 717 | ||
577 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 718 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
578 | done = sk_wait_event(sk, timeo_p, !tsk->port.congested); | 719 | done = sk_wait_event(sk, timeo_p, !tsk->link_cong); |
579 | finish_wait(sk_sleep(sk), &wait); | 720 | finish_wait(sk_sleep(sk), &wait); |
580 | } while (!done); | 721 | } while (!done); |
581 | return 0; | 722 | return 0; |
582 | } | 723 | } |
583 | 724 | ||
584 | |||
585 | /** | 725 | /** |
586 | * tipc_sendmsg - send message in connectionless manner | 726 | * tipc_sendmsg - send message in connectionless manner |
587 | * @iocb: if NULL, indicates that socket lock is already held | 727 | * @iocb: if NULL, indicates that socket lock is already held |
588 | * @sock: socket structure | 728 | * @sock: socket structure |
589 | * @m: message to send | 729 | * @m: message to send |
590 | * @total_len: length of message | 730 | * @dsz: amount of user data to be sent |
591 | * | 731 | * |
592 | * Message must have an destination specified explicitly. | 732 | * Message must have an destination specified explicitly. |
593 | * Used for SOCK_RDM and SOCK_DGRAM messages, | 733 | * Used for SOCK_RDM and SOCK_DGRAM messages, |
@@ -597,100 +737,123 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) | |||
597 | * Returns the number of bytes sent on success, or errno otherwise | 737 | * Returns the number of bytes sent on success, or errno otherwise |
598 | */ | 738 | */ |
599 | static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | 739 | static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, |
600 | struct msghdr *m, size_t total_len) | 740 | struct msghdr *m, size_t dsz) |
601 | { | 741 | { |
742 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | ||
602 | struct sock *sk = sock->sk; | 743 | struct sock *sk = sock->sk; |
603 | struct tipc_sock *tsk = tipc_sk(sk); | 744 | struct tipc_sock *tsk = tipc_sk(sk); |
604 | struct tipc_port *port = &tsk->port; | 745 | struct tipc_port *port = &tsk->port; |
605 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | 746 | struct tipc_msg *mhdr = &port->phdr; |
606 | int needs_conn; | 747 | struct iovec *iov = m->msg_iov; |
748 | u32 dnode, dport; | ||
749 | struct sk_buff *buf; | ||
750 | struct tipc_name_seq *seq = &dest->addr.nameseq; | ||
751 | u32 mtu; | ||
607 | long timeo; | 752 | long timeo; |
608 | int res = -EINVAL; | 753 | int rc = -EINVAL; |
609 | 754 | ||
610 | if (unlikely(!dest)) | 755 | if (unlikely(!dest)) |
611 | return -EDESTADDRREQ; | 756 | return -EDESTADDRREQ; |
757 | |||
612 | if (unlikely((m->msg_namelen < sizeof(*dest)) || | 758 | if (unlikely((m->msg_namelen < sizeof(*dest)) || |
613 | (dest->family != AF_TIPC))) | 759 | (dest->family != AF_TIPC))) |
614 | return -EINVAL; | 760 | return -EINVAL; |
615 | if (total_len > TIPC_MAX_USER_MSG_SIZE) | 761 | |
762 | if (dsz > TIPC_MAX_USER_MSG_SIZE) | ||
616 | return -EMSGSIZE; | 763 | return -EMSGSIZE; |
617 | 764 | ||
618 | if (iocb) | 765 | if (iocb) |
619 | lock_sock(sk); | 766 | lock_sock(sk); |
620 | 767 | ||
621 | needs_conn = (sock->state != SS_READY); | 768 | if (unlikely(sock->state != SS_READY)) { |
622 | if (unlikely(needs_conn)) { | ||
623 | if (sock->state == SS_LISTENING) { | 769 | if (sock->state == SS_LISTENING) { |
624 | res = -EPIPE; | 770 | rc = -EPIPE; |
625 | goto exit; | 771 | goto exit; |
626 | } | 772 | } |
627 | if (sock->state != SS_UNCONNECTED) { | 773 | if (sock->state != SS_UNCONNECTED) { |
628 | res = -EISCONN; | 774 | rc = -EISCONN; |
629 | goto exit; | 775 | goto exit; |
630 | } | 776 | } |
631 | if (tsk->port.published) { | 777 | if (tsk->port.published) { |
632 | res = -EOPNOTSUPP; | 778 | rc = -EOPNOTSUPP; |
633 | goto exit; | 779 | goto exit; |
634 | } | 780 | } |
635 | if (dest->addrtype == TIPC_ADDR_NAME) { | 781 | if (dest->addrtype == TIPC_ADDR_NAME) { |
636 | tsk->port.conn_type = dest->addr.name.name.type; | 782 | tsk->port.conn_type = dest->addr.name.name.type; |
637 | tsk->port.conn_instance = dest->addr.name.name.instance; | 783 | tsk->port.conn_instance = dest->addr.name.name.instance; |
638 | } | 784 | } |
639 | |||
640 | /* Abort any pending connection attempts (very unlikely) */ | ||
641 | reject_rx_queue(sk); | ||
642 | } | 785 | } |
786 | rc = dest_name_check(dest, m); | ||
787 | if (rc) | ||
788 | goto exit; | ||
643 | 789 | ||
644 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | 790 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); |
645 | do { | 791 | |
646 | if (dest->addrtype == TIPC_ADDR_NAME) { | 792 | if (dest->addrtype == TIPC_ADDR_MCAST) { |
647 | res = dest_name_check(dest, m); | 793 | rc = tipc_sendmcast(sock, seq, iov, dsz, timeo); |
648 | if (res) | 794 | goto exit; |
649 | break; | 795 | } else if (dest->addrtype == TIPC_ADDR_NAME) { |
650 | res = tipc_send2name(port, | 796 | u32 type = dest->addr.name.name.type; |
651 | &dest->addr.name.name, | 797 | u32 inst = dest->addr.name.name.instance; |
652 | dest->addr.name.domain, | 798 | u32 domain = dest->addr.name.domain; |
653 | m->msg_iov, | 799 | |
654 | total_len); | 800 | dnode = domain; |
655 | } else if (dest->addrtype == TIPC_ADDR_ID) { | 801 | msg_set_type(mhdr, TIPC_NAMED_MSG); |
656 | res = tipc_send2port(port, | 802 | msg_set_hdr_sz(mhdr, NAMED_H_SIZE); |
657 | &dest->addr.id, | 803 | msg_set_nametype(mhdr, type); |
658 | m->msg_iov, | 804 | msg_set_nameinst(mhdr, inst); |
659 | total_len); | 805 | msg_set_lookup_scope(mhdr, tipc_addr_scope(domain)); |
660 | } else if (dest->addrtype == TIPC_ADDR_MCAST) { | 806 | dport = tipc_nametbl_translate(type, inst, &dnode); |
661 | if (needs_conn) { | 807 | msg_set_destnode(mhdr, dnode); |
662 | res = -EOPNOTSUPP; | 808 | msg_set_destport(mhdr, dport); |
663 | break; | 809 | if (unlikely(!dport && !dnode)) { |
664 | } | 810 | rc = -EHOSTUNREACH; |
665 | res = dest_name_check(dest, m); | 811 | goto exit; |
666 | if (res) | ||
667 | break; | ||
668 | res = tipc_port_mcast_xmit(port, | ||
669 | &dest->addr.nameseq, | ||
670 | m->msg_iov, | ||
671 | total_len); | ||
672 | } | 812 | } |
673 | if (likely(res != -ELINKCONG)) { | 813 | } else if (dest->addrtype == TIPC_ADDR_ID) { |
674 | if (needs_conn && (res >= 0)) | 814 | dnode = dest->addr.id.node; |
815 | msg_set_type(mhdr, TIPC_DIRECT_MSG); | ||
816 | msg_set_lookup_scope(mhdr, 0); | ||
817 | msg_set_destnode(mhdr, dnode); | ||
818 | msg_set_destport(mhdr, dest->addr.id.ref); | ||
819 | msg_set_hdr_sz(mhdr, BASIC_H_SIZE); | ||
820 | } | ||
821 | |||
822 | new_mtu: | ||
823 | mtu = tipc_node_get_mtu(dnode, tsk->port.ref); | ||
824 | rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf); | ||
825 | if (rc < 0) | ||
826 | goto exit; | ||
827 | |||
828 | do { | ||
829 | rc = tipc_link_xmit(buf, dnode, tsk->port.ref); | ||
830 | if (likely(rc >= 0)) { | ||
831 | if (sock->state != SS_READY) | ||
675 | sock->state = SS_CONNECTING; | 832 | sock->state = SS_CONNECTING; |
833 | rc = dsz; | ||
676 | break; | 834 | break; |
677 | } | 835 | } |
678 | res = tipc_wait_for_sndmsg(sock, &timeo); | 836 | if (rc == -EMSGSIZE) |
679 | if (res) | 837 | goto new_mtu; |
838 | |||
839 | if (rc != -ELINKCONG) | ||
680 | break; | 840 | break; |
681 | } while (1); | ||
682 | 841 | ||
842 | rc = tipc_wait_for_sndmsg(sock, &timeo); | ||
843 | if (rc) | ||
844 | kfree_skb_list(buf); | ||
845 | } while (!rc); | ||
683 | exit: | 846 | exit: |
684 | if (iocb) | 847 | if (iocb) |
685 | release_sock(sk); | 848 | release_sock(sk); |
686 | return res; | 849 | |
850 | return rc; | ||
687 | } | 851 | } |
688 | 852 | ||
689 | static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p) | 853 | static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p) |
690 | { | 854 | { |
691 | struct sock *sk = sock->sk; | 855 | struct sock *sk = sock->sk; |
692 | struct tipc_sock *tsk = tipc_sk(sk); | 856 | struct tipc_sock *tsk = tipc_sk(sk); |
693 | struct tipc_port *port = &tsk->port; | ||
694 | DEFINE_WAIT(wait); | 857 | DEFINE_WAIT(wait); |
695 | int done; | 858 | int done; |
696 | 859 | ||
@@ -709,37 +872,49 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p) | |||
709 | 872 | ||
710 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 873 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
711 | done = sk_wait_event(sk, timeo_p, | 874 | done = sk_wait_event(sk, timeo_p, |
712 | (!port->congested || !port->connected)); | 875 | (!tsk->link_cong && |
876 | !tipc_sk_conn_cong(tsk)) || | ||
877 | !tsk->port.connected); | ||
713 | finish_wait(sk_sleep(sk), &wait); | 878 | finish_wait(sk_sleep(sk), &wait); |
714 | } while (!done); | 879 | } while (!done); |
715 | return 0; | 880 | return 0; |
716 | } | 881 | } |
717 | 882 | ||
718 | /** | 883 | /** |
719 | * tipc_send_packet - send a connection-oriented message | 884 | * tipc_send_stream - send stream-oriented data |
720 | * @iocb: if NULL, indicates that socket lock is already held | 885 | * @iocb: (unused) |
721 | * @sock: socket structure | 886 | * @sock: socket structure |
722 | * @m: message to send | 887 | * @m: data to send |
723 | * @total_len: length of message | 888 | * @dsz: total length of data to be transmitted |
724 | * | 889 | * |
725 | * Used for SOCK_SEQPACKET messages and SOCK_STREAM data. | 890 | * Used for SOCK_STREAM data. |
726 | * | 891 | * |
727 | * Returns the number of bytes sent on success, or errno otherwise | 892 | * Returns the number of bytes sent on success (or partial success), |
893 | * or errno if no data sent | ||
728 | */ | 894 | */ |
729 | static int tipc_send_packet(struct kiocb *iocb, struct socket *sock, | 895 | static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, |
730 | struct msghdr *m, size_t total_len) | 896 | struct msghdr *m, size_t dsz) |
731 | { | 897 | { |
732 | struct sock *sk = sock->sk; | 898 | struct sock *sk = sock->sk; |
733 | struct tipc_sock *tsk = tipc_sk(sk); | 899 | struct tipc_sock *tsk = tipc_sk(sk); |
900 | struct tipc_port *port = &tsk->port; | ||
901 | struct tipc_msg *mhdr = &port->phdr; | ||
902 | struct sk_buff *buf; | ||
734 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | 903 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); |
735 | int res = -EINVAL; | 904 | u32 ref = port->ref; |
905 | int rc = -EINVAL; | ||
736 | long timeo; | 906 | long timeo; |
907 | u32 dnode; | ||
908 | uint mtu, send, sent = 0; | ||
737 | 909 | ||
738 | /* Handle implied connection establishment */ | 910 | /* Handle implied connection establishment */ |
739 | if (unlikely(dest)) | 911 | if (unlikely(dest)) { |
740 | return tipc_sendmsg(iocb, sock, m, total_len); | 912 | rc = tipc_sendmsg(iocb, sock, m, dsz); |
741 | 913 | if (dsz && (dsz == rc)) | |
742 | if (total_len > TIPC_MAX_USER_MSG_SIZE) | 914 | tsk->sent_unacked = 1; |
915 | return rc; | ||
916 | } | ||
917 | if (dsz > (uint)INT_MAX) | ||
743 | return -EMSGSIZE; | 918 | return -EMSGSIZE; |
744 | 919 | ||
745 | if (iocb) | 920 | if (iocb) |
@@ -747,123 +922,66 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock, | |||
747 | 922 | ||
748 | if (unlikely(sock->state != SS_CONNECTED)) { | 923 | if (unlikely(sock->state != SS_CONNECTED)) { |
749 | if (sock->state == SS_DISCONNECTING) | 924 | if (sock->state == SS_DISCONNECTING) |
750 | res = -EPIPE; | 925 | rc = -EPIPE; |
751 | else | 926 | else |
752 | res = -ENOTCONN; | 927 | rc = -ENOTCONN; |
753 | goto exit; | 928 | goto exit; |
754 | } | 929 | } |
755 | 930 | ||
756 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | 931 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); |
932 | dnode = tipc_port_peernode(port); | ||
933 | |||
934 | next: | ||
935 | mtu = port->max_pkt; | ||
936 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); | ||
937 | rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf); | ||
938 | if (unlikely(rc < 0)) | ||
939 | goto exit; | ||
757 | do { | 940 | do { |
758 | res = tipc_send(&tsk->port, m->msg_iov, total_len); | 941 | if (likely(!tipc_sk_conn_cong(tsk))) { |
759 | if (likely(res != -ELINKCONG)) | 942 | rc = tipc_link_xmit(buf, dnode, ref); |
760 | break; | 943 | if (likely(!rc)) { |
761 | res = tipc_wait_for_sndpkt(sock, &timeo); | 944 | tsk->sent_unacked++; |
762 | if (res) | 945 | sent += send; |
763 | break; | 946 | if (sent == dsz) |
764 | } while (1); | 947 | break; |
948 | goto next; | ||
949 | } | ||
950 | if (rc == -EMSGSIZE) { | ||
951 | port->max_pkt = tipc_node_get_mtu(dnode, ref); | ||
952 | goto next; | ||
953 | } | ||
954 | if (rc != -ELINKCONG) | ||
955 | break; | ||
956 | } | ||
957 | rc = tipc_wait_for_sndpkt(sock, &timeo); | ||
958 | if (rc) | ||
959 | kfree_skb_list(buf); | ||
960 | } while (!rc); | ||
765 | exit: | 961 | exit: |
766 | if (iocb) | 962 | if (iocb) |
767 | release_sock(sk); | 963 | release_sock(sk); |
768 | return res; | 964 | return sent ? sent : rc; |
769 | } | 965 | } |
770 | 966 | ||
771 | /** | 967 | /** |
772 | * tipc_send_stream - send stream-oriented data | 968 | * tipc_send_packet - send a connection-oriented message |
773 | * @iocb: (unused) | 969 | * @iocb: if NULL, indicates that socket lock is already held |
774 | * @sock: socket structure | 970 | * @sock: socket structure |
775 | * @m: data to send | 971 | * @m: message to send |
776 | * @total_len: total length of data to be sent | 972 | * @dsz: length of data to be transmitted |
777 | * | 973 | * |
778 | * Used for SOCK_STREAM data. | 974 | * Used for SOCK_SEQPACKET messages. |
779 | * | 975 | * |
780 | * Returns the number of bytes sent on success (or partial success), | 976 | * Returns the number of bytes sent on success, or errno otherwise |
781 | * or errno if no data sent | ||
782 | */ | 977 | */ |
783 | static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | 978 | static int tipc_send_packet(struct kiocb *iocb, struct socket *sock, |
784 | struct msghdr *m, size_t total_len) | 979 | struct msghdr *m, size_t dsz) |
785 | { | 980 | { |
786 | struct sock *sk = sock->sk; | 981 | if (dsz > TIPC_MAX_USER_MSG_SIZE) |
787 | struct tipc_sock *tsk = tipc_sk(sk); | 982 | return -EMSGSIZE; |
788 | struct msghdr my_msg; | ||
789 | struct iovec my_iov; | ||
790 | struct iovec *curr_iov; | ||
791 | int curr_iovlen; | ||
792 | char __user *curr_start; | ||
793 | u32 hdr_size; | ||
794 | int curr_left; | ||
795 | int bytes_to_send; | ||
796 | int bytes_sent; | ||
797 | int res; | ||
798 | |||
799 | lock_sock(sk); | ||
800 | |||
801 | /* Handle special cases where there is no connection */ | ||
802 | if (unlikely(sock->state != SS_CONNECTED)) { | ||
803 | if (sock->state == SS_UNCONNECTED) | ||
804 | res = tipc_send_packet(NULL, sock, m, total_len); | ||
805 | else | ||
806 | res = sock->state == SS_DISCONNECTING ? -EPIPE : -ENOTCONN; | ||
807 | goto exit; | ||
808 | } | ||
809 | |||
810 | if (unlikely(m->msg_name)) { | ||
811 | res = -EISCONN; | ||
812 | goto exit; | ||
813 | } | ||
814 | |||
815 | if (total_len > (unsigned int)INT_MAX) { | ||
816 | res = -EMSGSIZE; | ||
817 | goto exit; | ||
818 | } | ||
819 | |||
820 | /* | ||
821 | * Send each iovec entry using one or more messages | ||
822 | * | ||
823 | * Note: This algorithm is good for the most likely case | ||
824 | * (i.e. one large iovec entry), but could be improved to pass sets | ||
825 | * of small iovec entries into send_packet(). | ||
826 | */ | ||
827 | curr_iov = m->msg_iov; | ||
828 | curr_iovlen = m->msg_iovlen; | ||
829 | my_msg.msg_iov = &my_iov; | ||
830 | my_msg.msg_iovlen = 1; | ||
831 | my_msg.msg_flags = m->msg_flags; | ||
832 | my_msg.msg_name = NULL; | ||
833 | bytes_sent = 0; | ||
834 | |||
835 | hdr_size = msg_hdr_sz(&tsk->port.phdr); | ||
836 | |||
837 | while (curr_iovlen--) { | ||
838 | curr_start = curr_iov->iov_base; | ||
839 | curr_left = curr_iov->iov_len; | ||
840 | |||
841 | while (curr_left) { | ||
842 | bytes_to_send = tsk->port.max_pkt - hdr_size; | ||
843 | if (bytes_to_send > TIPC_MAX_USER_MSG_SIZE) | ||
844 | bytes_to_send = TIPC_MAX_USER_MSG_SIZE; | ||
845 | if (curr_left < bytes_to_send) | ||
846 | bytes_to_send = curr_left; | ||
847 | my_iov.iov_base = curr_start; | ||
848 | my_iov.iov_len = bytes_to_send; | ||
849 | res = tipc_send_packet(NULL, sock, &my_msg, | ||
850 | bytes_to_send); | ||
851 | if (res < 0) { | ||
852 | if (bytes_sent) | ||
853 | res = bytes_sent; | ||
854 | goto exit; | ||
855 | } | ||
856 | curr_left -= bytes_to_send; | ||
857 | curr_start += bytes_to_send; | ||
858 | bytes_sent += bytes_to_send; | ||
859 | } | ||
860 | 983 | ||
861 | curr_iov++; | 984 | return tipc_send_stream(iocb, sock, m, dsz); |
862 | } | ||
863 | res = bytes_sent; | ||
864 | exit: | ||
865 | release_sock(sk); | ||
866 | return res; | ||
867 | } | 985 | } |
868 | 986 | ||
869 | /** | 987 | /** |
@@ -1104,8 +1222,10 @@ restart: | |||
1104 | /* Consume received message (optional) */ | 1222 | /* Consume received message (optional) */ |
1105 | if (likely(!(flags & MSG_PEEK))) { | 1223 | if (likely(!(flags & MSG_PEEK))) { |
1106 | if ((sock->state != SS_READY) && | 1224 | if ((sock->state != SS_READY) && |
1107 | (++port->conn_unacked >= TIPC_CONNACK_INTV)) | 1225 | (++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) { |
1108 | tipc_acknowledge(port->ref, port->conn_unacked); | 1226 | tipc_acknowledge(port->ref, tsk->rcv_unacked); |
1227 | tsk->rcv_unacked = 0; | ||
1228 | } | ||
1109 | advance_rx_queue(sk); | 1229 | advance_rx_queue(sk); |
1110 | } | 1230 | } |
1111 | exit: | 1231 | exit: |
@@ -1213,8 +1333,10 @@ restart: | |||
1213 | 1333 | ||
1214 | /* Consume received message (optional) */ | 1334 | /* Consume received message (optional) */ |
1215 | if (likely(!(flags & MSG_PEEK))) { | 1335 | if (likely(!(flags & MSG_PEEK))) { |
1216 | if (unlikely(++port->conn_unacked >= TIPC_CONNACK_INTV)) | 1336 | if (unlikely(++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) { |
1217 | tipc_acknowledge(port->ref, port->conn_unacked); | 1337 | tipc_acknowledge(port->ref, tsk->rcv_unacked); |
1338 | tsk->rcv_unacked = 0; | ||
1339 | } | ||
1218 | advance_rx_queue(sk); | 1340 | advance_rx_queue(sk); |
1219 | } | 1341 | } |
1220 | 1342 | ||
@@ -1269,17 +1391,16 @@ static void tipc_data_ready(struct sock *sk) | |||
1269 | * @tsk: TIPC socket | 1391 | * @tsk: TIPC socket |
1270 | * @msg: message | 1392 | * @msg: message |
1271 | * | 1393 | * |
1272 | * Returns TIPC error status code and socket error status code | 1394 | * Returns 0 (TIPC_OK) if everyting ok, -TIPC_ERR_NO_PORT otherwise |
1273 | * once it encounters some errors | ||
1274 | */ | 1395 | */ |
1275 | static u32 filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) | 1396 | static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) |
1276 | { | 1397 | { |
1277 | struct sock *sk = &tsk->sk; | 1398 | struct sock *sk = &tsk->sk; |
1278 | struct tipc_port *port = &tsk->port; | 1399 | struct tipc_port *port = &tsk->port; |
1279 | struct socket *sock = sk->sk_socket; | 1400 | struct socket *sock = sk->sk_socket; |
1280 | struct tipc_msg *msg = buf_msg(*buf); | 1401 | struct tipc_msg *msg = buf_msg(*buf); |
1281 | 1402 | ||
1282 | u32 retval = TIPC_ERR_NO_PORT; | 1403 | int retval = -TIPC_ERR_NO_PORT; |
1283 | int res; | 1404 | int res; |
1284 | 1405 | ||
1285 | if (msg_mcast(msg)) | 1406 | if (msg_mcast(msg)) |
@@ -1382,32 +1503,37 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf) | |||
1382 | * | 1503 | * |
1383 | * Called with socket lock already taken; port lock may also be taken. | 1504 | * Called with socket lock already taken; port lock may also be taken. |
1384 | * | 1505 | * |
1385 | * Returns TIPC error status code (TIPC_OK if message is not to be rejected) | 1506 | * Returns 0 (TIPC_OK) if message was consumed, -TIPC error code if message |
1507 | * to be rejected, 1 (TIPC_FWD_MSG) if (CONN_MANAGER) message to be forwarded | ||
1386 | */ | 1508 | */ |
1387 | static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | 1509 | static int filter_rcv(struct sock *sk, struct sk_buff *buf) |
1388 | { | 1510 | { |
1389 | struct socket *sock = sk->sk_socket; | 1511 | struct socket *sock = sk->sk_socket; |
1390 | struct tipc_sock *tsk = tipc_sk(sk); | 1512 | struct tipc_sock *tsk = tipc_sk(sk); |
1391 | struct tipc_msg *msg = buf_msg(buf); | 1513 | struct tipc_msg *msg = buf_msg(buf); |
1392 | unsigned int limit = rcvbuf_limit(sk, buf); | 1514 | unsigned int limit = rcvbuf_limit(sk, buf); |
1393 | u32 res = TIPC_OK; | 1515 | u32 onode; |
1516 | int rc = TIPC_OK; | ||
1517 | |||
1518 | if (unlikely(msg_user(msg) == CONN_MANAGER)) | ||
1519 | return tipc_sk_proto_rcv(tsk, &onode, buf); | ||
1394 | 1520 | ||
1395 | /* Reject message if it is wrong sort of message for socket */ | 1521 | /* Reject message if it is wrong sort of message for socket */ |
1396 | if (msg_type(msg) > TIPC_DIRECT_MSG) | 1522 | if (msg_type(msg) > TIPC_DIRECT_MSG) |
1397 | return TIPC_ERR_NO_PORT; | 1523 | return -TIPC_ERR_NO_PORT; |
1398 | 1524 | ||
1399 | if (sock->state == SS_READY) { | 1525 | if (sock->state == SS_READY) { |
1400 | if (msg_connected(msg)) | 1526 | if (msg_connected(msg)) |
1401 | return TIPC_ERR_NO_PORT; | 1527 | return -TIPC_ERR_NO_PORT; |
1402 | } else { | 1528 | } else { |
1403 | res = filter_connect(tsk, &buf); | 1529 | rc = filter_connect(tsk, &buf); |
1404 | if (res != TIPC_OK || buf == NULL) | 1530 | if (rc != TIPC_OK || buf == NULL) |
1405 | return res; | 1531 | return rc; |
1406 | } | 1532 | } |
1407 | 1533 | ||
1408 | /* Reject message if there isn't room to queue it */ | 1534 | /* Reject message if there isn't room to queue it */ |
1409 | if (sk_rmem_alloc_get(sk) + buf->truesize >= limit) | 1535 | if (sk_rmem_alloc_get(sk) + buf->truesize >= limit) |
1410 | return TIPC_ERR_OVERLOAD; | 1536 | return -TIPC_ERR_OVERLOAD; |
1411 | 1537 | ||
1412 | /* Enqueue message */ | 1538 | /* Enqueue message */ |
1413 | TIPC_SKB_CB(buf)->handle = NULL; | 1539 | TIPC_SKB_CB(buf)->handle = NULL; |
@@ -1429,16 +1555,23 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1429 | */ | 1555 | */ |
1430 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) | 1556 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) |
1431 | { | 1557 | { |
1432 | u32 res; | 1558 | int rc; |
1559 | u32 onode; | ||
1433 | struct tipc_sock *tsk = tipc_sk(sk); | 1560 | struct tipc_sock *tsk = tipc_sk(sk); |
1434 | uint truesize = buf->truesize; | 1561 | uint truesize = buf->truesize; |
1435 | 1562 | ||
1436 | res = filter_rcv(sk, buf); | 1563 | rc = filter_rcv(sk, buf); |
1437 | if (unlikely(res)) | ||
1438 | tipc_reject_msg(buf, res); | ||
1439 | 1564 | ||
1440 | if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) | 1565 | if (likely(!rc)) { |
1441 | atomic_add(truesize, &tsk->dupl_rcvcnt); | 1566 | if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) |
1567 | atomic_add(truesize, &tsk->dupl_rcvcnt); | ||
1568 | return 0; | ||
1569 | } | ||
1570 | |||
1571 | if ((rc < 0) && !tipc_msg_reverse(buf, &onode, -rc)) | ||
1572 | return 0; | ||
1573 | |||
1574 | tipc_link_xmit(buf, onode, 0); | ||
1442 | 1575 | ||
1443 | return 0; | 1576 | return 0; |
1444 | } | 1577 | } |
@@ -1455,19 +1588,14 @@ int tipc_sk_rcv(struct sk_buff *buf) | |||
1455 | struct tipc_port *port; | 1588 | struct tipc_port *port; |
1456 | struct sock *sk; | 1589 | struct sock *sk; |
1457 | u32 dport = msg_destport(buf_msg(buf)); | 1590 | u32 dport = msg_destport(buf_msg(buf)); |
1458 | int err = TIPC_OK; | 1591 | int rc = TIPC_OK; |
1459 | uint limit; | 1592 | uint limit; |
1593 | u32 dnode; | ||
1460 | 1594 | ||
1461 | /* Forward unresolved named message */ | 1595 | /* Validate destination and message */ |
1462 | if (unlikely(!dport)) { | ||
1463 | tipc_net_route_msg(buf); | ||
1464 | return 0; | ||
1465 | } | ||
1466 | |||
1467 | /* Validate destination */ | ||
1468 | port = tipc_port_lock(dport); | 1596 | port = tipc_port_lock(dport); |
1469 | if (unlikely(!port)) { | 1597 | if (unlikely(!port)) { |
1470 | err = TIPC_ERR_NO_PORT; | 1598 | rc = tipc_msg_eval(buf, &dnode); |
1471 | goto exit; | 1599 | goto exit; |
1472 | } | 1600 | } |
1473 | 1601 | ||
@@ -1478,23 +1606,25 @@ int tipc_sk_rcv(struct sk_buff *buf) | |||
1478 | bh_lock_sock(sk); | 1606 | bh_lock_sock(sk); |
1479 | 1607 | ||
1480 | if (!sock_owned_by_user(sk)) { | 1608 | if (!sock_owned_by_user(sk)) { |
1481 | err = filter_rcv(sk, buf); | 1609 | rc = filter_rcv(sk, buf); |
1482 | } else { | 1610 | } else { |
1483 | if (sk->sk_backlog.len == 0) | 1611 | if (sk->sk_backlog.len == 0) |
1484 | atomic_set(&tsk->dupl_rcvcnt, 0); | 1612 | atomic_set(&tsk->dupl_rcvcnt, 0); |
1485 | limit = rcvbuf_limit(sk, buf) + atomic_read(&tsk->dupl_rcvcnt); | 1613 | limit = rcvbuf_limit(sk, buf) + atomic_read(&tsk->dupl_rcvcnt); |
1486 | if (sk_add_backlog(sk, buf, limit)) | 1614 | if (sk_add_backlog(sk, buf, limit)) |
1487 | err = TIPC_ERR_OVERLOAD; | 1615 | rc = -TIPC_ERR_OVERLOAD; |
1488 | } | 1616 | } |
1489 | |||
1490 | bh_unlock_sock(sk); | 1617 | bh_unlock_sock(sk); |
1491 | tipc_port_unlock(port); | 1618 | tipc_port_unlock(port); |
1492 | 1619 | ||
1493 | if (likely(!err)) | 1620 | if (likely(!rc)) |
1494 | return 0; | 1621 | return 0; |
1495 | exit: | 1622 | exit: |
1496 | tipc_reject_msg(buf, err); | 1623 | if ((rc < 0) && !tipc_msg_reverse(buf, &dnode, -rc)) |
1497 | return -EHOSTUNREACH; | 1624 | return -EHOSTUNREACH; |
1625 | |||
1626 | tipc_link_xmit(buf, dnode, 0); | ||
1627 | return (rc < 0) ? -EHOSTUNREACH : 0; | ||
1498 | } | 1628 | } |
1499 | 1629 | ||
1500 | static int tipc_wait_for_connect(struct socket *sock, long *timeo_p) | 1630 | static int tipc_wait_for_connect(struct socket *sock, long *timeo_p) |
@@ -1758,6 +1888,7 @@ static int tipc_shutdown(struct socket *sock, int how) | |||
1758 | struct tipc_sock *tsk = tipc_sk(sk); | 1888 | struct tipc_sock *tsk = tipc_sk(sk); |
1759 | struct tipc_port *port = &tsk->port; | 1889 | struct tipc_port *port = &tsk->port; |
1760 | struct sk_buff *buf; | 1890 | struct sk_buff *buf; |
1891 | u32 peer; | ||
1761 | int res; | 1892 | int res; |
1762 | 1893 | ||
1763 | if (how != SHUT_RDWR) | 1894 | if (how != SHUT_RDWR) |
@@ -1778,7 +1909,8 @@ restart: | |||
1778 | goto restart; | 1909 | goto restart; |
1779 | } | 1910 | } |
1780 | tipc_port_disconnect(port->ref); | 1911 | tipc_port_disconnect(port->ref); |
1781 | tipc_reject_msg(buf, TIPC_CONN_SHUTDOWN); | 1912 | if (tipc_msg_reverse(buf, &peer, TIPC_CONN_SHUTDOWN)) |
1913 | tipc_link_xmit(buf, peer, 0); | ||
1782 | } else { | 1914 | } else { |
1783 | tipc_port_shutdown(port->ref); | 1915 | tipc_port_shutdown(port->ref); |
1784 | } | 1916 | } |
@@ -1841,7 +1973,7 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt, | |||
1841 | 1973 | ||
1842 | switch (opt) { | 1974 | switch (opt) { |
1843 | case TIPC_IMPORTANCE: | 1975 | case TIPC_IMPORTANCE: |
1844 | tipc_port_set_importance(port, value); | 1976 | res = tipc_port_set_importance(port, value); |
1845 | break; | 1977 | break; |
1846 | case TIPC_SRC_DROPPABLE: | 1978 | case TIPC_SRC_DROPPABLE: |
1847 | if (sock->type != SOCK_STREAM) | 1979 | if (sock->type != SOCK_STREAM) |
@@ -1936,7 +2068,7 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt, | |||
1936 | return put_user(sizeof(value), ol); | 2068 | return put_user(sizeof(value), ol); |
1937 | } | 2069 | } |
1938 | 2070 | ||
1939 | int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg) | 2071 | static int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg) |
1940 | { | 2072 | { |
1941 | struct tipc_sioc_ln_req lnr; | 2073 | struct tipc_sioc_ln_req lnr; |
1942 | void __user *argp = (void __user *)arg; | 2074 | void __user *argp = (void __user *)arg; |
@@ -1952,7 +2084,6 @@ int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg) | |||
1952 | return 0; | 2084 | return 0; |
1953 | } | 2085 | } |
1954 | return -EADDRNOTAVAIL; | 2086 | return -EADDRNOTAVAIL; |
1955 | break; | ||
1956 | default: | 2087 | default: |
1957 | return -ENOIOCTLCMD; | 2088 | return -ENOIOCTLCMD; |
1958 | } | 2089 | } |