static struct rose_route *rose_route_list;
static DEFINE_SPINLOCK(rose_route_list_lock);
-struct rose_neigh rose_loopback_neigh;
+struct rose_neigh *rose_loopback_neigh;
/*
* Add a new route to a node, and in the process add the node and the
*/
void rose_add_loopback_neigh(void)
{
- struct rose_neigh *sn = &rose_loopback_neigh;
+ struct rose_neigh *sn;
+
+ rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_KERNEL);
+ if (!rose_loopback_neigh)
+ return;
+ sn = rose_loopback_neigh;
sn->callsign = null_ax25_address;
sn->digipeat = NULL;
rose_node->mask = 10;
rose_node->count = 1;
rose_node->loopback = 1;
- rose_node->neighbour[0] = &rose_loopback_neigh;
+ rose_node->neighbour[0] = rose_loopback_neigh;
/* Insert at the head of list. Address is always mask=10 */
rose_node->next = rose_node_list;
rose_node_list = rose_node;
- rose_loopback_neigh.count++;
+ rose_loopback_neigh->count++;
out:
spin_unlock_bh(&rose_node_list_lock);
rose_remove_node(rose_node);
- rose_loopback_neigh.count--;
+ rose_loopback_neigh->count--;
out:
spin_unlock_bh(&rose_node_list_lock);
{
struct net_device *dev;
- if ((dev = dev_get_by_name(devname)) == NULL)
+ if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
return NULL;
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
struct net_device *dev, *first = NULL;
read_lock(&dev_base_lock);
- for_each_netdev(dev) {
+ for_each_netdev(&init_net, dev) {
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
first = dev;
struct net_device *dev;
read_lock(&dev_base_lock);
- for_each_netdev(dev) {
+ for_each_netdev(&init_net, dev) {
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) {
dev_hold(dev);
goto out;
struct net_device *dev;
read_lock(&dev_base_lock);
- for_each_netdev(dev) {
+ for_each_netdev(&init_net, dev) {
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0)
goto out;
}
}
/*
- * Find a neighbour given a ROSE address.
+ * Find a neighbour or a route given a ROSE address.
*/
struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
- unsigned char *diagnostic)
+ unsigned char *diagnostic, int new)
{
struct rose_neigh *res = NULL;
struct rose_node *node;
int failed = 0;
int i;
- spin_lock_bh(&rose_node_list_lock);
+ if (!new) spin_lock_bh(&rose_node_list_lock);
for (node = rose_node_list; node != NULL; node = node->next) {
if (rosecmpm(addr, &node->address, node->mask) == 0) {
for (i = 0; i < node->count; i++) {
- if (!rose_ftimer_running(node->neighbour[i])) {
- res = node->neighbour[i];
- goto out;
- } else
- failed = 1;
+ if (new) {
+ if (node->neighbour[i]->restarted) {
+ res = node->neighbour[i];
+ goto out;
+ }
+ }
+ else {
+ if (!rose_ftimer_running(node->neighbour[i])) {
+ res = node->neighbour[i];
+ goto out;
+ } else
+ failed = 1;
+ }
}
- break;
}
}
}
out:
- spin_unlock_bh(&rose_node_list_lock);
+ if (!new) spin_unlock_bh(&rose_node_list_lock);
return res;
}
src_addr = (rose_address *)(skb->data + 9);
dest_addr = (rose_address *)(skb->data + 4);
- spin_lock_bh(&rose_node_list_lock);
spin_lock_bh(&rose_neigh_list_lock);
spin_lock_bh(&rose_route_list_lock);
goto out;
}
- len = (((skb->data[3] >> 4) & 0x0F) + 1) / 2;
- len += (((skb->data[3] >> 0) & 0x0F) + 1) / 2;
+ len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1;
+ len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1;
memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
rose_route = rose_route->next;
}
- if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic)) == NULL) {
+ if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic, 1)) == NULL) {
rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic);
goto out;
}
out:
spin_unlock_bh(&rose_route_list_lock);
spin_unlock_bh(&rose_neigh_list_lock);
- spin_unlock_bh(&rose_node_list_lock);
return res;
}
#ifdef CONFIG_PROC_FS
static void *rose_node_start(struct seq_file *seq, loff_t *pos)
+ __acquires(rose_node_list_lock)
{
struct rose_node *rose_node;
int i = 1;
- spin_lock_bh(&rose_neigh_list_lock);
+ spin_lock_bh(&rose_node_list_lock);
if (*pos == 0)
return SEQ_START_TOKEN;
}
static void rose_node_stop(struct seq_file *seq, void *v)
+ __releases(rose_node_list_lock)
{
- spin_unlock_bh(&rose_neigh_list_lock);
+ spin_unlock_bh(&rose_node_list_lock);
}
static int rose_node_show(struct seq_file *seq, void *v)
return 0;
}
-static struct seq_operations rose_node_seqops = {
+static const struct seq_operations rose_node_seqops = {
.start = rose_node_start,
.next = rose_node_next,
.stop = rose_node_stop,
};
static void *rose_neigh_start(struct seq_file *seq, loff_t *pos)
+ __acquires(rose_neigh_list_lock)
{
struct rose_neigh *rose_neigh;
int i = 1;
}
static void rose_neigh_stop(struct seq_file *seq, void *v)
+ __releases(rose_neigh_list_lock)
{
spin_unlock_bh(&rose_neigh_list_lock);
}
}
-static struct seq_operations rose_neigh_seqops = {
+static const struct seq_operations rose_neigh_seqops = {
.start = rose_neigh_start,
.next = rose_neigh_next,
.stop = rose_neigh_stop,
static void *rose_route_start(struct seq_file *seq, loff_t *pos)
+ __acquires(rose_route_list_lock)
{
struct rose_route *rose_route;
int i = 1;
}
static void rose_route_stop(struct seq_file *seq, void *v)
+ __releases(rose_route_list_lock)
{
spin_unlock_bh(&rose_route_list_lock);
}
return 0;
}
-static struct seq_operations rose_route_seqops = {
+static const struct seq_operations rose_route_seqops = {
.start = rose_route_start,
.next = rose_route_next,
.stop = rose_route_stop,