aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 19729645d494..ad759bb034e7 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -563,6 +563,84 @@ msg_full:
563 return -EMSGSIZE; 563 return -EMSGSIZE;
564} 564}
565 565
566static struct tipc_link *tipc_node_select_link(struct tipc_node *n, int sel,
567 int *bearer_id,
568 struct tipc_media_addr **maddr)
569{
570 int id = n->active_links[sel & 1];
571
572 if (unlikely(id < 0))
573 return NULL;
574
575 *bearer_id = id;
576 *maddr = &n->links[id].maddr;
577 return n->links[id].link;
578}
579
580/**
581 * tipc_node_xmit() is the general link level function for message sending
582 * @net: the applicable net namespace
583 * @list: chain of buffers containing message
584 * @dnode: address of destination node
585 * @selector: a number used for deterministic link selection
586 * Consumes the buffer chain, except when returning -ELINKCONG
587 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
588 */
589int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
590 u32 dnode, int selector)
591{
592 struct tipc_link *l = NULL;
593 struct tipc_node *n;
594 struct sk_buff_head xmitq;
595 struct tipc_media_addr *maddr;
596 int bearer_id;
597 int rc = -EHOSTUNREACH;
598
599 __skb_queue_head_init(&xmitq);
600 n = tipc_node_find(net, dnode);
601 if (likely(n)) {
602 tipc_node_lock(n);
603 l = tipc_node_select_link(n, selector, &bearer_id, &maddr);
604 if (likely(l))
605 rc = tipc_link_xmit(l, list, &xmitq);
606 if (unlikely(rc == -ENOBUFS))
607 tipc_link_reset(l);
608 tipc_node_unlock(n);
609 tipc_node_put(n);
610 }
611 if (likely(!rc)) {
612 tipc_bearer_xmit(net, bearer_id, &xmitq, maddr);
613 return 0;
614 }
615 if (likely(in_own_node(net, dnode))) {
616 tipc_sk_rcv(net, list);
617 return 0;
618 }
619 return rc;
620}
621
622/* tipc_node_xmit_skb(): send single buffer to destination
623 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE
624 * messages, which will not be rejected
625 * The only exception is datagram messages rerouted after secondary
626 * lookup, which are rare and safe to dispose of anyway.
627 * TODO: Return real return value, and let callers use
628 * tipc_wait_for_sendpkt() where applicable
629 */
630int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
631 u32 selector)
632{
633 struct sk_buff_head head;
634 int rc;
635
636 skb_queue_head_init(&head);
637 __skb_queue_tail(&head, skb);
638 rc = tipc_node_xmit(net, &head, dnode, selector);
639 if (rc == -ELINKCONG)
640 kfree_skb(skb);
641 return 0;
642}
643
566int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb) 644int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
567{ 645{
568 int err; 646 int err;