aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c209
1 files changed, 182 insertions, 27 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index daf7c4df4531..64bbf9d03629 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/socket.c: TIPC socket API 2 * net/tipc/socket.c: TIPC socket API
3 * 3 *
4 * Copyright (c) 2001-2007, 2012-2016, Ericsson AB 4 * Copyright (c) 2001-2007, 2012-2017, Ericsson AB
5 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -45,6 +45,7 @@
45#include "socket.h" 45#include "socket.h"
46#include "bcast.h" 46#include "bcast.h"
47#include "netlink.h" 47#include "netlink.h"
48#include "group.h"
48 49
49#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ 50#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
50#define CONN_PROBING_INTERVAL msecs_to_jiffies(3600000) /* [ms] => 1 h */ 51#define CONN_PROBING_INTERVAL msecs_to_jiffies(3600000) /* [ms] => 1 h */
@@ -78,7 +79,7 @@ enum {
78 * @conn_timeout: the time we can wait for an unresponded setup request 79 * @conn_timeout: the time we can wait for an unresponded setup request
79 * @dupl_rcvcnt: number of bytes counted twice, in both backlog and rcv queue 80 * @dupl_rcvcnt: number of bytes counted twice, in both backlog and rcv queue
80 * @cong_link_cnt: number of congested links 81 * @cong_link_cnt: number of congested links
81 * @sent_unacked: # messages sent by socket, and not yet acked by peer 82 * @snt_unacked: # messages sent by socket, and not yet acked by peer
82 * @rcv_unacked: # messages read by user, but not yet acked back to peer 83 * @rcv_unacked: # messages read by user, but not yet acked back to peer
83 * @peer: 'connected' peer for dgram/rdm 84 * @peer: 'connected' peer for dgram/rdm
84 * @node: hash table node 85 * @node: hash table node
@@ -109,6 +110,7 @@ struct tipc_sock {
109 struct rhash_head node; 110 struct rhash_head node;
110 struct tipc_mc_method mc_method; 111 struct tipc_mc_method mc_method;
111 struct rcu_head rcu; 112 struct rcu_head rcu;
113 struct tipc_group *group;
112}; 114};
113 115
114static int tipc_sk_backlog_rcv(struct sock *sk, struct sk_buff *skb); 116static int tipc_sk_backlog_rcv(struct sock *sk, struct sk_buff *skb);
@@ -123,6 +125,7 @@ static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
123 struct tipc_name_seq const *seq); 125 struct tipc_name_seq const *seq);
124static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, 126static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
125 struct tipc_name_seq const *seq); 127 struct tipc_name_seq const *seq);
128static int tipc_sk_leave(struct tipc_sock *tsk);
126static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid); 129static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid);
127static int tipc_sk_insert(struct tipc_sock *tsk); 130static int tipc_sk_insert(struct tipc_sock *tsk);
128static void tipc_sk_remove(struct tipc_sock *tsk); 131static void tipc_sk_remove(struct tipc_sock *tsk);
@@ -559,6 +562,7 @@ static int tipc_release(struct socket *sock)
559 562
560 __tipc_shutdown(sock, TIPC_ERR_NO_PORT); 563 __tipc_shutdown(sock, TIPC_ERR_NO_PORT);
561 sk->sk_shutdown = SHUTDOWN_MASK; 564 sk->sk_shutdown = SHUTDOWN_MASK;
565 tipc_sk_leave(tsk);
562 tipc_sk_withdraw(tsk, 0, NULL); 566 tipc_sk_withdraw(tsk, 0, NULL);
563 sk_stop_timer(sk, &sk->sk_timer); 567 sk_stop_timer(sk, &sk->sk_timer);
564 tipc_sk_remove(tsk); 568 tipc_sk_remove(tsk);
@@ -601,7 +605,10 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
601 res = tipc_sk_withdraw(tsk, 0, NULL); 605 res = tipc_sk_withdraw(tsk, 0, NULL);
602 goto exit; 606 goto exit;
603 } 607 }
604 608 if (tsk->group) {
609 res = -EACCES;
610 goto exit;
611 }
605 if (uaddr_len < sizeof(struct sockaddr_tipc)) { 612 if (uaddr_len < sizeof(struct sockaddr_tipc)) {
606 res = -EINVAL; 613 res = -EINVAL;
607 goto exit; 614 goto exit;
@@ -698,6 +705,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
698{ 705{
699 struct sock *sk = sock->sk; 706 struct sock *sk = sock->sk;
700 struct tipc_sock *tsk = tipc_sk(sk); 707 struct tipc_sock *tsk = tipc_sk(sk);
708 struct tipc_group *grp = tsk->group;
701 u32 mask = 0; 709 u32 mask = 0;
702 710
703 sock_poll_wait(file, sk_sleep(sk), wait); 711 sock_poll_wait(file, sk_sleep(sk), wait);
@@ -718,8 +726,9 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
718 mask |= (POLLIN | POLLRDNORM); 726 mask |= (POLLIN | POLLRDNORM);
719 break; 727 break;
720 case TIPC_OPEN: 728 case TIPC_OPEN:
721 if (!tsk->cong_link_cnt) 729 if (!grp || tipc_group_size(grp))
722 mask |= POLLOUT; 730 if (!tsk->cong_link_cnt)
731 mask |= POLLOUT;
723 if (tipc_sk_type_connectionless(sk) && 732 if (tipc_sk_type_connectionless(sk) &&
724 (!skb_queue_empty(&sk->sk_receive_queue))) 733 (!skb_queue_empty(&sk->sk_receive_queue)))
725 mask |= (POLLIN | POLLRDNORM); 734 mask |= (POLLIN | POLLRDNORM);
@@ -757,6 +766,9 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
757 struct tipc_nlist dsts; 766 struct tipc_nlist dsts;
758 int rc; 767 int rc;
759 768
769 if (tsk->group)
770 return -EACCES;
771
760 /* Block or return if any destination link is congested */ 772 /* Block or return if any destination link is congested */
761 rc = tipc_wait_for_cond(sock, &timeout, !tsk->cong_link_cnt); 773 rc = tipc_wait_for_cond(sock, &timeout, !tsk->cong_link_cnt);
762 if (unlikely(rc)) 774 if (unlikely(rc))
@@ -794,6 +806,64 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
794} 806}
795 807
796/** 808/**
809 * tipc_send_group_bcast - send message to all members in communication group
810 * @sk: socket structure
811 * @m: message to send
812 * @dlen: total length of message data
813 * @timeout: timeout to wait for wakeup
814 *
815 * Called from function tipc_sendmsg(), which has done all sanity checks
816 * Returns the number of bytes sent on success, or errno
817 */
818static int tipc_send_group_bcast(struct socket *sock, struct msghdr *m,
819 int dlen, long timeout)
820{
821 struct sock *sk = sock->sk;
822 struct net *net = sock_net(sk);
823 struct tipc_sock *tsk = tipc_sk(sk);
824 struct tipc_group *grp = tsk->group;
825 struct tipc_nlist *dsts = tipc_group_dests(grp);
826 struct tipc_mc_method *method = &tsk->mc_method;
827 struct tipc_msg *hdr = &tsk->phdr;
828 int mtu = tipc_bcast_get_mtu(net);
829 struct sk_buff_head pkts;
830 int rc = -EHOSTUNREACH;
831
832 if (!dsts->local && !dsts->remote)
833 return -EHOSTUNREACH;
834
835 /* Block or return if any destination link is congested */
836 rc = tipc_wait_for_cond(sock, &timeout, !tsk->cong_link_cnt);
837 if (unlikely(rc))
838 return rc;
839
840 /* Complete message header */
841 msg_set_type(hdr, TIPC_GRP_BCAST_MSG);
842 msg_set_hdr_sz(hdr, MCAST_H_SIZE);
843 msg_set_destport(hdr, 0);
844 msg_set_destnode(hdr, 0);
845 msg_set_nameinst(hdr, 0);
846 msg_set_grp_bc_seqno(hdr, tipc_group_bc_snd_nxt(grp));
847
848 /* Build message as chain of buffers */
849 skb_queue_head_init(&pkts);
850 rc = tipc_msg_build(hdr, m, 0, dlen, mtu, &pkts);
851 if (unlikely(rc != dlen))
852 return rc;
853
854 /* Send message */
855 rc = tipc_mcast_xmit(net, &pkts, method, dsts,
856 &tsk->cong_link_cnt);
857 if (unlikely(rc))
858 return rc;
859
860 /* Update broadcast sequence number */
861 tipc_group_update_bc_members(tsk->group);
862
863 return dlen;
864}
865
866/**
797 * tipc_sk_mcast_rcv - Deliver multicast messages to all destination sockets 867 * tipc_sk_mcast_rcv - Deliver multicast messages to all destination sockets
798 * @arrvq: queue with arriving messages, to be cloned after destination lookup 868 * @arrvq: queue with arriving messages, to be cloned after destination lookup
799 * @inputq: queue with cloned messages, delivered to socket after dest lookup 869 * @inputq: queue with cloned messages, delivered to socket after dest lookup
@@ -803,13 +873,15 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
803void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, 873void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
804 struct sk_buff_head *inputq) 874 struct sk_buff_head *inputq)
805{ 875{
806 struct tipc_msg *msg;
807 struct list_head dports;
808 u32 portid;
809 u32 scope = TIPC_CLUSTER_SCOPE; 876 u32 scope = TIPC_CLUSTER_SCOPE;
810 struct sk_buff_head tmpq; 877 u32 self = tipc_own_addr(net);
811 uint hsz;
812 struct sk_buff *skb, *_skb; 878 struct sk_buff *skb, *_skb;
879 u32 lower = 0, upper = ~0;
880 struct sk_buff_head tmpq;
881 u32 portid, oport, onode;
882 struct list_head dports;
883 struct tipc_msg *msg;
884 int hsz;
813 885
814 __skb_queue_head_init(&tmpq); 886 __skb_queue_head_init(&tmpq);
815 INIT_LIST_HEAD(&dports); 887 INIT_LIST_HEAD(&dports);
@@ -818,14 +890,18 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
818 for (; skb; skb = tipc_skb_peek(arrvq, &inputq->lock)) { 890 for (; skb; skb = tipc_skb_peek(arrvq, &inputq->lock)) {
819 msg = buf_msg(skb); 891 msg = buf_msg(skb);
820 hsz = skb_headroom(skb) + msg_hdr_sz(msg); 892 hsz = skb_headroom(skb) + msg_hdr_sz(msg);
821 893 oport = msg_origport(msg);
822 if (in_own_node(net, msg_orignode(msg))) 894 onode = msg_orignode(msg);
895 if (onode == self)
823 scope = TIPC_NODE_SCOPE; 896 scope = TIPC_NODE_SCOPE;
824 897
825 /* Create destination port list and message clones: */ 898 /* Create destination port list and message clones: */
826 tipc_nametbl_mc_translate(net, 899 if (!msg_in_group(msg)) {
827 msg_nametype(msg), msg_namelower(msg), 900 lower = msg_namelower(msg);
828 msg_nameupper(msg), scope, &dports); 901 upper = msg_nameupper(msg);
902 }
903 tipc_nametbl_mc_translate(net, msg_nametype(msg), lower, upper,
904 scope, &dports);
829 while (tipc_dest_pop(&dports, NULL, &portid)) { 905 while (tipc_dest_pop(&dports, NULL, &portid)) {
830 _skb = __pskb_copy(skb, hsz, GFP_ATOMIC); 906 _skb = __pskb_copy(skb, hsz, GFP_ATOMIC);
831 if (_skb) { 907 if (_skb) {
@@ -895,10 +971,6 @@ exit:
895 kfree_skb(skb); 971 kfree_skb(skb);
896} 972}
897 973
898static void tipc_sk_top_evt(struct tipc_sock *tsk, struct tipc_event *evt)
899{
900}
901
902/** 974/**
903 * tipc_sendmsg - send message in connectionless manner 975 * tipc_sendmsg - send message in connectionless manner
904 * @sock: socket structure 976 * @sock: socket structure
@@ -934,6 +1006,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
934 long timeout = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); 1006 long timeout = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
935 struct list_head *clinks = &tsk->cong_links; 1007 struct list_head *clinks = &tsk->cong_links;
936 bool syn = !tipc_sk_type_connectionless(sk); 1008 bool syn = !tipc_sk_type_connectionless(sk);
1009 struct tipc_group *grp = tsk->group;
937 struct tipc_msg *hdr = &tsk->phdr; 1010 struct tipc_msg *hdr = &tsk->phdr;
938 struct tipc_name_seq *seq; 1011 struct tipc_name_seq *seq;
939 struct sk_buff_head pkts; 1012 struct sk_buff_head pkts;
@@ -944,6 +1017,9 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
944 if (unlikely(dlen > TIPC_MAX_USER_MSG_SIZE)) 1017 if (unlikely(dlen > TIPC_MAX_USER_MSG_SIZE))
945 return -EMSGSIZE; 1018 return -EMSGSIZE;
946 1019
1020 if (unlikely(grp))
1021 return tipc_send_group_bcast(sock, m, dlen, timeout);
1022
947 if (unlikely(!dest)) { 1023 if (unlikely(!dest)) {
948 dest = &tsk->peer; 1024 dest = &tsk->peer;
949 if (!syn || dest->family != AF_TIPC) 1025 if (!syn || dest->family != AF_TIPC)
@@ -1543,6 +1619,7 @@ static void tipc_sk_proto_rcv(struct sock *sk,
1543 struct sk_buff *skb = __skb_dequeue(inputq); 1619 struct sk_buff *skb = __skb_dequeue(inputq);
1544 struct tipc_sock *tsk = tipc_sk(sk); 1620 struct tipc_sock *tsk = tipc_sk(sk);
1545 struct tipc_msg *hdr = buf_msg(skb); 1621 struct tipc_msg *hdr = buf_msg(skb);
1622 struct tipc_group *grp = tsk->group;
1546 1623
1547 switch (msg_user(hdr)) { 1624 switch (msg_user(hdr)) {
1548 case CONN_MANAGER: 1625 case CONN_MANAGER:
@@ -1553,8 +1630,12 @@ static void tipc_sk_proto_rcv(struct sock *sk,
1553 tsk->cong_link_cnt--; 1630 tsk->cong_link_cnt--;
1554 sk->sk_write_space(sk); 1631 sk->sk_write_space(sk);
1555 break; 1632 break;
1633 case GROUP_PROTOCOL:
1634 tipc_group_proto_rcv(grp, hdr, xmitq);
1635 break;
1556 case TOP_SRV: 1636 case TOP_SRV:
1557 tipc_sk_top_evt(tsk, (void *)msg_data(hdr)); 1637 tipc_group_member_evt(tsk->group, skb, xmitq);
1638 skb = NULL;
1558 break; 1639 break;
1559 default: 1640 default:
1560 break; 1641 break;
@@ -1699,6 +1780,7 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb,
1699{ 1780{
1700 bool sk_conn = !tipc_sk_type_connectionless(sk); 1781 bool sk_conn = !tipc_sk_type_connectionless(sk);
1701 struct tipc_sock *tsk = tipc_sk(sk); 1782 struct tipc_sock *tsk = tipc_sk(sk);
1783 struct tipc_group *grp = tsk->group;
1702 struct tipc_msg *hdr = buf_msg(skb); 1784 struct tipc_msg *hdr = buf_msg(skb);
1703 struct net *net = sock_net(sk); 1785 struct net *net = sock_net(sk);
1704 struct sk_buff_head inputq; 1786 struct sk_buff_head inputq;
@@ -1710,15 +1792,19 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb,
1710 1792
1711 if (unlikely(!msg_isdata(hdr))) 1793 if (unlikely(!msg_isdata(hdr)))
1712 tipc_sk_proto_rcv(sk, &inputq, xmitq); 1794 tipc_sk_proto_rcv(sk, &inputq, xmitq);
1713 else if (unlikely(msg_type(hdr) > TIPC_DIRECT_MSG)) 1795 else if (unlikely(msg_type(hdr) > TIPC_GRP_BCAST_MSG))
1714 return kfree_skb(skb); 1796 return kfree_skb(skb);
1715 1797
1798 if (unlikely(grp))
1799 tipc_group_filter_msg(grp, &inputq, xmitq);
1800
1716 /* Validate and add to receive buffer if there is space */ 1801 /* Validate and add to receive buffer if there is space */
1717 while ((skb = __skb_dequeue(&inputq))) { 1802 while ((skb = __skb_dequeue(&inputq))) {
1718 hdr = buf_msg(skb); 1803 hdr = buf_msg(skb);
1719 limit = rcvbuf_limit(sk, skb); 1804 limit = rcvbuf_limit(sk, skb);
1720 if ((sk_conn && !tipc_sk_filter_connect(tsk, skb)) || 1805 if ((sk_conn && !tipc_sk_filter_connect(tsk, skb)) ||
1721 (!sk_conn && msg_connected(hdr))) 1806 (!sk_conn && msg_connected(hdr)) ||
1807 (!grp && msg_in_group(hdr)))
1722 err = TIPC_ERR_NO_PORT; 1808 err = TIPC_ERR_NO_PORT;
1723 else if (sk_rmem_alloc_get(sk) + skb->truesize >= limit) 1809 else if (sk_rmem_alloc_get(sk) + skb->truesize >= limit)
1724 err = TIPC_ERR_OVERLOAD; 1810 err = TIPC_ERR_OVERLOAD;
@@ -1837,7 +1923,6 @@ void tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq)
1837 sock_put(sk); 1923 sock_put(sk);
1838 continue; 1924 continue;
1839 } 1925 }
1840
1841 /* No destination socket => dequeue skb if still there */ 1926 /* No destination socket => dequeue skb if still there */
1842 skb = tipc_skb_dequeue(inputq, dport); 1927 skb = tipc_skb_dequeue(inputq, dport);
1843 if (!skb) 1928 if (!skb)
@@ -1905,6 +1990,11 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
1905 1990
1906 lock_sock(sk); 1991 lock_sock(sk);
1907 1992
1993 if (tsk->group) {
1994 res = -EINVAL;
1995 goto exit;
1996 }
1997
1908 if (dst->family == AF_UNSPEC) { 1998 if (dst->family == AF_UNSPEC) {
1909 memset(&tsk->peer, 0, sizeof(struct sockaddr_tipc)); 1999 memset(&tsk->peer, 0, sizeof(struct sockaddr_tipc));
1910 if (!tipc_sk_type_connectionless(sk)) 2000 if (!tipc_sk_type_connectionless(sk))
@@ -2341,6 +2431,52 @@ void tipc_sk_rht_destroy(struct net *net)
2341 rhashtable_destroy(&tn->sk_rht); 2431 rhashtable_destroy(&tn->sk_rht);
2342} 2432}
2343 2433
2434static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
2435{
2436 struct net *net = sock_net(&tsk->sk);
2437 u32 domain = addr_domain(net, mreq->scope);
2438 struct tipc_group *grp = tsk->group;
2439 struct tipc_msg *hdr = &tsk->phdr;
2440 struct tipc_name_seq seq;
2441 int rc;
2442
2443 if (mreq->type < TIPC_RESERVED_TYPES)
2444 return -EACCES;
2445 if (grp)
2446 return -EACCES;
2447 grp = tipc_group_create(net, tsk->portid, mreq);
2448 if (!grp)
2449 return -ENOMEM;
2450 tsk->group = grp;
2451 msg_set_lookup_scope(hdr, mreq->scope);
2452 msg_set_nametype(hdr, mreq->type);
2453 msg_set_dest_droppable(hdr, true);
2454 seq.type = mreq->type;
2455 seq.lower = mreq->instance;
2456 seq.upper = seq.lower;
2457 tipc_nametbl_build_group(net, grp, mreq->type, domain);
2458 rc = tipc_sk_publish(tsk, mreq->scope, &seq);
2459 if (rc)
2460 tipc_group_delete(net, grp);
2461 return rc;
2462}
2463
2464static int tipc_sk_leave(struct tipc_sock *tsk)
2465{
2466 struct net *net = sock_net(&tsk->sk);
2467 struct tipc_group *grp = tsk->group;
2468 struct tipc_name_seq seq;
2469 int scope;
2470
2471 if (!grp)
2472 return -EINVAL;
2473 tipc_group_self(grp, &seq, &scope);
2474 tipc_group_delete(net, grp);
2475 tsk->group = NULL;
2476 tipc_sk_withdraw(tsk, scope, &seq);
2477 return 0;
2478}
2479
2344/** 2480/**
2345 * tipc_setsockopt - set socket option 2481 * tipc_setsockopt - set socket option
2346 * @sock: socket structure 2482 * @sock: socket structure
@@ -2359,6 +2495,7 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
2359{ 2495{
2360 struct sock *sk = sock->sk; 2496 struct sock *sk = sock->sk;
2361 struct tipc_sock *tsk = tipc_sk(sk); 2497 struct tipc_sock *tsk = tipc_sk(sk);
2498 struct tipc_group_req mreq;
2362 u32 value = 0; 2499 u32 value = 0;
2363 int res = 0; 2500 int res = 0;
2364 2501
@@ -2374,9 +2511,14 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
2374 case TIPC_CONN_TIMEOUT: 2511 case TIPC_CONN_TIMEOUT:
2375 if (ol < sizeof(value)) 2512 if (ol < sizeof(value))
2376 return -EINVAL; 2513 return -EINVAL;
2377 res = get_user(value, (u32 __user *)ov); 2514 if (get_user(value, (u32 __user *)ov))
2378 if (res) 2515 return -EFAULT;
2379 return res; 2516 break;
2517 case TIPC_GROUP_JOIN:
2518 if (ol < sizeof(mreq))
2519 return -EINVAL;
2520 if (copy_from_user(&mreq, ov, sizeof(mreq)))
2521 return -EFAULT;
2380 break; 2522 break;
2381 default: 2523 default:
2382 if (ov || ol) 2524 if (ov || ol)
@@ -2409,6 +2551,12 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
2409 tsk->mc_method.rcast = true; 2551 tsk->mc_method.rcast = true;
2410 tsk->mc_method.mandatory = true; 2552 tsk->mc_method.mandatory = true;
2411 break; 2553 break;
2554 case TIPC_GROUP_JOIN:
2555 res = tipc_sk_join(tsk, &mreq);
2556 break;
2557 case TIPC_GROUP_LEAVE:
2558 res = tipc_sk_leave(tsk);
2559 break;
2412 default: 2560 default:
2413 res = -EINVAL; 2561 res = -EINVAL;
2414 } 2562 }
@@ -2436,7 +2584,8 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
2436{ 2584{
2437 struct sock *sk = sock->sk; 2585 struct sock *sk = sock->sk;
2438 struct tipc_sock *tsk = tipc_sk(sk); 2586 struct tipc_sock *tsk = tipc_sk(sk);
2439 int len; 2587 struct tipc_name_seq seq;
2588 int len, scope;
2440 u32 value; 2589 u32 value;
2441 int res; 2590 int res;
2442 2591
@@ -2470,6 +2619,12 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
2470 case TIPC_SOCK_RECVQ_DEPTH: 2619 case TIPC_SOCK_RECVQ_DEPTH:
2471 value = skb_queue_len(&sk->sk_receive_queue); 2620 value = skb_queue_len(&sk->sk_receive_queue);
2472 break; 2621 break;
2622 case TIPC_GROUP_JOIN:
2623 seq.type = 0;
2624 if (tsk->group)
2625 tipc_group_self(tsk->group, &seq, &scope);
2626 value = seq.type;
2627 break;
2473 default: 2628 default:
2474 res = -EINVAL; 2629 res = -EINVAL;
2475 } 2630 }