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.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 93b6ae3154c9..5bec8aac5008 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -79,6 +79,7 @@ enum {
79 * @rcv_unacked: # messages read by user, but not yet acked back to peer 79 * @rcv_unacked: # messages read by user, but not yet acked back to peer
80 * @peer: 'connected' peer for dgram/rdm 80 * @peer: 'connected' peer for dgram/rdm
81 * @node: hash table node 81 * @node: hash table node
82 * @mc_method: cookie for use between socket and broadcast layer
82 * @rcu: rcu struct for tipc_sock 83 * @rcu: rcu struct for tipc_sock
83 */ 84 */
84struct tipc_sock { 85struct tipc_sock {
@@ -103,6 +104,7 @@ struct tipc_sock {
103 u16 rcv_win; 104 u16 rcv_win;
104 struct sockaddr_tipc peer; 105 struct sockaddr_tipc peer;
105 struct rhash_head node; 106 struct rhash_head node;
107 struct tipc_mc_method mc_method;
106 struct rcu_head rcu; 108 struct rcu_head rcu;
107}; 109};
108 110
@@ -740,6 +742,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
740 struct tipc_msg *hdr = &tsk->phdr; 742 struct tipc_msg *hdr = &tsk->phdr;
741 struct net *net = sock_net(sk); 743 struct net *net = sock_net(sk);
742 int mtu = tipc_bcast_get_mtu(net); 744 int mtu = tipc_bcast_get_mtu(net);
745 struct tipc_mc_method *method = &tsk->mc_method;
743 u32 domain = addr_domain(net, TIPC_CLUSTER_SCOPE); 746 u32 domain = addr_domain(net, TIPC_CLUSTER_SCOPE);
744 struct sk_buff_head pkts; 747 struct sk_buff_head pkts;
745 struct tipc_nlist dsts; 748 struct tipc_nlist dsts;
@@ -773,7 +776,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
773 776
774 /* Send message if build was successful */ 777 /* Send message if build was successful */
775 if (unlikely(rc == dlen)) 778 if (unlikely(rc == dlen))
776 rc = tipc_mcast_xmit(net, &pkts, &dsts, 779 rc = tipc_mcast_xmit(net, &pkts, method, &dsts,
777 &tsk->cong_link_cnt); 780 &tsk->cong_link_cnt);
778 781
779 tipc_nlist_purge(&dsts); 782 tipc_nlist_purge(&dsts);
@@ -2344,18 +2347,29 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
2344{ 2347{
2345 struct sock *sk = sock->sk; 2348 struct sock *sk = sock->sk;
2346 struct tipc_sock *tsk = tipc_sk(sk); 2349 struct tipc_sock *tsk = tipc_sk(sk);
2347 u32 value; 2350 u32 value = 0;
2348 int res; 2351 int res;
2349 2352
2350 if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM)) 2353 if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM))
2351 return 0; 2354 return 0;
2352 if (lvl != SOL_TIPC) 2355 if (lvl != SOL_TIPC)
2353 return -ENOPROTOOPT; 2356 return -ENOPROTOOPT;
2354 if (ol < sizeof(value)) 2357
2355 return -EINVAL; 2358 switch (opt) {
2356 res = get_user(value, (u32 __user *)ov); 2359 case TIPC_IMPORTANCE:
2357 if (res) 2360 case TIPC_SRC_DROPPABLE:
2358 return res; 2361 case TIPC_DEST_DROPPABLE:
2362 case TIPC_CONN_TIMEOUT:
2363 if (ol < sizeof(value))
2364 return -EINVAL;
2365 res = get_user(value, (u32 __user *)ov);
2366 if (res)
2367 return res;
2368 break;
2369 default:
2370 if (ov || ol)
2371 return -EINVAL;
2372 }
2359 2373
2360 lock_sock(sk); 2374 lock_sock(sk);
2361 2375
@@ -2376,6 +2390,14 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
2376 tipc_sk(sk)->conn_timeout = value; 2390 tipc_sk(sk)->conn_timeout = value;
2377 /* no need to set "res", since already 0 at this point */ 2391 /* no need to set "res", since already 0 at this point */
2378 break; 2392 break;
2393 case TIPC_MCAST_BROADCAST:
2394 tsk->mc_method.rcast = false;
2395 tsk->mc_method.mandatory = true;
2396 break;
2397 case TIPC_MCAST_REPLICAST:
2398 tsk->mc_method.rcast = true;
2399 tsk->mc_method.mandatory = true;
2400 break;
2379 default: 2401 default:
2380 res = -EINVAL; 2402 res = -EINVAL;
2381 } 2403 }