Linux 6.10-rc3
[linux-block.git] / net / ax25 / ax25_route.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *
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) Steven Whitehouse GW7RRM (stevew@acm.org)
7  * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
8  * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
9  * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
10  */
11
12 #include <linux/capability.h>
13 #include <linux/errno.h>
14 #include <linux/types.h>
15 #include <linux/socket.h>
16 #include <linux/timer.h>
17 #include <linux/in.h>
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/string.h>
21 #include <linux/sockios.h>
22 #include <linux/net.h>
23 #include <linux/slab.h>
24 #include <net/ax25.h>
25 #include <linux/inet.h>
26 #include <linux/netdevice.h>
27 #include <linux/if_arp.h>
28 #include <linux/skbuff.h>
29 #include <linux/spinlock.h>
30 #include <net/sock.h>
31 #include <linux/uaccess.h>
32 #include <linux/fcntl.h>
33 #include <linux/mm.h>
34 #include <linux/interrupt.h>
35 #include <linux/init.h>
36 #include <linux/seq_file.h>
37 #include <linux/export.h>
38
39 static ax25_route *ax25_route_list;
40 DEFINE_RWLOCK(ax25_route_lock);
41
42 void ax25_rt_device_down(struct net_device *dev)
43 {
44         ax25_route *s, *t, *ax25_rt;
45
46         write_lock_bh(&ax25_route_lock);
47         ax25_rt = ax25_route_list;
48         while (ax25_rt != NULL) {
49                 s       = ax25_rt;
50                 ax25_rt = ax25_rt->next;
51
52                 if (s->dev == dev) {
53                         if (ax25_route_list == s) {
54                                 ax25_route_list = s->next;
55                                 kfree(s->digipeat);
56                                 kfree(s);
57                         } else {
58                                 for (t = ax25_route_list; t != NULL; t = t->next) {
59                                         if (t->next == s) {
60                                                 t->next = s->next;
61                                                 kfree(s->digipeat);
62                                                 kfree(s);
63                                                 break;
64                                         }
65                                 }
66                         }
67                 }
68         }
69         write_unlock_bh(&ax25_route_lock);
70 }
71
72 static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
73 {
74         ax25_route *ax25_rt;
75         ax25_dev *ax25_dev;
76         int i;
77
78         if (route->digi_count > AX25_MAX_DIGIS)
79                 return -EINVAL;
80
81         ax25_dev = ax25_addr_ax25dev(&route->port_addr);
82         if (!ax25_dev)
83                 return -EINVAL;
84
85         write_lock_bh(&ax25_route_lock);
86
87         ax25_rt = ax25_route_list;
88         while (ax25_rt != NULL) {
89                 if (ax25cmp(&ax25_rt->callsign, &route->dest_addr) == 0 &&
90                             ax25_rt->dev == ax25_dev->dev) {
91                         kfree(ax25_rt->digipeat);
92                         ax25_rt->digipeat = NULL;
93                         if (route->digi_count != 0) {
94                                 if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
95                                         write_unlock_bh(&ax25_route_lock);
96                                         ax25_dev_put(ax25_dev);
97                                         return -ENOMEM;
98                                 }
99                                 ax25_rt->digipeat->lastrepeat = -1;
100                                 ax25_rt->digipeat->ndigi      = route->digi_count;
101                                 for (i = 0; i < route->digi_count; i++) {
102                                         ax25_rt->digipeat->repeated[i] = 0;
103                                         ax25_rt->digipeat->calls[i]    = route->digi_addr[i];
104                                 }
105                         }
106                         write_unlock_bh(&ax25_route_lock);
107                         ax25_dev_put(ax25_dev);
108                         return 0;
109                 }
110                 ax25_rt = ax25_rt->next;
111         }
112
113         if ((ax25_rt = kmalloc(sizeof(ax25_route), GFP_ATOMIC)) == NULL) {
114                 write_unlock_bh(&ax25_route_lock);
115                 ax25_dev_put(ax25_dev);
116                 return -ENOMEM;
117         }
118
119         ax25_rt->callsign     = route->dest_addr;
120         ax25_rt->dev          = ax25_dev->dev;
121         ax25_rt->digipeat     = NULL;
122         ax25_rt->ip_mode      = ' ';
123         if (route->digi_count != 0) {
124                 if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
125                         write_unlock_bh(&ax25_route_lock);
126                         kfree(ax25_rt);
127                         ax25_dev_put(ax25_dev);
128                         return -ENOMEM;
129                 }
130                 ax25_rt->digipeat->lastrepeat = -1;
131                 ax25_rt->digipeat->ndigi      = route->digi_count;
132                 for (i = 0; i < route->digi_count; i++) {
133                         ax25_rt->digipeat->repeated[i] = 0;
134                         ax25_rt->digipeat->calls[i]    = route->digi_addr[i];
135                 }
136         }
137         ax25_rt->next   = ax25_route_list;
138         ax25_route_list = ax25_rt;
139         write_unlock_bh(&ax25_route_lock);
140         ax25_dev_put(ax25_dev);
141
142         return 0;
143 }
144
145 void __ax25_put_route(ax25_route *ax25_rt)
146 {
147         kfree(ax25_rt->digipeat);
148         kfree(ax25_rt);
149 }
150
151 static int ax25_rt_del(struct ax25_routes_struct *route)
152 {
153         ax25_route *s, *t, *ax25_rt;
154         ax25_dev *ax25_dev;
155
156         if ((ax25_dev = ax25_addr_ax25dev(&route->port_addr)) == NULL)
157                 return -EINVAL;
158
159         write_lock_bh(&ax25_route_lock);
160
161         ax25_rt = ax25_route_list;
162         while (ax25_rt != NULL) {
163                 s       = ax25_rt;
164                 ax25_rt = ax25_rt->next;
165                 if (s->dev == ax25_dev->dev &&
166                     ax25cmp(&route->dest_addr, &s->callsign) == 0) {
167                         if (ax25_route_list == s) {
168                                 ax25_route_list = s->next;
169                                 __ax25_put_route(s);
170                         } else {
171                                 for (t = ax25_route_list; t != NULL; t = t->next) {
172                                         if (t->next == s) {
173                                                 t->next = s->next;
174                                                 __ax25_put_route(s);
175                                                 break;
176                                         }
177                                 }
178                         }
179                 }
180         }
181         write_unlock_bh(&ax25_route_lock);
182         ax25_dev_put(ax25_dev);
183
184         return 0;
185 }
186
187 static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option)
188 {
189         ax25_route *ax25_rt;
190         ax25_dev *ax25_dev;
191         int err = 0;
192
193         if ((ax25_dev = ax25_addr_ax25dev(&rt_option->port_addr)) == NULL)
194                 return -EINVAL;
195
196         write_lock_bh(&ax25_route_lock);
197
198         ax25_rt = ax25_route_list;
199         while (ax25_rt != NULL) {
200                 if (ax25_rt->dev == ax25_dev->dev &&
201                     ax25cmp(&rt_option->dest_addr, &ax25_rt->callsign) == 0) {
202                         switch (rt_option->cmd) {
203                         case AX25_SET_RT_IPMODE:
204                                 switch (rt_option->arg) {
205                                 case ' ':
206                                 case 'D':
207                                 case 'V':
208                                         ax25_rt->ip_mode = rt_option->arg;
209                                         break;
210                                 default:
211                                         err = -EINVAL;
212                                         goto out;
213                                 }
214                                 break;
215                         default:
216                                 err = -EINVAL;
217                                 goto out;
218                         }
219                 }
220                 ax25_rt = ax25_rt->next;
221         }
222
223 out:
224         write_unlock_bh(&ax25_route_lock);
225         ax25_dev_put(ax25_dev);
226         return err;
227 }
228
229 int ax25_rt_ioctl(unsigned int cmd, void __user *arg)
230 {
231         struct ax25_route_opt_struct rt_option;
232         struct ax25_routes_struct route;
233
234         switch (cmd) {
235         case SIOCADDRT:
236                 if (copy_from_user(&route, arg, sizeof(route)))
237                         return -EFAULT;
238                 return ax25_rt_add(&route);
239
240         case SIOCDELRT:
241                 if (copy_from_user(&route, arg, sizeof(route)))
242                         return -EFAULT;
243                 return ax25_rt_del(&route);
244
245         case SIOCAX25OPTRT:
246                 if (copy_from_user(&rt_option, arg, sizeof(rt_option)))
247                         return -EFAULT;
248                 return ax25_rt_opt(&rt_option);
249
250         default:
251                 return -EINVAL;
252         }
253 }
254
255 #ifdef CONFIG_PROC_FS
256
257 static void *ax25_rt_seq_start(struct seq_file *seq, loff_t *pos)
258         __acquires(ax25_route_lock)
259 {
260         struct ax25_route *ax25_rt;
261         int i = 1;
262
263         read_lock(&ax25_route_lock);
264         if (*pos == 0)
265                 return SEQ_START_TOKEN;
266
267         for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
268                 if (i == *pos)
269                         return ax25_rt;
270                 ++i;
271         }
272
273         return NULL;
274 }
275
276 static void *ax25_rt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
277 {
278         ++*pos;
279         return (v == SEQ_START_TOKEN) ? ax25_route_list :
280                 ((struct ax25_route *) v)->next;
281 }
282
283 static void ax25_rt_seq_stop(struct seq_file *seq, void *v)
284         __releases(ax25_route_lock)
285 {
286         read_unlock(&ax25_route_lock);
287 }
288
289 static int ax25_rt_seq_show(struct seq_file *seq, void *v)
290 {
291         char buf[11];
292
293         if (v == SEQ_START_TOKEN)
294                 seq_puts(seq, "callsign  dev  mode digipeaters\n");
295         else {
296                 struct ax25_route *ax25_rt = v;
297                 const char *callsign;
298                 int i;
299
300                 if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0)
301                         callsign = "default";
302                 else
303                         callsign = ax2asc(buf, &ax25_rt->callsign);
304
305                 seq_printf(seq, "%-9s %-4s",
306                         callsign,
307                         ax25_rt->dev ? ax25_rt->dev->name : "???");
308
309                 switch (ax25_rt->ip_mode) {
310                 case 'V':
311                         seq_puts(seq, "   vc");
312                         break;
313                 case 'D':
314                         seq_puts(seq, "   dg");
315                         break;
316                 default:
317                         seq_puts(seq, "    *");
318                         break;
319                 }
320
321                 if (ax25_rt->digipeat != NULL)
322                         for (i = 0; i < ax25_rt->digipeat->ndigi; i++)
323                                 seq_printf(seq, " %s",
324                                      ax2asc(buf, &ax25_rt->digipeat->calls[i]));
325
326                 seq_puts(seq, "\n");
327         }
328         return 0;
329 }
330
331 const struct seq_operations ax25_rt_seqops = {
332         .start = ax25_rt_seq_start,
333         .next = ax25_rt_seq_next,
334         .stop = ax25_rt_seq_stop,
335         .show = ax25_rt_seq_show,
336 };
337 #endif
338
339 /*
340  *      Find AX.25 route
341  *
342  *      Only routes with a reference count of zero can be destroyed.
343  *      Must be called with ax25_route_lock read locked.
344  */
345 ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
346 {
347         ax25_route *ax25_spe_rt = NULL;
348         ax25_route *ax25_def_rt = NULL;
349         ax25_route *ax25_rt;
350
351         /*
352          *      Bind to the physical interface we heard them on, or the default
353          *      route if none is found;
354          */
355         for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
356                 if (dev == NULL) {
357                         if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev != NULL)
358                                 ax25_spe_rt = ax25_rt;
359                         if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0 && ax25_rt->dev != NULL)
360                                 ax25_def_rt = ax25_rt;
361                 } else {
362                         if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev == dev)
363                                 ax25_spe_rt = ax25_rt;
364                         if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0 && ax25_rt->dev == dev)
365                                 ax25_def_rt = ax25_rt;
366                 }
367         }
368
369         ax25_rt = ax25_def_rt;
370         if (ax25_spe_rt != NULL)
371                 ax25_rt = ax25_spe_rt;
372
373         return ax25_rt;
374 }
375
376 /*
377  *      Adjust path: If you specify a default route and want to connect
378  *      a target on the digipeater path but w/o having a special route
379  *      set before, the path has to be truncated from your target on.
380  */
381 static inline void ax25_adjust_path(ax25_address *addr, ax25_digi *digipeat)
382 {
383         int k;
384
385         for (k = 0; k < digipeat->ndigi; k++) {
386                 if (ax25cmp(addr, &digipeat->calls[k]) == 0)
387                         break;
388         }
389
390         digipeat->ndigi = k;
391 }
392
393
394 /*
395  *      Find which interface to use.
396  */
397 int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
398 {
399         ax25_uid_assoc *user;
400         ax25_route *ax25_rt;
401         int err = 0;
402
403         ax25_route_lock_use();
404         ax25_rt = ax25_get_route(addr, NULL);
405         if (!ax25_rt) {
406                 ax25_route_lock_unuse();
407                 return -EHOSTUNREACH;
408         }
409         if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
410                 err = -EHOSTUNREACH;
411                 goto put;
412         }
413
414         user = ax25_findbyuid(current_euid());
415         if (user) {
416                 ax25->source_addr = user->call;
417                 ax25_uid_put(user);
418         } else {
419                 if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
420                         err = -EPERM;
421                         goto put;
422                 }
423                 ax25->source_addr = *(ax25_address *)ax25->ax25_dev->dev->dev_addr;
424         }
425
426         if (ax25_rt->digipeat != NULL) {
427                 ax25->digipeat = kmemdup(ax25_rt->digipeat, sizeof(ax25_digi),
428                                          GFP_ATOMIC);
429                 if (ax25->digipeat == NULL) {
430                         err = -ENOMEM;
431                         goto put;
432                 }
433                 ax25_adjust_path(addr, ax25->digipeat);
434         }
435
436         if (ax25->sk != NULL) {
437                 local_bh_disable();
438                 bh_lock_sock(ax25->sk);
439                 sock_reset_flag(ax25->sk, SOCK_ZAPPED);
440                 bh_unlock_sock(ax25->sk);
441                 local_bh_enable();
442         }
443
444 put:
445         ax25_route_lock_unuse();
446         return err;
447 }
448
449 struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src,
450         ax25_address *dest, ax25_digi *digi)
451 {
452         unsigned char *bp;
453         int len;
454
455         len = digi->ndigi * AX25_ADDR_LEN;
456
457         if (unlikely(skb_headroom(skb) < len)) {
458                 skb = skb_expand_head(skb, len);
459                 if (!skb) {
460                         printk(KERN_CRIT "AX.25: ax25_dg_build_path - out of memory\n");
461                         return NULL;
462                 }
463         }
464
465         bp = skb_push(skb, len);
466
467         ax25_addr_build(bp, src, dest, digi, AX25_COMMAND, AX25_MODULUS);
468
469         return skb;
470 }
471
472 /*
473  *      Free all memory associated with routing structures.
474  */
475 void __exit ax25_rt_free(void)
476 {
477         ax25_route *s, *ax25_rt = ax25_route_list;
478
479         write_lock_bh(&ax25_route_lock);
480         while (ax25_rt != NULL) {
481                 s       = ax25_rt;
482                 ax25_rt = ax25_rt->next;
483
484                 kfree(s->digipeat);
485                 kfree(s);
486         }
487         write_unlock_bh(&ax25_route_lock);
488 }