Skip to content

Commit 6e9feb3

Browse files
committed
Merge branch 'tipc-next'
Jon Maloy says: ==================== tipc: make connection setup more robust In this series we make a few improvements to the connection setup and probing mechanism, culminating in the last commit where we make it possible for a client socket to make multiple setup attempts in case it encounters receive buffer overflow at the listener socket. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents a337531 + 6787927 commit 6e9feb3

File tree

4 files changed

+190
-118
lines changed

4 files changed

+190
-118
lines changed

net/tipc/msg.c

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -499,61 +499,79 @@ bool tipc_msg_make_bundle(struct sk_buff **skb, struct tipc_msg *msg,
499499
/**
500500
* tipc_msg_reverse(): swap source and destination addresses and add error code
501501
* @own_node: originating node id for reversed message
502-
* @skb: buffer containing message to be reversed; may be replaced.
502+
* @skb: buffer containing message to be reversed; will be consumed
503503
* @err: error code to be set in message, if any
504-
* Consumes buffer at failure
504+
* Replaces consumed buffer with new one when successful
505505
* Returns true if success, otherwise false
506506
*/
507507
bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err)
508508
{
509509
struct sk_buff *_skb = *skb;
510-
struct tipc_msg *hdr;
511-
struct tipc_msg ohdr;
512-
int dlen;
510+
struct tipc_msg *_hdr, *hdr;
511+
int hlen, dlen;
513512

514513
if (skb_linearize(_skb))
515514
goto exit;
516-
hdr = buf_msg(_skb);
517-
dlen = min_t(uint, msg_data_sz(hdr), MAX_FORWARD_SIZE);
518-
if (msg_dest_droppable(hdr))
515+
_hdr = buf_msg(_skb);
516+
dlen = min_t(uint, msg_data_sz(_hdr), MAX_FORWARD_SIZE);
517+
hlen = msg_hdr_sz(_hdr);
518+
519+
if (msg_dest_droppable(_hdr))
519520
goto exit;
520-
if (msg_errcode(hdr))
521+
if (msg_errcode(_hdr))
521522
goto exit;
522523

523-
/* Take a copy of original header before altering message */
524-
memcpy(&ohdr, hdr, msg_hdr_sz(hdr));
525-
526-
/* Never return SHORT header; expand by replacing buffer if necessary */
527-
if (msg_short(hdr)) {
528-
*skb = tipc_buf_acquire(BASIC_H_SIZE + dlen, GFP_ATOMIC);
529-
if (!*skb)
530-
goto exit;
531-
memcpy((*skb)->data + BASIC_H_SIZE, msg_data(hdr), dlen);
532-
kfree_skb(_skb);
533-
_skb = *skb;
534-
hdr = buf_msg(_skb);
535-
memcpy(hdr, &ohdr, BASIC_H_SIZE);
536-
msg_set_hdr_sz(hdr, BASIC_H_SIZE);
537-
}
524+
/* Never return SHORT header */
525+
if (hlen == SHORT_H_SIZE)
526+
hlen = BASIC_H_SIZE;
527+
528+
/* Don't return data along with SYN+, - sender has a clone */
529+
if (msg_is_syn(_hdr) && err == TIPC_ERR_OVERLOAD)
530+
dlen = 0;
531+
532+
/* Allocate new buffer to return */
533+
*skb = tipc_buf_acquire(hlen + dlen, GFP_ATOMIC);
534+
if (!*skb)
535+
goto exit;
536+
memcpy((*skb)->data, _skb->data, msg_hdr_sz(_hdr));
537+
memcpy((*skb)->data + hlen, msg_data(_hdr), dlen);
538538

539-
/* Now reverse the concerned fields */
539+
/* Build reverse header in new buffer */
540+
hdr = buf_msg(*skb);
541+
msg_set_hdr_sz(hdr, hlen);
540542
msg_set_errcode(hdr, err);
541543
msg_set_non_seq(hdr, 0);
542-
msg_set_origport(hdr, msg_destport(&ohdr));
543-
msg_set_destport(hdr, msg_origport(&ohdr));
544-
msg_set_destnode(hdr, msg_prevnode(&ohdr));
544+
msg_set_origport(hdr, msg_destport(_hdr));
545+
msg_set_destport(hdr, msg_origport(_hdr));
546+
msg_set_destnode(hdr, msg_prevnode(_hdr));
545547
msg_set_prevnode(hdr, own_node);
546548
msg_set_orignode(hdr, own_node);
547-
msg_set_size(hdr, msg_hdr_sz(hdr) + dlen);
548-
skb_trim(_skb, msg_size(hdr));
549+
msg_set_size(hdr, hlen + dlen);
549550
skb_orphan(_skb);
551+
kfree_skb(_skb);
550552
return true;
551553
exit:
552554
kfree_skb(_skb);
553555
*skb = NULL;
554556
return false;
555557
}
556558

559+
bool tipc_msg_skb_clone(struct sk_buff_head *msg, struct sk_buff_head *cpy)
560+
{
561+
struct sk_buff *skb, *_skb;
562+
563+
skb_queue_walk(msg, skb) {
564+
_skb = skb_clone(skb, GFP_ATOMIC);
565+
if (!_skb) {
566+
__skb_queue_purge(cpy);
567+
pr_err_ratelimited("Failed to clone buffer chain\n");
568+
return false;
569+
}
570+
__skb_queue_tail(cpy, _skb);
571+
}
572+
return true;
573+
}
574+
557575
/**
558576
* tipc_msg_lookup_dest(): try to find new destination for named message
559577
* @skb: the buffer containing the message.

net/tipc/msg.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,16 @@ static inline void msg_set_non_seq(struct tipc_msg *m, u32 n)
216216
msg_set_bits(m, 0, 20, 1, n);
217217
}
218218

219+
static inline int msg_is_syn(struct tipc_msg *m)
220+
{
221+
return msg_bits(m, 0, 17, 1);
222+
}
223+
224+
static inline void msg_set_syn(struct tipc_msg *m, u32 d)
225+
{
226+
msg_set_bits(m, 0, 17, 1, d);
227+
}
228+
219229
static inline int msg_dest_droppable(struct tipc_msg *m)
220230
{
221231
return msg_bits(m, 0, 19, 1);
@@ -970,6 +980,7 @@ bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg,
970980
struct sk_buff_head *cpy);
971981
void __tipc_skb_queue_sorted(struct sk_buff_head *list, u16 seqno,
972982
struct sk_buff *skb);
983+
bool tipc_msg_skb_clone(struct sk_buff_head *msg, struct sk_buff_head *cpy);
973984

974985
static inline u16 buf_seqno(struct sk_buff *skb)
975986
{

net/tipc/node.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
/* Optional capabilities supported by this code version
4646
*/
4747
enum {
48+
TIPC_SYN_BIT = (1),
4849
TIPC_BCAST_SYNCH = (1 << 1),
4950
TIPC_BCAST_STATE_NACK = (1 << 2),
5051
TIPC_BLOCK_FLOWCTL = (1 << 3),
@@ -53,11 +54,12 @@ enum {
5354
TIPC_LINK_PROTO_SEQNO = (1 << 6)
5455
};
5556

56-
#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \
57-
TIPC_BCAST_STATE_NACK | \
58-
TIPC_BCAST_RCAST | \
59-
TIPC_BLOCK_FLOWCTL | \
60-
TIPC_NODE_ID128 | \
57+
#define TIPC_NODE_CAPABILITIES (TIPC_SYN_BIT | \
58+
TIPC_BCAST_SYNCH | \
59+
TIPC_BCAST_STATE_NACK | \
60+
TIPC_BCAST_RCAST | \
61+
TIPC_BLOCK_FLOWCTL | \
62+
TIPC_NODE_ID128 | \
6163
TIPC_LINK_PROTO_SEQNO)
6264
#define INVALID_BEARER_ID -1
6365

0 commit comments

Comments
 (0)