diff options
-rw-r--r-- | net/tipc/bcast.c | 12 | ||||
-rw-r--r-- | net/tipc/link.c | 2 | ||||
-rw-r--r-- | net/tipc/msg.c | 51 | ||||
-rw-r--r-- | net/tipc/msg.h | 3 |
4 files changed, 55 insertions, 13 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 329325bd553e..37892b3909af 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/bcast.c: TIPC broadcast code | 2 | * net/tipc/bcast.c: TIPC broadcast code |
3 | * | 3 | * |
4 | * Copyright (c) 2004-2006, 2014-2016, Ericsson AB | 4 | * Copyright (c) 2004-2006, 2014-2017, Ericsson AB |
5 | * Copyright (c) 2004, Intel Corporation. | 5 | * Copyright (c) 2004, Intel Corporation. |
6 | * Copyright (c) 2005, 2010-2011, Wind River Systems | 6 | * Copyright (c) 2005, 2010-2011, Wind River Systems |
7 | * All rights reserved. | 7 | * All rights reserved. |
@@ -42,8 +42,8 @@ | |||
42 | #include "link.h" | 42 | #include "link.h" |
43 | #include "name_table.h" | 43 | #include "name_table.h" |
44 | 44 | ||
45 | #define BCLINK_WIN_DEFAULT 50 /* bcast link window size (default) */ | 45 | #define BCLINK_WIN_DEFAULT 50 /* bcast link window size (default) */ |
46 | #define BCLINK_WIN_MIN 32 /* bcast minimum link window size */ | 46 | #define BCLINK_WIN_MIN 32 /* bcast minimum link window size */ |
47 | 47 | ||
48 | const char tipc_bclink_name[] = "broadcast-link"; | 48 | const char tipc_bclink_name[] = "broadcast-link"; |
49 | 49 | ||
@@ -74,6 +74,10 @@ static struct tipc_bc_base *tipc_bc_base(struct net *net) | |||
74 | return tipc_net(net)->bcbase; | 74 | return tipc_net(net)->bcbase; |
75 | } | 75 | } |
76 | 76 | ||
77 | /* tipc_bcast_get_mtu(): -get the MTU currently used by broadcast link | ||
78 | * Note: the MTU is decremented to give room for a tunnel header, in | ||
79 | * case the message needs to be sent as replicast | ||
80 | */ | ||
77 | int tipc_bcast_get_mtu(struct net *net) | 81 | int tipc_bcast_get_mtu(struct net *net) |
78 | { | 82 | { |
79 | return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE; | 83 | return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE; |
@@ -515,7 +519,7 @@ int tipc_bcast_init(struct net *net) | |||
515 | spin_lock_init(&tipc_net(net)->bclock); | 519 | spin_lock_init(&tipc_net(net)->bclock); |
516 | 520 | ||
517 | if (!tipc_link_bc_create(net, 0, 0, | 521 | if (!tipc_link_bc_create(net, 0, 0, |
518 | U16_MAX, | 522 | FB_MTU, |
519 | BCLINK_WIN_DEFAULT, | 523 | BCLINK_WIN_DEFAULT, |
520 | 0, | 524 | 0, |
521 | &bb->inputq, | 525 | &bb->inputq, |
diff --git a/net/tipc/link.c b/net/tipc/link.c index 6bce0b1117bd..2d6b2aed30e0 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -483,7 +483,7 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id, | |||
483 | /** | 483 | /** |
484 | * tipc_link_bc_create - create new link to be used for broadcast | 484 | * tipc_link_bc_create - create new link to be used for broadcast |
485 | * @n: pointer to associated node | 485 | * @n: pointer to associated node |
486 | * @mtu: mtu to be used | 486 | * @mtu: mtu to be used initially if no peers |
487 | * @window: send window to be used | 487 | * @window: send window to be used |
488 | * @inputq: queue to put messages ready for delivery | 488 | * @inputq: queue to put messages ready for delivery |
489 | * @namedq: queue to put binding table update messages ready for delivery | 489 | * @namedq: queue to put binding table update messages ready for delivery |
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index b0d07b35909d..55d8ba92291d 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -251,20 +251,23 @@ bool tipc_msg_validate(struct sk_buff **_skb) | |||
251 | * @pktmax: Max packet size that can be used | 251 | * @pktmax: Max packet size that can be used |
252 | * @list: Buffer or chain of buffers to be returned to caller | 252 | * @list: Buffer or chain of buffers to be returned to caller |
253 | * | 253 | * |
254 | * Note that the recursive call we are making here is safe, since it can | ||
255 | * logically go only one further level down. | ||
256 | * | ||
254 | * Returns message data size or errno: -ENOMEM, -EFAULT | 257 | * Returns message data size or errno: -ENOMEM, -EFAULT |
255 | */ | 258 | */ |
256 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, | 259 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, |
257 | int offset, int dsz, int pktmax, struct sk_buff_head *list) | 260 | int dsz, int pktmax, struct sk_buff_head *list) |
258 | { | 261 | { |
259 | int mhsz = msg_hdr_sz(mhdr); | 262 | int mhsz = msg_hdr_sz(mhdr); |
263 | struct tipc_msg pkthdr; | ||
260 | int msz = mhsz + dsz; | 264 | int msz = mhsz + dsz; |
261 | int pktno = 1; | ||
262 | int pktsz; | ||
263 | int pktrem = pktmax; | 265 | int pktrem = pktmax; |
264 | int drem = dsz; | ||
265 | struct tipc_msg pkthdr; | ||
266 | struct sk_buff *skb; | 266 | struct sk_buff *skb; |
267 | int drem = dsz; | ||
268 | int pktno = 1; | ||
267 | char *pktpos; | 269 | char *pktpos; |
270 | int pktsz; | ||
268 | int rc; | 271 | int rc; |
269 | 272 | ||
270 | msg_set_size(mhdr, msz); | 273 | msg_set_size(mhdr, msz); |
@@ -272,8 +275,18 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, | |||
272 | /* No fragmentation needed? */ | 275 | /* No fragmentation needed? */ |
273 | if (likely(msz <= pktmax)) { | 276 | if (likely(msz <= pktmax)) { |
274 | skb = tipc_buf_acquire(msz, GFP_KERNEL); | 277 | skb = tipc_buf_acquire(msz, GFP_KERNEL); |
275 | if (unlikely(!skb)) | 278 | |
279 | /* Fall back to smaller MTU if node local message */ | ||
280 | if (unlikely(!skb)) { | ||
281 | if (pktmax != MAX_MSG_SIZE) | ||
282 | return -ENOMEM; | ||
283 | rc = tipc_msg_build(mhdr, m, offset, dsz, FB_MTU, list); | ||
284 | if (rc != dsz) | ||
285 | return rc; | ||
286 | if (tipc_msg_assemble(list)) | ||
287 | return dsz; | ||
276 | return -ENOMEM; | 288 | return -ENOMEM; |
289 | } | ||
277 | skb_orphan(skb); | 290 | skb_orphan(skb); |
278 | __skb_queue_tail(list, skb); | 291 | __skb_queue_tail(list, skb); |
279 | skb_copy_to_linear_data(skb, mhdr, mhsz); | 292 | skb_copy_to_linear_data(skb, mhdr, mhsz); |
@@ -589,6 +602,30 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err) | |||
589 | return true; | 602 | return true; |
590 | } | 603 | } |
591 | 604 | ||
605 | /* tipc_msg_assemble() - assemble chain of fragments into one message | ||
606 | */ | ||
607 | bool tipc_msg_assemble(struct sk_buff_head *list) | ||
608 | { | ||
609 | struct sk_buff *skb, *tmp = NULL; | ||
610 | |||
611 | if (skb_queue_len(list) == 1) | ||
612 | return true; | ||
613 | |||
614 | while ((skb = __skb_dequeue(list))) { | ||
615 | skb->next = NULL; | ||
616 | if (tipc_buf_append(&tmp, &skb)) { | ||
617 | __skb_queue_tail(list, skb); | ||
618 | return true; | ||
619 | } | ||
620 | if (!tmp) | ||
621 | break; | ||
622 | } | ||
623 | __skb_queue_purge(list); | ||
624 | __skb_queue_head_init(list); | ||
625 | pr_warn("Failed do assemble buffer\n"); | ||
626 | return false; | ||
627 | } | ||
628 | |||
592 | /* tipc_msg_reassemble() - clone a buffer chain of fragments and | 629 | /* tipc_msg_reassemble() - clone a buffer chain of fragments and |
593 | * reassemble the clones into one message | 630 | * reassemble the clones into one message |
594 | */ | 631 | */ |
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 3e4384c222f7..b4ba1b4f9ae7 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
@@ -98,7 +98,7 @@ struct plist; | |||
98 | #define MAX_H_SIZE 60 /* Largest possible TIPC header size */ | 98 | #define MAX_H_SIZE 60 /* Largest possible TIPC header size */ |
99 | 99 | ||
100 | #define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE) | 100 | #define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE) |
101 | 101 | #define FB_MTU 3744 | |
102 | #define TIPC_MEDIA_INFO_OFFSET 5 | 102 | #define TIPC_MEDIA_INFO_OFFSET 5 |
103 | 103 | ||
104 | struct tipc_skb_cb { | 104 | struct tipc_skb_cb { |
@@ -943,6 +943,7 @@ bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos); | |||
943 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, | 943 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, |
944 | int offset, int dsz, int mtu, struct sk_buff_head *list); | 944 | int offset, int dsz, int mtu, struct sk_buff_head *list); |
945 | bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err); | 945 | bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err); |
946 | bool tipc_msg_assemble(struct sk_buff_head *list); | ||
946 | bool tipc_msg_reassemble(struct sk_buff_head *list, struct sk_buff_head *rcvq); | 947 | bool tipc_msg_reassemble(struct sk_buff_head *list, struct sk_buff_head *rcvq); |
947 | bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg, | 948 | bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg, |
948 | struct sk_buff_head *cpy); | 949 | struct sk_buff_head *cpy); |