• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * net/tipc/msg.c: TIPC message header routines
3  *
4  * Copyright (c) 2000-2006, 2014-2015, Ericsson AB
5  * Copyright (c) 2005, 2010-2011, Wind River Systems
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the names of the copyright holders nor the names of its
17  *    contributors may be used to endorse or promote products derived from
18  *    this software without specific prior written permission.
19  *
20  * Alternatively, this software may be distributed under the terms of the
21  * GNU General Public License ("GPL") version 2 as published by the Free
22  * Software Foundation.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 #include <net/sock.h>
38 #include "core.h"
39 #include "msg.h"
40 #include "addr.h"
41 #include "name_table.h"
42 
43 #define MAX_FORWARD_SIZE 1024
44 #define BUF_HEADROOM (LL_MAX_HEADER + 48)
45 #define BUF_TAILROOM 16
46 
align(unsigned int i)47 static unsigned int align(unsigned int i)
48 {
49 	return (i + 3) & ~3u;
50 }
51 
52 /**
53  * tipc_buf_acquire - creates a TIPC message buffer
54  * @size: message size (including TIPC header)
55  *
56  * Returns a new buffer with data pointers set to the specified size.
57  *
58  * NOTE: Headroom is reserved to allow prepending of a data link header.
59  *       There may also be unrequested tailroom present at the buffer's end.
60  */
tipc_buf_acquire(u32 size,gfp_t gfp)61 struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp)
62 {
63 	struct sk_buff *skb;
64 	unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
65 
66 	skb = alloc_skb_fclone(buf_size, gfp);
67 	if (skb) {
68 		skb_reserve(skb, BUF_HEADROOM);
69 		skb_put(skb, size);
70 		skb->next = NULL;
71 	}
72 	return skb;
73 }
74 
tipc_msg_init(u32 own_node,struct tipc_msg * m,u32 user,u32 type,u32 hsize,u32 dnode)75 void tipc_msg_init(u32 own_node, struct tipc_msg *m, u32 user, u32 type,
76 		   u32 hsize, u32 dnode)
77 {
78 	memset(m, 0, hsize);
79 	msg_set_version(m);
80 	msg_set_user(m, user);
81 	msg_set_hdr_sz(m, hsize);
82 	msg_set_size(m, hsize);
83 	msg_set_prevnode(m, own_node);
84 	msg_set_type(m, type);
85 	if (hsize > SHORT_H_SIZE) {
86 		msg_set_orignode(m, own_node);
87 		msg_set_destnode(m, dnode);
88 	}
89 }
90 
tipc_msg_create(uint user,uint type,uint hdr_sz,uint data_sz,u32 dnode,u32 onode,u32 dport,u32 oport,int errcode)91 struct sk_buff *tipc_msg_create(uint user, uint type,
92 				uint hdr_sz, uint data_sz, u32 dnode,
93 				u32 onode, u32 dport, u32 oport, int errcode)
94 {
95 	struct tipc_msg *msg;
96 	struct sk_buff *buf;
97 
98 	buf = tipc_buf_acquire(hdr_sz + data_sz, GFP_ATOMIC);
99 	if (unlikely(!buf))
100 		return NULL;
101 
102 	msg = buf_msg(buf);
103 	tipc_msg_init(onode, msg, user, type, hdr_sz, dnode);
104 	msg_set_size(msg, hdr_sz + data_sz);
105 	msg_set_origport(msg, oport);
106 	msg_set_destport(msg, dport);
107 	msg_set_errcode(msg, errcode);
108 	if (hdr_sz > SHORT_H_SIZE) {
109 		msg_set_orignode(msg, onode);
110 		msg_set_destnode(msg, dnode);
111 	}
112 	return buf;
113 }
114 
115 /* tipc_buf_append(): Append a buffer to the fragment list of another buffer
116  * @*headbuf: in:  NULL for first frag, otherwise value returned from prev call
117  *            out: set when successful non-complete reassembly, otherwise NULL
118  * @*buf:     in:  the buffer to append. Always defined
119  *            out: head buf after successful complete reassembly, otherwise NULL
120  * Returns 1 when reassembly complete, otherwise 0
121  */
tipc_buf_append(struct sk_buff ** headbuf,struct sk_buff ** buf)122 int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
123 {
124 	struct sk_buff *head = *headbuf;
125 	struct sk_buff *frag = *buf;
126 	struct sk_buff *tail = NULL;
127 	struct tipc_msg *msg;
128 	u32 fragid;
129 	int delta;
130 	bool headstolen;
131 
132 	if (!frag)
133 		goto err;
134 
135 	msg = buf_msg(frag);
136 	fragid = msg_type(msg);
137 	frag->next = NULL;
138 	skb_pull(frag, msg_hdr_sz(msg));
139 
140 	if (fragid == FIRST_FRAGMENT) {
141 		if (unlikely(head))
142 			goto err;
143 		*buf = NULL;
144 		frag = skb_unshare(frag, GFP_ATOMIC);
145 		if (unlikely(!frag))
146 			goto err;
147 		head = *headbuf = frag;
148 		TIPC_SKB_CB(head)->tail = NULL;
149 		if (skb_is_nonlinear(head)) {
150 			skb_walk_frags(head, tail) {
151 				TIPC_SKB_CB(head)->tail = tail;
152 			}
153 		} else {
154 			skb_frag_list_init(head);
155 		}
156 		return 0;
157 	}
158 
159 	if (!head)
160 		goto err;
161 
162 	if (skb_try_coalesce(head, frag, &headstolen, &delta)) {
163 		kfree_skb_partial(frag, headstolen);
164 	} else {
165 		tail = TIPC_SKB_CB(head)->tail;
166 		if (!skb_has_frag_list(head))
167 			skb_shinfo(head)->frag_list = frag;
168 		else
169 			tail->next = frag;
170 		head->truesize += frag->truesize;
171 		head->data_len += frag->len;
172 		head->len += frag->len;
173 		TIPC_SKB_CB(head)->tail = frag;
174 	}
175 
176 	if (fragid == LAST_FRAGMENT) {
177 		TIPC_SKB_CB(head)->validated = false;
178 		if (unlikely(!tipc_msg_validate(&head)))
179 			goto err;
180 		*buf = head;
181 		TIPC_SKB_CB(head)->tail = NULL;
182 		*headbuf = NULL;
183 		return 1;
184 	}
185 	*buf = NULL;
186 	return 0;
187 err:
188 	kfree_skb(*buf);
189 	kfree_skb(*headbuf);
190 	*buf = *headbuf = NULL;
191 	return 0;
192 }
193 
194 /* tipc_msg_validate - validate basic format of received message
195  *
196  * This routine ensures a TIPC message has an acceptable header, and at least
197  * as much data as the header indicates it should.  The routine also ensures
198  * that the entire message header is stored in the main fragment of the message
199  * buffer, to simplify future access to message header fields.
200  *
201  * Note: Having extra info present in the message header or data areas is OK.
202  * TIPC will ignore the excess, under the assumption that it is optional info
203  * introduced by a later release of the protocol.
204  */
tipc_msg_validate(struct sk_buff ** _skb)205 bool tipc_msg_validate(struct sk_buff **_skb)
206 {
207 	struct sk_buff *skb = *_skb;
208 	struct tipc_msg *hdr;
209 	int msz, hsz;
210 
211 	/* Ensure that flow control ratio condition is satisfied */
212 	if (unlikely(skb->truesize / buf_roundup_len(skb) >= 4)) {
213 		skb = skb_copy_expand(skb, BUF_HEADROOM, 0, GFP_ATOMIC);
214 		if (!skb)
215 			return false;
216 		kfree_skb(*_skb);
217 		*_skb = skb;
218 	}
219 
220 	if (unlikely(TIPC_SKB_CB(skb)->validated))
221 		return true;
222 	if (unlikely(!pskb_may_pull(skb, MIN_H_SIZE)))
223 		return false;
224 
225 	hsz = msg_hdr_sz(buf_msg(skb));
226 	if (unlikely(hsz < MIN_H_SIZE) || (hsz > MAX_H_SIZE))
227 		return false;
228 	if (unlikely(!pskb_may_pull(skb, hsz)))
229 		return false;
230 
231 	hdr = buf_msg(skb);
232 	if (unlikely(msg_version(hdr) != TIPC_VERSION))
233 		return false;
234 
235 	msz = msg_size(hdr);
236 	if (unlikely(msz < hsz))
237 		return false;
238 	if (unlikely((msz - hsz) > TIPC_MAX_USER_MSG_SIZE))
239 		return false;
240 	if (unlikely(skb->len < msz))
241 		return false;
242 
243 	TIPC_SKB_CB(skb)->validated = true;
244 	return true;
245 }
246 
247 /**
248  * tipc_msg_build - create buffer chain containing specified header and data
249  * @mhdr: Message header, to be prepended to data
250  * @m: User message
251  * @dsz: Total length of user data
252  * @pktmax: Max packet size that can be used
253  * @list: Buffer or chain of buffers to be returned to caller
254  *
255  * Note that the recursive call we are making here is safe, since it can
256  * logically go only one further level down.
257  *
258  * Returns message data size or errno: -ENOMEM, -EFAULT
259  */
tipc_msg_build(struct tipc_msg * mhdr,struct msghdr * m,int offset,int dsz,int pktmax,struct sk_buff_head * list)260 int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
261 		   int dsz, int pktmax, struct sk_buff_head *list)
262 {
263 	int mhsz = msg_hdr_sz(mhdr);
264 	struct tipc_msg pkthdr;
265 	int msz = mhsz + dsz;
266 	int pktrem = pktmax;
267 	struct sk_buff *skb;
268 	int drem = dsz;
269 	int pktno = 1;
270 	char *pktpos;
271 	int pktsz;
272 	int rc;
273 
274 	msg_set_size(mhdr, msz);
275 
276 	/* No fragmentation needed? */
277 	if (likely(msz <= pktmax)) {
278 		skb = tipc_buf_acquire(msz, GFP_KERNEL);
279 
280 		/* Fall back to smaller MTU if node local message */
281 		if (unlikely(!skb)) {
282 			if (pktmax != MAX_MSG_SIZE)
283 				return -ENOMEM;
284 			rc = tipc_msg_build(mhdr, m, offset, dsz, FB_MTU, list);
285 			if (rc != dsz)
286 				return rc;
287 			if (tipc_msg_assemble(list))
288 				return dsz;
289 			return -ENOMEM;
290 		}
291 		skb_orphan(skb);
292 		__skb_queue_tail(list, skb);
293 		skb_copy_to_linear_data(skb, mhdr, mhsz);
294 		pktpos = skb->data + mhsz;
295 		if (copy_from_iter_full(pktpos, dsz, &m->msg_iter))
296 			return dsz;
297 		rc = -EFAULT;
298 		goto error;
299 	}
300 
301 	/* Prepare reusable fragment header */
302 	tipc_msg_init(msg_prevnode(mhdr), &pkthdr, MSG_FRAGMENTER,
303 		      FIRST_FRAGMENT, INT_H_SIZE, msg_destnode(mhdr));
304 	msg_set_size(&pkthdr, pktmax);
305 	msg_set_fragm_no(&pkthdr, pktno);
306 	msg_set_importance(&pkthdr, msg_importance(mhdr));
307 
308 	/* Prepare first fragment */
309 	skb = tipc_buf_acquire(pktmax, GFP_KERNEL);
310 	if (!skb)
311 		return -ENOMEM;
312 	skb_orphan(skb);
313 	__skb_queue_tail(list, skb);
314 	pktpos = skb->data;
315 	skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE);
316 	pktpos += INT_H_SIZE;
317 	pktrem -= INT_H_SIZE;
318 	skb_copy_to_linear_data_offset(skb, INT_H_SIZE, mhdr, mhsz);
319 	pktpos += mhsz;
320 	pktrem -= mhsz;
321 
322 	do {
323 		if (drem < pktrem)
324 			pktrem = drem;
325 
326 		if (!copy_from_iter_full(pktpos, pktrem, &m->msg_iter)) {
327 			rc = -EFAULT;
328 			goto error;
329 		}
330 		drem -= pktrem;
331 
332 		if (!drem)
333 			break;
334 
335 		/* Prepare new fragment: */
336 		if (drem < (pktmax - INT_H_SIZE))
337 			pktsz = drem + INT_H_SIZE;
338 		else
339 			pktsz = pktmax;
340 		skb = tipc_buf_acquire(pktsz, GFP_KERNEL);
341 		if (!skb) {
342 			rc = -ENOMEM;
343 			goto error;
344 		}
345 		skb_orphan(skb);
346 		__skb_queue_tail(list, skb);
347 		msg_set_type(&pkthdr, FRAGMENT);
348 		msg_set_size(&pkthdr, pktsz);
349 		msg_set_fragm_no(&pkthdr, ++pktno);
350 		skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE);
351 		pktpos = skb->data + INT_H_SIZE;
352 		pktrem = pktsz - INT_H_SIZE;
353 
354 	} while (1);
355 	msg_set_type(buf_msg(skb), LAST_FRAGMENT);
356 	return dsz;
357 error:
358 	__skb_queue_purge(list);
359 	__skb_queue_head_init(list);
360 	return rc;
361 }
362 
363 /**
364  * tipc_msg_bundle(): Append contents of a buffer to tail of an existing one
365  * @skb: the buffer to append to ("bundle")
366  * @msg:  message to be appended
367  * @mtu:  max allowable size for the bundle buffer
368  * Consumes buffer if successful
369  * Returns true if bundling could be performed, otherwise false
370  */
tipc_msg_bundle(struct sk_buff * skb,struct tipc_msg * msg,u32 mtu)371 bool tipc_msg_bundle(struct sk_buff *skb, struct tipc_msg *msg, u32 mtu)
372 {
373 	struct tipc_msg *bmsg;
374 	unsigned int bsz;
375 	unsigned int msz = msg_size(msg);
376 	u32 start, pad;
377 	u32 max = mtu - INT_H_SIZE;
378 
379 	if (likely(msg_user(msg) == MSG_FRAGMENTER))
380 		return false;
381 	if (!skb)
382 		return false;
383 	bmsg = buf_msg(skb);
384 	bsz = msg_size(bmsg);
385 	start = align(bsz);
386 	pad = start - bsz;
387 
388 	if (unlikely(msg_user(msg) == TUNNEL_PROTOCOL))
389 		return false;
390 	if (unlikely(msg_user(msg) == BCAST_PROTOCOL))
391 		return false;
392 	if (unlikely(msg_user(bmsg) != MSG_BUNDLER))
393 		return false;
394 	if (unlikely(skb_tailroom(skb) < (pad + msz)))
395 		return false;
396 	if (unlikely(max < (start + msz)))
397 		return false;
398 	if ((msg_importance(msg) < TIPC_SYSTEM_IMPORTANCE) &&
399 	    (msg_importance(bmsg) == TIPC_SYSTEM_IMPORTANCE))
400 		return false;
401 
402 	skb_put(skb, pad + msz);
403 	skb_copy_to_linear_data_offset(skb, start, msg, msz);
404 	msg_set_size(bmsg, start + msz);
405 	msg_set_msgcnt(bmsg, msg_msgcnt(bmsg) + 1);
406 	return true;
407 }
408 
409 /**
410  *  tipc_msg_extract(): extract bundled inner packet from buffer
411  *  @skb: buffer to be extracted from.
412  *  @iskb: extracted inner buffer, to be returned
413  *  @pos: position in outer message of msg to be extracted.
414  *        Returns position of next msg
415  *  Consumes outer buffer when last packet extracted
416  *  Returns true when when there is an extracted buffer, otherwise false
417  */
tipc_msg_extract(struct sk_buff * skb,struct sk_buff ** iskb,int * pos)418 bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos)
419 {
420 	struct tipc_msg *hdr, *ihdr;
421 	int imsz;
422 
423 	*iskb = NULL;
424 	if (unlikely(skb_linearize(skb)))
425 		goto none;
426 
427 	hdr = buf_msg(skb);
428 	if (unlikely(*pos > (msg_data_sz(hdr) - MIN_H_SIZE)))
429 		goto none;
430 
431 	ihdr = (struct tipc_msg *)(msg_data(hdr) + *pos);
432 	imsz = msg_size(ihdr);
433 
434 	if ((*pos + imsz) > msg_data_sz(hdr))
435 		goto none;
436 
437 	*iskb = tipc_buf_acquire(imsz, GFP_ATOMIC);
438 	if (!*iskb)
439 		goto none;
440 
441 	skb_copy_to_linear_data(*iskb, ihdr, imsz);
442 	if (unlikely(!tipc_msg_validate(iskb)))
443 		goto none;
444 
445 	*pos += align(imsz);
446 	return true;
447 none:
448 	kfree_skb(skb);
449 	kfree_skb(*iskb);
450 	*iskb = NULL;
451 	return false;
452 }
453 
454 /**
455  * tipc_msg_make_bundle(): Create bundle buf and append message to its tail
456  * @list: the buffer chain, where head is the buffer to replace/append
457  * @skb: buffer to be created, appended to and returned in case of success
458  * @msg: message to be appended
459  * @mtu: max allowable size for the bundle buffer, inclusive header
460  * @dnode: destination node for message. (Not always present in header)
461  * Returns true if success, otherwise false
462  */
tipc_msg_make_bundle(struct sk_buff ** skb,struct tipc_msg * msg,u32 mtu,u32 dnode)463 bool tipc_msg_make_bundle(struct sk_buff **skb,  struct tipc_msg *msg,
464 			  u32 mtu, u32 dnode)
465 {
466 	struct sk_buff *_skb;
467 	struct tipc_msg *bmsg;
468 	u32 msz = msg_size(msg);
469 	u32 max = mtu - INT_H_SIZE;
470 
471 	if (msg_user(msg) == MSG_FRAGMENTER)
472 		return false;
473 	if (msg_user(msg) == TUNNEL_PROTOCOL)
474 		return false;
475 	if (msg_user(msg) == BCAST_PROTOCOL)
476 		return false;
477 	if (msz > (max / 2))
478 		return false;
479 
480 	_skb = tipc_buf_acquire(max, GFP_ATOMIC);
481 	if (!_skb)
482 		return false;
483 
484 	skb_trim(_skb, INT_H_SIZE);
485 	bmsg = buf_msg(_skb);
486 	tipc_msg_init(msg_prevnode(msg), bmsg, MSG_BUNDLER, 0,
487 		      INT_H_SIZE, dnode);
488 	msg_set_importance(bmsg, msg_importance(msg));
489 	msg_set_seqno(bmsg, msg_seqno(msg));
490 	msg_set_ack(bmsg, msg_ack(msg));
491 	msg_set_bcast_ack(bmsg, msg_bcast_ack(msg));
492 	tipc_msg_bundle(_skb, msg, mtu);
493 	*skb = _skb;
494 	return true;
495 }
496 
497 /**
498  * tipc_msg_reverse(): swap source and destination addresses and add error code
499  * @own_node: originating node id for reversed message
500  * @skb:  buffer containing message to be reversed; may be replaced.
501  * @err:  error code to be set in message, if any
502  * Consumes buffer at failure
503  * Returns true if success, otherwise false
504  */
tipc_msg_reverse(u32 own_node,struct sk_buff ** skb,int err)505 bool tipc_msg_reverse(u32 own_node,  struct sk_buff **skb, int err)
506 {
507 	struct sk_buff *_skb = *skb;
508 	struct tipc_msg *hdr;
509 	struct tipc_msg ohdr;
510 	int dlen;
511 
512 	if (skb_linearize(_skb))
513 		goto exit;
514 	hdr = buf_msg(_skb);
515 	dlen = min_t(uint, msg_data_sz(hdr), MAX_FORWARD_SIZE);
516 	if (msg_dest_droppable(hdr))
517 		goto exit;
518 	if (msg_errcode(hdr))
519 		goto exit;
520 
521 	/* Take a copy of original header before altering message */
522 	memcpy(&ohdr, hdr, msg_hdr_sz(hdr));
523 
524 	/* Never return SHORT header; expand by replacing buffer if necessary */
525 	if (msg_short(hdr)) {
526 		*skb = tipc_buf_acquire(BASIC_H_SIZE + dlen, GFP_ATOMIC);
527 		if (!*skb)
528 			goto exit;
529 		memcpy((*skb)->data + BASIC_H_SIZE, msg_data(hdr), dlen);
530 		kfree_skb(_skb);
531 		_skb = *skb;
532 		hdr = buf_msg(_skb);
533 		memcpy(hdr, &ohdr, BASIC_H_SIZE);
534 		msg_set_hdr_sz(hdr, BASIC_H_SIZE);
535 	}
536 
537 	/* Now reverse the concerned fields */
538 	msg_set_errcode(hdr, err);
539 	msg_set_non_seq(hdr, 0);
540 	msg_set_origport(hdr, msg_destport(&ohdr));
541 	msg_set_destport(hdr, msg_origport(&ohdr));
542 	msg_set_destnode(hdr, msg_prevnode(&ohdr));
543 	msg_set_prevnode(hdr, own_node);
544 	msg_set_orignode(hdr, own_node);
545 	msg_set_size(hdr, msg_hdr_sz(hdr) + dlen);
546 	skb_trim(_skb, msg_size(hdr));
547 	skb_orphan(_skb);
548 	return true;
549 exit:
550 	kfree_skb(_skb);
551 	*skb = NULL;
552 	return false;
553 }
554 
555 /**
556  * tipc_msg_lookup_dest(): try to find new destination for named message
557  * @skb: the buffer containing the message.
558  * @err: error code to be used by caller if lookup fails
559  * Does not consume buffer
560  * Returns true if a destination is found, false otherwise
561  */
tipc_msg_lookup_dest(struct net * net,struct sk_buff * skb,int * err)562 bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err)
563 {
564 	struct tipc_msg *msg = buf_msg(skb);
565 	u32 dport, dnode;
566 	u32 onode = tipc_own_addr(net);
567 
568 	if (!msg_isdata(msg))
569 		return false;
570 	if (!msg_named(msg))
571 		return false;
572 	if (msg_errcode(msg))
573 		return false;
574 	*err = TIPC_ERR_NO_NAME;
575 	if (skb_linearize(skb))
576 		return false;
577 	msg = buf_msg(skb);
578 	if (msg_reroute_cnt(msg))
579 		return false;
580 	dnode = tipc_scope2node(net, msg_lookup_scope(msg));
581 	dport = tipc_nametbl_translate(net, msg_nametype(msg),
582 				       msg_nameinst(msg), &dnode);
583 	if (!dport)
584 		return false;
585 	msg_incr_reroute_cnt(msg);
586 	if (dnode != onode)
587 		msg_set_prevnode(msg, onode);
588 	msg_set_destnode(msg, dnode);
589 	msg_set_destport(msg, dport);
590 	*err = TIPC_OK;
591 
592 	if (!skb_cloned(skb))
593 		return true;
594 
595 	return true;
596 }
597 
598 /* tipc_msg_assemble() - assemble chain of fragments into one message
599  */
tipc_msg_assemble(struct sk_buff_head * list)600 bool tipc_msg_assemble(struct sk_buff_head *list)
601 {
602 	struct sk_buff *skb, *tmp = NULL;
603 
604 	if (skb_queue_len(list) == 1)
605 		return true;
606 
607 	while ((skb = __skb_dequeue(list))) {
608 		skb->next = NULL;
609 		if (tipc_buf_append(&tmp, &skb)) {
610 			__skb_queue_tail(list, skb);
611 			return true;
612 		}
613 		if (!tmp)
614 			break;
615 	}
616 	__skb_queue_purge(list);
617 	__skb_queue_head_init(list);
618 	pr_warn("Failed do assemble buffer\n");
619 	return false;
620 }
621 
622 /* tipc_msg_reassemble() - clone a buffer chain of fragments and
623  *                         reassemble the clones into one message
624  */
tipc_msg_reassemble(struct sk_buff_head * list,struct sk_buff_head * rcvq)625 bool tipc_msg_reassemble(struct sk_buff_head *list, struct sk_buff_head *rcvq)
626 {
627 	struct sk_buff *skb, *_skb;
628 	struct sk_buff *frag = NULL;
629 	struct sk_buff *head = NULL;
630 	int hdr_len;
631 
632 	/* Copy header if single buffer */
633 	if (skb_queue_len(list) == 1) {
634 		skb = skb_peek(list);
635 		hdr_len = skb_headroom(skb) + msg_hdr_sz(buf_msg(skb));
636 		_skb = __pskb_copy(skb, hdr_len, GFP_ATOMIC);
637 		if (!_skb)
638 			return false;
639 		__skb_queue_tail(rcvq, _skb);
640 		return true;
641 	}
642 
643 	/* Clone all fragments and reassemble */
644 	skb_queue_walk(list, skb) {
645 		frag = skb_clone(skb, GFP_ATOMIC);
646 		if (!frag)
647 			goto error;
648 		frag->next = NULL;
649 		if (tipc_buf_append(&head, &frag))
650 			break;
651 		if (!head)
652 			goto error;
653 	}
654 	__skb_queue_tail(rcvq, frag);
655 	return true;
656 error:
657 	pr_warn("Failed do clone local mcast rcv buffer\n");
658 	kfree_skb(head);
659 	return false;
660 }
661 
tipc_msg_pskb_copy(u32 dst,struct sk_buff_head * msg,struct sk_buff_head * cpy)662 bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg,
663 			struct sk_buff_head *cpy)
664 {
665 	struct sk_buff *skb, *_skb;
666 
667 	skb_queue_walk(msg, skb) {
668 		_skb = pskb_copy(skb, GFP_ATOMIC);
669 		if (!_skb) {
670 			__skb_queue_purge(cpy);
671 			return false;
672 		}
673 		msg_set_destnode(buf_msg(_skb), dst);
674 		__skb_queue_tail(cpy, _skb);
675 	}
676 	return true;
677 }
678 
679 /* tipc_skb_queue_sorted(); sort pkt into list according to sequence number
680  * @list: list to be appended to
681  * @seqno: sequence number of buffer to add
682  * @skb: buffer to add
683  */
__tipc_skb_queue_sorted(struct sk_buff_head * list,u16 seqno,struct sk_buff * skb)684 void __tipc_skb_queue_sorted(struct sk_buff_head *list, u16 seqno,
685 			     struct sk_buff *skb)
686 {
687 	struct sk_buff *_skb, *tmp;
688 
689 	if (skb_queue_empty(list) || less(seqno, buf_seqno(skb_peek(list)))) {
690 		__skb_queue_head(list, skb);
691 		return;
692 	}
693 
694 	if (more(seqno, buf_seqno(skb_peek_tail(list)))) {
695 		__skb_queue_tail(list, skb);
696 		return;
697 	}
698 
699 	skb_queue_walk_safe(list, _skb, tmp) {
700 		if (more(seqno, buf_seqno(_skb)))
701 			continue;
702 		if (seqno == buf_seqno(_skb))
703 			break;
704 		__skb_queue_before(list, _skb, skb);
705 		return;
706 	}
707 	kfree_skb(skb);
708 }
709 
tipc_skb_reject(struct net * net,int err,struct sk_buff * skb,struct sk_buff_head * xmitq)710 void tipc_skb_reject(struct net *net, int err, struct sk_buff *skb,
711 		     struct sk_buff_head *xmitq)
712 {
713 	if (tipc_msg_reverse(tipc_own_addr(net), &skb, err))
714 		__skb_queue_tail(xmitq, skb);
715 }
716