common.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:30k
源码类别:

嵌入式Linux

开发平台:

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