#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
rose_neigh = rose_neigh_list;
while (rose_neigh != NULL) {
- if (ax25cmp(&rose_route->neighbour, &rose_neigh->callsign) == 0
- && rose_neigh->dev == dev)
+ if (ax25cmp(&rose_route->neighbour,
+ &rose_neigh->callsign) == 0 &&
+ rose_neigh->dev == dev)
break;
rose_neigh = rose_neigh->next;
}
init_timer(&rose_neigh->t0timer);
if (rose_route->ndigis != 0) {
- if ((rose_neigh->digipeat = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) {
+ rose_neigh->digipeat =
+ kmalloc(sizeof(ax25_digi), GFP_ATOMIC);
+ if (rose_neigh->digipeat == NULL) {
kfree(rose_neigh);
res = -ENOMEM;
goto out;
if ((s = rose_neigh_list) == rose_neigh) {
rose_neigh_list = rose_neigh->next;
+ if (rose_neigh->ax25)
+ ax25_cb_put(rose_neigh->ax25);
kfree(rose_neigh->digipeat);
kfree(rose_neigh);
return;
while (s != NULL && s->next != NULL) {
if (s->next == rose_neigh) {
s->next = rose_neigh->next;
+ if (rose_neigh->ax25)
+ ax25_cb_put(rose_neigh->ax25);
kfree(rose_neigh->digipeat);
kfree(rose_neigh);
return;
rose_neigh = rose_neigh_list;
while (rose_neigh != NULL) {
- if (ax25cmp(&rose_route->neighbour, &rose_neigh->callsign) == 0
- && rose_neigh->dev == dev)
+ if (ax25cmp(&rose_route->neighbour,
+ &rose_neigh->callsign) == 0 &&
+ rose_neigh->dev == dev)
break;
rose_neigh = rose_neigh->next;
}
/*
* Check that the device given is a valid AX.25 interface that is "up".
+ * called whith RTNL
*/
-static struct net_device *rose_ax25_dev_get(char *devname)
+static struct net_device *rose_ax25_dev_find(char *devname)
{
struct net_device *dev;
- if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
+ if ((dev = __dev_get_by_name(&init_net, devname)) == NULL)
return NULL;
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
return dev;
- dev_put(dev);
return NULL;
}
{
struct net_device *dev, *first = NULL;
- read_lock(&dev_base_lock);
- for_each_netdev(&init_net, dev) {
+ rcu_read_lock();
+ for_each_netdev_rcu(&init_net, dev) {
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
first = dev;
}
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
return first;
}
{
struct net_device *dev;
- read_lock(&dev_base_lock);
- for_each_netdev(&init_net, dev) {
+ rcu_read_lock();
+ for_each_netdev_rcu(&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;
}
dev = NULL;
out:
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
return dev;
}
{
struct net_device *dev;
- read_lock(&dev_base_lock);
- for_each_netdev(&init_net, dev) {
+ rcu_read_lock();
+ for_each_netdev_rcu(&init_net, dev) {
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0)
goto out;
}
dev = NULL;
out:
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
return dev != NULL;
}
case SIOCADDRT:
if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
return -EFAULT;
- if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL)
+ if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
return -EINVAL;
- if (rose_dev_exists(&rose_route.address)) { /* Can't add routes to ourself */
- dev_put(dev);
+ if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */
return -EINVAL;
- }
if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
return -EINVAL;
if (rose_route.ndigis > AX25_MAX_DIGIS)
return -EINVAL;
err = rose_add_node(&rose_route, dev);
- dev_put(dev);
return err;
case SIOCDELRT:
if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
return -EFAULT;
- if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL)
+ if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
return -EINVAL;
err = rose_del_node(&rose_route, dev);
- dev_put(dev);
return err;
case SIOCRSCLRRT:
if (rose_neigh != NULL) {
rose_neigh->ax25 = NULL;
+ ax25_cb_put(ax25);
rose_del_route_by_neigh(rose_neigh);
rose_kill_by_neigh(rose_neigh);
unsigned int lci, new_lci;
unsigned char cause, diagnostic;
struct net_device *dev;
- int len, res = 0;
+ int res = 0;
char buf[11];
#if 0
return res;
#endif
+ if (skb->len < ROSE_MIN_LEN)
+ return res;
frametype = skb->data[2];
lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
- src_addr = (rose_address *)(skb->data + 9);
- dest_addr = (rose_address *)(skb->data + 4);
+ if (frametype == ROSE_CALL_REQUEST &&
+ (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
+ skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
+ ROSE_CALL_REQ_ADDR_LEN_VAL))
+ return res;
+ src_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF);
+ dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
spin_lock_bh(&rose_neigh_list_lock);
spin_lock_bh(&rose_route_list_lock);
goto out;
}
- len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1;
- len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1;
-
memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
- if (!rose_parse_facilities(skb->data + len + 4, &facilities)) {
+ if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
+ skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
+ &facilities)) {
rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76);
goto out;
}
static int rose_node_show(struct seq_file *seq, void *v)
{
+ char rsbuf[11];
int i;
if (v == SEQ_START_TOKEN)
const struct rose_node *rose_node = v;
/* if (rose_node->loopback) {
seq_printf(seq, "%-10s %04d 1 loopback\n",
- rose2asc(&rose_node->address),
- rose_node->mask);
+ rose2asc(rsbuf, &rose_node->address),
+ rose_node->mask);
} else { */
seq_printf(seq, "%-10s %04d %d",
- rose2asc(&rose_node->address),
- rose_node->mask,
- rose_node->count);
+ rose2asc(rsbuf, &rose_node->address),
+ rose_node->mask,
+ rose_node->count);
for (i = 0; i < rose_node->count; i++)
seq_printf(seq, " %05d",
static int rose_route_show(struct seq_file *seq, void *v)
{
- char buf[11];
+ char buf[11], rsbuf[11];
if (v == SEQ_START_TOKEN)
seq_puts(seq,
seq_printf(seq,
"%3.3X %-10s %-9s %05d ",
rose_route->lci1,
- rose2asc(&rose_route->src_addr),
+ rose2asc(rsbuf, &rose_route->src_addr),
ax2asc(buf, &rose_route->src_call),
rose_route->neigh1->number);
else
if (rose_route->neigh2)
seq_printf(seq,
"%3.3X %-10s %-9s %05d\n",
- rose_route->lci2,
- rose2asc(&rose_route->dest_addr),
- ax2asc(buf, &rose_route->dest_call),
- rose_route->neigh2->number);
+ rose_route->lci2,
+ rose2asc(rsbuf, &rose_route->dest_addr),
+ ax2asc(buf, &rose_route->dest_call),
+ rose_route->neigh2->number);
else
seq_puts(seq,
"000 * * 00000\n");