summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@kernel.bkbits.net>2002-12-07 22:28:56 -0800
committerDavid S. Miller <davem@kernel.bkbits.net>2002-12-07 22:28:56 -0800
commitb72e2aecaaeea6087ffaa4bb91b6b42fb7d0f46a (patch)
tree6e4a8abf02884968c7de9ba48d97d3c1568bc17e
parent51a169c1962ba2343936f3ff8326fb21eef56a08 (diff)
parent43ff0e0d904418ea56b23632bdef704fcfbf6093 (diff)
Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5
into kernel.bkbits.net:/home/davem/net-2.5
-rw-r--r--Documentation/crypto/api-intro.txt1
-rw-r--r--crypto/Makefile4
-rw-r--r--crypto/api.c120
-rw-r--r--crypto/internal.h9
-rw-r--r--crypto/proc.c105
-rw-r--r--include/linux/crypto.h1
-rw-r--r--include/net/route.h2
-rw-r--r--net/ipv4/route.c231
8 files changed, 289 insertions, 184 deletions
diff --git a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt
index c8090c84f0c7..b90af6f3af1b 100644
--- a/Documentation/crypto/api-intro.txt
+++ b/Documentation/crypto/api-intro.txt
@@ -185,6 +185,7 @@ Original developers of the crypto algorithms:
Jean-Luc Cooke (SHA256)
Kazunori Miyazawa / USAGI (HMAC)
Matthew Skala (Twofish)
+ Dag Arne Osvik (Serpent)
DES algorithm contributors:
Raimar Falke
diff --git a/crypto/Makefile b/crypto/Makefile
index 13415dce5181..9bbb7ac45d56 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -5,8 +5,10 @@
export-objs := api.o hmac.o
autoload-crypto-$(CONFIG_KMOD) = autoload.o
+proc-crypto-$(CONFIG_PROC_FS) = proc.o
-obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o $(autoload-crypto-y)
+obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \
+ $(autoload-crypto-y) $(proc-crypto-y)
obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
diff --git a/crypto/api.c b/crypto/api.c
index c903f2b39da2..626437fb5dea 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -16,12 +16,11 @@
#include <linux/init.h>
#include <linux/crypto.h>
#include <linux/rwsem.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "internal.h"
-static LIST_HEAD(crypto_alg_list);
-static DECLARE_RWSEM(crypto_alg_sem);
+LIST_HEAD(crypto_alg_list);
+DECLARE_RWSEM(crypto_alg_sem);
static inline int crypto_alg_get(struct crypto_alg *alg)
{
@@ -124,44 +123,26 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
if (alg == NULL)
goto out;
- tfm = kmalloc(sizeof(*tfm), GFP_KERNEL);
+ tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
if (tfm == NULL)
goto out_put;
memset(tfm, 0, sizeof(*tfm));
- if (alg->cra_ctxsize) {
- tfm->crt_ctx = kmalloc(alg->cra_ctxsize, GFP_KERNEL);
- if (tfm->crt_ctx == NULL)
- goto out_free_tfm;
- }
+ tfm->crt_ctx = (void*) &tfm[1];
tfm->__crt_alg = alg;
- if (alg->cra_blocksize) {
- tfm->crt_work_block = kmalloc(alg->cra_blocksize + 1,
- GFP_KERNEL);
- if (tfm->crt_work_block == NULL)
- goto out_free_ctx;
- }
-
if (crypto_init_flags(tfm, flags))
- goto out_free_work_block;
+ goto out_free_tfm;
if (crypto_init_ops(tfm)) {
crypto_exit_ops(tfm);
- goto out_free_ctx;
+ goto out_free_tfm;
}
goto out;
-out_free_work_block:
- if (tfm->__crt_alg->cra_blocksize)
- kfree(tfm->crt_work_block);
-
-out_free_ctx:
- if (tfm->__crt_alg->cra_ctxsize)
- kfree(tfm->crt_ctx);
out_free_tfm:
kfree(tfm);
tfm = NULL;
@@ -173,12 +154,6 @@ out:
void crypto_free_tfm(struct crypto_tfm *tfm)
{
- if (tfm->__crt_alg->cra_ctxsize)
- kfree(tfm->crt_ctx);
-
- if (tfm->__crt_alg->cra_blocksize)
- kfree(tfm->crt_work_block);
-
if (crypto_tfm_alg_type(tfm) == CRYPTO_ALG_TYPE_CIPHER)
if (tfm->crt_cipher.cit_iv)
kfree(tfm->crt_cipher.cit_iv);
@@ -240,89 +215,10 @@ int crypto_alg_available(const char *name, u32 flags)
return ret;
}
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
- struct list_head *v;
- loff_t n = *pos;
-
- down_read(&crypto_alg_sem);
- list_for_each(v, &crypto_alg_list)
- if (!n--)
- return list_entry(v, struct crypto_alg, cra_list);
- return NULL;
-}
-
-static void *c_next(struct seq_file *m, void *p, loff_t *pos)
-{
- struct list_head *v = p;
-
- (*pos)++;
- v = v->next;
- return (v == &crypto_alg_list) ?
- NULL : list_entry(v, struct crypto_alg, cra_list);
-}
-
-static void c_stop(struct seq_file *m, void *p)
-{
- up_read(&crypto_alg_sem);
-}
-
-static int c_show(struct seq_file *m, void *p)
-{
- struct crypto_alg *alg = (struct crypto_alg *)p;
-
- seq_printf(m, "name : %s\n", alg->cra_name);
- seq_printf(m, "module : %s\n", module_name(alg->cra_module));
- seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
-
- switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
- case CRYPTO_ALG_TYPE_CIPHER:
- seq_printf(m, "min keysize : %u\n",
- alg->cra_cipher.cia_min_keysize);
- seq_printf(m, "max keysize : %u\n",
- alg->cra_cipher.cia_max_keysize);
- seq_printf(m, "ivsize : %u\n",
- alg->cra_cipher.cia_ivsize);
- break;
-
- case CRYPTO_ALG_TYPE_DIGEST:
- seq_printf(m, "digestsize : %u\n",
- alg->cra_digest.dia_digestsize);
- break;
- }
-
- seq_putc(m, '\n');
- return 0;
-}
-
-static struct seq_operations crypto_seq_ops = {
- .start = c_start,
- .next = c_next,
- .stop = c_stop,
- .show = c_show
-};
-
-static int crypto_info_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &crypto_seq_ops);
-}
-
-struct file_operations proc_crypto_ops = {
- .open = crypto_info_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release
-};
-
static int __init init_crypto(void)
{
- struct proc_dir_entry *proc;
-
printk(KERN_INFO "Initializing Cryptographic API\n");
- proc = create_proc_entry("crypto", 0, NULL);
- if (proc)
- proc->proc_fops = &proc_crypto_ops;
-
+ crypto_init_proc();
return 0;
}
diff --git a/crypto/internal.h b/crypto/internal.h
index 408bc1bb5b0c..eb4c92d3b47f 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -11,9 +11,9 @@
*/
#ifndef _CRYPTO_INTERNAL_H
#define _CRYPTO_INTERNAL_H
-
#include <linux/mm.h>
#include <linux/highmem.h>
+#include <linux/init.h>
#include <asm/hardirq.h>
#include <asm/softirq.h>
@@ -65,6 +65,13 @@ static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
{ }
#endif
+#ifdef CONFIG_PROC_FS
+void __init crypto_init_proc(void);
+#else
+static inline void crypto_init_proc(void)
+{ }
+#endif
+
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
diff --git a/crypto/proc.c b/crypto/proc.c
new file mode 100644
index 000000000000..f51a3ccf52db
--- /dev/null
+++ b/crypto/proc.c
@@ -0,0 +1,105 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Procfs information.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/crypto.h>
+#include <linux/rwsem.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+extern struct list_head crypto_alg_list;
+extern struct rw_semaphore crypto_alg_sem;
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ struct list_head *v;
+ loff_t n = *pos;
+
+ down_read(&crypto_alg_sem);
+ list_for_each(v, &crypto_alg_list)
+ if (!n--)
+ return list_entry(v, struct crypto_alg, cra_list);
+ return NULL;
+}
+
+static void *c_next(struct seq_file *m, void *p, loff_t *pos)
+{
+ struct list_head *v = p;
+
+ (*pos)++;
+ v = v->next;
+ return (v == &crypto_alg_list) ?
+ NULL : list_entry(v, struct crypto_alg, cra_list);
+}
+
+static void c_stop(struct seq_file *m, void *p)
+{
+ up_read(&crypto_alg_sem);
+}
+
+static int c_show(struct seq_file *m, void *p)
+{
+ struct crypto_alg *alg = (struct crypto_alg *)p;
+
+ seq_printf(m, "name : %s\n", alg->cra_name);
+ seq_printf(m, "module : %s\n", module_name(alg->cra_module));
+ seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
+
+ switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+ case CRYPTO_ALG_TYPE_CIPHER:
+ seq_printf(m, "min keysize : %u\n",
+ alg->cra_cipher.cia_min_keysize);
+ seq_printf(m, "max keysize : %u\n",
+ alg->cra_cipher.cia_max_keysize);
+ seq_printf(m, "ivsize : %u\n",
+ alg->cra_cipher.cia_ivsize);
+ break;
+
+ case CRYPTO_ALG_TYPE_DIGEST:
+ seq_printf(m, "digestsize : %u\n",
+ alg->cra_digest.dia_digestsize);
+ break;
+ }
+
+ seq_putc(m, '\n');
+ return 0;
+}
+
+static struct seq_operations crypto_seq_ops = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = c_show
+};
+
+static int crypto_info_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &crypto_seq_ops);
+}
+
+static struct file_operations proc_crypto_ops = {
+ .open = crypto_info_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+void __init crypto_init_proc(void)
+{
+ struct proc_dir_entry *proc;
+
+ proc = create_proc_entry("crypto", 0, NULL);
+ if (proc)
+ proc->proc_fops = &proc_crypto_ops;
+}
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index f82c74decefe..5c29e2b58011 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -161,7 +161,6 @@ struct compress_tfm {
struct crypto_tfm {
void *crt_ctx;
- void *crt_work_block;
u32 crt_flags;
union {
diff --git a/include/net/route.h b/include/net/route.h
index afab97d19a81..593311a57fca 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -107,7 +107,7 @@ struct rt_cache_stat
extern struct ip_rt_acct *ip_rt_acct;
struct in_device;
-extern void ip_rt_init(void);
+extern int ip_rt_init(void);
extern void ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw,
u32 src, u8 tos, struct net_device *dev);
extern void ip_rt_advice(struct rtable **rp, int advice);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 3d2793635e41..42ef54e97539 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -53,6 +53,7 @@
* Vladimir V. Ivanov : IP rule info (flowid) is really useful.
* Marc Boucher : routing by fwmark
* Robert Olsson : Added rt_cache statistics
+ * Arnaldo C. Melo : Convert proc stuff to seq_file
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -208,74 +209,107 @@ static __inline__ unsigned rt_hash_code(u32 daddr, u32 saddr, u8 tos)
return (hash ^ (hash >> 8)) & rt_hash_mask;
}
-static int rt_cache_get_info(char *buffer, char **start, off_t offset,
- int length)
+#ifdef CONFIG_PROC_FS
+struct rt_cache_iter_state {
+ int bucket;
+};
+
+static struct rtable *rt_cache_get_first(struct seq_file *seq)
{
- int len = 0;
- off_t pos = 128;
- char temp[256];
- struct rtable *r;
- int i;
+ struct rtable *r = NULL;
+ struct rt_cache_iter_state *st = seq->private;
- if (offset < 128) {
- sprintf(buffer, "%-127s\n",
- "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
- "Metric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\t"
- "HHUptod\tSpecDst");
- len = 128;
- }
-
- for (i = rt_hash_mask; i >= 0; i--) {
- read_lock_bh(&rt_hash_table[i].lock);
- for (r = rt_hash_table[i].chain; r; r = r->u.rt_next) {
- /*
- * Spin through entries until we are ready
- */
- pos += 128;
+ for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
+ read_lock_bh(&rt_hash_table[st->bucket].lock);
+ r = rt_hash_table[st->bucket].chain;
+ if (r)
+ break;
+ read_unlock_bh(&rt_hash_table[st->bucket].lock);
+ }
+ return r;
+}
- if (pos <= offset) {
- len = 0;
- continue;
- }
- sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
- "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X",
- r->u.dst.dev ? r->u.dst.dev->name : "*",
- (unsigned long)r->rt_dst,
- (unsigned long)r->rt_gateway,
- r->rt_flags,
- atomic_read(&r->u.dst.__refcnt),
- r->u.dst.__use,
- 0,
- (unsigned long)r->rt_src,
- (dst_metric(&r->u.dst, RTAX_ADVMSS) ?
- (int) dst_metric(&r->u.dst, RTAX_ADVMSS) + 40 : 0),
- dst_metric(&r->u.dst, RTAX_WINDOW),
- (int)((dst_metric(&r->u.dst, RTAX_RTT) >> 3)
- + dst_metric(&r->u.dst, RTAX_RTTVAR)),
- r->fl.fl4_tos,
- r->u.dst.hh ?
- atomic_read(&r->u.dst.hh->hh_refcnt) :
- -1,
- r->u.dst.hh ?
- (r->u.dst.hh->hh_output ==
- dev_queue_xmit) : 0,
- r->rt_spec_dst);
- sprintf(buffer + len, "%-127s\n", temp);
- len += 128;
- if (pos >= offset+length) {
- read_unlock_bh(&rt_hash_table[i].lock);
- goto done;
- }
- }
- read_unlock_bh(&rt_hash_table[i].lock);
- }
+static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
+{
+ struct rt_cache_iter_state *st = seq->private;
-done:
- *start = buffer + len - (pos - offset);
- len = pos - offset;
- if (len > length)
- len = length;
- return len;
+ r = r->u.rt_next;
+ while (!r) {
+ read_unlock_bh(&rt_hash_table[st->bucket].lock);
+ if (--st->bucket < 0)
+ break;
+ read_lock_bh(&rt_hash_table[st->bucket].lock);
+ r = rt_hash_table[st->bucket].chain;
+ }
+ return r;
+}
+
+static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct rtable *r = rt_cache_get_first(seq);
+
+ if (r)
+ while (pos && (r = rt_cache_get_next(seq, r)))
+ --pos;
+ return pos ? NULL : r;
+}
+
+static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ return *pos ? rt_cache_get_idx(seq, *pos) : (void *)1;
+}
+
+static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct rtable *r = NULL;
+
+ if (v == (void *)1)
+ r = rt_cache_get_first(seq);
+ else
+ r = rt_cache_get_next(seq, v);
+ ++*pos;
+ return r;
+}
+
+static void rt_cache_seq_stop(struct seq_file *seq, void *v)
+{
+ if (v && v != (void *)1) {
+ struct rt_cache_iter_state *st = seq->private;
+
+ read_unlock_bh(&rt_hash_table[st->bucket].lock);
+ }
+}
+
+static int rt_cache_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == (void *)1)
+ seq_printf(seq, "%-127s\n",
+ "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
+ "Metric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\t"
+ "HHUptod\tSpecDst");
+ else {
+ struct rtable *r = v;
+ char temp[256];
+
+ sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
+ "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X",
+ r->u.dst.dev ? r->u.dst.dev->name : "*",
+ (unsigned long)r->rt_dst, (unsigned long)r->rt_gateway,
+ r->rt_flags, atomic_read(&r->u.dst.__refcnt),
+ r->u.dst.__use, 0, (unsigned long)r->rt_src,
+ (dst_metric(&r->u.dst, RTAX_ADVMSS) ?
+ (int)dst_metric(&r->u.dst, RTAX_ADVMSS) + 40 : 0),
+ dst_metric(&r->u.dst, RTAX_WINDOW),
+ (int)((dst_metric(&r->u.dst, RTAX_RTT) >> 3) +
+ dst_metric(&r->u.dst, RTAX_RTTVAR)),
+ r->fl.fl4_tos,
+ r->u.dst.hh ? atomic_read(&r->u.dst.hh->hh_refcnt) : -1,
+ r->u.dst.hh ? (r->u.dst.hh->hh_output ==
+ dev_queue_xmit) : 0,
+ r->rt_spec_dst);
+ seq_printf(seq, "%-127s\n", temp);
+ }
+ return 0;
}
static int rt_cache_stat_get_info(char *buffer, char **start, off_t offset, int length)
@@ -316,6 +350,59 @@ static int rt_cache_stat_get_info(char *buffer, char **start, off_t offset, int
*start = buffer + offset;
return len;
}
+
+static struct seq_operations rt_cache_seq_ops = {
+ .start = rt_cache_seq_start,
+ .next = rt_cache_seq_next,
+ .stop = rt_cache_seq_stop,
+ .show = rt_cache_seq_show,
+};
+
+static int rt_cache_seq_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int rc = -ENOMEM;
+ struct rt_cache_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+
+ if (!s)
+ goto out;
+ rc = seq_open(file, &rt_cache_seq_ops);
+ if (rc)
+ goto out_kfree;
+ seq = file->private_data;
+ seq->private = s;
+ memset(s, 0, sizeof(*s));
+out:
+ return rc;
+out_kfree:
+ kfree(s);
+ goto out;
+}
+
+static struct file_operations rt_cache_seq_fops = {
+ .open = rt_cache_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = ip_seq_release,
+};
+
+int __init rt_cache_proc_init(void)
+{
+ int rc = 0;
+ struct proc_dir_entry *p = create_proc_entry("rt_cache", S_IRUGO,
+ proc_net);
+ if (p)
+ p->proc_fops = &rt_cache_seq_fops;
+ else
+ rc = -ENOMEM;
+ return rc;
+}
+
+void __init rt_cache_proc_exit(void)
+{
+ remove_proc_entry("rt_cache", proc_net);
+}
+#endif /* CONFIG_PROC_FS */
static __inline__ void rt_free(struct rtable *rt)
{
@@ -2456,6 +2543,7 @@ struct ip_rt_acct *ip_rt_acct;
/* IP route accounting ptr for this logical cpu number. */
#define IP_RT_ACCT_CPU(i) (ip_rt_acct + i * 256)
+#ifdef CONFIG_PROC_FS
static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
int length, int *eof, void *data)
{
@@ -2488,11 +2576,12 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
}
return length;
}
-#endif
+#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_NET_CLS_ROUTE */
-void __init ip_rt_init(void)
+int __init ip_rt_init(void)
{
- int i, order, goal;
+ int i, order, goal, rc = 0;
#ifdef CONFIG_NET_CLS_ROUTE
for (order = 0;
@@ -2560,10 +2649,16 @@ void __init ip_rt_init(void)
ip_rt_gc_interval;
add_timer(&rt_periodic_timer);
- proc_net_create ("rt_cache", 0, rt_cache_get_info);
+ if (rt_cache_proc_init())
+ goto out_enomem;
proc_net_create ("rt_cache_stat", 0, rt_cache_stat_get_info);
#ifdef CONFIG_NET_CLS_ROUTE
create_proc_read_entry("net/rt_acct", 0, 0, ip_rt_acct_read, NULL);
#endif
xfrm_init();
+out:
+ return rc;
+out_enomem:
+ rc = -ENOMEM;
+ goto out;
}