Commit b72e2aec authored by David S. Miller's avatar David S. Miller

Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5

into kernel.bkbits.net:/home/davem/net-2.5
parents 51a169c1 43ff0e0d
......@@ -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
......
......@@ -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
......
......@@ -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 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
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;
}
......
......@@ -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);
......
/*
* 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;
}
......@@ -161,7 +161,6 @@ struct compress_tfm {
struct crypto_tfm {
void *crt_ctx;
void *crt_work_block;
u32 crt_flags;
union {
......
......@@ -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);
......
......@@ -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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment