^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) Terry Dawson VK2KTJ (terry@animats.net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/sockios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <net/ax25.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <net/tcp_states.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/termios.h> /* For TIOCINQ/OUTQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <net/rose.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static unsigned int rose_neigh_no = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static struct rose_node *rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static DEFINE_SPINLOCK(rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static struct rose_neigh *rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static DEFINE_SPINLOCK(rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static struct rose_route *rose_route_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static DEFINE_SPINLOCK(rose_route_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct rose_neigh *rose_loopback_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * Add a new route to a node, and in the process add the node and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * neighbour if it is new.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int __must_check rose_add_node(struct rose_route_struct *rose_route,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct rose_node *rose_node, *rose_tmpn, *rose_tmpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct rose_neigh *rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int i, res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) spin_lock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) spin_lock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) rose_node = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) while (rose_node != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if ((rose_node->mask == rose_route->mask) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) (rosecmpm(&rose_route->address, &rose_node->address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) rose_route->mask) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) rose_node = rose_node->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (rose_node != NULL && rose_node->loopback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) rose_neigh = rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) while (rose_neigh != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (ax25cmp(&rose_route->neighbour,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) &rose_neigh->callsign) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) rose_neigh->dev == dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) rose_neigh = rose_neigh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (rose_neigh == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) rose_neigh = kmalloc(sizeof(*rose_neigh), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (rose_neigh == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) res = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) rose_neigh->callsign = rose_route->neighbour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) rose_neigh->digipeat = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) rose_neigh->ax25 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) rose_neigh->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) rose_neigh->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) rose_neigh->use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) rose_neigh->dce_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) rose_neigh->loopback = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) rose_neigh->number = rose_neigh_no++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) rose_neigh->restarted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) skb_queue_head_init(&rose_neigh->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) timer_setup(&rose_neigh->ftimer, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) timer_setup(&rose_neigh->t0timer, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (rose_route->ndigis != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) rose_neigh->digipeat =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) kmalloc(sizeof(ax25_digi), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (rose_neigh->digipeat == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) kfree(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) res = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) rose_neigh->digipeat->ndigi = rose_route->ndigis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) rose_neigh->digipeat->lastrepeat = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) for (i = 0; i < rose_route->ndigis; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) rose_neigh->digipeat->calls[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) rose_route->digipeaters[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) rose_neigh->digipeat->repeated[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) rose_neigh->next = rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) rose_neigh_list = rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * This is a new node to be inserted into the list. Find where it needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * to be inserted into the list, and insert it. We want to be sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * to order the list in descending order of mask size to ensure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * later when we are searching this list the first match will be the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * best match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (rose_node == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) rose_tmpn = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) rose_tmpp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) while (rose_tmpn != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (rose_tmpn->mask > rose_route->mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) rose_tmpp = rose_tmpn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) rose_tmpn = rose_tmpn->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* create new node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) rose_node = kmalloc(sizeof(*rose_node), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (rose_node == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) res = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) rose_node->address = rose_route->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) rose_node->mask = rose_route->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) rose_node->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) rose_node->loopback = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) rose_node->neighbour[0] = rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (rose_tmpn == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (rose_tmpp == NULL) { /* Empty list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) rose_node_list = rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) rose_node->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) rose_tmpp->next = rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) rose_node->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (rose_tmpp == NULL) { /* 1st node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rose_node->next = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) rose_node_list = rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) rose_tmpp->next = rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) rose_node->next = rose_tmpn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) rose_neigh->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* We have space, slot it in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (rose_node->count < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) rose_node->neighbour[rose_node->count] = rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) rose_node->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) rose_neigh->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) spin_unlock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) spin_unlock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * Caller is holding rose_node_list_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static void rose_remove_node(struct rose_node *rose_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct rose_node *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if ((s = rose_node_list) == rose_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) rose_node_list = rose_node->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) kfree(rose_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) while (s != NULL && s->next != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (s->next == rose_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) s->next = rose_node->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) kfree(rose_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) s = s->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * Caller is holding rose_neigh_list_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static void rose_remove_neigh(struct rose_neigh *rose_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct rose_neigh *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rose_stop_ftimer(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) rose_stop_t0timer(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) skb_queue_purge(&rose_neigh->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if ((s = rose_neigh_list) == rose_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) rose_neigh_list = rose_neigh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (rose_neigh->ax25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ax25_cb_put(rose_neigh->ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) kfree(rose_neigh->digipeat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) kfree(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) while (s != NULL && s->next != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (s->next == rose_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) s->next = rose_neigh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (rose_neigh->ax25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ax25_cb_put(rose_neigh->ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) kfree(rose_neigh->digipeat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) kfree(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) s = s->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * Caller is holding rose_route_list_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static void rose_remove_route(struct rose_route *rose_route)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct rose_route *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (rose_route->neigh1 != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) rose_route->neigh1->use--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (rose_route->neigh2 != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) rose_route->neigh2->use--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if ((s = rose_route_list) == rose_route) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) rose_route_list = rose_route->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) kfree(rose_route);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) while (s != NULL && s->next != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (s->next == rose_route) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) s->next = rose_route->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) kfree(rose_route);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) s = s->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * "Delete" a node. Strictly speaking remove a route to a node. The node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * is only deleted if no routes are left to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static int rose_del_node(struct rose_route_struct *rose_route,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct rose_node *rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct rose_neigh *rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) spin_lock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) spin_lock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) rose_node = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) while (rose_node != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if ((rose_node->mask == rose_route->mask) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) (rosecmpm(&rose_route->address, &rose_node->address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) rose_route->mask) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) rose_node = rose_node->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (rose_node == NULL || rose_node->loopback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) rose_neigh = rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) while (rose_neigh != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (ax25cmp(&rose_route->neighbour,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) &rose_neigh->callsign) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) rose_neigh->dev == dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) rose_neigh = rose_neigh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (rose_neigh == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) for (i = 0; i < rose_node->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (rose_node->neighbour[i] == rose_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) rose_neigh->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (rose_neigh->count == 0 && rose_neigh->use == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) rose_remove_neigh(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) rose_node->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (rose_node->count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rose_remove_node(rose_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) rose_node->neighbour[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) rose_node->neighbour[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) rose_node->neighbour[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) rose_node->neighbour[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) spin_unlock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) spin_unlock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * Add the loopback neighbour.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) void rose_add_loopback_neigh(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct rose_neigh *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!rose_loopback_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) sn = rose_loopback_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sn->callsign = null_ax25_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) sn->digipeat = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) sn->ax25 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) sn->dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) sn->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) sn->use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) sn->dce_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) sn->loopback = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) sn->number = rose_neigh_no++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) sn->restarted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) skb_queue_head_init(&sn->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) timer_setup(&sn->ftimer, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) timer_setup(&sn->t0timer, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) spin_lock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) sn->next = rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) rose_neigh_list = sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) spin_unlock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * Add a loopback node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int rose_add_loopback_node(rose_address *address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct rose_node *rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) spin_lock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) rose_node = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) while (rose_node != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if ((rose_node->mask == 10) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) (rosecmpm(address, &rose_node->address, 10) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) rose_node->loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) rose_node = rose_node->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (rose_node != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if ((rose_node = kmalloc(sizeof(*rose_node), GFP_ATOMIC)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) rose_node->address = *address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) rose_node->mask = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) rose_node->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) rose_node->loopback = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) rose_node->neighbour[0] = rose_loopback_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Insert at the head of list. Address is always mask=10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) rose_node->next = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) rose_node_list = rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) rose_loopback_neigh->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) spin_unlock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * Delete a loopback node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) void rose_del_loopback_node(rose_address *address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct rose_node *rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) spin_lock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) rose_node = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) while (rose_node != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if ((rose_node->mask == 10) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) (rosecmpm(address, &rose_node->address, 10) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) rose_node->loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) rose_node = rose_node->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (rose_node == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) rose_remove_node(rose_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) rose_loopback_neigh->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) spin_unlock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * A device has been removed. Remove its routes and neighbours.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) void rose_rt_device_down(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct rose_neigh *s, *rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct rose_node *t, *rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) spin_lock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) spin_lock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) rose_neigh = rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) while (rose_neigh != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) s = rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) rose_neigh = rose_neigh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (s->dev != dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) rose_node = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) while (rose_node != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) t = rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) rose_node = rose_node->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) for (i = 0; i < t->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (t->neighbour[i] != s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) t->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) t->neighbour[0] = t->neighbour[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) t->neighbour[1] = t->neighbour[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (t->count <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) rose_remove_node(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) rose_remove_neigh(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) spin_unlock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) spin_unlock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) #if 0 /* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * A device has been removed. Remove its links.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) void rose_route_device_down(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct rose_route *s, *rose_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) spin_lock_bh(&rose_route_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) rose_route = rose_route_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) while (rose_route != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) s = rose_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) rose_route = rose_route->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (s->neigh1->dev == dev || s->neigh2->dev == dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) rose_remove_route(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) spin_unlock_bh(&rose_route_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * Clear all nodes and neighbours out, except for neighbours with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * active connections going through them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * Do not clear loopback neighbour and nodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int rose_clear_routes(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct rose_neigh *s, *rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct rose_node *t, *rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) spin_lock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) spin_lock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) rose_neigh = rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) rose_node = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) while (rose_node != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) t = rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) rose_node = rose_node->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (!t->loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) rose_remove_node(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) while (rose_neigh != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) s = rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) rose_neigh = rose_neigh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (s->use == 0 && !s->loopback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) s->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) rose_remove_neigh(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) spin_unlock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) spin_unlock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * Check that the device given is a valid AX.25 interface that is "up".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * called with RTNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static struct net_device *rose_ax25_dev_find(char *devname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if ((dev = __dev_get_by_name(&init_net, devname)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * Find the first active ROSE device, usually "rose0".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct net_device *rose_dev_first(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct net_device *dev, *first = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) for_each_netdev_rcu(&init_net, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) first = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * Find the ROSE device for the given address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct net_device *rose_dev_get(rose_address *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) for_each_netdev_rcu(&init_net, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) dev_hold(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static int rose_dev_exists(rose_address *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) for_each_netdev_rcu(&init_net, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return dev != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct rose_route *rose_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) for (rose_route = rose_route_list; rose_route != NULL; rose_route = rose_route->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if ((rose_route->neigh1 == neigh && rose_route->lci1 == lci) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) (rose_route->neigh2 == neigh && rose_route->lci2 == lci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return rose_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * Find a neighbour or a route given a ROSE address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) unsigned char *diagnostic, int route_frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct rose_neigh *res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct rose_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) int failed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (!route_frame) spin_lock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) for (node = rose_node_list; node != NULL; node = node->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (rosecmpm(addr, &node->address, node->mask) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) for (i = 0; i < node->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (node->neighbour[i]->restarted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) res = node->neighbour[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (!route_frame) { /* connect request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) for (node = rose_node_list; node != NULL; node = node->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (rosecmpm(addr, &node->address, node->mask) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) for (i = 0; i < node->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (!rose_ftimer_running(node->neighbour[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) res = node->neighbour[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) failed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (failed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) *cause = ROSE_OUT_OF_ORDER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) *diagnostic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) *cause = ROSE_NOT_OBTAINABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) *diagnostic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!route_frame) spin_unlock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * Handle the ioctls that control the routing functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) int rose_rt_ioctl(unsigned int cmd, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct rose_route_struct rose_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) case SIOCADDRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (rose_route.ndigis > AX25_MAX_DIGIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) err = rose_add_node(&rose_route, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) case SIOCDELRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) err = rose_del_node(&rose_route, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case SIOCRSCLRRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return rose_clear_routes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct rose_route *rose_route, *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) rose_neigh->restarted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) rose_stop_t0timer(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) rose_start_ftimer(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) skb_queue_purge(&rose_neigh->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) spin_lock_bh(&rose_route_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) rose_route = rose_route_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) while (rose_route != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if ((rose_route->neigh1 == rose_neigh && rose_route->neigh2 == rose_neigh) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) (rose_route->neigh1 == rose_neigh && rose_route->neigh2 == NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) (rose_route->neigh2 == rose_neigh && rose_route->neigh1 == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) s = rose_route->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) rose_remove_route(rose_route);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) rose_route = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (rose_route->neigh1 == rose_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) rose_route->neigh1->use--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) rose_route->neigh1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (rose_route->neigh2 == rose_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) rose_route->neigh2->use--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) rose_route->neigh2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) rose_route = rose_route->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) spin_unlock_bh(&rose_route_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * A level 2 link has timed out, therefore it appears to be a poor link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * then don't use that neighbour until it is reset. Blow away all through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * routes and connections using this route.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) void rose_link_failed(ax25_cb *ax25, int reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct rose_neigh *rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) spin_lock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) rose_neigh = rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) while (rose_neigh != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (rose_neigh->ax25 == ax25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) rose_neigh = rose_neigh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (rose_neigh != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) rose_neigh->ax25 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ax25_cb_put(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) rose_del_route_by_neigh(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) rose_kill_by_neigh(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) spin_unlock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * A device has been "downed" remove its link status. Blow away all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * through routes and connections that use this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) void rose_link_device_down(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) struct rose_neigh *rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (rose_neigh->dev == dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) rose_del_route_by_neigh(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) rose_kill_by_neigh(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * Route a frame to an appropriate AX.25 connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * A NULL ax25_cb indicates an internally generated frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct rose_neigh *rose_neigh, *new_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct rose_route *rose_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) struct rose_facilities_struct facilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) rose_address *src_addr, *dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) unsigned short frametype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) unsigned int lci, new_lci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) unsigned char cause, diagnostic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) char buf[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (skb->len < ROSE_MIN_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (!ax25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return rose_loopback_queue(skb, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) frametype = skb->data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (frametype == ROSE_CALL_REQUEST &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ROSE_CALL_REQ_ADDR_LEN_VAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) src_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) spin_lock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) spin_lock_bh(&rose_route_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) rose_neigh = rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) while (rose_neigh != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (ax25cmp(&ax25->dest_addr, &rose_neigh->callsign) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) ax25->ax25_dev->dev == rose_neigh->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) rose_neigh = rose_neigh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (rose_neigh == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) printk("rose_route : unknown neighbour or device %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ax2asc(buf, &ax25->dest_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * Obviously the link is working, halt the ftimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) rose_stop_ftimer(rose_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * LCI of zero is always for us, and its always a restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (lci == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) rose_link_rx_restart(skb, rose_neigh, frametype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * Find an existing socket.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if ((sk = rose_find_socket(lci, rose_neigh)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (frametype == ROSE_CALL_REQUEST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct rose_sock *rose = rose_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) /* Remove an existing unused socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) rose_clear_queues(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) rose->cause = ROSE_NETWORK_CONGESTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) rose->diagnostic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) rose->neighbour->use--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) rose->neighbour = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) rose->lci = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) rose->state = ROSE_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) sk->sk_state = TCP_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) sk->sk_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) sk->sk_shutdown |= SEND_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (!sock_flag(sk, SOCK_DEAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) sk->sk_state_change(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) sock_set_flag(sk, SOCK_DEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) res = rose_process_rx_frame(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * Is is a Call Request and is it for us ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (frametype == ROSE_CALL_REQUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if ((dev = rose_dev_get(dest_addr)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) res = rose_rx_call_request(skb, dev, rose_neigh, lci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (!sysctl_rose_routing_control) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) rose_transmit_clear_request(rose_neigh, lci, ROSE_NOT_OBTAINABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * Route it to the next in line if we have an entry for it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) rose_route = rose_route_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) while (rose_route != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (rose_route->lci1 == lci &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) rose_route->neigh1 == rose_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (frametype == ROSE_CALL_REQUEST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* F6FBB - Remove an existing unused route */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) rose_remove_route(rose_route);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) } else if (rose_route->neigh2 != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) skb->data[0] &= 0xF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) skb->data[1] = (rose_route->lci2 >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) rose_transmit_link(skb, rose_route->neigh2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (frametype == ROSE_CLEAR_CONFIRMATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) rose_remove_route(rose_route);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (frametype == ROSE_CLEAR_CONFIRMATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) rose_remove_route(rose_route);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (rose_route->lci2 == lci &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) rose_route->neigh2 == rose_neigh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (frametype == ROSE_CALL_REQUEST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /* F6FBB - Remove an existing unused route */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) rose_remove_route(rose_route);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) } else if (rose_route->neigh1 != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) skb->data[0] &= 0xF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) skb->data[0] |= (rose_route->lci1 >> 8) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) skb->data[1] = (rose_route->lci1 >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) rose_transmit_link(skb, rose_route->neigh1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (frametype == ROSE_CLEAR_CONFIRMATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) rose_remove_route(rose_route);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (frametype == ROSE_CLEAR_CONFIRMATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) rose_remove_route(rose_route);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) rose_route = rose_route->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * We know that:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * 1. The frame isn't for us,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * 2. It isn't "owned" by any existing route.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (frametype != ROSE_CALL_REQUEST) { /* XXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) &facilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * Check for routing loops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) rose_route = rose_route_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) while (rose_route != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (rose_route->rand == facilities.rand &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) rosecmp(src_addr, &rose_route->src_addr) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) ax25cmp(&facilities.dest_call, &rose_route->src_call) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) ax25cmp(&facilities.source_call, &rose_route->dest_call) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) rose_transmit_clear_request(rose_neigh, lci, ROSE_NOT_OBTAINABLE, 120);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) rose_route = rose_route->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic, 1)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if ((new_lci = rose_new_lci(new_neigh)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) rose_route->lci1 = lci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) rose_route->src_addr = *src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) rose_route->dest_addr = *dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) rose_route->src_call = facilities.dest_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) rose_route->dest_call = facilities.source_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) rose_route->rand = facilities.rand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) rose_route->neigh1 = rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) rose_route->lci2 = new_lci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) rose_route->neigh2 = new_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) rose_route->neigh1->use++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) rose_route->neigh2->use++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) rose_route->next = rose_route_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) rose_route_list = rose_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) skb->data[0] &= 0xF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) skb->data[1] = (rose_route->lci2 >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) rose_transmit_link(skb, rose_route->neigh2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) spin_unlock_bh(&rose_route_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) spin_unlock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static void *rose_node_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) __acquires(rose_node_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) struct rose_node *rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) int i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) spin_lock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (*pos == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return SEQ_START_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) for (rose_node = rose_node_list; rose_node && i < *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) rose_node = rose_node->next, ++i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return (i == *pos) ? rose_node : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) static void *rose_node_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) return (v == SEQ_START_TOKEN) ? rose_node_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) : ((struct rose_node *)v)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static void rose_node_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) __releases(rose_node_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) spin_unlock_bh(&rose_node_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static int rose_node_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) char rsbuf[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (v == SEQ_START_TOKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) seq_puts(seq, "address mask n neigh neigh neigh\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) const struct rose_node *rose_node = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) /* if (rose_node->loopback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) seq_printf(seq, "%-10s %04d 1 loopback\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) rose2asc(rsbuf, &rose_node->address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) rose_node->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) } else { */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) seq_printf(seq, "%-10s %04d %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) rose2asc(rsbuf, &rose_node->address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) rose_node->mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) rose_node->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) for (i = 0; i < rose_node->count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) seq_printf(seq, " %05d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) rose_node->neighbour[i]->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) seq_puts(seq, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /* } */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) const struct seq_operations rose_node_seqops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) .start = rose_node_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) .next = rose_node_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) .stop = rose_node_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .show = rose_node_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) static void *rose_neigh_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) __acquires(rose_neigh_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct rose_neigh *rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) int i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) spin_lock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (*pos == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return SEQ_START_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) for (rose_neigh = rose_neigh_list; rose_neigh && i < *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) rose_neigh = rose_neigh->next, ++i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return (i == *pos) ? rose_neigh : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) static void *rose_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) return (v == SEQ_START_TOKEN) ? rose_neigh_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) : ((struct rose_neigh *)v)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static void rose_neigh_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) __releases(rose_neigh_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) spin_unlock_bh(&rose_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) static int rose_neigh_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) char buf[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (v == SEQ_START_TOKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) "addr callsign dev count use mode restart t0 tf digipeaters\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) struct rose_neigh *rose_neigh = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) /* if (!rose_neigh->loopback) { */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) seq_printf(seq, "%05d %-9s %-4s %3d %3d %3s %3s %3lu %3lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) rose_neigh->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) rose_neigh->dev ? rose_neigh->dev->name : "???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) rose_neigh->count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) rose_neigh->use,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) (rose_neigh->dce_mode) ? "DCE" : "DTE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) (rose_neigh->restarted) ? "yes" : "no",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) ax25_display_timer(&rose_neigh->t0timer) / HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) ax25_display_timer(&rose_neigh->ftimer) / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (rose_neigh->digipeat != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) for (i = 0; i < rose_neigh->digipeat->ndigi; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) seq_printf(seq, " %s", ax2asc(buf, &rose_neigh->digipeat->calls[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) seq_puts(seq, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) const struct seq_operations rose_neigh_seqops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .start = rose_neigh_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .next = rose_neigh_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .stop = rose_neigh_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) .show = rose_neigh_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) static void *rose_route_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) __acquires(rose_route_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct rose_route *rose_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) int i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) spin_lock_bh(&rose_route_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (*pos == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return SEQ_START_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) for (rose_route = rose_route_list; rose_route && i < *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) rose_route = rose_route->next, ++i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return (i == *pos) ? rose_route : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) static void *rose_route_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return (v == SEQ_START_TOKEN) ? rose_route_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) : ((struct rose_route *)v)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static void rose_route_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) __releases(rose_route_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) spin_unlock_bh(&rose_route_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static int rose_route_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) char buf[11], rsbuf[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (v == SEQ_START_TOKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) "lci address callsign neigh <-> lci address callsign neigh\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) struct rose_route *rose_route = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (rose_route->neigh1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) "%3.3X %-10s %-9s %05d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) rose_route->lci1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) rose2asc(rsbuf, &rose_route->src_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) ax2asc(buf, &rose_route->src_call),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) rose_route->neigh1->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) "000 * * 00000 ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (rose_route->neigh2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) "%3.3X %-10s %-9s %05d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) rose_route->lci2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) rose2asc(rsbuf, &rose_route->dest_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) ax2asc(buf, &rose_route->dest_call),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) rose_route->neigh2->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) "000 * * 00000\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) struct seq_operations rose_route_seqops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) .start = rose_route_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) .next = rose_route_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) .stop = rose_route_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) .show = rose_route_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) #endif /* CONFIG_PROC_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * Release all memory associated with ROSE routing structures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) void __exit rose_rt_free(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) struct rose_neigh *s, *rose_neigh = rose_neigh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) struct rose_node *t, *rose_node = rose_node_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) struct rose_route *u, *rose_route = rose_route_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) while (rose_neigh != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) s = rose_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) rose_neigh = rose_neigh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) rose_remove_neigh(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) while (rose_node != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) t = rose_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) rose_node = rose_node->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) rose_remove_node(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) while (rose_route != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) u = rose_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) rose_route = rose_route->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) rose_remove_route(u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }