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), ATM_SKB(skb)->acct_truesize);
  39        WARN_ON(refcount_sub_and_test(ATM_SKB(skb)->acct_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        if (vcc->dev->ops->send_bh)
  58                return vcc->dev->ops->send_bh(vcc, skb);
  59        return vcc->dev->ops->send(vcc, skb);
  60}
  61
  62int atm_init_aal0(struct atm_vcc *vcc)
  63{
  64        vcc->push = atm_push_raw;
  65        vcc->pop = atm_pop_raw;
  66        vcc->push_oam = NULL;
  67        vcc->send = atm_send_aal0;
  68        return 0;
  69}
  70
  71int atm_init_aal34(struct atm_vcc *vcc)
  72{
  73        vcc->push = atm_push_raw;
  74        vcc->pop = atm_pop_raw;
  75        vcc->push_oam = NULL;
  76        if (vcc->dev->ops->send_bh)
  77                vcc->send = vcc->dev->ops->send_bh;
  78        else
  79                vcc->send = vcc->dev->ops->send;
  80        return 0;
  81}
  82
  83int atm_init_aal5(struct atm_vcc *vcc)
  84{
  85        vcc->push = atm_push_raw;
  86        vcc->pop = atm_pop_raw;
  87        vcc->push_oam = NULL;
  88        if (vcc->dev->ops->send_bh)
  89                vcc->send = vcc->dev->ops->send_bh;
  90        else
  91                vcc->send = vcc->dev->ops->send;
  92        return 0;
  93}
  94EXPORT_SYMBOL(atm_init_aal5);
  95