x25_link.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * X.25 Packet Layer release 002
  4. *
  5. * This is ALPHA test software. This code may break your machine,
  6. * randomly fail to work with new releases, misbehave and/or generally
  7. * screw up. It might even work.
  8. *
  9. * This code REQUIRES 2.1.15 or higher
  10. *
  11. * History
  12. * X.25 001 Jonathan Naylor Started coding.
  13. * X.25 002 Jonathan Naylor New timer architecture.
  14. * mar/20/00 Daniela Squassoni Disabling/enabling of facilities
  15. * negotiation.
  16. * 2000-09-04 Henner Eisen dev_hold() / dev_put() for x25_neigh.
  17. */
  18. #define pr_fmt(fmt) "X25: " fmt
  19. #include <linux/kernel.h>
  20. #include <linux/jiffies.h>
  21. #include <linux/timer.h>
  22. #include <linux/slab.h>
  23. #include <linux/netdevice.h>
  24. #include <linux/skbuff.h>
  25. #include <linux/uaccess.h>
  26. #include <linux/init.h>
  27. #include <net/x25.h>
  28. LIST_HEAD(x25_neigh_list);
  29. DEFINE_RWLOCK(x25_neigh_list_lock);
  30. static void x25_t20timer_expiry(struct timer_list *);
  31. static void x25_transmit_restart_confirmation(struct x25_neigh *nb);
  32. static void x25_transmit_restart_request(struct x25_neigh *nb);
  33. /*
  34. * Linux set/reset timer routines
  35. */
  36. static inline void x25_start_t20timer(struct x25_neigh *nb)
  37. {
  38. mod_timer(&nb->t20timer, jiffies + nb->t20);
  39. }
  40. static void x25_t20timer_expiry(struct timer_list *t)
  41. {
  42. struct x25_neigh *nb = from_timer(nb, t, t20timer);
  43. x25_transmit_restart_request(nb);
  44. x25_start_t20timer(nb);
  45. }
  46. static inline void x25_stop_t20timer(struct x25_neigh *nb)
  47. {
  48. del_timer(&nb->t20timer);
  49. }
  50. /*
  51. * This handles all restart and diagnostic frames.
  52. */
  53. void x25_link_control(struct sk_buff *skb, struct x25_neigh *nb,
  54. unsigned short frametype)
  55. {
  56. struct sk_buff *skbn;
  57. switch (frametype) {
  58. case X25_RESTART_REQUEST:
  59. switch (nb->state) {
  60. case X25_LINK_STATE_0:
  61. /* This can happen when the x25 module just gets loaded
  62. * and doesn't know layer 2 has already connected
  63. */
  64. nb->state = X25_LINK_STATE_3;
  65. x25_transmit_restart_confirmation(nb);
  66. break;
  67. case X25_LINK_STATE_2:
  68. x25_stop_t20timer(nb);
  69. nb->state = X25_LINK_STATE_3;
  70. break;
  71. case X25_LINK_STATE_3:
  72. /* clear existing virtual calls */
  73. x25_kill_by_neigh(nb);
  74. x25_transmit_restart_confirmation(nb);
  75. break;
  76. }
  77. break;
  78. case X25_RESTART_CONFIRMATION:
  79. switch (nb->state) {
  80. case X25_LINK_STATE_2:
  81. x25_stop_t20timer(nb);
  82. nb->state = X25_LINK_STATE_3;
  83. break;
  84. case X25_LINK_STATE_3:
  85. /* clear existing virtual calls */
  86. x25_kill_by_neigh(nb);
  87. x25_transmit_restart_request(nb);
  88. nb->state = X25_LINK_STATE_2;
  89. x25_start_t20timer(nb);
  90. break;
  91. }
  92. break;
  93. case X25_DIAGNOSTIC:
  94. if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 4))
  95. break;
  96. pr_warn("diagnostic #%d - %02X %02X %02X\n",
  97. skb->data[3], skb->data[4],
  98. skb->data[5], skb->data[6]);
  99. break;
  100. default:
  101. pr_warn("received unknown %02X with LCI 000\n",
  102. frametype);
  103. break;
  104. }
  105. if (nb->state == X25_LINK_STATE_3)
  106. while ((skbn = skb_dequeue(&nb->queue)) != NULL)
  107. x25_send_frame(skbn, nb);
  108. }
  109. /*
  110. * This routine is called when a Restart Request is needed
  111. */
  112. static void x25_transmit_restart_request(struct x25_neigh *nb)
  113. {
  114. unsigned char *dptr;
  115. int len = X25_MAX_L2_LEN + X25_STD_MIN_LEN + 2;
  116. struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
  117. if (!skb)
  118. return;
  119. skb_reserve(skb, X25_MAX_L2_LEN);
  120. dptr = skb_put(skb, X25_STD_MIN_LEN + 2);
  121. *dptr++ = nb->extended ? X25_GFI_EXTSEQ : X25_GFI_STDSEQ;
  122. *dptr++ = 0x00;
  123. *dptr++ = X25_RESTART_REQUEST;
  124. *dptr++ = 0x00;
  125. *dptr++ = 0;
  126. skb->sk = NULL;
  127. x25_send_frame(skb, nb);
  128. }
  129. /*
  130. * This routine is called when a Restart Confirmation is needed
  131. */
  132. static void x25_transmit_restart_confirmation(struct x25_neigh *nb)
  133. {
  134. unsigned char *dptr;
  135. int len = X25_MAX_L2_LEN + X25_STD_MIN_LEN;
  136. struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
  137. if (!skb)
  138. return;
  139. skb_reserve(skb, X25_MAX_L2_LEN);
  140. dptr = skb_put(skb, X25_STD_MIN_LEN);
  141. *dptr++ = nb->extended ? X25_GFI_EXTSEQ : X25_GFI_STDSEQ;
  142. *dptr++ = 0x00;
  143. *dptr++ = X25_RESTART_CONFIRMATION;
  144. skb->sk = NULL;
  145. x25_send_frame(skb, nb);
  146. }
  147. /*
  148. * This routine is called when a Clear Request is needed outside of the context
  149. * of a connected socket.
  150. */
  151. void x25_transmit_clear_request(struct x25_neigh *nb, unsigned int lci,
  152. unsigned char cause)
  153. {
  154. unsigned char *dptr;
  155. int len = X25_MAX_L2_LEN + X25_STD_MIN_LEN + 2;
  156. struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
  157. if (!skb)
  158. return;
  159. skb_reserve(skb, X25_MAX_L2_LEN);
  160. dptr = skb_put(skb, X25_STD_MIN_LEN + 2);
  161. *dptr++ = ((lci >> 8) & 0x0F) | (nb->extended ?
  162. X25_GFI_EXTSEQ :
  163. X25_GFI_STDSEQ);
  164. *dptr++ = (lci >> 0) & 0xFF;
  165. *dptr++ = X25_CLEAR_REQUEST;
  166. *dptr++ = cause;
  167. *dptr++ = 0x00;
  168. skb->sk = NULL;
  169. x25_send_frame(skb, nb);
  170. }
  171. void x25_transmit_link(struct sk_buff *skb, struct x25_neigh *nb)
  172. {
  173. switch (nb->state) {
  174. case X25_LINK_STATE_0:
  175. skb_queue_tail(&nb->queue, skb);
  176. nb->state = X25_LINK_STATE_1;
  177. x25_establish_link(nb);
  178. break;
  179. case X25_LINK_STATE_1:
  180. case X25_LINK_STATE_2:
  181. skb_queue_tail(&nb->queue, skb);
  182. break;
  183. case X25_LINK_STATE_3:
  184. x25_send_frame(skb, nb);
  185. break;
  186. }
  187. }
  188. /*
  189. * Called when the link layer has become established.
  190. */
  191. void x25_link_established(struct x25_neigh *nb)
  192. {
  193. switch (nb->state) {
  194. case X25_LINK_STATE_0:
  195. case X25_LINK_STATE_1:
  196. x25_transmit_restart_request(nb);
  197. nb->state = X25_LINK_STATE_2;
  198. x25_start_t20timer(nb);
  199. break;
  200. }
  201. }
  202. /*
  203. * Called when the link layer has terminated, or an establishment
  204. * request has failed.
  205. */
  206. void x25_link_terminated(struct x25_neigh *nb)
  207. {
  208. nb->state = X25_LINK_STATE_0;
  209. skb_queue_purge(&nb->queue);
  210. x25_stop_t20timer(nb);
  211. /* Out of order: clear existing virtual calls (X.25 03/93 4.6.3) */
  212. x25_kill_by_neigh(nb);
  213. }
  214. /*
  215. * Add a new device.
  216. */
  217. void x25_link_device_up(struct net_device *dev)
  218. {
  219. struct x25_neigh *nb = kmalloc(sizeof(*nb), GFP_ATOMIC);
  220. if (!nb)
  221. return;
  222. skb_queue_head_init(&nb->queue);
  223. timer_setup(&nb->t20timer, x25_t20timer_expiry, 0);
  224. dev_hold(dev);
  225. nb->dev = dev;
  226. nb->state = X25_LINK_STATE_0;
  227. nb->extended = 0;
  228. /*
  229. * Enables negotiation
  230. */
  231. nb->global_facil_mask = X25_MASK_REVERSE |
  232. X25_MASK_THROUGHPUT |
  233. X25_MASK_PACKET_SIZE |
  234. X25_MASK_WINDOW_SIZE;
  235. nb->t20 = sysctl_x25_restart_request_timeout;
  236. refcount_set(&nb->refcnt, 1);
  237. write_lock_bh(&x25_neigh_list_lock);
  238. list_add(&nb->node, &x25_neigh_list);
  239. write_unlock_bh(&x25_neigh_list_lock);
  240. }
  241. /**
  242. * __x25_remove_neigh - remove neighbour from x25_neigh_list
  243. * @nb: - neigh to remove
  244. *
  245. * Remove neighbour from x25_neigh_list. If it was there.
  246. * Caller must hold x25_neigh_list_lock.
  247. */
  248. static void __x25_remove_neigh(struct x25_neigh *nb)
  249. {
  250. if (nb->node.next) {
  251. list_del(&nb->node);
  252. x25_neigh_put(nb);
  253. }
  254. }
  255. /*
  256. * A device has been removed, remove its links.
  257. */
  258. void x25_link_device_down(struct net_device *dev)
  259. {
  260. struct x25_neigh *nb;
  261. struct list_head *entry, *tmp;
  262. write_lock_bh(&x25_neigh_list_lock);
  263. list_for_each_safe(entry, tmp, &x25_neigh_list) {
  264. nb = list_entry(entry, struct x25_neigh, node);
  265. if (nb->dev == dev) {
  266. __x25_remove_neigh(nb);
  267. dev_put(dev);
  268. }
  269. }
  270. write_unlock_bh(&x25_neigh_list_lock);
  271. }
  272. /*
  273. * Given a device, return the neighbour address.
  274. */
  275. struct x25_neigh *x25_get_neigh(struct net_device *dev)
  276. {
  277. struct x25_neigh *nb, *use = NULL;
  278. read_lock_bh(&x25_neigh_list_lock);
  279. list_for_each_entry(nb, &x25_neigh_list, node) {
  280. if (nb->dev == dev) {
  281. use = nb;
  282. break;
  283. }
  284. }
  285. if (use)
  286. x25_neigh_hold(use);
  287. read_unlock_bh(&x25_neigh_list_lock);
  288. return use;
  289. }
  290. /*
  291. * Handle the ioctls that control the subscription functions.
  292. */
  293. int x25_subscr_ioctl(unsigned int cmd, void __user *arg)
  294. {
  295. struct x25_subscrip_struct x25_subscr;
  296. struct x25_neigh *nb;
  297. struct net_device *dev;
  298. int rc = -EINVAL;
  299. if (cmd != SIOCX25GSUBSCRIP && cmd != SIOCX25SSUBSCRIP)
  300. goto out;
  301. rc = -EFAULT;
  302. if (copy_from_user(&x25_subscr, arg, sizeof(x25_subscr)))
  303. goto out;
  304. rc = -EINVAL;
  305. if ((dev = x25_dev_get(x25_subscr.device)) == NULL)
  306. goto out;
  307. if ((nb = x25_get_neigh(dev)) == NULL)
  308. goto out_dev_put;
  309. dev_put(dev);
  310. if (cmd == SIOCX25GSUBSCRIP) {
  311. read_lock_bh(&x25_neigh_list_lock);
  312. x25_subscr.extended = nb->extended;
  313. x25_subscr.global_facil_mask = nb->global_facil_mask;
  314. read_unlock_bh(&x25_neigh_list_lock);
  315. rc = copy_to_user(arg, &x25_subscr,
  316. sizeof(x25_subscr)) ? -EFAULT : 0;
  317. } else {
  318. rc = -EINVAL;
  319. if (!(x25_subscr.extended && x25_subscr.extended != 1)) {
  320. rc = 0;
  321. write_lock_bh(&x25_neigh_list_lock);
  322. nb->extended = x25_subscr.extended;
  323. nb->global_facil_mask = x25_subscr.global_facil_mask;
  324. write_unlock_bh(&x25_neigh_list_lock);
  325. }
  326. }
  327. x25_neigh_put(nb);
  328. out:
  329. return rc;
  330. out_dev_put:
  331. dev_put(dev);
  332. goto out;
  333. }
  334. /*
  335. * Release all memory associated with X.25 neighbour structures.
  336. */
  337. void __exit x25_link_free(void)
  338. {
  339. struct x25_neigh *nb;
  340. struct list_head *entry, *tmp;
  341. write_lock_bh(&x25_neigh_list_lock);
  342. list_for_each_safe(entry, tmp, &x25_neigh_list) {
  343. struct net_device *dev;
  344. nb = list_entry(entry, struct x25_neigh, node);
  345. dev = nb->dev;
  346. __x25_remove_neigh(nb);
  347. dev_put(dev);
  348. }
  349. write_unlock_bh(&x25_neigh_list_lock);
  350. }