aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/msg.c42
-rw-r--r--net/tipc/msg.h9
-rw-r--r--net/tipc/socket.c40
3 files changed, 48 insertions, 43 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 940d74197b8c..697223a21240 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -411,43 +411,43 @@ bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
411 return true; 411 return true;
412exit: 412exit:
413 kfree_skb(buf); 413 kfree_skb(buf);
414 *dnode = 0;
414 return false; 415 return false;
415} 416}
416 417
417/** 418/**
418 * tipc_msg_eval: determine fate of message that found no destination 419 * tipc_msg_lookup_dest(): try to find new destination for named message
419 * @buf: the buffer containing the message. 420 * @skb: the buffer containing the message.
420 * @dnode: return value: next-hop node, if message to be forwarded 421 * @dnode: return value: next-hop node, if destination found
421 * @err: error code to use, if message to be rejected 422 * @err: return value: error code to use, if message to be rejected
422 *
423 * Does not consume buffer 423 * Does not consume buffer
424 * Returns 0 (TIPC_OK) if message ok and we can try again, -TIPC error 424 * Returns true if a destination is found, false otherwise
425 * code if message to be rejected
426 */ 425 */
427int tipc_msg_eval(struct net *net, struct sk_buff *buf, u32 *dnode) 426bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb,
427 u32 *dnode, int *err)
428{ 428{
429 struct tipc_msg *msg = buf_msg(buf); 429 struct tipc_msg *msg = buf_msg(skb);
430 u32 dport; 430 u32 dport;
431 431
432 if (msg_type(msg) != TIPC_NAMED_MSG) 432 if (!msg_isdata(msg))
433 return -TIPC_ERR_NO_PORT; 433 return false;
434 if (skb_linearize(buf)) 434 if (!msg_named(msg))
435 return -TIPC_ERR_NO_NAME; 435 return false;
436 if (msg_data_sz(msg) > MAX_FORWARD_SIZE) 436 *err = -TIPC_ERR_NO_NAME;
437 return -TIPC_ERR_NO_NAME; 437 if (skb_linearize(skb))
438 return false;
438 if (msg_reroute_cnt(msg) > 0) 439 if (msg_reroute_cnt(msg) > 0)
439 return -TIPC_ERR_NO_NAME; 440 return false;
440
441 *dnode = addr_domain(net, msg_lookup_scope(msg)); 441 *dnode = addr_domain(net, msg_lookup_scope(msg));
442 dport = tipc_nametbl_translate(net, msg_nametype(msg), 442 dport = tipc_nametbl_translate(net, msg_nametype(msg),
443 msg_nameinst(msg), 443 msg_nameinst(msg), dnode);
444 dnode);
445 if (!dport) 444 if (!dport)
446 return -TIPC_ERR_NO_NAME; 445 return false;
447 msg_incr_reroute_cnt(msg); 446 msg_incr_reroute_cnt(msg);
448 msg_set_destnode(msg, *dnode); 447 msg_set_destnode(msg, *dnode);
449 msg_set_destport(msg, dport); 448 msg_set_destport(msg, dport);
450 return TIPC_OK; 449 *err = TIPC_OK;
450 return true;
451} 451}
452 452
453/* tipc_msg_reassemble() - clone a buffer chain of fragments and 453/* tipc_msg_reassemble() - clone a buffer chain of fragments and
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index f7ea95458c6f..60702992933d 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -750,18 +750,19 @@ static inline u32 msg_tot_origport(struct tipc_msg *m)
750struct sk_buff *tipc_buf_acquire(u32 size); 750struct sk_buff *tipc_buf_acquire(u32 size);
751bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode, 751bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
752 int err); 752 int err);
753int tipc_msg_eval(struct net *net, struct sk_buff *buf, u32 *dnode);
754void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type, 753void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
755 u32 hsize, u32 destnode); 754 u32 hsize, u32 destnode);
756struct sk_buff *tipc_msg_create(uint user, uint type, 755struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
757 uint hdr_sz, uint data_sz, u32 dnode, 756 uint data_sz, u32 dnode, u32 onode,
758 u32 onode, u32 dport, u32 oport, int errcode); 757 u32 dport, u32 oport, int errcode);
759int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf); 758int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
760bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu); 759bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu);
761bool tipc_msg_make_bundle(struct sk_buff_head *list, 760bool tipc_msg_make_bundle(struct sk_buff_head *list,
762 struct sk_buff *skb, u32 mtu, u32 dnode); 761 struct sk_buff *skb, u32 mtu, u32 dnode);
763int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, 762int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
764 int offset, int dsz, int mtu, struct sk_buff_head *list); 763 int offset, int dsz, int mtu, struct sk_buff_head *list);
764bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, u32 *dnode,
765 int *err);
765struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list); 766struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list);
766 767
767#endif 768#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 1d98bfcda6f6..e14b2aedb212 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1739,7 +1739,7 @@ static int filter_rcv(struct sock *sk, struct sk_buff **skb)
1739 * @sk: socket 1739 * @sk: socket
1740 * @skb: message 1740 * @skb: message
1741 * 1741 *
1742 * Caller must hold socket lock, but not port lock. 1742 * Caller must hold socket lock
1743 * 1743 *
1744 * Returns 0 1744 * Returns 0
1745 */ 1745 */
@@ -1805,27 +1805,31 @@ int tipc_sk_rcv(struct net *net, struct sk_buff *skb)
1805 struct tipc_net *tn; 1805 struct tipc_net *tn;
1806 struct sock *sk; 1806 struct sock *sk;
1807 u32 dport = msg_destport(buf_msg(skb)); 1807 u32 dport = msg_destport(buf_msg(skb));
1808 int err; 1808 int err = -TIPC_ERR_NO_PORT;
1809 u32 dnode; 1809 u32 dnode;
1810 1810
1811 /* Validate destination and message */ 1811 /* Find destination */
1812 tsk = tipc_sk_lookup(net, dport); 1812 tsk = tipc_sk_lookup(net, dport);
1813 if (unlikely(!tsk)) { 1813 if (likely(tsk)) {
1814 err = tipc_msg_eval(net, skb, &dnode); 1814 sk = &tsk->sk;
1815 goto exit; 1815 spin_lock_bh(&sk->sk_lock.slock);
1816 } 1816 err = tipc_sk_enqueue_skb(sk, &skb);
1817 sk = &tsk->sk; 1817 spin_unlock_bh(&sk->sk_lock.slock);
1818 1818 sock_put(sk);
1819 spin_lock_bh(&sk->sk_lock.slock);
1820 err = tipc_sk_enqueue_skb(sk, &skb);
1821 spin_unlock_bh(&sk->sk_lock.slock);
1822 sock_put(sk);
1823exit:
1824 if (unlikely(skb)) {
1825 tn = net_generic(net, tipc_net_id);
1826 if (!err || tipc_msg_reverse(tn->own_addr, skb, &dnode, -err))
1827 tipc_link_xmit_skb(net, skb, dnode, 0);
1828 } 1819 }
1820 if (likely(!skb))
1821 return 0;
1822 if (tipc_msg_lookup_dest(net, skb, &dnode, &err))
1823 goto xmit;
1824 if (!err) {
1825 dnode = msg_destnode(buf_msg(skb));
1826 goto xmit;
1827 }
1828 tn = net_generic(net, tipc_net_id);
1829 if (!tipc_msg_reverse(tn->own_addr, skb, &dnode, -err))
1830 return -EHOSTUNREACH;
1831xmit:
1832 tipc_link_xmit_skb(net, skb, dnode, dport);
1829 return err ? -EHOSTUNREACH : 0; 1833 return err ? -EHOSTUNREACH : 0;
1830} 1834}
1831 1835