common.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:30k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* net/atm/common.c - ATM sockets (common part for PVC and SVC) */
  2. /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
  3. #include <linux/config.h>
  4. #include <linux/module.h>
  5. #include <linux/kmod.h>
  6. #include <linux/net.h> /* struct socket, struct net_proto, struct
  7.    proto_ops */
  8. #include <linux/atm.h> /* ATM stuff */
  9. #include <linux/atmdev.h>
  10. #include <linux/atmclip.h> /* CLIP_*ENCAP */
  11. #include <linux/atmarp.h> /* manifest constants */
  12. #include <linux/sonet.h> /* for ioctls */
  13. #include <linux/socket.h> /* SOL_SOCKET */
  14. #include <linux/errno.h> /* error codes */
  15. #include <linux/capability.h>
  16. #include <linux/mm.h> /* verify_area */
  17. #include <linux/sched.h>
  18. #include <linux/time.h> /* struct timeval */
  19. #include <linux/skbuff.h>
  20. #include <linux/bitops.h>
  21. #include <net/sock.h> /* struct sock */
  22. #include <asm/uaccess.h>
  23. #include <asm/atomic.h>
  24. #include <asm/poll.h>
  25. #include <asm/ioctls.h>
  26. #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
  27. #include <linux/atmlec.h>
  28. #include "lec.h"
  29. #include "lec_arpc.h"
  30. struct atm_lane_ops atm_lane_ops;
  31. #endif
  32. #ifdef CONFIG_ATM_LANE_MODULE
  33. EXPORT_SYMBOL(atm_lane_ops);
  34. #endif
  35. #if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
  36. #include <linux/atmmpc.h>
  37. #include "mpc.h"
  38. struct atm_mpoa_ops atm_mpoa_ops;
  39. #endif
  40. #ifdef CONFIG_ATM_MPOA_MODULE
  41. EXPORT_SYMBOL(atm_mpoa_ops);
  42. #ifndef CONFIG_ATM_LANE_MODULE
  43. EXPORT_SYMBOL(atm_lane_ops);
  44. #endif
  45. #endif
  46. #if defined(CONFIG_ATM_TCP) || defined(CONFIG_ATM_TCP_MODULE)
  47. #include <linux/atm_tcp.h>
  48. #ifdef CONFIG_ATM_TCP_MODULE
  49. struct atm_tcp_ops atm_tcp_ops;
  50. EXPORT_SYMBOL(atm_tcp_ops);
  51. #endif
  52. #endif
  53. #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
  54. int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
  55. EXPORT_SYMBOL(pppoatm_ioctl_hook);
  56. #endif
  57. #if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
  58. int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
  59. #endif
  60. #ifdef CONFIG_ATM_BR2684_MODULE
  61. EXPORT_SYMBOL(br2684_ioctl_hook);
  62. #endif
  63. #include "resources.h" /* atm_find_dev */
  64. #include "common.h" /* prototypes */
  65. #include "protocols.h" /* atm_init_<transport> */
  66. #include "addr.h" /* address registry */
  67. #ifdef CONFIG_ATM_CLIP
  68. #include <net/atmclip.h> /* for clip_create */
  69. #endif
  70. #include "signaling.h" /* for WAITING and sigd_attach */
  71. #if 0
  72. #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
  73. #else
  74. #define DPRINTK(format,args...)
  75. #endif
  76. spinlock_t atm_dev_lock = SPIN_LOCK_UNLOCKED;
  77. static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size)
  78. {
  79. struct sk_buff *skb;
  80. if (atomic_read(&vcc->tx_inuse) && !atm_may_send(vcc,size)) {
  81. DPRINTK("Sorry: tx_inuse = %d, size = %d, sndbuf = %dn",
  82.     atomic_read(&vcc->tx_inuse),size,vcc->sk->sndbuf);
  83. return NULL;
  84. }
  85. while (!(skb = alloc_skb(size,GFP_KERNEL))) schedule();
  86. DPRINTK("AlTx %d += %dn",atomic_read(&vcc->tx_inuse),skb->truesize);
  87. atomic_add(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse);
  88. return skb;
  89. }
  90. int atm_create(struct socket *sock,int protocol,int family)
  91. {
  92. struct sock *sk;
  93. struct atm_vcc *vcc;
  94. sock->sk = NULL;
  95. if (sock->type == SOCK_STREAM) return -EINVAL;
  96. if (!(sk = alloc_atm_vcc_sk(family))) return -ENOMEM;
  97. vcc = sk->protinfo.af_atm;
  98. memset(&vcc->flags,0,sizeof(vcc->flags));
  99. vcc->dev = NULL;
  100. vcc->family = sock->ops->family;
  101. vcc->alloc_tx = alloc_tx;
  102. vcc->callback = NULL;
  103. memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc));
  104. memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc));
  105. vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */
  106. atomic_set(&vcc->tx_inuse,0);
  107. atomic_set(&vcc->rx_inuse,0);
  108. vcc->push = NULL;
  109. vcc->pop = NULL;
  110. vcc->push_oam = NULL;
  111. vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
  112. vcc->atm_options = vcc->aal_options = 0;
  113. vcc->timestamp.tv_sec = vcc->timestamp.tv_usec = 0;
  114. init_waitqueue_head(&vcc->sleep);
  115. skb_queue_head_init(&vcc->recvq);
  116. skb_queue_head_init(&vcc->listenq);
  117. sk->sleep = &vcc->sleep;
  118. sock->sk = sk;
  119. return 0;
  120. }
  121. void atm_release_vcc_sk(struct sock *sk,int free_sk)
  122. {
  123. struct atm_vcc *vcc;
  124. struct sk_buff *skb;
  125. vcc = sk->protinfo.af_atm;
  126. clear_bit(ATM_VF_READY,&vcc->flags);
  127. if (vcc->dev) {
  128. if (vcc->dev->ops->close) vcc->dev->ops->close(vcc);
  129. if (vcc->push) vcc->push(vcc,NULL); /* atmarpd has no push */
  130. while ((skb = skb_dequeue(&vcc->recvq))) {
  131. atm_return(vcc,skb->truesize);
  132. if (vcc->dev->ops->free_rx_skb)
  133. vcc->dev->ops->free_rx_skb(vcc,skb);
  134. else kfree_skb(skb);
  135. }
  136. spin_lock (&atm_dev_lock);
  137. fops_put (vcc->dev->ops);
  138. if (atomic_read(&vcc->rx_inuse))
  139. printk(KERN_WARNING "atm_release_vcc: strange ... "
  140.     "rx_inuse == %d after closingn",
  141.     atomic_read(&vcc->rx_inuse));
  142. bind_vcc(vcc,NULL);
  143. } else
  144. spin_lock (&atm_dev_lock);
  145. if (free_sk) free_atm_vcc_sk(sk);
  146. spin_unlock (&atm_dev_lock);
  147. }
  148. int atm_release(struct socket *sock)
  149. {
  150. if (sock->sk)
  151. atm_release_vcc_sk(sock->sk,1);
  152. return 0;
  153. }
  154. void atm_async_release_vcc(struct atm_vcc *vcc,int reply)
  155. {
  156. set_bit(ATM_VF_CLOSE,&vcc->flags);
  157. vcc->reply = reply;
  158. wake_up(&vcc->sleep);
  159. }
  160. EXPORT_SYMBOL(atm_async_release_vcc);
  161. static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
  162. {
  163. int max_sdu;
  164. if (!tp->traffic_class) return 0;
  165. switch (aal) {
  166. case ATM_AAL0:
  167. max_sdu = ATM_CELL_SIZE-1;
  168. break;
  169. case ATM_AAL34:
  170. max_sdu = ATM_MAX_AAL34_PDU;
  171. break;
  172. default:
  173. printk(KERN_WARNING "ATM: AAL problems ... "
  174.     "(%d)n",aal);
  175. /* fall through */
  176. case ATM_AAL5:
  177. max_sdu = ATM_MAX_AAL5_PDU;
  178. }
  179. if (!tp->max_sdu) tp->max_sdu = max_sdu;
  180. else if (tp->max_sdu > max_sdu) return -EINVAL;
  181. if (!tp->max_cdv) tp->max_cdv = ATM_MAX_CDV;
  182. return 0;
  183. }
  184. static int atm_do_connect_dev(struct atm_vcc *vcc,struct atm_dev *dev,int vpi,
  185.     int vci)
  186. {
  187. int error;
  188. if ((vpi != ATM_VPI_UNSPEC && vpi != ATM_VPI_ANY &&
  189.     vpi >> dev->ci_range.vpi_bits) || (vci != ATM_VCI_UNSPEC &&
  190.     vci != ATM_VCI_ANY && vci >> dev->ci_range.vci_bits))
  191. return -EINVAL;
  192. if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE))
  193. return -EPERM;
  194. error = 0;
  195. bind_vcc(vcc,dev);
  196. switch (vcc->qos.aal) {
  197. case ATM_AAL0:
  198. error = atm_init_aal0(vcc);
  199. vcc->stats = &dev->stats.aal0;
  200. break;
  201. case ATM_AAL34:
  202. error = atm_init_aal34(vcc);
  203. vcc->stats = &dev->stats.aal34;
  204. break;
  205. case ATM_NO_AAL:
  206. /* ATM_AAL5 is also used in the "0 for default" case */
  207. vcc->qos.aal = ATM_AAL5;
  208. /* fall through */
  209. case ATM_AAL5:
  210. error = atm_init_aal5(vcc);
  211. vcc->stats = &dev->stats.aal5;
  212. break;
  213. default:
  214. error = -EPROTOTYPE;
  215. }
  216. if (!error) error = adjust_tp(&vcc->qos.txtp,vcc->qos.aal);
  217. if (!error) error = adjust_tp(&vcc->qos.rxtp,vcc->qos.aal);
  218. if (error) {
  219. bind_vcc(vcc,NULL);
  220. return error;
  221. }
  222. DPRINTK("VCC %d.%d, AAL %dn",vpi,vci,vcc->qos.aal);
  223. DPRINTK("  TX: %d, PCR %d..%d, SDU %dn",vcc->qos.txtp.traffic_class,
  224.     vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu);
  225. DPRINTK("  RX: %d, PCR %d..%d, SDU %dn",vcc->qos.rxtp.traffic_class,
  226.     vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu);
  227. fops_get (dev->ops);
  228. if (dev->ops->open) {
  229. error = dev->ops->open(vcc,vpi,vci);
  230. if (error) {
  231. fops_put (dev->ops);
  232. bind_vcc(vcc,NULL);
  233. return error;
  234. }
  235. }
  236. return 0;
  237. }
  238. static int atm_do_connect(struct atm_vcc *vcc,int itf,int vpi,int vci)
  239. {
  240. struct atm_dev *dev;
  241. int return_val;
  242. spin_lock (&atm_dev_lock);
  243. dev = atm_find_dev(itf);
  244. if (!dev)
  245. return_val =  -ENODEV;
  246. else
  247. return_val = atm_do_connect_dev(vcc,dev,vpi,vci);
  248. spin_unlock (&atm_dev_lock);
  249. return return_val;
  250. }
  251. int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci)
  252. {
  253. if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC)
  254. clear_bit(ATM_VF_PARTIAL,&vcc->flags);
  255. else if (test_bit(ATM_VF_PARTIAL,&vcc->flags)) return -EINVAL;
  256. printk(KERN_DEBUG "atm_connect (TX: cl %d,bw %d-%d,sdu %d; "
  257.     "RX: cl %d,bw %d-%d,sdu %d,AAL %s%d)n",
  258.     vcc->qos.txtp.traffic_class,vcc->qos.txtp.min_pcr,
  259.     vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu,
  260.     vcc->qos.rxtp.traffic_class,vcc->qos.rxtp.min_pcr,
  261.     vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu,
  262.     vcc->qos.aal == ATM_AAL5 ? "" : vcc->qos.aal == ATM_AAL0 ? "" :
  263.     " ??? code ",vcc->qos.aal == ATM_AAL0 ? 0 : vcc->qos.aal);
  264. if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
  265. if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
  266.     vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
  267. return -EINVAL;
  268. if (itf != ATM_ITF_ANY) {
  269. int error;
  270. error = atm_do_connect(vcc,itf,vpi,vci);
  271. if (error) return error;
  272. }
  273. else {
  274. struct atm_dev *dev;
  275. spin_lock (&atm_dev_lock);
  276. for (dev = atm_devs; dev; dev = dev->next)
  277. if (!atm_do_connect_dev(vcc,dev,vpi,vci)) break;
  278. spin_unlock (&atm_dev_lock);
  279. if (!dev) return -ENODEV;
  280. }
  281. if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
  282. set_bit(ATM_VF_PARTIAL,&vcc->flags);
  283. return 0;
  284. }
  285. int atm_connect(struct socket *sock,int itf,short vpi,int vci)
  286. {
  287. int error;
  288. DPRINTK("atm_connect (vpi %d, vci %d)n",vpi,vci);
  289. if (sock->state == SS_CONNECTED) return -EISCONN;
  290. if (sock->state != SS_UNCONNECTED) return -EINVAL;
  291. if (!(vpi || vci)) return -EINVAL;
  292. error = atm_connect_vcc(ATM_SD(sock),itf,vpi,vci);
  293. if (error) return error;
  294. if (test_bit(ATM_VF_READY,&ATM_SD(sock)->flags))
  295. sock->state = SS_CONNECTED;
  296. return 0;
  297. }
  298. int atm_recvmsg(struct socket *sock,struct msghdr *m,int total_len,
  299.     int flags,struct scm_cookie *scm)
  300. {
  301. DECLARE_WAITQUEUE(wait,current);
  302. struct atm_vcc *vcc;
  303. struct sk_buff *skb;
  304. int eff_len,error;
  305. void *buff;
  306. int size;
  307. if (sock->state != SS_CONNECTED) return -ENOTCONN;
  308. if (flags & ~MSG_DONTWAIT) return -EOPNOTSUPP;
  309. if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
  310. buff = m->msg_iov->iov_base;
  311. size = m->msg_iov->iov_len;
  312. vcc = ATM_SD(sock);
  313. add_wait_queue(&vcc->sleep,&wait);
  314. set_current_state(TASK_INTERRUPTIBLE);
  315. error = 1; /* <= 0 is error */
  316. while (!(skb = skb_dequeue(&vcc->recvq))) {
  317. if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
  318.     test_bit(ATM_VF_CLOSE,&vcc->flags)) {
  319. error = vcc->reply;
  320. break;
  321. }
  322. if (!test_bit(ATM_VF_READY,&vcc->flags)) {
  323. error = 0;
  324. break;
  325. }
  326. if (flags & MSG_DONTWAIT) {
  327. error = -EAGAIN;
  328. break;
  329. }
  330. schedule();
  331. set_current_state(TASK_INTERRUPTIBLE);
  332. if (signal_pending(current)) {
  333. error = -ERESTARTSYS;
  334. break;
  335. }
  336. }
  337. set_current_state(TASK_RUNNING);
  338. remove_wait_queue(&vcc->sleep,&wait);
  339. if (error <= 0) return error;
  340. vcc->timestamp = skb->stamp;
  341. eff_len = skb->len > size ? size : skb->len;
  342. if (skb->len > size) /* Not fit ?  Report it... */
  343. m->msg_flags |= MSG_TRUNC;
  344. if (vcc->dev->ops->feedback)
  345. vcc->dev->ops->feedback(vcc,skb,(unsigned long) skb->data,
  346.     (unsigned long) buff,eff_len);
  347. DPRINTK("RcvM %d -= %dn",atomic_read(&vcc->rx_inuse),skb->truesize);
  348. atm_return(vcc,skb->truesize);
  349. if (ATM_SKB(skb)->iovcnt) { /* @@@ hack */
  350. /* iovcnt set, use scatter-gather for receive */
  351. int el, cnt;
  352. struct iovec *iov = (struct iovec *)skb->data;
  353. unsigned char *p = (unsigned char *)buff;
  354. el = eff_len;
  355. error = 0;
  356. for (cnt = 0; (cnt < ATM_SKB(skb)->iovcnt) && el; cnt++) {
  357. /*printk("s-g???: %p -> %p (%d)n",iov->iov_base,p,iov->iov_len);*/
  358. error = copy_to_user(p,iov->iov_base,
  359.     (iov->iov_len > el) ? el : iov->iov_len) ?
  360.     -EFAULT : 0;
  361. if (error) break;
  362. p += iov->iov_len;
  363. el -= (iov->iov_len > el)?el:iov->iov_len;
  364. iov++;
  365. }
  366. if (!vcc->dev->ops->free_rx_skb) kfree_skb(skb);
  367. else vcc->dev->ops->free_rx_skb(vcc, skb);
  368. return error ? error : eff_len;
  369. }
  370. error = copy_to_user(buff,skb->data,eff_len) ? -EFAULT : 0;
  371. if (!vcc->dev->ops->free_rx_skb) kfree_skb(skb);
  372. else vcc->dev->ops->free_rx_skb(vcc, skb);
  373. return error ? error : eff_len;
  374. }
  375. int atm_sendmsg(struct socket *sock,struct msghdr *m,int total_len,
  376.     struct scm_cookie *scm)
  377. {
  378. DECLARE_WAITQUEUE(wait,current);
  379. struct atm_vcc *vcc;
  380. struct sk_buff *skb;
  381. int eff,error;
  382. const void *buff;
  383. int size;
  384. if (sock->state != SS_CONNECTED) return -ENOTCONN;
  385. if (m->msg_name) return -EISCONN;
  386. if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
  387. buff = m->msg_iov->iov_base;
  388. size = m->msg_iov->iov_len;
  389. vcc = ATM_SD(sock);
  390. if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
  391.     test_bit(ATM_VF_CLOSE,&vcc->flags))
  392. return vcc->reply;
  393. if (!test_bit(ATM_VF_READY,&vcc->flags)) return -EPIPE;
  394. if (!size) return 0;
  395. if (size < 0 || size > vcc->qos.txtp.max_sdu) return -EMSGSIZE;
  396. /* verify_area is done by net/socket.c */
  397. eff = (size+3) & ~3; /* align to word boundary */
  398. add_wait_queue(&vcc->sleep,&wait);
  399. set_current_state(TASK_INTERRUPTIBLE);
  400. error = 0;
  401. while (!(skb = vcc->alloc_tx(vcc,eff))) {
  402. if (m->msg_flags & MSG_DONTWAIT) {
  403. error = -EAGAIN;
  404. break;
  405. }
  406. schedule();
  407. set_current_state(TASK_INTERRUPTIBLE);
  408. if (signal_pending(current)) {
  409. error = -ERESTARTSYS;
  410. break;
  411. }
  412. if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
  413.     test_bit(ATM_VF_CLOSE,&vcc->flags)) {
  414. error = vcc->reply;
  415. break;
  416. }
  417. if (!test_bit(ATM_VF_READY,&vcc->flags)) {
  418. error = -EPIPE;
  419. break;
  420. }
  421. }
  422. set_current_state(TASK_RUNNING);
  423. remove_wait_queue(&vcc->sleep,&wait);
  424. if (error) return error;
  425. skb->dev = NULL; /* for paths shared with net_device interfaces */
  426. ATM_SKB(skb)->iovcnt = 0;
  427. ATM_SKB(skb)->atm_options = vcc->atm_options;
  428. if (copy_from_user(skb_put(skb,size),buff,size)) {
  429. kfree_skb(skb);
  430. return -EFAULT;
  431. }
  432. if (eff != size) memset(skb->data+size,0,eff-size);
  433. error = vcc->dev->ops->send(vcc,skb);
  434. return error ? error : size;
  435. }
  436. unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait)
  437. {
  438. struct atm_vcc *vcc;
  439. unsigned int mask;
  440. vcc = ATM_SD(sock);
  441. poll_wait(file,&vcc->sleep,wait);
  442. mask = 0;
  443. if (skb_peek(&vcc->recvq) || skb_peek(&vcc->listenq))
  444. mask |= POLLIN | POLLRDNORM;
  445. if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
  446.     test_bit(ATM_VF_CLOSE,&vcc->flags))
  447. mask |= POLLHUP;
  448. if (sock->state != SS_CONNECTING) {
  449. if (vcc->qos.txtp.traffic_class != ATM_NONE &&
  450.     vcc->qos.txtp.max_sdu+atomic_read(&vcc->tx_inuse)+
  451.     ATM_PDU_OVHD <= vcc->sk->sndbuf)
  452. mask |= POLLOUT | POLLWRNORM;
  453. }
  454. else if (vcc->reply != WAITING) {
  455. mask |= POLLOUT | POLLWRNORM;
  456. if (vcc->reply) mask |= POLLERR;
  457. }
  458. return mask;
  459. }
  460. static void copy_aal_stats(struct k_atm_aal_stats *from,
  461.     struct atm_aal_stats *to)
  462. {
  463. #define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
  464. __AAL_STAT_ITEMS
  465. #undef __HANDLE_ITEM
  466. }
  467. static void subtract_aal_stats(struct k_atm_aal_stats *from,
  468.     struct atm_aal_stats *to)
  469. {
  470. #define __HANDLE_ITEM(i) atomic_sub(to->i,&from->i)
  471. __AAL_STAT_ITEMS
  472. #undef __HANDLE_ITEM
  473. }
  474. static int fetch_stats(struct atm_dev *dev,struct atm_dev_stats *arg,int zero)
  475. {
  476. struct atm_dev_stats tmp;
  477. int error = 0;
  478. copy_aal_stats(&dev->stats.aal0,&tmp.aal0);
  479. copy_aal_stats(&dev->stats.aal34,&tmp.aal34);
  480. copy_aal_stats(&dev->stats.aal5,&tmp.aal5);
  481. if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
  482. if (zero && !error) {
  483. subtract_aal_stats(&dev->stats.aal0,&tmp.aal0);
  484. subtract_aal_stats(&dev->stats.aal34,&tmp.aal34);
  485. subtract_aal_stats(&dev->stats.aal5,&tmp.aal5);
  486. }
  487. return error ? -EFAULT : 0;
  488. }
  489. int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
  490. {
  491. struct atm_dev *dev;
  492. struct atm_vcc *vcc;
  493. int *tmp_buf, *tmp_p;
  494. void *buf;
  495. int error,len,size,number, ret_val;
  496. ret_val = 0;
  497. spin_lock (&atm_dev_lock);
  498. vcc = ATM_SD(sock);
  499. switch (cmd) {
  500. case SIOCOUTQ:
  501. if (sock->state != SS_CONNECTED ||
  502.     !test_bit(ATM_VF_READY,&vcc->flags)) {
  503. ret_val =  -EINVAL;
  504. goto done;
  505. }
  506. ret_val =  put_user(vcc->sk->sndbuf-
  507.     atomic_read(&vcc->tx_inuse)-ATM_PDU_OVHD,
  508.     (int *) arg) ? -EFAULT : 0;
  509. goto done;
  510. case SIOCINQ:
  511. {
  512. struct sk_buff *skb;
  513. if (sock->state != SS_CONNECTED) {
  514. ret_val = -EINVAL;
  515. goto done;
  516. }
  517. skb = skb_peek(&vcc->recvq);
  518. ret_val = put_user(skb ? skb->len : 0,(int *) arg)
  519.     ? -EFAULT : 0;
  520. goto done;
  521. }
  522. case ATM_GETNAMES:
  523. if (get_user(buf,
  524.      &((struct atm_iobuf *) arg)->buffer)) {
  525. ret_val = -EFAULT;
  526. goto done;
  527. }
  528. if (get_user(len,
  529.      &((struct atm_iobuf *) arg)->length)) {
  530. ret_val = -EFAULT;
  531. goto done;
  532. }
  533. size = 0;
  534. for (dev = atm_devs; dev; dev = dev->next)
  535. size += sizeof(int);
  536. if (size > len) {
  537. ret_val = -E2BIG;
  538. goto done;
  539. }
  540. tmp_buf = kmalloc(size,GFP_KERNEL);
  541. if (!tmp_buf) {
  542. ret_val = -ENOMEM;
  543. goto done;
  544. }
  545. tmp_p = tmp_buf;
  546. for (dev = atm_devs; dev; dev = dev->next)
  547. *tmp_p++ = dev->number;
  548.         ret_val = ((copy_to_user(buf, tmp_buf, size)) ||
  549.     put_user(size, &((struct atm_iobuf *) arg)->length)
  550.     ) ? -EFAULT : 0;
  551. kfree(tmp_buf);
  552. goto done;
  553. case SIOCGSTAMP: /* borrowed from IP */
  554. if (!vcc->timestamp.tv_sec) {
  555. ret_val = -ENOENT;
  556. goto done;
  557. }
  558. vcc->timestamp.tv_sec += vcc->timestamp.tv_usec/1000000;
  559. vcc->timestamp.tv_usec %= 1000000;
  560. ret_val = copy_to_user((void *) arg,&vcc->timestamp,
  561.     sizeof(struct timeval)) ? -EFAULT : 0;
  562. goto done;
  563. case ATM_SETSC:
  564. printk(KERN_WARNING "ATM_SETSC is obsoleten");
  565. ret_val = 0;
  566. goto done;
  567. case ATMSIGD_CTRL:
  568. if (!capable(CAP_NET_ADMIN)) {
  569. ret_val = -EPERM;
  570. goto done;
  571. }
  572. /*
  573.  * The user/kernel protocol for exchanging signalling
  574.  * info uses kernel pointers as opaque references,
  575.  * so the holder of the file descriptor can scribble
  576.  * on the kernel... so we should make sure that we
  577.  * have the same privledges that /proc/kcore needs
  578.  */
  579. if (!capable(CAP_SYS_RAWIO)) {
  580. ret_val = -EPERM;
  581. goto done;
  582. }
  583. error = sigd_attach(vcc);
  584. if (!error) sock->state = SS_CONNECTED;
  585. ret_val = error;
  586. goto done;
  587. #ifdef CONFIG_ATM_CLIP
  588. case SIOCMKCLIP:
  589. if (!capable(CAP_NET_ADMIN))
  590. ret_val = -EPERM;
  591. else 
  592. ret_val = clip_create(arg);
  593. goto done;
  594. case ATMARPD_CTRL:
  595. if (!capable(CAP_NET_ADMIN)) {
  596. ret_val = -EPERM;
  597. goto done;
  598. }
  599. error = atm_init_atmarp(vcc);
  600. if (!error) sock->state = SS_CONNECTED;
  601. ret_val = error;
  602. goto done;
  603. case ATMARP_MKIP:
  604. if (!capable(CAP_NET_ADMIN)) 
  605. ret_val = -EPERM;
  606. else 
  607. ret_val = clip_mkip(vcc,arg);
  608. goto done;
  609. case ATMARP_SETENTRY:
  610. if (!capable(CAP_NET_ADMIN)) 
  611. ret_val = -EPERM;
  612. else
  613. ret_val = clip_setentry(vcc,arg);
  614. goto done;
  615. case ATMARP_ENCAP:
  616. if (!capable(CAP_NET_ADMIN)) 
  617. ret_val = -EPERM;
  618. else
  619. ret_val = clip_encap(vcc,arg);
  620. goto done;
  621. #endif
  622. #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
  623.                 case ATMLEC_CTRL:
  624.                         if (!capable(CAP_NET_ADMIN)) {
  625. ret_val = -EPERM;
  626. goto done;
  627. }
  628.                         if (atm_lane_ops.lecd_attach == NULL)
  629. atm_lane_init();
  630.                         if (atm_lane_ops.lecd_attach == NULL) { /* try again */
  631. ret_val = -ENOSYS;
  632. goto done;
  633. }
  634. error = atm_lane_ops.lecd_attach(vcc, (int)arg);
  635. if (error >= 0) sock->state = SS_CONNECTED;
  636. ret_val =  error;
  637. goto done;
  638.                 case ATMLEC_MCAST:
  639. if (!capable(CAP_NET_ADMIN))
  640. ret_val = -EPERM;
  641. else
  642. ret_val = atm_lane_ops.mcast_attach(vcc, (int)arg);
  643. goto done;
  644.                 case ATMLEC_DATA:
  645. if (!capable(CAP_NET_ADMIN))
  646. ret_val = -EPERM;
  647. else
  648. ret_val = atm_lane_ops.vcc_attach(vcc, (void*)arg);
  649. goto done;
  650. #endif
  651. #if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
  652. case ATMMPC_CTRL:
  653. if (!capable(CAP_NET_ADMIN)) {
  654. ret_val = -EPERM;
  655. goto done;
  656. }
  657. if (atm_mpoa_ops.mpoad_attach == NULL)
  658.                                 atm_mpoa_init();
  659. if (atm_mpoa_ops.mpoad_attach == NULL) { /* try again */
  660. ret_val = -ENOSYS;
  661. goto done;
  662. }
  663. error = atm_mpoa_ops.mpoad_attach(vcc, (int)arg);
  664. if (error >= 0) sock->state = SS_CONNECTED;
  665. ret_val = error;
  666. goto done;
  667. case ATMMPC_DATA:
  668. if (!capable(CAP_NET_ADMIN)) 
  669. ret_val = -EPERM;
  670. else
  671. ret_val = atm_mpoa_ops.vcc_attach(vcc, arg);
  672. goto done;
  673. #endif
  674. #if defined(CONFIG_ATM_TCP) || defined(CONFIG_ATM_TCP_MODULE)
  675. case SIOCSIFATMTCP:
  676. if (!capable(CAP_NET_ADMIN)) {
  677. ret_val = -EPERM;
  678. goto done;
  679. }
  680. if (!atm_tcp_ops.attach) {
  681. ret_val = -ENOPKG;
  682. goto done;
  683. }
  684. fops_get (&atm_tcp_ops);
  685. error = atm_tcp_ops.attach(vcc,(int) arg);
  686. if (error >= 0) sock->state = SS_CONNECTED;
  687. else            fops_put (&atm_tcp_ops);
  688. ret_val = error;
  689. goto done;
  690. case ATMTCP_CREATE:
  691. if (!capable(CAP_NET_ADMIN)) {
  692. ret_val = -EPERM;
  693. goto done;
  694. }
  695. if (!atm_tcp_ops.create_persistent) {
  696. ret_val = -ENOPKG;
  697. goto done;
  698. }
  699. error = atm_tcp_ops.create_persistent((int) arg);
  700. if (error < 0) fops_put (&atm_tcp_ops);
  701. ret_val = error;
  702. goto done;
  703. case ATMTCP_REMOVE:
  704. if (!capable(CAP_NET_ADMIN)) {
  705. ret_val = -EPERM;
  706. goto done;
  707. }
  708. if (!atm_tcp_ops.remove_persistent) {
  709. ret_val = -ENOPKG;
  710. goto done;
  711. }
  712. error = atm_tcp_ops.remove_persistent((int) arg);
  713. fops_put (&atm_tcp_ops);
  714. ret_val = error;
  715. goto done;
  716. #endif
  717. default:
  718. break;
  719. }
  720. #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
  721. if (pppoatm_ioctl_hook) {
  722. ret_val = pppoatm_ioctl_hook(vcc, cmd, arg);
  723. if (ret_val != -ENOIOCTLCMD)
  724. goto done;
  725. }
  726. #endif
  727. #if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
  728. if (br2684_ioctl_hook) {
  729. ret_val = br2684_ioctl_hook(vcc, cmd, arg);
  730. if (ret_val != -ENOIOCTLCMD)
  731. goto done;
  732. }
  733. #endif
  734. if (get_user(buf,&((struct atmif_sioc *) arg)->arg)) {
  735. ret_val = -EFAULT;
  736. goto done;
  737. }
  738. if (get_user(len,&((struct atmif_sioc *) arg)->length)) {
  739. ret_val = -EFAULT;
  740. goto done;
  741. }
  742. if (get_user(number,&((struct atmif_sioc *) arg)->number)) {
  743. ret_val = -EFAULT;
  744. goto done;
  745. }
  746. if (!(dev = atm_find_dev(number))) {
  747. ret_val = -ENODEV;
  748. goto done;
  749. }
  750. size = 0;
  751. switch (cmd) {
  752. case ATM_GETTYPE:
  753. size = strlen(dev->type)+1;
  754. if (copy_to_user(buf,dev->type,size)) {
  755. ret_val = -EFAULT;
  756. goto done;
  757. }
  758. break;
  759. case ATM_GETESI:
  760. size = ESI_LEN;
  761. if (copy_to_user(buf,dev->esi,size)) {
  762. ret_val = -EFAULT;
  763. goto done;
  764. }
  765. break;
  766. case ATM_SETESI:
  767. {
  768. int i;
  769. for (i = 0; i < ESI_LEN; i++)
  770. if (dev->esi[i]) {
  771. ret_val = -EEXIST;
  772. goto done;
  773. }
  774. }
  775. /* fall through */
  776. case ATM_SETESIF:
  777. {
  778. unsigned char esi[ESI_LEN];
  779. if (!capable(CAP_NET_ADMIN)) {
  780. ret_val = -EPERM;
  781. goto done;
  782. }
  783. if (copy_from_user(esi,buf,ESI_LEN)) {
  784. ret_val = -EFAULT;
  785. goto done;
  786. }
  787. memcpy(dev->esi,esi,ESI_LEN);
  788. ret_val =  ESI_LEN;
  789. goto done;
  790. }
  791. case ATM_GETSTATZ:
  792. if (!capable(CAP_NET_ADMIN)) {
  793. ret_val = -EPERM;
  794. goto done;
  795. }
  796. /* fall through */
  797. case ATM_GETSTAT:
  798. size = sizeof(struct atm_dev_stats);
  799. error = fetch_stats(dev,buf,cmd == ATM_GETSTATZ);
  800. if (error) {
  801. ret_val = error;
  802. goto done;
  803. }
  804. break;
  805. case ATM_GETCIRANGE:
  806. size = sizeof(struct atm_cirange);
  807. if (copy_to_user(buf,&dev->ci_range,size)) {
  808. ret_val = -EFAULT;
  809. goto done;
  810. }
  811. break;
  812. case ATM_GETLINKRATE:
  813. size = sizeof(int);
  814. if (copy_to_user(buf,&dev->link_rate,size)) {
  815. ret_val = -EFAULT;
  816. goto done;
  817. }
  818. break;
  819. case ATM_RSTADDR:
  820. if (!capable(CAP_NET_ADMIN)) {
  821. ret_val = -EPERM;
  822. goto done;
  823. }
  824. atm_reset_addr(dev);
  825. break;
  826. case ATM_ADDADDR:
  827. case ATM_DELADDR:
  828. if (!capable(CAP_NET_ADMIN)) {
  829. ret_val = -EPERM;
  830. goto done;
  831. }
  832. {
  833. struct sockaddr_atmsvc addr;
  834. if (copy_from_user(&addr,buf,sizeof(addr))) {
  835. ret_val = -EFAULT;
  836. goto done;
  837. }
  838. if (cmd == ATM_ADDADDR)
  839. ret_val = atm_add_addr(dev,&addr);
  840. else
  841. ret_val = atm_del_addr(dev,&addr);
  842. goto done;
  843. }
  844. case ATM_GETADDR:
  845. size = atm_get_addr(dev,buf,len);
  846. if (size < 0)
  847. ret_val = size;
  848. else
  849. /* may return 0, but later on size == 0 means "don't
  850.    write the length" */
  851. ret_val = put_user(size,
  852.    &((struct atmif_sioc *) arg)->length) ? -EFAULT : 0;
  853. goto done;
  854. case ATM_SETLOOP:
  855. if (__ATM_LM_XTRMT((int) (long) buf) &&
  856.     __ATM_LM_XTLOC((int) (long) buf) >
  857.     __ATM_LM_XTRMT((int) (long) buf)) {
  858. ret_val = -EINVAL;
  859. goto done;
  860. }
  861. /* fall through */
  862. case ATM_SETCIRANGE:
  863. case SONET_GETSTATZ:
  864. case SONET_SETDIAG:
  865. case SONET_CLRDIAG:
  866. case SONET_SETFRAMING:
  867. if (!capable(CAP_NET_ADMIN)) {
  868. ret_val = -EPERM;
  869. goto done;
  870. }
  871. /* fall through */
  872. default:
  873. if (!dev->ops->ioctl) {
  874. ret_val = -EINVAL;
  875. goto done;
  876. }
  877. size = dev->ops->ioctl(dev,cmd,buf);
  878. if (size < 0) {
  879. ret_val = (size == -ENOIOCTLCMD ? -EINVAL : size);
  880. goto done;
  881. }
  882. }
  883. if (size)
  884. ret_val =  put_user(size,&((struct atmif_sioc *) arg)->length) ?
  885. -EFAULT : 0;
  886. else
  887. ret_val = 0;
  888.  done:
  889. spin_unlock (&atm_dev_lock); 
  890. return ret_val;
  891. }
  892. static int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
  893. {
  894. int error;
  895. /*
  896.  * Don't let the QoS change the already connected AAL type nor the
  897.  * traffic class.
  898.  */
  899. if (qos->aal != vcc->qos.aal ||
  900.     qos->rxtp.traffic_class != vcc->qos.rxtp.traffic_class ||
  901.     qos->txtp.traffic_class != vcc->qos.txtp.traffic_class)
  902. return -EINVAL;
  903. error = adjust_tp(&qos->txtp,qos->aal);
  904. if (!error) error = adjust_tp(&qos->rxtp,qos->aal);
  905. if (error) return error;
  906. if (!vcc->dev->ops->change_qos) return -EOPNOTSUPP;
  907. if (vcc->family == AF_ATMPVC)
  908. return vcc->dev->ops->change_qos(vcc,qos,ATM_MF_SET);
  909. return svc_change_qos(vcc,qos);
  910. }
  911. static int check_tp(struct atm_trafprm *tp)
  912. {
  913. /* @@@ Should be merged with adjust_tp */
  914. if (!tp->traffic_class || tp->traffic_class == ATM_ANYCLASS) return 0;
  915. if (tp->traffic_class != ATM_UBR && !tp->min_pcr && !tp->pcr &&
  916.     !tp->max_pcr) return -EINVAL;
  917. if (tp->min_pcr == ATM_MAX_PCR) return -EINVAL;
  918. if (tp->min_pcr && tp->max_pcr && tp->max_pcr != ATM_MAX_PCR &&
  919.     tp->min_pcr > tp->max_pcr) return -EINVAL;
  920. /*
  921.  * We allow pcr to be outside [min_pcr,max_pcr], because later
  922.  * adjustment may still push it in the valid range.
  923.  */
  924. return 0;
  925. }
  926. static int check_qos(struct atm_qos *qos)
  927. {
  928. int error;
  929. if (!qos->txtp.traffic_class && !qos->rxtp.traffic_class)
  930.                 return -EINVAL;
  931. if (qos->txtp.traffic_class != qos->rxtp.traffic_class &&
  932.     qos->txtp.traffic_class && qos->rxtp.traffic_class &&
  933.     qos->txtp.traffic_class != ATM_ANYCLASS &&
  934.     qos->rxtp.traffic_class != ATM_ANYCLASS) return -EINVAL;
  935. error = check_tp(&qos->txtp);
  936. if (error) return error;
  937. return check_tp(&qos->rxtp);
  938. }
  939. static int atm_do_setsockopt(struct socket *sock,int level,int optname,
  940.     void *optval,int optlen)
  941. {
  942. struct atm_vcc *vcc;
  943. unsigned long value;
  944. int error;
  945. vcc = ATM_SD(sock);
  946. switch (optname) {
  947. case SO_ATMQOS:
  948. {
  949. struct atm_qos qos;
  950. if (copy_from_user(&qos,optval,sizeof(qos)))
  951. return -EFAULT;
  952. error = check_qos(&qos);
  953. if (error) return error;
  954. if (sock->state == SS_CONNECTED)
  955. return atm_change_qos(vcc,&qos);
  956. if (sock->state != SS_UNCONNECTED)
  957. return -EBADFD;
  958. vcc->qos = qos;
  959. set_bit(ATM_VF_HASQOS,&vcc->flags);
  960. return 0;
  961. }
  962. case SO_SETCLP:
  963. if (get_user(value,(unsigned long *) optval))
  964. return -EFAULT;
  965. if (value) vcc->atm_options |= ATM_ATMOPT_CLP;
  966. else vcc->atm_options &= ~ATM_ATMOPT_CLP;
  967. return 0;
  968. default:
  969. if (level == SOL_SOCKET) return -EINVAL;
  970. break;
  971. }
  972. if (!vcc->dev || !vcc->dev->ops->setsockopt) return -EINVAL;
  973. return vcc->dev->ops->setsockopt(vcc,level,optname,optval,optlen);
  974. }
  975. static int atm_do_getsockopt(struct socket *sock,int level,int optname,
  976.     void *optval,int optlen)
  977. {
  978. struct atm_vcc *vcc;
  979. vcc = ATM_SD(sock);
  980. switch (optname) {
  981. case SO_ATMQOS:
  982. if (!test_bit(ATM_VF_HASQOS,&vcc->flags))
  983. return -EINVAL;
  984. return copy_to_user(optval,&vcc->qos,sizeof(vcc->qos)) ?
  985.     -EFAULT : 0;
  986. case SO_SETCLP:
  987. return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 :
  988.   0,(unsigned long *) optval) ? -EFAULT : 0;
  989. case SO_ATMPVC:
  990. {
  991. struct sockaddr_atmpvc pvc;
  992. if (!vcc->dev ||
  993.     !test_bit(ATM_VF_ADDR,&vcc->flags))
  994. return -ENOTCONN;
  995. pvc.sap_family = AF_ATMPVC;
  996. pvc.sap_addr.itf = vcc->dev->number;
  997. pvc.sap_addr.vpi = vcc->vpi;
  998. pvc.sap_addr.vci = vcc->vci;
  999. return copy_to_user(optval,&pvc,sizeof(pvc)) ?
  1000.     -EFAULT : 0;
  1001. }
  1002. default:
  1003. if (level == SOL_SOCKET) return -EINVAL;
  1004. break;
  1005. }
  1006. if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL;
  1007. return vcc->dev->ops->getsockopt(vcc,level,optname,optval,optlen);
  1008. }
  1009. int atm_setsockopt(struct socket *sock,int level,int optname,char *optval,
  1010.     int optlen)
  1011. {
  1012. if (__SO_LEVEL_MATCH(optname, level) && optlen != __SO_SIZE(optname))
  1013. return -EINVAL;
  1014. return atm_do_setsockopt(sock,level,optname,optval,optlen);
  1015. }
  1016. int atm_getsockopt(struct socket *sock,int level,int optname,
  1017.     char *optval,int *optlen)
  1018. {
  1019. int len;
  1020. if (get_user(len,optlen)) return -EFAULT;
  1021. if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
  1022. return -EINVAL;
  1023. return atm_do_getsockopt(sock,level,optname,optval,len);
  1024. }
  1025. /*
  1026.  * lane_mpoa_init.c: A couple of helper functions
  1027.  * to make modular LANE and MPOA client easier to implement
  1028.  */
  1029. /*
  1030.  * This is how it goes:
  1031.  *
  1032.  * if xxxx is not compiled as module, call atm_xxxx_init_ops()
  1033.  *    from here
  1034.  * else call atm_mpoa_init_ops() from init_module() within
  1035.  *    the kernel when xxxx module is loaded
  1036.  *
  1037.  * In either case function pointers in struct atm_xxxx_ops
  1038.  * are initialized to their correct values. Either they
  1039.  * point to functions in the module or in the kernel
  1040.  */
  1041.  
  1042. extern struct atm_mpoa_ops atm_mpoa_ops; /* in common.c */
  1043. extern struct atm_lane_ops atm_lane_ops; /* in common.c */
  1044. #if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
  1045. void atm_mpoa_init(void)
  1046. {
  1047. #ifndef CONFIG_ATM_MPOA_MODULE /* not module */
  1048.         atm_mpoa_init_ops(&atm_mpoa_ops);
  1049. #else
  1050. request_module("mpoa");
  1051. #endif
  1052.         return;
  1053. }
  1054. #endif
  1055. #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
  1056. #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
  1057. struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
  1058. unsigned char *addr) = NULL;
  1059. void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent) = NULL;
  1060. #if defined(CONFIG_ATM_LANE_MODULE) || defined(CONFIG_BRIDGE_MODULE)
  1061. EXPORT_SYMBOL(br_fdb_get_hook);
  1062. EXPORT_SYMBOL(br_fdb_put_hook);
  1063. #endif /* defined(CONFIG_ATM_LANE_MODULE) || defined(CONFIG_BRIDGE_MODULE) */
  1064. #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
  1065. void atm_lane_init(void)
  1066. {
  1067. #ifndef CONFIG_ATM_LANE_MODULE /* not module */
  1068.         atm_lane_init_ops(&atm_lane_ops);
  1069. #else
  1070. request_module("lec");
  1071. #endif
  1072.         return;
  1073. }        
  1074. #endif