PageRenderTime 44ms CodeModel.GetById 1ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/atm/atmtcp.c

https://bitbucket.org/evzijst/gittest
C | 505 lines | 410 code | 81 blank | 14 comment | 86 complexity | 339866bf76f13076fe88ae5039a686dc MD5 | raw file
  1/* drivers/atm/atmtcp.c - ATM over TCP "device" driver */
  2
  3/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */
  4
  5
  6#include <linux/module.h>
  7#include <linux/wait.h>
  8#include <linux/atmdev.h>
  9#include <linux/atm_tcp.h>
 10#include <linux/bitops.h>
 11#include <linux/init.h>
 12#include <asm/uaccess.h>
 13#include <asm/atomic.h>
 14
 15
 16extern int atm_init_aal5(struct atm_vcc *vcc); /* "raw" AAL5 transport */
 17
 18
 19#define PRIV(dev) ((struct atmtcp_dev_data *) ((dev)->dev_data))
 20
 21
 22struct atmtcp_dev_data {
 23	struct atm_vcc *vcc;	/* control VCC; NULL if detached */
 24	int persist;		/* non-zero if persistent */
 25};
 26
 27
 28#define DEV_LABEL    "atmtcp"
 29
 30#define MAX_VPI_BITS  8	/* simplifies life */
 31#define MAX_VCI_BITS 16
 32
 33
 34/*
 35 * Hairy code ahead: the control VCC may be closed while we're still
 36 * waiting for an answer, so we need to re-validate out_vcc every once
 37 * in a while.
 38 */
 39
 40
 41static int atmtcp_send_control(struct atm_vcc *vcc,int type,
 42    const struct atmtcp_control *msg,int flag)
 43{
 44	DECLARE_WAITQUEUE(wait,current);
 45	struct atm_vcc *out_vcc;
 46	struct sk_buff *skb;
 47	struct atmtcp_control *new_msg;
 48	int old_test;
 49	int error = 0;
 50
 51	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
 52	if (!out_vcc) return -EUNATCH;
 53	skb = alloc_skb(sizeof(*msg),GFP_KERNEL);
 54	if (!skb) return -ENOMEM;
 55	mb();
 56	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
 57	if (!out_vcc) {
 58		dev_kfree_skb(skb);
 59		return -EUNATCH;
 60	}
 61	atm_force_charge(out_vcc,skb->truesize);
 62	new_msg = (struct atmtcp_control *) skb_put(skb,sizeof(*new_msg));
 63	*new_msg = *msg;
 64	new_msg->hdr.length = ATMTCP_HDR_MAGIC;
 65	new_msg->type = type;
 66	memset(&new_msg->vcc,0,sizeof(atm_kptr_t));
 67	*(struct atm_vcc **) &new_msg->vcc = vcc;
 68	old_test = test_bit(flag,&vcc->flags);
 69	out_vcc->push(out_vcc,skb);
 70	add_wait_queue(sk_atm(vcc)->sk_sleep, &wait);
 71	while (test_bit(flag,&vcc->flags) == old_test) {
 72		mb();
 73		out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
 74		if (!out_vcc) {
 75			error = -EUNATCH;
 76			break;
 77		}
 78		set_current_state(TASK_UNINTERRUPTIBLE);
 79		schedule();
 80	}
 81	set_current_state(TASK_RUNNING);
 82	remove_wait_queue(sk_atm(vcc)->sk_sleep, &wait);
 83	return error;
 84}
 85
 86
 87static int atmtcp_recv_control(const struct atmtcp_control *msg)
 88{
 89	struct atm_vcc *vcc = *(struct atm_vcc **) &msg->vcc;
 90
 91	vcc->vpi = msg->addr.sap_addr.vpi;
 92	vcc->vci = msg->addr.sap_addr.vci;
 93	vcc->qos = msg->qos;
 94	sk_atm(vcc)->sk_err = -msg->result;
 95	switch (msg->type) {
 96	    case ATMTCP_CTRL_OPEN:
 97		change_bit(ATM_VF_READY,&vcc->flags);
 98		break;
 99	    case ATMTCP_CTRL_CLOSE:
100		change_bit(ATM_VF_ADDR,&vcc->flags);
101		break;
102	    default:
103		printk(KERN_ERR "atmtcp_recv_control: unknown type %d\n",
104		    msg->type);
105		return -EINVAL;
106	}
107	wake_up(sk_atm(vcc)->sk_sleep);
108	return 0;
109}
110
111
112static void atmtcp_v_dev_close(struct atm_dev *dev)
113{
114	/* Nothing.... Isn't this simple :-)  -- REW */
115}
116
117
118static int atmtcp_v_open(struct atm_vcc *vcc)
119{
120	struct atmtcp_control msg;
121	int error;
122	short vpi = vcc->vpi;
123	int vci = vcc->vci;
124
125	memset(&msg,0,sizeof(msg));
126	msg.addr.sap_family = AF_ATMPVC;
127	msg.hdr.vpi = htons(vpi);
128	msg.addr.sap_addr.vpi = vpi;
129	msg.hdr.vci = htons(vci);
130	msg.addr.sap_addr.vci = vci;
131	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) return 0;
132	msg.type = ATMTCP_CTRL_OPEN;
133	msg.qos = vcc->qos;
134	set_bit(ATM_VF_ADDR,&vcc->flags);
135	clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
136	error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
137	if (error) return error;
138	return -sk_atm(vcc)->sk_err;
139}
140
141
142static void atmtcp_v_close(struct atm_vcc *vcc)
143{
144	struct atmtcp_control msg;
145
146	memset(&msg,0,sizeof(msg));
147	msg.addr.sap_family = AF_ATMPVC;
148	msg.addr.sap_addr.vpi = vcc->vpi;
149	msg.addr.sap_addr.vci = vcc->vci;
150	clear_bit(ATM_VF_READY,&vcc->flags);
151	(void) atmtcp_send_control(vcc,ATMTCP_CTRL_CLOSE,&msg,ATM_VF_ADDR);
152}
153
154
155static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
156{
157	struct atm_cirange ci;
158	struct atm_vcc *vcc;
159	struct hlist_node *node;
160	struct sock *s;
161	int i;
162
163	if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
164	if (copy_from_user(&ci, arg,sizeof(ci))) return -EFAULT;
165	if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS;
166	if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS;
167	if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
168	    ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL;
169	read_lock(&vcc_sklist_lock);
170	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
171		struct hlist_head *head = &vcc_hash[i];
172
173		sk_for_each(s, node, head) {
174			vcc = atm_sk(s);
175			if (vcc->dev != dev)
176				continue;
177			if ((vcc->vpi >> ci.vpi_bits) ||
178			    (vcc->vci >> ci.vci_bits)) {
179				read_unlock(&vcc_sklist_lock);
180				return -EBUSY;
181			}
182		}
183	}
184	read_unlock(&vcc_sklist_lock);
185	dev->ci_range = ci;
186	return 0;
187}
188
189
190static int atmtcp_v_send(struct atm_vcc *vcc,struct sk_buff *skb)
191{
192	struct atmtcp_dev_data *dev_data;
193	struct atm_vcc *out_vcc=NULL; /* Initializer quietens GCC warning */
194	struct sk_buff *new_skb;
195	struct atmtcp_hdr *hdr;
196	int size;
197
198	if (vcc->qos.txtp.traffic_class == ATM_NONE) {
199		if (vcc->pop) vcc->pop(vcc,skb);
200		else dev_kfree_skb(skb);
201		return -EINVAL;
202	}
203	dev_data = PRIV(vcc->dev);
204	if (dev_data) out_vcc = dev_data->vcc;
205	if (!dev_data || !out_vcc) {
206		if (vcc->pop) vcc->pop(vcc,skb);
207		else dev_kfree_skb(skb);
208		if (dev_data) return 0;
209		atomic_inc(&vcc->stats->tx_err);
210		return -ENOLINK;
211	}
212	size = skb->len+sizeof(struct atmtcp_hdr);
213	new_skb = atm_alloc_charge(out_vcc,size,GFP_ATOMIC);
214	if (!new_skb) {
215		if (vcc->pop) vcc->pop(vcc,skb);
216		else dev_kfree_skb(skb);
217		atomic_inc(&vcc->stats->tx_err);
218		return -ENOBUFS;
219	}
220	hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
221	hdr->vpi = htons(vcc->vpi);
222	hdr->vci = htons(vcc->vci);
223	hdr->length = htonl(skb->len);
224	memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
225	if (vcc->pop) vcc->pop(vcc,skb);
226	else dev_kfree_skb(skb);
227	out_vcc->push(out_vcc,new_skb);
228	atomic_inc(&vcc->stats->tx);
229	atomic_inc(&out_vcc->stats->rx);
230	return 0;
231}
232
233
234static int atmtcp_v_proc(struct atm_dev *dev,loff_t *pos,char *page)
235{
236	struct atmtcp_dev_data *dev_data = PRIV(dev);
237
238	if (*pos) return 0;
239	if (!dev_data->persist) return sprintf(page,"ephemeral\n");
240	return sprintf(page,"persistent, %sconnected\n",
241	    dev_data->vcc ? "" : "dis");
242}
243
244
245static void atmtcp_c_close(struct atm_vcc *vcc)
246{
247	struct atm_dev *atmtcp_dev;
248	struct atmtcp_dev_data *dev_data;
249	struct sock *s;
250	struct hlist_node *node;
251	struct atm_vcc *walk;
252	int i;
253
254	atmtcp_dev = (struct atm_dev *) vcc->dev_data;
255	dev_data = PRIV(atmtcp_dev);
256	dev_data->vcc = NULL;
257	if (dev_data->persist) return;
258	atmtcp_dev->dev_data = NULL;
259	kfree(dev_data);
260	shutdown_atm_dev(atmtcp_dev);
261	vcc->dev_data = NULL;
262	read_lock(&vcc_sklist_lock);
263	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
264		struct hlist_head *head = &vcc_hash[i];
265
266		sk_for_each(s, node, head) {
267			walk = atm_sk(s);
268			if (walk->dev != atmtcp_dev)
269				continue;
270			wake_up(s->sk_sleep);
271		}
272	}
273	read_unlock(&vcc_sklist_lock);
274	module_put(THIS_MODULE);
275}
276
277
278static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
279{
280        struct hlist_head *head;
281        struct atm_vcc *vcc;
282        struct hlist_node *node;
283        struct sock *s;
284
285        head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
286
287        sk_for_each(s, node, head) {
288                vcc = atm_sk(s);
289                if (vcc->dev == dev &&
290                    vcc->vci == vci && vcc->vpi == vpi &&
291                    vcc->qos.rxtp.traffic_class != ATM_NONE) {
292                                return vcc;
293                }
294        }
295        return NULL;
296}
297
298
299static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
300{
301	struct atm_dev *dev;
302	struct atmtcp_hdr *hdr;
303	struct atm_vcc *out_vcc;
304	struct sk_buff *new_skb;
305	int result = 0;
306
307	if (!skb->len) return 0;
308	dev = vcc->dev_data;
309	hdr = (struct atmtcp_hdr *) skb->data;
310	if (hdr->length == ATMTCP_HDR_MAGIC) {
311		result = atmtcp_recv_control(
312		    (struct atmtcp_control *) skb->data);
313		goto done;
314	}
315	read_lock(&vcc_sklist_lock);
316	out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
317	read_unlock(&vcc_sklist_lock);
318	if (!out_vcc) {
319		atomic_inc(&vcc->stats->tx_err);
320		goto done;
321	}
322	skb_pull(skb,sizeof(struct atmtcp_hdr));
323	new_skb = atm_alloc_charge(out_vcc,skb->len,GFP_KERNEL);
324	if (!new_skb) {
325		result = -ENOBUFS;
326		goto done;
327	}
328	do_gettimeofday(&new_skb->stamp);
329	memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
330	out_vcc->push(out_vcc,new_skb);
331	atomic_inc(&vcc->stats->tx);
332	atomic_inc(&out_vcc->stats->rx);
333done:
334	if (vcc->pop) vcc->pop(vcc,skb);
335	else dev_kfree_skb(skb);
336	return result;
337}
338
339
340/*
341 * Device operations for the virtual ATM devices created by ATMTCP.
342 */
343
344
345static struct atmdev_ops atmtcp_v_dev_ops = {
346	.dev_close	= atmtcp_v_dev_close,
347	.open		= atmtcp_v_open,
348	.close		= atmtcp_v_close,
349	.ioctl		= atmtcp_v_ioctl,
350	.send		= atmtcp_v_send,
351	.proc_read	= atmtcp_v_proc,
352	.owner		= THIS_MODULE
353};
354
355
356/*
357 * Device operations for the ATMTCP control device.
358 */
359
360
361static struct atmdev_ops atmtcp_c_dev_ops = {
362	.close		= atmtcp_c_close,
363	.send		= atmtcp_c_send
364};
365
366
367static struct atm_dev atmtcp_control_dev = {
368	.ops		= &atmtcp_c_dev_ops,
369	.type		= "atmtcp",
370	.number		= 999,
371	.lock		= SPIN_LOCK_UNLOCKED
372};
373
374
375static int atmtcp_create(int itf,int persist,struct atm_dev **result)
376{
377	struct atmtcp_dev_data *dev_data;
378	struct atm_dev *dev;
379
380	dev_data = kmalloc(sizeof(*dev_data),GFP_KERNEL);
381	if (!dev_data)
382		return -ENOMEM;
383
384	dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
385	if (!dev) {
386		kfree(dev_data);
387		return itf == -1 ? -ENOMEM : -EBUSY;
388	}
389	dev->ci_range.vpi_bits = MAX_VPI_BITS;
390	dev->ci_range.vci_bits = MAX_VCI_BITS;
391	dev->dev_data = dev_data;
392	PRIV(dev)->vcc = NULL;
393	PRIV(dev)->persist = persist;
394	if (result) *result = dev;
395	return 0;
396}
397
398
399static int atmtcp_attach(struct atm_vcc *vcc,int itf)
400{
401	struct atm_dev *dev;
402
403	dev = NULL;
404	if (itf != -1) dev = atm_dev_lookup(itf);
405	if (dev) {
406		if (dev->ops != &atmtcp_v_dev_ops) {
407			atm_dev_put(dev);
408			return -EMEDIUMTYPE;
409		}
410		if (PRIV(dev)->vcc) return -EBUSY;
411	}
412	else {
413		int error;
414
415		error = atmtcp_create(itf,0,&dev);
416		if (error) return error;
417	}
418	PRIV(dev)->vcc = vcc;
419	vcc->dev = &atmtcp_control_dev;
420	vcc_insert_socket(sk_atm(vcc));
421	set_bit(ATM_VF_META,&vcc->flags);
422	set_bit(ATM_VF_READY,&vcc->flags);
423	vcc->dev_data = dev;
424	(void) atm_init_aal5(vcc); /* @@@ losing AAL in transit ... */
425	vcc->stats = &atmtcp_control_dev.stats.aal5;
426	return dev->number;
427}
428
429
430static int atmtcp_create_persistent(int itf)
431{
432	return atmtcp_create(itf,1,NULL);
433}
434
435
436static int atmtcp_remove_persistent(int itf)
437{
438	struct atm_dev *dev;
439	struct atmtcp_dev_data *dev_data;
440
441	dev = atm_dev_lookup(itf);
442	if (!dev) return -ENODEV;
443	if (dev->ops != &atmtcp_v_dev_ops) {
444		atm_dev_put(dev);
445		return -EMEDIUMTYPE;
446	}
447	dev_data = PRIV(dev);
448	if (!dev_data->persist) return 0;
449	dev_data->persist = 0;
450	if (PRIV(dev)->vcc) return 0;
451	kfree(dev_data);
452	atm_dev_put(dev);
453	shutdown_atm_dev(dev);
454	return 0;
455}
456
457static int atmtcp_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
458{
459	int err = 0;
460	struct atm_vcc *vcc = ATM_SD(sock);
461
462	if (cmd != SIOCSIFATMTCP && cmd != ATMTCP_CREATE && cmd != ATMTCP_REMOVE)
463		return -ENOIOCTLCMD;
464
465	if (!capable(CAP_NET_ADMIN))
466		return -EPERM;
467
468	switch (cmd) {
469		case SIOCSIFATMTCP:
470			err = atmtcp_attach(vcc, (int) arg);
471			if (err >= 0) {
472				sock->state = SS_CONNECTED;
473				__module_get(THIS_MODULE);
474			}
475			break;
476		case ATMTCP_CREATE:
477			err = atmtcp_create_persistent((int) arg);
478			break;
479		case ATMTCP_REMOVE:
480			err = atmtcp_remove_persistent((int) arg);
481			break;
482	}
483	return err;
484}
485
486static struct atm_ioctl atmtcp_ioctl_ops = {
487	.owner 	= THIS_MODULE,
488	.ioctl	= atmtcp_ioctl,
489};
490
491static __init int atmtcp_init(void)
492{
493	register_atm_ioctl(&atmtcp_ioctl_ops);
494	return 0;
495}
496
497
498static void __exit atmtcp_exit(void)
499{
500	deregister_atm_ioctl(&atmtcp_ioctl_ops);
501}
502
503MODULE_LICENSE("GPL");
504module_init(atmtcp_init);
505module_exit(atmtcp_exit);