diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 425 |
1 files changed, 315 insertions, 110 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 75275c5cf929..4731cad99d1c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -121,6 +121,14 @@ static const struct proto_ops msg_ops; | |||
121 | static struct proto tipc_proto; | 121 | static struct proto tipc_proto; |
122 | static struct proto tipc_proto_kern; | 122 | static struct proto tipc_proto_kern; |
123 | 123 | ||
124 | static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { | ||
125 | [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, | ||
126 | [TIPC_NLA_SOCK_ADDR] = { .type = NLA_U32 }, | ||
127 | [TIPC_NLA_SOCK_REF] = { .type = NLA_U32 }, | ||
128 | [TIPC_NLA_SOCK_CON] = { .type = NLA_NESTED }, | ||
129 | [TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG } | ||
130 | }; | ||
131 | |||
124 | /* | 132 | /* |
125 | * Revised TIPC socket locking policy: | 133 | * Revised TIPC socket locking policy: |
126 | * | 134 | * |
@@ -236,12 +244,12 @@ static void tsk_advance_rx_queue(struct sock *sk) | |||
236 | */ | 244 | */ |
237 | static void tsk_rej_rx_queue(struct sock *sk) | 245 | static void tsk_rej_rx_queue(struct sock *sk) |
238 | { | 246 | { |
239 | struct sk_buff *buf; | 247 | struct sk_buff *skb; |
240 | u32 dnode; | 248 | u32 dnode; |
241 | 249 | ||
242 | while ((buf = __skb_dequeue(&sk->sk_receive_queue))) { | 250 | while ((skb = __skb_dequeue(&sk->sk_receive_queue))) { |
243 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) | 251 | if (tipc_msg_reverse(skb, &dnode, TIPC_ERR_NO_PORT)) |
244 | tipc_link_xmit(buf, dnode, 0); | 252 | tipc_link_xmit_skb(skb, dnode, 0); |
245 | } | 253 | } |
246 | } | 254 | } |
247 | 255 | ||
@@ -454,7 +462,7 @@ static int tipc_release(struct socket *sock) | |||
454 | { | 462 | { |
455 | struct sock *sk = sock->sk; | 463 | struct sock *sk = sock->sk; |
456 | struct tipc_sock *tsk; | 464 | struct tipc_sock *tsk; |
457 | struct sk_buff *buf; | 465 | struct sk_buff *skb; |
458 | u32 dnode; | 466 | u32 dnode; |
459 | 467 | ||
460 | /* | 468 | /* |
@@ -473,11 +481,11 @@ static int tipc_release(struct socket *sock) | |||
473 | */ | 481 | */ |
474 | dnode = tsk_peer_node(tsk); | 482 | dnode = tsk_peer_node(tsk); |
475 | while (sock->state != SS_DISCONNECTING) { | 483 | while (sock->state != SS_DISCONNECTING) { |
476 | buf = __skb_dequeue(&sk->sk_receive_queue); | 484 | skb = __skb_dequeue(&sk->sk_receive_queue); |
477 | if (buf == NULL) | 485 | if (skb == NULL) |
478 | break; | 486 | break; |
479 | if (TIPC_SKB_CB(buf)->handle != NULL) | 487 | if (TIPC_SKB_CB(skb)->handle != NULL) |
480 | kfree_skb(buf); | 488 | kfree_skb(skb); |
481 | else { | 489 | else { |
482 | if ((sock->state == SS_CONNECTING) || | 490 | if ((sock->state == SS_CONNECTING) || |
483 | (sock->state == SS_CONNECTED)) { | 491 | (sock->state == SS_CONNECTED)) { |
@@ -485,8 +493,8 @@ static int tipc_release(struct socket *sock) | |||
485 | tsk->connected = 0; | 493 | tsk->connected = 0; |
486 | tipc_node_remove_conn(dnode, tsk->ref); | 494 | tipc_node_remove_conn(dnode, tsk->ref); |
487 | } | 495 | } |
488 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) | 496 | if (tipc_msg_reverse(skb, &dnode, TIPC_ERR_NO_PORT)) |
489 | tipc_link_xmit(buf, dnode, 0); | 497 | tipc_link_xmit_skb(skb, dnode, 0); |
490 | } | 498 | } |
491 | } | 499 | } |
492 | 500 | ||
@@ -494,12 +502,12 @@ static int tipc_release(struct socket *sock) | |||
494 | tipc_sk_ref_discard(tsk->ref); | 502 | tipc_sk_ref_discard(tsk->ref); |
495 | k_cancel_timer(&tsk->timer); | 503 | k_cancel_timer(&tsk->timer); |
496 | if (tsk->connected) { | 504 | if (tsk->connected) { |
497 | buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, | 505 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, |
498 | SHORT_H_SIZE, 0, dnode, tipc_own_addr, | 506 | SHORT_H_SIZE, 0, dnode, tipc_own_addr, |
499 | tsk_peer_port(tsk), | 507 | tsk_peer_port(tsk), |
500 | tsk->ref, TIPC_ERR_NO_PORT); | 508 | tsk->ref, TIPC_ERR_NO_PORT); |
501 | if (buf) | 509 | if (skb) |
502 | tipc_link_xmit(buf, dnode, tsk->ref); | 510 | tipc_link_xmit_skb(skb, dnode, tsk->ref); |
503 | tipc_node_remove_conn(dnode, tsk->ref); | 511 | tipc_node_remove_conn(dnode, tsk->ref); |
504 | } | 512 | } |
505 | k_term_timer(&tsk->timer); | 513 | k_term_timer(&tsk->timer); |
@@ -692,7 +700,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
692 | * tipc_sendmcast - send multicast message | 700 | * tipc_sendmcast - send multicast message |
693 | * @sock: socket structure | 701 | * @sock: socket structure |
694 | * @seq: destination address | 702 | * @seq: destination address |
695 | * @iov: message data to send | 703 | * @msg: message to send |
696 | * @dsz: total length of message data | 704 | * @dsz: total length of message data |
697 | * @timeo: timeout to wait for wakeup | 705 | * @timeo: timeout to wait for wakeup |
698 | * | 706 | * |
@@ -700,11 +708,11 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
700 | * Returns the number of bytes sent on success, or errno | 708 | * Returns the number of bytes sent on success, or errno |
701 | */ | 709 | */ |
702 | static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, | 710 | static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, |
703 | struct iovec *iov, size_t dsz, long timeo) | 711 | struct msghdr *msg, size_t dsz, long timeo) |
704 | { | 712 | { |
705 | struct sock *sk = sock->sk; | 713 | struct sock *sk = sock->sk; |
706 | struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; | 714 | struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; |
707 | struct sk_buff *buf; | 715 | struct sk_buff_head head; |
708 | uint mtu; | 716 | uint mtu; |
709 | int rc; | 717 | int rc; |
710 | 718 | ||
@@ -719,12 +727,13 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, | |||
719 | 727 | ||
720 | new_mtu: | 728 | new_mtu: |
721 | mtu = tipc_bclink_get_mtu(); | 729 | mtu = tipc_bclink_get_mtu(); |
722 | rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf); | 730 | __skb_queue_head_init(&head); |
731 | rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &head); | ||
723 | if (unlikely(rc < 0)) | 732 | if (unlikely(rc < 0)) |
724 | return rc; | 733 | return rc; |
725 | 734 | ||
726 | do { | 735 | do { |
727 | rc = tipc_bclink_xmit(buf); | 736 | rc = tipc_bclink_xmit(&head); |
728 | if (likely(rc >= 0)) { | 737 | if (likely(rc >= 0)) { |
729 | rc = dsz; | 738 | rc = dsz; |
730 | break; | 739 | break; |
@@ -736,7 +745,7 @@ new_mtu: | |||
736 | tipc_sk(sk)->link_cong = 1; | 745 | tipc_sk(sk)->link_cong = 1; |
737 | rc = tipc_wait_for_sndmsg(sock, &timeo); | 746 | rc = tipc_wait_for_sndmsg(sock, &timeo); |
738 | if (rc) | 747 | if (rc) |
739 | kfree_skb_list(buf); | 748 | __skb_queue_purge(&head); |
740 | } while (!rc); | 749 | } while (!rc); |
741 | return rc; | 750 | return rc; |
742 | } | 751 | } |
@@ -818,39 +827,6 @@ exit: | |||
818 | return TIPC_OK; | 827 | return TIPC_OK; |
819 | } | 828 | } |
820 | 829 | ||
821 | /** | ||
822 | * dest_name_check - verify user is permitted to send to specified port name | ||
823 | * @dest: destination address | ||
824 | * @m: descriptor for message to be sent | ||
825 | * | ||
826 | * Prevents restricted configuration commands from being issued by | ||
827 | * unauthorized users. | ||
828 | * | ||
829 | * Returns 0 if permission is granted, otherwise errno | ||
830 | */ | ||
831 | static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m) | ||
832 | { | ||
833 | struct tipc_cfg_msg_hdr hdr; | ||
834 | |||
835 | if (unlikely(dest->addrtype == TIPC_ADDR_ID)) | ||
836 | return 0; | ||
837 | if (likely(dest->addr.name.name.type >= TIPC_RESERVED_TYPES)) | ||
838 | return 0; | ||
839 | if (likely(dest->addr.name.name.type == TIPC_TOP_SRV)) | ||
840 | return 0; | ||
841 | if (likely(dest->addr.name.name.type != TIPC_CFG_SRV)) | ||
842 | return -EACCES; | ||
843 | |||
844 | if (!m->msg_iovlen || (m->msg_iov[0].iov_len < sizeof(hdr))) | ||
845 | return -EMSGSIZE; | ||
846 | if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr))) | ||
847 | return -EFAULT; | ||
848 | if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN))) | ||
849 | return -EACCES; | ||
850 | |||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) | 830 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) |
855 | { | 831 | { |
856 | struct sock *sk = sock->sk; | 832 | struct sock *sk = sock->sk; |
@@ -897,13 +873,13 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
897 | struct sock *sk = sock->sk; | 873 | struct sock *sk = sock->sk; |
898 | struct tipc_sock *tsk = tipc_sk(sk); | 874 | struct tipc_sock *tsk = tipc_sk(sk); |
899 | struct tipc_msg *mhdr = &tsk->phdr; | 875 | struct tipc_msg *mhdr = &tsk->phdr; |
900 | struct iovec *iov = m->msg_iov; | ||
901 | u32 dnode, dport; | 876 | u32 dnode, dport; |
902 | struct sk_buff *buf; | 877 | struct sk_buff_head head; |
878 | struct sk_buff *skb; | ||
903 | struct tipc_name_seq *seq = &dest->addr.nameseq; | 879 | struct tipc_name_seq *seq = &dest->addr.nameseq; |
904 | u32 mtu; | 880 | u32 mtu; |
905 | long timeo; | 881 | long timeo; |
906 | int rc = -EINVAL; | 882 | int rc; |
907 | 883 | ||
908 | if (unlikely(!dest)) | 884 | if (unlikely(!dest)) |
909 | return -EDESTADDRREQ; | 885 | return -EDESTADDRREQ; |
@@ -936,14 +912,11 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
936 | tsk->conn_instance = dest->addr.name.name.instance; | 912 | tsk->conn_instance = dest->addr.name.name.instance; |
937 | } | 913 | } |
938 | } | 914 | } |
939 | rc = dest_name_check(dest, m); | ||
940 | if (rc) | ||
941 | goto exit; | ||
942 | 915 | ||
943 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | 916 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); |
944 | 917 | ||
945 | if (dest->addrtype == TIPC_ADDR_MCAST) { | 918 | if (dest->addrtype == TIPC_ADDR_MCAST) { |
946 | rc = tipc_sendmcast(sock, seq, iov, dsz, timeo); | 919 | rc = tipc_sendmcast(sock, seq, m, dsz, timeo); |
947 | goto exit; | 920 | goto exit; |
948 | } else if (dest->addrtype == TIPC_ADDR_NAME) { | 921 | } else if (dest->addrtype == TIPC_ADDR_NAME) { |
949 | u32 type = dest->addr.name.name.type; | 922 | u32 type = dest->addr.name.name.type; |
@@ -974,13 +947,15 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
974 | 947 | ||
975 | new_mtu: | 948 | new_mtu: |
976 | mtu = tipc_node_get_mtu(dnode, tsk->ref); | 949 | mtu = tipc_node_get_mtu(dnode, tsk->ref); |
977 | rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf); | 950 | __skb_queue_head_init(&head); |
951 | rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &head); | ||
978 | if (rc < 0) | 952 | if (rc < 0) |
979 | goto exit; | 953 | goto exit; |
980 | 954 | ||
981 | do { | 955 | do { |
982 | TIPC_SKB_CB(buf)->wakeup_pending = tsk->link_cong; | 956 | skb = skb_peek(&head); |
983 | rc = tipc_link_xmit(buf, dnode, tsk->ref); | 957 | TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong; |
958 | rc = tipc_link_xmit(&head, dnode, tsk->ref); | ||
984 | if (likely(rc >= 0)) { | 959 | if (likely(rc >= 0)) { |
985 | if (sock->state != SS_READY) | 960 | if (sock->state != SS_READY) |
986 | sock->state = SS_CONNECTING; | 961 | sock->state = SS_CONNECTING; |
@@ -994,7 +969,7 @@ new_mtu: | |||
994 | tsk->link_cong = 1; | 969 | tsk->link_cong = 1; |
995 | rc = tipc_wait_for_sndmsg(sock, &timeo); | 970 | rc = tipc_wait_for_sndmsg(sock, &timeo); |
996 | if (rc) | 971 | if (rc) |
997 | kfree_skb_list(buf); | 972 | __skb_queue_purge(&head); |
998 | } while (!rc); | 973 | } while (!rc); |
999 | exit: | 974 | exit: |
1000 | if (iocb) | 975 | if (iocb) |
@@ -1051,7 +1026,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1051 | struct sock *sk = sock->sk; | 1026 | struct sock *sk = sock->sk; |
1052 | struct tipc_sock *tsk = tipc_sk(sk); | 1027 | struct tipc_sock *tsk = tipc_sk(sk); |
1053 | struct tipc_msg *mhdr = &tsk->phdr; | 1028 | struct tipc_msg *mhdr = &tsk->phdr; |
1054 | struct sk_buff *buf; | 1029 | struct sk_buff_head head; |
1055 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | 1030 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); |
1056 | u32 ref = tsk->ref; | 1031 | u32 ref = tsk->ref; |
1057 | int rc = -EINVAL; | 1032 | int rc = -EINVAL; |
@@ -1086,12 +1061,13 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1086 | next: | 1061 | next: |
1087 | mtu = tsk->max_pkt; | 1062 | mtu = tsk->max_pkt; |
1088 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); | 1063 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); |
1089 | rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf); | 1064 | __skb_queue_head_init(&head); |
1065 | rc = tipc_msg_build(mhdr, m, sent, send, mtu, &head); | ||
1090 | if (unlikely(rc < 0)) | 1066 | if (unlikely(rc < 0)) |
1091 | goto exit; | 1067 | goto exit; |
1092 | do { | 1068 | do { |
1093 | if (likely(!tsk_conn_cong(tsk))) { | 1069 | if (likely(!tsk_conn_cong(tsk))) { |
1094 | rc = tipc_link_xmit(buf, dnode, ref); | 1070 | rc = tipc_link_xmit(&head, dnode, ref); |
1095 | if (likely(!rc)) { | 1071 | if (likely(!rc)) { |
1096 | tsk->sent_unacked++; | 1072 | tsk->sent_unacked++; |
1097 | sent += send; | 1073 | sent += send; |
@@ -1109,7 +1085,7 @@ next: | |||
1109 | } | 1085 | } |
1110 | rc = tipc_wait_for_sndpkt(sock, &timeo); | 1086 | rc = tipc_wait_for_sndpkt(sock, &timeo); |
1111 | if (rc) | 1087 | if (rc) |
1112 | kfree_skb_list(buf); | 1088 | __skb_queue_purge(&head); |
1113 | } while (!rc); | 1089 | } while (!rc); |
1114 | exit: | 1090 | exit: |
1115 | if (iocb) | 1091 | if (iocb) |
@@ -1254,20 +1230,20 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
1254 | 1230 | ||
1255 | static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack) | 1231 | static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack) |
1256 | { | 1232 | { |
1257 | struct sk_buff *buf = NULL; | 1233 | struct sk_buff *skb = NULL; |
1258 | struct tipc_msg *msg; | 1234 | struct tipc_msg *msg; |
1259 | u32 peer_port = tsk_peer_port(tsk); | 1235 | u32 peer_port = tsk_peer_port(tsk); |
1260 | u32 dnode = tsk_peer_node(tsk); | 1236 | u32 dnode = tsk_peer_node(tsk); |
1261 | 1237 | ||
1262 | if (!tsk->connected) | 1238 | if (!tsk->connected) |
1263 | return; | 1239 | return; |
1264 | buf = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode, | 1240 | skb = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode, |
1265 | tipc_own_addr, peer_port, tsk->ref, TIPC_OK); | 1241 | tipc_own_addr, peer_port, tsk->ref, TIPC_OK); |
1266 | if (!buf) | 1242 | if (!skb) |
1267 | return; | 1243 | return; |
1268 | msg = buf_msg(buf); | 1244 | msg = buf_msg(skb); |
1269 | msg_set_msgcnt(msg, ack); | 1245 | msg_set_msgcnt(msg, ack); |
1270 | tipc_link_xmit(buf, dnode, msg_link_selector(msg)); | 1246 | tipc_link_xmit_skb(skb, dnode, msg_link_selector(msg)); |
1271 | } | 1247 | } |
1272 | 1248 | ||
1273 | static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | 1249 | static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) |
@@ -1372,8 +1348,7 @@ restart: | |||
1372 | sz = buf_len; | 1348 | sz = buf_len; |
1373 | m->msg_flags |= MSG_TRUNC; | 1349 | m->msg_flags |= MSG_TRUNC; |
1374 | } | 1350 | } |
1375 | res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg), | 1351 | res = skb_copy_datagram_msg(buf, msg_hdr_sz(msg), m, sz); |
1376 | m->msg_iov, sz); | ||
1377 | if (res) | 1352 | if (res) |
1378 | goto exit; | 1353 | goto exit; |
1379 | res = sz; | 1354 | res = sz; |
@@ -1473,8 +1448,8 @@ restart: | |||
1473 | needed = (buf_len - sz_copied); | 1448 | needed = (buf_len - sz_copied); |
1474 | sz_to_copy = (sz <= needed) ? sz : needed; | 1449 | sz_to_copy = (sz <= needed) ? sz : needed; |
1475 | 1450 | ||
1476 | res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset, | 1451 | res = skb_copy_datagram_msg(buf, msg_hdr_sz(msg) + offset, |
1477 | m->msg_iov, sz_to_copy); | 1452 | m, sz_to_copy); |
1478 | if (res) | 1453 | if (res) |
1479 | goto exit; | 1454 | goto exit; |
1480 | 1455 | ||
@@ -1556,7 +1531,7 @@ static void tipc_data_ready(struct sock *sk) | |||
1556 | * @tsk: TIPC socket | 1531 | * @tsk: TIPC socket |
1557 | * @msg: message | 1532 | * @msg: message |
1558 | * | 1533 | * |
1559 | * Returns 0 (TIPC_OK) if everyting ok, -TIPC_ERR_NO_PORT otherwise | 1534 | * Returns 0 (TIPC_OK) if everything ok, -TIPC_ERR_NO_PORT otherwise |
1560 | */ | 1535 | */ |
1561 | static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) | 1536 | static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) |
1562 | { | 1537 | { |
@@ -1723,20 +1698,20 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1723 | /** | 1698 | /** |
1724 | * tipc_backlog_rcv - handle incoming message from backlog queue | 1699 | * tipc_backlog_rcv - handle incoming message from backlog queue |
1725 | * @sk: socket | 1700 | * @sk: socket |
1726 | * @buf: message | 1701 | * @skb: message |
1727 | * | 1702 | * |
1728 | * Caller must hold socket lock, but not port lock. | 1703 | * Caller must hold socket lock, but not port lock. |
1729 | * | 1704 | * |
1730 | * Returns 0 | 1705 | * Returns 0 |
1731 | */ | 1706 | */ |
1732 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) | 1707 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb) |
1733 | { | 1708 | { |
1734 | int rc; | 1709 | int rc; |
1735 | u32 onode; | 1710 | u32 onode; |
1736 | struct tipc_sock *tsk = tipc_sk(sk); | 1711 | struct tipc_sock *tsk = tipc_sk(sk); |
1737 | uint truesize = buf->truesize; | 1712 | uint truesize = skb->truesize; |
1738 | 1713 | ||
1739 | rc = filter_rcv(sk, buf); | 1714 | rc = filter_rcv(sk, skb); |
1740 | 1715 | ||
1741 | if (likely(!rc)) { | 1716 | if (likely(!rc)) { |
1742 | if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) | 1717 | if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) |
@@ -1744,25 +1719,25 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) | |||
1744 | return 0; | 1719 | return 0; |
1745 | } | 1720 | } |
1746 | 1721 | ||
1747 | if ((rc < 0) && !tipc_msg_reverse(buf, &onode, -rc)) | 1722 | if ((rc < 0) && !tipc_msg_reverse(skb, &onode, -rc)) |
1748 | return 0; | 1723 | return 0; |
1749 | 1724 | ||
1750 | tipc_link_xmit(buf, onode, 0); | 1725 | tipc_link_xmit_skb(skb, onode, 0); |
1751 | 1726 | ||
1752 | return 0; | 1727 | return 0; |
1753 | } | 1728 | } |
1754 | 1729 | ||
1755 | /** | 1730 | /** |
1756 | * tipc_sk_rcv - handle incoming message | 1731 | * tipc_sk_rcv - handle incoming message |
1757 | * @buf: buffer containing arriving message | 1732 | * @skb: buffer containing arriving message |
1758 | * Consumes buffer | 1733 | * Consumes buffer |
1759 | * Returns 0 if success, or errno: -EHOSTUNREACH | 1734 | * Returns 0 if success, or errno: -EHOSTUNREACH |
1760 | */ | 1735 | */ |
1761 | int tipc_sk_rcv(struct sk_buff *buf) | 1736 | int tipc_sk_rcv(struct sk_buff *skb) |
1762 | { | 1737 | { |
1763 | struct tipc_sock *tsk; | 1738 | struct tipc_sock *tsk; |
1764 | struct sock *sk; | 1739 | struct sock *sk; |
1765 | u32 dport = msg_destport(buf_msg(buf)); | 1740 | u32 dport = msg_destport(buf_msg(skb)); |
1766 | int rc = TIPC_OK; | 1741 | int rc = TIPC_OK; |
1767 | uint limit; | 1742 | uint limit; |
1768 | u32 dnode; | 1743 | u32 dnode; |
@@ -1770,32 +1745,32 @@ int tipc_sk_rcv(struct sk_buff *buf) | |||
1770 | /* Validate destination and message */ | 1745 | /* Validate destination and message */ |
1771 | tsk = tipc_sk_get(dport); | 1746 | tsk = tipc_sk_get(dport); |
1772 | if (unlikely(!tsk)) { | 1747 | if (unlikely(!tsk)) { |
1773 | rc = tipc_msg_eval(buf, &dnode); | 1748 | rc = tipc_msg_eval(skb, &dnode); |
1774 | goto exit; | 1749 | goto exit; |
1775 | } | 1750 | } |
1776 | sk = &tsk->sk; | 1751 | sk = &tsk->sk; |
1777 | 1752 | ||
1778 | /* Queue message */ | 1753 | /* Queue message */ |
1779 | bh_lock_sock(sk); | 1754 | spin_lock_bh(&sk->sk_lock.slock); |
1780 | 1755 | ||
1781 | if (!sock_owned_by_user(sk)) { | 1756 | if (!sock_owned_by_user(sk)) { |
1782 | rc = filter_rcv(sk, buf); | 1757 | rc = filter_rcv(sk, skb); |
1783 | } else { | 1758 | } else { |
1784 | if (sk->sk_backlog.len == 0) | 1759 | if (sk->sk_backlog.len == 0) |
1785 | atomic_set(&tsk->dupl_rcvcnt, 0); | 1760 | atomic_set(&tsk->dupl_rcvcnt, 0); |
1786 | limit = rcvbuf_limit(sk, buf) + atomic_read(&tsk->dupl_rcvcnt); | 1761 | limit = rcvbuf_limit(sk, skb) + atomic_read(&tsk->dupl_rcvcnt); |
1787 | if (sk_add_backlog(sk, buf, limit)) | 1762 | if (sk_add_backlog(sk, skb, limit)) |
1788 | rc = -TIPC_ERR_OVERLOAD; | 1763 | rc = -TIPC_ERR_OVERLOAD; |
1789 | } | 1764 | } |
1790 | bh_unlock_sock(sk); | 1765 | spin_unlock_bh(&sk->sk_lock.slock); |
1791 | tipc_sk_put(tsk); | 1766 | tipc_sk_put(tsk); |
1792 | if (likely(!rc)) | 1767 | if (likely(!rc)) |
1793 | return 0; | 1768 | return 0; |
1794 | exit: | 1769 | exit: |
1795 | if ((rc < 0) && !tipc_msg_reverse(buf, &dnode, -rc)) | 1770 | if ((rc < 0) && !tipc_msg_reverse(skb, &dnode, -rc)) |
1796 | return -EHOSTUNREACH; | 1771 | return -EHOSTUNREACH; |
1797 | 1772 | ||
1798 | tipc_link_xmit(buf, dnode, 0); | 1773 | tipc_link_xmit_skb(skb, dnode, 0); |
1799 | return (rc < 0) ? -EHOSTUNREACH : 0; | 1774 | return (rc < 0) ? -EHOSTUNREACH : 0; |
1800 | } | 1775 | } |
1801 | 1776 | ||
@@ -2053,7 +2028,7 @@ static int tipc_shutdown(struct socket *sock, int how) | |||
2053 | { | 2028 | { |
2054 | struct sock *sk = sock->sk; | 2029 | struct sock *sk = sock->sk; |
2055 | struct tipc_sock *tsk = tipc_sk(sk); | 2030 | struct tipc_sock *tsk = tipc_sk(sk); |
2056 | struct sk_buff *buf; | 2031 | struct sk_buff *skb; |
2057 | u32 dnode; | 2032 | u32 dnode; |
2058 | int res; | 2033 | int res; |
2059 | 2034 | ||
@@ -2068,23 +2043,23 @@ static int tipc_shutdown(struct socket *sock, int how) | |||
2068 | 2043 | ||
2069 | restart: | 2044 | restart: |
2070 | /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ | 2045 | /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ |
2071 | buf = __skb_dequeue(&sk->sk_receive_queue); | 2046 | skb = __skb_dequeue(&sk->sk_receive_queue); |
2072 | if (buf) { | 2047 | if (skb) { |
2073 | if (TIPC_SKB_CB(buf)->handle != NULL) { | 2048 | if (TIPC_SKB_CB(skb)->handle != NULL) { |
2074 | kfree_skb(buf); | 2049 | kfree_skb(skb); |
2075 | goto restart; | 2050 | goto restart; |
2076 | } | 2051 | } |
2077 | if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN)) | 2052 | if (tipc_msg_reverse(skb, &dnode, TIPC_CONN_SHUTDOWN)) |
2078 | tipc_link_xmit(buf, dnode, tsk->ref); | 2053 | tipc_link_xmit_skb(skb, dnode, tsk->ref); |
2079 | tipc_node_remove_conn(dnode, tsk->ref); | 2054 | tipc_node_remove_conn(dnode, tsk->ref); |
2080 | } else { | 2055 | } else { |
2081 | dnode = tsk_peer_node(tsk); | 2056 | dnode = tsk_peer_node(tsk); |
2082 | buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, | 2057 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, |
2083 | TIPC_CONN_MSG, SHORT_H_SIZE, | 2058 | TIPC_CONN_MSG, SHORT_H_SIZE, |
2084 | 0, dnode, tipc_own_addr, | 2059 | 0, dnode, tipc_own_addr, |
2085 | tsk_peer_port(tsk), | 2060 | tsk_peer_port(tsk), |
2086 | tsk->ref, TIPC_CONN_SHUTDOWN); | 2061 | tsk->ref, TIPC_CONN_SHUTDOWN); |
2087 | tipc_link_xmit(buf, dnode, tsk->ref); | 2062 | tipc_link_xmit_skb(skb, dnode, tsk->ref); |
2088 | } | 2063 | } |
2089 | tsk->connected = 0; | 2064 | tsk->connected = 0; |
2090 | sock->state = SS_DISCONNECTING; | 2065 | sock->state = SS_DISCONNECTING; |
@@ -2113,7 +2088,7 @@ static void tipc_sk_timeout(unsigned long ref) | |||
2113 | { | 2088 | { |
2114 | struct tipc_sock *tsk; | 2089 | struct tipc_sock *tsk; |
2115 | struct sock *sk; | 2090 | struct sock *sk; |
2116 | struct sk_buff *buf = NULL; | 2091 | struct sk_buff *skb = NULL; |
2117 | u32 peer_port, peer_node; | 2092 | u32 peer_port, peer_node; |
2118 | 2093 | ||
2119 | tsk = tipc_sk_get(ref); | 2094 | tsk = tipc_sk_get(ref); |
@@ -2131,20 +2106,20 @@ static void tipc_sk_timeout(unsigned long ref) | |||
2131 | 2106 | ||
2132 | if (tsk->probing_state == TIPC_CONN_PROBING) { | 2107 | if (tsk->probing_state == TIPC_CONN_PROBING) { |
2133 | /* Previous probe not answered -> self abort */ | 2108 | /* Previous probe not answered -> self abort */ |
2134 | buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, | 2109 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, |
2135 | SHORT_H_SIZE, 0, tipc_own_addr, | 2110 | SHORT_H_SIZE, 0, tipc_own_addr, |
2136 | peer_node, ref, peer_port, | 2111 | peer_node, ref, peer_port, |
2137 | TIPC_ERR_NO_PORT); | 2112 | TIPC_ERR_NO_PORT); |
2138 | } else { | 2113 | } else { |
2139 | buf = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE, | 2114 | skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE, |
2140 | 0, peer_node, tipc_own_addr, | 2115 | 0, peer_node, tipc_own_addr, |
2141 | peer_port, ref, TIPC_OK); | 2116 | peer_port, ref, TIPC_OK); |
2142 | tsk->probing_state = TIPC_CONN_PROBING; | 2117 | tsk->probing_state = TIPC_CONN_PROBING; |
2143 | k_start_timer(&tsk->timer, tsk->probing_interval); | 2118 | k_start_timer(&tsk->timer, tsk->probing_interval); |
2144 | } | 2119 | } |
2145 | bh_unlock_sock(sk); | 2120 | bh_unlock_sock(sk); |
2146 | if (buf) | 2121 | if (skb) |
2147 | tipc_link_xmit(buf, peer_node, ref); | 2122 | tipc_link_xmit_skb(skb, peer_node, ref); |
2148 | exit: | 2123 | exit: |
2149 | tipc_sk_put(tsk); | 2124 | tipc_sk_put(tsk); |
2150 | } | 2125 | } |
@@ -2673,7 +2648,7 @@ static int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg) | |||
2673 | case SIOCGETLINKNAME: | 2648 | case SIOCGETLINKNAME: |
2674 | if (copy_from_user(&lnr, argp, sizeof(lnr))) | 2649 | if (copy_from_user(&lnr, argp, sizeof(lnr))) |
2675 | return -EFAULT; | 2650 | return -EFAULT; |
2676 | if (!tipc_node_get_linkname(lnr.bearer_id, lnr.peer, | 2651 | if (!tipc_node_get_linkname(lnr.bearer_id & 0xffff, lnr.peer, |
2677 | lnr.linkname, TIPC_MAX_LINK_NAME)) { | 2652 | lnr.linkname, TIPC_MAX_LINK_NAME)) { |
2678 | if (copy_to_user(argp, &lnr, sizeof(lnr))) | 2653 | if (copy_to_user(argp, &lnr, sizeof(lnr))) |
2679 | return -EFAULT; | 2654 | return -EFAULT; |
@@ -2802,3 +2777,233 @@ void tipc_socket_stop(void) | |||
2802 | sock_unregister(tipc_family_ops.family); | 2777 | sock_unregister(tipc_family_ops.family); |
2803 | proto_unregister(&tipc_proto); | 2778 | proto_unregister(&tipc_proto); |
2804 | } | 2779 | } |
2780 | |||
2781 | /* Caller should hold socket lock for the passed tipc socket. */ | ||
2782 | static int __tipc_nl_add_sk_con(struct sk_buff *skb, struct tipc_sock *tsk) | ||
2783 | { | ||
2784 | u32 peer_node; | ||
2785 | u32 peer_port; | ||
2786 | struct nlattr *nest; | ||
2787 | |||
2788 | peer_node = tsk_peer_node(tsk); | ||
2789 | peer_port = tsk_peer_port(tsk); | ||
2790 | |||
2791 | nest = nla_nest_start(skb, TIPC_NLA_SOCK_CON); | ||
2792 | |||
2793 | if (nla_put_u32(skb, TIPC_NLA_CON_NODE, peer_node)) | ||
2794 | goto msg_full; | ||
2795 | if (nla_put_u32(skb, TIPC_NLA_CON_SOCK, peer_port)) | ||
2796 | goto msg_full; | ||
2797 | |||
2798 | if (tsk->conn_type != 0) { | ||
2799 | if (nla_put_flag(skb, TIPC_NLA_CON_FLAG)) | ||
2800 | goto msg_full; | ||
2801 | if (nla_put_u32(skb, TIPC_NLA_CON_TYPE, tsk->conn_type)) | ||
2802 | goto msg_full; | ||
2803 | if (nla_put_u32(skb, TIPC_NLA_CON_INST, tsk->conn_instance)) | ||
2804 | goto msg_full; | ||
2805 | } | ||
2806 | nla_nest_end(skb, nest); | ||
2807 | |||
2808 | return 0; | ||
2809 | |||
2810 | msg_full: | ||
2811 | nla_nest_cancel(skb, nest); | ||
2812 | |||
2813 | return -EMSGSIZE; | ||
2814 | } | ||
2815 | |||
2816 | /* Caller should hold socket lock for the passed tipc socket. */ | ||
2817 | static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, | ||
2818 | struct tipc_sock *tsk) | ||
2819 | { | ||
2820 | int err; | ||
2821 | void *hdr; | ||
2822 | struct nlattr *attrs; | ||
2823 | |||
2824 | 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); | ||
2826 | if (!hdr) | ||
2827 | goto msg_cancel; | ||
2828 | |||
2829 | attrs = nla_nest_start(skb, TIPC_NLA_SOCK); | ||
2830 | if (!attrs) | ||
2831 | goto genlmsg_cancel; | ||
2832 | if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->ref)) | ||
2833 | goto attr_msg_cancel; | ||
2834 | if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tipc_own_addr)) | ||
2835 | goto attr_msg_cancel; | ||
2836 | |||
2837 | if (tsk->connected) { | ||
2838 | err = __tipc_nl_add_sk_con(skb, tsk); | ||
2839 | if (err) | ||
2840 | goto attr_msg_cancel; | ||
2841 | } else if (!list_empty(&tsk->publications)) { | ||
2842 | if (nla_put_flag(skb, TIPC_NLA_SOCK_HAS_PUBL)) | ||
2843 | goto attr_msg_cancel; | ||
2844 | } | ||
2845 | nla_nest_end(skb, attrs); | ||
2846 | genlmsg_end(skb, hdr); | ||
2847 | |||
2848 | return 0; | ||
2849 | |||
2850 | attr_msg_cancel: | ||
2851 | nla_nest_cancel(skb, attrs); | ||
2852 | genlmsg_cancel: | ||
2853 | genlmsg_cancel(skb, hdr); | ||
2854 | msg_cancel: | ||
2855 | return -EMSGSIZE; | ||
2856 | } | ||
2857 | |||
2858 | int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) | ||
2859 | { | ||
2860 | int err; | ||
2861 | struct tipc_sock *tsk; | ||
2862 | u32 prev_ref = cb->args[0]; | ||
2863 | u32 ref = prev_ref; | ||
2864 | |||
2865 | tsk = tipc_sk_get_next(&ref); | ||
2866 | for (; tsk; tsk = tipc_sk_get_next(&ref)) { | ||
2867 | lock_sock(&tsk->sk); | ||
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 | |||
2874 | prev_ref = ref; | ||
2875 | } | ||
2876 | |||
2877 | cb->args[0] = prev_ref; | ||
2878 | |||
2879 | return skb->len; | ||
2880 | } | ||
2881 | |||
2882 | /* Caller should hold socket lock for the passed tipc socket. */ | ||
2883 | static int __tipc_nl_add_sk_publ(struct sk_buff *skb, | ||
2884 | struct netlink_callback *cb, | ||
2885 | struct publication *publ) | ||
2886 | { | ||
2887 | void *hdr; | ||
2888 | struct nlattr *attrs; | ||
2889 | |||
2890 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | ||
2891 | &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_PUBL_GET); | ||
2892 | if (!hdr) | ||
2893 | goto msg_cancel; | ||
2894 | |||
2895 | attrs = nla_nest_start(skb, TIPC_NLA_PUBL); | ||
2896 | if (!attrs) | ||
2897 | goto genlmsg_cancel; | ||
2898 | |||
2899 | if (nla_put_u32(skb, TIPC_NLA_PUBL_KEY, publ->key)) | ||
2900 | goto attr_msg_cancel; | ||
2901 | if (nla_put_u32(skb, TIPC_NLA_PUBL_TYPE, publ->type)) | ||
2902 | goto attr_msg_cancel; | ||
2903 | if (nla_put_u32(skb, TIPC_NLA_PUBL_LOWER, publ->lower)) | ||
2904 | goto attr_msg_cancel; | ||
2905 | if (nla_put_u32(skb, TIPC_NLA_PUBL_UPPER, publ->upper)) | ||
2906 | goto attr_msg_cancel; | ||
2907 | |||
2908 | nla_nest_end(skb, attrs); | ||
2909 | genlmsg_end(skb, hdr); | ||
2910 | |||
2911 | return 0; | ||
2912 | |||
2913 | attr_msg_cancel: | ||
2914 | nla_nest_cancel(skb, attrs); | ||
2915 | genlmsg_cancel: | ||
2916 | genlmsg_cancel(skb, hdr); | ||
2917 | msg_cancel: | ||
2918 | return -EMSGSIZE; | ||
2919 | } | ||
2920 | |||
2921 | /* Caller should hold socket lock for the passed tipc socket. */ | ||
2922 | static int __tipc_nl_list_sk_publ(struct sk_buff *skb, | ||
2923 | struct netlink_callback *cb, | ||
2924 | struct tipc_sock *tsk, u32 *last_publ) | ||
2925 | { | ||
2926 | int err; | ||
2927 | struct publication *p; | ||
2928 | |||
2929 | if (*last_publ) { | ||
2930 | list_for_each_entry(p, &tsk->publications, pport_list) { | ||
2931 | if (p->key == *last_publ) | ||
2932 | break; | ||
2933 | } | ||
2934 | if (p->key != *last_publ) { | ||
2935 | /* We never set seq or call nl_dump_check_consistent() | ||
2936 | * this means that setting prev_seq here will cause the | ||
2937 | * consistence check to fail in the netlink callback | ||
2938 | * handler. Resulting in the last NLMSG_DONE message | ||
2939 | * having the NLM_F_DUMP_INTR flag set. | ||
2940 | */ | ||
2941 | cb->prev_seq = 1; | ||
2942 | *last_publ = 0; | ||
2943 | return -EPIPE; | ||
2944 | } | ||
2945 | } else { | ||
2946 | p = list_first_entry(&tsk->publications, struct publication, | ||
2947 | pport_list); | ||
2948 | } | ||
2949 | |||
2950 | list_for_each_entry_from(p, &tsk->publications, pport_list) { | ||
2951 | err = __tipc_nl_add_sk_publ(skb, cb, p); | ||
2952 | if (err) { | ||
2953 | *last_publ = p->key; | ||
2954 | return err; | ||
2955 | } | ||
2956 | } | ||
2957 | *last_publ = 0; | ||
2958 | |||
2959 | return 0; | ||
2960 | } | ||
2961 | |||
2962 | int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb) | ||
2963 | { | ||
2964 | int err; | ||
2965 | u32 tsk_ref = cb->args[0]; | ||
2966 | u32 last_publ = cb->args[1]; | ||
2967 | u32 done = cb->args[2]; | ||
2968 | struct tipc_sock *tsk; | ||
2969 | |||
2970 | if (!tsk_ref) { | ||
2971 | struct nlattr **attrs; | ||
2972 | struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1]; | ||
2973 | |||
2974 | err = tipc_nlmsg_parse(cb->nlh, &attrs); | ||
2975 | if (err) | ||
2976 | return err; | ||
2977 | |||
2978 | err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, | ||
2979 | attrs[TIPC_NLA_SOCK], | ||
2980 | tipc_nl_sock_policy); | ||
2981 | if (err) | ||
2982 | return err; | ||
2983 | |||
2984 | if (!sock[TIPC_NLA_SOCK_REF]) | ||
2985 | return -EINVAL; | ||
2986 | |||
2987 | tsk_ref = nla_get_u32(sock[TIPC_NLA_SOCK_REF]); | ||
2988 | } | ||
2989 | |||
2990 | if (done) | ||
2991 | return 0; | ||
2992 | |||
2993 | tsk = tipc_sk_get(tsk_ref); | ||
2994 | if (!tsk) | ||
2995 | return -EINVAL; | ||
2996 | |||
2997 | lock_sock(&tsk->sk); | ||
2998 | err = __tipc_nl_list_sk_publ(skb, cb, tsk, &last_publ); | ||
2999 | if (!err) | ||
3000 | done = 1; | ||
3001 | release_sock(&tsk->sk); | ||
3002 | tipc_sk_put(tsk); | ||
3003 | |||
3004 | cb->args[0] = tsk_ref; | ||
3005 | cb->args[1] = last_publ; | ||
3006 | cb->args[2] = done; | ||
3007 | |||
3008 | return skb->len; | ||
3009 | } | ||