aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-02 19:40:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-02 19:40:27 -0400
commit8d65b08debc7e62b2c6032d7fe7389d895b92cbc (patch)
tree0c3141b60c3a03cc32742b5750c5e763b9dae489 /net/tipc/socket.c
parent5a0387a8a8efb90ae7fea1e2e5c62de3efa74691 (diff)
parent5d15af6778b8e4ed1fd41b040283af278e7a9a72 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Millar: "Here are some highlights from the 2065 networking commits that happened this development cycle: 1) XDP support for IXGBE (John Fastabend) and thunderx (Sunil Kowuri) 2) Add a generic XDP driver, so that anyone can test XDP even if they lack a networking device whose driver has explicit XDP support (me). 3) Sparc64 now has an eBPF JIT too (me) 4) Add a BPF program testing framework via BPF_PROG_TEST_RUN (Alexei Starovoitov) 5) Make netfitler network namespace teardown less expensive (Florian Westphal) 6) Add symmetric hashing support to nft_hash (Laura Garcia Liebana) 7) Implement NAPI and GRO in netvsc driver (Stephen Hemminger) 8) Support TC flower offload statistics in mlxsw (Arkadi Sharshevsky) 9) Multiqueue support in stmmac driver (Joao Pinto) 10) Remove TCP timewait recycling, it never really could possibly work well in the real world and timestamp randomization really zaps any hint of usability this feature had (Soheil Hassas Yeganeh) 11) Support level3 vs level4 ECMP route hashing in ipv4 (Nikolay Aleksandrov) 12) Add socket busy poll support to epoll (Sridhar Samudrala) 13) Netlink extended ACK support (Johannes Berg, Pablo Neira Ayuso, and several others) 14) IPSEC hw offload infrastructure (Steffen Klassert)" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (2065 commits) tipc: refactor function tipc_sk_recv_stream() tipc: refactor function tipc_sk_recvmsg() net: thunderx: Optimize page recycling for XDP net: thunderx: Support for XDP header adjustment net: thunderx: Add support for XDP_TX net: thunderx: Add support for XDP_DROP net: thunderx: Add basic XDP support net: thunderx: Cleanup receive buffer allocation net: thunderx: Optimize CQE_TX handling net: thunderx: Optimize RBDR descriptor handling net: thunderx: Support for page recycling ipx: call ipxitf_put() in ioctl error path net: sched: add helpers to handle extended actions qed*: Fix issues in the ptp filter config implementation. qede: Fix concurrency issue in PTP Tx path processing. stmmac: Add support for SIMATIC IOT2000 platform net: hns: fix ethtool_get_strings overflow in hns driver tcp: fix wraparound issue in tcp_lp bpf, arm64: fix jit branch offset related to ldimm64 bpf, arm64: implement jiting of BPF_XADD ...
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c296
1 files changed, 148 insertions, 148 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index bdce99f9407a..0d4f2f455a7c 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -51,6 +51,7 @@
51#define TIPC_FWD_MSG 1 51#define TIPC_FWD_MSG 1
52#define TIPC_MAX_PORT 0xffffffff 52#define TIPC_MAX_PORT 0xffffffff
53#define TIPC_MIN_PORT 1 53#define TIPC_MIN_PORT 1
54#define TIPC_ACK_RATE 4 /* ACK at 1/4 of of rcv window size */
54 55
55enum { 56enum {
56 TIPC_LISTEN = TCP_LISTEN, 57 TIPC_LISTEN = TCP_LISTEN,
@@ -1305,7 +1306,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
1305/** 1306/**
1306 * tipc_recvmsg - receive packet-oriented message 1307 * tipc_recvmsg - receive packet-oriented message
1307 * @m: descriptor for message info 1308 * @m: descriptor for message info
1308 * @buf_len: total size of user buffer area 1309 * @buflen: length of user buffer area
1309 * @flags: receive flags 1310 * @flags: receive flags
1310 * 1311 *
1311 * Used for SOCK_DGRAM, SOCK_RDM, and SOCK_SEQPACKET messages. 1312 * Used for SOCK_DGRAM, SOCK_RDM, and SOCK_SEQPACKET messages.
@@ -1313,95 +1314,85 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
1313 * 1314 *
1314 * Returns size of returned message data, errno otherwise 1315 * Returns size of returned message data, errno otherwise
1315 */ 1316 */
1316static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len, 1317static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
1317 int flags) 1318 size_t buflen, int flags)
1318{ 1319{
1319 struct sock *sk = sock->sk; 1320 struct sock *sk = sock->sk;
1320 struct tipc_sock *tsk = tipc_sk(sk); 1321 struct tipc_sock *tsk = tipc_sk(sk);
1321 struct sk_buff *buf; 1322 struct sk_buff *skb;
1322 struct tipc_msg *msg; 1323 struct tipc_msg *hdr;
1323 bool is_connectionless = tipc_sk_type_connectionless(sk); 1324 bool connected = !tipc_sk_type_connectionless(sk);
1324 long timeo; 1325 int rc, err, hlen, dlen, copy;
1325 unsigned int sz; 1326 long timeout;
1326 u32 err;
1327 int res, hlen;
1328 1327
1329 /* Catch invalid receive requests */ 1328 /* Catch invalid receive requests */
1330 if (unlikely(!buf_len)) 1329 if (unlikely(!buflen))
1331 return -EINVAL; 1330 return -EINVAL;
1332 1331
1333 lock_sock(sk); 1332 lock_sock(sk);
1334 1333 if (unlikely(connected && sk->sk_state == TIPC_OPEN)) {
1335 if (!is_connectionless && unlikely(sk->sk_state == TIPC_OPEN)) { 1334 rc = -ENOTCONN;
1336 res = -ENOTCONN;
1337 goto exit; 1335 goto exit;
1338 } 1336 }
1337 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1339 1338
1340 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); 1339 do {
1341restart: 1340 /* Look at first msg in receive queue; wait if necessary */
1342 1341 rc = tipc_wait_for_rcvmsg(sock, &timeout);
1343 /* Look for a message in receive queue; wait if necessary */ 1342 if (unlikely(rc))
1344 res = tipc_wait_for_rcvmsg(sock, &timeo); 1343 goto exit;
1345 if (res) 1344 skb = skb_peek(&sk->sk_receive_queue);
1346 goto exit; 1345 hdr = buf_msg(skb);
1347 1346 dlen = msg_data_sz(hdr);
1348 /* Look at first message in receive queue */ 1347 hlen = msg_hdr_sz(hdr);
1349 buf = skb_peek(&sk->sk_receive_queue); 1348 err = msg_errcode(hdr);
1350 msg = buf_msg(buf); 1349 if (likely(dlen || err))
1351 sz = msg_data_sz(msg); 1350 break;
1352 hlen = msg_hdr_sz(msg);
1353 err = msg_errcode(msg);
1354
1355 /* Discard an empty non-errored message & try again */
1356 if ((!sz) && (!err)) {
1357 tsk_advance_rx_queue(sk); 1351 tsk_advance_rx_queue(sk);
1358 goto restart; 1352 } while (1);
1359 }
1360
1361 /* Capture sender's address (optional) */
1362 set_orig_addr(m, msg);
1363 1353
1364 /* Capture ancillary data (optional) */ 1354 /* Collect msg meta data, including error code and rejected data */
1365 res = tipc_sk_anc_data_recv(m, msg, tsk); 1355 set_orig_addr(m, hdr);
1366 if (res) 1356 rc = tipc_sk_anc_data_recv(m, hdr, tsk);
1357 if (unlikely(rc))
1367 goto exit; 1358 goto exit;
1368 1359
1369 /* Capture message data (if valid) & compute return value (always) */ 1360 /* Capture data if non-error msg, otherwise just set return value */
1370 if (!err) { 1361 if (likely(!err)) {
1371 if (unlikely(buf_len < sz)) { 1362 copy = min_t(int, dlen, buflen);
1372 sz = buf_len; 1363 if (unlikely(copy != dlen))
1373 m->msg_flags |= MSG_TRUNC; 1364 m->msg_flags |= MSG_TRUNC;
1374 } 1365 rc = skb_copy_datagram_msg(skb, hlen, m, copy);
1375 res = skb_copy_datagram_msg(buf, hlen, m, sz);
1376 if (res)
1377 goto exit;
1378 res = sz;
1379 } else { 1366 } else {
1380 if (is_connectionless || err == TIPC_CONN_SHUTDOWN || 1367 copy = 0;
1381 m->msg_control) 1368 rc = 0;
1382 res = 0; 1369 if (err != TIPC_CONN_SHUTDOWN && connected && !m->msg_control)
1383 else 1370 rc = -ECONNRESET;
1384 res = -ECONNRESET;
1385 } 1371 }
1372 if (unlikely(rc))
1373 goto exit;
1386 1374
1375 /* Caption of data or error code/rejected data was successful */
1387 if (unlikely(flags & MSG_PEEK)) 1376 if (unlikely(flags & MSG_PEEK))
1388 goto exit; 1377 goto exit;
1389 1378
1390 if (likely(!is_connectionless)) {
1391 tsk->rcv_unacked += tsk_inc(tsk, hlen + sz);
1392 if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4)))
1393 tipc_sk_send_ack(tsk);
1394 }
1395 tsk_advance_rx_queue(sk); 1379 tsk_advance_rx_queue(sk);
1380 if (likely(!connected))
1381 goto exit;
1382
1383 /* Send connection flow control ack when applicable */
1384 tsk->rcv_unacked += tsk_inc(tsk, hlen + dlen);
1385 if (tsk->rcv_unacked >= tsk->rcv_win / TIPC_ACK_RATE)
1386 tipc_sk_send_ack(tsk);
1396exit: 1387exit:
1397 release_sock(sk); 1388 release_sock(sk);
1398 return res; 1389 return rc ? rc : copy;
1399} 1390}
1400 1391
1401/** 1392/**
1402 * tipc_recv_stream - receive stream-oriented data 1393 * tipc_recvstream - receive stream-oriented data
1403 * @m: descriptor for message info 1394 * @m: descriptor for message info
1404 * @buf_len: total size of user buffer area 1395 * @buflen: total size of user buffer area
1405 * @flags: receive flags 1396 * @flags: receive flags
1406 * 1397 *
1407 * Used for SOCK_STREAM messages only. If not enough data is available 1398 * Used for SOCK_STREAM messages only. If not enough data is available
@@ -1409,111 +1400,98 @@ exit:
1409 * 1400 *
1410 * Returns size of returned message data, errno otherwise 1401 * Returns size of returned message data, errno otherwise
1411 */ 1402 */
1412static int tipc_recv_stream(struct socket *sock, struct msghdr *m, 1403static int tipc_recvstream(struct socket *sock, struct msghdr *m,
1413 size_t buf_len, int flags) 1404 size_t buflen, int flags)
1414{ 1405{
1415 struct sock *sk = sock->sk; 1406 struct sock *sk = sock->sk;
1416 struct tipc_sock *tsk = tipc_sk(sk); 1407 struct tipc_sock *tsk = tipc_sk(sk);
1417 struct sk_buff *buf; 1408 struct sk_buff *skb;
1418 struct tipc_msg *msg; 1409 struct tipc_msg *hdr;
1419 long timeo; 1410 struct tipc_skb_cb *skb_cb;
1420 unsigned int sz; 1411 bool peek = flags & MSG_PEEK;
1421 int target; 1412 int offset, required, copy, copied = 0;
1422 int sz_copied = 0; 1413 int hlen, dlen, err, rc;
1423 u32 err; 1414 long timeout;
1424 int res = 0, hlen;
1425 1415
1426 /* Catch invalid receive attempts */ 1416 /* Catch invalid receive attempts */
1427 if (unlikely(!buf_len)) 1417 if (unlikely(!buflen))
1428 return -EINVAL; 1418 return -EINVAL;
1429 1419
1430 lock_sock(sk); 1420 lock_sock(sk);
1431 1421
1432 if (unlikely(sk->sk_state == TIPC_OPEN)) { 1422 if (unlikely(sk->sk_state == TIPC_OPEN)) {
1433 res = -ENOTCONN; 1423 rc = -ENOTCONN;
1434 goto exit;
1435 }
1436
1437 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1438 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1439
1440restart:
1441 /* Look for a message in receive queue; wait if necessary */
1442 res = tipc_wait_for_rcvmsg(sock, &timeo);
1443 if (res)
1444 goto exit; 1424 goto exit;
1445
1446 /* Look at first message in receive queue */
1447 buf = skb_peek(&sk->sk_receive_queue);
1448 msg = buf_msg(buf);
1449 sz = msg_data_sz(msg);
1450 hlen = msg_hdr_sz(msg);
1451 err = msg_errcode(msg);
1452
1453 /* Discard an empty non-errored message & try again */
1454 if ((!sz) && (!err)) {
1455 tsk_advance_rx_queue(sk);
1456 goto restart;
1457 } 1425 }
1426 required = sock_rcvlowat(sk, flags & MSG_WAITALL, buflen);
1427 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1458 1428
1459 /* Optionally capture sender's address & ancillary data of first msg */ 1429 do {
1460 if (sz_copied == 0) { 1430 /* Look at first msg in receive queue; wait if necessary */
1461 set_orig_addr(m, msg); 1431 rc = tipc_wait_for_rcvmsg(sock, &timeout);
1462 res = tipc_sk_anc_data_recv(m, msg, tsk); 1432 if (unlikely(rc))
1463 if (res) 1433 break;
1464 goto exit; 1434 skb = skb_peek(&sk->sk_receive_queue);
1465 } 1435 skb_cb = TIPC_SKB_CB(skb);
1466 1436 hdr = buf_msg(skb);
1467 /* Capture message data (if valid) & compute return value (always) */ 1437 dlen = msg_data_sz(hdr);
1468 if (!err) { 1438 hlen = msg_hdr_sz(hdr);
1469 u32 offset = TIPC_SKB_CB(buf)->bytes_read; 1439 err = msg_errcode(hdr);
1470 u32 needed; 1440
1471 int sz_to_copy; 1441 /* Discard any empty non-errored (SYN-) message */
1472 1442 if (unlikely(!dlen && !err)) {
1473 sz -= offset; 1443 tsk_advance_rx_queue(sk);
1474 needed = (buf_len - sz_copied); 1444 continue;
1475 sz_to_copy = min(sz, needed); 1445 }
1476
1477 res = skb_copy_datagram_msg(buf, hlen + offset, m, sz_to_copy);
1478 if (res)
1479 goto exit;
1480 1446
1481 sz_copied += sz_to_copy; 1447 /* Collect msg meta data, incl. error code and rejected data */
1448 if (!copied) {
1449 set_orig_addr(m, hdr);
1450 rc = tipc_sk_anc_data_recv(m, hdr, tsk);
1451 if (rc)
1452 break;
1453 }
1482 1454
1483 if (sz_to_copy < sz) { 1455 /* Copy data if msg ok, otherwise return error/partial data */
1484 if (!(flags & MSG_PEEK)) 1456 if (likely(!err)) {
1485 TIPC_SKB_CB(buf)->bytes_read = 1457 offset = skb_cb->bytes_read;
1486 offset + sz_to_copy; 1458 copy = min_t(int, dlen - offset, buflen - copied);
1487 goto exit; 1459 rc = skb_copy_datagram_msg(skb, hlen + offset, m, copy);
1460 if (unlikely(rc))
1461 break;
1462 copied += copy;
1463 offset += copy;
1464 if (unlikely(offset < dlen)) {
1465 if (!peek)
1466 skb_cb->bytes_read = offset;
1467 break;
1468 }
1469 } else {
1470 rc = 0;
1471 if ((err != TIPC_CONN_SHUTDOWN) && !m->msg_control)
1472 rc = -ECONNRESET;
1473 if (copied || rc)
1474 break;
1488 } 1475 }
1489 } else {
1490 if (sz_copied != 0)
1491 goto exit; /* can't add error msg to valid data */
1492 1476
1493 if ((err == TIPC_CONN_SHUTDOWN) || m->msg_control) 1477 if (unlikely(peek))
1494 res = 0; 1478 break;
1495 else
1496 res = -ECONNRESET;
1497 }
1498 1479
1499 if (unlikely(flags & MSG_PEEK)) 1480 tsk_advance_rx_queue(sk);
1500 goto exit;
1501 1481
1502 tsk->rcv_unacked += tsk_inc(tsk, hlen + msg_data_sz(msg)); 1482 /* Send connection flow control advertisement when applicable */
1503 if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4))) 1483 tsk->rcv_unacked += tsk_inc(tsk, hlen + dlen);
1504 tipc_sk_send_ack(tsk); 1484 if (unlikely(tsk->rcv_unacked >= tsk->rcv_win / TIPC_ACK_RATE))
1505 tsk_advance_rx_queue(sk); 1485 tipc_sk_send_ack(tsk);
1506 1486
1507 /* Loop around if more data is required */ 1487 /* Exit if all requested data or FIN/error received */
1508 if ((sz_copied < buf_len) && /* didn't get all requested data */ 1488 if (copied == buflen || err)
1509 (!skb_queue_empty(&sk->sk_receive_queue) || 1489 break;
1510 (sz_copied < target)) && /* and more is ready or required */
1511 (!err)) /* and haven't reached a FIN */
1512 goto restart;
1513 1490
1491 } while (!skb_queue_empty(&sk->sk_receive_queue) || copied < required);
1514exit: 1492exit:
1515 release_sock(sk); 1493 release_sock(sk);
1516 return sz_copied ? sz_copied : res; 1494 return copied ? copied : rc;
1517} 1495}
1518 1496
1519/** 1497/**
@@ -2537,6 +2515,28 @@ static int tipc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2537 } 2515 }
2538} 2516}
2539 2517
2518static int tipc_socketpair(struct socket *sock1, struct socket *sock2)
2519{
2520 struct tipc_sock *tsk2 = tipc_sk(sock2->sk);
2521 struct tipc_sock *tsk1 = tipc_sk(sock1->sk);
2522 u32 onode = tipc_own_addr(sock_net(sock1->sk));
2523
2524 tsk1->peer.family = AF_TIPC;
2525 tsk1->peer.addrtype = TIPC_ADDR_ID;
2526 tsk1->peer.scope = TIPC_NODE_SCOPE;
2527 tsk1->peer.addr.id.ref = tsk2->portid;
2528 tsk1->peer.addr.id.node = onode;
2529 tsk2->peer.family = AF_TIPC;
2530 tsk2->peer.addrtype = TIPC_ADDR_ID;
2531 tsk2->peer.scope = TIPC_NODE_SCOPE;
2532 tsk2->peer.addr.id.ref = tsk1->portid;
2533 tsk2->peer.addr.id.node = onode;
2534
2535 tipc_sk_finish_conn(tsk1, tsk2->portid, onode);
2536 tipc_sk_finish_conn(tsk2, tsk1->portid, onode);
2537 return 0;
2538}
2539
2540/* Protocol switches for the various types of TIPC sockets */ 2540/* Protocol switches for the various types of TIPC sockets */
2541 2541
2542static const struct proto_ops msg_ops = { 2542static const struct proto_ops msg_ops = {
@@ -2545,7 +2545,7 @@ static const struct proto_ops msg_ops = {
2545 .release = tipc_release, 2545 .release = tipc_release,
2546 .bind = tipc_bind, 2546 .bind = tipc_bind,
2547 .connect = tipc_connect, 2547 .connect = tipc_connect,
2548 .socketpair = sock_no_socketpair, 2548 .socketpair = tipc_socketpair,
2549 .accept = sock_no_accept, 2549 .accept = sock_no_accept,
2550 .getname = tipc_getname, 2550 .getname = tipc_getname,
2551 .poll = tipc_poll, 2551 .poll = tipc_poll,
@@ -2566,7 +2566,7 @@ static const struct proto_ops packet_ops = {
2566 .release = tipc_release, 2566 .release = tipc_release,
2567 .bind = tipc_bind, 2567 .bind = tipc_bind,
2568 .connect = tipc_connect, 2568 .connect = tipc_connect,
2569 .socketpair = sock_no_socketpair, 2569 .socketpair = tipc_socketpair,
2570 .accept = tipc_accept, 2570 .accept = tipc_accept,
2571 .getname = tipc_getname, 2571 .getname = tipc_getname,
2572 .poll = tipc_poll, 2572 .poll = tipc_poll,
@@ -2587,7 +2587,7 @@ static const struct proto_ops stream_ops = {
2587 .release = tipc_release, 2587 .release = tipc_release,
2588 .bind = tipc_bind, 2588 .bind = tipc_bind,
2589 .connect = tipc_connect, 2589 .connect = tipc_connect,
2590 .socketpair = sock_no_socketpair, 2590 .socketpair = tipc_socketpair,
2591 .accept = tipc_accept, 2591 .accept = tipc_accept,
2592 .getname = tipc_getname, 2592 .getname = tipc_getname,
2593 .poll = tipc_poll, 2593 .poll = tipc_poll,
@@ -2597,7 +2597,7 @@ static const struct proto_ops stream_ops = {
2597 .setsockopt = tipc_setsockopt, 2597 .setsockopt = tipc_setsockopt,
2598 .getsockopt = tipc_getsockopt, 2598 .getsockopt = tipc_getsockopt,
2599 .sendmsg = tipc_sendstream, 2599 .sendmsg = tipc_sendstream,
2600 .recvmsg = tipc_recv_stream, 2600 .recvmsg = tipc_recvstream,
2601 .mmap = sock_no_mmap, 2601 .mmap = sock_no_mmap,
2602 .sendpage = sock_no_sendpage 2602 .sendpage = sock_no_sendpage
2603}; 2603};
@@ -2870,7 +2870,7 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
2870 2870
2871 err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, 2871 err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX,
2872 attrs[TIPC_NLA_SOCK], 2872 attrs[TIPC_NLA_SOCK],
2873 tipc_nl_sock_policy); 2873 tipc_nl_sock_policy, NULL);
2874 if (err) 2874 if (err)
2875 return err; 2875 return err;
2876 2876