linux/net/atm/raw.c
<<
>>
Prefs
   1/* net/atm/raw.c - Raw AAL0 and AAL5 transports */
   2
   3/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
   4
   5#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
   6
   7#include <linux/module.h>
   8#include <linux/atmdev.h>
   9#include <linux/capability.h>
  10#include <linux/kernel.h>
  11#include <linux/skbuff.h>
  12#include <linux/mm.h>
  13#include <linux/slab.h>
  14
  15#include "common.h"
  16#include "protocols.h"
  17
  18/*
  19 * SKB == NULL indicates that the link is being closed
  20 */
  21
  22static void atm_push_raw(struct atm_vcc *vcc, struct sk_buff *skb)
  23{
  24        if (skb) {
  25                struct sock *sk = sk_atm(vcc);
  26
  27                skb_queue_tail(&sk->sk_receive_queue, skb);
  28                sk->sk_data_ready(sk);
  29        }
  30}
  31
  32static void atm_pop_raw(struct atm_vcc *vcc, struct sk_buff *skb)
  33{
  34        struct sock *sk = sk_atm(vcc);
  35
  36        pr_debug("(%d) %d -= %d\n",
  37                 vcc->vci, sk_wmem_alloc_get(sk), skb->truesize);
  38        atomic_sub(skb->truesize, &sk->sk_wmem_alloc);
  39        dev_kfree_skb_any(skb);
  40        sk->sk_write_space(sk);
  41}
  42
  43static int atm_send_aal0(struct atm_vcc *vcc, struct sk_buff *skb)
  44{
  45        /*
  46         * Note that if vpi/vci are _ANY or _UNSPEC the below will
  47         * still work
  48         */
  49        if (!capable(CAP_NET_ADMIN) &&
  50            (((u32 *)skb->data)[0] & (ATM_HDR_VPI_MASK | ATM_HDR_VCI_MASK)) !=
  51            ((vcc->vpi << ATM_HDR_VPI_SHIFT) |
  52             (vcc->vci << ATM_HDR_VCI_SHIFT))) {
  53                kfree_skb(skb);
  54                return -EADDRNOTAVAIL;
  55        }
  56        return vcc->dev->ops->send(vcc, skb);
  57}
  58
  59int atm_init_aal0(struct atm_vcc *vcc)
  60{
  61        vcc->push = atm_push_raw;
  62        vcc->pop = atm_pop_raw;
  63        vcc->push_oam = NULL;
  64        vcc->send = atm_send_aal0;
  65        return 0;
  66}
  67
  68int atm_init_aal34(struct atm_vcc *vcc)
  69{
  70        vcc->push = atm_push_raw;
  71        vcc->pop = atm_pop_raw;
  72        vcc->push_oam = NULL;
  73        vcc->send = vcc->dev->ops->send;
  74        return 0;
  75}
  76
  77int atm_init_aal5(struct atm_vcc *vcc)
  78{
  79        vcc->push = atm_push_raw;
  80        vcc->pop = atm_pop_raw;
  81        vcc->push_oam = NULL;
  82        vcc->send = vcc->dev->ops->send;
  83        return 0;
  84}
  85EXPORT_SYMBOL(atm_init_aal5);
  86