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