cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

svc.c (16434B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* net/atm/svc.c - ATM SVC sockets */
      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/string.h>
      9#include <linux/net.h>		/* struct socket, struct proto_ops */
     10#include <linux/errno.h>	/* error codes */
     11#include <linux/kernel.h>	/* printk */
     12#include <linux/skbuff.h>
     13#include <linux/wait.h>
     14#include <linux/sched/signal.h>
     15#include <linux/fcntl.h>	/* O_NONBLOCK */
     16#include <linux/init.h>
     17#include <linux/atm.h>		/* ATM stuff */
     18#include <linux/atmsap.h>
     19#include <linux/atmsvc.h>
     20#include <linux/atmdev.h>
     21#include <linux/bitops.h>
     22#include <net/sock.h>		/* for sock_no_* */
     23#include <linux/uaccess.h>
     24#include <linux/export.h>
     25
     26#include "resources.h"
     27#include "common.h"		/* common for PVCs and SVCs */
     28#include "signaling.h"
     29#include "addr.h"
     30
     31static int svc_create(struct net *net, struct socket *sock, int protocol,
     32		      int kern);
     33
     34/*
     35 * Note: since all this is still nicely synchronized with the signaling demon,
     36 *       there's no need to protect sleep loops with clis. If signaling is
     37 *       moved into the kernel, that would change.
     38 */
     39
     40
     41static int svc_shutdown(struct socket *sock, int how)
     42{
     43	return 0;
     44}
     45
     46static void svc_disconnect(struct atm_vcc *vcc)
     47{
     48	DEFINE_WAIT(wait);
     49	struct sk_buff *skb;
     50	struct sock *sk = sk_atm(vcc);
     51
     52	pr_debug("%p\n", vcc);
     53	if (test_bit(ATM_VF_REGIS, &vcc->flags)) {
     54		sigd_enq(vcc, as_close, NULL, NULL, NULL);
     55		for (;;) {
     56			prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE);
     57			if (test_bit(ATM_VF_RELEASED, &vcc->flags) || !sigd)
     58				break;
     59			schedule();
     60		}
     61		finish_wait(sk_sleep(sk), &wait);
     62	}
     63	/* beware - socket is still in use by atmsigd until the last
     64	   as_indicate has been answered */
     65	while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
     66		atm_return(vcc, skb->truesize);
     67		pr_debug("LISTEN REL\n");
     68		sigd_enq2(NULL, as_reject, vcc, NULL, NULL, &vcc->qos, 0);
     69		dev_kfree_skb(skb);
     70	}
     71	clear_bit(ATM_VF_REGIS, &vcc->flags);
     72	/* ... may retry later */
     73}
     74
     75static int svc_release(struct socket *sock)
     76{
     77	struct sock *sk = sock->sk;
     78	struct atm_vcc *vcc;
     79
     80	if (sk) {
     81		vcc = ATM_SD(sock);
     82		pr_debug("%p\n", vcc);
     83		clear_bit(ATM_VF_READY, &vcc->flags);
     84		/*
     85		 * VCC pointer is used as a reference,
     86		 * so we must not free it (thereby subjecting it to re-use)
     87		 * before all pending connections are closed
     88		 */
     89		svc_disconnect(vcc);
     90		vcc_release(sock);
     91	}
     92	return 0;
     93}
     94
     95static int svc_bind(struct socket *sock, struct sockaddr *sockaddr,
     96		    int sockaddr_len)
     97{
     98	DEFINE_WAIT(wait);
     99	struct sock *sk = sock->sk;
    100	struct sockaddr_atmsvc *addr;
    101	struct atm_vcc *vcc;
    102	int error;
    103
    104	if (sockaddr_len != sizeof(struct sockaddr_atmsvc))
    105		return -EINVAL;
    106	lock_sock(sk);
    107	if (sock->state == SS_CONNECTED) {
    108		error = -EISCONN;
    109		goto out;
    110	}
    111	if (sock->state != SS_UNCONNECTED) {
    112		error = -EINVAL;
    113		goto out;
    114	}
    115	vcc = ATM_SD(sock);
    116	addr = (struct sockaddr_atmsvc *) sockaddr;
    117	if (addr->sas_family != AF_ATMSVC) {
    118		error = -EAFNOSUPPORT;
    119		goto out;
    120	}
    121	clear_bit(ATM_VF_BOUND, &vcc->flags);
    122	    /* failing rebind will kill old binding */
    123	/* @@@ check memory (de)allocation on rebind */
    124	if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
    125		error = -EBADFD;
    126		goto out;
    127	}
    128	vcc->local = *addr;
    129	set_bit(ATM_VF_WAITING, &vcc->flags);
    130	sigd_enq(vcc, as_bind, NULL, NULL, &vcc->local);
    131	for (;;) {
    132		prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE);
    133		if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd)
    134			break;
    135		schedule();
    136	}
    137	finish_wait(sk_sleep(sk), &wait);
    138	clear_bit(ATM_VF_REGIS, &vcc->flags); /* doesn't count */
    139	if (!sigd) {
    140		error = -EUNATCH;
    141		goto out;
    142	}
    143	if (!sk->sk_err)
    144		set_bit(ATM_VF_BOUND, &vcc->flags);
    145	error = -sk->sk_err;
    146out:
    147	release_sock(sk);
    148	return error;
    149}
    150
    151static int svc_connect(struct socket *sock, struct sockaddr *sockaddr,
    152		       int sockaddr_len, int flags)
    153{
    154	DEFINE_WAIT(wait);
    155	struct sock *sk = sock->sk;
    156	struct sockaddr_atmsvc *addr;
    157	struct atm_vcc *vcc = ATM_SD(sock);
    158	int error;
    159
    160	pr_debug("%p\n", vcc);
    161	lock_sock(sk);
    162	if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) {
    163		error = -EINVAL;
    164		goto out;
    165	}
    166
    167	switch (sock->state) {
    168	default:
    169		error = -EINVAL;
    170		goto out;
    171	case SS_CONNECTED:
    172		error = -EISCONN;
    173		goto out;
    174	case SS_CONNECTING:
    175		if (test_bit(ATM_VF_WAITING, &vcc->flags)) {
    176			error = -EALREADY;
    177			goto out;
    178		}
    179		sock->state = SS_UNCONNECTED;
    180		if (sk->sk_err) {
    181			error = -sk->sk_err;
    182			goto out;
    183		}
    184		break;
    185	case SS_UNCONNECTED:
    186		addr = (struct sockaddr_atmsvc *) sockaddr;
    187		if (addr->sas_family != AF_ATMSVC) {
    188			error = -EAFNOSUPPORT;
    189			goto out;
    190		}
    191		if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
    192			error = -EBADFD;
    193			goto out;
    194		}
    195		if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
    196		    vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) {
    197			error = -EINVAL;
    198			goto out;
    199		}
    200		if (!vcc->qos.txtp.traffic_class &&
    201		    !vcc->qos.rxtp.traffic_class) {
    202			error = -EINVAL;
    203			goto out;
    204		}
    205		vcc->remote = *addr;
    206		set_bit(ATM_VF_WAITING, &vcc->flags);
    207		sigd_enq(vcc, as_connect, NULL, NULL, &vcc->remote);
    208		if (flags & O_NONBLOCK) {
    209			sock->state = SS_CONNECTING;
    210			error = -EINPROGRESS;
    211			goto out;
    212		}
    213		error = 0;
    214		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    215		while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
    216			schedule();
    217			if (!signal_pending(current)) {
    218				prepare_to_wait(sk_sleep(sk), &wait,
    219						TASK_INTERRUPTIBLE);
    220				continue;
    221			}
    222			pr_debug("*ABORT*\n");
    223			/*
    224			 * This is tricky:
    225			 *   Kernel ---close--> Demon
    226			 *   Kernel <--close--- Demon
    227			 * or
    228			 *   Kernel ---close--> Demon
    229			 *   Kernel <--error--- Demon
    230			 * or
    231			 *   Kernel ---close--> Demon
    232			 *   Kernel <--okay---- Demon
    233			 *   Kernel <--close--- Demon
    234			 */
    235			sigd_enq(vcc, as_close, NULL, NULL, NULL);
    236			while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
    237				prepare_to_wait(sk_sleep(sk), &wait,
    238						TASK_INTERRUPTIBLE);
    239				schedule();
    240			}
    241			if (!sk->sk_err)
    242				while (!test_bit(ATM_VF_RELEASED, &vcc->flags) &&
    243				       sigd) {
    244					prepare_to_wait(sk_sleep(sk), &wait,
    245							TASK_INTERRUPTIBLE);
    246					schedule();
    247				}
    248			clear_bit(ATM_VF_REGIS, &vcc->flags);
    249			clear_bit(ATM_VF_RELEASED, &vcc->flags);
    250			clear_bit(ATM_VF_CLOSE, &vcc->flags);
    251			    /* we're gone now but may connect later */
    252			error = -EINTR;
    253			break;
    254		}
    255		finish_wait(sk_sleep(sk), &wait);
    256		if (error)
    257			goto out;
    258		if (!sigd) {
    259			error = -EUNATCH;
    260			goto out;
    261		}
    262		if (sk->sk_err) {
    263			error = -sk->sk_err;
    264			goto out;
    265		}
    266	}
    267
    268	vcc->qos.txtp.max_pcr = SELECT_TOP_PCR(vcc->qos.txtp);
    269	vcc->qos.txtp.pcr = 0;
    270	vcc->qos.txtp.min_pcr = 0;
    271
    272	error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci);
    273	if (!error)
    274		sock->state = SS_CONNECTED;
    275	else
    276		(void)svc_disconnect(vcc);
    277out:
    278	release_sock(sk);
    279	return error;
    280}
    281
    282static int svc_listen(struct socket *sock, int backlog)
    283{
    284	DEFINE_WAIT(wait);
    285	struct sock *sk = sock->sk;
    286	struct atm_vcc *vcc = ATM_SD(sock);
    287	int error;
    288
    289	pr_debug("%p\n", vcc);
    290	lock_sock(sk);
    291	/* let server handle listen on unbound sockets */
    292	if (test_bit(ATM_VF_SESSION, &vcc->flags)) {
    293		error = -EINVAL;
    294		goto out;
    295	}
    296	if (test_bit(ATM_VF_LISTEN, &vcc->flags)) {
    297		error = -EADDRINUSE;
    298		goto out;
    299	}
    300	set_bit(ATM_VF_WAITING, &vcc->flags);
    301	sigd_enq(vcc, as_listen, NULL, NULL, &vcc->local);
    302	for (;;) {
    303		prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE);
    304		if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd)
    305			break;
    306		schedule();
    307	}
    308	finish_wait(sk_sleep(sk), &wait);
    309	if (!sigd) {
    310		error = -EUNATCH;
    311		goto out;
    312	}
    313	set_bit(ATM_VF_LISTEN, &vcc->flags);
    314	vcc_insert_socket(sk);
    315	sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT;
    316	error = -sk->sk_err;
    317out:
    318	release_sock(sk);
    319	return error;
    320}
    321
    322static int svc_accept(struct socket *sock, struct socket *newsock, int flags,
    323		      bool kern)
    324{
    325	struct sock *sk = sock->sk;
    326	struct sk_buff *skb;
    327	struct atmsvc_msg *msg;
    328	struct atm_vcc *old_vcc = ATM_SD(sock);
    329	struct atm_vcc *new_vcc;
    330	int error;
    331
    332	lock_sock(sk);
    333
    334	error = svc_create(sock_net(sk), newsock, 0, kern);
    335	if (error)
    336		goto out;
    337
    338	new_vcc = ATM_SD(newsock);
    339
    340	pr_debug("%p -> %p\n", old_vcc, new_vcc);
    341	while (1) {
    342		DEFINE_WAIT(wait);
    343
    344		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    345		while (!(skb = skb_dequeue(&sk->sk_receive_queue)) &&
    346		       sigd) {
    347			if (test_bit(ATM_VF_RELEASED, &old_vcc->flags))
    348				break;
    349			if (test_bit(ATM_VF_CLOSE, &old_vcc->flags)) {
    350				error = -sk->sk_err;
    351				break;
    352			}
    353			if (flags & O_NONBLOCK) {
    354				error = -EAGAIN;
    355				break;
    356			}
    357			release_sock(sk);
    358			schedule();
    359			lock_sock(sk);
    360			if (signal_pending(current)) {
    361				error = -ERESTARTSYS;
    362				break;
    363			}
    364			prepare_to_wait(sk_sleep(sk), &wait,
    365					TASK_INTERRUPTIBLE);
    366		}
    367		finish_wait(sk_sleep(sk), &wait);
    368		if (error)
    369			goto out;
    370		if (!skb) {
    371			error = -EUNATCH;
    372			goto out;
    373		}
    374		msg = (struct atmsvc_msg *)skb->data;
    375		new_vcc->qos = msg->qos;
    376		set_bit(ATM_VF_HASQOS, &new_vcc->flags);
    377		new_vcc->remote = msg->svc;
    378		new_vcc->local = msg->local;
    379		new_vcc->sap = msg->sap;
    380		error = vcc_connect(newsock, msg->pvc.sap_addr.itf,
    381				    msg->pvc.sap_addr.vpi,
    382				    msg->pvc.sap_addr.vci);
    383		dev_kfree_skb(skb);
    384		sk_acceptq_removed(sk);
    385		if (error) {
    386			sigd_enq2(NULL, as_reject, old_vcc, NULL, NULL,
    387				  &old_vcc->qos, error);
    388			error = error == -EAGAIN ? -EBUSY : error;
    389			goto out;
    390		}
    391		/* wait should be short, so we ignore the non-blocking flag */
    392		set_bit(ATM_VF_WAITING, &new_vcc->flags);
    393		sigd_enq(new_vcc, as_accept, old_vcc, NULL, NULL);
    394		for (;;) {
    395			prepare_to_wait(sk_sleep(sk_atm(new_vcc)), &wait,
    396					TASK_UNINTERRUPTIBLE);
    397			if (!test_bit(ATM_VF_WAITING, &new_vcc->flags) || !sigd)
    398				break;
    399			release_sock(sk);
    400			schedule();
    401			lock_sock(sk);
    402		}
    403		finish_wait(sk_sleep(sk_atm(new_vcc)), &wait);
    404		if (!sigd) {
    405			error = -EUNATCH;
    406			goto out;
    407		}
    408		if (!sk_atm(new_vcc)->sk_err)
    409			break;
    410		if (sk_atm(new_vcc)->sk_err != ERESTARTSYS) {
    411			error = -sk_atm(new_vcc)->sk_err;
    412			goto out;
    413		}
    414	}
    415	newsock->state = SS_CONNECTED;
    416out:
    417	release_sock(sk);
    418	return error;
    419}
    420
    421static int svc_getname(struct socket *sock, struct sockaddr *sockaddr,
    422		       int peer)
    423{
    424	struct sockaddr_atmsvc *addr;
    425
    426	addr = (struct sockaddr_atmsvc *) sockaddr;
    427	memcpy(addr, peer ? &ATM_SD(sock)->remote : &ATM_SD(sock)->local,
    428	       sizeof(struct sockaddr_atmsvc));
    429	return sizeof(struct sockaddr_atmsvc);
    430}
    431
    432int svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos)
    433{
    434	struct sock *sk = sk_atm(vcc);
    435	DEFINE_WAIT(wait);
    436
    437	set_bit(ATM_VF_WAITING, &vcc->flags);
    438	sigd_enq2(vcc, as_modify, NULL, NULL, &vcc->local, qos, 0);
    439	for (;;) {
    440		prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE);
    441		if (!test_bit(ATM_VF_WAITING, &vcc->flags) ||
    442		    test_bit(ATM_VF_RELEASED, &vcc->flags) || !sigd) {
    443			break;
    444		}
    445		schedule();
    446	}
    447	finish_wait(sk_sleep(sk), &wait);
    448	if (!sigd)
    449		return -EUNATCH;
    450	return -sk->sk_err;
    451}
    452
    453static int svc_setsockopt(struct socket *sock, int level, int optname,
    454			  sockptr_t optval, unsigned int optlen)
    455{
    456	struct sock *sk = sock->sk;
    457	struct atm_vcc *vcc = ATM_SD(sock);
    458	int value, error = 0;
    459
    460	lock_sock(sk);
    461	switch (optname) {
    462	case SO_ATMSAP:
    463		if (level != SOL_ATM || optlen != sizeof(struct atm_sap)) {
    464			error = -EINVAL;
    465			goto out;
    466		}
    467		if (copy_from_sockptr(&vcc->sap, optval, optlen)) {
    468			error = -EFAULT;
    469			goto out;
    470		}
    471		set_bit(ATM_VF_HASSAP, &vcc->flags);
    472		break;
    473	case SO_MULTIPOINT:
    474		if (level != SOL_ATM || optlen != sizeof(int)) {
    475			error = -EINVAL;
    476			goto out;
    477		}
    478		if (copy_from_sockptr(&value, optval, sizeof(int))) {
    479			error = -EFAULT;
    480			goto out;
    481		}
    482		if (value == 1)
    483			set_bit(ATM_VF_SESSION, &vcc->flags);
    484		else if (value == 0)
    485			clear_bit(ATM_VF_SESSION, &vcc->flags);
    486		else
    487			error = -EINVAL;
    488		break;
    489	default:
    490		error = vcc_setsockopt(sock, level, optname, optval, optlen);
    491	}
    492
    493out:
    494	release_sock(sk);
    495	return error;
    496}
    497
    498static int svc_getsockopt(struct socket *sock, int level, int optname,
    499			  char __user *optval, int __user *optlen)
    500{
    501	struct sock *sk = sock->sk;
    502	int error = 0, len;
    503
    504	lock_sock(sk);
    505	if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP) {
    506		error = vcc_getsockopt(sock, level, optname, optval, optlen);
    507		goto out;
    508	}
    509	if (get_user(len, optlen)) {
    510		error = -EFAULT;
    511		goto out;
    512	}
    513	if (len != sizeof(struct atm_sap)) {
    514		error = -EINVAL;
    515		goto out;
    516	}
    517	if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) {
    518		error = -EFAULT;
    519		goto out;
    520	}
    521out:
    522	release_sock(sk);
    523	return error;
    524}
    525
    526static int svc_addparty(struct socket *sock, struct sockaddr *sockaddr,
    527			int sockaddr_len, int flags)
    528{
    529	DEFINE_WAIT(wait);
    530	struct sock *sk = sock->sk;
    531	struct atm_vcc *vcc = ATM_SD(sock);
    532	int error;
    533
    534	lock_sock(sk);
    535	set_bit(ATM_VF_WAITING, &vcc->flags);
    536	sigd_enq(vcc, as_addparty, NULL, NULL,
    537		 (struct sockaddr_atmsvc *) sockaddr);
    538	if (flags & O_NONBLOCK) {
    539		error = -EINPROGRESS;
    540		goto out;
    541	}
    542	pr_debug("added wait queue\n");
    543	for (;;) {
    544		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    545		if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd)
    546			break;
    547		schedule();
    548	}
    549	finish_wait(sk_sleep(sk), &wait);
    550	error = -xchg(&sk->sk_err_soft, 0);
    551out:
    552	release_sock(sk);
    553	return error;
    554}
    555
    556static int svc_dropparty(struct socket *sock, int ep_ref)
    557{
    558	DEFINE_WAIT(wait);
    559	struct sock *sk = sock->sk;
    560	struct atm_vcc *vcc = ATM_SD(sock);
    561	int error;
    562
    563	lock_sock(sk);
    564	set_bit(ATM_VF_WAITING, &vcc->flags);
    565	sigd_enq2(vcc, as_dropparty, NULL, NULL, NULL, NULL, ep_ref);
    566	for (;;) {
    567		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    568		if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd)
    569			break;
    570		schedule();
    571	}
    572	finish_wait(sk_sleep(sk), &wait);
    573	if (!sigd) {
    574		error = -EUNATCH;
    575		goto out;
    576	}
    577	error = -xchg(&sk->sk_err_soft, 0);
    578out:
    579	release_sock(sk);
    580	return error;
    581}
    582
    583static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
    584{
    585	int error, ep_ref;
    586	struct sockaddr_atmsvc sa;
    587	struct atm_vcc *vcc = ATM_SD(sock);
    588
    589	switch (cmd) {
    590	case ATM_ADDPARTY:
    591		if (!test_bit(ATM_VF_SESSION, &vcc->flags))
    592			return -EINVAL;
    593		if (copy_from_user(&sa, (void __user *) arg, sizeof(sa)))
    594			return -EFAULT;
    595		error = svc_addparty(sock, (struct sockaddr *)&sa, sizeof(sa),
    596				     0);
    597		break;
    598	case ATM_DROPPARTY:
    599		if (!test_bit(ATM_VF_SESSION, &vcc->flags))
    600			return -EINVAL;
    601		if (copy_from_user(&ep_ref, (void __user *) arg, sizeof(int)))
    602			return -EFAULT;
    603		error = svc_dropparty(sock, ep_ref);
    604		break;
    605	default:
    606		error = vcc_ioctl(sock, cmd, arg);
    607	}
    608
    609	return error;
    610}
    611
    612#ifdef CONFIG_COMPAT
    613static int svc_compat_ioctl(struct socket *sock, unsigned int cmd,
    614			    unsigned long arg)
    615{
    616	/* The definition of ATM_ADDPARTY uses the size of struct atm_iobuf.
    617	   But actually it takes a struct sockaddr_atmsvc, which doesn't need
    618	   compat handling. So all we have to do is fix up cmd... */
    619	if (cmd == COMPAT_ATM_ADDPARTY)
    620		cmd = ATM_ADDPARTY;
    621
    622	if (cmd == ATM_ADDPARTY || cmd == ATM_DROPPARTY)
    623		return svc_ioctl(sock, cmd, arg);
    624	else
    625		return vcc_compat_ioctl(sock, cmd, arg);
    626}
    627#endif /* CONFIG_COMPAT */
    628
    629static const struct proto_ops svc_proto_ops = {
    630	.family =	PF_ATMSVC,
    631	.owner =	THIS_MODULE,
    632
    633	.release =	svc_release,
    634	.bind =		svc_bind,
    635	.connect =	svc_connect,
    636	.socketpair =	sock_no_socketpair,
    637	.accept =	svc_accept,
    638	.getname =	svc_getname,
    639	.poll =		vcc_poll,
    640	.ioctl =	svc_ioctl,
    641#ifdef CONFIG_COMPAT
    642	.compat_ioctl =	svc_compat_ioctl,
    643#endif
    644	.gettstamp =	sock_gettstamp,
    645	.listen =	svc_listen,
    646	.shutdown =	svc_shutdown,
    647	.setsockopt =	svc_setsockopt,
    648	.getsockopt =	svc_getsockopt,
    649	.sendmsg =	vcc_sendmsg,
    650	.recvmsg =	vcc_recvmsg,
    651	.mmap =		sock_no_mmap,
    652	.sendpage =	sock_no_sendpage,
    653};
    654
    655
    656static int svc_create(struct net *net, struct socket *sock, int protocol,
    657		      int kern)
    658{
    659	int error;
    660
    661	if (!net_eq(net, &init_net))
    662		return -EAFNOSUPPORT;
    663
    664	sock->ops = &svc_proto_ops;
    665	error = vcc_create(net, sock, protocol, AF_ATMSVC, kern);
    666	if (error)
    667		return error;
    668	ATM_SD(sock)->local.sas_family = AF_ATMSVC;
    669	ATM_SD(sock)->remote.sas_family = AF_ATMSVC;
    670	return 0;
    671}
    672
    673static const struct net_proto_family svc_family_ops = {
    674	.family = PF_ATMSVC,
    675	.create = svc_create,
    676	.owner = THIS_MODULE,
    677};
    678
    679
    680/*
    681 *	Initialize the ATM SVC protocol family
    682 */
    683
    684int __init atmsvc_init(void)
    685{
    686	return sock_register(&svc_family_ops);
    687}
    688
    689void atmsvc_exit(void)
    690{
    691	sock_unregister(PF_ATMSVC);
    692}