xref: /openbmc/linux/drivers/net/wan/lapbether.c (revision 71501859)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *	"LAPB via ethernet" driver release 001
4  *
5  *	This code REQUIRES 2.1.15 or higher/ NET3.038
6  *
7  *	This is a "pseudo" network driver to allow LAPB over Ethernet.
8  *
9  *	This driver can use any ethernet destination address, and can be
10  *	limited to accept frames from one dedicated ethernet card only.
11  *
12  *	History
13  *	LAPBETH 001	Jonathan Naylor		Cloned from bpqether.c
14  *	2000-10-29	Henner Eisen	lapb_data_indication() return status.
15  *	2000-11-14	Henner Eisen	dev_hold/put, NETDEV_GOING_DOWN support
16  */
17 
18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 
20 #include <linux/errno.h>
21 #include <linux/types.h>
22 #include <linux/socket.h>
23 #include <linux/in.h>
24 #include <linux/slab.h>
25 #include <linux/kernel.h>
26 #include <linux/string.h>
27 #include <linux/net.h>
28 #include <linux/inet.h>
29 #include <linux/netdevice.h>
30 #include <linux/if_arp.h>
31 #include <linux/skbuff.h>
32 #include <net/sock.h>
33 #include <linux/uaccess.h>
34 #include <linux/mm.h>
35 #include <linux/interrupt.h>
36 #include <linux/notifier.h>
37 #include <linux/stat.h>
38 #include <linux/module.h>
39 #include <linux/lapb.h>
40 #include <linux/init.h>
41 
42 #include <net/x25device.h>
43 
44 static const u8 bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
45 
46 /* If this number is made larger, check that the temporary string buffer
47  * in lapbeth_new_device is large enough to store the probe device name.*/
48 #define MAXLAPBDEV 100
49 
50 struct lapbethdev {
51 	struct list_head	node;
52 	struct net_device	*ethdev;	/* link to ethernet device */
53 	struct net_device	*axdev;		/* lapbeth device (lapb#) */
54 	bool			up;
55 	spinlock_t		up_lock;	/* Protects "up" */
56 	struct sk_buff_head	rx_queue;
57 	struct napi_struct	napi;
58 };
59 
60 static LIST_HEAD(lapbeth_devices);
61 
62 static void lapbeth_connected(struct net_device *dev, int reason);
63 static void lapbeth_disconnected(struct net_device *dev, int reason);
64 
65 /* ------------------------------------------------------------------------ */
66 
67 /*
68  *	Get the LAPB device for the ethernet device
69  */
70 static struct lapbethdev *lapbeth_get_x25_dev(struct net_device *dev)
71 {
72 	struct lapbethdev *lapbeth;
73 
74 	list_for_each_entry_rcu(lapbeth, &lapbeth_devices, node, lockdep_rtnl_is_held()) {
75 		if (lapbeth->ethdev == dev)
76 			return lapbeth;
77 	}
78 	return NULL;
79 }
80 
81 static __inline__ int dev_is_ethdev(struct net_device *dev)
82 {
83 	return dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5);
84 }
85 
86 /* ------------------------------------------------------------------------ */
87 
88 static int lapbeth_napi_poll(struct napi_struct *napi, int budget)
89 {
90 	struct lapbethdev *lapbeth = container_of(napi, struct lapbethdev,
91 						  napi);
92 	struct sk_buff *skb;
93 	int processed = 0;
94 
95 	for (; processed < budget; ++processed) {
96 		skb = skb_dequeue(&lapbeth->rx_queue);
97 		if (!skb)
98 			break;
99 		netif_receive_skb_core(skb);
100 	}
101 
102 	if (processed < budget)
103 		napi_complete(napi);
104 
105 	return processed;
106 }
107 
108 /*
109  *	Receive a LAPB frame via an ethernet interface.
110  */
111 static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev)
112 {
113 	int len, err;
114 	struct lapbethdev *lapbeth;
115 
116 	if (dev_net(dev) != &init_net)
117 		goto drop;
118 
119 	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
120 		return NET_RX_DROP;
121 
122 	if (!pskb_may_pull(skb, 2))
123 		goto drop;
124 
125 	rcu_read_lock();
126 	lapbeth = lapbeth_get_x25_dev(dev);
127 	if (!lapbeth)
128 		goto drop_unlock_rcu;
129 	spin_lock_bh(&lapbeth->up_lock);
130 	if (!lapbeth->up)
131 		goto drop_unlock;
132 
133 	len = skb->data[0] + skb->data[1] * 256;
134 	dev->stats.rx_packets++;
135 	dev->stats.rx_bytes += len;
136 
137 	skb_pull(skb, 2);	/* Remove the length bytes */
138 	skb_trim(skb, len);	/* Set the length of the data */
139 
140 	if ((err = lapb_data_received(lapbeth->axdev, skb)) != LAPB_OK) {
141 		printk(KERN_DEBUG "lapbether: lapb_data_received err - %d\n", err);
142 		goto drop_unlock;
143 	}
144 out:
145 	spin_unlock_bh(&lapbeth->up_lock);
146 	rcu_read_unlock();
147 	return 0;
148 drop_unlock:
149 	kfree_skb(skb);
150 	goto out;
151 drop_unlock_rcu:
152 	rcu_read_unlock();
153 drop:
154 	kfree_skb(skb);
155 	return 0;
156 }
157 
158 static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb)
159 {
160 	struct lapbethdev *lapbeth = netdev_priv(dev);
161 	unsigned char *ptr;
162 
163 	if (skb_cow(skb, 1)) {
164 		kfree_skb(skb);
165 		return NET_RX_DROP;
166 	}
167 
168 	skb_push(skb, 1);
169 
170 	ptr  = skb->data;
171 	*ptr = X25_IFACE_DATA;
172 
173 	skb->protocol = x25_type_trans(skb, dev);
174 
175 	skb_queue_tail(&lapbeth->rx_queue, skb);
176 	napi_schedule(&lapbeth->napi);
177 	return NET_RX_SUCCESS;
178 }
179 
180 /*
181  *	Send a LAPB frame via an ethernet interface
182  */
183 static netdev_tx_t lapbeth_xmit(struct sk_buff *skb,
184 				      struct net_device *dev)
185 {
186 	struct lapbethdev *lapbeth = netdev_priv(dev);
187 	int err;
188 
189 	spin_lock_bh(&lapbeth->up_lock);
190 	if (!lapbeth->up)
191 		goto drop;
192 
193 	/* There should be a pseudo header of 1 byte added by upper layers.
194 	 * Check to make sure it is there before reading it.
195 	 */
196 	if (skb->len < 1)
197 		goto drop;
198 
199 	switch (skb->data[0]) {
200 	case X25_IFACE_DATA:
201 		break;
202 	case X25_IFACE_CONNECT:
203 		err = lapb_connect_request(dev);
204 		if (err == LAPB_CONNECTED)
205 			lapbeth_connected(dev, LAPB_OK);
206 		else if (err != LAPB_OK)
207 			pr_err("lapb_connect_request error: %d\n", err);
208 		goto drop;
209 	case X25_IFACE_DISCONNECT:
210 		err = lapb_disconnect_request(dev);
211 		if (err == LAPB_NOTCONNECTED)
212 			lapbeth_disconnected(dev, LAPB_OK);
213 		else if (err != LAPB_OK)
214 			pr_err("lapb_disconnect_request err: %d\n", err);
215 		fallthrough;
216 	default:
217 		goto drop;
218 	}
219 
220 	skb_pull(skb, 1);
221 
222 	if ((err = lapb_data_request(dev, skb)) != LAPB_OK) {
223 		pr_err("lapb_data_request error - %d\n", err);
224 		goto drop;
225 	}
226 out:
227 	spin_unlock_bh(&lapbeth->up_lock);
228 	return NETDEV_TX_OK;
229 drop:
230 	kfree_skb(skb);
231 	goto out;
232 }
233 
234 static void lapbeth_data_transmit(struct net_device *ndev, struct sk_buff *skb)
235 {
236 	struct lapbethdev *lapbeth = netdev_priv(ndev);
237 	unsigned char *ptr;
238 	struct net_device *dev;
239 	int size = skb->len;
240 
241 	ptr = skb_push(skb, 2);
242 
243 	*ptr++ = size % 256;
244 	*ptr++ = size / 256;
245 
246 	ndev->stats.tx_packets++;
247 	ndev->stats.tx_bytes += size;
248 
249 	skb->dev = dev = lapbeth->ethdev;
250 
251 	skb->protocol = htons(ETH_P_DEC);
252 
253 	skb_reset_network_header(skb);
254 
255 	dev_hard_header(skb, dev, ETH_P_DEC, bcast_addr, NULL, 0);
256 
257 	dev_queue_xmit(skb);
258 }
259 
260 static void lapbeth_connected(struct net_device *dev, int reason)
261 {
262 	struct lapbethdev *lapbeth = netdev_priv(dev);
263 	unsigned char *ptr;
264 	struct sk_buff *skb = __dev_alloc_skb(1, GFP_ATOMIC | __GFP_NOMEMALLOC);
265 
266 	if (!skb) {
267 		pr_err("out of memory\n");
268 		return;
269 	}
270 
271 	ptr  = skb_put(skb, 1);
272 	*ptr = X25_IFACE_CONNECT;
273 
274 	skb->protocol = x25_type_trans(skb, dev);
275 
276 	skb_queue_tail(&lapbeth->rx_queue, skb);
277 	napi_schedule(&lapbeth->napi);
278 }
279 
280 static void lapbeth_disconnected(struct net_device *dev, int reason)
281 {
282 	struct lapbethdev *lapbeth = netdev_priv(dev);
283 	unsigned char *ptr;
284 	struct sk_buff *skb = __dev_alloc_skb(1, GFP_ATOMIC | __GFP_NOMEMALLOC);
285 
286 	if (!skb) {
287 		pr_err("out of memory\n");
288 		return;
289 	}
290 
291 	ptr  = skb_put(skb, 1);
292 	*ptr = X25_IFACE_DISCONNECT;
293 
294 	skb->protocol = x25_type_trans(skb, dev);
295 
296 	skb_queue_tail(&lapbeth->rx_queue, skb);
297 	napi_schedule(&lapbeth->napi);
298 }
299 
300 /*
301  *	Set AX.25 callsign
302  */
303 static int lapbeth_set_mac_address(struct net_device *dev, void *addr)
304 {
305 	struct sockaddr *sa = addr;
306 	memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
307 	return 0;
308 }
309 
310 
311 static const struct lapb_register_struct lapbeth_callbacks = {
312 	.connect_confirmation    = lapbeth_connected,
313 	.connect_indication      = lapbeth_connected,
314 	.disconnect_confirmation = lapbeth_disconnected,
315 	.disconnect_indication   = lapbeth_disconnected,
316 	.data_indication         = lapbeth_data_indication,
317 	.data_transmit           = lapbeth_data_transmit,
318 };
319 
320 /*
321  * open/close a device
322  */
323 static int lapbeth_open(struct net_device *dev)
324 {
325 	struct lapbethdev *lapbeth = netdev_priv(dev);
326 	int err;
327 
328 	napi_enable(&lapbeth->napi);
329 
330 	if ((err = lapb_register(dev, &lapbeth_callbacks)) != LAPB_OK) {
331 		pr_err("lapb_register error: %d\n", err);
332 		return -ENODEV;
333 	}
334 
335 	spin_lock_bh(&lapbeth->up_lock);
336 	lapbeth->up = true;
337 	spin_unlock_bh(&lapbeth->up_lock);
338 
339 	return 0;
340 }
341 
342 static int lapbeth_close(struct net_device *dev)
343 {
344 	struct lapbethdev *lapbeth = netdev_priv(dev);
345 	int err;
346 
347 	spin_lock_bh(&lapbeth->up_lock);
348 	lapbeth->up = false;
349 	spin_unlock_bh(&lapbeth->up_lock);
350 
351 	if ((err = lapb_unregister(dev)) != LAPB_OK)
352 		pr_err("lapb_unregister error: %d\n", err);
353 
354 	napi_disable(&lapbeth->napi);
355 
356 	return 0;
357 }
358 
359 /* ------------------------------------------------------------------------ */
360 
361 static const struct net_device_ops lapbeth_netdev_ops = {
362 	.ndo_open	     = lapbeth_open,
363 	.ndo_stop	     = lapbeth_close,
364 	.ndo_start_xmit	     = lapbeth_xmit,
365 	.ndo_set_mac_address = lapbeth_set_mac_address,
366 };
367 
368 static void lapbeth_setup(struct net_device *dev)
369 {
370 	dev->netdev_ops	     = &lapbeth_netdev_ops;
371 	dev->needs_free_netdev = true;
372 	dev->type            = ARPHRD_X25;
373 	dev->hard_header_len = 0;
374 	dev->mtu             = 1000;
375 	dev->addr_len        = 0;
376 }
377 
378 /*
379  *	Setup a new device.
380  */
381 static int lapbeth_new_device(struct net_device *dev)
382 {
383 	struct net_device *ndev;
384 	struct lapbethdev *lapbeth;
385 	int rc = -ENOMEM;
386 
387 	ASSERT_RTNL();
388 
389 	ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", NET_NAME_UNKNOWN,
390 			    lapbeth_setup);
391 	if (!ndev)
392 		goto out;
393 
394 	/* When transmitting data:
395 	 * first this driver removes a pseudo header of 1 byte,
396 	 * then the lapb module prepends an LAPB header of at most 3 bytes,
397 	 * then this driver prepends a length field of 2 bytes,
398 	 * then the underlying Ethernet device prepends its own header.
399 	 */
400 	ndev->needed_headroom = -1 + 3 + 2 + dev->hard_header_len
401 					   + dev->needed_headroom;
402 	ndev->needed_tailroom = dev->needed_tailroom;
403 
404 	lapbeth = netdev_priv(ndev);
405 	lapbeth->axdev = ndev;
406 
407 	dev_hold(dev);
408 	lapbeth->ethdev = dev;
409 
410 	lapbeth->up = false;
411 	spin_lock_init(&lapbeth->up_lock);
412 
413 	skb_queue_head_init(&lapbeth->rx_queue);
414 	netif_napi_add(ndev, &lapbeth->napi, lapbeth_napi_poll, 16);
415 
416 	rc = -EIO;
417 	if (register_netdevice(ndev))
418 		goto fail;
419 
420 	list_add_rcu(&lapbeth->node, &lapbeth_devices);
421 	rc = 0;
422 out:
423 	return rc;
424 fail:
425 	dev_put(dev);
426 	free_netdev(ndev);
427 	goto out;
428 }
429 
430 /*
431  *	Free a lapb network device.
432  */
433 static void lapbeth_free_device(struct lapbethdev *lapbeth)
434 {
435 	dev_put(lapbeth->ethdev);
436 	list_del_rcu(&lapbeth->node);
437 	unregister_netdevice(lapbeth->axdev);
438 }
439 
440 /*
441  *	Handle device status changes.
442  *
443  * Called from notifier with RTNL held.
444  */
445 static int lapbeth_device_event(struct notifier_block *this,
446 				unsigned long event, void *ptr)
447 {
448 	struct lapbethdev *lapbeth;
449 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
450 
451 	if (dev_net(dev) != &init_net)
452 		return NOTIFY_DONE;
453 
454 	if (!dev_is_ethdev(dev))
455 		return NOTIFY_DONE;
456 
457 	switch (event) {
458 	case NETDEV_UP:
459 		/* New ethernet device -> new LAPB interface	 */
460 		if (lapbeth_get_x25_dev(dev) == NULL)
461 			lapbeth_new_device(dev);
462 		break;
463 	case NETDEV_GOING_DOWN:
464 		/* ethernet device closes -> close LAPB interface */
465 		lapbeth = lapbeth_get_x25_dev(dev);
466 		if (lapbeth)
467 			dev_close(lapbeth->axdev);
468 		break;
469 	case NETDEV_UNREGISTER:
470 		/* ethernet device disappears -> remove LAPB interface */
471 		lapbeth = lapbeth_get_x25_dev(dev);
472 		if (lapbeth)
473 			lapbeth_free_device(lapbeth);
474 		break;
475 	}
476 
477 	return NOTIFY_DONE;
478 }
479 
480 /* ------------------------------------------------------------------------ */
481 
482 static struct packet_type lapbeth_packet_type __read_mostly = {
483 	.type = cpu_to_be16(ETH_P_DEC),
484 	.func = lapbeth_rcv,
485 };
486 
487 static struct notifier_block lapbeth_dev_notifier = {
488 	.notifier_call = lapbeth_device_event,
489 };
490 
491 static const char banner[] __initconst =
492 	KERN_INFO "LAPB Ethernet driver version 0.02\n";
493 
494 static int __init lapbeth_init_driver(void)
495 {
496 	dev_add_pack(&lapbeth_packet_type);
497 
498 	register_netdevice_notifier(&lapbeth_dev_notifier);
499 
500 	printk(banner);
501 
502 	return 0;
503 }
504 module_init(lapbeth_init_driver);
505 
506 static void __exit lapbeth_cleanup_driver(void)
507 {
508 	struct lapbethdev *lapbeth;
509 	struct list_head *entry, *tmp;
510 
511 	dev_remove_pack(&lapbeth_packet_type);
512 	unregister_netdevice_notifier(&lapbeth_dev_notifier);
513 
514 	rtnl_lock();
515 	list_for_each_safe(entry, tmp, &lapbeth_devices) {
516 		lapbeth = list_entry(entry, struct lapbethdev, node);
517 
518 		dev_put(lapbeth->ethdev);
519 		unregister_netdevice(lapbeth->axdev);
520 	}
521 	rtnl_unlock();
522 }
523 module_exit(lapbeth_cleanup_driver);
524 
525 MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
526 MODULE_DESCRIPTION("The unofficial LAPB over Ethernet driver");
527 MODULE_LICENSE("GPL");
528