1301013Sadrian// SPDX-License-Identifier: GPL-2.0 2301013Sadrian/* net/atm/svc.c - ATM SVC sockets */ 3301013Sadrian 4301013Sadrian/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ 5301013Sadrian 6301013Sadrian#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ 7301013Sadrian 8301013Sadrian#include <linux/string.h> 9301013Sadrian#include <linux/net.h> /* struct socket, struct proto_ops */ 10301013Sadrian#include <linux/errno.h> /* error codes */ 11301013Sadrian#include <linux/kernel.h> /* printk */ 12301013Sadrian#include <linux/skbuff.h> 13301013Sadrian#include <linux/wait.h> 14301013Sadrian#include <linux/sched/signal.h> 15301013Sadrian#include <linux/fcntl.h> /* O_NONBLOCK */ 16301013Sadrian#include <linux/init.h> 17301013Sadrian#include <linux/atm.h> /* ATM stuff */ 18301013Sadrian#include <linux/atmsap.h> 19301013Sadrian#include <linux/atmsvc.h> 20301013Sadrian#include <linux/atmdev.h> 21301013Sadrian#include <linux/bitops.h> 22301013Sadrian#include <net/sock.h> /* for sock_no_* */ 23301013Sadrian#include <linux/uaccess.h> 24301013Sadrian#include <linux/export.h> 25301013Sadrian 26301013Sadrian#include "resources.h" 27301013Sadrian#include "common.h" /* common for PVCs and SVCs */ 28301013Sadrian#include "signaling.h" 29301013Sadrian#include "addr.h" 30301013Sadrian 31301013Sadrian#ifdef CONFIG_COMPAT 32301013Sadrian/* It actually takes struct sockaddr_atmsvc, not struct atm_iobuf */ 33301013Sadrian#define COMPAT_ATM_ADDPARTY _IOW('a', ATMIOC_SPECIAL + 4, struct compat_atm_iobuf) 34301013Sadrian#endif 35301013Sadrian 36301013Sadrianstatic int svc_create(struct net *net, struct socket *sock, int protocol, 37301013Sadrian int kern); 38301013Sadrian 39301013Sadrian/* 40301013Sadrian * Note: since all this is still nicely synchronized with the signaling demon, 41301013Sadrian * there's no need to protect sleep loops with clis. If signaling is 42301013Sadrian * moved into the kernel, that would change. 43301013Sadrian */ 44301013Sadrian 45301013Sadrian 46301013Sadrianstatic int svc_shutdown(struct socket *sock, int how) 47301013Sadrian{ 48301013Sadrian return 0; 49301013Sadrian} 50301013Sadrian 51301013Sadrianstatic void svc_disconnect(struct atm_vcc *vcc) 52301013Sadrian{ 53301013Sadrian DEFINE_WAIT(wait); 54301013Sadrian struct sk_buff *skb; 55301013Sadrian struct sock *sk = sk_atm(vcc); 56301013Sadrian 57301013Sadrian pr_debug("%p\n", vcc); 58301013Sadrian if (test_bit(ATM_VF_REGIS, &vcc->flags)) { 59301013Sadrian sigd_enq(vcc, as_close, NULL, NULL, NULL); 60301013Sadrian for (;;) { 61301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 62301013Sadrian if (test_bit(ATM_VF_RELEASED, &vcc->flags) || !sigd) 63301013Sadrian break; 64301013Sadrian schedule(); 65301013Sadrian } 66301013Sadrian finish_wait(sk_sleep(sk), &wait); 67301013Sadrian } 68301013Sadrian /* beware - socket is still in use by atmsigd until the last 69301013Sadrian as_indicate has been answered */ 70301013Sadrian while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 71301013Sadrian atm_return(vcc, skb->truesize); 72301013Sadrian pr_debug("LISTEN REL\n"); 73301013Sadrian sigd_enq2(NULL, as_reject, vcc, NULL, NULL, &vcc->qos, 0); 74301013Sadrian dev_kfree_skb(skb); 75301013Sadrian } 76301013Sadrian clear_bit(ATM_VF_REGIS, &vcc->flags); 77301013Sadrian /* ... may retry later */ 78301013Sadrian} 79301013Sadrian 80301013Sadrianstatic int svc_release(struct socket *sock) 81301013Sadrian{ 82301013Sadrian struct sock *sk = sock->sk; 83301013Sadrian struct atm_vcc *vcc; 84301013Sadrian 85301013Sadrian if (sk) { 86301013Sadrian vcc = ATM_SD(sock); 87301013Sadrian pr_debug("%p\n", vcc); 88301013Sadrian clear_bit(ATM_VF_READY, &vcc->flags); 89301013Sadrian /* 90301013Sadrian * VCC pointer is used as a reference, 91301013Sadrian * so we must not free it (thereby subjecting it to re-use) 92301013Sadrian * before all pending connections are closed 93301013Sadrian */ 94301013Sadrian svc_disconnect(vcc); 95301013Sadrian vcc_release(sock); 96301013Sadrian } 97301013Sadrian return 0; 98301013Sadrian} 99301013Sadrian 100301013Sadrianstatic int svc_bind(struct socket *sock, struct sockaddr *sockaddr, 101301013Sadrian int sockaddr_len) 102301303Sadrian{ 103301013Sadrian DEFINE_WAIT(wait); 104301013Sadrian struct sock *sk = sock->sk; 105301013Sadrian struct sockaddr_atmsvc *addr; 106301013Sadrian struct atm_vcc *vcc; 107301013Sadrian int error; 108301013Sadrian 109301013Sadrian if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) 110301013Sadrian return -EINVAL; 111301013Sadrian lock_sock(sk); 112301013Sadrian if (sock->state == SS_CONNECTED) { 113301013Sadrian error = -EISCONN; 114301013Sadrian goto out; 115301013Sadrian } 116301013Sadrian if (sock->state != SS_UNCONNECTED) { 117301013Sadrian error = -EINVAL; 118301013Sadrian goto out; 119301013Sadrian } 120301013Sadrian vcc = ATM_SD(sock); 121301013Sadrian addr = (struct sockaddr_atmsvc *) sockaddr; 122301013Sadrian if (addr->sas_family != AF_ATMSVC) { 123301013Sadrian error = -EAFNOSUPPORT; 124301013Sadrian goto out; 125301013Sadrian } 126301013Sadrian clear_bit(ATM_VF_BOUND, &vcc->flags); 127301013Sadrian /* failing rebind will kill old binding */ 128301013Sadrian /* @@@ check memory (de)allocation on rebind */ 129301013Sadrian if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) { 130301013Sadrian error = -EBADFD; 131301013Sadrian goto out; 132301013Sadrian } 133301013Sadrian vcc->local = *addr; 134301013Sadrian set_bit(ATM_VF_WAITING, &vcc->flags); 135301013Sadrian sigd_enq(vcc, as_bind, NULL, NULL, &vcc->local); 136301013Sadrian for (;;) { 137301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 138301013Sadrian if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd) 139301013Sadrian break; 140301013Sadrian schedule(); 141301013Sadrian } 142301013Sadrian finish_wait(sk_sleep(sk), &wait); 143301013Sadrian clear_bit(ATM_VF_REGIS, &vcc->flags); /* doesn't count */ 144301013Sadrian if (!sigd) { 145301013Sadrian error = -EUNATCH; 146301013Sadrian goto out; 147301013Sadrian } 148301013Sadrian if (!sk->sk_err) 149301013Sadrian set_bit(ATM_VF_BOUND, &vcc->flags); 150301013Sadrian error = -sk->sk_err; 151301013Sadrianout: 152301013Sadrian release_sock(sk); 153301013Sadrian return error; 154301013Sadrian} 155301013Sadrian 156301013Sadrianstatic int svc_connect(struct socket *sock, struct sockaddr *sockaddr, 157301013Sadrian int sockaddr_len, int flags) 158301013Sadrian{ 159301013Sadrian DEFINE_WAIT(wait); 160301013Sadrian struct sock *sk = sock->sk; 161301013Sadrian struct sockaddr_atmsvc *addr; 162301013Sadrian struct atm_vcc *vcc = ATM_SD(sock); 163301013Sadrian int error; 164301013Sadrian 165301013Sadrian pr_debug("%p\n", vcc); 166301013Sadrian lock_sock(sk); 167301013Sadrian if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) { 168301013Sadrian error = -EINVAL; 169301013Sadrian goto out; 170301013Sadrian } 171301013Sadrian 172301013Sadrian switch (sock->state) { 173301013Sadrian default: 174301013Sadrian error = -EINVAL; 175301013Sadrian goto out; 176301013Sadrian case SS_CONNECTED: 177301013Sadrian error = -EISCONN; 178301013Sadrian goto out; 179301013Sadrian case SS_CONNECTING: 180301013Sadrian if (test_bit(ATM_VF_WAITING, &vcc->flags)) { 181301013Sadrian error = -EALREADY; 182301013Sadrian goto out; 183301013Sadrian } 184301013Sadrian sock->state = SS_UNCONNECTED; 185301013Sadrian if (sk->sk_err) { 186301013Sadrian error = -sk->sk_err; 187301013Sadrian goto out; 188301013Sadrian } 189301013Sadrian break; 190301013Sadrian case SS_UNCONNECTED: 191301013Sadrian addr = (struct sockaddr_atmsvc *) sockaddr; 192301013Sadrian if (addr->sas_family != AF_ATMSVC) { 193301013Sadrian error = -EAFNOSUPPORT; 194301013Sadrian goto out; 195301013Sadrian } 196301013Sadrian if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) { 197301013Sadrian error = -EBADFD; 198301013Sadrian goto out; 199301013Sadrian } 200301013Sadrian if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS || 201301013Sadrian vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) { 202301013Sadrian error = -EINVAL; 203301013Sadrian goto out; 204301013Sadrian } 205301013Sadrian if (!vcc->qos.txtp.traffic_class && 206301013Sadrian !vcc->qos.rxtp.traffic_class) { 207301013Sadrian error = -EINVAL; 208301013Sadrian goto out; 209301013Sadrian } 210301013Sadrian vcc->remote = *addr; 211301013Sadrian set_bit(ATM_VF_WAITING, &vcc->flags); 212301013Sadrian sigd_enq(vcc, as_connect, NULL, NULL, &vcc->remote); 213301013Sadrian if (flags & O_NONBLOCK) { 214301013Sadrian sock->state = SS_CONNECTING; 215301013Sadrian error = -EINPROGRESS; 216301013Sadrian goto out; 217301013Sadrian } 218301013Sadrian error = 0; 219301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 220301013Sadrian while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 221301013Sadrian schedule(); 222301013Sadrian if (!signal_pending(current)) { 223301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, 224301013Sadrian TASK_INTERRUPTIBLE); 225301013Sadrian continue; 226301013Sadrian } 227301013Sadrian pr_debug("*ABORT*\n"); 228301013Sadrian /* 229301013Sadrian * This is tricky: 230301013Sadrian * Kernel ---close--> Demon 231301013Sadrian * Kernel <--close--- Demon 232301013Sadrian * or 233301013Sadrian * Kernel ---close--> Demon 234301013Sadrian * Kernel <--error--- Demon 235301013Sadrian * or 236301013Sadrian * Kernel ---close--> Demon 237301013Sadrian * Kernel <--okay---- Demon 238301013Sadrian * Kernel <--close--- Demon 239301013Sadrian */ 240301013Sadrian sigd_enq(vcc, as_close, NULL, NULL, NULL); 241301013Sadrian while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 242301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, 243301013Sadrian TASK_INTERRUPTIBLE); 244301013Sadrian schedule(); 245301013Sadrian } 246301013Sadrian if (!sk->sk_err) 247301013Sadrian while (!test_bit(ATM_VF_RELEASED, &vcc->flags) && 248301013Sadrian sigd) { 249301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, 250301013Sadrian TASK_INTERRUPTIBLE); 251301013Sadrian schedule(); 252301013Sadrian } 253301013Sadrian clear_bit(ATM_VF_REGIS, &vcc->flags); 254301013Sadrian clear_bit(ATM_VF_RELEASED, &vcc->flags); 255301013Sadrian clear_bit(ATM_VF_CLOSE, &vcc->flags); 256301013Sadrian /* we're gone now but may connect later */ 257301013Sadrian error = -EINTR; 258301013Sadrian break; 259301013Sadrian } 260301013Sadrian finish_wait(sk_sleep(sk), &wait); 261301013Sadrian if (error) 262301013Sadrian goto out; 263301013Sadrian if (!sigd) { 264301013Sadrian error = -EUNATCH; 265301013Sadrian goto out; 266301013Sadrian } 267301013Sadrian if (sk->sk_err) { 268301013Sadrian error = -sk->sk_err; 269301013Sadrian goto out; 270301013Sadrian } 271301013Sadrian } 272301013Sadrian 273301013Sadrian vcc->qos.txtp.max_pcr = SELECT_TOP_PCR(vcc->qos.txtp); 274301013Sadrian vcc->qos.txtp.pcr = 0; 275301013Sadrian vcc->qos.txtp.min_pcr = 0; 276301013Sadrian 277301013Sadrian error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci); 278301013Sadrian if (!error) 279301013Sadrian sock->state = SS_CONNECTED; 280301013Sadrian else 281301013Sadrian (void)svc_disconnect(vcc); 282301013Sadrianout: 283301013Sadrian release_sock(sk); 284301013Sadrian return error; 285301013Sadrian} 286301013Sadrian 287301013Sadrianstatic int svc_listen(struct socket *sock, int backlog) 288301013Sadrian{ 289301013Sadrian DEFINE_WAIT(wait); 290301013Sadrian struct sock *sk = sock->sk; 291301013Sadrian struct atm_vcc *vcc = ATM_SD(sock); 292301013Sadrian int error; 293301013Sadrian 294301013Sadrian pr_debug("%p\n", vcc); 295301013Sadrian lock_sock(sk); 296301013Sadrian /* let server handle listen on unbound sockets */ 297301013Sadrian if (test_bit(ATM_VF_SESSION, &vcc->flags)) { 298301013Sadrian error = -EINVAL; 299301013Sadrian goto out; 300301013Sadrian } 301301013Sadrian if (test_bit(ATM_VF_LISTEN, &vcc->flags)) { 302301013Sadrian error = -EADDRINUSE; 303301013Sadrian goto out; 304301013Sadrian } 305301013Sadrian set_bit(ATM_VF_WAITING, &vcc->flags); 306301013Sadrian sigd_enq(vcc, as_listen, NULL, NULL, &vcc->local); 307301013Sadrian for (;;) { 308301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 309301013Sadrian if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd) 310301013Sadrian break; 311301013Sadrian schedule(); 312301013Sadrian } 313301013Sadrian finish_wait(sk_sleep(sk), &wait); 314301013Sadrian if (!sigd) { 315301013Sadrian error = -EUNATCH; 316301013Sadrian goto out; 317301013Sadrian } 318301013Sadrian set_bit(ATM_VF_LISTEN, &vcc->flags); 319301013Sadrian vcc_insert_socket(sk); 320301013Sadrian sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT; 321301013Sadrian error = -sk->sk_err; 322301013Sadrianout: 323301013Sadrian release_sock(sk); 324301013Sadrian return error; 325301013Sadrian} 326301013Sadrian 327301013Sadrianstatic int svc_accept(struct socket *sock, struct socket *newsock, int flags, 328301013Sadrian bool kern) 329301013Sadrian{ 330301013Sadrian struct sock *sk = sock->sk; 331301013Sadrian struct sk_buff *skb; 332301013Sadrian struct atmsvc_msg *msg; 333301013Sadrian struct atm_vcc *old_vcc = ATM_SD(sock); 334301013Sadrian struct atm_vcc *new_vcc; 335301013Sadrian int error; 336301013Sadrian 337301013Sadrian lock_sock(sk); 338301013Sadrian 339301013Sadrian error = svc_create(sock_net(sk), newsock, 0, kern); 340301013Sadrian if (error) 341301013Sadrian goto out; 342301013Sadrian 343301013Sadrian new_vcc = ATM_SD(newsock); 344301013Sadrian 345301013Sadrian pr_debug("%p -> %p\n", old_vcc, new_vcc); 346301013Sadrian while (1) { 347301013Sadrian DEFINE_WAIT(wait); 348301013Sadrian 349301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 350301013Sadrian while (!(skb = skb_dequeue(&sk->sk_receive_queue)) && 351301013Sadrian sigd) { 352301013Sadrian if (test_bit(ATM_VF_RELEASED, &old_vcc->flags)) 353301013Sadrian break; 354301013Sadrian if (test_bit(ATM_VF_CLOSE, &old_vcc->flags)) { 355301013Sadrian error = -sk->sk_err; 356301013Sadrian break; 357301013Sadrian } 358301013Sadrian if (flags & O_NONBLOCK) { 359301013Sadrian error = -EAGAIN; 360301013Sadrian break; 361301013Sadrian } 362301013Sadrian release_sock(sk); 363301013Sadrian schedule(); 364301013Sadrian lock_sock(sk); 365301013Sadrian if (signal_pending(current)) { 366301013Sadrian error = -ERESTARTSYS; 367301013Sadrian break; 368301013Sadrian } 369301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, 370301013Sadrian TASK_INTERRUPTIBLE); 371301013Sadrian } 372301013Sadrian finish_wait(sk_sleep(sk), &wait); 373301013Sadrian if (error) 374301013Sadrian goto out; 375301013Sadrian if (!skb) { 376301013Sadrian error = -EUNATCH; 377301013Sadrian goto out; 378301013Sadrian } 379301013Sadrian msg = (struct atmsvc_msg *)skb->data; 380301013Sadrian new_vcc->qos = msg->qos; 381301013Sadrian set_bit(ATM_VF_HASQOS, &new_vcc->flags); 382301013Sadrian new_vcc->remote = msg->svc; 383301013Sadrian new_vcc->local = msg->local; 384301013Sadrian new_vcc->sap = msg->sap; 385301013Sadrian error = vcc_connect(newsock, msg->pvc.sap_addr.itf, 386301013Sadrian msg->pvc.sap_addr.vpi, 387301013Sadrian msg->pvc.sap_addr.vci); 388301013Sadrian dev_kfree_skb(skb); 389301013Sadrian sk_acceptq_removed(sk); 390301013Sadrian if (error) { 391301013Sadrian sigd_enq2(NULL, as_reject, old_vcc, NULL, NULL, 392301013Sadrian &old_vcc->qos, error); 393301013Sadrian error = error == -EAGAIN ? -EBUSY : error; 394301013Sadrian goto out; 395301013Sadrian } 396301013Sadrian /* wait should be short, so we ignore the non-blocking flag */ 397301013Sadrian set_bit(ATM_VF_WAITING, &new_vcc->flags); 398301013Sadrian sigd_enq(new_vcc, as_accept, old_vcc, NULL, NULL); 399301013Sadrian for (;;) { 400301013Sadrian prepare_to_wait(sk_sleep(sk_atm(new_vcc)), &wait, 401301013Sadrian TASK_UNINTERRUPTIBLE); 402301013Sadrian if (!test_bit(ATM_VF_WAITING, &new_vcc->flags) || !sigd) 403301013Sadrian break; 404301013Sadrian release_sock(sk); 405301013Sadrian schedule(); 406301013Sadrian lock_sock(sk); 407301013Sadrian } 408301013Sadrian finish_wait(sk_sleep(sk_atm(new_vcc)), &wait); 409301013Sadrian if (!sigd) { 410301013Sadrian error = -EUNATCH; 411301013Sadrian goto out; 412301013Sadrian } 413301013Sadrian if (!sk_atm(new_vcc)->sk_err) 414301013Sadrian break; 415301013Sadrian if (sk_atm(new_vcc)->sk_err != ERESTARTSYS) { 416301013Sadrian error = -sk_atm(new_vcc)->sk_err; 417301013Sadrian goto out; 418301013Sadrian } 419301013Sadrian } 420301013Sadrian newsock->state = SS_CONNECTED; 421301013Sadrianout: 422301013Sadrian release_sock(sk); 423301013Sadrian return error; 424301013Sadrian} 425301013Sadrian 426301013Sadrianstatic int svc_getname(struct socket *sock, struct sockaddr *sockaddr, 427301013Sadrian int peer) 428301013Sadrian{ 429301013Sadrian struct sockaddr_atmsvc *addr; 430301013Sadrian 431301013Sadrian addr = (struct sockaddr_atmsvc *) sockaddr; 432301013Sadrian memcpy(addr, peer ? &ATM_SD(sock)->remote : &ATM_SD(sock)->local, 433301013Sadrian sizeof(struct sockaddr_atmsvc)); 434301013Sadrian return sizeof(struct sockaddr_atmsvc); 435301013Sadrian} 436301013Sadrian 437301013Sadrianint svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos) 438301013Sadrian{ 439301013Sadrian struct sock *sk = sk_atm(vcc); 440301013Sadrian DEFINE_WAIT(wait); 441301013Sadrian 442301013Sadrian set_bit(ATM_VF_WAITING, &vcc->flags); 443301013Sadrian sigd_enq2(vcc, as_modify, NULL, NULL, &vcc->local, qos, 0); 444301013Sadrian for (;;) { 445301013Sadrian prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); 446301013Sadrian if (!test_bit(ATM_VF_WAITING, &vcc->flags) || 447301013Sadrian test_bit(ATM_VF_RELEASED, &vcc->flags) || !sigd) { 448301013Sadrian break; 449301013Sadrian } 450301013Sadrian schedule(); 451301013Sadrian } 452301013Sadrian finish_wait(sk_sleep(sk), &wait); 453301013Sadrian if (!sigd) 454301013Sadrian return -EUNATCH; 455301013Sadrian return -sk->sk_err; 456301013Sadrian} 457301013Sadrian 458301013Sadrianstatic int svc_setsockopt(struct socket *sock, int level, int optname, 459301013Sadrian sockptr_t optval, unsigned int optlen) 460301013Sadrian{ 461301013Sadrian struct sock *sk = sock->sk; 462301013Sadrian struct atm_vcc *vcc = ATM_SD(sock); 463301013Sadrian int value, error = 0; 464301013Sadrian 465301013Sadrian lock_sock(sk); 466301013Sadrian switch (optname) { 467301013Sadrian case SO_ATMSAP: 468301013Sadrian if (level != SOL_ATM || optlen != sizeof(struct atm_sap)) { 469301013Sadrian error = -EINVAL; 470301013Sadrian goto out; 471301013Sadrian } 472301013Sadrian if (copy_from_sockptr(&vcc->sap, optval, optlen)) { 473301013Sadrian error = -EFAULT; 474301013Sadrian goto out; 475301013Sadrian } 476301013Sadrian set_bit(ATM_VF_HASSAP, &vcc->flags); 477301013Sadrian break; 478301013Sadrian case SO_MULTIPOINT: 479301013Sadrian if (level != SOL_ATM || optlen != sizeof(int)) { 480301013Sadrian error = -EINVAL; 481301013Sadrian goto out; 482301013Sadrian } 483301013Sadrian if (copy_from_sockptr(&value, optval, sizeof(int))) { 484301013Sadrian error = -EFAULT; 485301013Sadrian goto out; 486301013Sadrian } 487301013Sadrian if (value == 1) 488301013Sadrian set_bit(ATM_VF_SESSION, &vcc->flags); 489301013Sadrian else if (value == 0) 490301089Sadrian clear_bit(ATM_VF_SESSION, &vcc->flags); 491301089Sadrian else 492301089Sadrian error = -EINVAL; 493301089Sadrian break; 494301089Sadrian default: 495301089Sadrian error = vcc_setsockopt(sock, level, optname, optval, optlen); 496301089Sadrian } 497301089Sadrian 498301089Sadrianout: 499301089Sadrian release_sock(sk); 500301089Sadrian return error; 501301013Sadrian} 502301013Sadrian 503301013Sadrianstatic int svc_getsockopt(struct socket *sock, int level, int optname, 504301013Sadrian char __user *optval, int __user *optlen) 505301013Sadrian{ 506301013Sadrian struct sock *sk = sock->sk; 507301013Sadrian int error = 0, len; 508301013Sadrian 509301089Sadrian lock_sock(sk); 510301089Sadrian if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP) { 511301089Sadrian error = vcc_getsockopt(sock, level, optname, optval, optlen); 512301089Sadrian goto out; 513301089Sadrian } 514301089Sadrian if (get_user(len, optlen)) { 515301089Sadrian error = -EFAULT; 516301089Sadrian goto out; 517301089Sadrian } 518301089Sadrian if (len != sizeof(struct atm_sap)) { 519301013Sadrian error = -EINVAL; 520301013Sadrian goto out; 521301013Sadrian } 522301013Sadrian if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) { 523301013Sadrian error = -EFAULT; 524 goto out; 525 } 526out: 527 release_sock(sk); 528 return error; 529} 530 531static int svc_addparty(struct socket *sock, struct sockaddr *sockaddr, 532 int sockaddr_len, int flags) 533{ 534 DEFINE_WAIT(wait); 535 struct sock *sk = sock->sk; 536 struct atm_vcc *vcc = ATM_SD(sock); 537 int error; 538 539 lock_sock(sk); 540 set_bit(ATM_VF_WAITING, &vcc->flags); 541 sigd_enq(vcc, as_addparty, NULL, NULL, 542 (struct sockaddr_atmsvc *) sockaddr); 543 if (flags & O_NONBLOCK) { 544 error = -EINPROGRESS; 545 goto out; 546 } 547 pr_debug("added wait queue\n"); 548 for (;;) { 549 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 550 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd) 551 break; 552 schedule(); 553 } 554 finish_wait(sk_sleep(sk), &wait); 555 error = -xchg(&sk->sk_err_soft, 0); 556out: 557 release_sock(sk); 558 return error; 559} 560 561static int svc_dropparty(struct socket *sock, int ep_ref) 562{ 563 DEFINE_WAIT(wait); 564 struct sock *sk = sock->sk; 565 struct atm_vcc *vcc = ATM_SD(sock); 566 int error; 567 568 lock_sock(sk); 569 set_bit(ATM_VF_WAITING, &vcc->flags); 570 sigd_enq2(vcc, as_dropparty, NULL, NULL, NULL, NULL, ep_ref); 571 for (;;) { 572 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 573 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd) 574 break; 575 schedule(); 576 } 577 finish_wait(sk_sleep(sk), &wait); 578 if (!sigd) { 579 error = -EUNATCH; 580 goto out; 581 } 582 error = -xchg(&sk->sk_err_soft, 0); 583out: 584 release_sock(sk); 585 return error; 586} 587 588static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 589{ 590 int error, ep_ref; 591 struct sockaddr_atmsvc sa; 592 struct atm_vcc *vcc = ATM_SD(sock); 593 594 switch (cmd) { 595 case ATM_ADDPARTY: 596 if (!test_bit(ATM_VF_SESSION, &vcc->flags)) 597 return -EINVAL; 598 if (copy_from_user(&sa, (void __user *) arg, sizeof(sa))) 599 return -EFAULT; 600 error = svc_addparty(sock, (struct sockaddr *)&sa, sizeof(sa), 601 0); 602 break; 603 case ATM_DROPPARTY: 604 if (!test_bit(ATM_VF_SESSION, &vcc->flags)) 605 return -EINVAL; 606 if (copy_from_user(&ep_ref, (void __user *) arg, sizeof(int))) 607 return -EFAULT; 608 error = svc_dropparty(sock, ep_ref); 609 break; 610 default: 611 error = vcc_ioctl(sock, cmd, arg); 612 } 613 614 return error; 615} 616 617#ifdef CONFIG_COMPAT 618static int svc_compat_ioctl(struct socket *sock, unsigned int cmd, 619 unsigned long arg) 620{ 621 /* The definition of ATM_ADDPARTY uses the size of struct atm_iobuf. 622 But actually it takes a struct sockaddr_atmsvc, which doesn't need 623 compat handling. So all we have to do is fix up cmd... */ 624 if (cmd == COMPAT_ATM_ADDPARTY) 625 cmd = ATM_ADDPARTY; 626 627 if (cmd == ATM_ADDPARTY || cmd == ATM_DROPPARTY) 628 return svc_ioctl(sock, cmd, arg); 629 else 630 return vcc_compat_ioctl(sock, cmd, arg); 631} 632#endif /* CONFIG_COMPAT */ 633 634static const struct proto_ops svc_proto_ops = { 635 .family = PF_ATMSVC, 636 .owner = THIS_MODULE, 637 638 .release = svc_release, 639 .bind = svc_bind, 640 .connect = svc_connect, 641 .socketpair = sock_no_socketpair, 642 .accept = svc_accept, 643 .getname = svc_getname, 644 .poll = vcc_poll, 645 .ioctl = svc_ioctl, 646#ifdef CONFIG_COMPAT 647 .compat_ioctl = svc_compat_ioctl, 648#endif 649 .gettstamp = sock_gettstamp, 650 .listen = svc_listen, 651 .shutdown = svc_shutdown, 652 .setsockopt = svc_setsockopt, 653 .getsockopt = svc_getsockopt, 654 .sendmsg = vcc_sendmsg, 655 .recvmsg = vcc_recvmsg, 656 .mmap = sock_no_mmap, 657}; 658 659 660static int svc_create(struct net *net, struct socket *sock, int protocol, 661 int kern) 662{ 663 int error; 664 665 if (!net_eq(net, &init_net)) 666 return -EAFNOSUPPORT; 667 668 sock->ops = &svc_proto_ops; 669 error = vcc_create(net, sock, protocol, AF_ATMSVC, kern); 670 if (error) 671 return error; 672 ATM_SD(sock)->local.sas_family = AF_ATMSVC; 673 ATM_SD(sock)->remote.sas_family = AF_ATMSVC; 674 return 0; 675} 676 677static const struct net_proto_family svc_family_ops = { 678 .family = PF_ATMSVC, 679 .create = svc_create, 680 .owner = THIS_MODULE, 681}; 682 683 684/* 685 * Initialize the ATM SVC protocol family 686 */ 687 688int __init atmsvc_init(void) 689{ 690 return sock_register(&svc_family_ops); 691} 692 693void atmsvc_exit(void) 694{ 695 sock_unregister(PF_ATMSVC); 696} 697