diff options
-rw-r--r-- | net/tipc/Makefile | 2 | ||||
-rw-r--r-- | net/tipc/port.c | 123 | ||||
-rw-r--r-- | net/tipc/socket.c | 102 |
3 files changed, 97 insertions, 130 deletions
diff --git a/net/tipc/Makefile b/net/tipc/Makefile index a080c66d819a..5206a4440222 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile | |||
@@ -7,7 +7,7 @@ obj-$(CONFIG_TIPC) := tipc.o | |||
7 | tipc-y += addr.o bcast.o bearer.o config.o \ | 7 | tipc-y += addr.o bcast.o bearer.o config.o \ |
8 | core.o link.o discover.o msg.o \ | 8 | core.o link.o discover.o msg.o \ |
9 | name_distr.o subscr.o name_table.o net.o \ | 9 | name_distr.o subscr.o name_table.o net.o \ |
10 | netlink.o node.o node_subscr.o port.o ref.o \ | 10 | netlink.o node.o node_subscr.o ref.o \ |
11 | socket.o log.o eth_media.o server.o | 11 | socket.o log.o eth_media.o server.o |
12 | 12 | ||
13 | tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o | 13 | tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o |
diff --git a/net/tipc/port.c b/net/tipc/port.c deleted file mode 100644 index cea3730fe026..000000000000 --- a/net/tipc/port.c +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | /* | ||
2 | * net/tipc/port.c: TIPC port code | ||
3 | * | ||
4 | * Copyright (c) 1992-2007, 2014, Ericsson AB | ||
5 | * Copyright (c) 2004-2008, 2010-2013, Wind River Systems | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * 3. Neither the names of the copyright holders nor the names of its | ||
17 | * contributors may be used to endorse or promote products derived from | ||
18 | * this software without specific prior written permission. | ||
19 | * | ||
20 | * Alternatively, this software may be distributed under the terms of the | ||
21 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
22 | * Software Foundation. | ||
23 | * | ||
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
34 | * POSSIBILITY OF SUCH DAMAGE. | ||
35 | */ | ||
36 | |||
37 | #include "core.h" | ||
38 | #include "config.h" | ||
39 | #include "port.h" | ||
40 | #include "name_table.h" | ||
41 | #include "socket.h" | ||
42 | |||
43 | #define MAX_REJECT_SIZE 1024 | ||
44 | |||
45 | /** | ||
46 | * tipc_port_peer_msg - verify message was sent by connected port's peer | ||
47 | * | ||
48 | * Handles cases where the node's network address has changed from | ||
49 | * the default of <0.0.0> to its configured setting. | ||
50 | */ | ||
51 | int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg) | ||
52 | { | ||
53 | u32 peernode; | ||
54 | u32 orignode; | ||
55 | |||
56 | if (msg_origport(msg) != tipc_port_peerport(p_ptr)) | ||
57 | return 0; | ||
58 | |||
59 | orignode = msg_orignode(msg); | ||
60 | peernode = tipc_port_peernode(p_ptr); | ||
61 | return (orignode == peernode) || | ||
62 | (!orignode && (peernode == tipc_own_addr)) || | ||
63 | (!peernode && (orignode == tipc_own_addr)); | ||
64 | } | ||
65 | |||
66 | int tipc_publish(struct tipc_port *p_ptr, unsigned int scope, | ||
67 | struct tipc_name_seq const *seq) | ||
68 | { | ||
69 | struct publication *publ; | ||
70 | u32 key; | ||
71 | |||
72 | if (p_ptr->connected) | ||
73 | return -EINVAL; | ||
74 | key = p_ptr->ref + p_ptr->pub_count + 1; | ||
75 | if (key == p_ptr->ref) | ||
76 | return -EADDRINUSE; | ||
77 | |||
78 | publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, | ||
79 | scope, p_ptr->ref, key); | ||
80 | if (publ) { | ||
81 | list_add(&publ->pport_list, &p_ptr->publications); | ||
82 | p_ptr->pub_count++; | ||
83 | p_ptr->published = 1; | ||
84 | return 0; | ||
85 | } | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope, | ||
90 | struct tipc_name_seq const *seq) | ||
91 | { | ||
92 | struct publication *publ; | ||
93 | struct publication *tpubl; | ||
94 | int res = -EINVAL; | ||
95 | |||
96 | if (!seq) { | ||
97 | list_for_each_entry_safe(publ, tpubl, | ||
98 | &p_ptr->publications, pport_list) { | ||
99 | tipc_nametbl_withdraw(publ->type, publ->lower, | ||
100 | publ->ref, publ->key); | ||
101 | } | ||
102 | res = 0; | ||
103 | } else { | ||
104 | list_for_each_entry_safe(publ, tpubl, | ||
105 | &p_ptr->publications, pport_list) { | ||
106 | if (publ->scope != scope) | ||
107 | continue; | ||
108 | if (publ->type != seq->type) | ||
109 | continue; | ||
110 | if (publ->lower != seq->lower) | ||
111 | continue; | ||
112 | if (publ->upper != seq->upper) | ||
113 | break; | ||
114 | tipc_nametbl_withdraw(publ->type, publ->lower, | ||
115 | publ->ref, publ->key); | ||
116 | res = 0; | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | if (list_empty(&p_ptr->publications)) | ||
121 | p_ptr->published = 0; | ||
122 | return res; | ||
123 | } | ||
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); | |||
57 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); | 57 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); |
58 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); | 58 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); |
59 | static void tipc_sk_timeout(unsigned long ref); | 59 | static void tipc_sk_timeout(unsigned long ref); |
60 | static int tipc_sk_publish(struct tipc_port *port, uint scope, | ||
61 | struct tipc_name_seq const *seq); | ||
62 | static int tipc_sk_withdraw(struct tipc_port *port, uint scope, | ||
63 | struct tipc_name_seq const *seq); | ||
60 | 64 | ||
61 | static const struct proto_ops packet_ops; | 65 | static const struct proto_ops packet_ops; |
62 | static const struct proto_ops stream_ops; | 66 | static 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 | */ | ||
150 | static 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); |
440 | exit: | 476 | exit: |
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 | ||
2066 | static 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 | |||
2089 | static 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 | |||
2030 | static int tipc_sk_show(struct tipc_port *port, char *buf, | 2120 | static int tipc_sk_show(struct tipc_port *port, char *buf, |
2031 | int len, int full_id) | 2121 | int len, int full_id) |
2032 | { | 2122 | { |