blob: d53cbb4e25035f43ee57fbb671758d386e7ad9b2 [file] [log] [blame]
Thomas Gleixner2874c5f2019-05-27 08:55:01 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
4 * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
5 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
6 * Copyright (C) Darryl Miles G7LED (dlm@g7led.demon.co.uk)
7 * Copyright (C) Steven Whitehouse GW7RRM (stevew@acm.org)
8 * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
9 * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
10 * Copyright (C) Hans Alblas PE1AYX (hans@esrac.ele.tue.nl)
11 * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
12 */
Randy Dunlap4fc268d2006-01-11 12:17:47 -080013#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#include <linux/module.h>
15#include <linux/errno.h>
16#include <linux/types.h>
17#include <linux/socket.h>
18#include <linux/in.h>
19#include <linux/kernel.h>
Ingo Molnar3f07c012017-02-08 18:51:30 +010020#include <linux/sched/signal.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/timer.h>
22#include <linux/string.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <linux/sockios.h>
24#include <linux/net.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090025#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <net/ax25.h>
27#include <linux/inet.h>
28#include <linux/netdevice.h>
29#include <linux/if_arp.h>
30#include <linux/skbuff.h>
31#include <net/sock.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080032#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/fcntl.h>
34#include <linux/termios.h> /* For TIOCINQ/OUTQ */
35#include <linux/mm.h>
36#include <linux/interrupt.h>
37#include <linux/notifier.h>
38#include <linux/proc_fs.h>
39#include <linux/stat.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <linux/sysctl.h>
41#include <linux/init.h>
42#include <linux/spinlock.h>
Eric W. Biederman457c4cb2007-09-12 12:01:34 +020043#include <net/net_namespace.h>
Arnaldo Carvalho de Meloc752f072005-08-09 20:08:28 -070044#include <net/tcp_states.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <net/ip.h>
46#include <net/arp.h>
47
48
49
50HLIST_HEAD(ax25_list);
51DEFINE_SPINLOCK(ax25_list_lock);
52
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080053static const struct proto_ops ax25_proto_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55static void ax25_free_sock(struct sock *sk)
56{
David Miller32003922015-06-25 06:19:07 -070057 ax25_cb_put(sk_to_ax25(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -070058}
59
60/*
61 * Socket removal during an interrupt is now safe.
62 */
63static void ax25_cb_del(ax25_cb *ax25)
64{
65 if (!hlist_unhashed(&ax25->ax25_node)) {
66 spin_lock_bh(&ax25_list_lock);
67 hlist_del_init(&ax25->ax25_node);
68 spin_unlock_bh(&ax25_list_lock);
69 ax25_cb_put(ax25);
70 }
71}
72
73/*
74 * Kill all bound sockets on a dropped device.
75 */
76static void ax25_kill_by_device(struct net_device *dev)
77{
78 ax25_dev *ax25_dev;
79 ax25_cb *s;
Duoming Zhou4e0f7182022-01-28 12:47:15 +080080 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
82 if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
83 return;
84
85 spin_lock_bh(&ax25_list_lock);
Jarek Poplawskiecd2ebd2008-01-10 21:21:20 -080086again:
Sasha Levinb67bfe02013-02-27 17:06:00 -080087 ax25_for_each(s, &ax25_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 if (s->ax25_dev == ax25_dev) {
Duoming Zhou4e0f7182022-01-28 12:47:15 +080089 sk = s->sk;
90 sock_hold(sk);
Jarek Poplawskiecd2ebd2008-01-10 21:21:20 -080091 spin_unlock_bh(&ax25_list_lock);
Duoming Zhou4e0f7182022-01-28 12:47:15 +080092 lock_sock(sk);
Lin Ma1ade48d2021-12-17 10:29:41 +080093 s->ax25_dev = NULL;
Duoming Zhoufeef3182022-02-09 20:53:45 +080094 dev_put_track(ax25_dev->dev, &ax25_dev->dev_tracker);
Duoming Zhoud01ffb92022-01-28 12:47:16 +080095 ax25_dev_put(ax25_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 ax25_disconnect(s, ENETUNREACH);
Duoming Zhou7ec02f52022-02-08 23:40:00 +080097 release_sock(sk);
Jarek Poplawskiecd2ebd2008-01-10 21:21:20 -080098 spin_lock_bh(&ax25_list_lock);
Duoming Zhou4e0f7182022-01-28 12:47:15 +080099 sock_put(sk);
Jarek Poplawskiecd2ebd2008-01-10 21:21:20 -0800100 /* The entry could have been deleted from the
101 * list meanwhile and thus the next pointer is
102 * no longer valid. Play it safe and restart
103 * the scan. Forward progress is ensured
104 * because we set s->ax25_dev to NULL and we
105 * are never passed a NULL 'dev' argument.
106 */
107 goto again;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 }
109 }
110 spin_unlock_bh(&ax25_list_lock);
111}
112
113/*
114 * Handle device status changes.
115 */
116static int ax25_device_event(struct notifier_block *this, unsigned long event,
Jiri Pirko351638e2013-05-28 01:30:21 +0000117 void *ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118{
Jiri Pirko351638e2013-05-28 01:30:21 +0000119 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120
YOSHIFUJI Hideaki721499e2008-07-19 22:34:43 -0700121 if (!net_eq(dev_net(dev), &init_net))
Eric W. Biedermane9dc8652007-09-12 13:02:17 +0200122 return NOTIFY_DONE;
123
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 /* Reject non AX.25 devices */
125 if (dev->type != ARPHRD_AX25)
126 return NOTIFY_DONE;
127
128 switch (event) {
129 case NETDEV_UP:
130 ax25_dev_device_up(dev);
131 break;
132 case NETDEV_DOWN:
133 ax25_kill_by_device(dev);
134 ax25_rt_device_down(dev);
135 ax25_dev_device_down(dev);
136 break;
137 default:
138 break;
139 }
140
141 return NOTIFY_DONE;
142}
143
144/*
145 * Add a socket to the bound sockets list.
146 */
147void ax25_cb_add(ax25_cb *ax25)
148{
149 spin_lock_bh(&ax25_list_lock);
150 ax25_cb_hold(ax25);
151 hlist_add_head(&ax25->ax25_node, &ax25_list);
152 spin_unlock_bh(&ax25_list_lock);
153}
154
155/*
156 * Find a socket that wants to accept the SABM we have just
157 * received.
158 */
159struct sock *ax25_find_listener(ax25_address *addr, int digi,
160 struct net_device *dev, int type)
161{
162 ax25_cb *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163
Ralf Baechlec19c4b92006-07-12 13:25:23 -0700164 spin_lock(&ax25_list_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800165 ax25_for_each(s, &ax25_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 if ((s->iamdigi && !digi) || (!s->iamdigi && digi))
167 continue;
168 if (s->sk && !ax25cmp(&s->source_addr, addr) &&
169 s->sk->sk_type == type && s->sk->sk_state == TCP_LISTEN) {
170 /* If device is null we match any device */
171 if (s->ax25_dev == NULL || s->ax25_dev->dev == dev) {
172 sock_hold(s->sk);
Ralf Baechlec19c4b92006-07-12 13:25:23 -0700173 spin_unlock(&ax25_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 return s->sk;
175 }
176 }
177 }
Ralf Baechlec19c4b92006-07-12 13:25:23 -0700178 spin_unlock(&ax25_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179
180 return NULL;
181}
182
183/*
184 * Find an AX.25 socket given both ends.
185 */
186struct sock *ax25_get_socket(ax25_address *my_addr, ax25_address *dest_addr,
187 int type)
188{
189 struct sock *sk = NULL;
190 ax25_cb *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
Ralf Baechlec19c4b92006-07-12 13:25:23 -0700192 spin_lock(&ax25_list_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800193 ax25_for_each(s, &ax25_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 if (s->sk && !ax25cmp(&s->source_addr, my_addr) &&
195 !ax25cmp(&s->dest_addr, dest_addr) &&
196 s->sk->sk_type == type) {
197 sk = s->sk;
198 sock_hold(sk);
199 break;
200 }
201 }
202
Ralf Baechlec19c4b92006-07-12 13:25:23 -0700203 spin_unlock(&ax25_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205 return sk;
206}
207
208/*
209 * Find an AX.25 control block given both ends. It will only pick up
210 * floating AX.25 control blocks or non Raw socket bound control blocks.
211 */
Jakub Kicinskic045ad22021-10-12 08:58:35 -0700212ax25_cb *ax25_find_cb(const ax25_address *src_addr, ax25_address *dest_addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 ax25_digi *digi, struct net_device *dev)
214{
215 ax25_cb *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
217 spin_lock_bh(&ax25_list_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800218 ax25_for_each(s, &ax25_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 if (s->sk && s->sk->sk_type != SOCK_SEQPACKET)
220 continue;
221 if (s->ax25_dev == NULL)
222 continue;
223 if (ax25cmp(&s->source_addr, src_addr) == 0 && ax25cmp(&s->dest_addr, dest_addr) == 0 && s->ax25_dev->dev == dev) {
224 if (digi != NULL && digi->ndigi != 0) {
225 if (s->digipeat == NULL)
226 continue;
227 if (ax25digicmp(s->digipeat, digi) != 0)
228 continue;
229 } else {
230 if (s->digipeat != NULL && s->digipeat->ndigi != 0)
231 continue;
232 }
233 ax25_cb_hold(s);
234 spin_unlock_bh(&ax25_list_lock);
235
236 return s;
237 }
238 }
239 spin_unlock_bh(&ax25_list_lock);
240
241 return NULL;
242}
243
Ralf Baechle70868ea2006-05-03 23:25:17 -0700244EXPORT_SYMBOL(ax25_find_cb);
245
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246void ax25_send_to_raw(ax25_address *addr, struct sk_buff *skb, int proto)
247{
248 ax25_cb *s;
249 struct sk_buff *copy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250
Ralf Baechlec19c4b92006-07-12 13:25:23 -0700251 spin_lock(&ax25_list_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800252 ax25_for_each(s, &ax25_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 if (s->sk != NULL && ax25cmp(&s->source_addr, addr) == 0 &&
254 s->sk->sk_type == SOCK_RAW &&
255 s->sk->sk_protocol == proto &&
256 s->ax25_dev->dev == skb->dev &&
257 atomic_read(&s->sk->sk_rmem_alloc) <= s->sk->sk_rcvbuf) {
258 if ((copy = skb_clone(skb, GFP_ATOMIC)) == NULL)
259 continue;
260 if (sock_queue_rcv_skb(s->sk, copy) != 0)
261 kfree_skb(copy);
262 }
263 }
Ralf Baechlec19c4b92006-07-12 13:25:23 -0700264 spin_unlock(&ax25_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265}
266
267/*
268 * Deferred destroy.
269 */
270void ax25_destroy_socket(ax25_cb *);
271
272/*
273 * Handler for deferred kills.
274 */
Kees Cook8dbd05f2017-10-24 01:45:39 -0700275static void ax25_destroy_timer(struct timer_list *t)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276{
Kees Cook8dbd05f2017-10-24 01:45:39 -0700277 ax25_cb *ax25 = from_timer(ax25, t, dtimer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 struct sock *sk;
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900279
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 sk=ax25->sk;
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900281
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 bh_lock_sock(sk);
283 sock_hold(sk);
284 ax25_destroy_socket(ax25);
285 bh_unlock_sock(sk);
286 sock_put(sk);
287}
288
289/*
290 * This is called from user mode and the timers. Thus it protects itself
291 * against interrupt users but doesn't worry about being called during
292 * work. Once it is removed from the queue no interrupt or bottom half
293 * will touch it and we are (fairly 8-) ) safe.
294 */
295void ax25_destroy_socket(ax25_cb *ax25)
296{
297 struct sk_buff *skb;
298
299 ax25_cb_del(ax25);
300
301 ax25_stop_heartbeat(ax25);
302 ax25_stop_t1timer(ax25);
303 ax25_stop_t2timer(ax25);
304 ax25_stop_t3timer(ax25);
305 ax25_stop_idletimer(ax25);
306
307 ax25_clear_queues(ax25); /* Flush the queues */
308
309 if (ax25->sk != NULL) {
310 while ((skb = skb_dequeue(&ax25->sk->sk_receive_queue)) != NULL) {
311 if (skb->sk != ax25->sk) {
312 /* A pending connection */
David Miller32003922015-06-25 06:19:07 -0700313 ax25_cb *sax25 = sk_to_ax25(skb->sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314
315 /* Queue the unaccepted socket for death */
316 sock_orphan(skb->sk);
317
David S. Miller33d1d2c2008-10-06 12:53:50 -0700318 /* 9A4GL: hack to release unaccepted sockets */
319 skb->sk->sk_state = TCP_LISTEN;
320
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 ax25_start_heartbeat(sax25);
322 sax25->state = AX25_STATE_0;
323 }
324
325 kfree_skb(skb);
326 }
327 skb_queue_purge(&ax25->sk->sk_write_queue);
328 }
329
330 if (ax25->sk != NULL) {
Eric Dumazetc5640392009-06-16 10:12:03 +0000331 if (sk_has_allocations(ax25->sk)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 /* Defer: outstanding buffers */
Kees Cook8dbd05f2017-10-24 01:45:39 -0700333 timer_setup(&ax25->dtimer, ax25_destroy_timer, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 ax25->dtimer.expires = jiffies + 2 * HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 add_timer(&ax25->dtimer);
336 } else {
337 struct sock *sk=ax25->sk;
338 ax25->sk=NULL;
339 sock_put(sk);
340 }
341 } else {
342 ax25_cb_put(ax25);
343 }
344}
345
346/*
347 * dl1bke 960311: set parameters for existing AX.25 connections,
348 * includes a KILL command to abort any connection.
349 * VERY useful for debugging ;-)
350 */
351static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
352{
353 struct ax25_ctl_struct ax25_ctl;
354 ax25_digi digi;
355 ax25_dev *ax25_dev;
356 ax25_cb *ax25;
357 unsigned int k;
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000358 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
360 if (copy_from_user(&ax25_ctl, arg, sizeof(ax25_ctl)))
361 return -EFAULT;
362
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 if (ax25_ctl.digi_count > AX25_MAX_DIGIS)
364 return -EINVAL;
365
roel kluin43ab8502009-10-14 05:26:30 +0000366 if (ax25_ctl.arg > ULONG_MAX / HZ && ax25_ctl.cmd != AX25_KILL)
367 return -EINVAL;
368
Duoming Zhou87563a02022-02-03 23:08:11 +0800369 ax25_dev = ax25_addr_ax25dev(&ax25_ctl.port_addr);
370 if (!ax25_dev)
371 return -ENODEV;
372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 digi.ndigi = ax25_ctl.digi_count;
374 for (k = 0; k < digi.ndigi; k++)
375 digi.calls[k] = ax25_ctl.digi_addr[k];
376
Duoming Zhou87563a02022-02-03 23:08:11 +0800377 ax25 = ax25_find_cb(&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev);
378 if (!ax25) {
379 ax25_dev_put(ax25_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 return -ENOTCONN;
Duoming Zhou87563a02022-02-03 23:08:11 +0800381 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
383 switch (ax25_ctl.cmd) {
384 case AX25_KILL:
385 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
386#ifdef CONFIG_AX25_DAMA_SLAVE
387 if (ax25_dev->dama.slave && ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_DAMA_SLAVE)
388 ax25_dama_off(ax25);
389#endif
390 ax25_disconnect(ax25, ENETRESET);
391 break;
392
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900393 case AX25_WINDOW:
394 if (ax25->modulus == AX25_MODULUS) {
395 if (ax25_ctl.arg < 1 || ax25_ctl.arg > 7)
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000396 goto einval_put;
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900397 } else {
398 if (ax25_ctl.arg < 1 || ax25_ctl.arg > 63)
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000399 goto einval_put;
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900400 }
401 ax25->window = ax25_ctl.arg;
402 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900404 case AX25_T1:
Ralf Baechlebe639ac2011-11-24 06:12:59 +0000405 if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000406 goto einval_put;
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900407 ax25->rtt = (ax25_ctl.arg * HZ) / 2;
408 ax25->t1 = ax25_ctl.arg * HZ;
409 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900411 case AX25_T2:
Ralf Baechlebe639ac2011-11-24 06:12:59 +0000412 if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000413 goto einval_put;
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900414 ax25->t2 = ax25_ctl.arg * HZ;
415 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900417 case AX25_N2:
418 if (ax25_ctl.arg < 1 || ax25_ctl.arg > 31)
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000419 goto einval_put;
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900420 ax25->n2count = 0;
421 ax25->n2 = ax25_ctl.arg;
422 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900424 case AX25_T3:
Ralf Baechlebe639ac2011-11-24 06:12:59 +0000425 if (ax25_ctl.arg > ULONG_MAX / HZ)
426 goto einval_put;
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900427 ax25->t3 = ax25_ctl.arg * HZ;
428 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900430 case AX25_IDLE:
Ralf Baechlebe639ac2011-11-24 06:12:59 +0000431 if (ax25_ctl.arg > ULONG_MAX / (60 * HZ))
432 goto einval_put;
433
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900434 ax25->idle = ax25_ctl.arg * 60 * HZ;
435 break;
436
437 case AX25_PACLEN:
438 if (ax25_ctl.arg < 16 || ax25_ctl.arg > 65535)
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000439 goto einval_put;
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +0900440 ax25->paclen = ax25_ctl.arg;
441 break;
442
443 default:
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000444 goto einval_put;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 }
446
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000447out_put:
Duoming Zhoud01ffb92022-01-28 12:47:16 +0800448 ax25_dev_put(ax25_dev);
Jarek Poplawskic0181d42009-09-25 03:10:38 +0000449 ax25_cb_put(ax25);
450 return ret;
451
452einval_put:
453 ret = -EINVAL;
454 goto out_put;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455}
456
Ralf Baechlee1fdb5b2006-05-03 23:27:16 -0700457static void ax25_fillin_cb_from_dev(ax25_cb *ax25, ax25_dev *ax25_dev)
458{
459 ax25->rtt = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]) / 2;
460 ax25->t1 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]);
461 ax25->t2 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T2]);
462 ax25->t3 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T3]);
463 ax25->n2 = ax25_dev->values[AX25_VALUES_N2];
464 ax25->paclen = ax25_dev->values[AX25_VALUES_PACLEN];
465 ax25->idle = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_IDLE]);
466 ax25->backoff = ax25_dev->values[AX25_VALUES_BACKOFF];
467
468 if (ax25_dev->values[AX25_VALUES_AXDEFMODE]) {
469 ax25->modulus = AX25_EMODULUS;
470 ax25->window = ax25_dev->values[AX25_VALUES_EWINDOW];
471 } else {
472 ax25->modulus = AX25_MODULUS;
473 ax25->window = ax25_dev->values[AX25_VALUES_WINDOW];
474 }
475}
476
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477/*
478 * Fill in a created AX.25 created control block with the default
479 * values for a particular device.
480 */
481void ax25_fillin_cb(ax25_cb *ax25, ax25_dev *ax25_dev)
482{
483 ax25->ax25_dev = ax25_dev;
484
485 if (ax25->ax25_dev != NULL) {
Ralf Baechlee1fdb5b2006-05-03 23:27:16 -0700486 ax25_fillin_cb_from_dev(ax25, ax25_dev);
487 return;
488 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489
Ralf Baechlee1fdb5b2006-05-03 23:27:16 -0700490 /*
491 * No device, use kernel / AX.25 spec default values
492 */
493 ax25->rtt = msecs_to_jiffies(AX25_DEF_T1) / 2;
494 ax25->t1 = msecs_to_jiffies(AX25_DEF_T1);
495 ax25->t2 = msecs_to_jiffies(AX25_DEF_T2);
496 ax25->t3 = msecs_to_jiffies(AX25_DEF_T3);
497 ax25->n2 = AX25_DEF_N2;
498 ax25->paclen = AX25_DEF_PACLEN;
499 ax25->idle = msecs_to_jiffies(AX25_DEF_IDLE);
500 ax25->backoff = AX25_DEF_BACKOFF;
501
502 if (AX25_DEF_AXDEFMODE) {
503 ax25->modulus = AX25_EMODULUS;
504 ax25->window = AX25_DEF_EWINDOW;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 } else {
Ralf Baechlee1fdb5b2006-05-03 23:27:16 -0700506 ax25->modulus = AX25_MODULUS;
507 ax25->window = AX25_DEF_WINDOW;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 }
509}
510
511/*
512 * Create an empty AX.25 control block.
513 */
514ax25_cb *ax25_create_cb(void)
515{
516 ax25_cb *ax25;
517
Ralf Baechle1b30dd32006-07-09 12:14:22 -0700518 if ((ax25 = kzalloc(sizeof(*ax25), GFP_ATOMIC)) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 return NULL;
520
Reshetova, Elenab6d52ed2017-07-04 15:53:31 +0300521 refcount_set(&ax25->refcount, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
523 skb_queue_head_init(&ax25->write_queue);
524 skb_queue_head_init(&ax25->frag_queue);
525 skb_queue_head_init(&ax25->ack_queue);
526 skb_queue_head_init(&ax25->reseq_queue);
527
Jarek Poplawski21fab4a2008-02-11 21:36:39 -0800528 ax25_setup_timers(ax25);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
530 ax25_fillin_cb(ax25, NULL);
531
532 ax25->state = AX25_STATE_0;
533
534 return ax25;
535}
536
537/*
538 * Handling for system calls applied via the various interfaces to an
539 * AX25 socket object
540 */
541
542static int ax25_setsockopt(struct socket *sock, int level, int optname,
Christoph Hellwiga7b75c52020-07-23 08:09:07 +0200543 sockptr_t optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544{
545 struct sock *sk = sock->sk;
546 ax25_cb *ax25;
547 struct net_device *dev;
548 char devname[IFNAMSIZ];
Dan Carpenter93719372022-01-07 10:13:12 +0300549 unsigned int opt;
Xi Wangba1cffe2011-12-27 09:43:19 +0000550 int res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551
552 if (level != SOL_AX25)
553 return -ENOPROTOOPT;
554
Xi Wangba1cffe2011-12-27 09:43:19 +0000555 if (optlen < sizeof(unsigned int))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 return -EINVAL;
557
Christoph Hellwiga7b75c52020-07-23 08:09:07 +0200558 if (copy_from_sockptr(&opt, optval, sizeof(unsigned int)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 return -EFAULT;
560
561 lock_sock(sk);
David Miller32003922015-06-25 06:19:07 -0700562 ax25 = sk_to_ax25(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563
564 switch (optname) {
565 case AX25_WINDOW:
566 if (ax25->modulus == AX25_MODULUS) {
567 if (opt < 1 || opt > 7) {
568 res = -EINVAL;
569 break;
570 }
571 } else {
572 if (opt < 1 || opt > 63) {
573 res = -EINVAL;
574 break;
575 }
576 }
577 ax25->window = opt;
578 break;
579
580 case AX25_T1:
Dan Carpenter93719372022-01-07 10:13:12 +0300581 if (opt < 1 || opt > UINT_MAX / HZ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 res = -EINVAL;
583 break;
584 }
Eric Dumazetf16f3022008-01-13 22:29:41 -0800585 ax25->rtt = (opt * HZ) >> 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 ax25->t1 = opt * HZ;
587 break;
588
589 case AX25_T2:
Dan Carpenter93719372022-01-07 10:13:12 +0300590 if (opt < 1 || opt > UINT_MAX / HZ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 res = -EINVAL;
592 break;
593 }
594 ax25->t2 = opt * HZ;
595 break;
596
597 case AX25_N2:
598 if (opt < 1 || opt > 31) {
599 res = -EINVAL;
600 break;
601 }
602 ax25->n2 = opt;
603 break;
604
605 case AX25_T3:
Dan Carpenter93719372022-01-07 10:13:12 +0300606 if (opt < 1 || opt > UINT_MAX / HZ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 res = -EINVAL;
608 break;
609 }
610 ax25->t3 = opt * HZ;
611 break;
612
613 case AX25_IDLE:
Dan Carpenter93719372022-01-07 10:13:12 +0300614 if (opt > UINT_MAX / (60 * HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 res = -EINVAL;
616 break;
617 }
618 ax25->idle = opt * 60 * HZ;
619 break;
620
621 case AX25_BACKOFF:
Xi Wangba1cffe2011-12-27 09:43:19 +0000622 if (opt > 2) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 res = -EINVAL;
624 break;
625 }
626 ax25->backoff = opt;
627 break;
628
629 case AX25_EXTSEQ:
630 ax25->modulus = opt ? AX25_EMODULUS : AX25_MODULUS;
631 break;
632
633 case AX25_PIDINCL:
634 ax25->pidincl = opt ? 1 : 0;
635 break;
636
637 case AX25_IAMDIGI:
638 ax25->iamdigi = opt ? 1 : 0;
639 break;
640
641 case AX25_PACLEN:
642 if (opt < 16 || opt > 65535) {
643 res = -EINVAL;
644 break;
645 }
646 ax25->paclen = opt;
647 break;
648
649 case SO_BINDTODEVICE:
Eric Dumazet687775c2020-05-19 18:24:43 -0700650 if (optlen > IFNAMSIZ - 1)
651 optlen = IFNAMSIZ - 1;
652
653 memset(devname, 0, sizeof(devname));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654
Christoph Hellwiga7b75c52020-07-23 08:09:07 +0200655 if (copy_from_sockptr(devname, optval, optlen)) {
Ralf Baechle2f722912009-09-28 12:26:28 -0700656 res = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 break;
658 }
659
660 if (sk->sk_type == SOCK_SEQPACKET &&
661 (sock->state != SS_UNCONNECTED ||
662 sk->sk_state == TCP_LISTEN)) {
663 res = -EADDRNOTAVAIL;
Ralf Baechle2f722912009-09-28 12:26:28 -0700664 break;
665 }
666
Cong Wangc4335702018-12-29 13:56:36 -0800667 rtnl_lock();
668 dev = __dev_get_by_name(&init_net, devname);
Ralf Baechle2f722912009-09-28 12:26:28 -0700669 if (!dev) {
Cong Wangc4335702018-12-29 13:56:36 -0800670 rtnl_unlock();
Ralf Baechle2f722912009-09-28 12:26:28 -0700671 res = -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 break;
673 }
674
675 ax25->ax25_dev = ax25_dev_ax25dev(dev);
Cong Wangc4335702018-12-29 13:56:36 -0800676 if (!ax25->ax25_dev) {
677 rtnl_unlock();
678 res = -ENODEV;
679 break;
680 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 ax25_fillin_cb(ax25, ax25->ax25_dev);
Cong Wangc4335702018-12-29 13:56:36 -0800682 rtnl_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 break;
684
685 default:
686 res = -ENOPROTOOPT;
687 }
688 release_sock(sk);
689
690 return res;
691}
692
693static int ax25_getsockopt(struct socket *sock, int level, int optname,
694 char __user *optval, int __user *optlen)
695{
696 struct sock *sk = sock->sk;
697 ax25_cb *ax25;
698 struct ax25_dev *ax25_dev;
699 char devname[IFNAMSIZ];
700 void *valptr;
701 int val = 0;
702 int maxlen, length;
703
704 if (level != SOL_AX25)
705 return -ENOPROTOOPT;
706
707 if (get_user(maxlen, optlen))
708 return -EFAULT;
709
710 if (maxlen < 1)
711 return -EFAULT;
712
713 valptr = (void *) &val;
714 length = min_t(unsigned int, maxlen, sizeof(int));
715
716 lock_sock(sk);
David Miller32003922015-06-25 06:19:07 -0700717 ax25 = sk_to_ax25(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718
719 switch (optname) {
720 case AX25_WINDOW:
721 val = ax25->window;
722 break;
723
724 case AX25_T1:
725 val = ax25->t1 / HZ;
726 break;
727
728 case AX25_T2:
729 val = ax25->t2 / HZ;
730 break;
731
732 case AX25_N2:
733 val = ax25->n2;
734 break;
735
736 case AX25_T3:
737 val = ax25->t3 / HZ;
738 break;
739
740 case AX25_IDLE:
741 val = ax25->idle / (60 * HZ);
742 break;
743
744 case AX25_BACKOFF:
745 val = ax25->backoff;
746 break;
747
748 case AX25_EXTSEQ:
749 val = (ax25->modulus == AX25_EMODULUS);
750 break;
751
752 case AX25_PIDINCL:
753 val = ax25->pidincl;
754 break;
755
756 case AX25_IAMDIGI:
757 val = ax25->iamdigi;
758 break;
759
760 case AX25_PACLEN:
761 val = ax25->paclen;
762 break;
763
764 case SO_BINDTODEVICE:
765 ax25_dev = ax25->ax25_dev;
766
767 if (ax25_dev != NULL && ax25_dev->dev != NULL) {
768 strlcpy(devname, ax25_dev->dev->name, sizeof(devname));
769 length = strlen(devname) + 1;
770 } else {
771 *devname = '\0';
772 length = 1;
773 }
774
775 valptr = (void *) devname;
776 break;
777
778 default:
779 release_sock(sk);
780 return -ENOPROTOOPT;
781 }
782 release_sock(sk);
783
784 if (put_user(length, optlen))
785 return -EFAULT;
786
787 return copy_to_user(optval, valptr, length) ? -EFAULT : 0;
788}
789
790static int ax25_listen(struct socket *sock, int backlog)
791{
792 struct sock *sk = sock->sk;
793 int res = 0;
794
795 lock_sock(sk);
796 if (sk->sk_type == SOCK_SEQPACKET && sk->sk_state != TCP_LISTEN) {
797 sk->sk_max_ack_backlog = backlog;
798 sk->sk_state = TCP_LISTEN;
799 goto out;
800 }
801 res = -EOPNOTSUPP;
802
803out:
804 release_sock(sk);
805
806 return res;
807}
808
809/*
810 * XXX: when creating ax25_sock we should update the .obj_size setting
811 * below.
812 */
813static struct proto ax25_proto = {
814 .name = "AX25",
815 .owner = THIS_MODULE,
David Miller32003922015-06-25 06:19:07 -0700816 .obj_size = sizeof(struct ax25_sock),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817};
818
Eric Paris3f378b62009-11-05 22:18:14 -0800819static int ax25_create(struct net *net, struct socket *sock, int protocol,
820 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821{
822 struct sock *sk;
823 ax25_cb *ax25;
824
Mat Martineaue9cdced2020-01-09 07:59:14 -0800825 if (protocol < 0 || protocol > U8_MAX)
Hannes Frederic Sowa79462ad02015-12-14 22:03:39 +0100826 return -EINVAL;
827
Octavian Purdila09ad9bc2009-11-25 15:14:13 -0800828 if (!net_eq(net, &init_net))
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700829 return -EAFNOSUPPORT;
830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 switch (sock->type) {
832 case SOCK_DGRAM:
833 if (protocol == 0 || protocol == PF_AX25)
834 protocol = AX25_P_TEXT;
835 break;
836
837 case SOCK_SEQPACKET:
838 switch (protocol) {
839 case 0:
840 case PF_AX25: /* For CLX */
841 protocol = AX25_P_TEXT;
842 break;
843 case AX25_P_SEGMENT:
844#ifdef CONFIG_INET
845 case AX25_P_ARP:
846 case AX25_P_IP:
847#endif
848#ifdef CONFIG_NETROM
849 case AX25_P_NETROM:
850#endif
851#ifdef CONFIG_ROSE
852 case AX25_P_ROSE:
853#endif
854 return -ESOCKTNOSUPPORT;
855#ifdef CONFIG_NETROM_MODULE
856 case AX25_P_NETROM:
857 if (ax25_protocol_is_registered(AX25_P_NETROM))
858 return -ESOCKTNOSUPPORT;
Alan Coxef764a12012-07-13 06:33:08 +0000859 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860#endif
861#ifdef CONFIG_ROSE_MODULE
862 case AX25_P_ROSE:
863 if (ax25_protocol_is_registered(AX25_P_ROSE))
864 return -ESOCKTNOSUPPORT;
Gustavo A. R. Silva5646fba2021-03-09 23:39:41 -0600865 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866#endif
867 default:
868 break;
869 }
870 break;
871
872 case SOCK_RAW:
Ori Nimron0614e2b2019-09-20 09:35:47 +0200873 if (!capable(CAP_NET_RAW))
874 return -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 break;
876 default:
877 return -ESOCKTNOSUPPORT;
878 }
879
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500880 sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto, kern);
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700881 if (sk == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 return -ENOMEM;
883
David Miller32003922015-06-25 06:19:07 -0700884 ax25 = ax25_sk(sk)->cb = ax25_create_cb();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 if (!ax25) {
886 sk_free(sk);
887 return -ENOMEM;
888 }
889
890 sock_init_data(sock, sk);
891
892 sk->sk_destruct = ax25_free_sock;
893 sock->ops = &ax25_proto_ops;
894 sk->sk_protocol = protocol;
895
896 ax25->sk = sk;
897
898 return 0;
899}
900
901struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
902{
903 struct sock *sk;
904 ax25_cb *ax25, *oax25;
905
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500906 sk = sk_alloc(sock_net(osk), PF_AX25, GFP_ATOMIC, osk->sk_prot, 0);
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700907 if (sk == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 return NULL;
909
910 if ((ax25 = ax25_create_cb()) == NULL) {
911 sk_free(sk);
912 return NULL;
913 }
914
915 switch (osk->sk_type) {
916 case SOCK_DGRAM:
917 break;
918 case SOCK_SEQPACKET:
919 break;
920 default:
921 sk_free(sk);
922 ax25_cb_put(ax25);
923 return NULL;
924 }
925
926 sock_init_data(NULL, sk);
927
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 sk->sk_type = osk->sk_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 sk->sk_priority = osk->sk_priority;
930 sk->sk_protocol = osk->sk_protocol;
931 sk->sk_rcvbuf = osk->sk_rcvbuf;
932 sk->sk_sndbuf = osk->sk_sndbuf;
933 sk->sk_state = TCP_ESTABLISHED;
Ralf Baechle53b924b2005-08-23 10:11:30 -0700934 sock_copy_flags(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935
David Miller32003922015-06-25 06:19:07 -0700936 oax25 = sk_to_ax25(osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937
938 ax25->modulus = oax25->modulus;
939 ax25->backoff = oax25->backoff;
940 ax25->pidincl = oax25->pidincl;
941 ax25->iamdigi = oax25->iamdigi;
942 ax25->rtt = oax25->rtt;
943 ax25->t1 = oax25->t1;
944 ax25->t2 = oax25->t2;
945 ax25->t3 = oax25->t3;
946 ax25->n2 = oax25->n2;
947 ax25->idle = oax25->idle;
948 ax25->paclen = oax25->paclen;
949 ax25->window = oax25->window;
950
951 ax25->ax25_dev = ax25_dev;
952 ax25->source_addr = oax25->source_addr;
953
954 if (oax25->digipeat != NULL) {
Arnaldo Carvalho de Melo0459d70a2006-11-17 12:43:07 -0200955 ax25->digipeat = kmemdup(oax25->digipeat, sizeof(ax25_digi),
956 GFP_ATOMIC);
957 if (ax25->digipeat == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 sk_free(sk);
959 ax25_cb_put(ax25);
960 return NULL;
961 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 }
963
David Miller32003922015-06-25 06:19:07 -0700964 ax25_sk(sk)->cb = ax25;
Jarek Poplawski8c185ab2009-09-27 10:57:02 +0000965 sk->sk_destruct = ax25_free_sock;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 ax25->sk = sk;
967
968 return sk;
969}
970
971static int ax25_release(struct socket *sock)
972{
973 struct sock *sk = sock->sk;
974 ax25_cb *ax25;
975
976 if (sk == NULL)
977 return 0;
978
979 sock_hold(sk);
980 sock_orphan(sk);
981 lock_sock(sk);
David Miller32003922015-06-25 06:19:07 -0700982 ax25 = sk_to_ax25(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
984 if (sk->sk_type == SOCK_SEQPACKET) {
985 switch (ax25->state) {
986 case AX25_STATE_0:
987 release_sock(sk);
988 ax25_disconnect(ax25, 0);
989 lock_sock(sk);
990 ax25_destroy_socket(ax25);
991 break;
992
993 case AX25_STATE_1:
994 case AX25_STATE_2:
995 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
996 release_sock(sk);
997 ax25_disconnect(ax25, 0);
998 lock_sock(sk);
Basil Gunn4a7d99e2016-06-16 09:42:30 -0700999 if (!sock_flag(ax25->sk, SOCK_DESTROY))
1000 ax25_destroy_socket(ax25);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 break;
1002
1003 case AX25_STATE_3:
1004 case AX25_STATE_4:
1005 ax25_clear_queues(ax25);
1006 ax25->n2count = 0;
1007
1008 switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
1009 case AX25_PROTO_STD_SIMPLEX:
1010 case AX25_PROTO_STD_DUPLEX:
1011 ax25_send_control(ax25,
1012 AX25_DISC,
1013 AX25_POLLON,
1014 AX25_COMMAND);
1015 ax25_stop_t2timer(ax25);
1016 ax25_stop_t3timer(ax25);
1017 ax25_stop_idletimer(ax25);
1018 break;
1019#ifdef CONFIG_AX25_DAMA_SLAVE
1020 case AX25_PROTO_DAMA_SLAVE:
1021 ax25_stop_t3timer(ax25);
1022 ax25_stop_idletimer(ax25);
1023 break;
1024#endif
1025 }
1026 ax25_calculate_t1(ax25);
1027 ax25_start_t1timer(ax25);
1028 ax25->state = AX25_STATE_2;
1029 sk->sk_state = TCP_CLOSE;
1030 sk->sk_shutdown |= SEND_SHUTDOWN;
1031 sk->sk_state_change(sk);
1032 sock_set_flag(sk, SOCK_DESTROY);
1033 break;
1034
1035 default:
1036 break;
1037 }
1038 } else {
1039 sk->sk_state = TCP_CLOSE;
1040 sk->sk_shutdown |= SEND_SHUTDOWN;
1041 sk->sk_state_change(sk);
1042 ax25_destroy_socket(ax25);
1043 }
1044
1045 sock->sk = NULL;
1046 release_sock(sk);
1047 sock_put(sk);
1048
1049 return 0;
1050}
1051
1052/*
1053 * We support a funny extension here so you can (as root) give any callsign
1054 * digipeated via a local address as source. This hack is obsolete now
1055 * that we've implemented support for SO_BINDTODEVICE. It is however small
1056 * and trivially backward compatible.
1057 */
1058static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1059{
1060 struct sock *sk = sock->sk;
1061 struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr;
1062 ax25_dev *ax25_dev = NULL;
Ralf Baechle01d7dd02005-08-23 10:11:45 -07001063 ax25_uid_assoc *user;
1064 ax25_address call;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 ax25_cb *ax25;
1066 int err = 0;
1067
1068 if (addr_len != sizeof(struct sockaddr_ax25) &&
maximilian attems1987e7b2008-01-28 20:44:11 -08001069 addr_len != sizeof(struct full_sockaddr_ax25))
1070 /* support for old structure may go away some time
1071 * ax25_bind(): uses old (6 digipeater) socket structure.
1072 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
maximilian attems1987e7b2008-01-28 20:44:11 -08001074 (addr_len > sizeof(struct full_sockaddr_ax25)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
1077 if (addr->fsa_ax25.sax25_family != AF_AX25)
1078 return -EINVAL;
1079
David Howells73400402008-11-14 10:39:06 +11001080 user = ax25_findbyuid(current_euid());
Ralf Baechle01d7dd02005-08-23 10:11:45 -07001081 if (user) {
1082 call = user->call;
1083 ax25_uid_put(user);
1084 } else {
1085 if (ax25_uid_policy && !capable(CAP_NET_ADMIN))
1086 return -EACCES;
1087
1088 call = addr->fsa_ax25.sax25_call;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 }
1090
1091 lock_sock(sk);
1092
David Miller32003922015-06-25 06:19:07 -07001093 ax25 = sk_to_ax25(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 if (!sock_flag(sk, SOCK_ZAPPED)) {
1095 err = -EINVAL;
1096 goto out;
1097 }
1098
Ralf Baechle01d7dd02005-08-23 10:11:45 -07001099 ax25->source_addr = call;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
1101 /*
1102 * User already set interface with SO_BINDTODEVICE
1103 */
1104 if (ax25->ax25_dev != NULL)
1105 goto done;
1106
1107 if (addr_len > sizeof(struct sockaddr_ax25) && addr->fsa_ax25.sax25_ndigis == 1) {
1108 if (ax25cmp(&addr->fsa_digipeater[0], &null_ax25_address) != 0 &&
1109 (ax25_dev = ax25_addr_ax25dev(&addr->fsa_digipeater[0])) == NULL) {
1110 err = -EADDRNOTAVAIL;
1111 goto out;
1112 }
1113 } else {
1114 if ((ax25_dev = ax25_addr_ax25dev(&addr->fsa_ax25.sax25_call)) == NULL) {
1115 err = -EADDRNOTAVAIL;
1116 goto out;
1117 }
1118 }
1119
Duoming Zhoufeef3182022-02-09 20:53:45 +08001120 if (ax25_dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 ax25_fillin_cb(ax25, ax25_dev);
Duoming Zhoufeef3182022-02-09 20:53:45 +08001122 dev_hold_track(ax25_dev->dev, &ax25_dev->dev_tracker, GFP_ATOMIC);
1123 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124
1125done:
1126 ax25_cb_add(ax25);
1127 sock_reset_flag(sk, SOCK_ZAPPED);
1128
1129out:
1130 release_sock(sk);
1131
Julia Lawall49339cc2010-08-16 06:28:19 +00001132 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133}
1134
1135/*
1136 * FIXME: nonblock behaviour looks like it may have a bug.
1137 */
Ralf Baechlec9266b92006-12-14 15:49:28 -08001138static int __must_check ax25_connect(struct socket *sock,
1139 struct sockaddr *uaddr, int addr_len, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140{
1141 struct sock *sk = sock->sk;
David Miller32003922015-06-25 06:19:07 -07001142 ax25_cb *ax25 = sk_to_ax25(sk), *ax25t;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr;
1144 ax25_digi *digi = NULL;
1145 int ct = 0, err = 0;
1146
1147 /*
1148 * some sanity checks. code further down depends on this
1149 */
1150
maximilian attems27d1cba2008-01-10 03:57:29 -08001151 if (addr_len == sizeof(struct sockaddr_ax25))
1152 /* support for this will go away in early 2.5.x
1153 * ax25_connect(): uses obsolete socket structure
1154 */
1155 ;
1156 else if (addr_len != sizeof(struct full_sockaddr_ax25))
1157 /* support for old structure may go away some time
1158 * ax25_connect(): uses old (6 digipeater) socket structure.
1159 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
maximilian attems27d1cba2008-01-10 03:57:29 -08001161 (addr_len > sizeof(struct full_sockaddr_ax25)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164
1165 if (fsa->fsa_ax25.sax25_family != AF_AX25)
1166 return -EINVAL;
1167
1168 lock_sock(sk);
1169
1170 /* deal with restarts */
1171 if (sock->state == SS_CONNECTING) {
1172 switch (sk->sk_state) {
1173 case TCP_SYN_SENT: /* still trying */
1174 err = -EINPROGRESS;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001175 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176
1177 case TCP_ESTABLISHED: /* connection established */
1178 sock->state = SS_CONNECTED;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001179 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180
1181 case TCP_CLOSE: /* connection refused */
1182 sock->state = SS_UNCONNECTED;
1183 err = -ECONNREFUSED;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001184 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185 }
1186 }
1187
1188 if (sk->sk_state == TCP_ESTABLISHED && sk->sk_type == SOCK_SEQPACKET) {
1189 err = -EISCONN; /* No reconnect on a seqpacket socket */
Ralf Baechle75606dc2007-04-20 16:06:45 -07001190 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 }
1192
1193 sk->sk_state = TCP_CLOSE;
1194 sock->state = SS_UNCONNECTED;
1195
Jesper Juhla51482b2005-11-08 09:41:34 -08001196 kfree(ax25->digipeat);
1197 ax25->digipeat = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
1199 /*
1200 * Handle digi-peaters to be used.
1201 */
1202 if (addr_len > sizeof(struct sockaddr_ax25) &&
1203 fsa->fsa_ax25.sax25_ndigis != 0) {
1204 /* Valid number of digipeaters ? */
Peilin Ye2f2a7ff2020-07-22 11:19:01 -04001205 if (fsa->fsa_ax25.sax25_ndigis < 1 ||
Dan Carpenter17ad73e2020-07-23 17:49:57 +03001206 fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS ||
Peilin Ye2f2a7ff2020-07-22 11:19:01 -04001207 addr_len < sizeof(struct sockaddr_ax25) +
1208 sizeof(ax25_address) * fsa->fsa_ax25.sax25_ndigis) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 err = -EINVAL;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001210 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 }
1212
1213 if ((digi = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) {
1214 err = -ENOBUFS;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001215 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 }
1217
1218 digi->ndigi = fsa->fsa_ax25.sax25_ndigis;
1219 digi->lastrepeat = -1;
1220
1221 while (ct < fsa->fsa_ax25.sax25_ndigis) {
1222 if ((fsa->fsa_digipeater[ct].ax25_call[6] &
1223 AX25_HBIT) && ax25->iamdigi) {
1224 digi->repeated[ct] = 1;
1225 digi->lastrepeat = ct;
1226 } else {
1227 digi->repeated[ct] = 0;
1228 }
1229 digi->calls[ct] = fsa->fsa_digipeater[ct];
1230 ct++;
1231 }
1232 }
1233
1234 /*
1235 * Must bind first - autobinding in this may or may not work. If
1236 * the socket is already bound, check to see if the device has
1237 * been filled in, error if it hasn't.
1238 */
1239 if (sock_flag(sk, SOCK_ZAPPED)) {
1240 /* check if we can remove this feature. It is broken. */
1241 printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@yaina.de\n",
1242 current->comm);
1243 if ((err = ax25_rt_autobind(ax25, &fsa->fsa_ax25.sax25_call)) < 0) {
1244 kfree(digi);
Ralf Baechle75606dc2007-04-20 16:06:45 -07001245 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246 }
1247
1248 ax25_fillin_cb(ax25, ax25->ax25_dev);
1249 ax25_cb_add(ax25);
1250 } else {
1251 if (ax25->ax25_dev == NULL) {
1252 kfree(digi);
1253 err = -EHOSTUNREACH;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001254 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 }
1256 }
1257
1258 if (sk->sk_type == SOCK_SEQPACKET &&
1259 (ax25t=ax25_find_cb(&ax25->source_addr, &fsa->fsa_ax25.sax25_call, digi,
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +09001260 ax25->ax25_dev->dev))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 kfree(digi);
1262 err = -EADDRINUSE; /* Already such a connection */
1263 ax25_cb_put(ax25t);
Ralf Baechle75606dc2007-04-20 16:06:45 -07001264 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265 }
1266
1267 ax25->dest_addr = fsa->fsa_ax25.sax25_call;
1268 ax25->digipeat = digi;
1269
1270 /* First the easy one */
1271 if (sk->sk_type != SOCK_SEQPACKET) {
1272 sock->state = SS_CONNECTED;
1273 sk->sk_state = TCP_ESTABLISHED;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001274 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 }
1276
1277 /* Move to connecting socket, ax.25 lapb WAIT_UA.. */
1278 sock->state = SS_CONNECTING;
1279 sk->sk_state = TCP_SYN_SENT;
1280
1281 switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
1282 case AX25_PROTO_STD_SIMPLEX:
1283 case AX25_PROTO_STD_DUPLEX:
1284 ax25_std_establish_data_link(ax25);
1285 break;
1286
1287#ifdef CONFIG_AX25_DAMA_SLAVE
1288 case AX25_PROTO_DAMA_SLAVE:
1289 ax25->modulus = AX25_MODULUS;
1290 ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
1291 if (ax25->ax25_dev->dama.slave)
1292 ax25_ds_establish_data_link(ax25);
1293 else
1294 ax25_std_establish_data_link(ax25);
1295 break;
1296#endif
1297 }
1298
1299 ax25->state = AX25_STATE_1;
1300
1301 ax25_start_heartbeat(ax25);
1302
1303 /* Now the loop */
1304 if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) {
1305 err = -EINPROGRESS;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001306 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 }
1308
1309 if (sk->sk_state == TCP_SYN_SENT) {
Ralf Baechle75606dc2007-04-20 16:06:45 -07001310 DEFINE_WAIT(wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00001313 prepare_to_wait(sk_sleep(sk), &wait,
YOSHIFUJI Hideakibd3b0712007-07-19 10:43:13 +09001314 TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 if (sk->sk_state != TCP_SYN_SENT)
1316 break;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001317 if (!signal_pending(current)) {
1318 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319 schedule();
1320 lock_sock(sk);
1321 continue;
1322 }
Ralf Baechle75606dc2007-04-20 16:06:45 -07001323 err = -ERESTARTSYS;
1324 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 }
Eric Dumazetaa395142010-04-20 13:03:51 +00001326 finish_wait(sk_sleep(sk), &wait);
Ralf Baechle75606dc2007-04-20 16:06:45 -07001327
1328 if (err)
1329 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 }
1331
1332 if (sk->sk_state != TCP_ESTABLISHED) {
1333 /* Not in ABM, not in WAIT_UA -> failed */
1334 sock->state = SS_UNCONNECTED;
1335 err = sock_error(sk); /* Always set at this point */
Ralf Baechle75606dc2007-04-20 16:06:45 -07001336 goto out_release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 }
1338
1339 sock->state = SS_CONNECTED;
1340
Ralf Baechle75606dc2007-04-20 16:06:45 -07001341 err = 0;
1342out_release:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 release_sock(sk);
1344
1345 return err;
1346}
1347
David Howellscdfbabf2017-03-09 08:09:05 +00001348static int ax25_accept(struct socket *sock, struct socket *newsock, int flags,
1349 bool kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 struct sk_buff *skb;
1352 struct sock *newsk;
Ralf Baechle75606dc2007-04-20 16:06:45 -07001353 DEFINE_WAIT(wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 struct sock *sk;
1355 int err = 0;
1356
1357 if (sock->state != SS_UNCONNECTED)
1358 return -EINVAL;
1359
1360 if ((sk = sock->sk) == NULL)
1361 return -EINVAL;
1362
1363 lock_sock(sk);
1364 if (sk->sk_type != SOCK_SEQPACKET) {
1365 err = -EOPNOTSUPP;
1366 goto out;
1367 }
1368
1369 if (sk->sk_state != TCP_LISTEN) {
1370 err = -EINVAL;
1371 goto out;
1372 }
1373
1374 /*
1375 * The read queue this time is holding sockets ready to use
1376 * hooked into the SABM we saved
1377 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00001379 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 skb = skb_dequeue(&sk->sk_receive_queue);
1381 if (skb)
1382 break;
1383
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 if (flags & O_NONBLOCK) {
Ralf Baechle75606dc2007-04-20 16:06:45 -07001385 err = -EWOULDBLOCK;
1386 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 }
Ralf Baechle75606dc2007-04-20 16:06:45 -07001388 if (!signal_pending(current)) {
1389 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 schedule();
1391 lock_sock(sk);
1392 continue;
1393 }
Ralf Baechle75606dc2007-04-20 16:06:45 -07001394 err = -ERESTARTSYS;
1395 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 }
Eric Dumazetaa395142010-04-20 13:03:51 +00001397 finish_wait(sk_sleep(sk), &wait);
Ralf Baechle75606dc2007-04-20 16:06:45 -07001398
1399 if (err)
1400 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401
1402 newsk = skb->sk;
David S. Miller9375cb82008-06-17 02:20:54 -07001403 sock_graft(newsk, newsock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405 /* Now attach up the new socket */
1406 kfree_skb(skb);
Eric Dumazet7976a112019-11-05 14:11:52 -08001407 sk_acceptq_removed(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 newsock->state = SS_CONNECTED;
1409
1410out:
1411 release_sock(sk);
1412
1413 return err;
1414}
1415
1416static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001417 int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418{
1419 struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr;
1420 struct sock *sk = sock->sk;
1421 unsigned char ndigi, i;
1422 ax25_cb *ax25;
1423 int err = 0;
1424
Kees Cook5b919f82011-01-12 00:34:49 -08001425 memset(fsa, 0, sizeof(*fsa));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 lock_sock(sk);
David Miller32003922015-06-25 06:19:07 -07001427 ax25 = sk_to_ax25(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
1429 if (peer != 0) {
1430 if (sk->sk_state != TCP_ESTABLISHED) {
1431 err = -ENOTCONN;
1432 goto out;
1433 }
1434
1435 fsa->fsa_ax25.sax25_family = AF_AX25;
1436 fsa->fsa_ax25.sax25_call = ax25->dest_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437
1438 if (ax25->digipeat != NULL) {
1439 ndigi = ax25->digipeat->ndigi;
1440 fsa->fsa_ax25.sax25_ndigis = ndigi;
1441 for (i = 0; i < ndigi; i++)
1442 fsa->fsa_digipeater[i] =
1443 ax25->digipeat->calls[i];
1444 }
1445 } else {
1446 fsa->fsa_ax25.sax25_family = AF_AX25;
1447 fsa->fsa_ax25.sax25_call = ax25->source_addr;
1448 fsa->fsa_ax25.sax25_ndigis = 1;
1449 if (ax25->ax25_dev != NULL) {
1450 memcpy(&fsa->fsa_digipeater[0],
1451 ax25->ax25_dev->dev->dev_addr, AX25_ADDR_LEN);
1452 } else {
1453 fsa->fsa_digipeater[0] = null_ax25_address;
1454 }
1455 }
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001456 err = sizeof (struct full_sockaddr_ax25);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457
1458out:
1459 release_sock(sk);
1460
1461 return err;
1462}
1463
Ying Xue1b784142015-03-02 15:37:48 +08001464static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465{
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001466 DECLARE_SOCKADDR(struct sockaddr_ax25 *, usax, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 struct sock *sk = sock->sk;
1468 struct sockaddr_ax25 sax;
1469 struct sk_buff *skb;
1470 ax25_digi dtmp, *dp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 ax25_cb *ax25;
1472 size_t size;
1473 int lv, err, addr_len = msg->msg_namelen;
1474
1475 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
1476 return -EINVAL;
1477
1478 lock_sock(sk);
David Miller32003922015-06-25 06:19:07 -07001479 ax25 = sk_to_ax25(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
1481 if (sock_flag(sk, SOCK_ZAPPED)) {
1482 err = -EADDRNOTAVAIL;
1483 goto out;
1484 }
1485
1486 if (sk->sk_shutdown & SEND_SHUTDOWN) {
1487 send_sig(SIGPIPE, current, 0);
1488 err = -EPIPE;
1489 goto out;
1490 }
1491
1492 if (ax25->ax25_dev == NULL) {
1493 err = -ENETUNREACH;
1494 goto out;
1495 }
1496
1497 if (len > ax25->ax25_dev->dev->mtu) {
1498 err = -EMSGSIZE;
1499 goto out;
1500 }
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +09001501
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 if (usax != NULL) {
1503 if (usax->sax25_family != AF_AX25) {
1504 err = -EINVAL;
1505 goto out;
1506 }
1507
maximilian attems27d1cba2008-01-10 03:57:29 -08001508 if (addr_len == sizeof(struct sockaddr_ax25))
1509 /* ax25_sendmsg(): uses obsolete socket structure */
1510 ;
1511 else if (addr_len != sizeof(struct full_sockaddr_ax25))
1512 /* support for old structure may go away some time
1513 * ax25_sendmsg(): uses old (6 digipeater)
1514 * socket structure.
1515 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +09001517 (addr_len > sizeof(struct full_sockaddr_ax25))) {
1518 err = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519 goto out;
1520 }
1521
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522
1523 if (addr_len > sizeof(struct sockaddr_ax25) && usax->sax25_ndigis != 0) {
1524 int ct = 0;
1525 struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)usax;
1526
1527 /* Valid number of digipeaters ? */
Dan Carpenter17ad73e2020-07-23 17:49:57 +03001528 if (usax->sax25_ndigis < 1 ||
1529 usax->sax25_ndigis > AX25_MAX_DIGIS ||
1530 addr_len < sizeof(struct sockaddr_ax25) +
Peilin Ye8885bb02020-07-22 12:05:12 -04001531 sizeof(ax25_address) * usax->sax25_ndigis) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 err = -EINVAL;
1533 goto out;
1534 }
1535
1536 dtmp.ndigi = usax->sax25_ndigis;
1537
1538 while (ct < usax->sax25_ndigis) {
1539 dtmp.repeated[ct] = 0;
1540 dtmp.calls[ct] = fsa->fsa_digipeater[ct];
1541 ct++;
1542 }
1543
1544 dtmp.lastrepeat = 0;
1545 }
1546
1547 sax = *usax;
1548 if (sk->sk_type == SOCK_SEQPACKET &&
1549 ax25cmp(&ax25->dest_addr, &sax.sax25_call)) {
1550 err = -EISCONN;
1551 goto out;
1552 }
1553 if (usax->sax25_ndigis == 0)
1554 dp = NULL;
1555 else
1556 dp = &dtmp;
1557 } else {
1558 /*
1559 * FIXME: 1003.1g - if the socket is like this because
1560 * it has become closed (not started closed) and is VC
1561 * we ought to SIGPIPE, EPIPE
1562 */
1563 if (sk->sk_state != TCP_ESTABLISHED) {
1564 err = -ENOTCONN;
1565 goto out;
1566 }
1567 sax.sax25_family = AF_AX25;
1568 sax.sax25_call = ax25->dest_addr;
1569 dp = ax25->digipeat;
1570 }
1571
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572 /* Build a packet */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 /* Assume the worst case */
1574 size = len + ax25->ax25_dev->dev->hard_header_len;
1575
1576 skb = sock_alloc_send_skb(sk, size, msg->msg_flags&MSG_DONTWAIT, &err);
1577 if (skb == NULL)
1578 goto out;
1579
1580 skb_reserve(skb, size - len);
1581
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 /* User data follows immediately after the AX.25 data */
Al Viro6ce8e9c2014-04-06 21:25:44 -04001583 if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 err = -EFAULT;
1585 kfree_skb(skb);
1586 goto out;
1587 }
1588
Arnaldo Carvalho de Meloc1d2bbe2007-04-10 20:45:18 -07001589 skb_reset_network_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590
1591 /* Add the PID if one is not supplied by the user in the skb */
Arnaldo Carvalho de Melo967b05f2007-03-13 13:51:52 -03001592 if (!ax25->pidincl)
Johannes Bergd58ff352017-06-16 14:29:23 +02001593 *(u8 *)skb_push(skb, 1) = sk->sk_protocol;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 if (sk->sk_type == SOCK_SEQPACKET) {
1596 /* Connected mode sockets go via the LAPB machine */
1597 if (sk->sk_state != TCP_ESTABLISHED) {
1598 kfree_skb(skb);
1599 err = -ENOTCONN;
1600 goto out;
1601 }
1602
1603 /* Shove it onto the queue and kick */
1604 ax25_output(ax25, ax25->paclen, skb);
1605
1606 err = len;
1607 goto out;
1608 }
1609
Arnaldo Carvalho de Melo967b05f2007-03-13 13:51:52 -03001610 skb_push(skb, 1 + ax25_addr_size(dp));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611
Ralf Baechle8849b722011-04-14 00:20:07 -07001612 /* Building AX.25 Header */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613
1614 /* Build an AX.25 header */
Arnaldo Carvalho de Melo967b05f2007-03-13 13:51:52 -03001615 lv = ax25_addr_build(skb->data, &ax25->source_addr, &sax.sax25_call,
1616 dp, AX25_COMMAND, AX25_MODULUS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617
Arnaldo Carvalho de Melo967b05f2007-03-13 13:51:52 -03001618 skb_set_transport_header(skb, lv);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619
Arnaldo Carvalho de Melo9c702202007-04-25 18:04:18 -07001620 *skb_transport_header(skb) = AX25_UI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
1622 /* Datagram frames go straight out of the door as UI */
Arnaldo Carvalho de Melo29c4be52005-04-21 16:46:56 -07001623 ax25_queue_xmit(skb, ax25->ax25_dev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624
1625 err = len;
1626
1627out:
1628 release_sock(sk);
1629
1630 return err;
1631}
1632
Ying Xue1b784142015-03-02 15:37:48 +08001633static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
1634 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635{
1636 struct sock *sk = sock->sk;
1637 struct sk_buff *skb;
1638 int copied;
1639 int err = 0;
1640
1641 lock_sock(sk);
1642 /*
1643 * This works for seqpacket too. The receiver has ordered the
1644 * queue for us! We do one quick check first though
1645 */
1646 if (sk->sk_type == SOCK_SEQPACKET && sk->sk_state != TCP_ESTABLISHED) {
1647 err = -ENOTCONN;
1648 goto out;
1649 }
1650
1651 /* Now we can treat all alike */
1652 skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +09001653 flags & MSG_DONTWAIT, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 if (skb == NULL)
1655 goto out;
1656
David Miller32003922015-06-25 06:19:07 -07001657 if (!sk_to_ax25(sk)->pidincl)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 skb_pull(skb, 1); /* Remove PID */
1659
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -03001660 skb_reset_transport_header(skb);
1661 copied = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662
1663 if (copied > size) {
1664 copied = size;
1665 msg->msg_flags |= MSG_TRUNC;
1666 }
1667
David S. Miller51f3d022014-11-05 16:46:40 -05001668 skb_copy_datagram_msg(skb, 0, msg, copied);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669
Hannes Frederic Sowaf3d33422013-11-21 03:14:22 +01001670 if (msg->msg_name) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 ax25_digi digi;
1672 ax25_address src;
Arnaldo Carvalho de Melo98e399f2007-03-19 15:33:04 -07001673 const unsigned char *mac = skb_mac_header(skb);
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001674 DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675
Mathias Krauseef3313e2013-04-07 01:51:48 +00001676 memset(sax, 0, sizeof(struct full_sockaddr_ax25));
Arnaldo Carvalho de Melo98e399f2007-03-19 15:33:04 -07001677 ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
1678 &digi, NULL, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 sax->sax25_family = AF_AX25;
1680 /* We set this correctly, even though we may not let the
1681 application know the digi calls further down (because it
1682 did NOT ask to know them). This could get political... **/
1683 sax->sax25_ndigis = digi.ndigi;
1684 sax->sax25_call = src;
1685
1686 if (sax->sax25_ndigis != 0) {
1687 int ct;
1688 struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)sax;
1689
1690 for (ct = 0; ct < digi.ndigi; ct++)
1691 fsa->fsa_digipeater[ct] = digi.calls[ct];
1692 }
1693 msg->msg_namelen = sizeof(struct full_sockaddr_ax25);
1694 }
1695
1696 skb_free_datagram(sk, skb);
1697 err = copied;
1698
1699out:
1700 release_sock(sk);
1701
1702 return err;
1703}
1704
1705static int ax25_shutdown(struct socket *sk, int how)
1706{
1707 /* FIXME - generate DM and RNR states */
1708 return -EOPNOTSUPP;
1709}
1710
1711static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1712{
1713 struct sock *sk = sock->sk;
1714 void __user *argp = (void __user *)arg;
1715 int res = 0;
1716
1717 lock_sock(sk);
1718 switch (cmd) {
1719 case TIOCOUTQ: {
1720 long amount;
Eric Dumazet31e6d362009-06-17 19:05:41 -07001721
1722 amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 if (amount < 0)
1724 amount = 0;
1725 res = put_user(amount, (int __user *)argp);
1726 break;
1727 }
1728
1729 case TIOCINQ: {
1730 struct sk_buff *skb;
1731 long amount = 0L;
1732 /* These two are safe on a single CPU system as only user tasks fiddle here */
1733 if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
1734 amount = skb->len;
Ralf Baechle20b7d102005-09-12 14:24:55 -07001735 res = put_user(amount, (int __user *) argp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 break;
1737 }
1738
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */
1740 case SIOCAX25DELUID: /* Delete a uid from the uid/call map table */
1741 case SIOCAX25GETUID: {
1742 struct sockaddr_ax25 sax25;
1743 if (copy_from_user(&sax25, argp, sizeof(sax25))) {
1744 res = -EFAULT;
1745 break;
1746 }
1747 res = ax25_uid_ioctl(cmd, &sax25);
1748 break;
1749 }
1750
1751 case SIOCAX25NOUID: { /* Set the default policy (default/bar) */
1752 long amount;
1753 if (!capable(CAP_NET_ADMIN)) {
1754 res = -EPERM;
1755 break;
1756 }
1757 if (get_user(amount, (long __user *)argp)) {
1758 res = -EFAULT;
1759 break;
1760 }
Dan Carpenter76887752013-10-18 12:06:56 +03001761 if (amount < 0 || amount > AX25_NOUID_BLOCK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 res = -EINVAL;
1763 break;
1764 }
1765 ax25_uid_policy = amount;
1766 res = 0;
1767 break;
1768 }
1769
1770 case SIOCADDRT:
1771 case SIOCDELRT:
1772 case SIOCAX25OPTRT:
1773 if (!capable(CAP_NET_ADMIN)) {
1774 res = -EPERM;
1775 break;
1776 }
1777 res = ax25_rt_ioctl(cmd, argp);
1778 break;
1779
1780 case SIOCAX25CTLCON:
1781 if (!capable(CAP_NET_ADMIN)) {
1782 res = -EPERM;
1783 break;
1784 }
1785 res = ax25_ctl_ioctl(cmd, argp);
1786 break;
1787
1788 case SIOCAX25GETINFO:
1789 case SIOCAX25GETINFOOLD: {
David Miller32003922015-06-25 06:19:07 -07001790 ax25_cb *ax25 = sk_to_ax25(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 struct ax25_info_struct ax25_info;
1792
1793 ax25_info.t1 = ax25->t1 / HZ;
1794 ax25_info.t2 = ax25->t2 / HZ;
1795 ax25_info.t3 = ax25->t3 / HZ;
1796 ax25_info.idle = ax25->idle / (60 * HZ);
1797 ax25_info.n2 = ax25->n2;
1798 ax25_info.t1timer = ax25_display_timer(&ax25->t1timer) / HZ;
1799 ax25_info.t2timer = ax25_display_timer(&ax25->t2timer) / HZ;
1800 ax25_info.t3timer = ax25_display_timer(&ax25->t3timer) / HZ;
1801 ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ);
1802 ax25_info.n2count = ax25->n2count;
1803 ax25_info.state = ax25->state;
Eric Dumazet407fc5c2009-09-20 06:32:55 +00001804 ax25_info.rcv_q = sk_rmem_alloc_get(sk);
1805 ax25_info.snd_q = sk_wmem_alloc_get(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 ax25_info.vs = ax25->vs;
1807 ax25_info.vr = ax25->vr;
1808 ax25_info.va = ax25->va;
1809 ax25_info.vs_max = ax25->vs; /* reserved */
1810 ax25_info.paclen = ax25->paclen;
1811 ax25_info.window = ax25->window;
1812
1813 /* old structure? */
1814 if (cmd == SIOCAX25GETINFOOLD) {
1815 static int warned = 0;
1816 if (!warned) {
1817 printk(KERN_INFO "%s uses old SIOCAX25GETINFO\n",
1818 current->comm);
1819 warned=1;
1820 }
1821
1822 if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct_deprecated))) {
1823 res = -EFAULT;
1824 break;
1825 }
1826 } else {
1827 if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct))) {
1828 res = -EINVAL;
1829 break;
1830 }
1831 }
1832 res = 0;
1833 break;
1834 }
1835
1836 case SIOCAX25ADDFWD:
1837 case SIOCAX25DELFWD: {
1838 struct ax25_fwd_struct ax25_fwd;
1839 if (!capable(CAP_NET_ADMIN)) {
1840 res = -EPERM;
1841 break;
1842 }
1843 if (copy_from_user(&ax25_fwd, argp, sizeof(ax25_fwd))) {
1844 res = -EFAULT;
1845 break;
1846 }
1847 res = ax25_fwd_ioctl(cmd, &ax25_fwd);
1848 break;
1849 }
1850
1851 case SIOCGIFADDR:
1852 case SIOCSIFADDR:
1853 case SIOCGIFDSTADDR:
1854 case SIOCSIFDSTADDR:
1855 case SIOCGIFBRDADDR:
1856 case SIOCSIFBRDADDR:
1857 case SIOCGIFNETMASK:
1858 case SIOCSIFNETMASK:
1859 case SIOCGIFMETRIC:
1860 case SIOCSIFMETRIC:
1861 res = -EINVAL;
1862 break;
1863
1864 default:
Christoph Hellwigb5e5fa52006-01-03 14:18:33 -08001865 res = -ENOIOCTLCMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 break;
1867 }
1868 release_sock(sk);
1869
1870 return res;
1871}
1872
1873#ifdef CONFIG_PROC_FS
1874
1875static void *ax25_info_start(struct seq_file *seq, loff_t *pos)
Eric Dumazetf16f3022008-01-13 22:29:41 -08001876 __acquires(ax25_list_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 spin_lock_bh(&ax25_list_lock);
Li Zefanb512f3d2010-02-08 23:19:59 +00001879 return seq_hlist_start(&ax25_list, *pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880}
1881
1882static void *ax25_info_next(struct seq_file *seq, void *v, loff_t *pos)
1883{
Li Zefanb512f3d2010-02-08 23:19:59 +00001884 return seq_hlist_next(v, &ax25_list, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885}
YOSHIFUJI Hideaki528930b2007-02-09 23:24:31 +09001886
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887static void ax25_info_stop(struct seq_file *seq, void *v)
Eric Dumazetf16f3022008-01-13 22:29:41 -08001888 __releases(ax25_list_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889{
1890 spin_unlock_bh(&ax25_list_lock);
1891}
1892
1893static int ax25_info_show(struct seq_file *seq, void *v)
1894{
Li Zefanb512f3d2010-02-08 23:19:59 +00001895 ax25_cb *ax25 = hlist_entry(v, struct ax25_cb, ax25_node);
Ralf Baechlef75268c2005-09-06 15:49:39 -07001896 char buf[11];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 int k;
1898
1899
1900 /*
1901 * New format:
1902 * magic dev src_addr dest_addr,digi1,digi2,.. st vs vr va t1 t1 t2 t2 t3 t3 idle idle n2 n2 rtt window paclen Snd-Q Rcv-Q inode
1903 */
1904
Fuqian Huang966cdde2019-04-21 19:48:06 +08001905 seq_printf(seq, "%p %s %s%s ",
1906 ax25,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name,
Ralf Baechlef75268c2005-09-06 15:49:39 -07001908 ax2asc(buf, &ax25->source_addr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 ax25->iamdigi? "*":"");
Ralf Baechlef75268c2005-09-06 15:49:39 -07001910 seq_printf(seq, "%s", ax2asc(buf, &ax25->dest_addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
1912 for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) {
1913 seq_printf(seq, ",%s%s",
Ralf Baechlef75268c2005-09-06 15:49:39 -07001914 ax2asc(buf, &ax25->digipeat->calls[k]),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 ax25->digipeat->repeated[k]? "*":"");
1916 }
1917
1918 seq_printf(seq, " %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %d %d",
1919 ax25->state,
1920 ax25->vs, ax25->vr, ax25->va,
1921 ax25_display_timer(&ax25->t1timer) / HZ, ax25->t1 / HZ,
1922 ax25_display_timer(&ax25->t2timer) / HZ, ax25->t2 / HZ,
1923 ax25_display_timer(&ax25->t3timer) / HZ, ax25->t3 / HZ,
1924 ax25_display_timer(&ax25->idletimer) / (60 * HZ),
1925 ax25->idle / (60 * HZ),
1926 ax25->n2count, ax25->n2,
1927 ax25->rtt / HZ,
1928 ax25->window,
1929 ax25->paclen);
1930
1931 if (ax25->sk != NULL) {
Jarek Poplawski1105b5d2008-02-11 21:24:56 -08001932 seq_printf(seq, " %d %d %lu\n",
Eric Dumazet31e6d362009-06-17 19:05:41 -07001933 sk_wmem_alloc_get(ax25->sk),
1934 sk_rmem_alloc_get(ax25->sk),
Jarek Poplawski1105b5d2008-02-11 21:24:56 -08001935 sock_i_ino(ax25->sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 } else {
1937 seq_puts(seq, " * * *\n");
1938 }
1939 return 0;
1940}
1941
Philippe De Muyter56b3d972007-07-10 23:07:31 -07001942static const struct seq_operations ax25_info_seqops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 .start = ax25_info_start,
1944 .next = ax25_info_next,
1945 .stop = ax25_info_stop,
1946 .show = ax25_info_show,
1947};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948#endif
1949
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001950static const struct net_proto_family ax25_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 .family = PF_AX25,
1952 .create = ax25_create,
1953 .owner = THIS_MODULE,
1954};
1955
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001956static const struct proto_ops ax25_proto_ops = {
Ralf Baechle46763562005-09-12 14:25:25 -07001957 .family = PF_AX25,
1958 .owner = THIS_MODULE,
1959 .release = ax25_release,
1960 .bind = ax25_bind,
1961 .connect = ax25_connect,
1962 .socketpair = sock_no_socketpair,
1963 .accept = ax25_accept,
1964 .getname = ax25_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07001965 .poll = datagram_poll,
Ralf Baechle46763562005-09-12 14:25:25 -07001966 .ioctl = ax25_ioctl,
Arnd Bergmannc7cbdbf2019-04-17 22:51:48 +02001967 .gettstamp = sock_gettstamp,
Ralf Baechle46763562005-09-12 14:25:25 -07001968 .listen = ax25_listen,
1969 .shutdown = ax25_shutdown,
1970 .setsockopt = ax25_setsockopt,
1971 .getsockopt = ax25_getsockopt,
1972 .sendmsg = ax25_sendmsg,
1973 .recvmsg = ax25_recvmsg,
1974 .mmap = sock_no_mmap,
1975 .sendpage = sock_no_sendpage,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976};
1977
1978/*
1979 * Called by socket.c on kernel start up
1980 */
Stephen Hemminger7546dd92009-03-09 08:18:29 +00001981static struct packet_type ax25_packet_type __read_mostly = {
Harvey Harrison09640e632009-02-01 00:45:17 -08001982 .type = cpu_to_be16(ETH_P_AX25),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983 .func = ax25_kiss_rcv,
1984};
1985
1986static struct notifier_block ax25_dev_notifier = {
Jiri Pirko351638e2013-05-28 01:30:21 +00001987 .notifier_call = ax25_device_event,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988};
1989
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990static int __init ax25_init(void)
1991{
1992 int rc = proto_register(&ax25_proto, 0);
1993
1994 if (rc != 0)
1995 goto out;
1996
1997 sock_register(&ax25_family_ops);
1998 dev_add_pack(&ax25_packet_type);
1999 register_netdevice_notifier(&ax25_dev_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000
Christoph Hellwigfddda2b2018-04-13 19:44:18 +02002001 proc_create_seq("ax25_route", 0444, init_net.proc_net, &ax25_rt_seqops);
2002 proc_create_seq("ax25", 0444, init_net.proc_net, &ax25_info_seqops);
2003 proc_create_seq("ax25_calls", 0444, init_net.proc_net,
2004 &ax25_uid_seqops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005out:
2006 return rc;
2007}
2008module_init(ax25_init);
2009
2010
2011MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
2012MODULE_DESCRIPTION("The amateur radio AX.25 link layer protocol");
2013MODULE_LICENSE("GPL");
2014MODULE_ALIAS_NETPROTO(PF_AX25);
2015
2016static void __exit ax25_exit(void)
2017{
Gao fengece31ff2013-02-18 01:34:56 +00002018 remove_proc_entry("ax25_route", init_net.proc_net);
2019 remove_proc_entry("ax25", init_net.proc_net);
2020 remove_proc_entry("ax25_calls", init_net.proc_net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 unregister_netdevice_notifier(&ax25_dev_notifier);
2023
2024 dev_remove_pack(&ax25_packet_type);
2025
2026 sock_unregister(PF_AX25);
2027 proto_unregister(&ax25_proto);
Eric W. Biederman3adadc02012-04-18 16:11:23 +00002028
2029 ax25_rt_free();
2030 ax25_uid_free();
2031 ax25_dev_free();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032}
2033module_exit(ax25_exit);