diff options
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r-- | net/tipc/msg.c | 86 |
1 files changed, 49 insertions, 37 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 08b4cc7d496d..562c926a51cc 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -463,60 +463,72 @@ bool tipc_msg_make_bundle(struct sk_buff **skb, struct tipc_msg *msg, | |||
463 | 463 | ||
464 | /** | 464 | /** |
465 | * tipc_msg_reverse(): swap source and destination addresses and add error code | 465 | * tipc_msg_reverse(): swap source and destination addresses and add error code |
466 | * @buf: buffer containing message to be reversed | 466 | * @own_node: originating node id for reversed message |
467 | * @dnode: return value: node where to send message after reversal | 467 | * @skb: buffer containing message to be reversed; may be replaced. |
468 | * @err: error code to be set in message | 468 | * @err: error code to be set in message, if any |
469 | * Consumes buffer if failure | 469 | * Consumes buffer at failure |
470 | * Returns true if success, otherwise false | 470 | * Returns true if success, otherwise false |
471 | */ | 471 | */ |
472 | bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode, | 472 | bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err) |
473 | int err) | ||
474 | { | 473 | { |
475 | struct tipc_msg *msg = buf_msg(buf); | 474 | struct sk_buff *_skb = *skb; |
475 | struct tipc_msg *hdr = buf_msg(_skb); | ||
476 | struct tipc_msg ohdr; | 476 | struct tipc_msg ohdr; |
477 | uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE); | 477 | int dlen = min_t(uint, msg_data_sz(hdr), MAX_FORWARD_SIZE); |
478 | 478 | ||
479 | if (skb_linearize(buf)) | 479 | if (skb_linearize(_skb)) |
480 | goto exit; | 480 | goto exit; |
481 | msg = buf_msg(buf); | 481 | hdr = buf_msg(_skb); |
482 | if (msg_dest_droppable(msg)) | 482 | if (msg_dest_droppable(hdr)) |
483 | goto exit; | 483 | goto exit; |
484 | if (msg_errcode(msg)) | 484 | if (msg_errcode(hdr)) |
485 | goto exit; | 485 | goto exit; |
486 | memcpy(&ohdr, msg, msg_hdr_sz(msg)); | 486 | |
487 | msg_set_errcode(msg, err); | 487 | /* Take a copy of original header before altering message */ |
488 | msg_set_origport(msg, msg_destport(&ohdr)); | 488 | memcpy(&ohdr, hdr, msg_hdr_sz(hdr)); |
489 | msg_set_destport(msg, msg_origport(&ohdr)); | 489 | |
490 | msg_set_prevnode(msg, own_addr); | 490 | /* Never return SHORT header; expand by replacing buffer if necessary */ |
491 | if (!msg_short(msg)) { | 491 | if (msg_short(hdr)) { |
492 | msg_set_orignode(msg, msg_destnode(&ohdr)); | 492 | *skb = tipc_buf_acquire(BASIC_H_SIZE + dlen); |
493 | msg_set_destnode(msg, msg_orignode(&ohdr)); | 493 | if (!*skb) |
494 | goto exit; | ||
495 | memcpy((*skb)->data + BASIC_H_SIZE, msg_data(hdr), dlen); | ||
496 | kfree_skb(_skb); | ||
497 | _skb = *skb; | ||
498 | hdr = buf_msg(_skb); | ||
499 | memcpy(hdr, &ohdr, BASIC_H_SIZE); | ||
500 | msg_set_hdr_sz(hdr, BASIC_H_SIZE); | ||
494 | } | 501 | } |
495 | msg_set_size(msg, msg_hdr_sz(msg) + rdsz); | 502 | |
496 | skb_trim(buf, msg_size(msg)); | 503 | /* Now reverse the concerned fields */ |
497 | skb_orphan(buf); | 504 | msg_set_errcode(hdr, err); |
498 | *dnode = msg_orignode(&ohdr); | 505 | msg_set_origport(hdr, msg_destport(&ohdr)); |
506 | msg_set_destport(hdr, msg_origport(&ohdr)); | ||
507 | msg_set_destnode(hdr, msg_prevnode(&ohdr)); | ||
508 | msg_set_prevnode(hdr, own_node); | ||
509 | msg_set_orignode(hdr, own_node); | ||
510 | msg_set_size(hdr, msg_hdr_sz(hdr) + dlen); | ||
511 | skb_trim(_skb, msg_size(hdr)); | ||
512 | skb_orphan(_skb); | ||
499 | return true; | 513 | return true; |
500 | exit: | 514 | exit: |
501 | kfree_skb(buf); | 515 | kfree_skb(_skb); |
502 | *dnode = 0; | 516 | *skb = NULL; |
503 | return false; | 517 | return false; |
504 | } | 518 | } |
505 | 519 | ||
506 | /** | 520 | /** |
507 | * tipc_msg_lookup_dest(): try to find new destination for named message | 521 | * tipc_msg_lookup_dest(): try to find new destination for named message |
508 | * @skb: the buffer containing the message. | 522 | * @skb: the buffer containing the message. |
509 | * @dnode: return value: next-hop node, if destination found | 523 | * @err: error code to be used by caller if lookup fails |
510 | * @err: return value: error code to use, if message to be rejected | ||
511 | * Does not consume buffer | 524 | * Does not consume buffer |
512 | * Returns true if a destination is found, false otherwise | 525 | * Returns true if a destination is found, false otherwise |
513 | */ | 526 | */ |
514 | bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, | 527 | bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err) |
515 | u32 *dnode, int *err) | ||
516 | { | 528 | { |
517 | struct tipc_msg *msg = buf_msg(skb); | 529 | struct tipc_msg *msg = buf_msg(skb); |
518 | u32 dport; | 530 | u32 dport, dnode; |
519 | u32 own_addr = tipc_own_addr(net); | 531 | u32 onode = tipc_own_addr(net); |
520 | 532 | ||
521 | if (!msg_isdata(msg)) | 533 | if (!msg_isdata(msg)) |
522 | return false; | 534 | return false; |
@@ -529,15 +541,15 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, | |||
529 | return false; | 541 | return false; |
530 | if (msg_reroute_cnt(msg)) | 542 | if (msg_reroute_cnt(msg)) |
531 | return false; | 543 | return false; |
532 | *dnode = addr_domain(net, msg_lookup_scope(msg)); | 544 | dnode = addr_domain(net, msg_lookup_scope(msg)); |
533 | dport = tipc_nametbl_translate(net, msg_nametype(msg), | 545 | dport = tipc_nametbl_translate(net, msg_nametype(msg), |
534 | msg_nameinst(msg), dnode); | 546 | msg_nameinst(msg), &dnode); |
535 | if (!dport) | 547 | if (!dport) |
536 | return false; | 548 | return false; |
537 | msg_incr_reroute_cnt(msg); | 549 | msg_incr_reroute_cnt(msg); |
538 | if (*dnode != own_addr) | 550 | if (dnode != onode) |
539 | msg_set_prevnode(msg, own_addr); | 551 | msg_set_prevnode(msg, onode); |
540 | msg_set_destnode(msg, *dnode); | 552 | msg_set_destnode(msg, dnode); |
541 | msg_set_destport(msg, dport); | 553 | msg_set_destport(msg, dport); |
542 | *err = TIPC_OK; | 554 | *err = TIPC_OK; |
543 | return true; | 555 | return true; |