aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/port.c49
1 files changed, 24 insertions, 25 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 70ecdfdf6e3a..53118171b7e6 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -358,14 +358,10 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
358 struct sk_buff *rbuf; 358 struct sk_buff *rbuf;
359 struct tipc_msg *rmsg; 359 struct tipc_msg *rmsg;
360 int hdr_sz; 360 int hdr_sz;
361 u32 imp = msg_importance(msg); 361 u32 imp;
362 u32 data_sz = msg_data_sz(msg); 362 u32 data_sz = msg_data_sz(msg);
363 u32 src_node; 363 u32 src_node;
364 364 u32 rmsg_sz;
365 if (data_sz > MAX_REJECT_SIZE)
366 data_sz = MAX_REJECT_SIZE;
367 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE))
368 imp++;
369 365
370 /* discard rejected message if it shouldn't be returned to sender */ 366 /* discard rejected message if it shouldn't be returned to sender */
371 367
@@ -377,30 +373,33 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
377 if (msg_errcode(msg) || msg_dest_droppable(msg)) 373 if (msg_errcode(msg) || msg_dest_droppable(msg))
378 goto exit; 374 goto exit;
379 375
380 /* construct rejected message */ 376 /*
381 if (msg_mcast(msg)) 377 * construct returned message by copying rejected message header and
382 hdr_sz = MCAST_H_SIZE; 378 * data (or subset), then updating header fields that need adjusting
383 else 379 */
384 hdr_sz = LONG_H_SIZE; 380
385 rbuf = tipc_buf_acquire(data_sz + hdr_sz); 381 hdr_sz = msg_hdr_sz(msg);
382 rmsg_sz = hdr_sz + min_t(u32, data_sz, MAX_REJECT_SIZE);
383
384 rbuf = tipc_buf_acquire(rmsg_sz);
386 if (rbuf == NULL) 385 if (rbuf == NULL)
387 goto exit; 386 goto exit;
388 387
389 rmsg = buf_msg(rbuf); 388 rmsg = buf_msg(rbuf);
390 tipc_msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg)); 389 skb_copy_to_linear_data(rbuf, msg, rmsg_sz);
391 msg_set_errcode(rmsg, err); 390
392 msg_set_destport(rmsg, msg_origport(msg)); 391 if (msg_connected(rmsg)) {
393 msg_set_origport(rmsg, msg_destport(msg)); 392 imp = msg_importance(rmsg);
394 if (msg_short(msg)) { 393 if (imp < TIPC_CRITICAL_IMPORTANCE)
395 msg_set_orignode(rmsg, tipc_own_addr); 394 msg_set_importance(rmsg, ++imp);
396 /* leave name type & instance as zeroes */
397 } else {
398 msg_set_orignode(rmsg, msg_destnode(msg));
399 msg_set_nametype(rmsg, msg_nametype(msg));
400 msg_set_nameinst(rmsg, msg_nameinst(msg));
401 } 395 }
402 msg_set_size(rmsg, data_sz + hdr_sz); 396 msg_set_non_seq(rmsg, 0);
403 skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); 397 msg_set_size(rmsg, rmsg_sz);
398 msg_set_errcode(rmsg, err);
399 msg_set_prevnode(rmsg, tipc_own_addr);
400 msg_swap_words(rmsg, 4, 5);
401 if (!msg_short(rmsg))
402 msg_swap_words(rmsg, 6, 7);
404 403
405 /* send self-abort message when rejecting on a connected port */ 404 /* send self-abort message when rejecting on a connected port */
406 if (msg_connected(msg)) { 405 if (msg_connected(msg)) {