net/atm/ioctl.c

Source file repositories/reference/linux-study-clean/net/atm/ioctl.c

File Facts

System
Linux kernel
Corpus path
net/atm/ioctl.c
Extension
.c
Size
7445 bytes
Lines
294
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/net.h>		/* struct socket, struct proto_ops */
#include <linux/atm.h>		/* ATM stuff */
#include <linux/atmdev.h>
#include <linux/capability.h>
#include <linux/mutex.h>
#include <asm/ioctls.h>
#include <net/compat.h>

#include "resources.h"
#include "common.h"


static DEFINE_MUTEX(ioctl_mutex);
static LIST_HEAD(ioctl_list);


void register_atm_ioctl(struct atm_ioctl *ioctl)
{
	mutex_lock(&ioctl_mutex);
	list_add_tail(&ioctl->list, &ioctl_list);
	mutex_unlock(&ioctl_mutex);
}
EXPORT_SYMBOL(register_atm_ioctl);

void deregister_atm_ioctl(struct atm_ioctl *ioctl)
{
	mutex_lock(&ioctl_mutex);
	list_del(&ioctl->list);
	mutex_unlock(&ioctl_mutex);
}
EXPORT_SYMBOL(deregister_atm_ioctl);

static int do_vcc_ioctl(struct socket *sock, unsigned int cmd,
			unsigned long arg, int compat)
{
	struct sock *sk = sock->sk;
	struct atm_vcc *vcc;
	int error;
	struct list_head *pos;
	void __user *argp = (void __user *)arg;
	void __user *buf;
	int __user *len;

	vcc = ATM_SD(sock);
	switch (cmd) {
	case SIOCOUTQ:
		if (sock->state != SS_CONNECTED ||
		    !test_bit(ATM_VF_READY, &vcc->flags)) {
			error =  -EINVAL;
			goto done;
		}
		error = put_user(sk->sk_sndbuf - sk_wmem_alloc_get(sk),
				 (int __user *)argp);
		goto done;
	case SIOCINQ:
	{
		struct sk_buff *skb;
		int amount;

		if (sock->state != SS_CONNECTED) {
			error = -EINVAL;
			goto done;
		}
		spin_lock_irq(&sk->sk_receive_queue.lock);
		skb = skb_peek(&sk->sk_receive_queue);
		amount = skb ? skb->len : 0;
		spin_unlock_irq(&sk->sk_receive_queue.lock);
		error = put_user(amount, (int __user *)argp);
		goto done;
	}
	case ATM_SETSC:
		net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n",
				     current->comm, task_pid_nr(current));
		error = 0;
		goto done;
	case ATM_SETBACKEND:
	case ATM_NEWBACKENDIF:
	{
		atm_backend_t backend;
		error = get_user(backend, (atm_backend_t __user *)argp);
		if (error)
			goto done;
		switch (backend) {
		case ATM_BACKEND_PPP:
			request_module("pppoatm");
			break;
		case ATM_BACKEND_BR2684:
			request_module("br2684");
			break;
		}

Annotation

Implementation Notes