diff options
Diffstat (limited to 'net/tipc/msg.c')
| -rw-r--r-- | net/tipc/msg.c | 71 | 
1 files changed, 51 insertions, 20 deletions
| diff --git a/net/tipc/msg.c b/net/tipc/msg.c index a687b30a699c..18aba9e99345 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | * POSSIBILITY OF SUCH DAMAGE. | 34 | * POSSIBILITY OF SUCH DAMAGE. | 
| 35 | */ | 35 | */ | 
| 36 | 36 | ||
| 37 | #include <net/sock.h> | ||
| 37 | #include "core.h" | 38 | #include "core.h" | 
| 38 | #include "msg.h" | 39 | #include "msg.h" | 
| 39 | #include "addr.h" | 40 | #include "addr.h" | 
| @@ -46,25 +47,50 @@ static unsigned int align(unsigned int i) | |||
| 46 | return (i + 3) & ~3u; | 47 | return (i + 3) & ~3u; | 
| 47 | } | 48 | } | 
| 48 | 49 | ||
| 49 | void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, | 50 | /** | 
| 50 | u32 destnode) | 51 | * tipc_buf_acquire - creates a TIPC message buffer | 
| 52 | * @size: message size (including TIPC header) | ||
| 53 | * | ||
| 54 | * Returns a new buffer with data pointers set to the specified size. | ||
| 55 | * | ||
| 56 | * NOTE: Headroom is reserved to allow prepending of a data link header. | ||
| 57 | * There may also be unrequested tailroom present at the buffer's end. | ||
| 58 | */ | ||
| 59 | struct sk_buff *tipc_buf_acquire(u32 size) | ||
| 51 | { | 60 | { | 
| 61 | struct sk_buff *skb; | ||
| 62 | unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u; | ||
| 63 | |||
| 64 | skb = alloc_skb_fclone(buf_size, GFP_ATOMIC); | ||
| 65 | if (skb) { | ||
| 66 | skb_reserve(skb, BUF_HEADROOM); | ||
| 67 | skb_put(skb, size); | ||
| 68 | skb->next = NULL; | ||
| 69 | } | ||
| 70 | return skb; | ||
| 71 | } | ||
| 72 | |||
| 73 | void tipc_msg_init(struct net *net, struct tipc_msg *m, u32 user, u32 type, | ||
| 74 | u32 hsize, u32 destnode) | ||
| 75 | { | ||
| 76 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 77 | |||
| 52 | memset(m, 0, hsize); | 78 | memset(m, 0, hsize); | 
| 53 | msg_set_version(m); | 79 | msg_set_version(m); | 
| 54 | msg_set_user(m, user); | 80 | msg_set_user(m, user); | 
| 55 | msg_set_hdr_sz(m, hsize); | 81 | msg_set_hdr_sz(m, hsize); | 
| 56 | msg_set_size(m, hsize); | 82 | msg_set_size(m, hsize); | 
| 57 | msg_set_prevnode(m, tipc_own_addr); | 83 | msg_set_prevnode(m, tn->own_addr); | 
| 58 | msg_set_type(m, type); | 84 | msg_set_type(m, type); | 
| 59 | if (hsize > SHORT_H_SIZE) { | 85 | if (hsize > SHORT_H_SIZE) { | 
| 60 | msg_set_orignode(m, tipc_own_addr); | 86 | msg_set_orignode(m, tn->own_addr); | 
| 61 | msg_set_destnode(m, destnode); | 87 | msg_set_destnode(m, destnode); | 
| 62 | } | 88 | } | 
| 63 | } | 89 | } | 
| 64 | 90 | ||
| 65 | struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz, | 91 | struct sk_buff *tipc_msg_create(struct net *net, uint user, uint type, | 
| 66 | uint data_sz, u32 dnode, u32 onode, | 92 | uint hdr_sz, uint data_sz, u32 dnode, | 
| 67 | u32 dport, u32 oport, int errcode) | 93 | u32 onode, u32 dport, u32 oport, int errcode) | 
| 68 | { | 94 | { | 
| 69 | struct tipc_msg *msg; | 95 | struct tipc_msg *msg; | 
| 70 | struct sk_buff *buf; | 96 | struct sk_buff *buf; | 
| @@ -74,7 +100,7 @@ struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz, | |||
| 74 | return NULL; | 100 | return NULL; | 
| 75 | 101 | ||
| 76 | msg = buf_msg(buf); | 102 | msg = buf_msg(buf); | 
| 77 | tipc_msg_init(msg, user, type, hdr_sz, dnode); | 103 | tipc_msg_init(net, msg, user, type, hdr_sz, dnode); | 
| 78 | msg_set_size(msg, hdr_sz + data_sz); | 104 | msg_set_size(msg, hdr_sz + data_sz); | 
| 79 | msg_set_prevnode(msg, onode); | 105 | msg_set_prevnode(msg, onode); | 
| 80 | msg_set_origport(msg, oport); | 106 | msg_set_origport(msg, oport); | 
| @@ -170,8 +196,8 @@ err: | |||
| 170 | * | 196 | * | 
| 171 | * Returns message data size or errno: -ENOMEM, -EFAULT | 197 | * Returns message data size or errno: -ENOMEM, -EFAULT | 
| 172 | */ | 198 | */ | 
| 173 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, | 199 | int tipc_msg_build(struct net *net, struct tipc_msg *mhdr, struct msghdr *m, | 
| 174 | int dsz, int pktmax, struct sk_buff_head *list) | 200 | int offset, int dsz, int pktmax, struct sk_buff_head *list) | 
| 175 | { | 201 | { | 
| 176 | int mhsz = msg_hdr_sz(mhdr); | 202 | int mhsz = msg_hdr_sz(mhdr); | 
| 177 | int msz = mhsz + dsz; | 203 | int msz = mhsz + dsz; | 
| @@ -191,6 +217,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, | |||
| 191 | skb = tipc_buf_acquire(msz); | 217 | skb = tipc_buf_acquire(msz); | 
| 192 | if (unlikely(!skb)) | 218 | if (unlikely(!skb)) | 
| 193 | return -ENOMEM; | 219 | return -ENOMEM; | 
| 220 | skb_orphan(skb); | ||
| 194 | __skb_queue_tail(list, skb); | 221 | __skb_queue_tail(list, skb); | 
| 195 | skb_copy_to_linear_data(skb, mhdr, mhsz); | 222 | skb_copy_to_linear_data(skb, mhdr, mhsz); | 
| 196 | pktpos = skb->data + mhsz; | 223 | pktpos = skb->data + mhsz; | 
| @@ -202,8 +229,8 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, | |||
| 202 | } | 229 | } | 
| 203 | 230 | ||
| 204 | /* Prepare reusable fragment header */ | 231 | /* Prepare reusable fragment header */ | 
| 205 | tipc_msg_init(&pkthdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 232 | tipc_msg_init(net, &pkthdr, MSG_FRAGMENTER, FIRST_FRAGMENT, INT_H_SIZE, | 
| 206 | INT_H_SIZE, msg_destnode(mhdr)); | 233 | msg_destnode(mhdr)); | 
| 207 | msg_set_size(&pkthdr, pktmax); | 234 | msg_set_size(&pkthdr, pktmax); | 
| 208 | msg_set_fragm_no(&pkthdr, pktno); | 235 | msg_set_fragm_no(&pkthdr, pktno); | 
| 209 | 236 | ||
| @@ -211,6 +238,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, | |||
| 211 | skb = tipc_buf_acquire(pktmax); | 238 | skb = tipc_buf_acquire(pktmax); | 
| 212 | if (!skb) | 239 | if (!skb) | 
| 213 | return -ENOMEM; | 240 | return -ENOMEM; | 
| 241 | skb_orphan(skb); | ||
| 214 | __skb_queue_tail(list, skb); | 242 | __skb_queue_tail(list, skb); | 
| 215 | pktpos = skb->data; | 243 | pktpos = skb->data; | 
| 216 | skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE); | 244 | skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE); | 
| @@ -244,6 +272,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, | |||
| 244 | rc = -ENOMEM; | 272 | rc = -ENOMEM; | 
| 245 | goto error; | 273 | goto error; | 
| 246 | } | 274 | } | 
| 275 | skb_orphan(skb); | ||
| 247 | __skb_queue_tail(list, skb); | 276 | __skb_queue_tail(list, skb); | 
| 248 | msg_set_type(&pkthdr, FRAGMENT); | 277 | msg_set_type(&pkthdr, FRAGMENT); | 
| 249 | msg_set_size(&pkthdr, pktsz); | 278 | msg_set_size(&pkthdr, pktsz); | 
| @@ -312,8 +341,8 @@ bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu) | |||
| 312 | * Replaces buffer if successful | 341 | * Replaces buffer if successful | 
| 313 | * Returns true if success, otherwise false | 342 | * Returns true if success, otherwise false | 
| 314 | */ | 343 | */ | 
| 315 | bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb, | 344 | bool tipc_msg_make_bundle(struct net *net, struct sk_buff_head *list, | 
| 316 | u32 mtu, u32 dnode) | 345 | struct sk_buff *skb, u32 mtu, u32 dnode) | 
| 317 | { | 346 | { | 
| 318 | struct sk_buff *bskb; | 347 | struct sk_buff *bskb; | 
| 319 | struct tipc_msg *bmsg; | 348 | struct tipc_msg *bmsg; | 
| @@ -336,7 +365,7 @@ bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb, | |||
| 336 | 365 | ||
| 337 | skb_trim(bskb, INT_H_SIZE); | 366 | skb_trim(bskb, INT_H_SIZE); | 
| 338 | bmsg = buf_msg(bskb); | 367 | bmsg = buf_msg(bskb); | 
| 339 | tipc_msg_init(bmsg, MSG_BUNDLER, 0, INT_H_SIZE, dnode); | 368 | tipc_msg_init(net, bmsg, MSG_BUNDLER, 0, INT_H_SIZE, dnode); | 
| 340 | msg_set_seqno(bmsg, msg_seqno(msg)); | 369 | msg_set_seqno(bmsg, msg_seqno(msg)); | 
| 341 | msg_set_ack(bmsg, msg_ack(msg)); | 370 | msg_set_ack(bmsg, msg_ack(msg)); | 
| 342 | msg_set_bcast_ack(bmsg, msg_bcast_ack(msg)); | 371 | msg_set_bcast_ack(bmsg, msg_bcast_ack(msg)); | 
| @@ -353,8 +382,10 @@ bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb, | |||
| 353 | * Consumes buffer if failure | 382 | * Consumes buffer if failure | 
| 354 | * Returns true if success, otherwise false | 383 | * Returns true if success, otherwise false | 
| 355 | */ | 384 | */ | 
| 356 | bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err) | 385 | bool tipc_msg_reverse(struct net *net, struct sk_buff *buf, u32 *dnode, | 
| 386 | int err) | ||
| 357 | { | 387 | { | 
| 388 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 358 | struct tipc_msg *msg = buf_msg(buf); | 389 | struct tipc_msg *msg = buf_msg(buf); | 
| 359 | uint imp = msg_importance(msg); | 390 | uint imp = msg_importance(msg); | 
| 360 | struct tipc_msg ohdr; | 391 | struct tipc_msg ohdr; | 
| @@ -374,7 +405,7 @@ bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err) | |||
| 374 | msg_set_errcode(msg, err); | 405 | msg_set_errcode(msg, err); | 
| 375 | msg_set_origport(msg, msg_destport(&ohdr)); | 406 | msg_set_origport(msg, msg_destport(&ohdr)); | 
| 376 | msg_set_destport(msg, msg_origport(&ohdr)); | 407 | msg_set_destport(msg, msg_origport(&ohdr)); | 
| 377 | msg_set_prevnode(msg, tipc_own_addr); | 408 | msg_set_prevnode(msg, tn->own_addr); | 
| 378 | if (!msg_short(msg)) { | 409 | if (!msg_short(msg)) { | 
| 379 | msg_set_orignode(msg, msg_destnode(&ohdr)); | 410 | msg_set_orignode(msg, msg_destnode(&ohdr)); | 
| 380 | msg_set_destnode(msg, msg_orignode(&ohdr)); | 411 | msg_set_destnode(msg, msg_orignode(&ohdr)); | 
| @@ -399,7 +430,7 @@ exit: | |||
| 399 | * Returns 0 (TIPC_OK) if message ok and we can try again, -TIPC error | 430 | * Returns 0 (TIPC_OK) if message ok and we can try again, -TIPC error | 
| 400 | * code if message to be rejected | 431 | * code if message to be rejected | 
| 401 | */ | 432 | */ | 
| 402 | int tipc_msg_eval(struct sk_buff *buf, u32 *dnode) | 433 | int tipc_msg_eval(struct net *net, struct sk_buff *buf, u32 *dnode) | 
| 403 | { | 434 | { | 
| 404 | struct tipc_msg *msg = buf_msg(buf); | 435 | struct tipc_msg *msg = buf_msg(buf); | 
| 405 | u32 dport; | 436 | u32 dport; | 
| @@ -413,8 +444,8 @@ int tipc_msg_eval(struct sk_buff *buf, u32 *dnode) | |||
| 413 | if (msg_reroute_cnt(msg) > 0) | 444 | if (msg_reroute_cnt(msg) > 0) | 
| 414 | return -TIPC_ERR_NO_NAME; | 445 | return -TIPC_ERR_NO_NAME; | 
| 415 | 446 | ||
| 416 | *dnode = addr_domain(msg_lookup_scope(msg)); | 447 | *dnode = addr_domain(net, msg_lookup_scope(msg)); | 
| 417 | dport = tipc_nametbl_translate(msg_nametype(msg), | 448 | dport = tipc_nametbl_translate(net, msg_nametype(msg), | 
| 418 | msg_nameinst(msg), | 449 | msg_nameinst(msg), | 
| 419 | dnode); | 450 | dnode); | 
| 420 | if (!dport) | 451 | if (!dport) | 
