18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/* net/atm/raw.c - Raw AAL0 and AAL5 transports */
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/module.h>
98c2ecf20Sopenharmony_ci#include <linux/atmdev.h>
108c2ecf20Sopenharmony_ci#include <linux/capability.h>
118c2ecf20Sopenharmony_ci#include <linux/kernel.h>
128c2ecf20Sopenharmony_ci#include <linux/skbuff.h>
138c2ecf20Sopenharmony_ci#include <linux/mm.h>
148c2ecf20Sopenharmony_ci#include <linux/slab.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include "common.h"
178c2ecf20Sopenharmony_ci#include "protocols.h"
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/*
208c2ecf20Sopenharmony_ci * SKB == NULL indicates that the link is being closed
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_cistatic void atm_push_raw(struct atm_vcc *vcc, struct sk_buff *skb)
248c2ecf20Sopenharmony_ci{
258c2ecf20Sopenharmony_ci	if (skb) {
268c2ecf20Sopenharmony_ci		struct sock *sk = sk_atm(vcc);
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci		skb_queue_tail(&sk->sk_receive_queue, skb);
298c2ecf20Sopenharmony_ci		sk->sk_data_ready(sk);
308c2ecf20Sopenharmony_ci	}
318c2ecf20Sopenharmony_ci}
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistatic void atm_pop_raw(struct atm_vcc *vcc, struct sk_buff *skb)
348c2ecf20Sopenharmony_ci{
358c2ecf20Sopenharmony_ci	struct sock *sk = sk_atm(vcc);
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	pr_debug("(%d) %d -= %d\n",
388c2ecf20Sopenharmony_ci		 vcc->vci, sk_wmem_alloc_get(sk), ATM_SKB(skb)->acct_truesize);
398c2ecf20Sopenharmony_ci	WARN_ON(refcount_sub_and_test(ATM_SKB(skb)->acct_truesize, &sk->sk_wmem_alloc));
408c2ecf20Sopenharmony_ci	dev_kfree_skb_any(skb);
418c2ecf20Sopenharmony_ci	sk->sk_write_space(sk);
428c2ecf20Sopenharmony_ci}
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_cistatic int atm_send_aal0(struct atm_vcc *vcc, struct sk_buff *skb)
458c2ecf20Sopenharmony_ci{
468c2ecf20Sopenharmony_ci	/*
478c2ecf20Sopenharmony_ci	 * Note that if vpi/vci are _ANY or _UNSPEC the below will
488c2ecf20Sopenharmony_ci	 * still work
498c2ecf20Sopenharmony_ci	 */
508c2ecf20Sopenharmony_ci	if (!capable(CAP_NET_ADMIN) &&
518c2ecf20Sopenharmony_ci	    (((u32 *)skb->data)[0] & (ATM_HDR_VPI_MASK | ATM_HDR_VCI_MASK)) !=
528c2ecf20Sopenharmony_ci	    ((vcc->vpi << ATM_HDR_VPI_SHIFT) |
538c2ecf20Sopenharmony_ci	     (vcc->vci << ATM_HDR_VCI_SHIFT))) {
548c2ecf20Sopenharmony_ci		kfree_skb(skb);
558c2ecf20Sopenharmony_ci		return -EADDRNOTAVAIL;
568c2ecf20Sopenharmony_ci	}
578c2ecf20Sopenharmony_ci	return vcc->dev->ops->send(vcc, skb);
588c2ecf20Sopenharmony_ci}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ciint atm_init_aal0(struct atm_vcc *vcc)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	vcc->push = atm_push_raw;
638c2ecf20Sopenharmony_ci	vcc->pop = atm_pop_raw;
648c2ecf20Sopenharmony_ci	vcc->push_oam = NULL;
658c2ecf20Sopenharmony_ci	vcc->send = atm_send_aal0;
668c2ecf20Sopenharmony_ci	return 0;
678c2ecf20Sopenharmony_ci}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ciint atm_init_aal34(struct atm_vcc *vcc)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	vcc->push = atm_push_raw;
728c2ecf20Sopenharmony_ci	vcc->pop = atm_pop_raw;
738c2ecf20Sopenharmony_ci	vcc->push_oam = NULL;
748c2ecf20Sopenharmony_ci	vcc->send = vcc->dev->ops->send;
758c2ecf20Sopenharmony_ci	return 0;
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ciint atm_init_aal5(struct atm_vcc *vcc)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	vcc->push = atm_push_raw;
818c2ecf20Sopenharmony_ci	vcc->pop = atm_pop_raw;
828c2ecf20Sopenharmony_ci	vcc->push_oam = NULL;
838c2ecf20Sopenharmony_ci	vcc->send = vcc->dev->ops->send;
848c2ecf20Sopenharmony_ci	return 0;
858c2ecf20Sopenharmony_ci}
868c2ecf20Sopenharmony_ciEXPORT_SYMBOL(atm_init_aal5);
87