nfsd: nfsd should drop CAP_MKNOD for non-root
[safe/jmp/linux-2.6] / net / rose / rose_route.c
index 7252344..a81066a 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/string.h>
 #include <linux/sockios.h>
@@ -52,7 +51,7 @@ struct rose_neigh *rose_loopback_neigh;
  *     Add a new route to a node, and in the process add the node and the
  *     neighbour if it is new.
  */
-static int rose_add_node(struct rose_route_struct *rose_route,
+static int __must_check rose_add_node(struct rose_route_struct *rose_route,
        struct net_device *dev)
 {
        struct rose_node  *rose_node, *rose_tmpn, *rose_tmpp;
@@ -66,7 +65,7 @@ static int rose_add_node(struct rose_route_struct *rose_route,
        while (rose_node != NULL) {
                if ((rose_node->mask == rose_route->mask) &&
                    (rosecmpm(&rose_route->address, &rose_node->address,
-                             rose_route->mask) == 0))
+                             rose_route->mask) == 0))
                        break;
                rose_node = rose_node->next;
        }
@@ -300,7 +299,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
        while (rose_node != NULL) {
                if ((rose_node->mask == rose_route->mask) &&
                    (rosecmpm(&rose_route->address, &rose_node->address,
-                             rose_route->mask) == 0))
+                             rose_route->mask) == 0))
                        break;
                rose_node = rose_node->next;
        }
@@ -361,33 +360,35 @@ out:
 /*
  *     Add the loopback neighbour.
  */
-int rose_add_loopback_neigh(void)
+void rose_add_loopback_neigh(void)
 {
-       if ((rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_ATOMIC)) == NULL)
-               return -ENOMEM;
+       struct rose_neigh *sn;
 
-       rose_loopback_neigh->callsign  = null_ax25_address;
-       rose_loopback_neigh->digipeat  = NULL;
-       rose_loopback_neigh->ax25      = NULL;
-       rose_loopback_neigh->dev       = NULL;
-       rose_loopback_neigh->count     = 0;
-       rose_loopback_neigh->use       = 0;
-       rose_loopback_neigh->dce_mode  = 1;
-       rose_loopback_neigh->loopback  = 1;
-       rose_loopback_neigh->number    = rose_neigh_no++;
-       rose_loopback_neigh->restarted = 1;
+       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;
+       sn->ax25      = NULL;
+       sn->dev       = NULL;
+       sn->count     = 0;
+       sn->use       = 0;
+       sn->dce_mode  = 1;
+       sn->loopback  = 1;
+       sn->number    = rose_neigh_no++;
+       sn->restarted = 1;
 
-       skb_queue_head_init(&rose_loopback_neigh->queue);
+       skb_queue_head_init(&sn->queue);
 
-       init_timer(&rose_loopback_neigh->ftimer);
-       init_timer(&rose_loopback_neigh->t0timer);
+       init_timer(&sn->ftimer);
+       init_timer(&sn->t0timer);
 
        spin_lock_bh(&rose_neigh_list_lock);
-       rose_loopback_neigh->next = rose_neigh_list;
-       rose_neigh_list           = rose_loopback_neigh;
+       sn->next = rose_neigh_list;
+       rose_neigh_list           = sn;
        spin_unlock_bh(&rose_neigh_list_lock);
-
-       return 0;
 }
 
 /*
@@ -582,7 +583,7 @@ static struct net_device *rose_ax25_dev_get(char *devname)
 {
        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)
@@ -600,7 +601,7 @@ struct net_device *rose_dev_first(void)
        struct net_device *dev, *first = NULL;
 
        read_lock(&dev_base_lock);
-       for (dev = dev_base; dev != NULL; dev = dev->next) {
+       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;
@@ -618,12 +619,13 @@ struct net_device *rose_dev_get(rose_address *addr)
        struct net_device *dev;
 
        read_lock(&dev_base_lock);
-       for (dev = dev_base; dev != NULL; dev = dev->next) {
+       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;
                }
        }
+       dev = NULL;
 out:
        read_unlock(&dev_base_lock);
        return dev;
@@ -634,10 +636,11 @@ static int rose_dev_exists(rose_address *addr)
        struct net_device *dev;
 
        read_lock(&dev_base_lock);
-       for (dev = dev_base; dev != NULL; dev = dev->next) {
+       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;
        }
+       dev = NULL;
 out:
        read_unlock(&dev_base_lock);
        return dev != NULL;
@@ -659,27 +662,34 @@ struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neig
 }
 
 /*
- *     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;
                }
        }
 
@@ -692,7 +702,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
        }
 
 out:
-       spin_unlock_bh(&rose_node_list_lock);
+       if (!new) spin_unlock_bh(&rose_node_list_lock);
 
        return res;
 }
@@ -854,7 +864,6 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
        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);
 
@@ -910,7 +919,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
                        }
                }
                else {
-                       skb->h.raw = skb->data;
+                       skb_reset_transport_header(skb);
                        res = rose_process_rx_frame(sk, skb);
                        goto out;
                }
@@ -991,8 +1000,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
                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));
 
@@ -1016,7 +1025,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
                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;
        }
@@ -1057,7 +1066,6 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
 out:
        spin_unlock_bh(&rose_route_list_lock);
        spin_unlock_bh(&rose_neigh_list_lock);
-       spin_unlock_bh(&rose_node_list_lock);
 
        return res;
 }
@@ -1065,15 +1073,16 @@ out:
 #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;
 
-       for (rose_node = rose_node_list; rose_node && i < *pos; 
+       for (rose_node = rose_node_list; rose_node && i < *pos;
             rose_node = rose_node->next, ++i);
 
        return (i == *pos) ? rose_node : NULL;
@@ -1082,14 +1091,15 @@ static void *rose_node_start(struct seq_file *seq, loff_t *pos)
 static void *rose_node_next(struct seq_file *seq, void *v, loff_t *pos)
 {
        ++*pos;
-       
-       return (v == SEQ_START_TOKEN) ? rose_node_list 
+
+       return (v == SEQ_START_TOKEN) ? rose_node_list
                : ((struct rose_node *)v)->next;
 }
 
 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)
@@ -1120,7 +1130,7 @@ 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,
@@ -1132,7 +1142,7 @@ static int rose_nodes_open(struct inode *inode, struct file *file)
        return seq_open(file, &rose_node_seqops);
 }
 
-struct file_operations rose_nodes_fops = {
+const struct file_operations rose_nodes_fops = {
        .owner = THIS_MODULE,
        .open = rose_nodes_open,
        .read = seq_read,
@@ -1141,6 +1151,7 @@ struct file_operations rose_nodes_fops = {
 };
 
 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;
@@ -1149,7 +1160,7 @@ static void *rose_neigh_start(struct seq_file *seq, loff_t *pos)
        if (*pos == 0)
                return SEQ_START_TOKEN;
 
-       for (rose_neigh = rose_neigh_list; rose_neigh && i < *pos; 
+       for (rose_neigh = rose_neigh_list; rose_neigh && i < *pos;
             rose_neigh = rose_neigh->next, ++i);
 
        return (i == *pos) ? rose_neigh : NULL;
@@ -1158,12 +1169,13 @@ static void *rose_neigh_start(struct seq_file *seq, loff_t *pos)
 static void *rose_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
 {
        ++*pos;
-       
-       return (v == SEQ_START_TOKEN) ? rose_neigh_list 
+
+       return (v == SEQ_START_TOKEN) ? rose_neigh_list
                : ((struct rose_neigh *)v)->next;
 }
 
 static void rose_neigh_stop(struct seq_file *seq, void *v)
+       __releases(rose_neigh_list_lock)
 {
        spin_unlock_bh(&rose_neigh_list_lock);
 }
@@ -1174,7 +1186,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
        int i;
 
        if (v == SEQ_START_TOKEN)
-               seq_puts(seq, 
+               seq_puts(seq,
                         "addr  callsign  dev  count use mode restart  t0  tf digipeaters\n");
        else {
                struct rose_neigh *rose_neigh = v;
@@ -1202,7 +1214,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
 }
 
 
-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,
@@ -1214,7 +1226,7 @@ static int rose_neigh_open(struct inode *inode, struct file *file)
        return seq_open(file, &rose_neigh_seqops);
 }
 
-struct file_operations rose_neigh_fops = {
+const struct file_operations rose_neigh_fops = {
        .owner = THIS_MODULE,
        .open = rose_neigh_open,
        .read = seq_read,
@@ -1224,6 +1236,7 @@ struct file_operations rose_neigh_fops = {
 
 
 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;
@@ -1232,7 +1245,7 @@ static void *rose_route_start(struct seq_file *seq, loff_t *pos)
        if (*pos == 0)
                return SEQ_START_TOKEN;
 
-       for (rose_route = rose_route_list; rose_route && i < *pos; 
+       for (rose_route = rose_route_list; rose_route && i < *pos;
             rose_route = rose_route->next, ++i);
 
        return (i == *pos) ? rose_route : NULL;
@@ -1241,12 +1254,13 @@ static void *rose_route_start(struct seq_file *seq, loff_t *pos)
 static void *rose_route_next(struct seq_file *seq, void *v, loff_t *pos)
 {
        ++*pos;
-       
-       return (v == SEQ_START_TOKEN) ? rose_route_list 
+
+       return (v == SEQ_START_TOKEN) ? rose_route_list
                : ((struct rose_route *)v)->next;
 }
 
 static void rose_route_stop(struct seq_file *seq, void *v)
+       __releases(rose_route_list_lock)
 {
        spin_unlock_bh(&rose_route_list_lock);
 }
@@ -1256,37 +1270,37 @@ static int rose_route_show(struct seq_file *seq, void *v)
        char buf[11];
 
        if (v == SEQ_START_TOKEN)
-               seq_puts(seq, 
+               seq_puts(seq,
                         "lci  address     callsign   neigh  <-> lci  address     callsign   neigh\n");
        else {
                struct rose_route *rose_route = v;
 
-               if (rose_route->neigh1) 
+               if (rose_route->neigh1)
                        seq_printf(seq,
                                   "%3.3X  %-10s  %-9s  %05d      ",
                                   rose_route->lci1,
                                   rose2asc(&rose_route->src_addr),
                                   ax2asc(buf, &rose_route->src_call),
                                   rose_route->neigh1->number);
-               else 
-                       seq_puts(seq, 
+               else
+                       seq_puts(seq,
                                 "000  *           *          00000      ");
 
-               if (rose_route->neigh2) 
+               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);
-                else 
+                else
                         seq_puts(seq,
                                  "000  *           *          00000\n");
                }
        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,
@@ -1298,7 +1312,7 @@ static int rose_route_open(struct inode *inode, struct file *file)
        return seq_open(file, &rose_route_seqops);
 }
 
-struct file_operations rose_routes_fops = {
+const struct file_operations rose_routes_fops = {
        .owner = THIS_MODULE,
        .open = rose_route_open,
        .read = seq_read,