aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c16
-rw-r--r--net/tipc/bearer.c18
-rw-r--r--net/tipc/bearer.h10
-rw-r--r--net/tipc/core.c7
-rw-r--r--net/tipc/core.h28
-rw-r--r--net/tipc/eth_media.c68
-rw-r--r--net/tipc/handler.c11
-rw-r--r--net/tipc/ib_media.c58
-rw-r--r--net/tipc/link.c494
-rw-r--r--net/tipc/link.h24
-rw-r--r--net/tipc/msg.c27
-rw-r--r--net/tipc/msg.h15
-rw-r--r--net/tipc/netlink.c11
-rw-r--r--net/tipc/node.c7
-rw-r--r--net/tipc/node.h6
-rw-r--r--net/tipc/port.c111
-rw-r--r--net/tipc/port.h22
-rw-r--r--net/tipc/socket.c64
18 files changed, 408 insertions, 589 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 716de1ac6cb5..0d4402587fdf 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -480,18 +480,24 @@ receive:
480 tipc_node_unlock(node); 480 tipc_node_unlock(node);
481 tipc_link_recv_bundle(buf); 481 tipc_link_recv_bundle(buf);
482 } else if (msg_user(msg) == MSG_FRAGMENTER) { 482 } else if (msg_user(msg) == MSG_FRAGMENTER) {
483 int ret = tipc_link_recv_fragment(&node->bclink.defragm, 483 int ret;
484 &buf, &msg); 484 ret = tipc_link_recv_fragment(&node->bclink.reasm_head,
485 if (ret < 0) 485 &node->bclink.reasm_tail,
486 &buf);
487 if (ret == LINK_REASM_ERROR)
486 goto unlock; 488 goto unlock;
487 spin_lock_bh(&bc_lock); 489 spin_lock_bh(&bc_lock);
488 bclink_accept_pkt(node, seqno); 490 bclink_accept_pkt(node, seqno);
489 bcl->stats.recv_fragments++; 491 bcl->stats.recv_fragments++;
490 if (ret > 0) 492 if (ret == LINK_REASM_COMPLETE) {
491 bcl->stats.recv_fragmented++; 493 bcl->stats.recv_fragmented++;
494 /* Point msg to inner header */
495 msg = buf_msg(buf);
496 spin_unlock_bh(&bc_lock);
497 goto receive;
498 }
492 spin_unlock_bh(&bc_lock); 499 spin_unlock_bh(&bc_lock);
493 tipc_node_unlock(node); 500 tipc_node_unlock(node);
494 tipc_net_route_msg(buf);
495 } else if (msg_user(msg) == NAME_DISTRIBUTOR) { 501 } else if (msg_user(msg) == NAME_DISTRIBUTOR) {
496 spin_lock_bh(&bc_lock); 502 spin_lock_bh(&bc_lock);
497 bclink_accept_pkt(node, seqno); 503 bclink_accept_pkt(node, seqno);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 609c30c80816..3f9707a16d06 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -387,7 +387,7 @@ restart:
387 387
388 b_ptr = &tipc_bearers[bearer_id]; 388 b_ptr = &tipc_bearers[bearer_id];
389 strcpy(b_ptr->name, name); 389 strcpy(b_ptr->name, name);
390 res = m_ptr->enable_bearer(b_ptr); 390 res = m_ptr->enable_media(b_ptr);
391 if (res) { 391 if (res) {
392 pr_warn("Bearer <%s> rejected, enable failure (%d)\n", 392 pr_warn("Bearer <%s> rejected, enable failure (%d)\n",
393 name, -res); 393 name, -res);
@@ -420,23 +420,15 @@ exit:
420} 420}
421 421
422/** 422/**
423 * tipc_block_bearer - Block the bearer with the given name, and reset all its links 423 * tipc_block_bearer - Block the bearer, and reset all its links
424 */ 424 */
425int tipc_block_bearer(const char *name) 425int tipc_block_bearer(struct tipc_bearer *b_ptr)
426{ 426{
427 struct tipc_bearer *b_ptr = NULL;
428 struct tipc_link *l_ptr; 427 struct tipc_link *l_ptr;
429 struct tipc_link *temp_l_ptr; 428 struct tipc_link *temp_l_ptr;
430 429
431 read_lock_bh(&tipc_net_lock); 430 read_lock_bh(&tipc_net_lock);
432 b_ptr = tipc_bearer_find(name); 431 pr_info("Blocking bearer <%s>\n", b_ptr->name);
433 if (!b_ptr) {
434 pr_warn("Attempt to block unknown bearer <%s>\n", name);
435 read_unlock_bh(&tipc_net_lock);
436 return -EINVAL;
437 }
438
439 pr_info("Blocking bearer <%s>\n", name);
440 spin_lock_bh(&b_ptr->lock); 432 spin_lock_bh(&b_ptr->lock);
441 b_ptr->blocked = 1; 433 b_ptr->blocked = 1;
442 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 434 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
@@ -465,7 +457,7 @@ static void bearer_disable(struct tipc_bearer *b_ptr)
465 pr_info("Disabling bearer <%s>\n", b_ptr->name); 457 pr_info("Disabling bearer <%s>\n", b_ptr->name);
466 spin_lock_bh(&b_ptr->lock); 458 spin_lock_bh(&b_ptr->lock);
467 b_ptr->blocked = 1; 459 b_ptr->blocked = 1;
468 b_ptr->media->disable_bearer(b_ptr); 460 b_ptr->media->disable_media(b_ptr);
469 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 461 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
470 tipc_link_delete(l_ptr); 462 tipc_link_delete(l_ptr);
471 } 463 }
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 09c869adcfcf..e5e04be6fffa 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -75,8 +75,8 @@ struct tipc_bearer;
75/** 75/**
76 * struct tipc_media - TIPC media information available to internal users 76 * struct tipc_media - TIPC media information available to internal users
77 * @send_msg: routine which handles buffer transmission 77 * @send_msg: routine which handles buffer transmission
78 * @enable_bearer: routine which enables a bearer 78 * @enable_media: routine which enables a media
79 * @disable_bearer: routine which disables a bearer 79 * @disable_media: routine which disables a media
80 * @addr2str: routine which converts media address to string 80 * @addr2str: routine which converts media address to string
81 * @addr2msg: routine which converts media address to protocol message area 81 * @addr2msg: routine which converts media address to protocol message area
82 * @msg2addr: routine which converts media address from protocol message area 82 * @msg2addr: routine which converts media address from protocol message area
@@ -91,8 +91,8 @@ struct tipc_media {
91 int (*send_msg)(struct sk_buff *buf, 91 int (*send_msg)(struct sk_buff *buf,
92 struct tipc_bearer *b_ptr, 92 struct tipc_bearer *b_ptr,
93 struct tipc_media_addr *dest); 93 struct tipc_media_addr *dest);
94 int (*enable_bearer)(struct tipc_bearer *b_ptr); 94 int (*enable_media)(struct tipc_bearer *b_ptr);
95 void (*disable_bearer)(struct tipc_bearer *b_ptr); 95 void (*disable_media)(struct tipc_bearer *b_ptr);
96 int (*addr2str)(struct tipc_media_addr *a, char *str_buf, int str_size); 96 int (*addr2str)(struct tipc_media_addr *a, char *str_buf, int str_size);
97 int (*addr2msg)(struct tipc_media_addr *a, char *msg_area); 97 int (*addr2msg)(struct tipc_media_addr *a, char *msg_area);
98 int (*msg2addr)(const struct tipc_bearer *b_ptr, 98 int (*msg2addr)(const struct tipc_bearer *b_ptr,
@@ -163,7 +163,7 @@ int tipc_register_media(struct tipc_media *m_ptr);
163 163
164void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr); 164void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
165 165
166int tipc_block_bearer(const char *name); 166int tipc_block_bearer(struct tipc_bearer *b_ptr);
167void tipc_continue(struct tipc_bearer *tb_ptr); 167void tipc_continue(struct tipc_bearer *tb_ptr);
168 168
169int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority); 169int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
diff --git a/net/tipc/core.c b/net/tipc/core.c
index fd4eeeaa972a..c6d3f75a9e1b 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -113,7 +113,6 @@ err:
113static void tipc_core_stop(void) 113static void tipc_core_stop(void)
114{ 114{
115 tipc_netlink_stop(); 115 tipc_netlink_stop();
116 tipc_handler_stop();
117 tipc_cfg_stop(); 116 tipc_cfg_stop();
118 tipc_subscr_stop(); 117 tipc_subscr_stop();
119 tipc_nametbl_stop(); 118 tipc_nametbl_stop();
@@ -146,9 +145,10 @@ static int tipc_core_start(void)
146 res = tipc_subscr_start(); 145 res = tipc_subscr_start();
147 if (!res) 146 if (!res)
148 res = tipc_cfg_init(); 147 res = tipc_cfg_init();
149 if (res) 148 if (res) {
149 tipc_handler_stop();
150 tipc_core_stop(); 150 tipc_core_stop();
151 151 }
152 return res; 152 return res;
153} 153}
154 154
@@ -178,6 +178,7 @@ static int __init tipc_init(void)
178 178
179static void __exit tipc_exit(void) 179static void __exit tipc_exit(void)
180{ 180{
181 tipc_handler_stop();
181 tipc_core_stop_net(); 182 tipc_core_stop_net();
182 tipc_core_stop(); 183 tipc_core_stop();
183 pr_info("Deactivated\n"); 184 pr_info("Deactivated\n");
diff --git a/net/tipc/core.h b/net/tipc/core.h
index be72f8cebc53..94895d4e86ab 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -90,21 +90,21 @@ extern int tipc_random __read_mostly;
90/* 90/*
91 * Routines available to privileged subsystems 91 * Routines available to privileged subsystems
92 */ 92 */
93extern int tipc_core_start_net(unsigned long); 93int tipc_core_start_net(unsigned long);
94extern int tipc_handler_start(void); 94int tipc_handler_start(void);
95extern void tipc_handler_stop(void); 95void tipc_handler_stop(void);
96extern int tipc_netlink_start(void); 96int tipc_netlink_start(void);
97extern void tipc_netlink_stop(void); 97void tipc_netlink_stop(void);
98extern int tipc_socket_init(void); 98int tipc_socket_init(void);
99extern void tipc_socket_stop(void); 99void tipc_socket_stop(void);
100extern int tipc_sock_create_local(int type, struct socket **res); 100int tipc_sock_create_local(int type, struct socket **res);
101extern void tipc_sock_release_local(struct socket *sock); 101void tipc_sock_release_local(struct socket *sock);
102extern int tipc_sock_accept_local(struct socket *sock, 102int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
103 struct socket **newsock, int flags); 103 int flags);
104 104
105#ifdef CONFIG_SYSCTL 105#ifdef CONFIG_SYSCTL
106extern int tipc_register_sysctl(void); 106int tipc_register_sysctl(void);
107extern void tipc_unregister_sysctl(void); 107void tipc_unregister_sysctl(void);
108#else 108#else
109#define tipc_register_sysctl() 0 109#define tipc_register_sysctl() 0
110#define tipc_unregister_sysctl() 110#define tipc_unregister_sysctl()
@@ -201,6 +201,6 @@ static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
201 return (struct tipc_msg *)skb->data; 201 return (struct tipc_msg *)skb->data;
202} 202}
203 203
204extern struct sk_buff *tipc_buf_acquire(u32 size); 204struct sk_buff *tipc_buf_acquire(u32 size);
205 205
206#endif 206#endif
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 40ea40cf6204..f80d59f5a161 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -2,7 +2,7 @@
2 * net/tipc/eth_media.c: Ethernet bearer support for TIPC 2 * net/tipc/eth_media.c: Ethernet bearer support for TIPC
3 * 3 *
4 * Copyright (c) 2001-2007, Ericsson AB 4 * Copyright (c) 2001-2007, Ericsson AB
5 * Copyright (c) 2005-2008, 2011, Wind River Systems 5 * Copyright (c) 2005-2008, 2011-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,19 +37,19 @@
37#include "core.h" 37#include "core.h"
38#include "bearer.h" 38#include "bearer.h"
39 39
40#define MAX_ETH_BEARERS MAX_BEARERS 40#define MAX_ETH_MEDIA MAX_BEARERS
41 41
42#define ETH_ADDR_OFFSET 4 /* message header offset of MAC address */ 42#define ETH_ADDR_OFFSET 4 /* message header offset of MAC address */
43 43
44/** 44/**
45 * struct eth_bearer - Ethernet bearer data structure 45 * struct eth_media - Ethernet bearer data structure
46 * @bearer: ptr to associated "generic" bearer structure 46 * @bearer: ptr to associated "generic" bearer structure
47 * @dev: ptr to associated Ethernet network device 47 * @dev: ptr to associated Ethernet network device
48 * @tipc_packet_type: used in binding TIPC to Ethernet driver 48 * @tipc_packet_type: used in binding TIPC to Ethernet driver
49 * @setup: work item used when enabling bearer 49 * @setup: work item used when enabling bearer
50 * @cleanup: work item used when disabling bearer 50 * @cleanup: work item used when disabling bearer
51 */ 51 */
52struct eth_bearer { 52struct eth_media {
53 struct tipc_bearer *bearer; 53 struct tipc_bearer *bearer;
54 struct net_device *dev; 54 struct net_device *dev;
55 struct packet_type tipc_packet_type; 55 struct packet_type tipc_packet_type;
@@ -58,7 +58,7 @@ struct eth_bearer {
58}; 58};
59 59
60static struct tipc_media eth_media_info; 60static struct tipc_media eth_media_info;
61static struct eth_bearer eth_bearers[MAX_ETH_BEARERS]; 61static struct eth_media eth_media_array[MAX_ETH_MEDIA];
62static int eth_started; 62static int eth_started;
63 63
64static int recv_notification(struct notifier_block *nb, unsigned long evt, 64static int recv_notification(struct notifier_block *nb, unsigned long evt,
@@ -100,7 +100,7 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
100 if (!clone) 100 if (!clone)
101 return 0; 101 return 0;
102 102
103 dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; 103 dev = ((struct eth_media *)(tb_ptr->usr_handle))->dev;
104 delta = dev->hard_header_len - skb_headroom(buf); 104 delta = dev->hard_header_len - skb_headroom(buf);
105 105
106 if ((delta > 0) && 106 if ((delta > 0) &&
@@ -128,43 +128,43 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
128static int recv_msg(struct sk_buff *buf, struct net_device *dev, 128static int recv_msg(struct sk_buff *buf, struct net_device *dev,
129 struct packet_type *pt, struct net_device *orig_dev) 129 struct packet_type *pt, struct net_device *orig_dev)
130{ 130{
131 struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; 131 struct eth_media *eb_ptr = (struct eth_media *)pt->af_packet_priv;
132 132
133 if (!net_eq(dev_net(dev), &init_net)) { 133 if (!net_eq(dev_net(dev), &init_net)) {
134 kfree_skb(buf); 134 kfree_skb(buf);
135 return 0; 135 return NET_RX_DROP;
136 } 136 }
137 137
138 if (likely(eb_ptr->bearer)) { 138 if (likely(eb_ptr->bearer)) {
139 if (likely(buf->pkt_type <= PACKET_BROADCAST)) { 139 if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
140 buf->next = NULL; 140 buf->next = NULL;
141 tipc_recv_msg(buf, eb_ptr->bearer); 141 tipc_recv_msg(buf, eb_ptr->bearer);
142 return 0; 142 return NET_RX_SUCCESS;
143 } 143 }
144 } 144 }
145 kfree_skb(buf); 145 kfree_skb(buf);
146 return 0; 146 return NET_RX_DROP;
147} 147}
148 148
149/** 149/**
150 * setup_bearer - setup association between Ethernet bearer and interface 150 * setup_media - setup association between Ethernet bearer and interface
151 */ 151 */
152static void setup_bearer(struct work_struct *work) 152static void setup_media(struct work_struct *work)
153{ 153{
154 struct eth_bearer *eb_ptr = 154 struct eth_media *eb_ptr =
155 container_of(work, struct eth_bearer, setup); 155 container_of(work, struct eth_media, setup);
156 156
157 dev_add_pack(&eb_ptr->tipc_packet_type); 157 dev_add_pack(&eb_ptr->tipc_packet_type);
158} 158}
159 159
160/** 160/**
161 * enable_bearer - attach TIPC bearer to an Ethernet interface 161 * enable_media - attach TIPC bearer to an Ethernet interface
162 */ 162 */
163static int enable_bearer(struct tipc_bearer *tb_ptr) 163static int enable_media(struct tipc_bearer *tb_ptr)
164{ 164{
165 struct net_device *dev; 165 struct net_device *dev;
166 struct eth_bearer *eb_ptr = &eth_bearers[0]; 166 struct eth_media *eb_ptr = &eth_media_array[0];
167 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS]; 167 struct eth_media *stop = &eth_media_array[MAX_ETH_MEDIA];
168 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; 168 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
169 int pending_dev = 0; 169 int pending_dev = 0;
170 170
@@ -188,7 +188,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
188 eb_ptr->tipc_packet_type.func = recv_msg; 188 eb_ptr->tipc_packet_type.func = recv_msg;
189 eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr; 189 eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;
190 INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list)); 190 INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));
191 INIT_WORK(&eb_ptr->setup, setup_bearer); 191 INIT_WORK(&eb_ptr->setup, setup_media);
192 schedule_work(&eb_ptr->setup); 192 schedule_work(&eb_ptr->setup);
193 193
194 /* Associate TIPC bearer with Ethernet bearer */ 194 /* Associate TIPC bearer with Ethernet bearer */
@@ -205,14 +205,14 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
205} 205}
206 206
207/** 207/**
208 * cleanup_bearer - break association between Ethernet bearer and interface 208 * cleanup_media - break association between Ethernet bearer and interface
209 * 209 *
210 * This routine must be invoked from a work queue because it can sleep. 210 * This routine must be invoked from a work queue because it can sleep.
211 */ 211 */
212static void cleanup_bearer(struct work_struct *work) 212static void cleanup_media(struct work_struct *work)
213{ 213{
214 struct eth_bearer *eb_ptr = 214 struct eth_media *eb_ptr =
215 container_of(work, struct eth_bearer, cleanup); 215 container_of(work, struct eth_media, cleanup);
216 216
217 dev_remove_pack(&eb_ptr->tipc_packet_type); 217 dev_remove_pack(&eb_ptr->tipc_packet_type);
218 dev_put(eb_ptr->dev); 218 dev_put(eb_ptr->dev);
@@ -220,18 +220,18 @@ static void cleanup_bearer(struct work_struct *work)
220} 220}
221 221
222/** 222/**
223 * disable_bearer - detach TIPC bearer from an Ethernet interface 223 * disable_media - detach TIPC bearer from an Ethernet interface
224 * 224 *
225 * Mark Ethernet bearer as inactive so that incoming buffers are thrown away, 225 * Mark Ethernet bearer as inactive so that incoming buffers are thrown away,
226 * then get worker thread to complete bearer cleanup. (Can't do cleanup 226 * then get worker thread to complete bearer cleanup. (Can't do cleanup
227 * here because cleanup code needs to sleep and caller holds spinlocks.) 227 * here because cleanup code needs to sleep and caller holds spinlocks.)
228 */ 228 */
229static void disable_bearer(struct tipc_bearer *tb_ptr) 229static void disable_media(struct tipc_bearer *tb_ptr)
230{ 230{
231 struct eth_bearer *eb_ptr = (struct eth_bearer *)tb_ptr->usr_handle; 231 struct eth_media *eb_ptr = (struct eth_media *)tb_ptr->usr_handle;
232 232
233 eb_ptr->bearer = NULL; 233 eb_ptr->bearer = NULL;
234 INIT_WORK(&eb_ptr->cleanup, cleanup_bearer); 234 INIT_WORK(&eb_ptr->cleanup, cleanup_media);
235 schedule_work(&eb_ptr->cleanup); 235 schedule_work(&eb_ptr->cleanup);
236} 236}
237 237
@@ -245,8 +245,8 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
245 void *ptr) 245 void *ptr)
246{ 246{
247 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 247 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
248 struct eth_bearer *eb_ptr = &eth_bearers[0]; 248 struct eth_media *eb_ptr = &eth_media_array[0];
249 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS]; 249 struct eth_media *stop = &eth_media_array[MAX_ETH_MEDIA];
250 250
251 if (!net_eq(dev_net(dev), &init_net)) 251 if (!net_eq(dev_net(dev), &init_net))
252 return NOTIFY_DONE; 252 return NOTIFY_DONE;
@@ -265,17 +265,17 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
265 if (netif_carrier_ok(dev)) 265 if (netif_carrier_ok(dev))
266 tipc_continue(eb_ptr->bearer); 266 tipc_continue(eb_ptr->bearer);
267 else 267 else
268 tipc_block_bearer(eb_ptr->bearer->name); 268 tipc_block_bearer(eb_ptr->bearer);
269 break; 269 break;
270 case NETDEV_UP: 270 case NETDEV_UP:
271 tipc_continue(eb_ptr->bearer); 271 tipc_continue(eb_ptr->bearer);
272 break; 272 break;
273 case NETDEV_DOWN: 273 case NETDEV_DOWN:
274 tipc_block_bearer(eb_ptr->bearer->name); 274 tipc_block_bearer(eb_ptr->bearer);
275 break; 275 break;
276 case NETDEV_CHANGEMTU: 276 case NETDEV_CHANGEMTU:
277 case NETDEV_CHANGEADDR: 277 case NETDEV_CHANGEADDR:
278 tipc_block_bearer(eb_ptr->bearer->name); 278 tipc_block_bearer(eb_ptr->bearer);
279 tipc_continue(eb_ptr->bearer); 279 tipc_continue(eb_ptr->bearer);
280 break; 280 break;
281 case NETDEV_UNREGISTER: 281 case NETDEV_UNREGISTER:
@@ -327,8 +327,8 @@ static int eth_msg2addr(const struct tipc_bearer *tb_ptr,
327 */ 327 */
328static struct tipc_media eth_media_info = { 328static struct tipc_media eth_media_info = {
329 .send_msg = send_msg, 329 .send_msg = send_msg,
330 .enable_bearer = enable_bearer, 330 .enable_media = enable_media,
331 .disable_bearer = disable_bearer, 331 .disable_media = disable_media,
332 .addr2str = eth_addr2str, 332 .addr2str = eth_addr2str,
333 .addr2msg = eth_addr2msg, 333 .addr2msg = eth_addr2msg,
334 .msg2addr = eth_msg2addr, 334 .msg2addr = eth_msg2addr,
diff --git a/net/tipc/handler.c b/net/tipc/handler.c
index b36f0fcd9bdf..e4bc8a296744 100644
--- a/net/tipc/handler.c
+++ b/net/tipc/handler.c
@@ -56,12 +56,13 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument)
56{ 56{
57 struct queue_item *item; 57 struct queue_item *item;
58 58
59 spin_lock_bh(&qitem_lock);
59 if (!handler_enabled) { 60 if (!handler_enabled) {
60 pr_err("Signal request ignored by handler\n"); 61 pr_err("Signal request ignored by handler\n");
62 spin_unlock_bh(&qitem_lock);
61 return -ENOPROTOOPT; 63 return -ENOPROTOOPT;
62 } 64 }
63 65
64 spin_lock_bh(&qitem_lock);
65 item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); 66 item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC);
66 if (!item) { 67 if (!item) {
67 pr_err("Signal queue out of memory\n"); 68 pr_err("Signal queue out of memory\n");
@@ -112,10 +113,14 @@ void tipc_handler_stop(void)
112 struct list_head *l, *n; 113 struct list_head *l, *n;
113 struct queue_item *item; 114 struct queue_item *item;
114 115
115 if (!handler_enabled) 116 spin_lock_bh(&qitem_lock);
117 if (!handler_enabled) {
118 spin_unlock_bh(&qitem_lock);
116 return; 119 return;
117 120 }
118 handler_enabled = 0; 121 handler_enabled = 0;
122 spin_unlock_bh(&qitem_lock);
123
119 tasklet_kill(&tipc_tasklet); 124 tasklet_kill(&tipc_tasklet);
120 125
121 spin_lock_bh(&qitem_lock); 126 spin_lock_bh(&qitem_lock);
diff --git a/net/tipc/ib_media.c b/net/tipc/ib_media.c
index 9934a32bfa87..c13989297464 100644
--- a/net/tipc/ib_media.c
+++ b/net/tipc/ib_media.c
@@ -42,17 +42,17 @@
42#include "core.h" 42#include "core.h"
43#include "bearer.h" 43#include "bearer.h"
44 44
45#define MAX_IB_BEARERS MAX_BEARERS 45#define MAX_IB_MEDIA MAX_BEARERS
46 46
47/** 47/**
48 * struct ib_bearer - Infiniband bearer data structure 48 * struct ib_media - Infiniband media data structure
49 * @bearer: ptr to associated "generic" bearer structure 49 * @bearer: ptr to associated "generic" bearer structure
50 * @dev: ptr to associated Infiniband network device 50 * @dev: ptr to associated Infiniband network device
51 * @tipc_packet_type: used in binding TIPC to Infiniband driver 51 * @tipc_packet_type: used in binding TIPC to Infiniband driver
52 * @cleanup: work item used when disabling bearer 52 * @cleanup: work item used when disabling bearer
53 */ 53 */
54 54
55struct ib_bearer { 55struct ib_media {
56 struct tipc_bearer *bearer; 56 struct tipc_bearer *bearer;
57 struct net_device *dev; 57 struct net_device *dev;
58 struct packet_type tipc_packet_type; 58 struct packet_type tipc_packet_type;
@@ -61,7 +61,7 @@ struct ib_bearer {
61}; 61};
62 62
63static struct tipc_media ib_media_info; 63static struct tipc_media ib_media_info;
64static struct ib_bearer ib_bearers[MAX_IB_BEARERS]; 64static struct ib_media ib_media_array[MAX_IB_MEDIA];
65static int ib_started; 65static int ib_started;
66 66
67/** 67/**
@@ -93,7 +93,7 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
93 if (!clone) 93 if (!clone)
94 return 0; 94 return 0;
95 95
96 dev = ((struct ib_bearer *)(tb_ptr->usr_handle))->dev; 96 dev = ((struct ib_media *)(tb_ptr->usr_handle))->dev;
97 delta = dev->hard_header_len - skb_headroom(buf); 97 delta = dev->hard_header_len - skb_headroom(buf);
98 98
99 if ((delta > 0) && 99 if ((delta > 0) &&
@@ -121,43 +121,43 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
121static int recv_msg(struct sk_buff *buf, struct net_device *dev, 121static int recv_msg(struct sk_buff *buf, struct net_device *dev,
122 struct packet_type *pt, struct net_device *orig_dev) 122 struct packet_type *pt, struct net_device *orig_dev)
123{ 123{
124 struct ib_bearer *ib_ptr = (struct ib_bearer *)pt->af_packet_priv; 124 struct ib_media *ib_ptr = (struct ib_media *)pt->af_packet_priv;
125 125
126 if (!net_eq(dev_net(dev), &init_net)) { 126 if (!net_eq(dev_net(dev), &init_net)) {
127 kfree_skb(buf); 127 kfree_skb(buf);
128 return 0; 128 return NET_RX_DROP;
129 } 129 }
130 130
131 if (likely(ib_ptr->bearer)) { 131 if (likely(ib_ptr->bearer)) {
132 if (likely(buf->pkt_type <= PACKET_BROADCAST)) { 132 if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
133 buf->next = NULL; 133 buf->next = NULL;
134 tipc_recv_msg(buf, ib_ptr->bearer); 134 tipc_recv_msg(buf, ib_ptr->bearer);
135 return 0; 135 return NET_RX_SUCCESS;
136 } 136 }
137 } 137 }
138 kfree_skb(buf); 138 kfree_skb(buf);
139 return 0; 139 return NET_RX_DROP;
140} 140}
141 141
142/** 142/**
143 * setup_bearer - setup association between InfiniBand bearer and interface 143 * setup_bearer - setup association between InfiniBand bearer and interface
144 */ 144 */
145static void setup_bearer(struct work_struct *work) 145static void setup_media(struct work_struct *work)
146{ 146{
147 struct ib_bearer *ib_ptr = 147 struct ib_media *ib_ptr =
148 container_of(work, struct ib_bearer, setup); 148 container_of(work, struct ib_media, setup);
149 149
150 dev_add_pack(&ib_ptr->tipc_packet_type); 150 dev_add_pack(&ib_ptr->tipc_packet_type);
151} 151}
152 152
153/** 153/**
154 * enable_bearer - attach TIPC bearer to an InfiniBand interface 154 * enable_media - attach TIPC bearer to an InfiniBand interface
155 */ 155 */
156static int enable_bearer(struct tipc_bearer *tb_ptr) 156static int enable_media(struct tipc_bearer *tb_ptr)
157{ 157{
158 struct net_device *dev; 158 struct net_device *dev;
159 struct ib_bearer *ib_ptr = &ib_bearers[0]; 159 struct ib_media *ib_ptr = &ib_media_array[0];
160 struct ib_bearer *stop = &ib_bearers[MAX_IB_BEARERS]; 160 struct ib_media *stop = &ib_media_array[MAX_IB_MEDIA];
161 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; 161 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
162 int pending_dev = 0; 162 int pending_dev = 0;
163 163
@@ -181,7 +181,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
181 ib_ptr->tipc_packet_type.func = recv_msg; 181 ib_ptr->tipc_packet_type.func = recv_msg;
182 ib_ptr->tipc_packet_type.af_packet_priv = ib_ptr; 182 ib_ptr->tipc_packet_type.af_packet_priv = ib_ptr;
183 INIT_LIST_HEAD(&(ib_ptr->tipc_packet_type.list)); 183 INIT_LIST_HEAD(&(ib_ptr->tipc_packet_type.list));
184 INIT_WORK(&ib_ptr->setup, setup_bearer); 184 INIT_WORK(&ib_ptr->setup, setup_media);
185 schedule_work(&ib_ptr->setup); 185 schedule_work(&ib_ptr->setup);
186 186
187 /* Associate TIPC bearer with InfiniBand bearer */ 187 /* Associate TIPC bearer with InfiniBand bearer */
@@ -204,8 +204,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
204 */ 204 */
205static void cleanup_bearer(struct work_struct *work) 205static void cleanup_bearer(struct work_struct *work)
206{ 206{
207 struct ib_bearer *ib_ptr = 207 struct ib_media *ib_ptr =
208 container_of(work, struct ib_bearer, cleanup); 208 container_of(work, struct ib_media, cleanup);
209 209
210 dev_remove_pack(&ib_ptr->tipc_packet_type); 210 dev_remove_pack(&ib_ptr->tipc_packet_type);
211 dev_put(ib_ptr->dev); 211 dev_put(ib_ptr->dev);
@@ -213,15 +213,15 @@ static void cleanup_bearer(struct work_struct *work)
213} 213}
214 214
215/** 215/**
216 * disable_bearer - detach TIPC bearer from an InfiniBand interface 216 * disable_media - detach TIPC bearer from an InfiniBand interface
217 * 217 *
218 * Mark InfiniBand bearer as inactive so that incoming buffers are thrown away, 218 * Mark InfiniBand bearer as inactive so that incoming buffers are thrown away,
219 * then get worker thread to complete bearer cleanup. (Can't do cleanup 219 * then get worker thread to complete bearer cleanup. (Can't do cleanup
220 * here because cleanup code needs to sleep and caller holds spinlocks.) 220 * here because cleanup code needs to sleep and caller holds spinlocks.)
221 */ 221 */
222static void disable_bearer(struct tipc_bearer *tb_ptr) 222static void disable_media(struct tipc_bearer *tb_ptr)
223{ 223{
224 struct ib_bearer *ib_ptr = (struct ib_bearer *)tb_ptr->usr_handle; 224 struct ib_media *ib_ptr = (struct ib_media *)tb_ptr->usr_handle;
225 225
226 ib_ptr->bearer = NULL; 226 ib_ptr->bearer = NULL;
227 INIT_WORK(&ib_ptr->cleanup, cleanup_bearer); 227 INIT_WORK(&ib_ptr->cleanup, cleanup_bearer);
@@ -238,8 +238,8 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
238 void *ptr) 238 void *ptr)
239{ 239{
240 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 240 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
241 struct ib_bearer *ib_ptr = &ib_bearers[0]; 241 struct ib_media *ib_ptr = &ib_media_array[0];
242 struct ib_bearer *stop = &ib_bearers[MAX_IB_BEARERS]; 242 struct ib_media *stop = &ib_media_array[MAX_IB_MEDIA];
243 243
244 if (!net_eq(dev_net(dev), &init_net)) 244 if (!net_eq(dev_net(dev), &init_net))
245 return NOTIFY_DONE; 245 return NOTIFY_DONE;
@@ -258,17 +258,17 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
258 if (netif_carrier_ok(dev)) 258 if (netif_carrier_ok(dev))
259 tipc_continue(ib_ptr->bearer); 259 tipc_continue(ib_ptr->bearer);
260 else 260 else
261 tipc_block_bearer(ib_ptr->bearer->name); 261 tipc_block_bearer(ib_ptr->bearer);
262 break; 262 break;
263 case NETDEV_UP: 263 case NETDEV_UP:
264 tipc_continue(ib_ptr->bearer); 264 tipc_continue(ib_ptr->bearer);
265 break; 265 break;
266 case NETDEV_DOWN: 266 case NETDEV_DOWN:
267 tipc_block_bearer(ib_ptr->bearer->name); 267 tipc_block_bearer(ib_ptr->bearer);
268 break; 268 break;
269 case NETDEV_CHANGEMTU: 269 case NETDEV_CHANGEMTU:
270 case NETDEV_CHANGEADDR: 270 case NETDEV_CHANGEADDR:
271 tipc_block_bearer(ib_ptr->bearer->name); 271 tipc_block_bearer(ib_ptr->bearer);
272 tipc_continue(ib_ptr->bearer); 272 tipc_continue(ib_ptr->bearer);
273 break; 273 break;
274 case NETDEV_UNREGISTER: 274 case NETDEV_UNREGISTER:
@@ -323,8 +323,8 @@ static int ib_msg2addr(const struct tipc_bearer *tb_ptr,
323 */ 323 */
324static struct tipc_media ib_media_info = { 324static struct tipc_media ib_media_info = {
325 .send_msg = send_msg, 325 .send_msg = send_msg,
326 .enable_bearer = enable_bearer, 326 .enable_media = enable_media,
327 .disable_bearer = disable_bearer, 327 .disable_media = disable_media,
328 .addr2str = ib_addr2str, 328 .addr2str = ib_addr2str,
329 .addr2msg = ib_addr2msg, 329 .addr2msg = ib_addr2msg,
330 .msg2addr = ib_msg2addr, 330 .msg2addr = ib_msg2addr,
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 0cc3d9015c5d..13b987745820 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -75,20 +75,6 @@ static const char *link_unk_evt = "Unknown link event ";
75 */ 75 */
76#define START_CHANGEOVER 100000u 76#define START_CHANGEOVER 100000u
77 77
78/**
79 * struct tipc_link_name - deconstructed link name
80 * @addr_local: network address of node at this end
81 * @if_local: name of interface at this end
82 * @addr_peer: network address of node at far end
83 * @if_peer: name of interface at far end
84 */
85struct tipc_link_name {
86 u32 addr_local;
87 char if_local[TIPC_MAX_IF_NAME];
88 u32 addr_peer;
89 char if_peer[TIPC_MAX_IF_NAME];
90};
91
92static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, 78static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
93 struct sk_buff *buf); 79 struct sk_buff *buf);
94static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf); 80static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf);
@@ -97,8 +83,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
97static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance); 83static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance);
98static int link_send_sections_long(struct tipc_port *sender, 84static int link_send_sections_long(struct tipc_port *sender,
99 struct iovec const *msg_sect, 85 struct iovec const *msg_sect,
100 u32 num_sect, unsigned int total_len, 86 unsigned int len, u32 destnode);
101 u32 destnode);
102static void link_state_event(struct tipc_link *l_ptr, u32 event); 87static void link_state_event(struct tipc_link *l_ptr, u32 event);
103static void link_reset_statistics(struct tipc_link *l_ptr); 88static void link_reset_statistics(struct tipc_link *l_ptr);
104static void link_print(struct tipc_link *l_ptr, const char *str); 89static void link_print(struct tipc_link *l_ptr, const char *str);
@@ -161,72 +146,6 @@ int tipc_link_is_active(struct tipc_link *l_ptr)
161} 146}
162 147
163/** 148/**
164 * link_name_validate - validate & (optionally) deconstruct tipc_link name
165 * @name: ptr to link name string
166 * @name_parts: ptr to area for link name components (or NULL if not needed)
167 *
168 * Returns 1 if link name is valid, otherwise 0.
169 */
170static int link_name_validate(const char *name,
171 struct tipc_link_name *name_parts)
172{
173 char name_copy[TIPC_MAX_LINK_NAME];
174 char *addr_local;
175 char *if_local;
176 char *addr_peer;
177 char *if_peer;
178 char dummy;
179 u32 z_local, c_local, n_local;
180 u32 z_peer, c_peer, n_peer;
181 u32 if_local_len;
182 u32 if_peer_len;
183
184 /* copy link name & ensure length is OK */
185 name_copy[TIPC_MAX_LINK_NAME - 1] = 0;
186 /* need above in case non-Posix strncpy() doesn't pad with nulls */
187 strncpy(name_copy, name, TIPC_MAX_LINK_NAME);
188 if (name_copy[TIPC_MAX_LINK_NAME - 1] != 0)
189 return 0;
190
191 /* ensure all component parts of link name are present */
192 addr_local = name_copy;
193 if_local = strchr(addr_local, ':');
194 if (if_local == NULL)
195 return 0;
196 *(if_local++) = 0;
197 addr_peer = strchr(if_local, '-');
198 if (addr_peer == NULL)
199 return 0;
200 *(addr_peer++) = 0;
201 if_local_len = addr_peer - if_local;
202 if_peer = strchr(addr_peer, ':');
203 if (if_peer == NULL)
204 return 0;
205 *(if_peer++) = 0;
206 if_peer_len = strlen(if_peer) + 1;
207
208 /* validate component parts of link name */
209 if ((sscanf(addr_local, "%u.%u.%u%c",
210 &z_local, &c_local, &n_local, &dummy) != 3) ||
211 (sscanf(addr_peer, "%u.%u.%u%c",
212 &z_peer, &c_peer, &n_peer, &dummy) != 3) ||
213 (z_local > 255) || (c_local > 4095) || (n_local > 4095) ||
214 (z_peer > 255) || (c_peer > 4095) || (n_peer > 4095) ||
215 (if_local_len <= 1) || (if_local_len > TIPC_MAX_IF_NAME) ||
216 (if_peer_len <= 1) || (if_peer_len > TIPC_MAX_IF_NAME))
217 return 0;
218
219 /* return link name components, if necessary */
220 if (name_parts) {
221 name_parts->addr_local = tipc_addr(z_local, c_local, n_local);
222 strcpy(name_parts->if_local, if_local);
223 name_parts->addr_peer = tipc_addr(z_peer, c_peer, n_peer);
224 strcpy(name_parts->if_peer, if_peer);
225 }
226 return 1;
227}
228
229/**
230 * link_timeout - handle expiration of link timer 149 * link_timeout - handle expiration of link timer
231 * @l_ptr: pointer to link 150 * @l_ptr: pointer to link
232 * 151 *
@@ -485,15 +404,9 @@ static void link_release_outqueue(struct tipc_link *l_ptr)
485 */ 404 */
486void tipc_link_reset_fragments(struct tipc_link *l_ptr) 405void tipc_link_reset_fragments(struct tipc_link *l_ptr)
487{ 406{
488 struct sk_buff *buf = l_ptr->defragm_buf; 407 kfree_skb(l_ptr->reasm_head);
489 struct sk_buff *next; 408 l_ptr->reasm_head = NULL;
490 409 l_ptr->reasm_tail = NULL;
491 while (buf) {
492 next = buf->next;
493 kfree_skb(buf);
494 buf = next;
495 }
496 l_ptr->defragm_buf = NULL;
497} 410}
498 411
499/** 412/**
@@ -1065,8 +978,7 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
1065 */ 978 */
1066int tipc_link_send_sections_fast(struct tipc_port *sender, 979int tipc_link_send_sections_fast(struct tipc_port *sender,
1067 struct iovec const *msg_sect, 980 struct iovec const *msg_sect,
1068 const u32 num_sect, unsigned int total_len, 981 unsigned int len, u32 destaddr)
1069 u32 destaddr)
1070{ 982{
1071 struct tipc_msg *hdr = &sender->phdr; 983 struct tipc_msg *hdr = &sender->phdr;
1072 struct tipc_link *l_ptr; 984 struct tipc_link *l_ptr;
@@ -1080,8 +992,7 @@ again:
1080 * Try building message using port's max_pkt hint. 992 * Try building message using port's max_pkt hint.
1081 * (Must not hold any locks while building message.) 993 * (Must not hold any locks while building message.)
1082 */ 994 */
1083 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, 995 res = tipc_msg_build(hdr, msg_sect, len, sender->max_pkt, &buf);
1084 sender->max_pkt, &buf);
1085 /* Exit if build request was invalid */ 996 /* Exit if build request was invalid */
1086 if (unlikely(res < 0)) 997 if (unlikely(res < 0))
1087 return res; 998 return res;
@@ -1121,8 +1032,7 @@ exit:
1121 if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt) 1032 if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
1122 goto again; 1033 goto again;
1123 1034
1124 return link_send_sections_long(sender, msg_sect, 1035 return link_send_sections_long(sender, msg_sect, len,
1125 num_sect, total_len,
1126 destaddr); 1036 destaddr);
1127 } 1037 }
1128 tipc_node_unlock(node); 1038 tipc_node_unlock(node);
@@ -1133,8 +1043,8 @@ exit:
1133 if (buf) 1043 if (buf)
1134 return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); 1044 return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
1135 if (res >= 0) 1045 if (res >= 0)
1136 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, 1046 return tipc_port_reject_sections(sender, hdr, msg_sect,
1137 total_len, TIPC_ERR_NO_NODE); 1047 len, TIPC_ERR_NO_NODE);
1138 return res; 1048 return res;
1139} 1049}
1140 1050
@@ -1154,18 +1064,17 @@ exit:
1154 */ 1064 */
1155static int link_send_sections_long(struct tipc_port *sender, 1065static int link_send_sections_long(struct tipc_port *sender,
1156 struct iovec const *msg_sect, 1066 struct iovec const *msg_sect,
1157 u32 num_sect, unsigned int total_len, 1067 unsigned int len, u32 destaddr)
1158 u32 destaddr)
1159{ 1068{
1160 struct tipc_link *l_ptr; 1069 struct tipc_link *l_ptr;
1161 struct tipc_node *node; 1070 struct tipc_node *node;
1162 struct tipc_msg *hdr = &sender->phdr; 1071 struct tipc_msg *hdr = &sender->phdr;
1163 u32 dsz = total_len; 1072 u32 dsz = len;
1164 u32 max_pkt, fragm_sz, rest; 1073 u32 max_pkt, fragm_sz, rest;
1165 struct tipc_msg fragm_hdr; 1074 struct tipc_msg fragm_hdr;
1166 struct sk_buff *buf, *buf_chain, *prev; 1075 struct sk_buff *buf, *buf_chain, *prev;
1167 u32 fragm_crs, fragm_rest, hsz, sect_rest; 1076 u32 fragm_crs, fragm_rest, hsz, sect_rest;
1168 const unchar *sect_crs; 1077 const unchar __user *sect_crs;
1169 int curr_sect; 1078 int curr_sect;
1170 u32 fragm_no; 1079 u32 fragm_no;
1171 int res = 0; 1080 int res = 0;
@@ -1207,7 +1116,7 @@ again:
1207 1116
1208 if (!sect_rest) { 1117 if (!sect_rest) {
1209 sect_rest = msg_sect[++curr_sect].iov_len; 1118 sect_rest = msg_sect[++curr_sect].iov_len;
1210 sect_crs = (const unchar *)msg_sect[curr_sect].iov_base; 1119 sect_crs = msg_sect[curr_sect].iov_base;
1211 } 1120 }
1212 1121
1213 if (sect_rest < fragm_rest) 1122 if (sect_rest < fragm_rest)
@@ -1283,8 +1192,8 @@ reject:
1283 buf = buf_chain->next; 1192 buf = buf_chain->next;
1284 kfree_skb(buf_chain); 1193 kfree_skb(buf_chain);
1285 } 1194 }
1286 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, 1195 return tipc_port_reject_sections(sender, hdr, msg_sect,
1287 total_len, TIPC_ERR_NO_NODE); 1196 len, TIPC_ERR_NO_NODE);
1288 } 1197 }
1289 1198
1290 /* Append chain of fragments to send queue & send them */ 1199 /* Append chain of fragments to send queue & send them */
@@ -1589,18 +1498,19 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1589 int type; 1498 int type;
1590 1499
1591 head = head->next; 1500 head = head->next;
1501 buf->next = NULL;
1592 1502
1593 /* Ensure bearer is still enabled */ 1503 /* Ensure bearer is still enabled */
1594 if (unlikely(!b_ptr->active)) 1504 if (unlikely(!b_ptr->active))
1595 goto cont; 1505 goto discard;
1596 1506
1597 /* Ensure message is well-formed */ 1507 /* Ensure message is well-formed */
1598 if (unlikely(!link_recv_buf_validate(buf))) 1508 if (unlikely(!link_recv_buf_validate(buf)))
1599 goto cont; 1509 goto discard;
1600 1510
1601 /* Ensure message data is a single contiguous unit */ 1511 /* Ensure message data is a single contiguous unit */
1602 if (unlikely(skb_linearize(buf))) 1512 if (unlikely(skb_linearize(buf)))
1603 goto cont; 1513 goto discard;
1604 1514
1605 /* Handle arrival of a non-unicast link message */ 1515 /* Handle arrival of a non-unicast link message */
1606 msg = buf_msg(buf); 1516 msg = buf_msg(buf);
@@ -1616,20 +1526,18 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1616 /* Discard unicast link messages destined for another node */ 1526 /* Discard unicast link messages destined for another node */
1617 if (unlikely(!msg_short(msg) && 1527 if (unlikely(!msg_short(msg) &&
1618 (msg_destnode(msg) != tipc_own_addr))) 1528 (msg_destnode(msg) != tipc_own_addr)))
1619 goto cont; 1529 goto discard;
1620 1530
1621 /* Locate neighboring node that sent message */ 1531 /* Locate neighboring node that sent message */
1622 n_ptr = tipc_node_find(msg_prevnode(msg)); 1532 n_ptr = tipc_node_find(msg_prevnode(msg));
1623 if (unlikely(!n_ptr)) 1533 if (unlikely(!n_ptr))
1624 goto cont; 1534 goto discard;
1625 tipc_node_lock(n_ptr); 1535 tipc_node_lock(n_ptr);
1626 1536
1627 /* Locate unicast link endpoint that should handle message */ 1537 /* Locate unicast link endpoint that should handle message */
1628 l_ptr = n_ptr->links[b_ptr->identity]; 1538 l_ptr = n_ptr->links[b_ptr->identity];
1629 if (unlikely(!l_ptr)) { 1539 if (unlikely(!l_ptr))
1630 tipc_node_unlock(n_ptr); 1540 goto unlock_discard;
1631 goto cont;
1632 }
1633 1541
1634 /* Verify that communication with node is currently allowed */ 1542 /* Verify that communication with node is currently allowed */
1635 if ((n_ptr->block_setup & WAIT_PEER_DOWN) && 1543 if ((n_ptr->block_setup & WAIT_PEER_DOWN) &&
@@ -1639,10 +1547,8 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1639 !msg_redundant_link(msg)) 1547 !msg_redundant_link(msg))
1640 n_ptr->block_setup &= ~WAIT_PEER_DOWN; 1548 n_ptr->block_setup &= ~WAIT_PEER_DOWN;
1641 1549
1642 if (n_ptr->block_setup) { 1550 if (n_ptr->block_setup)
1643 tipc_node_unlock(n_ptr); 1551 goto unlock_discard;
1644 goto cont;
1645 }
1646 1552
1647 /* Validate message sequence number info */ 1553 /* Validate message sequence number info */
1648 seq_no = msg_seqno(msg); 1554 seq_no = msg_seqno(msg);
@@ -1678,98 +1584,100 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1678 1584
1679 /* Now (finally!) process the incoming message */ 1585 /* Now (finally!) process the incoming message */
1680protocol_check: 1586protocol_check:
1681 if (likely(link_working_working(l_ptr))) { 1587 if (unlikely(!link_working_working(l_ptr))) {
1682 if (likely(seq_no == mod(l_ptr->next_in_no))) { 1588 if (msg_user(msg) == LINK_PROTOCOL) {
1683 l_ptr->next_in_no++; 1589 link_recv_proto_msg(l_ptr, buf);
1684 if (unlikely(l_ptr->oldest_deferred_in)) 1590 head = link_insert_deferred_queue(l_ptr, head);
1685 head = link_insert_deferred_queue(l_ptr, 1591 tipc_node_unlock(n_ptr);
1686 head); 1592 continue;
1687deliver: 1593 }
1688 if (likely(msg_isdata(msg))) { 1594
1689 tipc_node_unlock(n_ptr); 1595 /* Traffic message. Conditionally activate link */
1690 tipc_port_recv_msg(buf); 1596 link_state_event(l_ptr, TRAFFIC_MSG_EVT);
1691 continue; 1597
1692 } 1598 if (link_working_working(l_ptr)) {
1693 switch (msg_user(msg)) { 1599 /* Re-insert buffer in front of queue */
1694 int ret; 1600 buf->next = head;
1695 case MSG_BUNDLER: 1601 head = buf;
1696 l_ptr->stats.recv_bundles++;
1697 l_ptr->stats.recv_bundled +=
1698 msg_msgcnt(msg);
1699 tipc_node_unlock(n_ptr);
1700 tipc_link_recv_bundle(buf);
1701 continue;
1702 case NAME_DISTRIBUTOR:
1703 n_ptr->bclink.recv_permitted = true;
1704 tipc_node_unlock(n_ptr);
1705 tipc_named_recv(buf);
1706 continue;
1707 case BCAST_PROTOCOL:
1708 tipc_link_recv_sync(n_ptr, buf);
1709 tipc_node_unlock(n_ptr);
1710 continue;
1711 case CONN_MANAGER:
1712 tipc_node_unlock(n_ptr);
1713 tipc_port_recv_proto_msg(buf);
1714 continue;
1715 case MSG_FRAGMENTER:
1716 l_ptr->stats.recv_fragments++;
1717 ret = tipc_link_recv_fragment(
1718 &l_ptr->defragm_buf,
1719 &buf, &msg);
1720 if (ret == 1) {
1721 l_ptr->stats.recv_fragmented++;
1722 goto deliver;
1723 }
1724 if (ret == -1)
1725 l_ptr->next_in_no--;
1726 break;
1727 case CHANGEOVER_PROTOCOL:
1728 type = msg_type(msg);
1729 if (link_recv_changeover_msg(&l_ptr,
1730 &buf)) {
1731 msg = buf_msg(buf);
1732 seq_no = msg_seqno(msg);
1733 if (type == ORIGINAL_MSG)
1734 goto deliver;
1735 goto protocol_check;
1736 }
1737 break;
1738 default:
1739 kfree_skb(buf);
1740 buf = NULL;
1741 break;
1742 }
1743 tipc_node_unlock(n_ptr); 1602 tipc_node_unlock(n_ptr);
1744 tipc_net_route_msg(buf);
1745 continue; 1603 continue;
1746 } 1604 }
1605 goto unlock_discard;
1606 }
1607
1608 /* Link is now in state WORKING_WORKING */
1609 if (unlikely(seq_no != mod(l_ptr->next_in_no))) {
1747 link_handle_out_of_seq_msg(l_ptr, buf); 1610 link_handle_out_of_seq_msg(l_ptr, buf);
1748 head = link_insert_deferred_queue(l_ptr, head); 1611 head = link_insert_deferred_queue(l_ptr, head);
1749 tipc_node_unlock(n_ptr); 1612 tipc_node_unlock(n_ptr);
1750 continue; 1613 continue;
1751 } 1614 }
1752 1615 l_ptr->next_in_no++;
1753 /* Link is not in state WORKING_WORKING */ 1616 if (unlikely(l_ptr->oldest_deferred_in))
1754 if (msg_user(msg) == LINK_PROTOCOL) {
1755 link_recv_proto_msg(l_ptr, buf);
1756 head = link_insert_deferred_queue(l_ptr, head); 1617 head = link_insert_deferred_queue(l_ptr, head);
1618deliver:
1619 if (likely(msg_isdata(msg))) {
1757 tipc_node_unlock(n_ptr); 1620 tipc_node_unlock(n_ptr);
1621 tipc_port_recv_msg(buf);
1758 continue; 1622 continue;
1759 } 1623 }
1760 1624 switch (msg_user(msg)) {
1761 /* Traffic message. Conditionally activate link */ 1625 int ret;
1762 link_state_event(l_ptr, TRAFFIC_MSG_EVT); 1626 case MSG_BUNDLER:
1763 1627 l_ptr->stats.recv_bundles++;
1764 if (link_working_working(l_ptr)) { 1628 l_ptr->stats.recv_bundled += msg_msgcnt(msg);
1765 /* Re-insert buffer in front of queue */ 1629 tipc_node_unlock(n_ptr);
1766 buf->next = head; 1630 tipc_link_recv_bundle(buf);
1767 head = buf; 1631 continue;
1632 case NAME_DISTRIBUTOR:
1633 n_ptr->bclink.recv_permitted = true;
1634 tipc_node_unlock(n_ptr);
1635 tipc_named_recv(buf);
1636 continue;
1637 case BCAST_PROTOCOL:
1638 tipc_link_recv_sync(n_ptr, buf);
1639 tipc_node_unlock(n_ptr);
1640 continue;
1641 case CONN_MANAGER:
1642 tipc_node_unlock(n_ptr);
1643 tipc_port_recv_proto_msg(buf);
1644 continue;
1645 case MSG_FRAGMENTER:
1646 l_ptr->stats.recv_fragments++;
1647 ret = tipc_link_recv_fragment(&l_ptr->reasm_head,
1648 &l_ptr->reasm_tail,
1649 &buf);
1650 if (ret == LINK_REASM_COMPLETE) {
1651 l_ptr->stats.recv_fragmented++;
1652 msg = buf_msg(buf);
1653 goto deliver;
1654 }
1655 if (ret == LINK_REASM_ERROR)
1656 tipc_link_reset(l_ptr);
1768 tipc_node_unlock(n_ptr); 1657 tipc_node_unlock(n_ptr);
1769 continue; 1658 continue;
1659 case CHANGEOVER_PROTOCOL:
1660 type = msg_type(msg);
1661 if (link_recv_changeover_msg(&l_ptr, &buf)) {
1662 msg = buf_msg(buf);
1663 seq_no = msg_seqno(msg);
1664 if (type == ORIGINAL_MSG)
1665 goto deliver;
1666 goto protocol_check;
1667 }
1668 break;
1669 default:
1670 kfree_skb(buf);
1671 buf = NULL;
1672 break;
1770 } 1673 }
1771 tipc_node_unlock(n_ptr); 1674 tipc_node_unlock(n_ptr);
1772cont: 1675 tipc_net_route_msg(buf);
1676 continue;
1677unlock_discard:
1678
1679 tipc_node_unlock(n_ptr);
1680discard:
1773 kfree_skb(buf); 1681 kfree_skb(buf);
1774 } 1682 }
1775 read_unlock_bh(&tipc_net_lock); 1683 read_unlock_bh(&tipc_net_lock);
@@ -2432,114 +2340,48 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
2432} 2340}
2433 2341
2434/* 2342/*
2435 * A pending message being re-assembled must store certain values
2436 * to handle subsequent fragments correctly. The following functions
2437 * help storing these values in unused, available fields in the
2438 * pending message. This makes dynamic memory allocation unnecessary.
2439 */
2440static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno)
2441{
2442 msg_set_seqno(buf_msg(buf), seqno);
2443}
2444
2445static u32 get_fragm_size(struct sk_buff *buf)
2446{
2447 return msg_ack(buf_msg(buf));
2448}
2449
2450static void set_fragm_size(struct sk_buff *buf, u32 sz)
2451{
2452 msg_set_ack(buf_msg(buf), sz);
2453}
2454
2455static u32 get_expected_frags(struct sk_buff *buf)
2456{
2457 return msg_bcast_ack(buf_msg(buf));
2458}
2459
2460static void set_expected_frags(struct sk_buff *buf, u32 exp)
2461{
2462 msg_set_bcast_ack(buf_msg(buf), exp);
2463}
2464
2465/*
2466 * tipc_link_recv_fragment(): Called with node lock on. Returns 2343 * tipc_link_recv_fragment(): Called with node lock on. Returns
2467 * the reassembled buffer if message is complete. 2344 * the reassembled buffer if message is complete.
2468 */ 2345 */
2469int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, 2346int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail,
2470 struct tipc_msg **m) 2347 struct sk_buff **fbuf)
2471{ 2348{
2472 struct sk_buff *prev = NULL; 2349 struct sk_buff *frag = *fbuf;
2473 struct sk_buff *fbuf = *fb; 2350 struct tipc_msg *msg = buf_msg(frag);
2474 struct tipc_msg *fragm = buf_msg(fbuf); 2351 u32 fragid = msg_type(msg);
2475 struct sk_buff *pbuf = *pending; 2352 bool headstolen;
2476 u32 long_msg_seq_no = msg_long_msgno(fragm); 2353 int delta;
2477 2354
2478 *fb = NULL; 2355 skb_pull(frag, msg_hdr_sz(msg));
2479 2356 if (fragid == FIRST_FRAGMENT) {
2480 /* Is there an incomplete message waiting for this fragment? */ 2357 if (*head || skb_unclone(frag, GFP_ATOMIC))
2481 while (pbuf && ((buf_seqno(pbuf) != long_msg_seq_no) || 2358 goto out_free;
2482 (msg_orignode(fragm) != msg_orignode(buf_msg(pbuf))))) { 2359 *head = frag;
2483 prev = pbuf; 2360 skb_frag_list_init(*head);
2484 pbuf = pbuf->next;
2485 }
2486
2487 if (!pbuf && (msg_type(fragm) == FIRST_FRAGMENT)) {
2488 struct tipc_msg *imsg = (struct tipc_msg *)msg_data(fragm);
2489 u32 msg_sz = msg_size(imsg);
2490 u32 fragm_sz = msg_data_sz(fragm);
2491 u32 exp_fragm_cnt;
2492 u32 max = TIPC_MAX_USER_MSG_SIZE + NAMED_H_SIZE;
2493
2494 if (msg_type(imsg) == TIPC_MCAST_MSG)
2495 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
2496 if (fragm_sz == 0 || msg_size(imsg) > max) {
2497 kfree_skb(fbuf);
2498 return 0;
2499 }
2500 exp_fragm_cnt = msg_sz / fragm_sz + !!(msg_sz % fragm_sz);
2501 pbuf = tipc_buf_acquire(msg_size(imsg));
2502 if (pbuf != NULL) {
2503 pbuf->next = *pending;
2504 *pending = pbuf;
2505 skb_copy_to_linear_data(pbuf, imsg,
2506 msg_data_sz(fragm));
2507 /* Prepare buffer for subsequent fragments. */
2508 set_long_msg_seqno(pbuf, long_msg_seq_no);
2509 set_fragm_size(pbuf, fragm_sz);
2510 set_expected_frags(pbuf, exp_fragm_cnt - 1);
2511 } else {
2512 pr_debug("Link unable to reassemble fragmented message\n");
2513 kfree_skb(fbuf);
2514 return -1;
2515 }
2516 kfree_skb(fbuf);
2517 return 0;
2518 } else if (pbuf && (msg_type(fragm) != FIRST_FRAGMENT)) {
2519 u32 dsz = msg_data_sz(fragm);
2520 u32 fsz = get_fragm_size(pbuf);
2521 u32 crs = ((msg_fragm_no(fragm) - 1) * fsz);
2522 u32 exp_frags = get_expected_frags(pbuf) - 1;
2523 skb_copy_to_linear_data_offset(pbuf, crs,
2524 msg_data(fragm), dsz);
2525 kfree_skb(fbuf);
2526
2527 /* Is message complete? */
2528 if (exp_frags == 0) {
2529 if (prev)
2530 prev->next = pbuf->next;
2531 else
2532 *pending = pbuf->next;
2533 msg_reset_reroute_cnt(buf_msg(pbuf));
2534 *fb = pbuf;
2535 *m = buf_msg(pbuf);
2536 return 1;
2537 }
2538 set_expected_frags(pbuf, exp_frags);
2539 return 0; 2361 return 0;
2362 } else if (*head &&
2363 skb_try_coalesce(*head, frag, &headstolen, &delta)) {
2364 kfree_skb_partial(frag, headstolen);
2365 } else {
2366 if (!*head)
2367 goto out_free;
2368 if (!skb_has_frag_list(*head))
2369 skb_shinfo(*head)->frag_list = frag;
2370 else
2371 (*tail)->next = frag;
2372 *tail = frag;
2373 (*head)->truesize += frag->truesize;
2374 }
2375 if (fragid == LAST_FRAGMENT) {
2376 *fbuf = *head;
2377 *tail = *head = NULL;
2378 return LINK_REASM_COMPLETE;
2540 } 2379 }
2541 kfree_skb(fbuf);
2542 return 0; 2380 return 0;
2381out_free:
2382 pr_warn_ratelimited("Link unable to reassemble fragmented message\n");
2383 kfree_skb(*fbuf);
2384 return LINK_REASM_ERROR;
2543} 2385}
2544 2386
2545static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance) 2387static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance)
@@ -2585,25 +2427,21 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
2585static struct tipc_link *link_find_link(const char *name, 2427static struct tipc_link *link_find_link(const char *name,
2586 struct tipc_node **node) 2428 struct tipc_node **node)
2587{ 2429{
2588 struct tipc_link_name link_name_parts;
2589 struct tipc_bearer *b_ptr;
2590 struct tipc_link *l_ptr; 2430 struct tipc_link *l_ptr;
2431 struct tipc_node *n_ptr;
2432 int i;
2591 2433
2592 if (!link_name_validate(name, &link_name_parts)) 2434 list_for_each_entry(n_ptr, &tipc_node_list, list) {
2593 return NULL; 2435 for (i = 0; i < MAX_BEARERS; i++) {
2594 2436 l_ptr = n_ptr->links[i];
2595 b_ptr = tipc_bearer_find_interface(link_name_parts.if_local); 2437 if (l_ptr && !strcmp(l_ptr->name, name))
2596 if (!b_ptr) 2438 goto found;
2597 return NULL; 2439 }
2598 2440 }
2599 *node = tipc_node_find(link_name_parts.addr_peer); 2441 l_ptr = NULL;
2600 if (!*node) 2442 n_ptr = NULL;
2601 return NULL; 2443found:
2602 2444 *node = n_ptr;
2603 l_ptr = (*node)->links[b_ptr->identity];
2604 if (!l_ptr || strcmp(l_ptr->name, name))
2605 return NULL;
2606
2607 return l_ptr; 2445 return l_ptr;
2608} 2446}
2609 2447
@@ -2646,6 +2484,7 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2646 struct tipc_link *l_ptr; 2484 struct tipc_link *l_ptr;
2647 struct tipc_bearer *b_ptr; 2485 struct tipc_bearer *b_ptr;
2648 struct tipc_media *m_ptr; 2486 struct tipc_media *m_ptr;
2487 int res = 0;
2649 2488
2650 l_ptr = link_find_link(name, &node); 2489 l_ptr = link_find_link(name, &node);
2651 if (l_ptr) { 2490 if (l_ptr) {
@@ -2668,9 +2507,12 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2668 case TIPC_CMD_SET_LINK_WINDOW: 2507 case TIPC_CMD_SET_LINK_WINDOW:
2669 tipc_link_set_queue_limits(l_ptr, new_value); 2508 tipc_link_set_queue_limits(l_ptr, new_value);
2670 break; 2509 break;
2510 default:
2511 res = -EINVAL;
2512 break;
2671 } 2513 }
2672 tipc_node_unlock(node); 2514 tipc_node_unlock(node);
2673 return 0; 2515 return res;
2674 } 2516 }
2675 2517
2676 b_ptr = tipc_bearer_find(name); 2518 b_ptr = tipc_bearer_find(name);
@@ -2678,15 +2520,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2678 switch (cmd) { 2520 switch (cmd) {
2679 case TIPC_CMD_SET_LINK_TOL: 2521 case TIPC_CMD_SET_LINK_TOL:
2680 b_ptr->tolerance = new_value; 2522 b_ptr->tolerance = new_value;
2681 return 0; 2523 break;
2682 case TIPC_CMD_SET_LINK_PRI: 2524 case TIPC_CMD_SET_LINK_PRI:
2683 b_ptr->priority = new_value; 2525 b_ptr->priority = new_value;
2684 return 0; 2526 break;
2685 case TIPC_CMD_SET_LINK_WINDOW: 2527 case TIPC_CMD_SET_LINK_WINDOW:
2686 b_ptr->window = new_value; 2528 b_ptr->window = new_value;
2687 return 0; 2529 break;
2530 default:
2531 res = -EINVAL;
2532 break;
2688 } 2533 }
2689 return -EINVAL; 2534 return res;
2690 } 2535 }
2691 2536
2692 m_ptr = tipc_media_find(name); 2537 m_ptr = tipc_media_find(name);
@@ -2695,15 +2540,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2695 switch (cmd) { 2540 switch (cmd) {
2696 case TIPC_CMD_SET_LINK_TOL: 2541 case TIPC_CMD_SET_LINK_TOL:
2697 m_ptr->tolerance = new_value; 2542 m_ptr->tolerance = new_value;
2698 return 0; 2543 break;
2699 case TIPC_CMD_SET_LINK_PRI: 2544 case TIPC_CMD_SET_LINK_PRI:
2700 m_ptr->priority = new_value; 2545 m_ptr->priority = new_value;
2701 return 0; 2546 break;
2702 case TIPC_CMD_SET_LINK_WINDOW: 2547 case TIPC_CMD_SET_LINK_WINDOW:
2703 m_ptr->window = new_value; 2548 m_ptr->window = new_value;
2704 return 0; 2549 break;
2550 default:
2551 res = -EINVAL;
2552 break;
2705 } 2553 }
2706 return -EINVAL; 2554 return res;
2707} 2555}
2708 2556
2709struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, 2557struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space,
diff --git a/net/tipc/link.h b/net/tipc/link.h
index c048ed1cbd76..8a6c1026644d 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -41,6 +41,12 @@
41#include "node.h" 41#include "node.h"
42 42
43/* 43/*
44 * Link reassembly status codes
45 */
46#define LINK_REASM_ERROR -1
47#define LINK_REASM_COMPLETE 1
48
49/*
44 * Out-of-range value for link sequence numbers 50 * Out-of-range value for link sequence numbers
45 */ 51 */
46#define INVALID_LINK_SEQ 0x10000 52#define INVALID_LINK_SEQ 0x10000
@@ -134,7 +140,8 @@ struct tipc_stats {
134 * @next_out: ptr to first unsent outbound message in queue 140 * @next_out: ptr to first unsent outbound message in queue
135 * @waiting_ports: linked list of ports waiting for link congestion to abate 141 * @waiting_ports: linked list of ports waiting for link congestion to abate
136 * @long_msg_seq_no: next identifier to use for outbound fragmented messages 142 * @long_msg_seq_no: next identifier to use for outbound fragmented messages
137 * @defragm_buf: list of partially reassembled inbound message fragments 143 * @reasm_head: list head of partially reassembled inbound message fragments
144 * @reasm_tail: last fragment received
138 * @stats: collects statistics regarding link activity 145 * @stats: collects statistics regarding link activity
139 */ 146 */
140struct tipc_link { 147struct tipc_link {
@@ -196,9 +203,10 @@ struct tipc_link {
196 struct sk_buff *next_out; 203 struct sk_buff *next_out;
197 struct list_head waiting_ports; 204 struct list_head waiting_ports;
198 205
199 /* Fragmentation/defragmentation */ 206 /* Fragmentation/reassembly */
200 u32 long_msg_seq_no; 207 u32 long_msg_seq_no;
201 struct sk_buff *defragm_buf; 208 struct sk_buff *reasm_head;
209 struct sk_buff *reasm_tail;
202 210
203 /* Statistics */ 211 /* Statistics */
204 struct tipc_stats stats; 212 struct tipc_stats stats;
@@ -227,13 +235,11 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf);
227u32 tipc_link_get_max_pkt(u32 dest, u32 selector); 235u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
228int tipc_link_send_sections_fast(struct tipc_port *sender, 236int tipc_link_send_sections_fast(struct tipc_port *sender,
229 struct iovec const *msg_sect, 237 struct iovec const *msg_sect,
230 const u32 num_sect, 238 unsigned int len, u32 destnode);
231 unsigned int total_len,
232 u32 destnode);
233void tipc_link_recv_bundle(struct sk_buff *buf); 239void tipc_link_recv_bundle(struct sk_buff *buf);
234int tipc_link_recv_fragment(struct sk_buff **pending, 240int tipc_link_recv_fragment(struct sk_buff **reasm_head,
235 struct sk_buff **fb, 241 struct sk_buff **reasm_tail,
236 struct tipc_msg **msg); 242 struct sk_buff **fbuf);
237void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, int prob, 243void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, int prob,
238 u32 gap, u32 tolerance, u32 priority, 244 u32 gap, u32 tolerance, u32 priority,
239 u32 acked_mtu); 245 u32 acked_mtu);
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index ced60e2fc4f7..e525f8ce1dee 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -73,13 +73,13 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
73 * Returns message data size or errno 73 * Returns message data size or errno
74 */ 74 */
75int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, 75int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
76 u32 num_sect, unsigned int total_len, int max_size, 76 unsigned int len, int max_size, struct sk_buff **buf)
77 struct sk_buff **buf)
78{ 77{
79 int dsz, sz, hsz, pos, res, cnt; 78 int dsz, sz, hsz;
79 unsigned char *to;
80 80
81 dsz = total_len; 81 dsz = len;
82 pos = hsz = msg_hdr_sz(hdr); 82 hsz = msg_hdr_sz(hdr);
83 sz = hsz + dsz; 83 sz = hsz + dsz;
84 msg_set_size(hdr, sz); 84 msg_set_size(hdr, sz);
85 if (unlikely(sz > max_size)) { 85 if (unlikely(sz > max_size)) {
@@ -91,16 +91,11 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
91 if (!(*buf)) 91 if (!(*buf))
92 return -ENOMEM; 92 return -ENOMEM;
93 skb_copy_to_linear_data(*buf, hdr, hsz); 93 skb_copy_to_linear_data(*buf, hdr, hsz);
94 for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) { 94 to = (*buf)->data + hsz;
95 skb_copy_to_linear_data_offset(*buf, pos, 95 if (len && memcpy_fromiovecend(to, msg_sect, 0, dsz)) {
96 msg_sect[cnt].iov_base, 96 kfree_skb(*buf);
97 msg_sect[cnt].iov_len); 97 *buf = NULL;
98 pos += msg_sect[cnt].iov_len; 98 return -EFAULT;
99 } 99 }
100 if (likely(res)) 100 return dsz;
101 return dsz;
102
103 kfree_skb(*buf);
104 *buf = NULL;
105 return -EFAULT;
106} 101}
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 5e4ccf5c27df..76d1269b9443 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -554,12 +554,6 @@ static inline void msg_set_last_bcast(struct tipc_msg *m, u32 n)
554 msg_set_bits(m, 4, 16, 0xffff, n); 554 msg_set_bits(m, 4, 16, 0xffff, n);
555} 555}
556 556
557
558static inline u32 msg_fragm_no(struct tipc_msg *m)
559{
560 return msg_bits(m, 4, 16, 0xffff);
561}
562
563static inline void msg_set_fragm_no(struct tipc_msg *m, u32 n) 557static inline void msg_set_fragm_no(struct tipc_msg *m, u32 n)
564{ 558{
565 msg_set_bits(m, 4, 16, 0xffff, n); 559 msg_set_bits(m, 4, 16, 0xffff, n);
@@ -576,12 +570,6 @@ static inline void msg_set_next_sent(struct tipc_msg *m, u32 n)
576 msg_set_bits(m, 4, 0, 0xffff, n); 570 msg_set_bits(m, 4, 0, 0xffff, n);
577} 571}
578 572
579
580static inline u32 msg_long_msgno(struct tipc_msg *m)
581{
582 return msg_bits(m, 4, 0, 0xffff);
583}
584
585static inline void msg_set_long_msgno(struct tipc_msg *m, u32 n) 573static inline void msg_set_long_msgno(struct tipc_msg *m, u32 n)
586{ 574{
587 msg_set_bits(m, 4, 0, 0xffff, n); 575 msg_set_bits(m, 4, 0, 0xffff, n);
@@ -722,6 +710,5 @@ u32 tipc_msg_tot_importance(struct tipc_msg *m);
722void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, 710void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
723 u32 destnode); 711 u32 destnode);
724int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, 712int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
725 u32 num_sect, unsigned int total_len, int max_size, 713 unsigned int len, int max_size, struct sk_buff **buf);
726 struct sk_buff **buf);
727#endif 714#endif
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 8bcd4985d0fb..9f72a6376362 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -76,9 +76,11 @@ static struct genl_family tipc_genl_family = {
76 .maxattr = 0, 76 .maxattr = 0,
77}; 77};
78 78
79static struct genl_ops tipc_genl_ops = { 79static struct genl_ops tipc_genl_ops[] = {
80 .cmd = TIPC_GENL_CMD, 80 {
81 .doit = handle_cmd, 81 .cmd = TIPC_GENL_CMD,
82 .doit = handle_cmd,
83 },
82}; 84};
83 85
84static int tipc_genl_family_registered; 86static int tipc_genl_family_registered;
@@ -87,8 +89,7 @@ int tipc_netlink_start(void)
87{ 89{
88 int res; 90 int res;
89 91
90 res = genl_register_family_with_ops(&tipc_genl_family, 92 res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops);
91 &tipc_genl_ops, 1);
92 if (res) { 93 if (res) {
93 pr_err("Failed to register netlink interface\n"); 94 pr_err("Failed to register netlink interface\n");
94 return res; 95 return res;
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 6e6c434872e8..25100c0a6fe8 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -298,9 +298,10 @@ static void node_lost_contact(struct tipc_node *n_ptr)
298 } 298 }
299 n_ptr->bclink.deferred_size = 0; 299 n_ptr->bclink.deferred_size = 0;
300 300
301 if (n_ptr->bclink.defragm) { 301 if (n_ptr->bclink.reasm_head) {
302 kfree_skb(n_ptr->bclink.defragm); 302 kfree_skb(n_ptr->bclink.reasm_head);
303 n_ptr->bclink.defragm = NULL; 303 n_ptr->bclink.reasm_head = NULL;
304 n_ptr->bclink.reasm_tail = NULL;
304 } 305 }
305 306
306 tipc_bclink_remove_node(n_ptr->addr); 307 tipc_bclink_remove_node(n_ptr->addr);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 3c189b35b102..e5e96c04e167 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -74,7 +74,8 @@
74 * @deferred_size: number of OOS b'cast messages in deferred queue 74 * @deferred_size: number of OOS b'cast messages in deferred queue
75 * @deferred_head: oldest OOS b'cast message received from node 75 * @deferred_head: oldest OOS b'cast message received from node
76 * @deferred_tail: newest OOS b'cast message received from node 76 * @deferred_tail: newest OOS b'cast message received from node
77 * @defragm: list of partially reassembled b'cast message fragments from node 77 * @reasm_head: broadcast reassembly queue head from node
78 * @reasm_tail: last broadcast fragment received from node
78 * @recv_permitted: true if node is allowed to receive b'cast messages 79 * @recv_permitted: true if node is allowed to receive b'cast messages
79 */ 80 */
80struct tipc_node { 81struct tipc_node {
@@ -98,7 +99,8 @@ struct tipc_node {
98 u32 deferred_size; 99 u32 deferred_size;
99 struct sk_buff *deferred_head; 100 struct sk_buff *deferred_head;
100 struct sk_buff *deferred_tail; 101 struct sk_buff *deferred_tail;
101 struct sk_buff *defragm; 102 struct sk_buff *reasm_head;
103 struct sk_buff *reasm_tail;
102 bool recv_permitted; 104 bool recv_permitted;
103 } bclink; 105 } bclink;
104}; 106};
diff --git a/net/tipc/port.c b/net/tipc/port.c
index b3ed2fcab4fb..d43f3182b1d4 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -90,8 +90,7 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg)
90 * tipc_multicast - send a multicast message to local and remote destinations 90 * tipc_multicast - send a multicast message to local and remote destinations
91 */ 91 */
92int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, 92int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
93 u32 num_sect, struct iovec const *msg_sect, 93 struct iovec const *msg_sect, unsigned int len)
94 unsigned int total_len)
95{ 94{
96 struct tipc_msg *hdr; 95 struct tipc_msg *hdr;
97 struct sk_buff *buf; 96 struct sk_buff *buf;
@@ -114,8 +113,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
114 msg_set_namelower(hdr, seq->lower); 113 msg_set_namelower(hdr, seq->lower);
115 msg_set_nameupper(hdr, seq->upper); 114 msg_set_nameupper(hdr, seq->upper);
116 msg_set_hdr_sz(hdr, MCAST_H_SIZE); 115 msg_set_hdr_sz(hdr, MCAST_H_SIZE);
117 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, 116 res = tipc_msg_build(hdr, msg_sect, len, MAX_MSG_SIZE, &buf);
118 &buf);
119 if (unlikely(!buf)) 117 if (unlikely(!buf))
120 return res; 118 return res;
121 119
@@ -253,18 +251,15 @@ struct tipc_port *tipc_createport(struct sock *sk,
253 return p_ptr; 251 return p_ptr;
254} 252}
255 253
256int tipc_deleteport(u32 ref) 254int tipc_deleteport(struct tipc_port *p_ptr)
257{ 255{
258 struct tipc_port *p_ptr;
259 struct sk_buff *buf = NULL; 256 struct sk_buff *buf = NULL;
260 257
261 tipc_withdraw(ref, 0, NULL); 258 tipc_withdraw(p_ptr, 0, NULL);
262 p_ptr = tipc_port_lock(ref);
263 if (!p_ptr)
264 return -EINVAL;
265 259
266 tipc_ref_discard(ref); 260 spin_lock_bh(p_ptr->lock);
267 tipc_port_unlock(p_ptr); 261 tipc_ref_discard(p_ptr->ref);
262 spin_unlock_bh(p_ptr->lock);
268 263
269 k_cancel_timer(&p_ptr->timer); 264 k_cancel_timer(&p_ptr->timer);
270 if (p_ptr->connected) { 265 if (p_ptr->connected) {
@@ -436,14 +431,13 @@ exit:
436} 431}
437 432
438int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, 433int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
439 struct iovec const *msg_sect, u32 num_sect, 434 struct iovec const *msg_sect, unsigned int len,
440 unsigned int total_len, int err) 435 int err)
441{ 436{
442 struct sk_buff *buf; 437 struct sk_buff *buf;
443 int res; 438 int res;
444 439
445 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, 440 res = tipc_msg_build(hdr, msg_sect, len, MAX_MSG_SIZE, &buf);
446 &buf);
447 if (!buf) 441 if (!buf)
448 return res; 442 return res;
449 443
@@ -707,47 +701,36 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
707} 701}
708 702
709 703
710int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 704int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
705 struct tipc_name_seq const *seq)
711{ 706{
712 struct tipc_port *p_ptr;
713 struct publication *publ; 707 struct publication *publ;
714 u32 key; 708 u32 key;
715 int res = -EINVAL;
716 709
717 p_ptr = tipc_port_lock(ref); 710 if (p_ptr->connected)
718 if (!p_ptr)
719 return -EINVAL; 711 return -EINVAL;
712 key = p_ptr->ref + p_ptr->pub_count + 1;
713 if (key == p_ptr->ref)
714 return -EADDRINUSE;
720 715
721 if (p_ptr->connected)
722 goto exit;
723 key = ref + p_ptr->pub_count + 1;
724 if (key == ref) {
725 res = -EADDRINUSE;
726 goto exit;
727 }
728 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, 716 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
729 scope, p_ptr->ref, key); 717 scope, p_ptr->ref, key);
730 if (publ) { 718 if (publ) {
731 list_add(&publ->pport_list, &p_ptr->publications); 719 list_add(&publ->pport_list, &p_ptr->publications);
732 p_ptr->pub_count++; 720 p_ptr->pub_count++;
733 p_ptr->published = 1; 721 p_ptr->published = 1;
734 res = 0; 722 return 0;
735 } 723 }
736exit: 724 return -EINVAL;
737 tipc_port_unlock(p_ptr);
738 return res;
739} 725}
740 726
741int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 727int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
728 struct tipc_name_seq const *seq)
742{ 729{
743 struct tipc_port *p_ptr;
744 struct publication *publ; 730 struct publication *publ;
745 struct publication *tpubl; 731 struct publication *tpubl;
746 int res = -EINVAL; 732 int res = -EINVAL;
747 733
748 p_ptr = tipc_port_lock(ref);
749 if (!p_ptr)
750 return -EINVAL;
751 if (!seq) { 734 if (!seq) {
752 list_for_each_entry_safe(publ, tpubl, 735 list_for_each_entry_safe(publ, tpubl,
753 &p_ptr->publications, pport_list) { 736 &p_ptr->publications, pport_list) {
@@ -774,7 +757,6 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
774 } 757 }
775 if (list_empty(&p_ptr->publications)) 758 if (list_empty(&p_ptr->publications))
776 p_ptr->published = 0; 759 p_ptr->published = 0;
777 tipc_port_unlock(p_ptr);
778 return res; 760 return res;
779} 761}
780 762
@@ -918,15 +900,14 @@ int tipc_port_recv_msg(struct sk_buff *buf)
918 * tipc_port_recv_sections(): Concatenate and deliver sectioned 900 * tipc_port_recv_sections(): Concatenate and deliver sectioned
919 * message for this node. 901 * message for this node.
920 */ 902 */
921static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect, 903static int tipc_port_recv_sections(struct tipc_port *sender,
922 struct iovec const *msg_sect, 904 struct iovec const *msg_sect,
923 unsigned int total_len) 905 unsigned int len)
924{ 906{
925 struct sk_buff *buf; 907 struct sk_buff *buf;
926 int res; 908 int res;
927 909
928 res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len, 910 res = tipc_msg_build(&sender->phdr, msg_sect, len, MAX_MSG_SIZE, &buf);
929 MAX_MSG_SIZE, &buf);
930 if (likely(buf)) 911 if (likely(buf))
931 tipc_port_recv_msg(buf); 912 tipc_port_recv_msg(buf);
932 return res; 913 return res;
@@ -935,8 +916,7 @@ static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_se
935/** 916/**
936 * tipc_send - send message sections on connection 917 * tipc_send - send message sections on connection
937 */ 918 */
938int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect, 919int tipc_send(u32 ref, struct iovec const *msg_sect, unsigned int len)
939 unsigned int total_len)
940{ 920{
941 struct tipc_port *p_ptr; 921 struct tipc_port *p_ptr;
942 u32 destnode; 922 u32 destnode;
@@ -950,11 +930,10 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
950 if (!tipc_port_congested(p_ptr)) { 930 if (!tipc_port_congested(p_ptr)) {
951 destnode = port_peernode(p_ptr); 931 destnode = port_peernode(p_ptr);
952 if (likely(!in_own_node(destnode))) 932 if (likely(!in_own_node(destnode)))
953 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 933 res = tipc_link_send_sections_fast(p_ptr, msg_sect,
954 total_len, destnode); 934 len, destnode);
955 else 935 else
956 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect, 936 res = tipc_port_recv_sections(p_ptr, msg_sect, len);
957 total_len);
958 937
959 if (likely(res != -ELINKCONG)) { 938 if (likely(res != -ELINKCONG)) {
960 p_ptr->congested = 0; 939 p_ptr->congested = 0;
@@ -965,7 +944,7 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
965 } 944 }
966 if (port_unreliable(p_ptr)) { 945 if (port_unreliable(p_ptr)) {
967 p_ptr->congested = 0; 946 p_ptr->congested = 0;
968 return total_len; 947 return len;
969 } 948 }
970 return -ELINKCONG; 949 return -ELINKCONG;
971} 950}
@@ -974,8 +953,7 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
974 * tipc_send2name - send message sections to port name 953 * tipc_send2name - send message sections to port name
975 */ 954 */
976int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, 955int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
977 unsigned int num_sect, struct iovec const *msg_sect, 956 struct iovec const *msg_sect, unsigned int len)
978 unsigned int total_len)
979{ 957{
980 struct tipc_port *p_ptr; 958 struct tipc_port *p_ptr;
981 struct tipc_msg *msg; 959 struct tipc_msg *msg;
@@ -999,36 +977,32 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
999 977
1000 if (likely(destport || destnode)) { 978 if (likely(destport || destnode)) {
1001 if (likely(in_own_node(destnode))) 979 if (likely(in_own_node(destnode)))
1002 res = tipc_port_recv_sections(p_ptr, num_sect, 980 res = tipc_port_recv_sections(p_ptr, msg_sect, len);
1003 msg_sect, total_len);
1004 else if (tipc_own_addr) 981 else if (tipc_own_addr)
1005 res = tipc_link_send_sections_fast(p_ptr, msg_sect, 982 res = tipc_link_send_sections_fast(p_ptr, msg_sect,
1006 num_sect, total_len, 983 len, destnode);
1007 destnode);
1008 else 984 else
1009 res = tipc_port_reject_sections(p_ptr, msg, msg_sect, 985 res = tipc_port_reject_sections(p_ptr, msg, msg_sect,
1010 num_sect, total_len, 986 len, TIPC_ERR_NO_NODE);
1011 TIPC_ERR_NO_NODE);
1012 if (likely(res != -ELINKCONG)) { 987 if (likely(res != -ELINKCONG)) {
1013 if (res > 0) 988 if (res > 0)
1014 p_ptr->sent++; 989 p_ptr->sent++;
1015 return res; 990 return res;
1016 } 991 }
1017 if (port_unreliable(p_ptr)) { 992 if (port_unreliable(p_ptr)) {
1018 return total_len; 993 return len;
1019 } 994 }
1020 return -ELINKCONG; 995 return -ELINKCONG;
1021 } 996 }
1022 return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, 997 return tipc_port_reject_sections(p_ptr, msg, msg_sect, len,
1023 total_len, TIPC_ERR_NO_NAME); 998 TIPC_ERR_NO_NAME);
1024} 999}
1025 1000
1026/** 1001/**
1027 * tipc_send2port - send message sections to port identity 1002 * tipc_send2port - send message sections to port identity
1028 */ 1003 */
1029int tipc_send2port(u32 ref, struct tipc_portid const *dest, 1004int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1030 unsigned int num_sect, struct iovec const *msg_sect, 1005 struct iovec const *msg_sect, unsigned int len)
1031 unsigned int total_len)
1032{ 1006{
1033 struct tipc_port *p_ptr; 1007 struct tipc_port *p_ptr;
1034 struct tipc_msg *msg; 1008 struct tipc_msg *msg;
@@ -1046,21 +1020,20 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1046 msg_set_hdr_sz(msg, BASIC_H_SIZE); 1020 msg_set_hdr_sz(msg, BASIC_H_SIZE);
1047 1021
1048 if (in_own_node(dest->node)) 1022 if (in_own_node(dest->node))
1049 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect, 1023 res = tipc_port_recv_sections(p_ptr, msg_sect, len);
1050 total_len);
1051 else if (tipc_own_addr) 1024 else if (tipc_own_addr)
1052 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 1025 res = tipc_link_send_sections_fast(p_ptr, msg_sect, len,
1053 total_len, dest->node); 1026 dest->node);
1054 else 1027 else
1055 res = tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, 1028 res = tipc_port_reject_sections(p_ptr, msg, msg_sect, len,
1056 total_len, TIPC_ERR_NO_NODE); 1029 TIPC_ERR_NO_NODE);
1057 if (likely(res != -ELINKCONG)) { 1030 if (likely(res != -ELINKCONG)) {
1058 if (res > 0) 1031 if (res > 0)
1059 p_ptr->sent++; 1032 p_ptr->sent++;
1060 return res; 1033 return res;
1061 } 1034 }
1062 if (port_unreliable(p_ptr)) { 1035 if (port_unreliable(p_ptr)) {
1063 return total_len; 1036 return len;
1064 } 1037 }
1065 return -ELINKCONG; 1038 return -ELINKCONG;
1066} 1039}
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 5a7026b9c345..34f12bd4074e 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -116,7 +116,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err);
116 116
117void tipc_acknowledge(u32 port_ref, u32 ack); 117void tipc_acknowledge(u32 port_ref, u32 ack);
118 118
119int tipc_deleteport(u32 portref); 119int tipc_deleteport(struct tipc_port *p_ptr);
120 120
121int tipc_portimportance(u32 portref, unsigned int *importance); 121int tipc_portimportance(u32 portref, unsigned int *importance);
122int tipc_set_portimportance(u32 portref, unsigned int importance); 122int tipc_set_portimportance(u32 portref, unsigned int importance);
@@ -127,9 +127,9 @@ int tipc_set_portunreliable(u32 portref, unsigned int isunreliable);
127int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); 127int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
128int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); 128int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
129 129
130int tipc_publish(u32 portref, unsigned int scope, 130int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
131 struct tipc_name_seq const *name_seq); 131 struct tipc_name_seq const *name_seq);
132int tipc_withdraw(u32 portref, unsigned int scope, 132int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
133 struct tipc_name_seq const *name_seq); 133 struct tipc_name_seq const *name_seq);
134 134
135int tipc_connect(u32 portref, struct tipc_portid const *port); 135int tipc_connect(u32 portref, struct tipc_portid const *port);
@@ -151,24 +151,20 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg);
151 * TIPC messaging routines 151 * TIPC messaging routines
152 */ 152 */
153int tipc_port_recv_msg(struct sk_buff *buf); 153int tipc_port_recv_msg(struct sk_buff *buf);
154int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect, 154int tipc_send(u32 portref, struct iovec const *msg_sect, unsigned int len);
155 unsigned int total_len);
156 155
157int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, 156int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
158 unsigned int num_sect, struct iovec const *msg_sect, 157 struct iovec const *msg_sect, unsigned int len);
159 unsigned int total_len);
160 158
161int tipc_send2port(u32 portref, struct tipc_portid const *dest, 159int tipc_send2port(u32 portref, struct tipc_portid const *dest,
162 unsigned int num_sect, struct iovec const *msg_sect, 160 struct iovec const *msg_sect, unsigned int len);
163 unsigned int total_len);
164 161
165int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, 162int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
166 unsigned int section_count, struct iovec const *msg, 163 struct iovec const *msg, unsigned int len);
167 unsigned int total_len);
168 164
169int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, 165int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
170 struct iovec const *msg_sect, u32 num_sect, 166 struct iovec const *msg_sect, unsigned int len,
171 unsigned int total_len, int err); 167 int err);
172struct sk_buff *tipc_port_get_ports(void); 168struct sk_buff *tipc_port_get_ports(void);
173void tipc_port_recv_proto_msg(struct sk_buff *buf); 169void tipc_port_recv_proto_msg(struct sk_buff *buf);
174void tipc_port_recv_mcast(struct sk_buff *buf, struct tipc_port_list *dp); 170void tipc_port_recv_mcast(struct sk_buff *buf, struct tipc_port_list *dp);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 6cc7ddd2fb7c..e741416d1d24 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -338,7 +338,7 @@ static int release(struct socket *sock)
338 buf = __skb_dequeue(&sk->sk_receive_queue); 338 buf = __skb_dequeue(&sk->sk_receive_queue);
339 if (buf == NULL) 339 if (buf == NULL)
340 break; 340 break;
341 if (TIPC_SKB_CB(buf)->handle != 0) 341 if (TIPC_SKB_CB(buf)->handle != NULL)
342 kfree_skb(buf); 342 kfree_skb(buf);
343 else { 343 else {
344 if ((sock->state == SS_CONNECTING) || 344 if ((sock->state == SS_CONNECTING) ||
@@ -354,7 +354,7 @@ static int release(struct socket *sock)
354 * Delete TIPC port; this ensures no more messages are queued 354 * Delete TIPC port; this ensures no more messages are queued
355 * (also disconnects an active connection & sends a 'FIN-' to peer) 355 * (also disconnects an active connection & sends a 'FIN-' to peer)
356 */ 356 */
357 res = tipc_deleteport(tport->ref); 357 res = tipc_deleteport(tport);
358 358
359 /* Discard any remaining (connection-based) messages in receive queue */ 359 /* Discard any remaining (connection-based) messages in receive queue */
360 __skb_queue_purge(&sk->sk_receive_queue); 360 __skb_queue_purge(&sk->sk_receive_queue);
@@ -386,30 +386,46 @@ static int release(struct socket *sock)
386 */ 386 */
387static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) 387static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
388{ 388{
389 struct sock *sk = sock->sk;
389 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 390 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
390 u32 portref = tipc_sk_port(sock->sk)->ref; 391 struct tipc_port *tport = tipc_sk_port(sock->sk);
392 int res = -EINVAL;
391 393
392 if (unlikely(!uaddr_len)) 394 lock_sock(sk);
393 return tipc_withdraw(portref, 0, NULL); 395 if (unlikely(!uaddr_len)) {
396 res = tipc_withdraw(tport, 0, NULL);
397 goto exit;
398 }
394 399
395 if (uaddr_len < sizeof(struct sockaddr_tipc)) 400 if (uaddr_len < sizeof(struct sockaddr_tipc)) {
396 return -EINVAL; 401 res = -EINVAL;
397 if (addr->family != AF_TIPC) 402 goto exit;
398 return -EAFNOSUPPORT; 403 }
404 if (addr->family != AF_TIPC) {
405 res = -EAFNOSUPPORT;
406 goto exit;
407 }
399 408
400 if (addr->addrtype == TIPC_ADDR_NAME) 409 if (addr->addrtype == TIPC_ADDR_NAME)
401 addr->addr.nameseq.upper = addr->addr.nameseq.lower; 410 addr->addr.nameseq.upper = addr->addr.nameseq.lower;
402 else if (addr->addrtype != TIPC_ADDR_NAMESEQ) 411 else if (addr->addrtype != TIPC_ADDR_NAMESEQ) {
403 return -EAFNOSUPPORT; 412 res = -EAFNOSUPPORT;
413 goto exit;
414 }
404 415
405 if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && 416 if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) &&
406 (addr->addr.nameseq.type != TIPC_TOP_SRV) && 417 (addr->addr.nameseq.type != TIPC_TOP_SRV) &&
407 (addr->addr.nameseq.type != TIPC_CFG_SRV)) 418 (addr->addr.nameseq.type != TIPC_CFG_SRV)) {
408 return -EACCES; 419 res = -EACCES;
420 goto exit;
421 }
409 422
410 return (addr->scope > 0) ? 423 res = (addr->scope > 0) ?
411 tipc_publish(portref, addr->scope, &addr->addr.nameseq) : 424 tipc_publish(tport, addr->scope, &addr->addr.nameseq) :
412 tipc_withdraw(portref, -addr->scope, &addr->addr.nameseq); 425 tipc_withdraw(tport, -addr->scope, &addr->addr.nameseq);
426exit:
427 release_sock(sk);
428 return res;
413} 429}
414 430
415/** 431/**
@@ -622,13 +638,11 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
622 res = tipc_send2name(tport->ref, 638 res = tipc_send2name(tport->ref,
623 &dest->addr.name.name, 639 &dest->addr.name.name,
624 dest->addr.name.domain, 640 dest->addr.name.domain,
625 m->msg_iovlen,
626 m->msg_iov, 641 m->msg_iov,
627 total_len); 642 total_len);
628 } else if (dest->addrtype == TIPC_ADDR_ID) { 643 } else if (dest->addrtype == TIPC_ADDR_ID) {
629 res = tipc_send2port(tport->ref, 644 res = tipc_send2port(tport->ref,
630 &dest->addr.id, 645 &dest->addr.id,
631 m->msg_iovlen,
632 m->msg_iov, 646 m->msg_iov,
633 total_len); 647 total_len);
634 } else if (dest->addrtype == TIPC_ADDR_MCAST) { 648 } else if (dest->addrtype == TIPC_ADDR_MCAST) {
@@ -641,7 +655,6 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
641 break; 655 break;
642 res = tipc_multicast(tport->ref, 656 res = tipc_multicast(tport->ref,
643 &dest->addr.nameseq, 657 &dest->addr.nameseq,
644 m->msg_iovlen,
645 m->msg_iov, 658 m->msg_iov,
646 total_len); 659 total_len);
647 } 660 }
@@ -707,8 +720,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
707 break; 720 break;
708 } 721 }
709 722
710 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov, 723 res = tipc_send(tport->ref, m->msg_iov, total_len);
711 total_len);
712 if (likely(res != -ELINKCONG)) 724 if (likely(res != -ELINKCONG))
713 break; 725 break;
714 if (timeout_val <= 0L) { 726 if (timeout_val <= 0L) {
@@ -984,9 +996,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
984 goto exit; 996 goto exit;
985 } 997 }
986 998
987 /* will be updated in set_orig_addr() if needed */
988 m->msg_namelen = 0;
989
990 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); 999 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
991restart: 1000restart:
992 1001
@@ -1095,9 +1104,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1095 goto exit; 1104 goto exit;
1096 } 1105 }
1097 1106
1098 /* will be updated in set_orig_addr() if needed */
1099 m->msg_namelen = 0;
1100
1101 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); 1107 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1102 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); 1108 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1103 1109
@@ -1368,7 +1374,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1368 return TIPC_ERR_OVERLOAD; 1374 return TIPC_ERR_OVERLOAD;
1369 1375
1370 /* Enqueue message */ 1376 /* Enqueue message */
1371 TIPC_SKB_CB(buf)->handle = 0; 1377 TIPC_SKB_CB(buf)->handle = NULL;
1372 __skb_queue_tail(&sk->sk_receive_queue, buf); 1378 __skb_queue_tail(&sk->sk_receive_queue, buf);
1373 skb_set_owner_r(buf, sk); 1379 skb_set_owner_r(buf, sk);
1374 1380
@@ -1691,7 +1697,7 @@ restart:
1691 /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ 1697 /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */
1692 buf = __skb_dequeue(&sk->sk_receive_queue); 1698 buf = __skb_dequeue(&sk->sk_receive_queue);
1693 if (buf) { 1699 if (buf) {
1694 if (TIPC_SKB_CB(buf)->handle != 0) { 1700 if (TIPC_SKB_CB(buf)->handle != NULL) {
1695 kfree_skb(buf); 1701 kfree_skb(buf);
1696 goto restart; 1702 goto restart;
1697 } 1703 }