From: Hoang Le <hoang.h...@dektech.com.au>

We introduce a set/getsockopt for setting socket receive buffer per
individual socket. This has turned out to sometimes be necessary for
anycast and multicast receivers when used without flow control.

Signed-off-by: Hoang Le <hoang.h...@dektech.com.au>
Signed-off-by: Jon Maloy <jon.ma...@ericsson.com>
---
 include/uapi/linux/tipc.h | 1 +
 net/tipc/socket.c         | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index 14bacc7..8ce4a69 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -233,6 +233,7 @@ struct sockaddr_tipc {
 #define TIPC_MCAST_REPLICAST    134     /* Default: TIPC selects. No arg */
 #define TIPC_GROUP_JOIN         135     /* Takes struct tipc_group_req* */
 #define TIPC_GROUP_LEAVE        136     /* No argument */
+#define TIPC_SO_RCVBUF          137     /* Range tipc_rmem_min:tipc_rmem_max */
 
 /*
  * Flag values
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 8b04e60..cfd519b 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2829,6 +2829,7 @@ static int tipc_setsockopt(struct socket *sock, int lvl, 
int opt,
        case TIPC_SRC_DROPPABLE:
        case TIPC_DEST_DROPPABLE:
        case TIPC_CONN_TIMEOUT:
+       case TIPC_SO_RCVBUF:
                if (ol < sizeof(value))
                        return -EINVAL;
                if (get_user(value, (u32 __user *)ov))
@@ -2877,6 +2878,10 @@ static int tipc_setsockopt(struct socket *sock, int lvl, 
int opt,
        case TIPC_GROUP_LEAVE:
                res = tipc_sk_leave(tsk);
                break;
+       case TIPC_SO_RCVBUF:
+               value = max_t(int, value, sysctl_tipc_rmem[0]);
+               sk->sk_rcvbuf = min_t(int, value, sysctl_tipc_rmem[2]);
+               break;
        default:
                res = -EINVAL;
        }
@@ -2945,6 +2950,9 @@ static int tipc_getsockopt(struct socket *sock, int lvl, 
int opt,
                        tipc_group_self(tsk->group, &seq, &scope);
                value = seq.type;
                break;
+       case TIPC_SO_RCVBUF:
+               value = sk->sk_rcvbuf;
+               break;
        default:
                res = -EINVAL;
        }
-- 
2.1.4

Reply via email to