root/net/atm/svc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. svc_shutdown
  2. svc_disconnect
  3. svc_release
  4. svc_bind
  5. svc_connect
  6. svc_listen
  7. svc_accept
  8. svc_getname
  9. svc_change_qos
  10. svc_setsockopt
  11. svc_getsockopt
  12. svc_addparty
  13. svc_dropparty
  14. svc_ioctl
  15. svc_compat_ioctl
  16. svc_create
  17. atmsvc_init
  18. atmsvc_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* net/atm/svc.c - ATM SVC sockets */
   3 
   4 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
   5 
   6 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
   7 
   8 #include <linux/string.h>
   9 #include <linux/net.h>          /* struct socket, struct proto_ops */
  10 #include <linux/errno.h>        /* error codes */
  11 #include <linux/kernel.h>       /* printk */
  12 #include <linux/skbuff.h>
  13 #include <linux/wait.h>
  14 #include <linux/sched/signal.h>
  15 #include <linux/fcntl.h>        /* O_NONBLOCK */
  16 #include <linux/init.h>
  17 #include <linux/atm.h>          /* ATM stuff */
  18 #include <linux/atmsap.h>
  19 #include <linux/atmsvc.h>
  20 #include <linux/atmdev.h>
  21 #include <linux/bitops.h>
  22 #include <net/sock.h>           /* for sock_no_* */
  23 #include <linux/uaccess.h>
  24 #include <linux/export.h>
  25 
  26 #include "resources.h"
  27 #include "common.h"             /* common for PVCs and SVCs */
  28 #include "signaling.h"
  29 #include "addr.h"
  30 
  31 static int svc_create(struct net *net, struct socket *sock, int protocol,
  32                       int kern);
  33 
  34 /*
  35  * Note: since all this is still nicely synchronized with the signaling demon,
  36  *       there's no need to protect sleep loops with clis. If signaling is
  37  *       moved into the kernel, that would change.
  38  */
  39 
  40 
  41 static int svc_shutdown(struct socket *sock, int how)
  42 {
  43         return 0;
  44 }
  45 
  46 static void svc_disconnect(struct atm_vcc *vcc)
  47 {
  48         DEFINE_WAIT(wait);
  49         struct sk_buff *skb;
  50         struct sock *sk = sk_atm(vcc);
  51 
  52         pr_debug("%p\n", vcc);
  53         if (test_bit(ATM_VF_REGIS, &vcc->flags)) {
  54                 sigd_enq(vcc, as_close, NULL, NULL, NULL);
  55                 for (;;) {
  56                         prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE);
  57                         if (test_bit(ATM_VF_RELEASED, &vcc->flags) || !sigd)
  58                                 break;
  59                         schedule();
  60                 }
  61                 finish_wait(sk_sleep(sk), &wait);
  62         }
  63         /* beware - socket is still in use by atmsigd until the last
  64            as_indicate has been answered */
  65         while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
  66                 atm_return(vcc, skb->truesize);
  67                 pr_debug("LISTEN REL\n");
  68                 sigd_enq2(NULL, as_reject, vcc, NULL, NULL, &vcc->qos, 0);
  69                 dev_kfree_skb(skb);
  70         }
  71         clear_bit(ATM_VF_REGIS, &vcc->flags);
  72         /* ... may retry later */
  73 }
  74 
  75 static int svc_release(struct socket *sock)
  76 {
  77         struct sock *sk = sock->sk;
  78         struct atm_vcc *vcc;
  79 
  80         if (sk) {
  81                 vcc = ATM_SD(sock);
  82                 pr_debug("%p\n", vcc);
  83                 clear_bit(ATM_VF_READY, &vcc->flags);
  84                 /*
  85                  * VCC pointer is used as a reference,
  86                  * so we must not free it (thereby subjecting it to re-use)
  87                  * before all pending connections are closed
  88                  */
  89                 svc_disconnect(vcc);
  90                 vcc_release(sock);
  91         }
  92         return 0;
  93 }
  94 
  95 static int svc_bind(struct socket *sock, struct sockaddr *sockaddr,
  96                     int sockaddr_len)
  97 {
  98         DEFINE_WAIT(wait);
  99         struct sock *sk = sock->sk;
 100         struct sockaddr_atmsvc *addr;
 101         struct atm_vcc *vcc;
 102         int error;
 103 
 104         if (sockaddr_len != sizeof(struct sockaddr_atmsvc))
 105                 return -EINVAL;
 106         lock_sock(sk);
 107         if (sock->state == SS_CONNECTED) {
 108                 error = -EISCONN;
 109                 goto out;
 110         }
 111         if (sock->state != SS_UNCONNECTED) {
 112                 error = -EINVAL;
 113                 goto out;
 114         }
 115         vcc = ATM_SD(sock);
 116         addr = (struct sockaddr_atmsvc *) sockaddr;
 117         if (addr->sas_family != AF_ATMSVC) {
 118                 error = -EAFNOSUPPORT;
 119                 goto out;
 120         }
 121         clear_bit(ATM_VF_BOUND, &vcc->flags);
 122             /* failing rebind will kill old binding */
 123         /* @@@ check memory (de)allocation on rebind */
 124         if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
 125                 error = -EBADFD;
 126                 goto out;
 127         }
 128         vcc->local = *addr;
 129         set_bit(ATM_VF_WAITING, &vcc->flags);
 130         sigd_enq(vcc, as_bind, NULL, NULL, &vcc->local);
 131         for (;;) {
 132                 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE);
 133                 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd)
 134                         break;
 135                 schedule();
 136         }
 137         finish_wait(sk_sleep(sk), &wait);
 138         clear_bit(ATM_VF_REGIS, &vcc->flags); /* doesn't count */
 139         if (!sigd) {
 140                 error = -EUNATCH;
 141                 goto out;
 142         }
 143         if (!sk->sk_err)
 144                 set_bit(ATM_VF_BOUND, &vcc->flags);
 145         error = -sk->sk_err;
 146 out:
 147         release_sock(sk);
 148         return error;
 149 }
 150 
 151 static int svc_connect(struct socket *sock, struct sockaddr *sockaddr,
 152                        int sockaddr_len, int flags)
 153 {
 154         DEFINE_WAIT(wait);
 155         struct sock *sk = sock->sk;
 156         struct sockaddr_atmsvc *addr;
 157         struct atm_vcc *vcc = ATM_SD(sock);
 158         int error;
 159 
 160         pr_debug("%p\n", vcc);
 161         lock_sock(sk);
 162         if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) {
 163                 error = -EINVAL;
 164                 goto out;
 165         }
 166 
 167         switch (sock->state) {
 168         default:
 169                 error = -EINVAL;
 170                 goto out;
 171         case SS_CONNECTED:
 172                 error = -EISCONN;
 173                 goto out;
 174         case SS_CONNECTING:
 175                 if (test_bit(ATM_VF_WAITING, &vcc->flags)) {
 176                         error = -EALREADY;
 177                         goto out;
 178                 }
 179                 sock->state = SS_UNCONNECTED;
 180                 if (sk->sk_err) {
 181                         error = -sk->sk_err;
 182                         goto out;
 183                 }
 184                 break;
 185         case SS_UNCONNECTED:
 186                 addr = (struct sockaddr_atmsvc *) sockaddr;
 187                 if (addr->sas_family != AF_ATMSVC) {
 188                         error = -EAFNOSUPPORT;
 189                         goto out;
 190                 }
 191                 if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
 192                         error = -EBADFD;
 193                         goto out;
 194                 }
 195                 if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
 196                     vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) {
 197                         error = -EINVAL;
 198                         goto out;
 199                 }
 200                 if (!vcc->qos.txtp.traffic_class &&
 201                     !vcc->qos.rxtp.traffic_class) {
 202                         error = -EINVAL;
 203                         goto out;
 204                 }
 205                 vcc->remote = *addr;
 206                 set_bit(ATM_VF_WAITING, &vcc->flags);
 207                 sigd_enq(vcc, as_connect, NULL, NULL, &vcc->remote);
 208                 if (flags & O_NONBLOCK) {
 209                         sock->state = SS_CONNECTING;
 210                         error = -EINPROGRESS;
 211                         goto out;
 212                 }
 213                 error = 0;
 214                 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 215                 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
 216                         schedule();
 217                         if (!signal_pending(current)) {
 218                                 prepare_to_wait(sk_sleep(sk), &wait,
 219                                                 TASK_INTERRUPTIBLE);
 220                                 continue;
 221                         }
 222                         pr_debug("*ABORT*\n");
 223                         /*
 224                          * This is tricky:
 225                          *   Kernel ---close--> Demon
 226                          *   Kernel <--close--- Demon
 227                          * or
 228                          *   Kernel ---close--> Demon
 229                          *   Kernel <--error--- Demon
 230                          * or
 231                          *   Kernel ---close--> Demon
 232                          *   Kernel <--okay---- Demon
 233                          *   Kernel <--close--- Demon
 234                          */
 235                         sigd_enq(vcc, as_close, NULL, NULL, NULL);
 236                         while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
 237                                 prepare_to_wait(sk_sleep(sk), &wait,
 238                                                 TASK_INTERRUPTIBLE);
 239                                 schedule();
 240                         }
 241                         if (!sk->sk_err)
 242                                 while (!test_bit(ATM_VF_RELEASED, &vcc->flags) &&
 243                                        sigd) {
 244                                         prepare_to_wait(sk_sleep(sk), &wait,
 245                                                         TASK_INTERRUPTIBLE);
 246                                         schedule();
 247                                 }
 248                         clear_bit(ATM_VF_REGIS, &vcc->flags);
 249                         clear_bit(ATM_VF_RELEASED, &vcc->flags);
 250                         clear_bit(ATM_VF_CLOSE, &vcc->flags);
 251                             /* we're gone now but may connect later */
 252                         error = -EINTR;
 253                         break;
 254                 }
 255                 finish_wait(sk_sleep(sk), &wait);
 256                 if (error)
 257                         goto out;
 258                 if (!sigd) {
 259                         error = -EUNATCH;
 260                         goto out;
 261                 }
 262                 if (sk->sk_err) {
 263                         error = -sk->sk_err;
 264                         goto out;
 265                 }
 266         }
 267 
 268         vcc->qos.txtp.max_pcr = SELECT_TOP_PCR(vcc->qos.txtp);
 269         vcc->qos.txtp.pcr = 0;
 270         vcc->qos.txtp.min_pcr = 0;
 271 
 272         error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci);
 273         if (!error)
 274                 sock->state = SS_CONNECTED;
 275         else
 276                 (void)svc_disconnect(vcc);
 277 out:
 278         release_sock(sk);
 279         return error;
 280 }
 281 
 282 static int svc_listen(struct socket *sock, int backlog)
 283 {
 284         DEFINE_WAIT(wait);
 285         struct sock *sk = sock->sk;
 286         struct atm_vcc *vcc = ATM_SD(sock);
 287         int error;
 288 
 289         pr_debug("%p\n", vcc);
 290         lock_sock(sk);
 291         /* let server handle listen on unbound sockets */
 292         if (test_bit(ATM_VF_SESSION, &vcc->flags)) {
 293                 error = -EINVAL;
 294                 goto out;
 295         }
 296         if (test_bit(ATM_VF_LISTEN, &vcc->flags)) {
 297                 error = -EADDRINUSE;
 298                 goto out;
 299         }
 300         set_bit(ATM_VF_WAITING, &vcc->flags);
 301         sigd_enq(vcc, as_listen, NULL, NULL, &vcc->local);
 302         for (;;) {
 303                 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE);
 304                 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd)
 305                         break;
 306                 schedule();
 307         }
 308         finish_wait(sk_sleep(sk), &wait);
 309         if (!sigd) {
 310                 error = -EUNATCH;
 311                 goto out;
 312         }
 313         set_bit(ATM_VF_LISTEN, &vcc->flags);
 314         vcc_insert_socket(sk);
 315         sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT;
 316         error = -sk->sk_err;
 317 out:
 318         release_sock(sk);
 319         return error;
 320 }
 321 
 322 static int svc_accept(struct socket *sock, struct socket *newsock, int flags,
 323                       bool kern)
 324 {
 325         struct sock *sk = sock->sk;
 326         struct sk_buff *skb;
 327         struct atmsvc_msg *msg;
 328         struct atm_vcc *old_vcc = ATM_SD(sock);
 329         struct atm_vcc *new_vcc;
 330         int error;
 331 
 332         lock_sock(sk);
 333 
 334         error = svc_create(sock_net(sk), newsock, 0, kern);
 335         if (error)
 336                 goto out;
 337 
 338         new_vcc = ATM_SD(newsock);
 339 
 340         pr_debug("%p -> %p\n", old_vcc, new_vcc);
 341         while (1) {
 342                 DEFINE_WAIT(wait);
 343 
 344                 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 345                 while (!(skb = skb_dequeue(&sk->sk_receive_queue)) &&
 346                        sigd) {
 347                         if (test_bit(ATM_VF_RELEASED, &old_vcc->flags))
 348                                 break;
 349                         if (test_bit(ATM_VF_CLOSE, &old_vcc->flags)) {
 350                                 error = -sk->sk_err;
 351                                 break;
 352                         }
 353                         if (flags & O_NONBLOCK) {
 354                                 error = -EAGAIN;
 355                                 break;
 356                         }
 357                         release_sock(sk);
 358                         schedule();
 359                         lock_sock(sk);
 360                         if (signal_pending(current)) {
 361                                 error = -ERESTARTSYS;
 362                                 break;
 363                         }
 364                         prepare_to_wait(sk_sleep(sk), &wait,
 365                                         TASK_INTERRUPTIBLE);
 366                 }
 367                 finish_wait(sk_sleep(sk), &wait);
 368                 if (error)
 369                         goto out;
 370                 if (!skb) {
 371                         error = -EUNATCH;
 372                         goto out;
 373                 }
 374                 msg = (struct atmsvc_msg *)skb->data;
 375                 new_vcc->qos = msg->qos;
 376                 set_bit(ATM_VF_HASQOS, &new_vcc->flags);
 377                 new_vcc->remote = msg->svc;
 378                 new_vcc->local = msg->local;
 379                 new_vcc->sap = msg->sap;
 380                 error = vcc_connect(newsock, msg->pvc.sap_addr.itf,
 381                                     msg->pvc.sap_addr.vpi,
 382                                     msg->pvc.sap_addr.vci);
 383                 dev_kfree_skb(skb);
 384                 sk->sk_ack_backlog--;
 385                 if (error) {
 386                         sigd_enq2(NULL, as_reject, old_vcc, NULL, NULL,
 387                                   &old_vcc->qos, error);
 388                         error = error == -EAGAIN ? -EBUSY : error;
 389                         goto out;
 390                 }
 391                 /* wait should be short, so we ignore the non-blocking flag */
 392                 set_bit(ATM_VF_WAITING, &new_vcc->flags);
 393                 sigd_enq(new_vcc, as_accept, old_vcc, NULL, NULL);
 394                 for (;;) {
 395                         prepare_to_wait(sk_sleep(sk_atm(new_vcc)), &wait,
 396                                         TASK_UNINTERRUPTIBLE);
 397                         if (!test_bit(ATM_VF_WAITING, &new_vcc->flags) || !sigd)
 398                                 break;
 399                         release_sock(sk);
 400                         schedule();
 401                         lock_sock(sk);
 402                 }
 403                 finish_wait(sk_sleep(sk_atm(new_vcc)), &wait);
 404                 if (!sigd) {
 405                         error = -EUNATCH;
 406                         goto out;
 407                 }
 408                 if (!sk_atm(new_vcc)->sk_err)
 409                         break;
 410                 if (sk_atm(new_vcc)->sk_err != ERESTARTSYS) {
 411                         error = -sk_atm(new_vcc)->sk_err;
 412                         goto out;
 413                 }
 414         }
 415         newsock->state = SS_CONNECTED;
 416 out:
 417         release_sock(sk);
 418         return error;
 419 }
 420 
 421 static int svc_getname(struct socket *sock, struct sockaddr *sockaddr,
 422                        int peer)
 423 {
 424         struct sockaddr_atmsvc *addr;
 425 
 426         addr = (struct sockaddr_atmsvc *) sockaddr;
 427         memcpy(addr, peer ? &ATM_SD(sock)->remote : &ATM_SD(sock)->local,
 428                sizeof(struct sockaddr_atmsvc));
 429         return sizeof(struct sockaddr_atmsvc);
 430 }
 431 
 432 int svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos)
 433 {
 434         struct sock *sk = sk_atm(vcc);
 435         DEFINE_WAIT(wait);
 436 
 437         set_bit(ATM_VF_WAITING, &vcc->flags);
 438         sigd_enq2(vcc, as_modify, NULL, NULL, &vcc->local, qos, 0);
 439         for (;;) {
 440                 prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE);
 441                 if (!test_bit(ATM_VF_WAITING, &vcc->flags) ||
 442                     test_bit(ATM_VF_RELEASED, &vcc->flags) || !sigd) {
 443                         break;
 444                 }
 445                 schedule();
 446         }
 447         finish_wait(sk_sleep(sk), &wait);
 448         if (!sigd)
 449                 return -EUNATCH;
 450         return -sk->sk_err;
 451 }
 452 
 453 static int svc_setsockopt(struct socket *sock, int level, int optname,
 454                           char __user *optval, unsigned int optlen)
 455 {
 456         struct sock *sk = sock->sk;
 457         struct atm_vcc *vcc = ATM_SD(sock);
 458         int value, error = 0;
 459 
 460         lock_sock(sk);
 461         switch (optname) {
 462         case SO_ATMSAP:
 463                 if (level != SOL_ATM || optlen != sizeof(struct atm_sap)) {
 464                         error = -EINVAL;
 465                         goto out;
 466                 }
 467                 if (copy_from_user(&vcc->sap, optval, optlen)) {
 468                         error = -EFAULT;
 469                         goto out;
 470                 }
 471                 set_bit(ATM_VF_HASSAP, &vcc->flags);
 472                 break;
 473         case SO_MULTIPOINT:
 474                 if (level != SOL_ATM || optlen != sizeof(int)) {
 475                         error = -EINVAL;
 476                         goto out;
 477                 }
 478                 if (get_user(value, (int __user *)optval)) {
 479                         error = -EFAULT;
 480                         goto out;
 481                 }
 482                 if (value == 1)
 483                         set_bit(ATM_VF_SESSION, &vcc->flags);
 484                 else if (value == 0)
 485                         clear_bit(ATM_VF_SESSION, &vcc->flags);
 486                 else
 487                         error = -EINVAL;
 488                 break;
 489         default:
 490                 error = vcc_setsockopt(sock, level, optname, optval, optlen);
 491         }
 492 
 493 out:
 494         release_sock(sk);
 495         return error;
 496 }
 497 
 498 static int svc_getsockopt(struct socket *sock, int level, int optname,
 499                           char __user *optval, int __user *optlen)
 500 {
 501         struct sock *sk = sock->sk;
 502         int error = 0, len;
 503 
 504         lock_sock(sk);
 505         if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP) {
 506                 error = vcc_getsockopt(sock, level, optname, optval, optlen);
 507                 goto out;
 508         }
 509         if (get_user(len, optlen)) {
 510                 error = -EFAULT;
 511                 goto out;
 512         }
 513         if (len != sizeof(struct atm_sap)) {
 514                 error = -EINVAL;
 515                 goto out;
 516         }
 517         if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) {
 518                 error = -EFAULT;
 519                 goto out;
 520         }
 521 out:
 522         release_sock(sk);
 523         return error;
 524 }
 525 
 526 static int svc_addparty(struct socket *sock, struct sockaddr *sockaddr,
 527                         int sockaddr_len, int flags)
 528 {
 529         DEFINE_WAIT(wait);
 530         struct sock *sk = sock->sk;
 531         struct atm_vcc *vcc = ATM_SD(sock);
 532         int error;
 533 
 534         lock_sock(sk);
 535         set_bit(ATM_VF_WAITING, &vcc->flags);
 536         sigd_enq(vcc, as_addparty, NULL, NULL,
 537                  (struct sockaddr_atmsvc *) sockaddr);
 538         if (flags & O_NONBLOCK) {
 539                 error = -EINPROGRESS;
 540                 goto out;
 541         }
 542         pr_debug("added wait queue\n");
 543         for (;;) {
 544                 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 545                 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd)
 546                         break;
 547                 schedule();
 548         }
 549         finish_wait(sk_sleep(sk), &wait);
 550         error = -xchg(&sk->sk_err_soft, 0);
 551 out:
 552         release_sock(sk);
 553         return error;
 554 }
 555 
 556 static int svc_dropparty(struct socket *sock, int ep_ref)
 557 {
 558         DEFINE_WAIT(wait);
 559         struct sock *sk = sock->sk;
 560         struct atm_vcc *vcc = ATM_SD(sock);
 561         int error;
 562 
 563         lock_sock(sk);
 564         set_bit(ATM_VF_WAITING, &vcc->flags);
 565         sigd_enq2(vcc, as_dropparty, NULL, NULL, NULL, NULL, ep_ref);
 566         for (;;) {
 567                 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 568                 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd)
 569                         break;
 570                 schedule();
 571         }
 572         finish_wait(sk_sleep(sk), &wait);
 573         if (!sigd) {
 574                 error = -EUNATCH;
 575                 goto out;
 576         }
 577         error = -xchg(&sk->sk_err_soft, 0);
 578 out:
 579         release_sock(sk);
 580         return error;
 581 }
 582 
 583 static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 584 {
 585         int error, ep_ref;
 586         struct sockaddr_atmsvc sa;
 587         struct atm_vcc *vcc = ATM_SD(sock);
 588 
 589         switch (cmd) {
 590         case ATM_ADDPARTY:
 591                 if (!test_bit(ATM_VF_SESSION, &vcc->flags))
 592                         return -EINVAL;
 593                 if (copy_from_user(&sa, (void __user *) arg, sizeof(sa)))
 594                         return -EFAULT;
 595                 error = svc_addparty(sock, (struct sockaddr *)&sa, sizeof(sa),
 596                                      0);
 597                 break;
 598         case ATM_DROPPARTY:
 599                 if (!test_bit(ATM_VF_SESSION, &vcc->flags))
 600                         return -EINVAL;
 601                 if (copy_from_user(&ep_ref, (void __user *) arg, sizeof(int)))
 602                         return -EFAULT;
 603                 error = svc_dropparty(sock, ep_ref);
 604                 break;
 605         default:
 606                 error = vcc_ioctl(sock, cmd, arg);
 607         }
 608 
 609         return error;
 610 }
 611 
 612 #ifdef CONFIG_COMPAT
 613 static int svc_compat_ioctl(struct socket *sock, unsigned int cmd,
 614                             unsigned long arg)
 615 {
 616         /* The definition of ATM_ADDPARTY uses the size of struct atm_iobuf.
 617            But actually it takes a struct sockaddr_atmsvc, which doesn't need
 618            compat handling. So all we have to do is fix up cmd... */
 619         if (cmd == COMPAT_ATM_ADDPARTY)
 620                 cmd = ATM_ADDPARTY;
 621 
 622         if (cmd == ATM_ADDPARTY || cmd == ATM_DROPPARTY)
 623                 return svc_ioctl(sock, cmd, arg);
 624         else
 625                 return vcc_compat_ioctl(sock, cmd, arg);
 626 }
 627 #endif /* CONFIG_COMPAT */
 628 
 629 static const struct proto_ops svc_proto_ops = {
 630         .family =       PF_ATMSVC,
 631         .owner =        THIS_MODULE,
 632 
 633         .release =      svc_release,
 634         .bind =         svc_bind,
 635         .connect =      svc_connect,
 636         .socketpair =   sock_no_socketpair,
 637         .accept =       svc_accept,
 638         .getname =      svc_getname,
 639         .poll =         vcc_poll,
 640         .ioctl =        svc_ioctl,
 641 #ifdef CONFIG_COMPAT
 642         .compat_ioctl = svc_compat_ioctl,
 643 #endif
 644         .gettstamp =    sock_gettstamp,
 645         .listen =       svc_listen,
 646         .shutdown =     svc_shutdown,
 647         .setsockopt =   svc_setsockopt,
 648         .getsockopt =   svc_getsockopt,
 649         .sendmsg =      vcc_sendmsg,
 650         .recvmsg =      vcc_recvmsg,
 651         .mmap =         sock_no_mmap,
 652         .sendpage =     sock_no_sendpage,
 653 };
 654 
 655 
 656 static int svc_create(struct net *net, struct socket *sock, int protocol,
 657                       int kern)
 658 {
 659         int error;
 660 
 661         if (!net_eq(net, &init_net))
 662                 return -EAFNOSUPPORT;
 663 
 664         sock->ops = &svc_proto_ops;
 665         error = vcc_create(net, sock, protocol, AF_ATMSVC, kern);
 666         if (error)
 667                 return error;
 668         ATM_SD(sock)->local.sas_family = AF_ATMSVC;
 669         ATM_SD(sock)->remote.sas_family = AF_ATMSVC;
 670         return 0;
 671 }
 672 
 673 static const struct net_proto_family svc_family_ops = {
 674         .family = PF_ATMSVC,
 675         .create = svc_create,
 676         .owner = THIS_MODULE,
 677 };
 678 
 679 
 680 /*
 681  *      Initialize the ATM SVC protocol family
 682  */
 683 
 684 int __init atmsvc_init(void)
 685 {
 686         return sock_register(&svc_family_ops);
 687 }
 688 
 689 void atmsvc_exit(void)
 690 {
 691         sock_unregister(PF_ATMSVC);
 692 }

/* [<][>][^][v][top][bottom][index][help] */