Skip to content

Commit 37e2216

Browse files
Jon Paul Maloydavem330
authored andcommitted
tipc: rename and move message reassembly function
The function tipc_link_frag_rcv() is in reality a re-entrant generic message reassemby function that has nothing in particular to do with the link, where it is defined now. This becomes obvious when we see the need to call the function from other places in the code. In this commit rename it to tipc_buf_append() and move it to the file msg.c. We also simplify its signature by moving the tail pointer to the control block of the head buffer, hence making the head buffer self-contained. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 5074ab8 commit 37e2216

File tree

8 files changed

+74
-91
lines changed

8 files changed

+74
-91
lines changed

net/tipc/bcast.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -506,18 +506,14 @@ void tipc_bclink_rcv(struct sk_buff *buf)
506506
tipc_node_unlock(node);
507507
tipc_link_bundle_rcv(buf);
508508
} else if (msg_user(msg) == MSG_FRAGMENTER) {
509-
int ret;
510-
ret = tipc_link_frag_rcv(&node->bclink.reasm_head,
511-
&node->bclink.reasm_tail,
512-
&buf);
513-
if (ret == LINK_REASM_ERROR)
509+
tipc_buf_append(&node->bclink.reasm_buf, &buf);
510+
if (unlikely(!buf && !node->bclink.reasm_buf))
514511
goto unlock;
515512
tipc_bclink_lock();
516513
bclink_accept_pkt(node, seqno);
517514
bcl->stats.recv_fragments++;
518-
if (ret == LINK_REASM_COMPLETE) {
515+
if (buf) {
519516
bcl->stats.recv_fragmented++;
520-
/* Point msg to inner header */
521517
msg = buf_msg(buf);
522518
tipc_bclink_unlock();
523519
goto receive;

net/tipc/core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ static inline void k_term_timer(struct timer_list *timer)
187187
struct tipc_skb_cb {
188188
void *handle;
189189
bool deferred;
190+
struct sk_buff *tail;
190191
};
191192

192193
#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0]))

net/tipc/link.c

Lines changed: 5 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,8 @@ static void link_release_outqueue(struct tipc_link *l_ptr)
398398
*/
399399
void tipc_link_reset_fragments(struct tipc_link *l_ptr)
400400
{
401-
kfree_skb(l_ptr->reasm_head);
402-
l_ptr->reasm_head = NULL;
403-
l_ptr->reasm_tail = NULL;
401+
kfree_skb(l_ptr->reasm_buf);
402+
l_ptr->reasm_buf = NULL;
404403
}
405404

406405
/**
@@ -1573,17 +1572,12 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
15731572
}
15741573
msg = buf_msg(buf);
15751574
} else if (msg_user(msg) == MSG_FRAGMENTER) {
1576-
int rc;
1577-
15781575
l_ptr->stats.recv_fragments++;
1579-
rc = tipc_link_frag_rcv(&l_ptr->reasm_head,
1580-
&l_ptr->reasm_tail,
1581-
&buf);
1582-
if (rc == LINK_REASM_COMPLETE) {
1576+
if (tipc_buf_append(&l_ptr->reasm_buf, &buf)) {
15831577
l_ptr->stats.recv_fragmented++;
15841578
msg = buf_msg(buf);
15851579
} else {
1586-
if (rc == LINK_REASM_ERROR)
1580+
if (!l_ptr->reasm_buf)
15871581
tipc_link_reset(l_ptr);
15881582
tipc_node_unlock(n_ptr);
15891583
continue;
@@ -2169,9 +2163,7 @@ static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr,
21692163
}
21702164
if (msg_user(msg) == MSG_FRAGMENTER) {
21712165
l_ptr->stats.recv_fragments++;
2172-
tipc_link_frag_rcv(&l_ptr->reasm_head,
2173-
&l_ptr->reasm_tail,
2174-
&buf);
2166+
tipc_buf_append(&l_ptr->reasm_buf, &buf);
21752167
}
21762168
}
21772169
exit:
@@ -2309,55 +2301,6 @@ static int tipc_link_frag_xmit(struct tipc_link *l_ptr, struct sk_buff *buf)
23092301
return dsz;
23102302
}
23112303

2312-
/* tipc_link_frag_rcv(): Called with node lock on. Returns
2313-
* the reassembled buffer if message is complete.
2314-
*/
2315-
int tipc_link_frag_rcv(struct sk_buff **head, struct sk_buff **tail,
2316-
struct sk_buff **fbuf)
2317-
{
2318-
struct sk_buff *frag = *fbuf;
2319-
struct tipc_msg *msg = buf_msg(frag);
2320-
u32 fragid = msg_type(msg);
2321-
bool headstolen;
2322-
int delta;
2323-
2324-
skb_pull(frag, msg_hdr_sz(msg));
2325-
if (fragid == FIRST_FRAGMENT) {
2326-
if (*head || skb_unclone(frag, GFP_ATOMIC))
2327-
goto out_free;
2328-
*head = frag;
2329-
skb_frag_list_init(*head);
2330-
*fbuf = NULL;
2331-
return 0;
2332-
} else if (*head &&
2333-
skb_try_coalesce(*head, frag, &headstolen, &delta)) {
2334-
kfree_skb_partial(frag, headstolen);
2335-
} else {
2336-
if (!*head)
2337-
goto out_free;
2338-
if (!skb_has_frag_list(*head))
2339-
skb_shinfo(*head)->frag_list = frag;
2340-
else
2341-
(*tail)->next = frag;
2342-
*tail = frag;
2343-
(*head)->truesize += frag->truesize;
2344-
(*head)->data_len += frag->len;
2345-
(*head)->len += frag->len;
2346-
}
2347-
if (fragid == LAST_FRAGMENT) {
2348-
*fbuf = *head;
2349-
*tail = *head = NULL;
2350-
return LINK_REASM_COMPLETE;
2351-
}
2352-
*fbuf = NULL;
2353-
return 0;
2354-
out_free:
2355-
pr_warn_ratelimited("Link unable to reassemble fragmented message\n");
2356-
kfree_skb(*fbuf);
2357-
*fbuf = NULL;
2358-
return LINK_REASM_ERROR;
2359-
}
2360-
23612304
static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance)
23622305
{
23632306
if ((tolerance < TIPC_MIN_LINK_TOL) || (tolerance > TIPC_MAX_LINK_TOL))

net/tipc/link.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@
4040
#include "msg.h"
4141
#include "node.h"
4242

43-
/* Link reassembly status codes
44-
*/
45-
#define LINK_REASM_ERROR -1
46-
#define LINK_REASM_COMPLETE 1
47-
4843
/* Out-of-range value for link sequence numbers
4944
*/
5045
#define INVALID_LINK_SEQ 0x10000
@@ -140,8 +135,7 @@ struct tipc_stats {
140135
* @next_out: ptr to first unsent outbound message in queue
141136
* @waiting_ports: linked list of ports waiting for link congestion to abate
142137
* @long_msg_seq_no: next identifier to use for outbound fragmented messages
143-
* @reasm_head: list head of partially reassembled inbound message fragments
144-
* @reasm_tail: last fragment received
138+
* @reasm_buf: head of partially reassembled inbound message fragments
145139
* @stats: collects statistics regarding link activity
146140
*/
147141
struct tipc_link {
@@ -204,8 +198,7 @@ struct tipc_link {
204198

205199
/* Fragmentation/reassembly */
206200
u32 long_msg_seq_no;
207-
struct sk_buff *reasm_head;
208-
struct sk_buff *reasm_tail;
201+
struct sk_buff *reasm_buf;
209202

210203
/* Statistics */
211204
struct tipc_stats stats;
@@ -242,9 +235,6 @@ int tipc_link_iovec_xmit_fast(struct tipc_port *sender,
242235
struct iovec const *msg_sect,
243236
unsigned int len, u32 destnode);
244237
void tipc_link_bundle_rcv(struct sk_buff *buf);
245-
int tipc_link_frag_rcv(struct sk_buff **reasm_head,
246-
struct sk_buff **reasm_tail,
247-
struct sk_buff **fbuf);
248238
void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob,
249239
u32 gap, u32 tolerance, u32 priority, u32 acked_mtu);
250240
void tipc_link_push_queue(struct tipc_link *l_ptr);

net/tipc/msg.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* net/tipc/msg.c: TIPC message header routines
33
*
4-
* Copyright (c) 2000-2006, Ericsson AB
4+
* Copyright (c) 2000-2006, 2014, Ericsson AB
55
* Copyright (c) 2005, 2010-2011, Wind River Systems
66
* All rights reserved.
77
*
@@ -99,3 +99,56 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
9999
}
100100
return dsz;
101101
}
102+
103+
/* tipc_buf_append(): Append a buffer to the fragment list of another buffer
104+
* Let first buffer become head buffer
105+
* Returns 1 and sets *buf to headbuf if chain is complete, otherwise 0
106+
* Leaves headbuf pointer at NULL if failure
107+
*/
108+
int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
109+
{
110+
struct sk_buff *head = *headbuf;
111+
struct sk_buff *frag = *buf;
112+
struct sk_buff *tail;
113+
struct tipc_msg *msg = buf_msg(frag);
114+
u32 fragid = msg_type(msg);
115+
bool headstolen;
116+
int delta;
117+
118+
skb_pull(frag, msg_hdr_sz(msg));
119+
120+
if (fragid == FIRST_FRAGMENT) {
121+
if (head || skb_unclone(frag, GFP_ATOMIC))
122+
goto out_free;
123+
head = *headbuf = frag;
124+
skb_frag_list_init(head);
125+
return 0;
126+
}
127+
if (!head)
128+
goto out_free;
129+
tail = TIPC_SKB_CB(head)->tail;
130+
if (skb_try_coalesce(head, frag, &headstolen, &delta)) {
131+
kfree_skb_partial(frag, headstolen);
132+
} else {
133+
if (!skb_has_frag_list(head))
134+
skb_shinfo(head)->frag_list = frag;
135+
else
136+
tail->next = frag;
137+
head->truesize += frag->truesize;
138+
head->data_len += frag->len;
139+
head->len += frag->len;
140+
TIPC_SKB_CB(head)->tail = frag;
141+
}
142+
if (fragid == LAST_FRAGMENT) {
143+
*buf = head;
144+
TIPC_SKB_CB(head)->tail = NULL;
145+
*headbuf = NULL;
146+
return 1;
147+
}
148+
*buf = NULL;
149+
return 0;
150+
out_free:
151+
pr_warn_ratelimited("Unable to build fragment list\n");
152+
kfree_skb(*buf);
153+
return 0;
154+
}

net/tipc/msg.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* net/tipc/msg.h: Include file for TIPC message header routines
33
*
4-
* Copyright (c) 2000-2007, Ericsson AB
4+
* Copyright (c) 2000-2007, 2014, Ericsson AB
55
* Copyright (c) 2005-2008, 2010-2011, Wind River Systems
66
* All rights reserved.
77
*
@@ -711,4 +711,7 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
711711
u32 destnode);
712712
int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
713713
unsigned int len, int max_size, struct sk_buff **buf);
714+
715+
int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
716+
714717
#endif

net/tipc/node.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,9 @@ static void node_lost_contact(struct tipc_node *n_ptr)
286286
kfree_skb_list(n_ptr->bclink.deferred_head);
287287
n_ptr->bclink.deferred_size = 0;
288288

289-
if (n_ptr->bclink.reasm_head) {
290-
kfree_skb(n_ptr->bclink.reasm_head);
291-
n_ptr->bclink.reasm_head = NULL;
292-
n_ptr->bclink.reasm_tail = NULL;
289+
if (n_ptr->bclink.reasm_buf) {
290+
kfree_skb(n_ptr->bclink.reasm_buf);
291+
n_ptr->bclink.reasm_buf = NULL;
293292
}
294293

295294
tipc_bclink_remove_node(n_ptr->addr);

net/tipc/node.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ enum {
6969
* @deferred_size: number of OOS b'cast messages in deferred queue
7070
* @deferred_head: oldest OOS b'cast message received from node
7171
* @deferred_tail: newest OOS b'cast message received from node
72-
* @reasm_head: broadcast reassembly queue head from node
73-
* @reasm_tail: last broadcast fragment received from node
72+
* @reasm_buf: broadcast reassembly queue head from node
7473
* @recv_permitted: true if node is allowed to receive b'cast messages
7574
*/
7675
struct tipc_node_bclink {
@@ -81,8 +80,7 @@ struct tipc_node_bclink {
8180
u32 deferred_size;
8281
struct sk_buff *deferred_head;
8382
struct sk_buff *deferred_tail;
84-
struct sk_buff *reasm_head;
85-
struct sk_buff *reasm_tail;
83+
struct sk_buff *reasm_buf;
8684
bool recv_permitted;
8785
};
8886

0 commit comments

Comments
 (0)