aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/msg.c10
-rw-r--r--net/tipc/port.c53
-rw-r--r--net/tipc/port.h1
-rw-r--r--net/tipc/socket.c64
-rw-r--r--net/tipc/socket.h3
5 files changed, 68 insertions, 63 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 7bfc4422bf2c..6ec958401f78 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -348,13 +348,17 @@ bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err)
348 struct tipc_msg ohdr; 348 struct tipc_msg ohdr;
349 uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE); 349 uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE);
350 350
351 if (skb_linearize(buf) || !msg_isdata(msg)) 351 if (skb_linearize(buf))
352 goto exit;
353 if (msg_dest_droppable(msg))
352 goto exit; 354 goto exit;
353 if (msg_dest_droppable(msg) || msg_errcode(msg)) 355 if (msg_errcode(msg))
354 goto exit; 356 goto exit;
355 357
356 memcpy(&ohdr, msg, msg_hdr_sz(msg)); 358 memcpy(&ohdr, msg, msg_hdr_sz(msg));
357 msg_set_importance(msg, min_t(uint, ++imp, TIPC_CRITICAL_IMPORTANCE)); 359 imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE);
360 if (msg_isdata(msg))
361 msg_set_importance(msg, imp);
358 msg_set_errcode(msg, err); 362 msg_set_errcode(msg, err);
359 msg_set_origport(msg, msg_destport(&ohdr)); 363 msg_set_origport(msg, msg_destport(&ohdr));
360 msg_set_destport(msg, msg_origport(&ohdr)); 364 msg_set_destport(msg, msg_origport(&ohdr));
diff --git a/net/tipc/port.c b/net/tipc/port.c
index dcc630948e04..9f53d5ac35e1 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -42,8 +42,6 @@
42 42
43/* Connection management: */ 43/* Connection management: */
44#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */ 44#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */
45#define CONFIRMED 0
46#define PROBING 1
47 45
48#define MAX_REJECT_SIZE 1024 46#define MAX_REJECT_SIZE 1024
49 47
@@ -299,11 +297,11 @@ static void port_timeout(unsigned long ref)
299 } 297 }
300 298
301 /* Last probe answered ? */ 299 /* Last probe answered ? */
302 if (p_ptr->probing_state == PROBING) { 300 if (p_ptr->probing_state == TIPC_CONN_PROBING) {
303 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 301 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
304 } else { 302 } else {
305 buf = port_build_proto_msg(p_ptr, CONN_PROBE, 0); 303 buf = port_build_proto_msg(p_ptr, CONN_PROBE, 0);
306 p_ptr->probing_state = PROBING; 304 p_ptr->probing_state = TIPC_CONN_PROBING;
307 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 305 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
308 } 306 }
309 tipc_port_unlock(p_ptr); 307 tipc_port_unlock(p_ptr);
@@ -365,51 +363,6 @@ static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 er
365 return buf; 363 return buf;
366} 364}
367 365
368void tipc_port_proto_rcv(struct tipc_port *p_ptr, struct sk_buff *buf)
369{
370 struct tipc_msg *msg = buf_msg(buf);
371 struct sk_buff *r_buf = NULL;
372 u32 destport = msg_destport(msg);
373 int wakeable;
374
375 /* Validate connection */
376 if (!p_ptr || !p_ptr->connected || !tipc_port_peer_msg(p_ptr, msg)) {
377 r_buf = tipc_buf_acquire(BASIC_H_SIZE);
378 if (r_buf) {
379 msg = buf_msg(r_buf);
380 tipc_msg_init(msg, TIPC_HIGH_IMPORTANCE, TIPC_CONN_MSG,
381 BASIC_H_SIZE, msg_orignode(msg));
382 msg_set_errcode(msg, TIPC_ERR_NO_PORT);
383 msg_set_origport(msg, destport);
384 msg_set_destport(msg, msg_origport(msg));
385 }
386 goto exit;
387 }
388
389 /* Process protocol message sent by peer */
390 switch (msg_type(msg)) {
391 case CONN_ACK:
392 wakeable = tipc_port_congested(p_ptr) && p_ptr->congested;
393 p_ptr->acked += msg_msgcnt(msg);
394 if (!tipc_port_congested(p_ptr)) {
395 p_ptr->congested = 0;
396 if (wakeable)
397 tipc_port_wakeup(p_ptr);
398 }
399 break;
400 case CONN_PROBE:
401 r_buf = port_build_proto_msg(p_ptr, CONN_PROBE_REPLY, 0);
402 break;
403 default:
404 /* CONN_PROBE_REPLY or unrecognized - no action required */
405 break;
406 }
407 p_ptr->probing_state = CONFIRMED;
408exit:
409 tipc_link_xmit2(r_buf, msg_destnode(msg), msg_link_selector(msg));
410 kfree_skb(buf);
411}
412
413static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id) 366static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id)
414{ 367{
415 struct publication *publ; 368 struct publication *publ;
@@ -613,7 +566,7 @@ int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
613 msg_set_hdr_sz(msg, SHORT_H_SIZE); 566 msg_set_hdr_sz(msg, SHORT_H_SIZE);
614 567
615 p_ptr->probing_interval = PROBING_INTERVAL; 568 p_ptr->probing_interval = PROBING_INTERVAL;
616 p_ptr->probing_state = CONFIRMED; 569 p_ptr->probing_state = TIPC_CONN_OK;
617 p_ptr->connected = 1; 570 p_ptr->connected = 1;
618 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 571 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
619 572
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 3f28fd420ff9..3a4f808135c3 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -140,7 +140,6 @@ int tipc_port_mcast_xmit(struct tipc_port *port,
140 unsigned int len); 140 unsigned int len);
141 141
142struct sk_buff *tipc_port_get_ports(void); 142struct sk_buff *tipc_port_get_ports(void);
143void tipc_port_proto_rcv(struct tipc_port *port, struct sk_buff *buf);
144void tipc_port_mcast_rcv(struct sk_buff *buf, struct tipc_port_list *dp); 143void tipc_port_mcast_rcv(struct sk_buff *buf, struct tipc_port_list *dp);
145void tipc_port_reinit(void); 144void tipc_port_reinit(void);
146 145
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index d838a4b66d3a..1762323156af 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -46,6 +46,7 @@
46#define SS_READY -2 /* socket is connectionless */ 46#define SS_READY -2 /* socket is connectionless */
47 47
48#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ 48#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
49#define TIPC_FWD_MSG 1
49 50
50static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); 51static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
51static void tipc_data_ready(struct sock *sk); 52static void tipc_data_ready(struct sock *sk);
@@ -534,6 +535,46 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
534} 535}
535 536
536/** 537/**
538 * tipc_sk_proto_rcv - receive a connection mng protocol message
539 * @tsk: receiving socket
540 * @dnode: node to send response message to, if any
541 * @buf: buffer containing protocol message
542 * Returns 0 (TIPC_OK) if message was consumed, 1 (TIPC_FWD_MSG) if
543 * (CONN_PROBE_REPLY) message should be forwarded.
544 */
545int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode, struct sk_buff *buf)
546{
547 struct tipc_msg *msg = buf_msg(buf);
548 struct tipc_port *port = &tsk->port;
549 int wakeable;
550
551 /* Ignore if connection cannot be validated: */
552 if (!port->connected || !tipc_port_peer_msg(port, msg))
553 goto exit;
554
555 port->probing_state = TIPC_CONN_OK;
556
557 if (msg_type(msg) == CONN_ACK) {
558 wakeable = tipc_port_congested(port) && port->congested;
559 port->acked += msg_msgcnt(msg);
560 if (!tipc_port_congested(port)) {
561 port->congested = 0;
562 if (wakeable)
563 tipc_port_wakeup(port);
564 }
565 } else if (msg_type(msg) == CONN_PROBE) {
566 if (!tipc_msg_reverse(buf, dnode, TIPC_OK))
567 return TIPC_OK;
568 msg_set_type(msg, CONN_PROBE_REPLY);
569 return TIPC_FWD_MSG;
570 }
571 /* Do nothing if msg_type() == CONN_PROBE_REPLY */
572exit:
573 kfree_skb(buf);
574 return TIPC_OK;
575}
576
577/**
537 * dest_name_check - verify user is permitted to send to specified port name 578 * dest_name_check - verify user is permitted to send to specified port name
538 * @dest: destination address 579 * @dest: destination address
539 * @m: descriptor for message to be sent 580 * @m: descriptor for message to be sent
@@ -1406,7 +1447,7 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf)
1406 * Called with socket lock already taken; port lock may also be taken. 1447 * Called with socket lock already taken; port lock may also be taken.
1407 * 1448 *
1408 * Returns 0 (TIPC_OK) if message was consumed, -TIPC error code if message 1449 * Returns 0 (TIPC_OK) if message was consumed, -TIPC error code if message
1409 * to be rejected. 1450 * to be rejected, 1 (TIPC_FWD_MSG) if (CONN_MANAGER) message to be forwarded
1410 */ 1451 */
1411static int filter_rcv(struct sock *sk, struct sk_buff *buf) 1452static int filter_rcv(struct sock *sk, struct sk_buff *buf)
1412{ 1453{
@@ -1414,12 +1455,11 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf)
1414 struct tipc_sock *tsk = tipc_sk(sk); 1455 struct tipc_sock *tsk = tipc_sk(sk);
1415 struct tipc_msg *msg = buf_msg(buf); 1456 struct tipc_msg *msg = buf_msg(buf);
1416 unsigned int limit = rcvbuf_limit(sk, buf); 1457 unsigned int limit = rcvbuf_limit(sk, buf);
1458 u32 onode;
1417 int rc = TIPC_OK; 1459 int rc = TIPC_OK;
1418 1460
1419 if (unlikely(msg_user(msg) == CONN_MANAGER)) { 1461 if (unlikely(msg_user(msg) == CONN_MANAGER))
1420 tipc_port_proto_rcv(&tsk->port, buf); 1462 return tipc_sk_proto_rcv(tsk, &onode, buf);
1421 return TIPC_OK;
1422 }
1423 1463
1424 /* Reject message if it is wrong sort of message for socket */ 1464 /* Reject message if it is wrong sort of message for socket */
1425 if (msg_type(msg) > TIPC_DIRECT_MSG) 1465 if (msg_type(msg) > TIPC_DIRECT_MSG)
@@ -1465,10 +1505,16 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf)
1465 1505
1466 rc = filter_rcv(sk, buf); 1506 rc = filter_rcv(sk, buf);
1467 1507
1468 if (unlikely(rc && tipc_msg_reverse(buf, &onode, -rc))) 1508 if (likely(!rc)) {
1469 tipc_link_xmit2(buf, onode, 0); 1509 if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT)
1470 else if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) 1510 atomic_add(truesize, &tsk->dupl_rcvcnt);
1471 atomic_add(truesize, &tsk->dupl_rcvcnt); 1511 return 0;
1512 }
1513
1514 if ((rc < 0) && !tipc_msg_reverse(buf, &onode, -rc))
1515 return 0;
1516
1517 tipc_link_xmit2(buf, onode, 0);
1472 1518
1473 return 0; 1519 return 0;
1474} 1520}
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 3afcd2a70b31..69fd06bce68a 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -38,6 +38,9 @@
38#include "port.h" 38#include "port.h"
39#include <net/sock.h> 39#include <net/sock.h>
40 40
41#define TIPC_CONN_OK 0
42#define TIPC_CONN_PROBING 1
43
41/** 44/**
42 * struct tipc_sock - TIPC socket structure 45 * struct tipc_sock - TIPC socket structure
43 * @sk: socket - interacts with 'port' and with user via the socket API 46 * @sk: socket - interacts with 'port' and with user via the socket API