diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 150 | 
1 files changed, 118 insertions, 32 deletions
| diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 515ce38e4f4c..6cc7ddd2fb7c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/socket.c: TIPC socket API | 2 | * net/tipc/socket.c: TIPC socket API | 
| 3 | * | 3 | * | 
| 4 | * Copyright (c) 2001-2007, 2012 Ericsson AB | 4 | * Copyright (c) 2001-2007, 2012 Ericsson AB | 
| 5 | * Copyright (c) 2004-2008, 2010-2012, Wind River Systems | 5 | * Copyright (c) 2004-2008, 2010-2013, Wind River Systems | 
| 6 | * All rights reserved. | 6 | * All rights reserved. | 
| 7 | * | 7 | * | 
| 8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | 
| @@ -43,8 +43,6 @@ | |||
| 43 | #define SS_LISTENING -1 /* socket is listening */ | 43 | #define SS_LISTENING -1 /* socket is listening */ | 
| 44 | #define SS_READY -2 /* socket is connectionless */ | 44 | #define SS_READY -2 /* socket is connectionless */ | 
| 45 | 45 | ||
| 46 | #define CONN_OVERLOAD_LIMIT ((TIPC_FLOW_CONTROL_WIN * 2 + 1) * \ | ||
| 47 | SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE)) | ||
| 48 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 46 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 
| 49 | 47 | ||
| 50 | struct tipc_sock { | 48 | struct tipc_sock { | 
| @@ -65,12 +63,15 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); | |||
| 65 | static void wakeupdispatch(struct tipc_port *tport); | 63 | static void wakeupdispatch(struct tipc_port *tport); | 
| 66 | static void tipc_data_ready(struct sock *sk, int len); | 64 | static void tipc_data_ready(struct sock *sk, int len); | 
| 67 | static void tipc_write_space(struct sock *sk); | 65 | static void tipc_write_space(struct sock *sk); | 
| 66 | static int release(struct socket *sock); | ||
| 67 | static int accept(struct socket *sock, struct socket *new_sock, int flags); | ||
| 68 | 68 | ||
| 69 | static const struct proto_ops packet_ops; | 69 | static const struct proto_ops packet_ops; | 
| 70 | static const struct proto_ops stream_ops; | 70 | static const struct proto_ops stream_ops; | 
| 71 | static const struct proto_ops msg_ops; | 71 | static const struct proto_ops msg_ops; | 
| 72 | 72 | ||
| 73 | static struct proto tipc_proto; | 73 | static struct proto tipc_proto; | 
| 74 | static struct proto tipc_proto_kern; | ||
| 74 | 75 | ||
| 75 | static int sockets_enabled; | 76 | static int sockets_enabled; | 
| 76 | 77 | ||
| @@ -143,7 +144,7 @@ static void reject_rx_queue(struct sock *sk) | |||
| 143 | } | 144 | } | 
| 144 | 145 | ||
| 145 | /** | 146 | /** | 
| 146 | * tipc_create - create a TIPC socket | 147 | * tipc_sk_create - create a TIPC socket | 
| 147 | * @net: network namespace (must be default network) | 148 | * @net: network namespace (must be default network) | 
| 148 | * @sock: pre-allocated socket structure | 149 | * @sock: pre-allocated socket structure | 
| 149 | * @protocol: protocol indicator (must be 0) | 150 | * @protocol: protocol indicator (must be 0) | 
| @@ -154,8 +155,8 @@ static void reject_rx_queue(struct sock *sk) | |||
| 154 | * | 155 | * | 
| 155 | * Returns 0 on success, errno otherwise | 156 | * Returns 0 on success, errno otherwise | 
| 156 | */ | 157 | */ | 
| 157 | static int tipc_create(struct net *net, struct socket *sock, int protocol, | 158 | static int tipc_sk_create(struct net *net, struct socket *sock, int protocol, | 
| 158 | int kern) | 159 | int kern) | 
| 159 | { | 160 | { | 
| 160 | const struct proto_ops *ops; | 161 | const struct proto_ops *ops; | 
| 161 | socket_state state; | 162 | socket_state state; | 
| @@ -185,13 +186,17 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
| 185 | } | 186 | } | 
| 186 | 187 | ||
| 187 | /* Allocate socket's protocol area */ | 188 | /* Allocate socket's protocol area */ | 
| 188 | sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto); | 189 | if (!kern) | 
| 190 | sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto); | ||
| 191 | else | ||
| 192 | sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto_kern); | ||
| 193 | |||
| 189 | if (sk == NULL) | 194 | if (sk == NULL) | 
| 190 | return -ENOMEM; | 195 | return -ENOMEM; | 
| 191 | 196 | ||
| 192 | /* Allocate TIPC port for socket to use */ | 197 | /* Allocate TIPC port for socket to use */ | 
| 193 | tp_ptr = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, | 198 | tp_ptr = tipc_createport(sk, &dispatch, &wakeupdispatch, | 
| 194 | TIPC_LOW_IMPORTANCE); | 199 | TIPC_LOW_IMPORTANCE); | 
| 195 | if (unlikely(!tp_ptr)) { | 200 | if (unlikely(!tp_ptr)) { | 
| 196 | sk_free(sk); | 201 | sk_free(sk); | 
| 197 | return -ENOMEM; | 202 | return -ENOMEM; | 
| @@ -203,6 +208,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
| 203 | 208 | ||
| 204 | sock_init_data(sock, sk); | 209 | sock_init_data(sock, sk); | 
| 205 | sk->sk_backlog_rcv = backlog_rcv; | 210 | sk->sk_backlog_rcv = backlog_rcv; | 
| 211 | sk->sk_rcvbuf = sysctl_tipc_rmem[1]; | ||
| 206 | sk->sk_data_ready = tipc_data_ready; | 212 | sk->sk_data_ready = tipc_data_ready; | 
| 207 | sk->sk_write_space = tipc_write_space; | 213 | sk->sk_write_space = tipc_write_space; | 
| 208 | tipc_sk(sk)->p = tp_ptr; | 214 | tipc_sk(sk)->p = tp_ptr; | 
| @@ -220,6 +226,78 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
| 220 | } | 226 | } | 
| 221 | 227 | ||
| 222 | /** | 228 | /** | 
| 229 | * tipc_sock_create_local - create TIPC socket from inside TIPC module | ||
| 230 | * @type: socket type - SOCK_RDM or SOCK_SEQPACKET | ||
| 231 | * | ||
| 232 | * We cannot use sock_creat_kern here because it bumps module user count. | ||
| 233 | * Since socket owner and creator is the same module we must make sure | ||
| 234 | * that module count remains zero for module local sockets, otherwise | ||
| 235 | * we cannot do rmmod. | ||
| 236 | * | ||
| 237 | * Returns 0 on success, errno otherwise | ||
| 238 | */ | ||
| 239 | int tipc_sock_create_local(int type, struct socket **res) | ||
| 240 | { | ||
| 241 | int rc; | ||
| 242 | struct sock *sk; | ||
| 243 | |||
| 244 | rc = sock_create_lite(AF_TIPC, type, 0, res); | ||
| 245 | if (rc < 0) { | ||
| 246 | pr_err("Failed to create kernel socket\n"); | ||
| 247 | return rc; | ||
| 248 | } | ||
| 249 | tipc_sk_create(&init_net, *res, 0, 1); | ||
| 250 | |||
| 251 | sk = (*res)->sk; | ||
| 252 | |||
| 253 | return 0; | ||
| 254 | } | ||
| 255 | |||
| 256 | /** | ||
| 257 | * tipc_sock_release_local - release socket created by tipc_sock_create_local | ||
| 258 | * @sock: the socket to be released. | ||
| 259 | * | ||
| 260 | * Module reference count is not incremented when such sockets are created, | ||
| 261 | * so we must keep it from being decremented when they are released. | ||
| 262 | */ | ||
| 263 | void tipc_sock_release_local(struct socket *sock) | ||
| 264 | { | ||
| 265 | release(sock); | ||
| 266 | sock->ops = NULL; | ||
| 267 | sock_release(sock); | ||
| 268 | } | ||
| 269 | |||
| 270 | /** | ||
| 271 | * tipc_sock_accept_local - accept a connection on a socket created | ||
| 272 | * with tipc_sock_create_local. Use this function to avoid that | ||
| 273 | * module reference count is inadvertently incremented. | ||
| 274 | * | ||
| 275 | * @sock: the accepting socket | ||
| 276 | * @newsock: reference to the new socket to be created | ||
| 277 | * @flags: socket flags | ||
| 278 | */ | ||
| 279 | |||
| 280 | int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, | ||
| 281 | int flags) | ||
| 282 | { | ||
| 283 | struct sock *sk = sock->sk; | ||
| 284 | int ret; | ||
| 285 | |||
| 286 | ret = sock_create_lite(sk->sk_family, sk->sk_type, | ||
| 287 | sk->sk_protocol, newsock); | ||
| 288 | if (ret < 0) | ||
| 289 | return ret; | ||
| 290 | |||
| 291 | ret = accept(sock, *newsock, flags); | ||
| 292 | if (ret < 0) { | ||
| 293 | sock_release(*newsock); | ||
| 294 | return ret; | ||
| 295 | } | ||
| 296 | (*newsock)->ops = sock->ops; | ||
| 297 | return ret; | ||
| 298 | } | ||
| 299 | |||
| 300 | /** | ||
| 223 | * release - destroy a TIPC socket | 301 | * release - destroy a TIPC socket | 
| 224 | * @sock: socket to destroy | 302 | * @sock: socket to destroy | 
| 225 | * | 303 | * | 
| @@ -324,7 +402,9 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | |||
| 324 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) | 402 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) | 
| 325 | return -EAFNOSUPPORT; | 403 | return -EAFNOSUPPORT; | 
| 326 | 404 | ||
| 327 | if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES) | 405 | if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && | 
| 406 | (addr->addr.nameseq.type != TIPC_TOP_SRV) && | ||
| 407 | (addr->addr.nameseq.type != TIPC_CFG_SRV)) | ||
| 328 | return -EACCES; | 408 | return -EACCES; | 
| 329 | 409 | ||
| 330 | return (addr->scope > 0) ? | 410 | return (addr->scope > 0) ? | 
| @@ -519,8 +599,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
| 519 | res = -EISCONN; | 599 | res = -EISCONN; | 
| 520 | goto exit; | 600 | goto exit; | 
| 521 | } | 601 | } | 
| 522 | if ((tport->published) || | 602 | if (tport->published) { | 
| 523 | ((sock->type == SOCK_STREAM) && (total_len != 0))) { | ||
| 524 | res = -EOPNOTSUPP; | 603 | res = -EOPNOTSUPP; | 
| 525 | goto exit; | 604 | goto exit; | 
| 526 | } | 605 | } | 
| @@ -810,7 +889,7 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) | |||
| 810 | * Returns 0 if successful, otherwise errno | 889 | * Returns 0 if successful, otherwise errno | 
| 811 | */ | 890 | */ | 
| 812 | static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | 891 | static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | 
| 813 | struct tipc_port *tport) | 892 | struct tipc_port *tport) | 
| 814 | { | 893 | { | 
| 815 | u32 anc_data[3]; | 894 | u32 anc_data[3]; | 
| 816 | u32 err; | 895 | u32 err; | 
| @@ -1011,8 +1090,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1011 | 1090 | ||
| 1012 | lock_sock(sk); | 1091 | lock_sock(sk); | 
| 1013 | 1092 | ||
| 1014 | if (unlikely((sock->state == SS_UNCONNECTED) || | 1093 | if (unlikely((sock->state == SS_UNCONNECTED))) { | 
| 1015 | (sock->state == SS_CONNECTING))) { | ||
| 1016 | res = -ENOTCONN; | 1094 | res = -ENOTCONN; | 
| 1017 | goto exit; | 1095 | goto exit; | 
| 1018 | } | 1096 | } | 
| @@ -1179,7 +1257,7 @@ static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf) | |||
| 1179 | /* Accept only ACK or NACK message */ | 1257 | /* Accept only ACK or NACK message */ | 
| 1180 | if (unlikely(msg_errcode(msg))) { | 1258 | if (unlikely(msg_errcode(msg))) { | 
| 1181 | sock->state = SS_DISCONNECTING; | 1259 | sock->state = SS_DISCONNECTING; | 
| 1182 | sk->sk_err = -ECONNREFUSED; | 1260 | sk->sk_err = ECONNREFUSED; | 
| 1183 | retval = TIPC_OK; | 1261 | retval = TIPC_OK; | 
| 1184 | break; | 1262 | break; | 
| 1185 | } | 1263 | } | 
| @@ -1190,7 +1268,7 @@ static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf) | |||
| 1190 | res = auto_connect(sock, msg); | 1268 | res = auto_connect(sock, msg); | 
| 1191 | if (res) { | 1269 | if (res) { | 
| 1192 | sock->state = SS_DISCONNECTING; | 1270 | sock->state = SS_DISCONNECTING; | 
| 1193 | sk->sk_err = res; | 1271 | sk->sk_err = -res; | 
| 1194 | retval = TIPC_OK; | 1272 | retval = TIPC_OK; | 
| 1195 | break; | 1273 | break; | 
| 1196 | } | 1274 | } | 
| @@ -1233,10 +1311,10 @@ static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf) | |||
| 1233 | * For all connectionless messages, by default new queue limits are | 1311 | * For all connectionless messages, by default new queue limits are | 
| 1234 | * as belows: | 1312 | * as belows: | 
| 1235 | * | 1313 | * | 
| 1236 | * TIPC_LOW_IMPORTANCE (5MB) | 1314 | * TIPC_LOW_IMPORTANCE (4 MB) | 
| 1237 | * TIPC_MEDIUM_IMPORTANCE (10MB) | 1315 | * TIPC_MEDIUM_IMPORTANCE (8 MB) | 
| 1238 | * TIPC_HIGH_IMPORTANCE (20MB) | 1316 | * TIPC_HIGH_IMPORTANCE (16 MB) | 
| 1239 | * TIPC_CRITICAL_IMPORTANCE (40MB) | 1317 | * TIPC_CRITICAL_IMPORTANCE (32 MB) | 
| 1240 | * | 1318 | * | 
| 1241 | * Returns overload limit according to corresponding message importance | 1319 | * Returns overload limit according to corresponding message importance | 
| 1242 | */ | 1320 | */ | 
| @@ -1246,9 +1324,10 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf) | |||
| 1246 | unsigned int limit; | 1324 | unsigned int limit; | 
| 1247 | 1325 | ||
| 1248 | if (msg_connected(msg)) | 1326 | if (msg_connected(msg)) | 
| 1249 | limit = CONN_OVERLOAD_LIMIT; | 1327 | limit = sysctl_tipc_rmem[2]; | 
| 1250 | else | 1328 | else | 
| 1251 | limit = sk->sk_rcvbuf << (msg_importance(msg) + 5); | 1329 | limit = sk->sk_rcvbuf >> TIPC_CRITICAL_IMPORTANCE << | 
| 1330 | msg_importance(msg); | ||
| 1252 | return limit; | 1331 | return limit; | 
| 1253 | } | 1332 | } | 
| 1254 | 1333 | ||
| @@ -1327,7 +1406,7 @@ static int backlog_rcv(struct sock *sk, struct sk_buff *buf) | |||
| 1327 | */ | 1406 | */ | 
| 1328 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) | 1407 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) | 
| 1329 | { | 1408 | { | 
| 1330 | struct sock *sk = (struct sock *)tport->usr_handle; | 1409 | struct sock *sk = tport->sk; | 
| 1331 | u32 res; | 1410 | u32 res; | 
| 1332 | 1411 | ||
| 1333 | /* | 1412 | /* | 
| @@ -1358,7 +1437,7 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) | |||
| 1358 | */ | 1437 | */ | 
| 1359 | static void wakeupdispatch(struct tipc_port *tport) | 1438 | static void wakeupdispatch(struct tipc_port *tport) | 
| 1360 | { | 1439 | { | 
| 1361 | struct sock *sk = (struct sock *)tport->usr_handle; | 1440 | struct sock *sk = tport->sk; | 
| 1362 | 1441 | ||
| 1363 | sk->sk_write_space(sk); | 1442 | sk->sk_write_space(sk); | 
| 1364 | } | 1443 | } | 
| @@ -1531,7 +1610,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
| 1531 | 1610 | ||
| 1532 | buf = skb_peek(&sk->sk_receive_queue); | 1611 | buf = skb_peek(&sk->sk_receive_queue); | 
| 1533 | 1612 | ||
| 1534 | res = tipc_create(sock_net(sock->sk), new_sock, 0, 0); | 1613 | res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 1); | 
| 1535 | if (res) | 1614 | if (res) | 
| 1536 | goto exit; | 1615 | goto exit; | 
| 1537 | 1616 | ||
| @@ -1657,8 +1736,8 @@ restart: | |||
| 1657 | * | 1736 | * | 
| 1658 | * Returns 0 on success, errno otherwise | 1737 | * Returns 0 on success, errno otherwise | 
| 1659 | */ | 1738 | */ | 
| 1660 | static int setsockopt(struct socket *sock, | 1739 | static int setsockopt(struct socket *sock, int lvl, int opt, char __user *ov, | 
| 1661 | int lvl, int opt, char __user *ov, unsigned int ol) | 1740 | unsigned int ol) | 
| 1662 | { | 1741 | { | 
| 1663 | struct sock *sk = sock->sk; | 1742 | struct sock *sk = sock->sk; | 
| 1664 | struct tipc_port *tport = tipc_sk_port(sk); | 1743 | struct tipc_port *tport = tipc_sk_port(sk); | 
| @@ -1716,8 +1795,8 @@ static int setsockopt(struct socket *sock, | |||
| 1716 | * | 1795 | * | 
| 1717 | * Returns 0 on success, errno otherwise | 1796 | * Returns 0 on success, errno otherwise | 
| 1718 | */ | 1797 | */ | 
| 1719 | static int getsockopt(struct socket *sock, | 1798 | static int getsockopt(struct socket *sock, int lvl, int opt, char __user *ov, | 
| 1720 | int lvl, int opt, char __user *ov, int __user *ol) | 1799 | int __user *ol) | 
| 1721 | { | 1800 | { | 
| 1722 | struct sock *sk = sock->sk; | 1801 | struct sock *sk = sock->sk; | 
| 1723 | struct tipc_port *tport = tipc_sk_port(sk); | 1802 | struct tipc_port *tport = tipc_sk_port(sk); | 
| @@ -1841,13 +1920,20 @@ static const struct proto_ops stream_ops = { | |||
| 1841 | static const struct net_proto_family tipc_family_ops = { | 1920 | static const struct net_proto_family tipc_family_ops = { | 
| 1842 | .owner = THIS_MODULE, | 1921 | .owner = THIS_MODULE, | 
| 1843 | .family = AF_TIPC, | 1922 | .family = AF_TIPC, | 
| 1844 | .create = tipc_create | 1923 | .create = tipc_sk_create | 
| 1845 | }; | 1924 | }; | 
| 1846 | 1925 | ||
| 1847 | static struct proto tipc_proto = { | 1926 | static struct proto tipc_proto = { | 
| 1848 | .name = "TIPC", | 1927 | .name = "TIPC", | 
| 1849 | .owner = THIS_MODULE, | 1928 | .owner = THIS_MODULE, | 
| 1850 | .obj_size = sizeof(struct tipc_sock) | 1929 | .obj_size = sizeof(struct tipc_sock), | 
| 1930 | .sysctl_rmem = sysctl_tipc_rmem | ||
| 1931 | }; | ||
| 1932 | |||
| 1933 | static struct proto tipc_proto_kern = { | ||
| 1934 | .name = "TIPC", | ||
| 1935 | .obj_size = sizeof(struct tipc_sock), | ||
| 1936 | .sysctl_rmem = sysctl_tipc_rmem | ||
| 1851 | }; | 1937 | }; | 
| 1852 | 1938 | ||
| 1853 | /** | 1939 | /** | 
