net: lapbether: Prevent racing when checking whether the netif is running
[linux-2.6-microblaze.git] / drivers / net / wan / lapbether.c
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 };
57
58 static LIST_HEAD(lapbeth_devices);
59
60 static void lapbeth_connected(struct net_device *dev, int reason);
61 static void lapbeth_disconnected(struct net_device *dev, int reason);
62
63 /* ------------------------------------------------------------------------ */
64
65 /*
66  *      Get the LAPB device for the ethernet device
67  */
68 static struct lapbethdev *lapbeth_get_x25_dev(struct net_device *dev)
69 {
70         struct lapbethdev *lapbeth;
71
72         list_for_each_entry_rcu(lapbeth, &lapbeth_devices, node, lockdep_rtnl_is_held()) {
73                 if (lapbeth->ethdev == dev) 
74                         return lapbeth;
75         }
76         return NULL;
77 }
78
79 static __inline__ int dev_is_ethdev(struct net_device *dev)
80 {
81         return dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5);
82 }
83
84 /* ------------------------------------------------------------------------ */
85
86 /*
87  *      Receive a LAPB frame via an ethernet interface.
88  */
89 static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev)
90 {
91         int len, err;
92         struct lapbethdev *lapbeth;
93
94         if (dev_net(dev) != &init_net)
95                 goto drop;
96
97         if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
98                 return NET_RX_DROP;
99
100         if (!pskb_may_pull(skb, 2))
101                 goto drop;
102
103         rcu_read_lock();
104         lapbeth = lapbeth_get_x25_dev(dev);
105         if (!lapbeth)
106                 goto drop_unlock_rcu;
107         spin_lock_bh(&lapbeth->up_lock);
108         if (!lapbeth->up)
109                 goto drop_unlock;
110
111         len = skb->data[0] + skb->data[1] * 256;
112         dev->stats.rx_packets++;
113         dev->stats.rx_bytes += len;
114
115         skb_pull(skb, 2);       /* Remove the length bytes */
116         skb_trim(skb, len);     /* Set the length of the data */
117
118         if ((err = lapb_data_received(lapbeth->axdev, skb)) != LAPB_OK) {
119                 printk(KERN_DEBUG "lapbether: lapb_data_received err - %d\n", err);
120                 goto drop_unlock;
121         }
122 out:
123         spin_unlock_bh(&lapbeth->up_lock);
124         rcu_read_unlock();
125         return 0;
126 drop_unlock:
127         kfree_skb(skb);
128         goto out;
129 drop_unlock_rcu:
130         rcu_read_unlock();
131 drop:
132         kfree_skb(skb);
133         return 0;
134 }
135
136 static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb)
137 {
138         unsigned char *ptr;
139
140         if (skb_cow(skb, 1)) {
141                 kfree_skb(skb);
142                 return NET_RX_DROP;
143         }
144
145         skb_push(skb, 1);
146
147         ptr  = skb->data;
148         *ptr = X25_IFACE_DATA;
149
150         skb->protocol = x25_type_trans(skb, dev);
151         return netif_rx(skb);
152 }
153
154 /*
155  *      Send a LAPB frame via an ethernet interface
156  */
157 static netdev_tx_t lapbeth_xmit(struct sk_buff *skb,
158                                       struct net_device *dev)
159 {
160         struct lapbethdev *lapbeth = netdev_priv(dev);
161         int err;
162
163         spin_lock_bh(&lapbeth->up_lock);
164         if (!lapbeth->up)
165                 goto drop;
166
167         /* There should be a pseudo header of 1 byte added by upper layers.
168          * Check to make sure it is there before reading it.
169          */
170         if (skb->len < 1)
171                 goto drop;
172
173         switch (skb->data[0]) {
174         case X25_IFACE_DATA:
175                 break;
176         case X25_IFACE_CONNECT:
177                 err = lapb_connect_request(dev);
178                 if (err == LAPB_CONNECTED)
179                         lapbeth_connected(dev, LAPB_OK);
180                 else if (err != LAPB_OK)
181                         pr_err("lapb_connect_request error: %d\n", err);
182                 goto drop;
183         case X25_IFACE_DISCONNECT:
184                 err = lapb_disconnect_request(dev);
185                 if (err == LAPB_NOTCONNECTED)
186                         lapbeth_disconnected(dev, LAPB_OK);
187                 else if (err != LAPB_OK)
188                         pr_err("lapb_disconnect_request err: %d\n", err);
189                 fallthrough;
190         default:
191                 goto drop;
192         }
193
194         skb_pull(skb, 1);
195
196         if ((err = lapb_data_request(dev, skb)) != LAPB_OK) {
197                 pr_err("lapb_data_request error - %d\n", err);
198                 goto drop;
199         }
200 out:
201         spin_unlock_bh(&lapbeth->up_lock);
202         return NETDEV_TX_OK;
203 drop:
204         kfree_skb(skb);
205         goto out;
206 }
207
208 static void lapbeth_data_transmit(struct net_device *ndev, struct sk_buff *skb)
209 {
210         struct lapbethdev *lapbeth = netdev_priv(ndev);
211         unsigned char *ptr;
212         struct net_device *dev;
213         int size = skb->len;
214
215         ptr = skb_push(skb, 2);
216
217         *ptr++ = size % 256;
218         *ptr++ = size / 256;
219
220         ndev->stats.tx_packets++;
221         ndev->stats.tx_bytes += size;
222
223         skb->dev = dev = lapbeth->ethdev;
224
225         skb->protocol = htons(ETH_P_DEC);
226
227         skb_reset_network_header(skb);
228
229         dev_hard_header(skb, dev, ETH_P_DEC, bcast_addr, NULL, 0);
230
231         dev_queue_xmit(skb);
232 }
233
234 static void lapbeth_connected(struct net_device *dev, int reason)
235 {
236         unsigned char *ptr;
237         struct sk_buff *skb = dev_alloc_skb(1);
238
239         if (!skb) {
240                 pr_err("out of memory\n");
241                 return;
242         }
243
244         ptr  = skb_put(skb, 1);
245         *ptr = X25_IFACE_CONNECT;
246
247         skb->protocol = x25_type_trans(skb, dev);
248         netif_rx(skb);
249 }
250
251 static void lapbeth_disconnected(struct net_device *dev, int reason)
252 {
253         unsigned char *ptr;
254         struct sk_buff *skb = dev_alloc_skb(1);
255
256         if (!skb) {
257                 pr_err("out of memory\n");
258                 return;
259         }
260
261         ptr  = skb_put(skb, 1);
262         *ptr = X25_IFACE_DISCONNECT;
263
264         skb->protocol = x25_type_trans(skb, dev);
265         netif_rx(skb);
266 }
267
268 /*
269  *      Set AX.25 callsign
270  */
271 static int lapbeth_set_mac_address(struct net_device *dev, void *addr)
272 {
273         struct sockaddr *sa = addr;
274         memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
275         return 0;
276 }
277
278
279 static const struct lapb_register_struct lapbeth_callbacks = {
280         .connect_confirmation    = lapbeth_connected,
281         .connect_indication      = lapbeth_connected,
282         .disconnect_confirmation = lapbeth_disconnected,
283         .disconnect_indication   = lapbeth_disconnected,
284         .data_indication         = lapbeth_data_indication,
285         .data_transmit           = lapbeth_data_transmit,
286 };
287
288 /*
289  * open/close a device
290  */
291 static int lapbeth_open(struct net_device *dev)
292 {
293         struct lapbethdev *lapbeth = netdev_priv(dev);
294         int err;
295
296         if ((err = lapb_register(dev, &lapbeth_callbacks)) != LAPB_OK) {
297                 pr_err("lapb_register error: %d\n", err);
298                 return -ENODEV;
299         }
300
301         spin_lock_bh(&lapbeth->up_lock);
302         lapbeth->up = true;
303         spin_unlock_bh(&lapbeth->up_lock);
304
305         return 0;
306 }
307
308 static int lapbeth_close(struct net_device *dev)
309 {
310         struct lapbethdev *lapbeth = netdev_priv(dev);
311         int err;
312
313         spin_lock_bh(&lapbeth->up_lock);
314         lapbeth->up = false;
315         spin_unlock_bh(&lapbeth->up_lock);
316
317         if ((err = lapb_unregister(dev)) != LAPB_OK)
318                 pr_err("lapb_unregister error: %d\n", err);
319
320         return 0;
321 }
322
323 /* ------------------------------------------------------------------------ */
324
325 static const struct net_device_ops lapbeth_netdev_ops = {
326         .ndo_open            = lapbeth_open,
327         .ndo_stop            = lapbeth_close,
328         .ndo_start_xmit      = lapbeth_xmit,
329         .ndo_set_mac_address = lapbeth_set_mac_address,
330 };
331
332 static void lapbeth_setup(struct net_device *dev)
333 {
334         dev->netdev_ops      = &lapbeth_netdev_ops;
335         dev->needs_free_netdev = true;
336         dev->type            = ARPHRD_X25;
337         dev->hard_header_len = 0;
338         dev->mtu             = 1000;
339         dev->addr_len        = 0;
340 }
341
342 /*
343  *      Setup a new device.
344  */
345 static int lapbeth_new_device(struct net_device *dev)
346 {
347         struct net_device *ndev;
348         struct lapbethdev *lapbeth;
349         int rc = -ENOMEM;
350
351         ASSERT_RTNL();
352
353         ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", NET_NAME_UNKNOWN,
354                             lapbeth_setup);
355         if (!ndev)
356                 goto out;
357
358         /* When transmitting data:
359          * first this driver removes a pseudo header of 1 byte,
360          * then the lapb module prepends an LAPB header of at most 3 bytes,
361          * then this driver prepends a length field of 2 bytes,
362          * then the underlying Ethernet device prepends its own header.
363          */
364         ndev->needed_headroom = -1 + 3 + 2 + dev->hard_header_len
365                                            + dev->needed_headroom;
366         ndev->needed_tailroom = dev->needed_tailroom;
367
368         lapbeth = netdev_priv(ndev);
369         lapbeth->axdev = ndev;
370
371         dev_hold(dev);
372         lapbeth->ethdev = dev;
373
374         lapbeth->up = false;
375         spin_lock_init(&lapbeth->up_lock);
376
377         rc = -EIO;
378         if (register_netdevice(ndev))
379                 goto fail;
380
381         list_add_rcu(&lapbeth->node, &lapbeth_devices);
382         rc = 0;
383 out:
384         return rc;
385 fail:
386         dev_put(dev);
387         free_netdev(ndev);
388         goto out;
389 }
390
391 /*
392  *      Free a lapb network device.
393  */
394 static void lapbeth_free_device(struct lapbethdev *lapbeth)
395 {
396         dev_put(lapbeth->ethdev);
397         list_del_rcu(&lapbeth->node);
398         unregister_netdevice(lapbeth->axdev);
399 }
400
401 /*
402  *      Handle device status changes.
403  *
404  * Called from notifier with RTNL held.
405  */
406 static int lapbeth_device_event(struct notifier_block *this,
407                                 unsigned long event, void *ptr)
408 {
409         struct lapbethdev *lapbeth;
410         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
411
412         if (dev_net(dev) != &init_net)
413                 return NOTIFY_DONE;
414
415         if (!dev_is_ethdev(dev))
416                 return NOTIFY_DONE;
417
418         switch (event) {
419         case NETDEV_UP:
420                 /* New ethernet device -> new LAPB interface     */
421                 if (lapbeth_get_x25_dev(dev) == NULL)
422                         lapbeth_new_device(dev);
423                 break;
424         case NETDEV_DOWN:       
425                 /* ethernet device closed -> close LAPB interface */
426                 lapbeth = lapbeth_get_x25_dev(dev);
427                 if (lapbeth) 
428                         dev_close(lapbeth->axdev);
429                 break;
430         case NETDEV_UNREGISTER:
431                 /* ethernet device disappears -> remove LAPB interface */
432                 lapbeth = lapbeth_get_x25_dev(dev);
433                 if (lapbeth)
434                         lapbeth_free_device(lapbeth);
435                 break;
436         }
437
438         return NOTIFY_DONE;
439 }
440
441 /* ------------------------------------------------------------------------ */
442
443 static struct packet_type lapbeth_packet_type __read_mostly = {
444         .type = cpu_to_be16(ETH_P_DEC),
445         .func = lapbeth_rcv,
446 };
447
448 static struct notifier_block lapbeth_dev_notifier = {
449         .notifier_call = lapbeth_device_event,
450 };
451
452 static const char banner[] __initconst =
453         KERN_INFO "LAPB Ethernet driver version 0.02\n";
454
455 static int __init lapbeth_init_driver(void)
456 {
457         dev_add_pack(&lapbeth_packet_type);
458
459         register_netdevice_notifier(&lapbeth_dev_notifier);
460
461         printk(banner);
462
463         return 0;
464 }
465 module_init(lapbeth_init_driver);
466
467 static void __exit lapbeth_cleanup_driver(void)
468 {
469         struct lapbethdev *lapbeth;
470         struct list_head *entry, *tmp;
471
472         dev_remove_pack(&lapbeth_packet_type);
473         unregister_netdevice_notifier(&lapbeth_dev_notifier);
474
475         rtnl_lock();
476         list_for_each_safe(entry, tmp, &lapbeth_devices) {
477                 lapbeth = list_entry(entry, struct lapbethdev, node);
478
479                 dev_put(lapbeth->ethdev);
480                 unregister_netdevice(lapbeth->axdev);
481         }
482         rtnl_unlock();
483 }
484 module_exit(lapbeth_cleanup_driver);
485
486 MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
487 MODULE_DESCRIPTION("The unofficial LAPB over Ethernet driver");
488 MODULE_LICENSE("GPL");