pktgen: Dont leak kernel memory
[safe/jmp/linux-2.6] / net / 802 / tr.c
index 987d915..e874447 100644 (file)
@@ -35,7 +35,9 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/sysctl.h>
 #include <net/arp.h>
+#include <net/net_namespace.h>
 
 static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev);
 static void rif_check_expire(unsigned long dummy);
@@ -74,7 +76,7 @@ static DEFINE_SPINLOCK(rif_lock);
 
 static struct timer_list rif_timer;
 
-int sysctl_tr_rif_timeout = 60*10*HZ;
+static int sysctl_tr_rif_timeout = 60*10*HZ;
 
 static inline unsigned long rif_hash(const unsigned char *addr)
 {
@@ -99,7 +101,7 @@ static inline unsigned long rif_hash(const unsigned char *addr)
 
 static int tr_header(struct sk_buff *skb, struct net_device *dev,
                     unsigned short type,
-                    void *daddr, void *saddr, unsigned len)
+                    const void *daddr, const void *saddr, unsigned len)
 {
        struct trh_hdr *trh;
        int hdr_len;
@@ -141,7 +143,7 @@ static int tr_header(struct sk_buff *skb, struct net_device *dev,
        if(daddr)
        {
                memcpy(trh->daddr,daddr,dev->addr_len);
-               tr_source_route(skb,trh,dev);
+               tr_source_route(skb, trh, dev);
                return(hdr_len);
        }
 
@@ -194,7 +196,7 @@ __be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev)
        unsigned riflen=0;
 
        skb->dev = dev;
-       skb->mac.raw = skb->data;
+       skb_reset_mac_header(skb);
        trh = tr_hdr(skb);
 
        if(trh->saddr[0] & TR_RII)
@@ -246,7 +248,8 @@ __be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev)
  *     We try to do source routing...
  */
 
-void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *dev)
+void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,
+                    struct net_device *dev)
 {
        int slack;
        unsigned int hash;
@@ -282,8 +285,7 @@ void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *
                if(entry)
                {
 #if TR_SR_DEBUG
-printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0],
-                 trh->daddr[1],trh->daddr[2],trh->daddr[3],trh->daddr[4],trh->daddr[5]);
+printk("source routing for %pM\n", trh->daddr);
 #endif
                        if(!entry->local_ring && (ntohs(entry->rcf) & TR_RCF_LEN_MASK) >> 8)
                        {
@@ -365,10 +367,8 @@ static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev)
        if(entry==NULL)
        {
 #if TR_SR_DEBUG
-printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
-               trh->saddr[0],trh->saddr[1],trh->saddr[2],
-               trh->saddr[3],trh->saddr[4],trh->saddr[5],
-               ntohs(trh->rcf));
+               printk("adding rif_entry: addr:%pM rcf:%04X\n",
+                      trh->saddr, ntohs(trh->rcf));
 #endif
                /*
                 *      Allocate our new entry. A failure to allocate loses
@@ -413,10 +413,8 @@ printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
                         !(trh->rcf & htons(TR_RCF_BROADCAST_MASK)))
                    {
 #if TR_SR_DEBUG
-printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
-               trh->saddr[0],trh->saddr[1],trh->saddr[2],
-               trh->saddr[3],trh->saddr[4],trh->saddr[5],
-               ntohs(trh->rcf));
+printk("updating rif_entry: addr:%pM rcf:%04X\n",
+               trh->saddr, ntohs(trh->rcf));
 #endif
                            entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK);
                            memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short));
@@ -488,6 +486,7 @@ static struct rif_cache *rif_get_idx(loff_t pos)
 }
 
 static void *rif_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(&rif_lock)
 {
        spin_lock_irq(&rif_lock);
 
@@ -519,6 +518,7 @@ static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void rif_seq_stop(struct seq_file *seq, void *v)
+       __releases(&rif_lock)
 {
        spin_unlock_irq(&rif_lock);
 }
@@ -532,14 +532,13 @@ static int rif_seq_show(struct seq_file *seq, void *v)
                seq_puts(seq,
                     "if     TR address       TTL   rcf   routing segments\n");
        else {
-               struct net_device *dev = dev_get_by_index(entry->iface);
+               struct net_device *dev = dev_get_by_index(&init_net, entry->iface);
                long ttl = (long) (entry->last_used + sysctl_tr_rif_timeout)
                                - (long) jiffies;
 
-               seq_printf(seq, "%s %02X:%02X:%02X:%02X:%02X:%02X %7li ",
+               seq_printf(seq, "%s %pM %7li ",
                           dev?dev->name:"?",
-                          entry->addr[0],entry->addr[1],entry->addr[2],
-                          entry->addr[3],entry->addr[4],entry->addr[5],
+                          entry->addr,
                           ttl/HZ);
 
                        if (entry->local_ring)
@@ -554,19 +553,23 @@ static int rif_seq_show(struct seq_file *seq, void *v)
                                        if(j==1) {
                                                segment=ntohs(entry->rseg[j-1])>>4;
                                                seq_printf(seq,"  %03X",segment);
-                                       };
+                                       }
+
                                        segment=ntohs(entry->rseg[j])>>4;
                                        brdgnmb=ntohs(entry->rseg[j-1])&0x00f;
                                        seq_printf(seq,"-%01X-%03X",brdgnmb,segment);
                                }
                                seq_putc(seq, '\n');
                        }
+
+               if (dev)
+                       dev_put(dev);
                }
        return 0;
 }
 
 
-static struct seq_operations rif_seq_ops = {
+static const struct seq_operations rif_seq_ops = {
        .start = rif_seq_start,
        .next  = rif_seq_next,
        .stop  = rif_seq_stop,
@@ -588,14 +591,18 @@ static const struct file_operations rif_seq_fops = {
 
 #endif
 
+static const struct header_ops tr_header_ops = {
+       .create = tr_header,
+       .rebuild= tr_rebuild_header,
+};
+
 static void tr_setup(struct net_device *dev)
 {
        /*
         *      Configure and register
         */
 
-       dev->hard_header        = tr_header;
-       dev->rebuild_header     = tr_rebuild_header;
+       dev->header_ops = &tr_header_ops;
 
        dev->type               = ARPHRD_IEEE802_TR;
        dev->hard_header_len    = TR_HLEN;
@@ -625,6 +632,26 @@ struct net_device *alloc_trdev(int sizeof_priv)
        return alloc_netdev(sizeof_priv, "tr%d", tr_setup);
 }
 
+#ifdef CONFIG_SYSCTL
+static struct ctl_table tr_table[] = {
+       {
+               .ctl_name       = NET_TR_RIF_TIMEOUT,
+               .procname       = "rif_timeout",
+               .data           = &sysctl_tr_rif_timeout,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec
+       },
+       { 0 },
+};
+
+static __initdata struct ctl_path tr_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "token-ring", .ctl_name = NET_TR, },
+       { }
+};
+#endif
+
 /*
  *     Called during bootup.  We don't actually have to initialise
  *     too much for this.
@@ -632,13 +659,13 @@ struct net_device *alloc_trdev(int sizeof_priv)
 
 static int __init rif_init(void)
 {
-       init_timer(&rif_timer);
-       rif_timer.expires  = sysctl_tr_rif_timeout;
-       rif_timer.data     = 0L;
-       rif_timer.function = rif_check_expire;
+       rif_timer.expires  = jiffies + sysctl_tr_rif_timeout;
+       setup_timer(&rif_timer, rif_check_expire, 0);
        add_timer(&rif_timer);
-
-       proc_net_fops_create("tr_rif", S_IRUGO, &rif_seq_fops);
+#ifdef CONFIG_SYSCTL
+       register_sysctl_paths(tr_path, tr_table);
+#endif
+       proc_net_fops_create(&init_net, "tr_rif", S_IRUGO, &rif_seq_fops);
        return 0;
 }
 
@@ -646,3 +673,5 @@ module_init(rif_init);
 
 EXPORT_SYMBOL(tr_type_trans);
 EXPORT_SYMBOL(alloc_trdev);
+
+MODULE_LICENSE("GPL");