diff options
| author | David S. Miller <davem@kernel.bkbits.net> | 2002-12-07 22:28:56 -0800 |
|---|---|---|
| committer | David S. Miller <davem@kernel.bkbits.net> | 2002-12-07 22:28:56 -0800 |
| commit | b72e2aecaaeea6087ffaa4bb91b6b42fb7d0f46a (patch) | |
| tree | 6e4a8abf02884968c7de9ba48d97d3c1568bc17e | |
| parent | 51a169c1962ba2343936f3ff8326fb21eef56a08 (diff) | |
| parent | 43ff0e0d904418ea56b23632bdef704fcfbf6093 (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.txt | 1 | ||||
| -rw-r--r-- | crypto/Makefile | 4 | ||||
| -rw-r--r-- | crypto/api.c | 120 | ||||
| -rw-r--r-- | crypto/internal.h | 9 | ||||
| -rw-r--r-- | crypto/proc.c | 105 | ||||
| -rw-r--r-- | include/linux/crypto.h | 1 | ||||
| -rw-r--r-- | include/net/route.h | 2 | ||||
| -rw-r--r-- | net/ipv4/route.c | 231 |
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; } |
