0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/errno.h>
0009 #include <linux/types.h>
0010 #include <linux/socket.h>
0011 #include <linux/in.h>
0012 #include <linux/kernel.h>
0013 #include <linux/timer.h>
0014 #include <linux/string.h>
0015 #include <linux/sockios.h>
0016 #include <linux/net.h>
0017 #include <linux/slab.h>
0018 #include <net/ax25.h>
0019 #include <linux/inet.h>
0020 #include <linux/netdevice.h>
0021 #include <net/arp.h>
0022 #include <linux/if_arp.h>
0023 #include <linux/skbuff.h>
0024 #include <net/sock.h>
0025 #include <linux/uaccess.h>
0026 #include <linux/fcntl.h>
0027 #include <linux/termios.h> /* For TIOCINQ/OUTQ */
0028 #include <linux/mm.h>
0029 #include <linux/interrupt.h>
0030 #include <linux/notifier.h>
0031 #include <linux/init.h>
0032 #include <linux/spinlock.h>
0033 #include <net/netrom.h>
0034 #include <linux/seq_file.h>
0035 #include <linux/export.h>
0036
0037 static unsigned int nr_neigh_no = 1;
0038
0039 static HLIST_HEAD(nr_node_list);
0040 static DEFINE_SPINLOCK(nr_node_list_lock);
0041 static HLIST_HEAD(nr_neigh_list);
0042 static DEFINE_SPINLOCK(nr_neigh_list_lock);
0043
0044 static struct nr_node *nr_node_get(ax25_address *callsign)
0045 {
0046 struct nr_node *found = NULL;
0047 struct nr_node *nr_node;
0048
0049 spin_lock_bh(&nr_node_list_lock);
0050 nr_node_for_each(nr_node, &nr_node_list)
0051 if (ax25cmp(callsign, &nr_node->callsign) == 0) {
0052 nr_node_hold(nr_node);
0053 found = nr_node;
0054 break;
0055 }
0056 spin_unlock_bh(&nr_node_list_lock);
0057 return found;
0058 }
0059
0060 static struct nr_neigh *nr_neigh_get_dev(ax25_address *callsign,
0061 struct net_device *dev)
0062 {
0063 struct nr_neigh *found = NULL;
0064 struct nr_neigh *nr_neigh;
0065
0066 spin_lock_bh(&nr_neigh_list_lock);
0067 nr_neigh_for_each(nr_neigh, &nr_neigh_list)
0068 if (ax25cmp(callsign, &nr_neigh->callsign) == 0 &&
0069 nr_neigh->dev == dev) {
0070 nr_neigh_hold(nr_neigh);
0071 found = nr_neigh;
0072 break;
0073 }
0074 spin_unlock_bh(&nr_neigh_list_lock);
0075 return found;
0076 }
0077
0078 static void nr_remove_neigh(struct nr_neigh *);
0079
0080
0081 static void re_sort_routes(struct nr_node *nr_node, int x, int y)
0082 {
0083 if (nr_node->routes[y].quality > nr_node->routes[x].quality) {
0084 if (nr_node->which == x)
0085 nr_node->which = y;
0086 else if (nr_node->which == y)
0087 nr_node->which = x;
0088
0089 swap(nr_node->routes[x], nr_node->routes[y]);
0090 }
0091 }
0092
0093
0094
0095
0096
0097 static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
0098 ax25_address *ax25, ax25_digi *ax25_digi, struct net_device *dev,
0099 int quality, int obs_count)
0100 {
0101 struct nr_node *nr_node;
0102 struct nr_neigh *nr_neigh;
0103 int i, found;
0104 struct net_device *odev;
0105
0106 if ((odev=nr_dev_get(nr)) != NULL) {
0107 dev_put(odev);
0108 return -EINVAL;
0109 }
0110
0111 nr_node = nr_node_get(nr);
0112
0113 nr_neigh = nr_neigh_get_dev(ax25, dev);
0114
0115
0116
0117
0118
0119
0120
0121 if (nr_neigh != NULL && nr_neigh->failed != 0 && quality == 0) {
0122 struct nr_node *nr_nodet;
0123
0124 spin_lock_bh(&nr_node_list_lock);
0125 nr_node_for_each(nr_nodet, &nr_node_list) {
0126 nr_node_lock(nr_nodet);
0127 for (i = 0; i < nr_nodet->count; i++)
0128 if (nr_nodet->routes[i].neighbour == nr_neigh)
0129 if (i < nr_nodet->which)
0130 nr_nodet->which = i;
0131 nr_node_unlock(nr_nodet);
0132 }
0133 spin_unlock_bh(&nr_node_list_lock);
0134 }
0135
0136 if (nr_neigh != NULL)
0137 nr_neigh->failed = 0;
0138
0139 if (quality == 0 && nr_neigh != NULL && nr_node != NULL) {
0140 nr_neigh_put(nr_neigh);
0141 nr_node_put(nr_node);
0142 return 0;
0143 }
0144
0145 if (nr_neigh == NULL) {
0146 if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) {
0147 if (nr_node)
0148 nr_node_put(nr_node);
0149 return -ENOMEM;
0150 }
0151
0152 nr_neigh->callsign = *ax25;
0153 nr_neigh->digipeat = NULL;
0154 nr_neigh->ax25 = NULL;
0155 nr_neigh->dev = dev;
0156 nr_neigh->quality = sysctl_netrom_default_path_quality;
0157 nr_neigh->locked = 0;
0158 nr_neigh->count = 0;
0159 nr_neigh->number = nr_neigh_no++;
0160 nr_neigh->failed = 0;
0161 refcount_set(&nr_neigh->refcount, 1);
0162
0163 if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
0164 nr_neigh->digipeat = kmemdup(ax25_digi,
0165 sizeof(*ax25_digi),
0166 GFP_KERNEL);
0167 if (nr_neigh->digipeat == NULL) {
0168 kfree(nr_neigh);
0169 if (nr_node)
0170 nr_node_put(nr_node);
0171 return -ENOMEM;
0172 }
0173 }
0174
0175 spin_lock_bh(&nr_neigh_list_lock);
0176 hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list);
0177 nr_neigh_hold(nr_neigh);
0178 spin_unlock_bh(&nr_neigh_list_lock);
0179 }
0180
0181 if (quality != 0 && ax25cmp(nr, ax25) == 0 && !nr_neigh->locked)
0182 nr_neigh->quality = quality;
0183
0184 if (nr_node == NULL) {
0185 if ((nr_node = kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL) {
0186 if (nr_neigh)
0187 nr_neigh_put(nr_neigh);
0188 return -ENOMEM;
0189 }
0190
0191 nr_node->callsign = *nr;
0192 strcpy(nr_node->mnemonic, mnemonic);
0193
0194 nr_node->which = 0;
0195 nr_node->count = 1;
0196 refcount_set(&nr_node->refcount, 1);
0197 spin_lock_init(&nr_node->node_lock);
0198
0199 nr_node->routes[0].quality = quality;
0200 nr_node->routes[0].obs_count = obs_count;
0201 nr_node->routes[0].neighbour = nr_neigh;
0202
0203 nr_neigh_hold(nr_neigh);
0204 nr_neigh->count++;
0205
0206 spin_lock_bh(&nr_node_list_lock);
0207 hlist_add_head(&nr_node->node_node, &nr_node_list);
0208
0209 spin_unlock_bh(&nr_node_list_lock);
0210
0211 nr_neigh_put(nr_neigh);
0212 return 0;
0213 }
0214 nr_node_lock(nr_node);
0215
0216 if (quality != 0)
0217 strcpy(nr_node->mnemonic, mnemonic);
0218
0219 for (found = 0, i = 0; i < nr_node->count; i++) {
0220 if (nr_node->routes[i].neighbour == nr_neigh) {
0221 nr_node->routes[i].quality = quality;
0222 nr_node->routes[i].obs_count = obs_count;
0223 found = 1;
0224 break;
0225 }
0226 }
0227
0228 if (!found) {
0229
0230 if (nr_node->count < 3) {
0231 nr_node->routes[2] = nr_node->routes[1];
0232 nr_node->routes[1] = nr_node->routes[0];
0233
0234 nr_node->routes[0].quality = quality;
0235 nr_node->routes[0].obs_count = obs_count;
0236 nr_node->routes[0].neighbour = nr_neigh;
0237
0238 nr_node->which++;
0239 nr_node->count++;
0240 nr_neigh_hold(nr_neigh);
0241 nr_neigh->count++;
0242 } else {
0243
0244 if (quality > nr_node->routes[2].quality) {
0245 nr_node->routes[2].neighbour->count--;
0246 nr_neigh_put(nr_node->routes[2].neighbour);
0247
0248 if (nr_node->routes[2].neighbour->count == 0 && !nr_node->routes[2].neighbour->locked)
0249 nr_remove_neigh(nr_node->routes[2].neighbour);
0250
0251 nr_node->routes[2].quality = quality;
0252 nr_node->routes[2].obs_count = obs_count;
0253 nr_node->routes[2].neighbour = nr_neigh;
0254
0255 nr_neigh_hold(nr_neigh);
0256 nr_neigh->count++;
0257 }
0258 }
0259 }
0260
0261
0262 switch (nr_node->count) {
0263 case 3:
0264 re_sort_routes(nr_node, 0, 1);
0265 re_sort_routes(nr_node, 1, 2);
0266 fallthrough;
0267 case 2:
0268 re_sort_routes(nr_node, 0, 1);
0269 break;
0270 case 1:
0271 break;
0272 }
0273
0274 for (i = 0; i < nr_node->count; i++) {
0275 if (nr_node->routes[i].neighbour == nr_neigh) {
0276 if (i < nr_node->which)
0277 nr_node->which = i;
0278 break;
0279 }
0280 }
0281
0282 nr_neigh_put(nr_neigh);
0283 nr_node_unlock(nr_node);
0284 nr_node_put(nr_node);
0285 return 0;
0286 }
0287
0288 static inline void __nr_remove_node(struct nr_node *nr_node)
0289 {
0290 hlist_del_init(&nr_node->node_node);
0291 nr_node_put(nr_node);
0292 }
0293
0294 #define nr_remove_node_locked(__node) \
0295 __nr_remove_node(__node)
0296
0297 static void nr_remove_node(struct nr_node *nr_node)
0298 {
0299 spin_lock_bh(&nr_node_list_lock);
0300 __nr_remove_node(nr_node);
0301 spin_unlock_bh(&nr_node_list_lock);
0302 }
0303
0304 static inline void __nr_remove_neigh(struct nr_neigh *nr_neigh)
0305 {
0306 hlist_del_init(&nr_neigh->neigh_node);
0307 nr_neigh_put(nr_neigh);
0308 }
0309
0310 #define nr_remove_neigh_locked(__neigh) \
0311 __nr_remove_neigh(__neigh)
0312
0313 static void nr_remove_neigh(struct nr_neigh *nr_neigh)
0314 {
0315 spin_lock_bh(&nr_neigh_list_lock);
0316 __nr_remove_neigh(nr_neigh);
0317 spin_unlock_bh(&nr_neigh_list_lock);
0318 }
0319
0320
0321
0322
0323
0324 static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct net_device *dev)
0325 {
0326 struct nr_node *nr_node;
0327 struct nr_neigh *nr_neigh;
0328 int i;
0329
0330 nr_node = nr_node_get(callsign);
0331
0332 if (nr_node == NULL)
0333 return -EINVAL;
0334
0335 nr_neigh = nr_neigh_get_dev(neighbour, dev);
0336
0337 if (nr_neigh == NULL) {
0338 nr_node_put(nr_node);
0339 return -EINVAL;
0340 }
0341
0342 nr_node_lock(nr_node);
0343 for (i = 0; i < nr_node->count; i++) {
0344 if (nr_node->routes[i].neighbour == nr_neigh) {
0345 nr_neigh->count--;
0346 nr_neigh_put(nr_neigh);
0347
0348 if (nr_neigh->count == 0 && !nr_neigh->locked)
0349 nr_remove_neigh(nr_neigh);
0350 nr_neigh_put(nr_neigh);
0351
0352 nr_node->count--;
0353
0354 if (nr_node->count == 0) {
0355 nr_remove_node(nr_node);
0356 } else {
0357 switch (i) {
0358 case 0:
0359 nr_node->routes[0] = nr_node->routes[1];
0360 fallthrough;
0361 case 1:
0362 nr_node->routes[1] = nr_node->routes[2];
0363 fallthrough;
0364 case 2:
0365 break;
0366 }
0367 nr_node_put(nr_node);
0368 }
0369 nr_node_unlock(nr_node);
0370
0371 return 0;
0372 }
0373 }
0374 nr_neigh_put(nr_neigh);
0375 nr_node_unlock(nr_node);
0376 nr_node_put(nr_node);
0377
0378 return -EINVAL;
0379 }
0380
0381
0382
0383
0384 static int __must_check nr_add_neigh(ax25_address *callsign,
0385 ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
0386 {
0387 struct nr_neigh *nr_neigh;
0388
0389 nr_neigh = nr_neigh_get_dev(callsign, dev);
0390 if (nr_neigh) {
0391 nr_neigh->quality = quality;
0392 nr_neigh->locked = 1;
0393 nr_neigh_put(nr_neigh);
0394 return 0;
0395 }
0396
0397 if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
0398 return -ENOMEM;
0399
0400 nr_neigh->callsign = *callsign;
0401 nr_neigh->digipeat = NULL;
0402 nr_neigh->ax25 = NULL;
0403 nr_neigh->dev = dev;
0404 nr_neigh->quality = quality;
0405 nr_neigh->locked = 1;
0406 nr_neigh->count = 0;
0407 nr_neigh->number = nr_neigh_no++;
0408 nr_neigh->failed = 0;
0409 refcount_set(&nr_neigh->refcount, 1);
0410
0411 if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
0412 nr_neigh->digipeat = kmemdup(ax25_digi, sizeof(*ax25_digi),
0413 GFP_KERNEL);
0414 if (nr_neigh->digipeat == NULL) {
0415 kfree(nr_neigh);
0416 return -ENOMEM;
0417 }
0418 }
0419
0420 spin_lock_bh(&nr_neigh_list_lock);
0421 hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list);
0422
0423 spin_unlock_bh(&nr_neigh_list_lock);
0424
0425 return 0;
0426 }
0427
0428
0429
0430
0431
0432 static int nr_del_neigh(ax25_address *callsign, struct net_device *dev, unsigned int quality)
0433 {
0434 struct nr_neigh *nr_neigh;
0435
0436 nr_neigh = nr_neigh_get_dev(callsign, dev);
0437
0438 if (nr_neigh == NULL) return -EINVAL;
0439
0440 nr_neigh->quality = quality;
0441 nr_neigh->locked = 0;
0442
0443 if (nr_neigh->count == 0)
0444 nr_remove_neigh(nr_neigh);
0445 nr_neigh_put(nr_neigh);
0446
0447 return 0;
0448 }
0449
0450
0451
0452
0453
0454
0455 static int nr_dec_obs(void)
0456 {
0457 struct nr_neigh *nr_neigh;
0458 struct nr_node *s;
0459 struct hlist_node *nodet;
0460 int i;
0461
0462 spin_lock_bh(&nr_node_list_lock);
0463 nr_node_for_each_safe(s, nodet, &nr_node_list) {
0464 nr_node_lock(s);
0465 for (i = 0; i < s->count; i++) {
0466 switch (s->routes[i].obs_count) {
0467 case 0:
0468 break;
0469
0470 case 1:
0471 nr_neigh = s->routes[i].neighbour;
0472
0473 nr_neigh->count--;
0474 nr_neigh_put(nr_neigh);
0475
0476 if (nr_neigh->count == 0 && !nr_neigh->locked)
0477 nr_remove_neigh(nr_neigh);
0478
0479 s->count--;
0480
0481 switch (i) {
0482 case 0:
0483 s->routes[0] = s->routes[1];
0484 fallthrough;
0485 case 1:
0486 s->routes[1] = s->routes[2];
0487 break;
0488 case 2:
0489 break;
0490 }
0491 break;
0492
0493 default:
0494 s->routes[i].obs_count--;
0495 break;
0496
0497 }
0498 }
0499
0500 if (s->count <= 0)
0501 nr_remove_node_locked(s);
0502 nr_node_unlock(s);
0503 }
0504 spin_unlock_bh(&nr_node_list_lock);
0505
0506 return 0;
0507 }
0508
0509
0510
0511
0512 void nr_rt_device_down(struct net_device *dev)
0513 {
0514 struct nr_neigh *s;
0515 struct hlist_node *nodet, *node2t;
0516 struct nr_node *t;
0517 int i;
0518
0519 spin_lock_bh(&nr_neigh_list_lock);
0520 nr_neigh_for_each_safe(s, nodet, &nr_neigh_list) {
0521 if (s->dev == dev) {
0522 spin_lock_bh(&nr_node_list_lock);
0523 nr_node_for_each_safe(t, node2t, &nr_node_list) {
0524 nr_node_lock(t);
0525 for (i = 0; i < t->count; i++) {
0526 if (t->routes[i].neighbour == s) {
0527 t->count--;
0528
0529 switch (i) {
0530 case 0:
0531 t->routes[0] = t->routes[1];
0532 fallthrough;
0533 case 1:
0534 t->routes[1] = t->routes[2];
0535 break;
0536 case 2:
0537 break;
0538 }
0539 }
0540 }
0541
0542 if (t->count <= 0)
0543 nr_remove_node_locked(t);
0544 nr_node_unlock(t);
0545 }
0546 spin_unlock_bh(&nr_node_list_lock);
0547
0548 nr_remove_neigh_locked(s);
0549 }
0550 }
0551 spin_unlock_bh(&nr_neigh_list_lock);
0552 }
0553
0554
0555
0556
0557
0558 static struct net_device *nr_ax25_dev_get(char *devname)
0559 {
0560 struct net_device *dev;
0561
0562 if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
0563 return NULL;
0564
0565 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
0566 return dev;
0567
0568 dev_put(dev);
0569 return NULL;
0570 }
0571
0572
0573
0574
0575 struct net_device *nr_dev_first(void)
0576 {
0577 struct net_device *dev, *first = NULL;
0578
0579 rcu_read_lock();
0580 for_each_netdev_rcu(&init_net, dev) {
0581 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM)
0582 if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
0583 first = dev;
0584 }
0585 dev_hold(first);
0586 rcu_read_unlock();
0587
0588 return first;
0589 }
0590
0591
0592
0593
0594 struct net_device *nr_dev_get(ax25_address *addr)
0595 {
0596 struct net_device *dev;
0597
0598 rcu_read_lock();
0599 for_each_netdev_rcu(&init_net, dev) {
0600 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM &&
0601 ax25cmp(addr, (const ax25_address *)dev->dev_addr) == 0) {
0602 dev_hold(dev);
0603 goto out;
0604 }
0605 }
0606 dev = NULL;
0607 out:
0608 rcu_read_unlock();
0609 return dev;
0610 }
0611
0612 static ax25_digi *nr_call_to_digi(ax25_digi *digi, int ndigis,
0613 ax25_address *digipeaters)
0614 {
0615 int i;
0616
0617 if (ndigis == 0)
0618 return NULL;
0619
0620 for (i = 0; i < ndigis; i++) {
0621 digi->calls[i] = digipeaters[i];
0622 digi->repeated[i] = 0;
0623 }
0624
0625 digi->ndigi = ndigis;
0626 digi->lastrepeat = -1;
0627
0628 return digi;
0629 }
0630
0631
0632
0633
0634 int nr_rt_ioctl(unsigned int cmd, void __user *arg)
0635 {
0636 struct nr_route_struct nr_route;
0637 struct net_device *dev;
0638 ax25_digi digi;
0639 int ret;
0640
0641 switch (cmd) {
0642 case SIOCADDRT:
0643 if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
0644 return -EFAULT;
0645 if (nr_route.ndigis > AX25_MAX_DIGIS)
0646 return -EINVAL;
0647 if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
0648 return -EINVAL;
0649 switch (nr_route.type) {
0650 case NETROM_NODE:
0651 if (strnlen(nr_route.mnemonic, 7) == 7) {
0652 ret = -EINVAL;
0653 break;
0654 }
0655
0656 ret = nr_add_node(&nr_route.callsign,
0657 nr_route.mnemonic,
0658 &nr_route.neighbour,
0659 nr_call_to_digi(&digi, nr_route.ndigis,
0660 nr_route.digipeaters),
0661 dev, nr_route.quality,
0662 nr_route.obs_count);
0663 break;
0664 case NETROM_NEIGH:
0665 ret = nr_add_neigh(&nr_route.callsign,
0666 nr_call_to_digi(&digi, nr_route.ndigis,
0667 nr_route.digipeaters),
0668 dev, nr_route.quality);
0669 break;
0670 default:
0671 ret = -EINVAL;
0672 }
0673 dev_put(dev);
0674 return ret;
0675
0676 case SIOCDELRT:
0677 if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
0678 return -EFAULT;
0679 if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
0680 return -EINVAL;
0681 switch (nr_route.type) {
0682 case NETROM_NODE:
0683 ret = nr_del_node(&nr_route.callsign,
0684 &nr_route.neighbour, dev);
0685 break;
0686 case NETROM_NEIGH:
0687 ret = nr_del_neigh(&nr_route.callsign,
0688 dev, nr_route.quality);
0689 break;
0690 default:
0691 ret = -EINVAL;
0692 }
0693 dev_put(dev);
0694 return ret;
0695
0696 case SIOCNRDECOBS:
0697 return nr_dec_obs();
0698
0699 default:
0700 return -EINVAL;
0701 }
0702
0703 return 0;
0704 }
0705
0706
0707
0708
0709
0710 void nr_link_failed(ax25_cb *ax25, int reason)
0711 {
0712 struct nr_neigh *s, *nr_neigh = NULL;
0713 struct nr_node *nr_node = NULL;
0714
0715 spin_lock_bh(&nr_neigh_list_lock);
0716 nr_neigh_for_each(s, &nr_neigh_list) {
0717 if (s->ax25 == ax25) {
0718 nr_neigh_hold(s);
0719 nr_neigh = s;
0720 break;
0721 }
0722 }
0723 spin_unlock_bh(&nr_neigh_list_lock);
0724
0725 if (nr_neigh == NULL)
0726 return;
0727
0728 nr_neigh->ax25 = NULL;
0729 ax25_cb_put(ax25);
0730
0731 if (++nr_neigh->failed < sysctl_netrom_link_fails_count) {
0732 nr_neigh_put(nr_neigh);
0733 return;
0734 }
0735 spin_lock_bh(&nr_node_list_lock);
0736 nr_node_for_each(nr_node, &nr_node_list) {
0737 nr_node_lock(nr_node);
0738 if (nr_node->which < nr_node->count &&
0739 nr_node->routes[nr_node->which].neighbour == nr_neigh)
0740 nr_node->which++;
0741 nr_node_unlock(nr_node);
0742 }
0743 spin_unlock_bh(&nr_node_list_lock);
0744 nr_neigh_put(nr_neigh);
0745 }
0746
0747
0748
0749
0750
0751 int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
0752 {
0753 ax25_address *nr_src, *nr_dest;
0754 struct nr_neigh *nr_neigh;
0755 struct nr_node *nr_node;
0756 struct net_device *dev;
0757 unsigned char *dptr;
0758 ax25_cb *ax25s;
0759 int ret;
0760 struct sk_buff *skbn;
0761
0762
0763 nr_src = (ax25_address *)(skb->data + 0);
0764 nr_dest = (ax25_address *)(skb->data + 7);
0765
0766 if (ax25 != NULL) {
0767 ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
0768 ax25->ax25_dev->dev, 0,
0769 sysctl_netrom_obsolescence_count_initialiser);
0770 if (ret)
0771 return ret;
0772 }
0773
0774 if ((dev = nr_dev_get(nr_dest)) != NULL) {
0775 if (ax25 == NULL)
0776 ret = nr_loopback_queue(skb);
0777 else
0778 ret = nr_rx_frame(skb, dev);
0779 dev_put(dev);
0780 return ret;
0781 }
0782
0783 if (!sysctl_netrom_routing_control && ax25 != NULL)
0784 return 0;
0785
0786
0787 if (skb->data[14] == 1) {
0788 return 0;
0789 }
0790
0791 nr_node = nr_node_get(nr_dest);
0792 if (nr_node == NULL)
0793 return 0;
0794 nr_node_lock(nr_node);
0795
0796 if (nr_node->which >= nr_node->count) {
0797 nr_node_unlock(nr_node);
0798 nr_node_put(nr_node);
0799 return 0;
0800 }
0801
0802 nr_neigh = nr_node->routes[nr_node->which].neighbour;
0803
0804 if ((dev = nr_dev_first()) == NULL) {
0805 nr_node_unlock(nr_node);
0806 nr_node_put(nr_node);
0807 return 0;
0808 }
0809
0810
0811
0812
0813 if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) {
0814 nr_node_unlock(nr_node);
0815 nr_node_put(nr_node);
0816 dev_put(dev);
0817 return 0;
0818 }
0819 kfree_skb(skb);
0820 skb=skbn;
0821 skb->data[14]--;
0822
0823 dptr = skb_push(skb, 1);
0824 *dptr = AX25_P_NETROM;
0825
0826 ax25s = nr_neigh->ax25;
0827 nr_neigh->ax25 = ax25_send_frame(skb, 256,
0828 (const ax25_address *)dev->dev_addr,
0829 &nr_neigh->callsign,
0830 nr_neigh->digipeat, nr_neigh->dev);
0831 if (ax25s)
0832 ax25_cb_put(ax25s);
0833
0834 dev_put(dev);
0835 ret = (nr_neigh->ax25 != NULL);
0836 nr_node_unlock(nr_node);
0837 nr_node_put(nr_node);
0838
0839 return ret;
0840 }
0841
0842 #ifdef CONFIG_PROC_FS
0843
0844 static void *nr_node_start(struct seq_file *seq, loff_t *pos)
0845 __acquires(&nr_node_list_lock)
0846 {
0847 spin_lock_bh(&nr_node_list_lock);
0848 return seq_hlist_start_head(&nr_node_list, *pos);
0849 }
0850
0851 static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos)
0852 {
0853 return seq_hlist_next(v, &nr_node_list, pos);
0854 }
0855
0856 static void nr_node_stop(struct seq_file *seq, void *v)
0857 __releases(&nr_node_list_lock)
0858 {
0859 spin_unlock_bh(&nr_node_list_lock);
0860 }
0861
0862 static int nr_node_show(struct seq_file *seq, void *v)
0863 {
0864 char buf[11];
0865 int i;
0866
0867 if (v == SEQ_START_TOKEN)
0868 seq_puts(seq,
0869 "callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
0870 else {
0871 struct nr_node *nr_node = hlist_entry(v, struct nr_node,
0872 node_node);
0873
0874 nr_node_lock(nr_node);
0875 seq_printf(seq, "%-9s %-7s %d %d",
0876 ax2asc(buf, &nr_node->callsign),
0877 (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
0878 nr_node->which + 1,
0879 nr_node->count);
0880
0881 for (i = 0; i < nr_node->count; i++) {
0882 seq_printf(seq, " %3d %d %05d",
0883 nr_node->routes[i].quality,
0884 nr_node->routes[i].obs_count,
0885 nr_node->routes[i].neighbour->number);
0886 }
0887 nr_node_unlock(nr_node);
0888
0889 seq_puts(seq, "\n");
0890 }
0891 return 0;
0892 }
0893
0894 const struct seq_operations nr_node_seqops = {
0895 .start = nr_node_start,
0896 .next = nr_node_next,
0897 .stop = nr_node_stop,
0898 .show = nr_node_show,
0899 };
0900
0901 static void *nr_neigh_start(struct seq_file *seq, loff_t *pos)
0902 __acquires(&nr_neigh_list_lock)
0903 {
0904 spin_lock_bh(&nr_neigh_list_lock);
0905 return seq_hlist_start_head(&nr_neigh_list, *pos);
0906 }
0907
0908 static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
0909 {
0910 return seq_hlist_next(v, &nr_neigh_list, pos);
0911 }
0912
0913 static void nr_neigh_stop(struct seq_file *seq, void *v)
0914 __releases(&nr_neigh_list_lock)
0915 {
0916 spin_unlock_bh(&nr_neigh_list_lock);
0917 }
0918
0919 static int nr_neigh_show(struct seq_file *seq, void *v)
0920 {
0921 char buf[11];
0922 int i;
0923
0924 if (v == SEQ_START_TOKEN)
0925 seq_puts(seq, "addr callsign dev qual lock count failed digipeaters\n");
0926 else {
0927 struct nr_neigh *nr_neigh;
0928
0929 nr_neigh = hlist_entry(v, struct nr_neigh, neigh_node);
0930 seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d",
0931 nr_neigh->number,
0932 ax2asc(buf, &nr_neigh->callsign),
0933 nr_neigh->dev ? nr_neigh->dev->name : "???",
0934 nr_neigh->quality,
0935 nr_neigh->locked,
0936 nr_neigh->count,
0937 nr_neigh->failed);
0938
0939 if (nr_neigh->digipeat != NULL) {
0940 for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
0941 seq_printf(seq, " %s",
0942 ax2asc(buf, &nr_neigh->digipeat->calls[i]));
0943 }
0944
0945 seq_puts(seq, "\n");
0946 }
0947 return 0;
0948 }
0949
0950 const struct seq_operations nr_neigh_seqops = {
0951 .start = nr_neigh_start,
0952 .next = nr_neigh_next,
0953 .stop = nr_neigh_stop,
0954 .show = nr_neigh_show,
0955 };
0956 #endif
0957
0958
0959
0960
0961 void nr_rt_free(void)
0962 {
0963 struct nr_neigh *s = NULL;
0964 struct nr_node *t = NULL;
0965 struct hlist_node *nodet;
0966
0967 spin_lock_bh(&nr_neigh_list_lock);
0968 spin_lock_bh(&nr_node_list_lock);
0969 nr_node_for_each_safe(t, nodet, &nr_node_list) {
0970 nr_node_lock(t);
0971 nr_remove_node_locked(t);
0972 nr_node_unlock(t);
0973 }
0974 nr_neigh_for_each_safe(s, nodet, &nr_neigh_list) {
0975 while(s->count) {
0976 s->count--;
0977 nr_neigh_put(s);
0978 }
0979 nr_remove_neigh_locked(s);
0980 }
0981 spin_unlock_bh(&nr_node_list_lock);
0982 spin_unlock_bh(&nr_neigh_list_lock);
0983 }