linux/net/atm/common.c
<<
>>
Prefs
   1/* net/atm/common.c - ATM sockets (common part for PVC and SVC) */
   2
   3/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
   4
   5
   6#include <linux/module.h>
   7#include <linux/kmod.h>
   8#include <linux/net.h>          /* struct socket, struct proto_ops */
   9#include <linux/atm.h>          /* ATM stuff */
  10#include <linux/atmdev.h>
  11#include <linux/socket.h>       /* SOL_SOCKET */
  12#include <linux/errno.h>        /* error codes */
  13#include <linux/capability.h>
  14#include <linux/mm.h>
  15#include <linux/sched.h>
  16#include <linux/time.h>         /* struct timeval */
  17#include <linux/skbuff.h>
  18#include <linux/bitops.h>
  19#include <linux/init.h>
  20#include <net/sock.h>           /* struct sock */
  21
  22#include <asm/uaccess.h>
  23#include <asm/atomic.h>
  24#include <asm/poll.h>
  25
  26
  27#include "resources.h"          /* atm_find_dev */
  28#include "common.h"             /* prototypes */
  29#include "protocols.h"          /* atm_init_<transport> */
  30#include "addr.h"               /* address registry */
  31#include "signaling.h"          /* for WAITING and sigd_attach */
  32
  33struct hlist_head vcc_hash[VCC_HTABLE_SIZE];
  34DEFINE_RWLOCK(vcc_sklist_lock);
  35
  36static void __vcc_insert_socket(struct sock *sk)
  37{
  38        struct atm_vcc *vcc = atm_sk(sk);
  39        struct hlist_head *head = &vcc_hash[vcc->vci &
  40                                        (VCC_HTABLE_SIZE - 1)];
  41        sk->sk_hash = vcc->vci & (VCC_HTABLE_SIZE - 1);
  42        sk_add_node(sk, head);
  43}
  44
  45void vcc_insert_socket(struct sock *sk)
  46{
  47        write_lock_irq(&vcc_sklist_lock);
  48        __vcc_insert_socket(sk);
  49        write_unlock_irq(&vcc_sklist_lock);
  50}
  51
  52static void vcc_remove_socket(struct sock *sk)
  53{
  54        write_lock_irq(&vcc_sklist_lock);
  55        sk_del_node_init(sk);
  56        write_unlock_irq(&vcc_sklist_lock);
  57}
  58
  59
  60static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size)
  61{
  62        struct sk_buff *skb;
  63        struct sock *sk = sk_atm(vcc);
  64
  65        if (atomic_read(&sk->sk_wmem_alloc) && !atm_may_send(vcc, size)) {
  66                pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n",
  67                        atomic_read(&sk->sk_wmem_alloc), size,
  68                        sk->sk_sndbuf);
  69                return NULL;
  70        }
  71        while (!(skb = alloc_skb(size,GFP_KERNEL))) schedule();
  72        pr_debug("AlTx %d += %d\n", atomic_read(&sk->sk_wmem_alloc),
  73                skb->truesize);
  74        atomic_add(skb->truesize, &sk->sk_wmem_alloc);
  75        return skb;
  76}
  77
  78
  79EXPORT_SYMBOL(vcc_hash);
  80EXPORT_SYMBOL(vcc_sklist_lock);
  81EXPORT_SYMBOL(vcc_insert_socket);
  82
  83static void vcc_sock_destruct(struct sock *sk)
  84{
  85        if (atomic_read(&sk->sk_rmem_alloc))
  86                printk(KERN_DEBUG "vcc_sock_destruct: rmem leakage (%d bytes) detected.\n", atomic_read(&sk->sk_rmem_alloc));
  87
  88        if (atomic_read(&sk->sk_wmem_alloc))
  89                printk(KERN_DEBUG "vcc_sock_destruct: wmem leakage (%d bytes) detected.\n", atomic_read(&sk->sk_wmem_alloc));
  90}
  91
  92static void vcc_def_wakeup(struct sock *sk)
  93{
  94        read_lock(&sk->sk_callback_lock);
  95        if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
  96                wake_up(sk->sk_sleep);
  97        read_unlock(&sk->sk_callback_lock);
  98}
  99
 100static inline int vcc_writable(struct sock *sk)
 101{
 102        struct atm_vcc *vcc = atm_sk(sk);
 103
 104        return (vcc->qos.txtp.max_sdu +
 105                atomic_read(&sk->sk_wmem_alloc)) <= sk->sk_sndbuf;
 106}
 107
 108static void vcc_write_space(struct sock *sk)
 109{
 110        read_lock(&sk->sk_callback_lock);
 111
 112        if (vcc_writable(sk)) {
 113                if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
 114                        wake_up_interruptible(sk->sk_sleep);
 115
 116                sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
 117        }
 118
 119        read_unlock(&sk->sk_callback_lock);
 120}
 121
 122static struct proto vcc_proto = {
 123        .name     = "VCC",
 124        .owner    = THIS_MODULE,
 125        .obj_size = sizeof(struct atm_vcc),
 126};
 127
 128int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
 129{
 130        struct sock *sk;
 131        struct atm_vcc *vcc;
 132
 133        sock->sk = NULL;
 134        if (sock->type == SOCK_STREAM)
 135                return -EINVAL;
 136        sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto);
 137        if (!sk)
 138                return -ENOMEM;
 139        sock_init_data(sock, sk);
 140        sk->sk_state_change = vcc_def_wakeup;
 141        sk->sk_write_space = vcc_write_space;
 142
 143        vcc = atm_sk(sk);
 144        vcc->dev = NULL;
 145        memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc));
 146        memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc));
 147        vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */
 148        atomic_set(&sk->sk_wmem_alloc, 0);
 149        atomic_set(&sk->sk_rmem_alloc, 0);
 150        vcc->push = NULL;
 151        vcc->pop = NULL;
 152        vcc->push_oam = NULL;
 153        vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
 154        vcc->atm_options = vcc->aal_options = 0;
 155        sk->sk_destruct = vcc_sock_destruct;
 156        return 0;
 157}
 158
 159
 160static void vcc_destroy_socket(struct sock *sk)
 161{
 162        struct atm_vcc *vcc = atm_sk(sk);
 163        struct sk_buff *skb;
 164
 165        set_bit(ATM_VF_CLOSE, &vcc->flags);
 166        clear_bit(ATM_VF_READY, &vcc->flags);
 167        if (vcc->dev) {
 168                if (vcc->dev->ops->close)
 169                        vcc->dev->ops->close(vcc);
 170                if (vcc->push)
 171                        vcc->push(vcc, NULL); /* atmarpd has no push */
 172
 173                while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
 174                        atm_return(vcc,skb->truesize);
 175                        kfree_skb(skb);
 176                }
 177
 178                module_put(vcc->dev->ops->owner);
 179                atm_dev_put(vcc->dev);
 180        }
 181
 182        vcc_remove_socket(sk);
 183}
 184
 185
 186int vcc_release(struct socket *sock)
 187{
 188        struct sock *sk = sock->sk;
 189
 190        if (sk) {
 191                lock_sock(sk);
 192                vcc_destroy_socket(sock->sk);
 193                release_sock(sk);
 194                sock_put(sk);
 195        }
 196
 197        return 0;
 198}
 199
 200
 201void vcc_release_async(struct atm_vcc *vcc, int reply)
 202{
 203        struct sock *sk = sk_atm(vcc);
 204
 205        set_bit(ATM_VF_CLOSE, &vcc->flags);
 206        sk->sk_shutdown |= RCV_SHUTDOWN;
 207        sk->sk_err = -reply;
 208        clear_bit(ATM_VF_WAITING, &vcc->flags);
 209        sk->sk_state_change(sk);
 210}
 211
 212
 213EXPORT_SYMBOL(vcc_release_async);
 214
 215
 216void atm_dev_release_vccs(struct atm_dev *dev)
 217{
 218        int i;
 219
 220        write_lock_irq(&vcc_sklist_lock);
 221        for (i = 0; i < VCC_HTABLE_SIZE; i++) {
 222                struct hlist_head *head = &vcc_hash[i];
 223                struct hlist_node *node, *tmp;
 224                struct sock *s;
 225                struct atm_vcc *vcc;
 226
 227                sk_for_each_safe(s, node, tmp, head) {
 228                        vcc = atm_sk(s);
 229                        if (vcc->dev == dev) {
 230                                vcc_release_async(vcc, -EPIPE);
 231                                sk_del_node_init(s);
 232                        }
 233                }
 234        }
 235        write_unlock_irq(&vcc_sklist_lock);
 236}
 237
 238
 239static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
 240{
 241        int max_sdu;
 242
 243        if (!tp->traffic_class) return 0;
 244        switch (aal) {
 245                case ATM_AAL0:
 246                        max_sdu = ATM_CELL_SIZE-1;
 247                        break;
 248                case ATM_AAL34:
 249                        max_sdu = ATM_MAX_AAL34_PDU;
 250                        break;
 251                default:
 252                        printk(KERN_WARNING "ATM: AAL problems ... "
 253                            "(%d)\n",aal);
 254                        /* fall through */
 255                case ATM_AAL5:
 256                        max_sdu = ATM_MAX_AAL5_PDU;
 257        }
 258        if (!tp->max_sdu) tp->max_sdu = max_sdu;
 259        else if (tp->max_sdu > max_sdu) return -EINVAL;
 260        if (!tp->max_cdv) tp->max_cdv = ATM_MAX_CDV;
 261        return 0;
 262}
 263
 264
 265static int check_ci(const struct atm_vcc *vcc, short vpi, int vci)
 266{
 267        struct hlist_head *head = &vcc_hash[vci &
 268                                        (VCC_HTABLE_SIZE - 1)];
 269        struct hlist_node *node;
 270        struct sock *s;
 271        struct atm_vcc *walk;
 272
 273        sk_for_each(s, node, head) {
 274                walk = atm_sk(s);
 275                if (walk->dev != vcc->dev)
 276                        continue;
 277                if (test_bit(ATM_VF_ADDR, &walk->flags) && walk->vpi == vpi &&
 278                    walk->vci == vci && ((walk->qos.txtp.traffic_class !=
 279                    ATM_NONE && vcc->qos.txtp.traffic_class != ATM_NONE) ||
 280                    (walk->qos.rxtp.traffic_class != ATM_NONE &&
 281                    vcc->qos.rxtp.traffic_class != ATM_NONE)))
 282                        return -EADDRINUSE;
 283        }
 284
 285        /* allow VCCs with same VPI/VCI iff they don't collide on
 286           TX/RX (but we may refuse such sharing for other reasons,
 287           e.g. if protocol requires to have both channels) */
 288
 289        return 0;
 290}
 291
 292
 293static int find_ci(const struct atm_vcc *vcc, short *vpi, int *vci)
 294{
 295        static short p;        /* poor man's per-device cache */
 296        static int c;
 297        short old_p;
 298        int old_c;
 299        int err;
 300
 301        if (*vpi != ATM_VPI_ANY && *vci != ATM_VCI_ANY) {
 302                err = check_ci(vcc, *vpi, *vci);
 303                return err;
 304        }
 305        /* last scan may have left values out of bounds for current device */
 306        if (*vpi != ATM_VPI_ANY)
 307                p = *vpi;
 308        else if (p >= 1 << vcc->dev->ci_range.vpi_bits)
 309                p = 0;
 310        if (*vci != ATM_VCI_ANY)
 311                c = *vci;
 312        else if (c < ATM_NOT_RSV_VCI || c >= 1 << vcc->dev->ci_range.vci_bits)
 313                        c = ATM_NOT_RSV_VCI;
 314        old_p = p;
 315        old_c = c;
 316        do {
 317                if (!check_ci(vcc, p, c)) {
 318                        *vpi = p;
 319                        *vci = c;
 320                        return 0;
 321                }
 322                if (*vci == ATM_VCI_ANY) {
 323                        c++;
 324                        if (c >= 1 << vcc->dev->ci_range.vci_bits)
 325                                c = ATM_NOT_RSV_VCI;
 326                }
 327                if ((c == ATM_NOT_RSV_VCI || *vci != ATM_VCI_ANY) &&
 328                    *vpi == ATM_VPI_ANY) {
 329                        p++;
 330                        if (p >= 1 << vcc->dev->ci_range.vpi_bits) p = 0;
 331                }
 332        }
 333        while (old_p != p || old_c != c);
 334        return -EADDRINUSE;
 335}
 336
 337
 338static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi,
 339                         int vci)
 340{
 341        struct sock *sk = sk_atm(vcc);
 342        int error;
 343
 344        if ((vpi != ATM_VPI_UNSPEC && vpi != ATM_VPI_ANY &&
 345            vpi >> dev->ci_range.vpi_bits) || (vci != ATM_VCI_UNSPEC &&
 346            vci != ATM_VCI_ANY && vci >> dev->ci_range.vci_bits))
 347                return -EINVAL;
 348        if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE))
 349                return -EPERM;
 350        error = -ENODEV;
 351        if (!try_module_get(dev->ops->owner))
 352                return error;
 353        vcc->dev = dev;
 354        write_lock_irq(&vcc_sklist_lock);
 355        if (test_bit(ATM_DF_REMOVED, &dev->flags) ||
 356            (error = find_ci(vcc, &vpi, &vci))) {
 357                write_unlock_irq(&vcc_sklist_lock);
 358                goto fail_module_put;
 359        }
 360        vcc->vpi = vpi;
 361        vcc->vci = vci;
 362        __vcc_insert_socket(sk);
 363        write_unlock_irq(&vcc_sklist_lock);
 364        switch (vcc->qos.aal) {
 365                case ATM_AAL0:
 366                        error = atm_init_aal0(vcc);
 367                        vcc->stats = &dev->stats.aal0;
 368                        break;
 369                case ATM_AAL34:
 370                        error = atm_init_aal34(vcc);
 371                        vcc->stats = &dev->stats.aal34;
 372                        break;
 373                case ATM_NO_AAL:
 374                        /* ATM_AAL5 is also used in the "0 for default" case */
 375                        vcc->qos.aal = ATM_AAL5;
 376                        /* fall through */
 377                case ATM_AAL5:
 378                        error = atm_init_aal5(vcc);
 379                        vcc->stats = &dev->stats.aal5;
 380                        break;
 381                default:
 382                        error = -EPROTOTYPE;
 383        }
 384        if (!error) error = adjust_tp(&vcc->qos.txtp,vcc->qos.aal);
 385        if (!error) error = adjust_tp(&vcc->qos.rxtp,vcc->qos.aal);
 386        if (error)
 387                goto fail;
 388        pr_debug("VCC %d.%d, AAL %d\n",vpi,vci,vcc->qos.aal);
 389        pr_debug("  TX: %d, PCR %d..%d, SDU %d\n",vcc->qos.txtp.traffic_class,
 390            vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu);
 391        pr_debug("  RX: %d, PCR %d..%d, SDU %d\n",vcc->qos.rxtp.traffic_class,
 392            vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu);
 393
 394        if (dev->ops->open) {
 395                if ((error = dev->ops->open(vcc)))
 396                        goto fail;
 397        }
 398        return 0;
 399
 400fail:
 401        vcc_remove_socket(sk);
 402fail_module_put:
 403        module_put(dev->ops->owner);
 404        /* ensure we get dev module ref count correct */
 405        vcc->dev = NULL;
 406        return error;
 407}
 408
 409
 410int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
 411{
 412        struct atm_dev *dev;
 413        struct atm_vcc *vcc = ATM_SD(sock);
 414        int error;
 415
 416        pr_debug("vcc_connect (vpi %d, vci %d)\n",vpi,vci);
 417        if (sock->state == SS_CONNECTED)
 418                return -EISCONN;
 419        if (sock->state != SS_UNCONNECTED)
 420                return -EINVAL;
 421        if (!(vpi || vci))
 422                return -EINVAL;
 423
 424        if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC)
 425                clear_bit(ATM_VF_PARTIAL,&vcc->flags);
 426        else
 427                if (test_bit(ATM_VF_PARTIAL,&vcc->flags))
 428                        return -EINVAL;
 429        pr_debug("vcc_connect (TX: cl %d,bw %d-%d,sdu %d; "
 430            "RX: cl %d,bw %d-%d,sdu %d,AAL %s%d)\n",
 431            vcc->qos.txtp.traffic_class,vcc->qos.txtp.min_pcr,
 432            vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu,
 433            vcc->qos.rxtp.traffic_class,vcc->qos.rxtp.min_pcr,
 434            vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu,
 435            vcc->qos.aal == ATM_AAL5 ? "" : vcc->qos.aal == ATM_AAL0 ? "" :
 436            " ??? code ",vcc->qos.aal == ATM_AAL0 ? 0 : vcc->qos.aal);
 437        if (!test_bit(ATM_VF_HASQOS, &vcc->flags))
 438                return -EBADFD;
 439        if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
 440            vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
 441                return -EINVAL;
 442        if (likely(itf != ATM_ITF_ANY)) {
 443                dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf);
 444        } else {
 445                dev = NULL;
 446                mutex_lock(&atm_dev_mutex);
 447                if (!list_empty(&atm_devs)) {
 448                        dev = list_entry(atm_devs.next, struct atm_dev, dev_list);
 449                        atm_dev_hold(dev);
 450                }
 451                mutex_unlock(&atm_dev_mutex);
 452        }
 453        if (!dev)
 454                return -ENODEV;
 455        error = __vcc_connect(vcc, dev, vpi, vci);
 456        if (error) {
 457                atm_dev_put(dev);
 458                return error;
 459        }
 460        if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
 461                set_bit(ATM_VF_PARTIAL,&vcc->flags);
 462        if (test_bit(ATM_VF_READY,&ATM_SD(sock)->flags))
 463                sock->state = SS_CONNECTED;
 464        return 0;
 465}
 466
 467
 468int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 469                size_t size, int flags)
 470{
 471        struct sock *sk = sock->sk;
 472        struct atm_vcc *vcc;
 473        struct sk_buff *skb;
 474        int copied, error = -EINVAL;
 475
 476        if (sock->state != SS_CONNECTED)
 477                return -ENOTCONN;
 478        if (flags & ~MSG_DONTWAIT)              /* only handle MSG_DONTWAIT */
 479                return -EOPNOTSUPP;
 480        vcc = ATM_SD(sock);
 481        if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
 482            test_bit(ATM_VF_CLOSE,&vcc->flags) ||
 483            !test_bit(ATM_VF_READY, &vcc->flags))
 484                return 0;
 485
 486        skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &error);
 487        if (!skb)
 488                return error;
 489
 490        copied = skb->len;
 491        if (copied > size) {
 492                copied = size;
 493                msg->msg_flags |= MSG_TRUNC;
 494        }
 495
 496        error = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 497        if (error)
 498                return error;
 499        sock_recv_timestamp(msg, sk, skb);
 500        pr_debug("RcvM %d -= %d\n", atomic_read(&sk->sk_rmem_alloc), skb->truesize);
 501        atm_return(vcc, skb->truesize);
 502        skb_free_datagram(sk, skb);
 503        return copied;
 504}
 505
 506
 507int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
 508                size_t total_len)
 509{
 510        struct sock *sk = sock->sk;
 511        DEFINE_WAIT(wait);
 512        struct atm_vcc *vcc;
 513        struct sk_buff *skb;
 514        int eff,error;
 515        const void __user *buff;
 516        int size;
 517
 518        lock_sock(sk);
 519        if (sock->state != SS_CONNECTED) {
 520                error = -ENOTCONN;
 521                goto out;
 522        }
 523        if (m->msg_name) {
 524                error = -EISCONN;
 525                goto out;
 526        }
 527        if (m->msg_iovlen != 1) {
 528                error = -ENOSYS; /* fix this later @@@ */
 529                goto out;
 530        }
 531        buff = m->msg_iov->iov_base;
 532        size = m->msg_iov->iov_len;
 533        vcc = ATM_SD(sock);
 534        if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
 535            test_bit(ATM_VF_CLOSE, &vcc->flags) ||
 536            !test_bit(ATM_VF_READY, &vcc->flags)) {
 537                error = -EPIPE;
 538                send_sig(SIGPIPE, current, 0);
 539                goto out;
 540        }
 541        if (!size) {
 542                error = 0;
 543                goto out;
 544        }
 545        if (size < 0 || size > vcc->qos.txtp.max_sdu) {
 546                error = -EMSGSIZE;
 547                goto out;
 548        }
 549
 550        eff = (size+3) & ~3; /* align to word boundary */
 551        prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 552        error = 0;
 553        while (!(skb = alloc_tx(vcc,eff))) {
 554                if (m->msg_flags & MSG_DONTWAIT) {
 555                        error = -EAGAIN;
 556                        break;
 557                }
 558                schedule();
 559                if (signal_pending(current)) {
 560                        error = -ERESTARTSYS;
 561                        break;
 562                }
 563                if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
 564                    test_bit(ATM_VF_CLOSE,&vcc->flags) ||
 565                    !test_bit(ATM_VF_READY,&vcc->flags)) {
 566                        error = -EPIPE;
 567                        send_sig(SIGPIPE, current, 0);
 568                        break;
 569                }
 570                prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 571        }
 572        finish_wait(sk->sk_sleep, &wait);
 573        if (error)
 574                goto out;
 575        skb->dev = NULL; /* for paths shared with net_device interfaces */
 576        ATM_SKB(skb)->atm_options = vcc->atm_options;
 577        if (copy_from_user(skb_put(skb,size),buff,size)) {
 578                kfree_skb(skb);
 579                error = -EFAULT;
 580                goto out;
 581        }
 582        if (eff != size) memset(skb->data+size,0,eff-size);
 583        error = vcc->dev->ops->send(vcc,skb);
 584        error = error ? error : size;
 585out:
 586        release_sock(sk);
 587        return error;
 588}
 589
 590
 591unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
 592{
 593        struct sock *sk = sock->sk;
 594        struct atm_vcc *vcc;
 595        unsigned int mask;
 596
 597        poll_wait(file, sk->sk_sleep, wait);
 598        mask = 0;
 599
 600        vcc = ATM_SD(sock);
 601
 602        /* exceptional events */
 603        if (sk->sk_err)
 604                mask = POLLERR;
 605
 606        if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
 607            test_bit(ATM_VF_CLOSE, &vcc->flags))
 608                mask |= POLLHUP;
 609
 610        /* readable? */
 611        if (!skb_queue_empty(&sk->sk_receive_queue))
 612                mask |= POLLIN | POLLRDNORM;
 613
 614        /* writable? */
 615        if (sock->state == SS_CONNECTING &&
 616            test_bit(ATM_VF_WAITING, &vcc->flags))
 617                return mask;
 618
 619        if (vcc->qos.txtp.traffic_class != ATM_NONE &&
 620            vcc_writable(sk))
 621                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
 622
 623        return mask;
 624}
 625
 626
 627static int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
 628{
 629        int error;
 630
 631        /*
 632         * Don't let the QoS change the already connected AAL type nor the
 633         * traffic class.
 634         */
 635        if (qos->aal != vcc->qos.aal ||
 636            qos->rxtp.traffic_class != vcc->qos.rxtp.traffic_class ||
 637            qos->txtp.traffic_class != vcc->qos.txtp.traffic_class)
 638                return -EINVAL;
 639        error = adjust_tp(&qos->txtp,qos->aal);
 640        if (!error) error = adjust_tp(&qos->rxtp,qos->aal);
 641        if (error) return error;
 642        if (!vcc->dev->ops->change_qos) return -EOPNOTSUPP;
 643        if (sk_atm(vcc)->sk_family == AF_ATMPVC)
 644                return vcc->dev->ops->change_qos(vcc,qos,ATM_MF_SET);
 645        return svc_change_qos(vcc,qos);
 646}
 647
 648
 649static int check_tp(const struct atm_trafprm *tp)
 650{
 651        /* @@@ Should be merged with adjust_tp */
 652        if (!tp->traffic_class || tp->traffic_class == ATM_ANYCLASS) return 0;
 653        if (tp->traffic_class != ATM_UBR && !tp->min_pcr && !tp->pcr &&
 654            !tp->max_pcr) return -EINVAL;
 655        if (tp->min_pcr == ATM_MAX_PCR) return -EINVAL;
 656        if (tp->min_pcr && tp->max_pcr && tp->max_pcr != ATM_MAX_PCR &&
 657            tp->min_pcr > tp->max_pcr) return -EINVAL;
 658        /*
 659         * We allow pcr to be outside [min_pcr,max_pcr], because later
 660         * adjustment may still push it in the valid range.
 661         */
 662        return 0;
 663}
 664
 665
 666static int check_qos(const struct atm_qos *qos)
 667{
 668        int error;
 669
 670        if (!qos->txtp.traffic_class && !qos->rxtp.traffic_class)
 671                return -EINVAL;
 672        if (qos->txtp.traffic_class != qos->rxtp.traffic_class &&
 673            qos->txtp.traffic_class && qos->rxtp.traffic_class &&
 674            qos->txtp.traffic_class != ATM_ANYCLASS &&
 675            qos->rxtp.traffic_class != ATM_ANYCLASS) return -EINVAL;
 676        error = check_tp(&qos->txtp);
 677        if (error) return error;
 678        return check_tp(&qos->rxtp);
 679}
 680
 681int vcc_setsockopt(struct socket *sock, int level, int optname,
 682                   char __user *optval, int optlen)
 683{
 684        struct atm_vcc *vcc;
 685        unsigned long value;
 686        int error;
 687
 688        if (__SO_LEVEL_MATCH(optname, level) && optlen != __SO_SIZE(optname))
 689                return -EINVAL;
 690
 691        vcc = ATM_SD(sock);
 692        switch (optname) {
 693                case SO_ATMQOS:
 694                        {
 695                                struct atm_qos qos;
 696
 697                                if (copy_from_user(&qos,optval,sizeof(qos)))
 698                                        return -EFAULT;
 699                                error = check_qos(&qos);
 700                                if (error) return error;
 701                                if (sock->state == SS_CONNECTED)
 702                                        return atm_change_qos(vcc,&qos);
 703                                if (sock->state != SS_UNCONNECTED)
 704                                        return -EBADFD;
 705                                vcc->qos = qos;
 706                                set_bit(ATM_VF_HASQOS,&vcc->flags);
 707                                return 0;
 708                        }
 709                case SO_SETCLP:
 710                        if (get_user(value,(unsigned long __user *)optval))
 711                                return -EFAULT;
 712                        if (value) vcc->atm_options |= ATM_ATMOPT_CLP;
 713                        else vcc->atm_options &= ~ATM_ATMOPT_CLP;
 714                        return 0;
 715                default:
 716                        if (level == SOL_SOCKET) return -EINVAL;
 717                        break;
 718        }
 719        if (!vcc->dev || !vcc->dev->ops->setsockopt) return -EINVAL;
 720        return vcc->dev->ops->setsockopt(vcc,level,optname,optval,optlen);
 721}
 722
 723
 724int vcc_getsockopt(struct socket *sock, int level, int optname,
 725                   char __user *optval, int __user *optlen)
 726{
 727        struct atm_vcc *vcc;
 728        int len;
 729
 730        if (get_user(len, optlen))
 731                return -EFAULT;
 732        if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
 733                return -EINVAL;
 734
 735        vcc = ATM_SD(sock);
 736        switch (optname) {
 737                case SO_ATMQOS:
 738                        if (!test_bit(ATM_VF_HASQOS,&vcc->flags))
 739                                return -EINVAL;
 740                        return copy_to_user(optval,&vcc->qos,sizeof(vcc->qos)) ?
 741                            -EFAULT : 0;
 742                case SO_SETCLP:
 743                        return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 :
 744                          0,(unsigned long __user *)optval) ? -EFAULT : 0;
 745                case SO_ATMPVC:
 746                        {
 747                                struct sockaddr_atmpvc pvc;
 748
 749                                if (!vcc->dev ||
 750                                    !test_bit(ATM_VF_ADDR,&vcc->flags))
 751                                        return -ENOTCONN;
 752                                pvc.sap_family = AF_ATMPVC;
 753                                pvc.sap_addr.itf = vcc->dev->number;
 754                                pvc.sap_addr.vpi = vcc->vpi;
 755                                pvc.sap_addr.vci = vcc->vci;
 756                                return copy_to_user(optval,&pvc,sizeof(pvc)) ?
 757                                    -EFAULT : 0;
 758                        }
 759                default:
 760                        if (level == SOL_SOCKET) return -EINVAL;
 761                        break;
 762        }
 763        if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL;
 764        return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len);
 765}
 766
 767static int __init atm_init(void)
 768{
 769        int error;
 770
 771        if ((error = proto_register(&vcc_proto, 0)) < 0)
 772                goto out;
 773
 774        if ((error = atmpvc_init()) < 0) {
 775                printk(KERN_ERR "atmpvc_init() failed with %d\n", error);
 776                goto out_unregister_vcc_proto;
 777        }
 778        if ((error = atmsvc_init()) < 0) {
 779                printk(KERN_ERR "atmsvc_init() failed with %d\n", error);
 780                goto out_atmpvc_exit;
 781        }
 782        if ((error = atm_proc_init()) < 0) {
 783                printk(KERN_ERR "atm_proc_init() failed with %d\n",error);
 784                goto out_atmsvc_exit;
 785        }
 786        if ((error = atm_sysfs_init()) < 0) {
 787                printk(KERN_ERR "atm_sysfs_init() failed with %d\n",error);
 788                goto out_atmproc_exit;
 789        }
 790out:
 791        return error;
 792out_atmproc_exit:
 793        atm_proc_exit();
 794out_atmsvc_exit:
 795        atmsvc_exit();
 796out_atmpvc_exit:
 797        atmsvc_exit();
 798out_unregister_vcc_proto:
 799        proto_unregister(&vcc_proto);
 800        goto out;
 801}
 802
 803static void __exit atm_exit(void)
 804{
 805        atm_proc_exit();
 806        atm_sysfs_exit();
 807        atmsvc_exit();
 808        atmpvc_exit();
 809        proto_unregister(&vcc_proto);
 810}
 811
 812subsys_initcall(atm_init);
 813
 814module_exit(atm_exit);
 815
 816MODULE_LICENSE("GPL");
 817MODULE_ALIAS_NETPROTO(PF_ATMPVC);
 818MODULE_ALIAS_NETPROTO(PF_ATMSVC);
 819