aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c102
1 files changed, 96 insertions, 6 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 7e6240e41e69..ea33eab4fb9d 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -57,6 +57,10 @@ static int tipc_release(struct socket *sock);
57static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); 57static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
58static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); 58static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
59static void tipc_sk_timeout(unsigned long ref); 59static void tipc_sk_timeout(unsigned long ref);
60static int tipc_sk_publish(struct tipc_port *port, uint scope,
61 struct tipc_name_seq const *seq);
62static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
63 struct tipc_name_seq const *seq);
60 64
61static const struct proto_ops packet_ops; 65static const struct proto_ops packet_ops;
62static const struct proto_ops stream_ops; 66static const struct proto_ops stream_ops;
@@ -138,6 +142,38 @@ static void reject_rx_queue(struct sock *sk)
138 } 142 }
139} 143}
140 144
145/* tipc_sk_peer_msg - verify if message was sent by connected port's peer
146 *
147 * Handles cases where the node's network address has changed from
148 * the default of <0.0.0> to its configured setting.
149 */
150static bool tipc_sk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
151{
152 u32 peer_port = tipc_port_peerport(&tsk->port);
153 u32 orig_node;
154 u32 peer_node;
155
156 if (unlikely(!tsk->port.connected))
157 return false;
158
159 if (unlikely(msg_origport(msg) != peer_port))
160 return false;
161
162 orig_node = msg_orignode(msg);
163 peer_node = tipc_port_peernode(&tsk->port);
164
165 if (likely(orig_node == peer_node))
166 return true;
167
168 if (!orig_node && (peer_node == tipc_own_addr))
169 return true;
170
171 if (!peer_node && (orig_node == tipc_own_addr))
172 return true;
173
174 return false;
175}
176
141/** 177/**
142 * tipc_sk_create - create a TIPC socket 178 * tipc_sk_create - create a TIPC socket
143 * @net: network namespace (must be default network) 179 * @net: network namespace (must be default network)
@@ -356,7 +392,7 @@ static int tipc_release(struct socket *sock)
356 } 392 }
357 } 393 }
358 394
359 tipc_withdraw(port, 0, NULL); 395 tipc_sk_withdraw(port, 0, NULL);
360 tipc_ref_discard(port->ref); 396 tipc_ref_discard(port->ref);
361 k_cancel_timer(&port->timer); 397 k_cancel_timer(&port->timer);
362 if (port->connected) { 398 if (port->connected) {
@@ -407,7 +443,7 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
407 443
408 lock_sock(sk); 444 lock_sock(sk);
409 if (unlikely(!uaddr_len)) { 445 if (unlikely(!uaddr_len)) {
410 res = tipc_withdraw(&tsk->port, 0, NULL); 446 res = tipc_sk_withdraw(&tsk->port, 0, NULL);
411 goto exit; 447 goto exit;
412 } 448 }
413 449
@@ -435,8 +471,8 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
435 } 471 }
436 472
437 res = (addr->scope > 0) ? 473 res = (addr->scope > 0) ?
438 tipc_publish(&tsk->port, addr->scope, &addr->addr.nameseq) : 474 tipc_sk_publish(&tsk->port, addr->scope, &addr->addr.nameseq) :
439 tipc_withdraw(&tsk->port, -addr->scope, &addr->addr.nameseq); 475 tipc_sk_withdraw(&tsk->port, -addr->scope, &addr->addr.nameseq);
440exit: 476exit:
441 release_sock(sk); 477 release_sock(sk);
442 return res; 478 return res;
@@ -663,7 +699,7 @@ static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
663 int conn_cong; 699 int conn_cong;
664 700
665 /* Ignore if connection cannot be validated: */ 701 /* Ignore if connection cannot be validated: */
666 if (!port->connected || !tipc_port_peer_msg(port, msg)) 702 if (!tipc_sk_peer_msg(tsk, msg))
667 goto exit; 703 goto exit;
668 704
669 port->probing_state = TIPC_CONN_OK; 705 port->probing_state = TIPC_CONN_OK;
@@ -1444,7 +1480,7 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
1444 switch ((int)sock->state) { 1480 switch ((int)sock->state) {
1445 case SS_CONNECTED: 1481 case SS_CONNECTED:
1446 /* Accept only connection-based messages sent by peer */ 1482 /* Accept only connection-based messages sent by peer */
1447 if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) { 1483 if (tipc_sk_peer_msg(tsk, msg)) {
1448 if (unlikely(msg_errcode(msg))) { 1484 if (unlikely(msg_errcode(msg))) {
1449 sock->state = SS_DISCONNECTING; 1485 sock->state = SS_DISCONNECTING;
1450 port->connected = 0; 1486 port->connected = 0;
@@ -2027,6 +2063,60 @@ exit:
2027 tipc_sk_put(tsk); 2063 tipc_sk_put(tsk);
2028} 2064}
2029 2065
2066static int tipc_sk_publish(struct tipc_port *port, uint scope,
2067 struct tipc_name_seq const *seq)
2068{
2069 struct publication *publ;
2070 u32 key;
2071
2072 if (port->connected)
2073 return -EINVAL;
2074 key = port->ref + port->pub_count + 1;
2075 if (key == port->ref)
2076 return -EADDRINUSE;
2077
2078 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
2079 scope, port->ref, key);
2080 if (unlikely(!publ))
2081 return -EINVAL;
2082
2083 list_add(&publ->pport_list, &port->publications);
2084 port->pub_count++;
2085 port->published = 1;
2086 return 0;
2087}
2088
2089static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
2090 struct tipc_name_seq const *seq)
2091{
2092 struct publication *publ;
2093 struct publication *safe;
2094 int rc = -EINVAL;
2095
2096 list_for_each_entry_safe(publ, safe, &port->publications, pport_list) {
2097 if (seq) {
2098 if (publ->scope != scope)
2099 continue;
2100 if (publ->type != seq->type)
2101 continue;
2102 if (publ->lower != seq->lower)
2103 continue;
2104 if (publ->upper != seq->upper)
2105 break;
2106 tipc_nametbl_withdraw(publ->type, publ->lower,
2107 publ->ref, publ->key);
2108 rc = 0;
2109 break;
2110 }
2111 tipc_nametbl_withdraw(publ->type, publ->lower,
2112 publ->ref, publ->key);
2113 rc = 0;
2114 }
2115 if (list_empty(&port->publications))
2116 port->published = 0;
2117 return rc;
2118}
2119
2030static int tipc_sk_show(struct tipc_port *port, char *buf, 2120static int tipc_sk_show(struct tipc_port *port, char *buf,
2031 int len, int full_id) 2121 int len, int full_id)
2032{ 2122{