Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (79 commits)
  [IPX]: Fix NULL pointer dereference on ipx unload
  [ATM]: atmarp.h needs to always include linux/types.h
  [NET]: Fix net/socket.c warnings.
  [NET]: cleanup sock_from_file()
  [NET]: change layout of ehash table
  [S390]: Add AF_IUCV socket support
  [S390]: Adapt special message interface to new IUCV API
  [S390]: Adapt netiucv driver to new IUCV API
  [S390]: Adapt vmlogrdr driver to new IUCV API
  [S390]: Adapt monreader driver to new IUCV API
  [S390]: Rewrite of the IUCV base code, part 2
  [S390]: Rewrite of the IUCV base code, part 1
  [X.25]: Adds /proc/net/x25/forward to view active forwarded calls.
  [X.25]: Adds /proc/sys/net/x25/x25_forward to control forwarding.
  [X.25]: Add call forwarding
  [XFRM]: xfrm_migrate() needs exporting to modules.
  [PFKEYV2]: CONFIG_NET_KEY_MIGRATE option
  [PFKEYV2]: Extension for dynamic update of endpoint address(es)
  [XFRM]: CONFIG_XFRM_MIGRATE option
  [XFRM]: User interface for handling XFRM_MSG_MIGRATE
  ...
This commit is contained in:
Linus Torvalds 2007-02-09 08:01:37 -08:00
commit f049274b01
213 changed files with 10785 additions and 6110 deletions

View File

@ -193,6 +193,7 @@ Original developers of the crypto algorithms:
Kartikey Mahendra Bhatt (CAST6)
Jon Oberheide (ARC4)
Jouni Malinen (Michael MIC)
NTT(Nippon Telegraph and Telephone Corporation) (Camellia)
SHA1 algorithm contributors:
Jean-Francois Dive
@ -246,6 +247,9 @@ Tiger algorithm contributors:
VIA PadLock contributors:
Michal Ludvig
Camellia algorithm contributors:
NTT(Nippon Telegraph and Telephone Corporation) (Camellia)
Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
Please send any credits updates or corrections to:

View File

@ -179,6 +179,8 @@ CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
CONFIG_NET_KEY=y
CONFIG_IUCV=m
CONFIG_AFIUCV=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
@ -508,7 +510,6 @@ CONFIG_NET_ETHERNET=y
#
CONFIG_LCS=m
CONFIG_CTC=m
CONFIG_IUCV=m
# CONFIG_NETIUCV is not set
# CONFIG_SMSGIUCV is not set
# CONFIG_CLAW is not set

View File

@ -149,6 +149,15 @@ config CRYPTO_CBC
CBC: Cipher Block Chaining mode
This block cipher algorithm is required for IPSec.
config CRYPTO_PCBC
tristate "PCBC support"
select CRYPTO_BLKCIPHER
select CRYPTO_MANAGER
default m
help
PCBC: Propagating Cipher Block Chaining mode
This block cipher algorithm is required for RxRPC.
config CRYPTO_LRW
tristate "LRW support (EXPERIMENTAL)"
depends on EXPERIMENTAL
@ -168,6 +177,13 @@ config CRYPTO_DES
help
DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
config CRYPTO_FCRYPT
tristate "FCrypt cipher algorithm"
select CRYPTO_ALGAPI
select CRYPTO_BLKCIPHER
help
FCrypt algorithm used by RxRPC.
config CRYPTO_BLOWFISH
tristate "Blowfish cipher algorithm"
select CRYPTO_ALGAPI
@ -409,6 +425,21 @@ config CRYPTO_CRC32C
See Castagnoli93. This implementation uses lib/libcrc32c.
Module will be crc32c.
config CRYPTO_CAMELLIA
tristate "Camellia cipher algorithms"
depends on CRYPTO
select CRYPTO_ALGAPI
help
Camellia cipher algorithms module.
Camellia is a symmetric key block cipher developed jointly
at NTT and Mitsubishi Electric Corporation.
The Camellia specifies three key sizes: 128, 192 and 256 bits.
See also:
<https://info.isl.ntt.co.jp/crypt/eng/camellia/index_s.html>
config CRYPTO_TEST
tristate "Testing module"
depends on m

View File

@ -27,13 +27,16 @@ obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
obj-$(CONFIG_CRYPTO_ECB) += ecb.o
obj-$(CONFIG_CRYPTO_CBC) += cbc.o
obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o
obj-$(CONFIG_CRYPTO_LRW) += lrw.o
obj-$(CONFIG_CRYPTO_DES) += des.o
obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
obj-$(CONFIG_CRYPTO_AES) += aes.o
obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia.o
obj-$(CONFIG_CRYPTO_CAST5) += cast5.o
obj-$(CONFIG_CRYPTO_CAST6) += cast6.o
obj-$(CONFIG_CRYPTO_ARC4) += arc4.o

View File

@ -377,7 +377,8 @@ void crypto_drop_spawn(struct crypto_spawn *spawn)
}
EXPORT_SYMBOL_GPL(crypto_drop_spawn);
struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn)
struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
u32 mask)
{
struct crypto_alg *alg;
struct crypto_alg *alg2;
@ -396,10 +397,18 @@ struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn)
return ERR_PTR(-EAGAIN);
}
tfm = __crypto_alloc_tfm(alg, 0);
if (IS_ERR(tfm))
crypto_mod_put(alg);
tfm = ERR_PTR(-EINVAL);
if (unlikely((alg->cra_flags ^ type) & mask))
goto out_put_alg;
tfm = __crypto_alloc_tfm(alg, type, mask);
if (IS_ERR(tfm))
goto out_put_alg;
return tfm;
out_put_alg:
crypto_mod_put(alg);
return tfm;
}
EXPORT_SYMBOL_GPL(crypto_spawn_tfm);

View File

@ -212,31 +212,12 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
}
EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup);
static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
{
tfm->crt_flags = flags & CRYPTO_TFM_REQ_MASK;
flags &= ~CRYPTO_TFM_REQ_MASK;
switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER:
return crypto_init_cipher_flags(tfm, flags);
case CRYPTO_ALG_TYPE_DIGEST:
return crypto_init_digest_flags(tfm, flags);
case CRYPTO_ALG_TYPE_COMPRESS:
return crypto_init_compress_flags(tfm, flags);
}
return 0;
}
const struct crypto_type *type_obj = tfm->__crt_alg->cra_type;
static int crypto_init_ops(struct crypto_tfm *tfm)
{
const struct crypto_type *type = tfm->__crt_alg->cra_type;
if (type)
return type->init(tfm);
if (type_obj)
return type_obj->init(tfm, type, mask);
switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER:
@ -285,29 +266,29 @@ static void crypto_exit_ops(struct crypto_tfm *tfm)
}
}
static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags)
static unsigned int crypto_ctxsize(struct crypto_alg *alg, u32 type, u32 mask)
{
const struct crypto_type *type = alg->cra_type;
const struct crypto_type *type_obj = alg->cra_type;
unsigned int len;
len = alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1);
if (type)
return len + type->ctxsize(alg);
if (type_obj)
return len + type_obj->ctxsize(alg, type, mask);
switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
default:
BUG();
case CRYPTO_ALG_TYPE_CIPHER:
len += crypto_cipher_ctxsize(alg, flags);
len += crypto_cipher_ctxsize(alg);
break;
case CRYPTO_ALG_TYPE_DIGEST:
len += crypto_digest_ctxsize(alg, flags);
len += crypto_digest_ctxsize(alg);
break;
case CRYPTO_ALG_TYPE_COMPRESS:
len += crypto_compress_ctxsize(alg, flags);
len += crypto_compress_ctxsize(alg);
break;
}
@ -322,24 +303,21 @@ void crypto_shoot_alg(struct crypto_alg *alg)
}
EXPORT_SYMBOL_GPL(crypto_shoot_alg);
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags)
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
u32 mask)
{
struct crypto_tfm *tfm = NULL;
unsigned int tfm_size;
int err = -ENOMEM;
tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags);
tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, type, mask);
tfm = kzalloc(tfm_size, GFP_KERNEL);
if (tfm == NULL)
goto out_err;
tfm->__crt_alg = alg;
err = crypto_init_flags(tfm, flags);
if (err)
goto out_free_tfm;
err = crypto_init_ops(tfm);
err = crypto_init_ops(tfm, type, mask);
if (err)
goto out_free_tfm;
@ -362,31 +340,6 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags)
}
EXPORT_SYMBOL_GPL(__crypto_alloc_tfm);
struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
{
struct crypto_tfm *tfm = NULL;
int err;
do {
struct crypto_alg *alg;
alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC);
err = PTR_ERR(alg);
if (IS_ERR(alg))
continue;
tfm = __crypto_alloc_tfm(alg, flags);
err = 0;
if (IS_ERR(tfm)) {
crypto_mod_put(alg);
err = PTR_ERR(tfm);
tfm = NULL;
}
} while (err == -EAGAIN && !signal_pending(current));
return tfm;
}
/*
* crypto_alloc_base - Locate algorithm and allocate transform
* @alg_name: Name of algorithm
@ -420,7 +373,7 @@ struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask)
goto err;
}
tfm = __crypto_alloc_tfm(alg, 0);
tfm = __crypto_alloc_tfm(alg, type, mask);
if (!IS_ERR(tfm))
return tfm;
@ -466,7 +419,6 @@ void crypto_free_tfm(struct crypto_tfm *tfm)
kfree(tfm);
}
EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
EXPORT_SYMBOL_GPL(crypto_free_tfm);
int crypto_has_alg(const char *name, u32 type, u32 mask)

View File

@ -16,6 +16,7 @@
#include <linux/crypto.h>
#include <linux/errno.h>
#include <linux/hardirq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
@ -313,6 +314,9 @@ static int blkcipher_walk_first(struct blkcipher_desc *desc,
struct crypto_blkcipher *tfm = desc->tfm;
unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
if (WARN_ON_ONCE(in_irq()))
return -EDEADLK;
walk->nbytes = walk->total;
if (unlikely(!walk->total))
return 0;
@ -345,7 +349,8 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key,
return cipher->setkey(tfm, key, keylen);
}
static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg)
static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type,
u32 mask)
{
struct blkcipher_alg *cipher = &alg->cra_blkcipher;
unsigned int len = alg->cra_ctxsize;
@ -358,7 +363,7 @@ static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg)
return len;
}
static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm)
static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
{
struct blkcipher_tfm *crt = &tfm->crt_blkcipher;
struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;

1801
crypto/camellia.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -243,6 +243,7 @@ static int crypto_cbc_init_tfm(struct crypto_tfm *tfm)
struct crypto_instance *inst = (void *)tfm->__crt_alg;
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
struct crypto_cbc_ctx *ctx = crypto_tfm_ctx(tfm);
struct crypto_cipher *cipher;
switch (crypto_tfm_alg_blocksize(tfm)) {
case 8:
@ -260,11 +261,11 @@ static int crypto_cbc_init_tfm(struct crypto_tfm *tfm)
ctx->xor = xor_quad;
}
tfm = crypto_spawn_tfm(spawn);
if (IS_ERR(tfm))
return PTR_ERR(tfm);
cipher = crypto_spawn_cipher(spawn);
if (IS_ERR(cipher))
return PTR_ERR(cipher);
ctx->child = crypto_cipher_cast(tfm);
ctx->child = cipher;
return 0;
}

View File

@ -12,274 +12,13 @@
* any later version.
*
*/
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/crypto.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/string.h>
#include <asm/scatterlist.h>
#include "internal.h"
#include "scatterwalk.h"
struct cipher_alg_compat {
unsigned int cia_min_keysize;
unsigned int cia_max_keysize;
int (*cia_setkey)(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen);
void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes);
unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes);
unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes);
unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes);
};
static inline void xor_64(u8 *a, const u8 *b)
{
((u32 *)a)[0] ^= ((u32 *)b)[0];
((u32 *)a)[1] ^= ((u32 *)b)[1];
}
static inline void xor_128(u8 *a, const u8 *b)
{
((u32 *)a)[0] ^= ((u32 *)b)[0];
((u32 *)a)[1] ^= ((u32 *)b)[1];
((u32 *)a)[2] ^= ((u32 *)b)[2];
((u32 *)a)[3] ^= ((u32 *)b)[3];
}
static unsigned int crypt_slow(const struct cipher_desc *desc,
struct scatter_walk *in,
struct scatter_walk *out, unsigned int bsize)
{
unsigned long alignmask = crypto_tfm_alg_alignmask(desc->tfm);
u8 buffer[bsize * 2 + alignmask];
u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
u8 *dst = src + bsize;
scatterwalk_copychunks(src, in, bsize, 0);
desc->prfn(desc, dst, src, bsize);
scatterwalk_copychunks(dst, out, bsize, 1);
return bsize;
}
static inline unsigned int crypt_fast(const struct cipher_desc *desc,
struct scatter_walk *in,
struct scatter_walk *out,
unsigned int nbytes, u8 *tmp)
{
u8 *src, *dst;
u8 *real_src, *real_dst;
real_src = scatterwalk_map(in, 0);
real_dst = scatterwalk_map(out, 1);
src = real_src;
dst = scatterwalk_samebuf(in, out) ? src : real_dst;
if (tmp) {
memcpy(tmp, src, nbytes);
src = tmp;
dst = tmp;
}
nbytes = desc->prfn(desc, dst, src, nbytes);
if (tmp)
memcpy(real_dst, tmp, nbytes);
scatterwalk_unmap(real_src, 0);
scatterwalk_unmap(real_dst, 1);
scatterwalk_advance(in, nbytes);
scatterwalk_advance(out, nbytes);
return nbytes;
}
/*
* Generic encrypt/decrypt wrapper for ciphers, handles operations across
* multiple page boundaries by using temporary blocks. In user context,
* the kernel is given a chance to schedule us once per page.
*/
static int crypt(const struct cipher_desc *desc,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
struct scatter_walk walk_in, walk_out;
struct crypto_tfm *tfm = desc->tfm;
const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
unsigned long buffer = 0;
if (!nbytes)
return 0;
if (nbytes % bsize) {
tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
return -EINVAL;
}
scatterwalk_start(&walk_in, src);
scatterwalk_start(&walk_out, dst);
for(;;) {
unsigned int n = nbytes;
u8 *tmp = NULL;
if (!scatterwalk_aligned(&walk_in, alignmask) ||
!scatterwalk_aligned(&walk_out, alignmask)) {
if (!buffer) {
buffer = __get_free_page(GFP_ATOMIC);
if (!buffer)
n = 0;
}
tmp = (u8 *)buffer;
}
n = scatterwalk_clamp(&walk_in, n);
n = scatterwalk_clamp(&walk_out, n);
if (likely(n >= bsize))
n = crypt_fast(desc, &walk_in, &walk_out, n, tmp);
else
n = crypt_slow(desc, &walk_in, &walk_out, bsize);
nbytes -= n;
scatterwalk_done(&walk_in, 0, nbytes);
scatterwalk_done(&walk_out, 1, nbytes);
if (!nbytes)
break;
crypto_yield(tfm->crt_flags);
}
if (buffer)
free_page(buffer);
return 0;
}
static int crypt_iv_unaligned(struct cipher_desc *desc,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
struct crypto_tfm *tfm = desc->tfm;
unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
u8 *iv = desc->info;
if (unlikely(((unsigned long)iv & alignmask))) {
unsigned int ivsize = tfm->crt_cipher.cit_ivsize;
u8 buffer[ivsize + alignmask];
u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
int err;
desc->info = memcpy(tmp, iv, ivsize);
err = crypt(desc, dst, src, nbytes);
memcpy(iv, tmp, ivsize);
return err;
}
return crypt(desc, dst, src, nbytes);
}
static unsigned int cbc_process_encrypt(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes)
{
struct crypto_tfm *tfm = desc->tfm;
void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block;
int bsize = crypto_tfm_alg_blocksize(tfm);
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn;
u8 *iv = desc->info;
unsigned int done = 0;
nbytes -= bsize;
do {
xor(iv, src);
fn(tfm, dst, iv);
memcpy(iv, dst, bsize);
src += bsize;
dst += bsize;
} while ((done += bsize) <= nbytes);
return done;
}
static unsigned int cbc_process_decrypt(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes)
{
struct crypto_tfm *tfm = desc->tfm;
void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block;
int bsize = crypto_tfm_alg_blocksize(tfm);
unsigned long alignmask = crypto_tfm_alg_alignmask(desc->tfm);
u8 stack[src == dst ? bsize + alignmask : 0];
u8 *buf = (u8 *)ALIGN((unsigned long)stack, alignmask + 1);
u8 **dst_p = src == dst ? &buf : &dst;
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn;
u8 *iv = desc->info;
unsigned int done = 0;
nbytes -= bsize;
do {
u8 *tmp_dst = *dst_p;
fn(tfm, tmp_dst, src);
xor(tmp_dst, iv);
memcpy(iv, src, bsize);
if (tmp_dst != dst)
memcpy(dst, tmp_dst, bsize);
src += bsize;
dst += bsize;
} while ((done += bsize) <= nbytes);
return done;
}
static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst,
const u8 *src, unsigned int nbytes)
{
struct crypto_tfm *tfm = desc->tfm;
int bsize = crypto_tfm_alg_blocksize(tfm);
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn;
unsigned int done = 0;
nbytes -= bsize;
do {
fn(tfm, dst, src);
src += bsize;
dst += bsize;
} while ((done += bsize) <= nbytes);
return done;
}
static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
{
@ -293,122 +32,6 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
return cia->cia_setkey(tfm, key, keylen);
}
static int ecb_encrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src, unsigned int nbytes)
{
struct cipher_desc desc;
struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
desc.tfm = tfm;
desc.crfn = cipher->cia_encrypt;
desc.prfn = cipher->cia_encrypt_ecb ?: ecb_process;
return crypt(&desc, dst, src, nbytes);
}
static int ecb_decrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
struct cipher_desc desc;
struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
desc.tfm = tfm;
desc.crfn = cipher->cia_decrypt;
desc.prfn = cipher->cia_decrypt_ecb ?: ecb_process;
return crypt(&desc, dst, src, nbytes);
}
static int cbc_encrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
struct cipher_desc desc;
struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
desc.tfm = tfm;
desc.crfn = cipher->cia_encrypt;
desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt;
desc.info = tfm->crt_cipher.cit_iv;
return crypt(&desc, dst, src, nbytes);
}
static int cbc_encrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv)
{
struct cipher_desc desc;
struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
desc.tfm = tfm;
desc.crfn = cipher->cia_encrypt;
desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt;
desc.info = iv;
return crypt_iv_unaligned(&desc, dst, src, nbytes);
}
static int cbc_decrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
struct cipher_desc desc;
struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
desc.tfm = tfm;
desc.crfn = cipher->cia_decrypt;
desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt;
desc.info = tfm->crt_cipher.cit_iv;
return crypt(&desc, dst, src, nbytes);
}
static int cbc_decrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv)
{
struct cipher_desc desc;
struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher;
desc.tfm = tfm;
desc.crfn = cipher->cia_decrypt;
desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt;
desc.info = iv;
return crypt_iv_unaligned(&desc, dst, src, nbytes);
}
static int nocrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
return -ENOSYS;
}
static int nocrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv)
{
return -ENOSYS;
}
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
{
u32 mode = flags & CRYPTO_TFM_MODE_MASK;
tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
return 0;
}
static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *,
const u8 *),
struct crypto_tfm *tfm,
@ -454,7 +77,6 @@ static void cipher_decrypt_unaligned(struct crypto_tfm *tfm,
int crypto_init_cipher_ops(struct crypto_tfm *tfm)
{
int ret = 0;
struct cipher_tfm *ops = &tfm->crt_cipher;
struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
@ -464,70 +86,7 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm)
ops->cit_decrypt_one = crypto_tfm_alg_alignmask(tfm) ?
cipher_decrypt_unaligned : cipher->cia_decrypt;
switch (tfm->crt_cipher.cit_mode) {
case CRYPTO_TFM_MODE_ECB:
ops->cit_encrypt = ecb_encrypt;
ops->cit_decrypt = ecb_decrypt;
ops->cit_encrypt_iv = nocrypt_iv;
ops->cit_decrypt_iv = nocrypt_iv;
break;
case CRYPTO_TFM_MODE_CBC:
ops->cit_encrypt = cbc_encrypt;
ops->cit_decrypt = cbc_decrypt;
ops->cit_encrypt_iv = cbc_encrypt_iv;
ops->cit_decrypt_iv = cbc_decrypt_iv;
break;
case CRYPTO_TFM_MODE_CFB:
ops->cit_encrypt = nocrypt;
ops->cit_decrypt = nocrypt;
ops->cit_encrypt_iv = nocrypt_iv;
ops->cit_decrypt_iv = nocrypt_iv;
break;
case CRYPTO_TFM_MODE_CTR:
ops->cit_encrypt = nocrypt;
ops->cit_decrypt = nocrypt;
ops->cit_encrypt_iv = nocrypt_iv;
ops->cit_decrypt_iv = nocrypt_iv;
break;
default:
BUG();
}
if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) {
unsigned long align;
unsigned long addr;
switch (crypto_tfm_alg_blocksize(tfm)) {
case 8:
ops->cit_xor_block = xor_64;
break;
case 16:
ops->cit_xor_block = xor_128;
break;
default:
printk(KERN_WARNING "%s: block size %u not supported\n",
crypto_tfm_alg_name(tfm),
crypto_tfm_alg_blocksize(tfm));
ret = -EINVAL;
goto out;
}
ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm);
align = crypto_tfm_alg_alignmask(tfm) + 1;
addr = (unsigned long)crypto_tfm_ctx(tfm);
addr = ALIGN(addr, align);
addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align);
ops->cit_iv = (void *)addr;
}
out:
return ret;
return 0;
}
void crypto_exit_cipher_ops(struct crypto_tfm *tfm)

View File

@ -34,11 +34,6 @@ static int crypto_decompress(struct crypto_tfm *tfm,
dlen);
}
int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
{
return flags ? -EINVAL : 0;
}
int crypto_init_compress_ops(struct crypto_tfm *tfm)
{
struct compress_tfm *ops = &tfm->crt_compress;

View File

@ -14,7 +14,9 @@
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/hardirq.h>
#include <linux/highmem.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
@ -29,8 +31,8 @@ static int init(struct hash_desc *desc)
return 0;
}
static int update(struct hash_desc *desc,
struct scatterlist *sg, unsigned int nbytes)
static int update2(struct hash_desc *desc,
struct scatterlist *sg, unsigned int nbytes)
{
struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
@ -81,6 +83,14 @@ static int update(struct hash_desc *desc,
return 0;
}
static int update(struct hash_desc *desc,
struct scatterlist *sg, unsigned int nbytes)
{
if (WARN_ON_ONCE(in_irq()))
return -EDEADLK;
return update2(desc, sg, nbytes);
}
static int final(struct hash_desc *desc, u8 *out)
{
struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
@ -118,14 +128,12 @@ static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen)
static int digest(struct hash_desc *desc,
struct scatterlist *sg, unsigned int nbytes, u8 *out)
{
init(desc);
update(desc, sg, nbytes);
return final(desc, out);
}
if (WARN_ON_ONCE(in_irq()))
return -EDEADLK;
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
{
return flags ? -EINVAL : 0;
init(desc);
update2(desc, sg, nbytes);
return final(desc, out);
}
int crypto_init_digest_ops(struct crypto_tfm *tfm)

View File

@ -99,12 +99,13 @@ static int crypto_ecb_init_tfm(struct crypto_tfm *tfm)
struct crypto_instance *inst = (void *)tfm->__crt_alg;
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
struct crypto_ecb_ctx *ctx = crypto_tfm_ctx(tfm);
struct crypto_cipher *cipher;
tfm = crypto_spawn_tfm(spawn);
if (IS_ERR(tfm))
return PTR_ERR(tfm);
cipher = crypto_spawn_cipher(spawn);
if (IS_ERR(cipher))
return PTR_ERR(cipher);
ctx->child = crypto_cipher_cast(tfm);
ctx->child = cipher;
return 0;
}

423
crypto/fcrypt.c Normal file
View File

@ -0,0 +1,423 @@
/* FCrypt encryption algorithm
*
* Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* 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.
*
* Based on code:
*
* Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <asm/byteorder.h>
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/crypto.h>
#define ROUNDS 16
struct fcrypt_ctx {
u32 sched[ROUNDS];
};
/* Rotate right two 32 bit numbers as a 56 bit number */
#define ror56(hi, lo, n) \
do { \
u32 t = lo & ((1 << n) - 1); \
lo = (lo >> n) | ((hi & ((1 << n) - 1)) << (32 - n)); \
hi = (hi >> n) | (t << (24-n)); \
} while(0)
/* Rotate right one 64 bit number as a 56 bit number */
#define ror56_64(k, n) \
do { \
k = (k >> n) | ((k & ((1 << n) - 1)) << (56 - n)); \
} while(0)
/*
* Sboxes for Feistel network derived from
* /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h
*/
#undef Z
#define Z(x) __constant_be32_to_cpu(x << 3)
static const u32 sbox0[256] = {
Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11),
Z(0xcd), Z(0x86), Z(0x86), Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06),
Z(0x0e), Z(0x06), Z(0xd2), Z(0x65), Z(0x73), Z(0xc5), Z(0x28), Z(0x60),
Z(0xf2), Z(0x20), Z(0xb5), Z(0x38), Z(0x7e), Z(0xda), Z(0x9f), Z(0xe3),
Z(0xd2), Z(0xcf), Z(0xc4), Z(0x3c), Z(0x61), Z(0xff), Z(0x4a), Z(0x4a),
Z(0x35), Z(0xac), Z(0xaa), Z(0x5f), Z(0x2b), Z(0xbb), Z(0xbc), Z(0x53),
Z(0x4e), Z(0x9d), Z(0x78), Z(0xa3), Z(0xdc), Z(0x09), Z(0x32), Z(0x10),
Z(0xc6), Z(0x6f), Z(0x66), Z(0xd6), Z(0xab), Z(0xa9), Z(0xaf), Z(0xfd),
Z(0x3b), Z(0x95), Z(0xe8), Z(0x34), Z(0x9a), Z(0x81), Z(0x72), Z(0x80),
Z(0x9c), Z(0xf3), Z(0xec), Z(0xda), Z(0x9f), Z(0x26), Z(0x76), Z(0x15),
Z(0x3e), Z(0x55), Z(0x4d), Z(0xde), Z(0x84), Z(0xee), Z(0xad), Z(0xc7),
Z(0xf1), Z(0x6b), Z(0x3d), Z(0xd3), Z(0x04), Z(0x49), Z(0xaa), Z(0x24),
Z(0x0b), Z(0x8a), Z(0x83), Z(0xba), Z(0xfa), Z(0x85), Z(0xa0), Z(0xa8),
Z(0xb1), Z(0xd4), Z(0x01), Z(0xd8), Z(0x70), Z(0x64), Z(0xf0), Z(0x51),
Z(0xd2), Z(0xc3), Z(0xa7), Z(0x75), Z(0x8c), Z(0xa5), Z(0x64), Z(0xef),
Z(0x10), Z(0x4e), Z(0xb7), Z(0xc6), Z(0x61), Z(0x03), Z(0xeb), Z(0x44),
Z(0x3d), Z(0xe5), Z(0xb3), Z(0x5b), Z(0xae), Z(0xd5), Z(0xad), Z(0x1d),
Z(0xfa), Z(0x5a), Z(0x1e), Z(0x33), Z(0xab), Z(0x93), Z(0xa2), Z(0xb7),
Z(0xe7), Z(0xa8), Z(0x45), Z(0xa4), Z(0xcd), Z(0x29), Z(0x63), Z(0x44),
Z(0xb6), Z(0x69), Z(0x7e), Z(0x2e), Z(0x62), Z(0x03), Z(0xc8), Z(0xe0),
Z(0x17), Z(0xbb), Z(0xc7), Z(0xf3), Z(0x3f), Z(0x36), Z(0xba), Z(0x71),
Z(0x8e), Z(0x97), Z(0x65), Z(0x60), Z(0x69), Z(0xb6), Z(0xf6), Z(0xe6),
Z(0x6e), Z(0xe0), Z(0x81), Z(0x59), Z(0xe8), Z(0xaf), Z(0xdd), Z(0x95),
Z(0x22), Z(0x99), Z(0xfd), Z(0x63), Z(0x19), Z(0x74), Z(0x61), Z(0xb1),
Z(0xb6), Z(0x5b), Z(0xae), Z(0x54), Z(0xb3), Z(0x70), Z(0xff), Z(0xc6),
Z(0x3b), Z(0x3e), Z(0xc1), Z(0xd7), Z(0xe1), Z(0x0e), Z(0x76), Z(0xe5),
Z(0x36), Z(0x4f), Z(0x59), Z(0xc7), Z(0x08), Z(0x6e), Z(0x82), Z(0xa6),
Z(0x93), Z(0xc4), Z(0xaa), Z(0x26), Z(0x49), Z(0xe0), Z(0x21), Z(0x64),
Z(0x07), Z(0x9f), Z(0x64), Z(0x81), Z(0x9c), Z(0xbf), Z(0xf9), Z(0xd1),
Z(0x43), Z(0xf8), Z(0xb6), Z(0xb9), Z(0xf1), Z(0x24), Z(0x75), Z(0x03),
Z(0xe4), Z(0xb0), Z(0x99), Z(0x46), Z(0x3d), Z(0xf5), Z(0xd1), Z(0x39),
Z(0x72), Z(0x12), Z(0xf6), Z(0xba), Z(0x0c), Z(0x0d), Z(0x42), Z(0x2e)
};
#undef Z
#define Z(x) __constant_be32_to_cpu((x << 27) | (x >> 5))
static const u32 sbox1[256] = {
Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e),
Z(0x67), Z(0x6c), Z(0xa1), Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85),
Z(0x6c), Z(0x7b), Z(0x67), Z(0xc6), Z(0x23), Z(0xe3), Z(0xf2), Z(0x89),
Z(0x50), Z(0x9c), Z(0x03), Z(0xb7), Z(0x73), Z(0xe6), Z(0xe1), Z(0x39),
Z(0x31), Z(0x2c), Z(0x27), Z(0x9f), Z(0xa5), Z(0x69), Z(0x44), Z(0xd6),
Z(0x23), Z(0x83), Z(0x98), Z(0x7d), Z(0x3c), Z(0xb4), Z(0x2d), Z(0x99),
Z(0x1c), Z(0x1f), Z(0x8c), Z(0x20), Z(0x03), Z(0x7c), Z(0x5f), Z(0xad),
Z(0xf4), Z(0xfa), Z(0x95), Z(0xca), Z(0x76), Z(0x44), Z(0xcd), Z(0xb6),
Z(0xb8), Z(0xa1), Z(0xa1), Z(0xbe), Z(0x9e), Z(0x54), Z(0x8f), Z(0x0b),
Z(0x16), Z(0x74), Z(0x31), Z(0x8a), Z(0x23), Z(0x17), Z(0x04), Z(0xfa),
Z(0x79), Z(0x84), Z(0xb1), Z(0xf5), Z(0x13), Z(0xab), Z(0xb5), Z(0x2e),
Z(0xaa), Z(0x0c), Z(0x60), Z(0x6b), Z(0x5b), Z(0xc4), Z(0x4b), Z(0xbc),
Z(0xe2), Z(0xaf), Z(0x45), Z(0x73), Z(0xfa), Z(0xc9), Z(0x49), Z(0xcd),
Z(0x00), Z(0x92), Z(0x7d), Z(0x97), Z(0x7a), Z(0x18), Z(0x60), Z(0x3d),
Z(0xcf), Z(0x5b), Z(0xde), Z(0xc6), Z(0xe2), Z(0xe6), Z(0xbb), Z(0x8b),
Z(0x06), Z(0xda), Z(0x08), Z(0x15), Z(0x1b), Z(0x88), Z(0x6a), Z(0x17),
Z(0x89), Z(0xd0), Z(0xa9), Z(0xc1), Z(0xc9), Z(0x70), Z(0x6b), Z(0xe5),
Z(0x43), Z(0xf4), Z(0x68), Z(0xc8), Z(0xd3), Z(0x84), Z(0x28), Z(0x0a),
Z(0x52), Z(0x66), Z(0xa3), Z(0xca), Z(0xf2), Z(0xe3), Z(0x7f), Z(0x7a),
Z(0x31), Z(0xf7), Z(0x88), Z(0x94), Z(0x5e), Z(0x9c), Z(0x63), Z(0xd5),
Z(0x24), Z(0x66), Z(0xfc), Z(0xb3), Z(0x57), Z(0x25), Z(0xbe), Z(0x89),
Z(0x44), Z(0xc4), Z(0xe0), Z(0x8f), Z(0x23), Z(0x3c), Z(0x12), Z(0x52),
Z(0xf5), Z(0x1e), Z(0xf4), Z(0xcb), Z(0x18), Z(0x33), Z(0x1f), Z(0xf8),
Z(0x69), Z(0x10), Z(0x9d), Z(0xd3), Z(0xf7), Z(0x28), Z(0xf8), Z(0x30),
Z(0x05), Z(0x5e), Z(0x32), Z(0xc0), Z(0xd5), Z(0x19), Z(0xbd), Z(0x45),
Z(0x8b), Z(0x5b), Z(0xfd), Z(0xbc), Z(0xe2), Z(0x5c), Z(0xa9), Z(0x96),
Z(0xef), Z(0x70), Z(0xcf), Z(0xc2), Z(0x2a), Z(0xb3), Z(0x61), Z(0xad),
Z(0x80), Z(0x48), Z(0x81), Z(0xb7), Z(0x1d), Z(0x43), Z(0xd9), Z(0xd7),
Z(0x45), Z(0xf0), Z(0xd8), Z(0x8a), Z(0x59), Z(0x7c), Z(0x57), Z(0xc1),
Z(0x79), Z(0xc7), Z(0x34), Z(0xd6), Z(0x43), Z(0xdf), Z(0xe4), Z(0x78),
Z(0x16), Z(0x06), Z(0xda), Z(0x92), Z(0x76), Z(0x51), Z(0xe1), Z(0xd4),
Z(0x70), Z(0x03), Z(0xe0), Z(0x2f), Z(0x96), Z(0x91), Z(0x82), Z(0x80)
};
#undef Z
#define Z(x) __constant_be32_to_cpu(x << 11)
static const u32 sbox2[256] = {
Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86),
Z(0xd1), Z(0xec), Z(0x50), Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d),
Z(0xbf), Z(0x80), Z(0x87), Z(0x27), Z(0x95), Z(0xe2), Z(0xc5), Z(0x5d),
Z(0xf9), Z(0x6f), Z(0xdb), Z(0xb4), Z(0x65), Z(0x6e), Z(0xe7), Z(0x24),
Z(0xc8), Z(0x1a), Z(0xbb), Z(0x49), Z(0xb5), Z(0x0a), Z(0x7d), Z(0xb9),
Z(0xe8), Z(0xdc), Z(0xb7), Z(0xd9), Z(0x45), Z(0x20), Z(0x1b), Z(0xce),
Z(0x59), Z(0x9d), Z(0x6b), Z(0xbd), Z(0x0e), Z(0x8f), Z(0xa3), Z(0xa9),
Z(0xbc), Z(0x74), Z(0xa6), Z(0xf6), Z(0x7f), Z(0x5f), Z(0xb1), Z(0x68),
Z(0x84), Z(0xbc), Z(0xa9), Z(0xfd), Z(0x55), Z(0x50), Z(0xe9), Z(0xb6),
Z(0x13), Z(0x5e), Z(0x07), Z(0xb8), Z(0x95), Z(0x02), Z(0xc0), Z(0xd0),
Z(0x6a), Z(0x1a), Z(0x85), Z(0xbd), Z(0xb6), Z(0xfd), Z(0xfe), Z(0x17),
Z(0x3f), Z(0x09), Z(0xa3), Z(0x8d), Z(0xfb), Z(0xed), Z(0xda), Z(0x1d),
Z(0x6d), Z(0x1c), Z(0x6c), Z(0x01), Z(0x5a), Z(0xe5), Z(0x71), Z(0x3e),
Z(0x8b), Z(0x6b), Z(0xbe), Z(0x29), Z(0xeb), Z(0x12), Z(0x19), Z(0x34),
Z(0xcd), Z(0xb3), Z(0xbd), Z(0x35), Z(0xea), Z(0x4b), Z(0xd5), Z(0xae),
Z(0x2a), Z(0x79), Z(0x5a), Z(0xa5), Z(0x32), Z(0x12), Z(0x7b), Z(0xdc),
Z(0x2c), Z(0xd0), Z(0x22), Z(0x4b), Z(0xb1), Z(0x85), Z(0x59), Z(0x80),
Z(0xc0), Z(0x30), Z(0x9f), Z(0x73), Z(0xd3), Z(0x14), Z(0x48), Z(0x40),
Z(0x07), Z(0x2d), Z(0x8f), Z(0x80), Z(0x0f), Z(0xce), Z(0x0b), Z(0x5e),
Z(0xb7), Z(0x5e), Z(0xac), Z(0x24), Z(0x94), Z(0x4a), Z(0x18), Z(0x15),
Z(0x05), Z(0xe8), Z(0x02), Z(0x77), Z(0xa9), Z(0xc7), Z(0x40), Z(0x45),
Z(0x89), Z(0xd1), Z(0xea), Z(0xde), Z(0x0c), Z(0x79), Z(0x2a), Z(0x99),
Z(0x6c), Z(0x3e), Z(0x95), Z(0xdd), Z(0x8c), Z(0x7d), Z(0xad), Z(0x6f),
Z(0xdc), Z(0xff), Z(0xfd), Z(0x62), Z(0x47), Z(0xb3), Z(0x21), Z(0x8a),
Z(0xec), Z(0x8e), Z(0x19), Z(0x18), Z(0xb4), Z(0x6e), Z(0x3d), Z(0xfd),
Z(0x74), Z(0x54), Z(0x1e), Z(0x04), Z(0x85), Z(0xd8), Z(0xbc), Z(0x1f),
Z(0x56), Z(0xe7), Z(0x3a), Z(0x56), Z(0x67), Z(0xd6), Z(0xc8), Z(0xa5),
Z(0xf3), Z(0x8e), Z(0xde), Z(0xae), Z(0x37), Z(0x49), Z(0xb7), Z(0xfa),
Z(0xc8), Z(0xf4), Z(0x1f), Z(0xe0), Z(0x2a), Z(0x9b), Z(0x15), Z(0xd1),
Z(0x34), Z(0x0e), Z(0xb5), Z(0xe0), Z(0x44), Z(0x78), Z(0x84), Z(0x59),
Z(0x56), Z(0x68), Z(0x77), Z(0xa5), Z(0x14), Z(0x06), Z(0xf5), Z(0x2f),
Z(0x8c), Z(0x8a), Z(0x73), Z(0x80), Z(0x76), Z(0xb4), Z(0x10), Z(0x86)
};
#undef Z
#define Z(x) __constant_be32_to_cpu(x << 19)
static const u32 sbox3[256] = {
Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2),
Z(0xb5), Z(0xb7), Z(0x42), Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12),
Z(0x44), Z(0x48), Z(0x6d), Z(0x28), Z(0xaa), Z(0x20), Z(0x6d), Z(0x57),
Z(0xd6), Z(0x6b), Z(0x5d), Z(0x72), Z(0xf0), Z(0x92), Z(0x5a), Z(0x1b),
Z(0x53), Z(0x80), Z(0x24), Z(0x70), Z(0x9a), Z(0xcc), Z(0xa7), Z(0x66),
Z(0xa1), Z(0x01), Z(0xa5), Z(0x41), Z(0x97), Z(0x41), Z(0x31), Z(0x82),
Z(0xf1), Z(0x14), Z(0xcf), Z(0x53), Z(0x0d), Z(0xa0), Z(0x10), Z(0xcc),
Z(0x2a), Z(0x7d), Z(0xd2), Z(0xbf), Z(0x4b), Z(0x1a), Z(0xdb), Z(0x16),
Z(0x47), Z(0xf6), Z(0x51), Z(0x36), Z(0xed), Z(0xf3), Z(0xb9), Z(0x1a),
Z(0xa7), Z(0xdf), Z(0x29), Z(0x43), Z(0x01), Z(0x54), Z(0x70), Z(0xa4),
Z(0xbf), Z(0xd4), Z(0x0b), Z(0x53), Z(0x44), Z(0x60), Z(0x9e), Z(0x23),
Z(0xa1), Z(0x18), Z(0x68), Z(0x4f), Z(0xf0), Z(0x2f), Z(0x82), Z(0xc2),
Z(0x2a), Z(0x41), Z(0xb2), Z(0x42), Z(0x0c), Z(0xed), Z(0x0c), Z(0x1d),
Z(0x13), Z(0x3a), Z(0x3c), Z(0x6e), Z(0x35), Z(0xdc), Z(0x60), Z(0x65),
Z(0x85), Z(0xe9), Z(0x64), Z(0x02), Z(0x9a), Z(0x3f), Z(0x9f), Z(0x87),
Z(0x96), Z(0xdf), Z(0xbe), Z(0xf2), Z(0xcb), Z(0xe5), Z(0x6c), Z(0xd4),
Z(0x5a), Z(0x83), Z(0xbf), Z(0x92), Z(0x1b), Z(0x94), Z(0x00), Z(0x42),
Z(0xcf), Z(0x4b), Z(0x00), Z(0x75), Z(0xba), Z(0x8f), Z(0x76), Z(0x5f),
Z(0x5d), Z(0x3a), Z(0x4d), Z(0x09), Z(0x12), Z(0x08), Z(0x38), Z(0x95),
Z(0x17), Z(0xe4), Z(0x01), Z(0x1d), Z(0x4c), Z(0xa9), Z(0xcc), Z(0x85),
Z(0x82), Z(0x4c), Z(0x9d), Z(0x2f), Z(0x3b), Z(0x66), Z(0xa1), Z(0x34),
Z(0x10), Z(0xcd), Z(0x59), Z(0x89), Z(0xa5), Z(0x31), Z(0xcf), Z(0x05),
Z(0xc8), Z(0x84), Z(0xfa), Z(0xc7), Z(0xba), Z(0x4e), Z(0x8b), Z(0x1a),
Z(0x19), Z(0xf1), Z(0xa1), Z(0x3b), Z(0x18), Z(0x12), Z(0x17), Z(0xb0),
Z(0x98), Z(0x8d), Z(0x0b), Z(0x23), Z(0xc3), Z(0x3a), Z(0x2d), Z(0x20),
Z(0xdf), Z(0x13), Z(0xa0), Z(0xa8), Z(0x4c), Z(0x0d), Z(0x6c), Z(0x2f),
Z(0x47), Z(0x13), Z(0x13), Z(0x52), Z(0x1f), Z(0x2d), Z(0xf5), Z(0x79),
Z(0x3d), Z(0xa2), Z(0x54), Z(0xbd), Z(0x69), Z(0xc8), Z(0x6b), Z(0xf3),
Z(0x05), Z(0x28), Z(0xf1), Z(0x16), Z(0x46), Z(0x40), Z(0xb0), Z(0x11),
Z(0xd3), Z(0xb7), Z(0x95), Z(0x49), Z(0xcf), Z(0xc3), Z(0x1d), Z(0x8f),
Z(0xd8), Z(0xe1), Z(0x73), Z(0xdb), Z(0xad), Z(0xc8), Z(0xc9), Z(0xa9),
Z(0xa1), Z(0xc2), Z(0xc5), Z(0xe3), Z(0xba), Z(0xfc), Z(0x0e), Z(0x25)
};
/*
* This is a 16 round Feistel network with permutation F_ENCRYPT
*/
#define F_ENCRYPT(R, L, sched) \
do { \
union lc4 { u32 l; u8 c[4]; } u; \
u.l = sched ^ R; \
L ^= sbox0[u.c[0]] ^ sbox1[u.c[1]] ^ sbox2[u.c[2]] ^ sbox3[u.c[3]]; \
} while(0)
/*
* encryptor
*/
static void fcrypt_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
{
const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm);
struct {
u32 l, r;
} X;
memcpy(&X, src, sizeof(X));
F_ENCRYPT(X.r, X.l, ctx->sched[0x0]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x1]);
F_ENCRYPT(X.r, X.l, ctx->sched[0x2]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x3]);
F_ENCRYPT(X.r, X.l, ctx->sched[0x4]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x5]);
F_ENCRYPT(X.r, X.l, ctx->sched[0x6]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x7]);
F_ENCRYPT(X.r, X.l, ctx->sched[0x8]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x9]);
F_ENCRYPT(X.r, X.l, ctx->sched[0xa]);
F_ENCRYPT(X.l, X.r, ctx->sched[0xb]);
F_ENCRYPT(X.r, X.l, ctx->sched[0xc]);
F_ENCRYPT(X.l, X.r, ctx->sched[0xd]);
F_ENCRYPT(X.r, X.l, ctx->sched[0xe]);
F_ENCRYPT(X.l, X.r, ctx->sched[0xf]);
memcpy(dst, &X, sizeof(X));
}
/*
* decryptor
*/
static void fcrypt_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
{
const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm);
struct {
u32 l, r;
} X;
memcpy(&X, src, sizeof(X));
F_ENCRYPT(X.l, X.r, ctx->sched[0xf]);
F_ENCRYPT(X.r, X.l, ctx->sched[0xe]);
F_ENCRYPT(X.l, X.r, ctx->sched[0xd]);
F_ENCRYPT(X.r, X.l, ctx->sched[0xc]);
F_ENCRYPT(X.l, X.r, ctx->sched[0xb]);
F_ENCRYPT(X.r, X.l, ctx->sched[0xa]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x9]);
F_ENCRYPT(X.r, X.l, ctx->sched[0x8]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x7]);
F_ENCRYPT(X.r, X.l, ctx->sched[0x6]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x5]);
F_ENCRYPT(X.r, X.l, ctx->sched[0x4]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x3]);
F_ENCRYPT(X.r, X.l, ctx->sched[0x2]);
F_ENCRYPT(X.l, X.r, ctx->sched[0x1]);
F_ENCRYPT(X.r, X.l, ctx->sched[0x0]);
memcpy(dst, &X, sizeof(X));
}
/*
* Generate a key schedule from key, the least significant bit in each key byte
* is parity and shall be ignored. This leaves 56 significant bits in the key
* to scatter over the 16 key schedules. For each schedule extract the low
* order 32 bits and use as schedule, then rotate right by 11 bits.
*/
static int fcrypt_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
{
struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm);
#if BITS_PER_LONG == 64 /* the 64-bit version can also be used for 32-bit
* kernels - it seems to be faster but the code is
* larger */
u64 k; /* k holds all 56 non-parity bits */
/* discard the parity bits */
k = (*key++) >> 1;
k <<= 7;
k |= (*key++) >> 1;
k <<= 7;
k |= (*key++) >> 1;
k <<= 7;
k |= (*key++) >> 1;
k <<= 7;
k |= (*key++) >> 1;
k <<= 7;
k |= (*key++) >> 1;
k <<= 7;
k |= (*key++) >> 1;
k <<= 7;
k |= (*key) >> 1;
/* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
ctx->sched[0x0] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0x1] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0x2] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0x3] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0x4] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0x5] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0x6] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0x7] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0x8] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0x9] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0xa] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0xb] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0xc] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0xd] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0xe] = be32_to_cpu(k); ror56_64(k, 11);
ctx->sched[0xf] = be32_to_cpu(k);
return 0;
#else
u32 hi, lo; /* hi is upper 24 bits and lo lower 32, total 56 */
/* discard the parity bits */
lo = (*key++) >> 1;
lo <<= 7;
lo |= (*key++) >> 1;
lo <<= 7;
lo |= (*key++) >> 1;
lo <<= 7;
lo |= (*key++) >> 1;
hi = lo >> 4;
lo &= 0xf;
lo <<= 7;
lo |= (*key++) >> 1;
lo <<= 7;
lo |= (*key++) >> 1;
lo <<= 7;
lo |= (*key++) >> 1;
lo <<= 7;
lo |= (*key) >> 1;
/* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
ctx->sched[0x0] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0x1] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0x2] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0x3] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0x4] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0x5] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0x6] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0x7] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0x8] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0x9] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0xa] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0xb] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0xc] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0xd] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0xe] = be32_to_cpu(lo); ror56(hi, lo, 11);
ctx->sched[0xf] = be32_to_cpu(lo);
return 0;
#endif
}
static struct crypto_alg fcrypt_alg = {
.cra_name = "fcrypt",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = 8,
.cra_ctxsize = sizeof(struct fcrypt_ctx),
.cra_module = THIS_MODULE,
.cra_alignmask = 3,
.cra_list = LIST_HEAD_INIT(fcrypt_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = 8,
.cia_max_keysize = 8,
.cia_setkey = fcrypt_setkey,
.cia_encrypt = fcrypt_encrypt,
.cia_decrypt = fcrypt_decrypt } }
};
static int __init init(void)
{
return crypto_register_alg(&fcrypt_alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&fcrypt_alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("FCrypt Cipher Algorithm");
MODULE_AUTHOR("David Howells <dhowells@redhat.com>");

View File

@ -16,12 +16,13 @@
#include "internal.h"
static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg)
static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg, u32 type,
u32 mask)
{
return alg->cra_ctxsize;
}
static int crypto_init_hash_ops(struct crypto_tfm *tfm)
static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
{
struct hash_tfm *crt = &tfm->crt_hash;
struct hash_alg *alg = &tfm->__crt_alg->cra_hash;

View File

@ -172,15 +172,16 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
static int hmac_init_tfm(struct crypto_tfm *tfm)
{
struct crypto_hash *hash;
struct crypto_instance *inst = (void *)tfm->__crt_alg;
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
struct hmac_ctx *ctx = hmac_ctx(__crypto_hash_cast(tfm));
tfm = crypto_spawn_tfm(spawn);
if (IS_ERR(tfm))
return PTR_ERR(tfm);
hash = crypto_spawn_hash(spawn);
if (IS_ERR(hash))
return PTR_ERR(hash);
ctx->child = crypto_hash_cast(tfm);
ctx->child = hash;
return 0;
}

View File

@ -83,8 +83,7 @@ static inline void crypto_exit_proc(void)
{ }
#endif
static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg,
int flags)
static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg)
{
unsigned int len = alg->cra_ctxsize;
@ -96,23 +95,12 @@ static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg,
return len;
}
static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg,
int flags)
static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg)
{
unsigned int len = alg->cra_ctxsize;
switch (flags & CRYPTO_TFM_MODE_MASK) {
case CRYPTO_TFM_MODE_CBC:
len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1);
len += alg->cra_blocksize;
break;
}
return len;
return alg->cra_ctxsize;
}
static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg,
int flags)
static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg)
{
return alg->cra_ctxsize;
}
@ -121,10 +109,6 @@ struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);
struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask);
struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
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);
int crypto_init_digest_ops(struct crypto_tfm *tfm);
int crypto_init_cipher_ops(struct crypto_tfm *tfm);
int crypto_init_compress_ops(struct crypto_tfm *tfm);
@ -136,7 +120,8 @@ void crypto_exit_compress_ops(struct crypto_tfm *tfm);
void crypto_larval_error(const char *name, u32 type, u32 mask);
void crypto_shoot_alg(struct crypto_alg *alg);
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags);
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
u32 mask);
int crypto_register_instance(struct crypto_template *tmpl,
struct crypto_instance *inst);

View File

@ -201,21 +201,22 @@ static int decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
static int init_tfm(struct crypto_tfm *tfm)
{
struct crypto_cipher *cipher;
struct crypto_instance *inst = (void *)tfm->__crt_alg;
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
struct priv *ctx = crypto_tfm_ctx(tfm);
u32 *flags = &tfm->crt_flags;
tfm = crypto_spawn_tfm(spawn);
if (IS_ERR(tfm))
return PTR_ERR(tfm);
cipher = crypto_spawn_cipher(spawn);
if (IS_ERR(cipher))
return PTR_ERR(cipher);
if (crypto_tfm_alg_blocksize(tfm) != 16) {
if (crypto_cipher_blocksize(cipher) != 16) {
*flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
return -EINVAL;
}
ctx->child = crypto_cipher_cast(tfm);
ctx->child = cipher;
return 0;
}

349
crypto/pcbc.c Normal file
View File

@ -0,0 +1,349 @@
/*
* PCBC: Propagating Cipher Block Chaining mode
*
* Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* Derived from cbc.c
* - Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.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 <crypto/algapi.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
struct crypto_pcbc_ctx {
struct crypto_cipher *child;
void (*xor)(u8 *dst, const u8 *src, unsigned int bs);
};
static int crypto_pcbc_setkey(struct crypto_tfm *parent, const u8 *key,
unsigned int keylen)
{
struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(parent);
struct crypto_cipher *child = ctx->child;
int err;
crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
CRYPTO_TFM_REQ_MASK);
err = crypto_cipher_setkey(child, key, keylen);
crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
CRYPTO_TFM_RES_MASK);
return err;
}
static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
struct crypto_cipher *tfm,
void (*xor)(u8 *, const u8 *,
unsigned int))
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_encrypt;
int bsize = crypto_cipher_blocksize(tfm);
unsigned int nbytes = walk->nbytes;
u8 *src = walk->src.virt.addr;
u8 *dst = walk->dst.virt.addr;
u8 *iv = walk->iv;
do {
xor(iv, src, bsize);
fn(crypto_cipher_tfm(tfm), dst, iv);
memcpy(iv, dst, bsize);
xor(iv, src, bsize);
src += bsize;
dst += bsize;
} while ((nbytes -= bsize) >= bsize);
return nbytes;
}
static int crypto_pcbc_encrypt_inplace(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
struct crypto_cipher *tfm,
void (*xor)(u8 *, const u8 *,
unsigned int))
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_encrypt;
int bsize = crypto_cipher_blocksize(tfm);
unsigned int nbytes = walk->nbytes;
u8 *src = walk->src.virt.addr;
u8 *iv = walk->iv;
u8 tmpbuf[bsize];
do {
memcpy(tmpbuf, src, bsize);
xor(iv, tmpbuf, bsize);
fn(crypto_cipher_tfm(tfm), src, iv);
memcpy(iv, src, bsize);
xor(iv, tmpbuf, bsize);
src += bsize;
} while ((nbytes -= bsize) >= bsize);
memcpy(walk->iv, iv, bsize);
return nbytes;
}
static int crypto_pcbc_encrypt(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes)
{
struct blkcipher_walk walk;
struct crypto_blkcipher *tfm = desc->tfm;
struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
struct crypto_cipher *child = ctx->child;
void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);
while ((nbytes = walk.nbytes)) {
if (walk.src.virt.addr == walk.dst.virt.addr)
nbytes = crypto_pcbc_encrypt_inplace(desc, &walk, child,
xor);
else
nbytes = crypto_pcbc_encrypt_segment(desc, &walk, child,
xor);
err = blkcipher_walk_done(desc, &walk, nbytes);
}
return err;
}
static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
struct crypto_cipher *tfm,
void (*xor)(u8 *, const u8 *,
unsigned int))
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_decrypt;
int bsize = crypto_cipher_blocksize(tfm);
unsigned int nbytes = walk->nbytes;
u8 *src = walk->src.virt.addr;
u8 *dst = walk->dst.virt.addr;
u8 *iv = walk->iv;
do {
fn(crypto_cipher_tfm(tfm), dst, src);
xor(dst, iv, bsize);
memcpy(iv, src, bsize);
xor(iv, dst, bsize);
src += bsize;
dst += bsize;
} while ((nbytes -= bsize) >= bsize);
memcpy(walk->iv, iv, bsize);
return nbytes;
}
static int crypto_pcbc_decrypt_inplace(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
struct crypto_cipher *tfm,
void (*xor)(u8 *, const u8 *,
unsigned int))
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_decrypt;
int bsize = crypto_cipher_blocksize(tfm);
unsigned int nbytes = walk->nbytes;
u8 *src = walk->src.virt.addr;
u8 *iv = walk->iv;
u8 tmpbuf[bsize];
do {
memcpy(tmpbuf, src, bsize);
fn(crypto_cipher_tfm(tfm), src, src);
xor(src, iv, bsize);
memcpy(iv, tmpbuf, bsize);
xor(iv, src, bsize);
src += bsize;
} while ((nbytes -= bsize) >= bsize);
memcpy(walk->iv, iv, bsize);
return nbytes;
}
static int crypto_pcbc_decrypt(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes)
{
struct blkcipher_walk walk;
struct crypto_blkcipher *tfm = desc->tfm;
struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
struct crypto_cipher *child = ctx->child;
void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);
while ((nbytes = walk.nbytes)) {
if (walk.src.virt.addr == walk.dst.virt.addr)
nbytes = crypto_pcbc_decrypt_inplace(desc, &walk, child,
xor);
else
nbytes = crypto_pcbc_decrypt_segment(desc, &walk, child,
xor);
err = blkcipher_walk_done(desc, &walk, nbytes);
}
return err;
}
static void xor_byte(u8 *a, const u8 *b, unsigned int bs)
{
do {
*a++ ^= *b++;
} while (--bs);
}
static void xor_quad(u8 *dst, const u8 *src, unsigned int bs)
{
u32 *a = (u32 *)dst;
u32 *b = (u32 *)src;
do {
*a++ ^= *b++;
} while ((bs -= 4));
}
static void xor_64(u8 *a, const u8 *b, unsigned int bs)
{
((u32 *)a)[0] ^= ((u32 *)b)[0];
((u32 *)a)[1] ^= ((u32 *)b)[1];
}
static void xor_128(u8 *a, const u8 *b, unsigned int bs)
{
((u32 *)a)[0] ^= ((u32 *)b)[0];
((u32 *)a)[1] ^= ((u32 *)b)[1];
((u32 *)a)[2] ^= ((u32 *)b)[2];
((u32 *)a)[3] ^= ((u32 *)b)[3];
}
static int crypto_pcbc_init_tfm(struct crypto_tfm *tfm)
{
struct crypto_instance *inst = (void *)tfm->__crt_alg;
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(tfm);
struct crypto_cipher *cipher;
switch (crypto_tfm_alg_blocksize(tfm)) {
case 8:
ctx->xor = xor_64;
break;
case 16:
ctx->xor = xor_128;
break;
default:
if (crypto_tfm_alg_blocksize(tfm) % 4)
ctx->xor = xor_byte;
else
ctx->xor = xor_quad;
}
cipher = crypto_spawn_cipher(spawn);
if (IS_ERR(cipher))
return PTR_ERR(cipher);
ctx->child = cipher;
return 0;
}
static void crypto_pcbc_exit_tfm(struct crypto_tfm *tfm)
{
struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(tfm);
crypto_free_cipher(ctx->child);
}
static struct crypto_instance *crypto_pcbc_alloc(void *param, unsigned int len)
{
struct crypto_instance *inst;
struct crypto_alg *alg;
alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));
inst = crypto_alloc_instance("pcbc", alg);
if (IS_ERR(inst))
goto out_put_alg;
inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
inst->alg.cra_priority = alg->cra_priority;
inst->alg.cra_blocksize = alg->cra_blocksize;
inst->alg.cra_alignmask = alg->cra_alignmask;
inst->alg.cra_type = &crypto_blkcipher_type;
if (!(alg->cra_blocksize % 4))
inst->alg.cra_alignmask |= 3;
inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize;
inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
inst->alg.cra_ctxsize = sizeof(struct crypto_pcbc_ctx);
inst->alg.cra_init = crypto_pcbc_init_tfm;
inst->alg.cra_exit = crypto_pcbc_exit_tfm;
inst->alg.cra_blkcipher.setkey = crypto_pcbc_setkey;
inst->alg.cra_blkcipher.encrypt = crypto_pcbc_encrypt;
inst->alg.cra_blkcipher.decrypt = crypto_pcbc_decrypt;
out_put_alg:
crypto_mod_put(alg);
return inst;
}
static void crypto_pcbc_free(struct crypto_instance *inst)
{
crypto_drop_spawn(crypto_instance_ctx(inst));
kfree(inst);
}
static struct crypto_template crypto_pcbc_tmpl = {
.name = "pcbc",
.alloc = crypto_pcbc_alloc,
.free = crypto_pcbc_free,
.module = THIS_MODULE,
};
static int __init crypto_pcbc_module_init(void)
{
return crypto_register_template(&crypto_pcbc_tmpl);
}
static void __exit crypto_pcbc_module_exit(void)
{
crypto_unregister_template(&crypto_pcbc_tmpl);
}
module_init(crypto_pcbc_module_init);
module_exit(crypto_pcbc_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PCBC block cipher algorithm");

View File

@ -12,6 +12,7 @@
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests
* 2004-08-09 Added cipher speed tests (Reyk Floeter <reyk@vantronix.net>)
* 2003-09-14 Rewritten by Kartikey Mahendra Bhatt
*
@ -71,7 +72,8 @@ static char *check[] = {
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
"arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
"khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", NULL
"khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt",
"camellia", NULL
};
static void hexdump(unsigned char *buf, unsigned int len)
@ -765,7 +767,7 @@ static void test_deflate(void)
memcpy(tvmem, deflate_comp_tv_template, tsize);
tv = (void *)tvmem;
tfm = crypto_alloc_tfm("deflate", 0);
tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC);
if (tfm == NULL) {
printk("failed to load transform for deflate\n");
return;
@ -964,6 +966,26 @@ static void do_test(void)
test_cipher("ecb(xeta)", DECRYPT, xeta_dec_tv_template,
XETA_DEC_TEST_VECTORS);
//FCrypt
test_cipher("pcbc(fcrypt)", ENCRYPT, fcrypt_pcbc_enc_tv_template,
FCRYPT_ENC_TEST_VECTORS);
test_cipher("pcbc(fcrypt)", DECRYPT, fcrypt_pcbc_dec_tv_template,
FCRYPT_DEC_TEST_VECTORS);
//CAMELLIA
test_cipher("ecb(camellia)", ENCRYPT,
camellia_enc_tv_template,
CAMELLIA_ENC_TEST_VECTORS);
test_cipher("ecb(camellia)", DECRYPT,
camellia_dec_tv_template,
CAMELLIA_DEC_TEST_VECTORS);
test_cipher("cbc(camellia)", ENCRYPT,
camellia_cbc_enc_tv_template,
CAMELLIA_CBC_ENC_TEST_VECTORS);
test_cipher("cbc(camellia)", DECRYPT,
camellia_cbc_dec_tv_template,
CAMELLIA_CBC_DEC_TEST_VECTORS);
test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS);
@ -980,6 +1002,10 @@ static void do_test(void)
HMAC_SHA1_TEST_VECTORS);
test_hash("hmac(sha256)", hmac_sha256_tv_template,
HMAC_SHA256_TEST_VECTORS);
test_hash("hmac(sha384)", hmac_sha384_tv_template,
HMAC_SHA384_TEST_VECTORS);
test_hash("hmac(sha512)", hmac_sha512_tv_template,
HMAC_SHA512_TEST_VECTORS);
test_hash("xcbc(aes)", aes_xcbc128_tv_template,
XCBC_AES_TEST_VECTORS);
@ -1177,6 +1203,28 @@ static void do_test(void)
XETA_DEC_TEST_VECTORS);
break;
case 31:
test_cipher("pcbc(fcrypt)", ENCRYPT, fcrypt_pcbc_enc_tv_template,
FCRYPT_ENC_TEST_VECTORS);
test_cipher("pcbc(fcrypt)", DECRYPT, fcrypt_pcbc_dec_tv_template,
FCRYPT_DEC_TEST_VECTORS);
break;
case 32:
test_cipher("ecb(camellia)", ENCRYPT,
camellia_enc_tv_template,
CAMELLIA_ENC_TEST_VECTORS);
test_cipher("ecb(camellia)", DECRYPT,
camellia_dec_tv_template,
CAMELLIA_DEC_TEST_VECTORS);
test_cipher("cbc(camellia)", ENCRYPT,
camellia_cbc_enc_tv_template,
CAMELLIA_CBC_ENC_TEST_VECTORS);
test_cipher("cbc(camellia)", DECRYPT,
camellia_cbc_dec_tv_template,
CAMELLIA_CBC_DEC_TEST_VECTORS);
break;
case 100:
test_hash("hmac(md5)", hmac_md5_tv_template,
HMAC_MD5_TEST_VECTORS);
@ -1192,6 +1240,16 @@ static void do_test(void)
HMAC_SHA256_TEST_VECTORS);
break;
case 103:
test_hash("hmac(sha384)", hmac_sha384_tv_template,
HMAC_SHA384_TEST_VECTORS);
break;
case 104:
test_hash("hmac(sha512)", hmac_sha512_tv_template,
HMAC_SHA512_TEST_VECTORS);
break;
case 200:
test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
@ -1260,6 +1318,17 @@ static void do_test(void)
des_speed_template);
break;
case 205:
test_cipher_speed("ecb(camellia)", ENCRYPT, sec, NULL, 0,
camellia_speed_template);
test_cipher_speed("ecb(camellia)", DECRYPT, sec, NULL, 0,
camellia_speed_template);
test_cipher_speed("cbc(camellia)", ENCRYPT, sec, NULL, 0,
camellia_speed_template);
test_cipher_speed("cbc(camellia)", DECRYPT, sec, NULL, 0,
camellia_speed_template);
break;
case 300:
/* fall through */

View File

@ -12,6 +12,7 @@
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests
* 2004-08-09 Cipher speed tests by Reyk Floeter <reyk@vantronix.net>
* 2003-09-14 Changes by Kartikey Mahendra Bhatt
*
@ -27,7 +28,7 @@
struct hash_testvec {
/* only used with keyed hash algorithms */
char key[128] __attribute__ ((__aligned__(4)));
char key[132] __attribute__ ((__aligned__(4)));
char plaintext[240];
char digest[MAX_DIGEST_SIZE];
unsigned char tap[MAX_TAP];
@ -1001,6 +1002,248 @@ static struct hash_testvec aes_xcbc128_tv_template[] = {
}
};
/*
* SHA384 HMAC test vectors from RFC4231
*/
#define HMAC_SHA384_TEST_VECTORS 4
static struct hash_testvec hmac_sha384_tv_template[] = {
{
.key = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b }, // (20 bytes)
.ksize = 20,
.plaintext = { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 }, // ("Hi There")
.psize = 8,
.digest = { 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f,
0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 },
}, {
.key = { 0x4a, 0x65, 0x66, 0x65 }, // ("Jefe")
.ksize = 4,
.plaintext = { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, // ("what do ya want ")
0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
0x69, 0x6e, 0x67, 0x3f }, // ("for nothing?")
.psize = 28,
.digest = { 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e,
0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 },
.np = 4,
.tap = { 7, 7, 7, 7 }
}, {
.key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa }, // (131 bytes)
.ksize = 131,
.plaintext = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, // ("Test Using Large")
0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, // ("r Than Block-Siz")
0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, // ("e Key - Hash Key")
0x20, 0x46, 0x69, 0x72, 0x73, 0x74 }, // (" First")
.psize = 54,
.digest = { 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90,
0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4,
0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6,
0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 },
}, {
.key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa }, // (131 bytes)
.ksize = 131,
.plaintext = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75, // ("This is a test u")
0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c,
0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, // ("sing a larger th")
0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65, // ("an block-size ke")
0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20,
0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, // ("y and a larger t")
0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64, // ("han block-size d")
0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65,
0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65, // ("ata. The key nee")
0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65,
0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, // ("ds to be hashed ")
0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62,
0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, // ("before being use")
0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65,
0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c, // ("d by the HMAC al")
0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e }, // ("gorithm.")
.psize = 152,
.digest = { 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d,
0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c,
0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5,
0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e },
},
};
/*
* SHA512 HMAC test vectors from RFC4231
*/
#define HMAC_SHA512_TEST_VECTORS 4
static struct hash_testvec hmac_sha512_tv_template[] = {
{
.key = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b }, // (20 bytes)
.ksize = 20,
.plaintext = { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 }, // ("Hi There")
.psize = 8,
.digest = { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 },
}, {
.key = { 0x4a, 0x65, 0x66, 0x65 }, // ("Jefe")
.ksize = 4,
.plaintext = { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, // ("what do ya want ")
0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
0x69, 0x6e, 0x67, 0x3f }, // ("for nothing?")
.psize = 28,
.digest = { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b,
0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 },
.np = 4,
.tap = { 7, 7, 7, 7 }
}, {
.key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa }, // (131 bytes)
.ksize = 131,
.plaintext = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, // ("Test Using Large")
0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, // ("r Than Block-Siz")
0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, // ("e Key - Hash Key")
0x20, 0x46, 0x69, 0x72, 0x73, 0x74 }, // (" First")
.psize = 54,
.digest = { 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb,
0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1,
0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec,
0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 },
}, {
.key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa }, // (131 bytes)
.ksize = 131,
.plaintext = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75, // ("This is a test u")
0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c,
0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, // ("sing a larger th")
0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65, // ("an block-size ke")
0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20,
0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, // ("y and a larger t")
0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64, // ("han block-size d")
0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65,
0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65, // ("ata. The key nee")
0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65,
0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, // ("ds to be hashed ")
0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62,
0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, // ("before being use")
0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65,
0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c, // ("d by the HMAC al")
0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e }, // ("gorithm.")
.psize = 152,
.digest = { 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba,
0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86,
0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60,
0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 },
},
};
/*
* DES test vectors.
*/
@ -3316,6 +3559,278 @@ static struct cipher_testvec xeta_dec_tv_template[] = {
}
};
/*
* FCrypt test vectors
*/
#define FCRYPT_ENC_TEST_VECTORS ARRAY_SIZE(fcrypt_pcbc_enc_tv_template)
#define FCRYPT_DEC_TEST_VECTORS ARRAY_SIZE(fcrypt_pcbc_dec_tv_template)
static struct cipher_testvec fcrypt_pcbc_enc_tv_template[] = {
{ /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
.key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.klen = 8,
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.ilen = 8,
.result = { 0x0E, 0x09, 0x00, 0xC7, 0x3E, 0xF7, 0xED, 0x41 },
.rlen = 8,
}, {
.key = { 0x11, 0x44, 0x77, 0xAA, 0xDD, 0x00, 0x33, 0x66 },
.klen = 8,
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.input = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 },
.ilen = 8,
.result = { 0xD8, 0xED, 0x78, 0x74, 0x77, 0xEC, 0x06, 0x80 },
.rlen = 8,
}, { /* From Arla */
.key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
.klen = 8,
.iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.input = "The quick brown fox jumps over the lazy dogs.\0\0",
.ilen = 48,
.result = { 0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82,
0xee, 0xac, 0x98, 0x62, 0x44, 0x51, 0xe4, 0x84,
0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7,
0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03,
0x23, 0xb5, 0x62, 0xd7, 0x0c, 0xf5, 0x27, 0xd1,
0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef },
.rlen = 48,
}, {
.key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.klen = 8,
.iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
.input = "The quick brown fox jumps over the lazy dogs.\0\0",
.ilen = 48,
.result = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c,
0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d,
0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58,
0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0,
0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94,
0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f },
.rlen = 48,
}, { /* split-page version */
.key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.klen = 8,
.iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
.input = "The quick brown fox jumps over the lazy dogs.\0\0",
.ilen = 48,
.result = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c,
0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d,
0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58,
0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0,
0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94,
0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f },
.rlen = 48,
.np = 2,
.tap = { 20, 28 },
}
};
static struct cipher_testvec fcrypt_pcbc_dec_tv_template[] = {
{ /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
.key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.klen = 8,
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.input = { 0x0E, 0x09, 0x00, 0xC7, 0x3E, 0xF7, 0xED, 0x41 },
.ilen = 8,
.result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.rlen = 8,
}, {
.key = { 0x11, 0x44, 0x77, 0xAA, 0xDD, 0x00, 0x33, 0x66 },
.klen = 8,
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.input = { 0xD8, 0xED, 0x78, 0x74, 0x77, 0xEC, 0x06, 0x80 },
.ilen = 8,
.result = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 },
.rlen = 8,
}, { /* From Arla */
.key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
.klen = 8,
.iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.input = { 0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82,
0xee, 0xac, 0x98, 0x62, 0x44, 0x51, 0xe4, 0x84,
0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7,
0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03,
0x23, 0xb5, 0x62, 0xd7, 0x0c, 0xf5, 0x27, 0xd1,
0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef },
.ilen = 48,
.result = "The quick brown fox jumps over the lazy dogs.\0\0",
.rlen = 48,
}, {
.key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.klen = 8,
.iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
.input = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c,
0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d,
0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58,
0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0,
0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94,
0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f },
.ilen = 48,
.result = "The quick brown fox jumps over the lazy dogs.\0\0",
.rlen = 48,
}, { /* split-page version */
.key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.klen = 8,
.iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
.input = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c,
0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d,
0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58,
0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0,
0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94,
0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f },
.ilen = 48,
.result = "The quick brown fox jumps over the lazy dogs.\0\0",
.rlen = 48,
.np = 2,
.tap = { 20, 28 },
}
};
/*
* CAMELLIA test vectors.
*/
#define CAMELLIA_ENC_TEST_VECTORS 3
#define CAMELLIA_DEC_TEST_VECTORS 3
#define CAMELLIA_CBC_ENC_TEST_VECTORS 2
#define CAMELLIA_CBC_DEC_TEST_VECTORS 2
static struct cipher_testvec camellia_enc_tv_template[] = {
{
.key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.klen = 16,
.input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.ilen = 16,
.result = { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
.rlen = 16,
}, {
.key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
.klen = 24,
.input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.ilen = 16,
.result = { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
.rlen = 16,
}, {
.key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
.klen = 32,
.input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.ilen = 16,
.result = { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
.rlen = 16,
},
};
static struct cipher_testvec camellia_dec_tv_template[] = {
{
.key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.klen = 16,
.input = { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
.ilen = 16,
.result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.rlen = 16,
}, {
.key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
.klen = 24,
.input = { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
.ilen = 16,
.result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.rlen = 16,
}, {
.key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
.klen = 32,
.input = { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
.ilen = 16,
.result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
.rlen = 16,
},
};
static struct cipher_testvec camellia_cbc_enc_tv_template[] = {
{
.key = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
.klen = 16,
.iv = { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
.input = { "Single block msg" },
.ilen = 16,
.result = { 0xea, 0x32, 0x12, 0x76, 0x3b, 0x50, 0x10, 0xe7,
0x18, 0xf6, 0xfd, 0x5d, 0xf6, 0x8f, 0x13, 0x51 },
.rlen = 16,
}, {
.key = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
.klen = 16,
.iv = { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
.input = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
.ilen = 32,
.result = { 0xa5, 0xdf, 0x6e, 0x50, 0xda, 0x70, 0x6c, 0x01,
0x4a, 0xab, 0xf3, 0xf2, 0xd6, 0xfc, 0x6c, 0xfd,
0x19, 0xb4, 0x3e, 0x57, 0x1c, 0x02, 0x5e, 0xa0,
0x15, 0x78, 0xe0, 0x5e, 0xf2, 0xcb, 0x87, 0x16 },
.rlen = 32,
},
};
static struct cipher_testvec camellia_cbc_dec_tv_template[] = {
{
.key = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
.klen = 16,
.iv = { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
.input = { 0xea, 0x32, 0x12, 0x76, 0x3b, 0x50, 0x10, 0xe7,
0x18, 0xf6, 0xfd, 0x5d, 0xf6, 0x8f, 0x13, 0x51 },
.ilen = 16,
.result = { "Single block msg" },
.rlen = 16,
}, {
.key = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
.klen = 16,
.iv = { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
.input = { 0xa5, 0xdf, 0x6e, 0x50, 0xda, 0x70, 0x6c, 0x01,
0x4a, 0xab, 0xf3, 0xf2, 0xd6, 0xfc, 0x6c, 0xfd,
0x19, 0xb4, 0x3e, 0x57, 0x1c, 0x02, 0x5e, 0xa0,
0x15, 0x78, 0xe0, 0x5e, 0xf2, 0xcb, 0x87, 0x16 },
.ilen = 32,
.result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
.rlen = 32,
},
};
/*
* Compression stuff.
*/
@ -3769,4 +4284,25 @@ static struct hash_speed generic_hash_speed_template[] = {
{ .blen = 0, .plen = 0, }
};
static struct cipher_speed camellia_speed_template[] = {
{ .klen = 16, .blen = 16, },
{ .klen = 16, .blen = 64, },
{ .klen = 16, .blen = 256, },
{ .klen = 16, .blen = 1024, },
{ .klen = 16, .blen = 8192, },
{ .klen = 24, .blen = 16, },
{ .klen = 24, .blen = 64, },
{ .klen = 24, .blen = 256, },
{ .klen = 24, .blen = 1024, },
{ .klen = 24, .blen = 8192, },
{ .klen = 32, .blen = 16, },
{ .klen = 32, .blen = 64, },
{ .klen = 32, .blen = 256, },
{ .klen = 32, .blen = 1024, },
{ .klen = 32, .blen = 8192, },
/* End marker */
{ .klen = 0, .blen = 0, }
};
#endif /* _CRYPTO_TCRYPT_H */

View File

@ -21,6 +21,7 @@
#include <linux/crypto.h>
#include <linux/err.h>
#include <linux/hardirq.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/rtnetlink.h>
@ -47,7 +48,7 @@ static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
* +------------------------
*/
struct crypto_xcbc_ctx {
struct crypto_tfm *child;
struct crypto_cipher *child;
u8 *odds;
u8 *prev;
u8 *key;
@ -75,8 +76,7 @@ static int _crypto_xcbc_digest_setkey(struct crypto_hash *parent,
if ((err = crypto_cipher_setkey(ctx->child, ctx->key, ctx->keylen)))
return err;
ctx->child->__crt_alg->cra_cipher.cia_encrypt(ctx->child, key1,
ctx->consts);
crypto_cipher_encrypt_one(ctx->child, key1, ctx->consts);
return crypto_cipher_setkey(ctx->child, key1, bs);
}
@ -86,7 +86,7 @@ static int crypto_xcbc_digest_setkey(struct crypto_hash *parent,
{
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent);
if (keylen != crypto_tfm_alg_blocksize(ctx->child))
if (keylen != crypto_cipher_blocksize(ctx->child))
return -EINVAL;
ctx->keylen = keylen;
@ -108,13 +108,13 @@ static int crypto_xcbc_digest_init(struct hash_desc *pdesc)
return 0;
}
static int crypto_xcbc_digest_update(struct hash_desc *pdesc,
struct scatterlist *sg,
unsigned int nbytes)
static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
struct scatterlist *sg,
unsigned int nbytes)
{
struct crypto_hash *parent = pdesc->tfm;
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent);
struct crypto_tfm *tfm = ctx->child;
struct crypto_cipher *tfm = ctx->child;
int bs = crypto_hash_blocksize(parent);
unsigned int i = 0;
@ -142,7 +142,7 @@ static int crypto_xcbc_digest_update(struct hash_desc *pdesc,
offset += len;
crypto_kunmap(p, 0);
crypto_yield(tfm->crt_flags);
crypto_yield(pdesc->flags);
continue;
}
@ -152,7 +152,7 @@ static int crypto_xcbc_digest_update(struct hash_desc *pdesc,
p += bs - ctx->len;
ctx->xor(ctx->prev, ctx->odds, bs);
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, ctx->prev, ctx->prev);
crypto_cipher_encrypt_one(tfm, ctx->prev, ctx->prev);
/* clearing the length */
ctx->len = 0;
@ -160,7 +160,8 @@ static int crypto_xcbc_digest_update(struct hash_desc *pdesc,
/* encrypting the rest of data */
while (len > bs) {
ctx->xor(ctx->prev, p, bs);
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, ctx->prev, ctx->prev);
crypto_cipher_encrypt_one(tfm, ctx->prev,
ctx->prev);
p += bs;
len -= bs;
}
@ -171,7 +172,7 @@ static int crypto_xcbc_digest_update(struct hash_desc *pdesc,
ctx->len = len;
}
crypto_kunmap(p, 0);
crypto_yield(tfm->crt_flags);
crypto_yield(pdesc->flags);
slen -= min(slen, ((unsigned int)(PAGE_SIZE)) - offset);
offset = 0;
pg++;
@ -183,11 +184,20 @@ static int crypto_xcbc_digest_update(struct hash_desc *pdesc,
return 0;
}
static int crypto_xcbc_digest_update(struct hash_desc *pdesc,
struct scatterlist *sg,
unsigned int nbytes)
{
if (WARN_ON_ONCE(in_irq()))
return -EDEADLK;
return crypto_xcbc_digest_update2(pdesc, sg, nbytes);
}
static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out)
{
struct crypto_hash *parent = pdesc->tfm;
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent);
struct crypto_tfm *tfm = ctx->child;
struct crypto_cipher *tfm = ctx->child;
int bs = crypto_hash_blocksize(parent);
int err = 0;
@ -197,13 +207,14 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out)
if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0)
return err;
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key2, (const u8*)(ctx->consts+bs));
crypto_cipher_encrypt_one(tfm, key2,
(u8 *)(ctx->consts + bs));
ctx->xor(ctx->prev, ctx->odds, bs);
ctx->xor(ctx->prev, key2, bs);
_crypto_xcbc_digest_setkey(parent, ctx);
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, ctx->prev);
crypto_cipher_encrypt_one(tfm, out, ctx->prev);
} else {
u8 key3[bs];
unsigned int rlen;
@ -218,14 +229,15 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out)
if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0)
return err;
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key3, (const u8*)(ctx->consts+bs*2));
crypto_cipher_encrypt_one(tfm, key3,
(u8 *)(ctx->consts + bs * 2));
ctx->xor(ctx->prev, ctx->odds, bs);
ctx->xor(ctx->prev, key3, bs);
_crypto_xcbc_digest_setkey(parent, ctx);
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, ctx->prev);
crypto_cipher_encrypt_one(tfm, out, ctx->prev);
}
return 0;
@ -234,21 +246,25 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out)
static int crypto_xcbc_digest(struct hash_desc *pdesc,
struct scatterlist *sg, unsigned int nbytes, u8 *out)
{
if (WARN_ON_ONCE(in_irq()))
return -EDEADLK;
crypto_xcbc_digest_init(pdesc);
crypto_xcbc_digest_update(pdesc, sg, nbytes);
crypto_xcbc_digest_update2(pdesc, sg, nbytes);
return crypto_xcbc_digest_final(pdesc, out);
}
static int xcbc_init_tfm(struct crypto_tfm *tfm)
{
struct crypto_cipher *cipher;
struct crypto_instance *inst = (void *)tfm->__crt_alg;
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(__crypto_hash_cast(tfm));
int bs = crypto_hash_blocksize(__crypto_hash_cast(tfm));
tfm = crypto_spawn_tfm(spawn);
if (IS_ERR(tfm))
return PTR_ERR(tfm);
cipher = crypto_spawn_cipher(spawn);
if (IS_ERR(cipher))
return PTR_ERR(cipher);
switch(bs) {
case 16:
@ -258,7 +274,7 @@ static int xcbc_init_tfm(struct crypto_tfm *tfm)
return -EINVAL;
}
ctx->child = crypto_cipher_cast(tfm);
ctx->child = cipher;
ctx->odds = (u8*)(ctx+1);
ctx->prev = ctx->odds + bs;
ctx->key = ctx->prev + bs;

View File

@ -457,7 +457,7 @@ static struct pci_driver geode_aes_driver = {
static int __init
geode_aes_init(void)
{
return pci_module_init(&geode_aes_driver);
return pci_register_driver(&geode_aes_driver);
}
static void __exit

View File

@ -184,7 +184,7 @@ static int tlb_initialize(struct bonding *bond)
spin_lock_init(&(bond_info->tx_hashtbl_lock));
new_hashtbl = kmalloc(size, GFP_KERNEL);
new_hashtbl = kzalloc(size, GFP_KERNEL);
if (!new_hashtbl) {
printk(KERN_ERR DRV_NAME
": %s: Error: Failed to allocate TLB hash table\n",
@ -195,8 +195,6 @@ static int tlb_initialize(struct bonding *bond)
bond_info->tx_hashtbl = new_hashtbl;
memset(bond_info->tx_hashtbl, 0, size);
for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) {
tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1);
}

View File

@ -1343,14 +1343,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
"inaccurate.\n", bond_dev->name, slave_dev->name);
}
new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL);
new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
if (!new_slave) {
res = -ENOMEM;
goto err_undo_flags;
}
memset(new_slave, 0, sizeof(struct slave));
/* save slave's original flags before calling
* netdev_set_master and dev_open
*/

View File

@ -1343,15 +1343,12 @@ static int __init slip_init(void)
printk(KERN_INFO "SLIP linefill/keepalive option.\n");
#endif
slip_devs = kmalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL);
slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL);
if (!slip_devs) {
printk(KERN_ERR "SLIP: Can't allocate slip devices array! Uaargh! (-> No SLIP available)\n");
return -ENOMEM;
}
/* Clear the pointer array, we allocate devices when we need them */
memset(slip_devs, 0, sizeof(struct net_device *)*slip_maxdev);
/* Fill in our line protocol discipline, and register it */
if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) {
printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status);

View File

@ -3380,7 +3380,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
}
next_pkt_nopost:
sw_idx++;
sw_idx %= TG3_RX_RCB_RING_SIZE(tp);
sw_idx &= (TG3_RX_RCB_RING_SIZE(tp) - 1);
/* Refresh hw_idx to see if there is new work */
if (sw_idx == hw_idx) {

View File

@ -3,7 +3,7 @@
*
* Character device driver for reading z/VM *MONITOR service records.
*
* Copyright (C) 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH.
* Copyright 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH.
*
* Author: Gerald Schaefer <geraldsc@de.ibm.com>
*/
@ -22,7 +22,7 @@
#include <asm/ebcdic.h>
#include <asm/extmem.h>
#include <linux/poll.h>
#include "../net/iucv.h"
#include <net/iucv/iucv.h>
//#define MON_DEBUG /* Debug messages on/off */
@ -50,14 +50,13 @@ static char mon_dcss_name[9] = "MONDCSS\0";
struct mon_msg {
u32 pos;
u32 mca_offset;
iucv_MessagePending local_eib;
struct iucv_message msg;
char msglim_reached;
char replied_msglim;
};
struct mon_private {
u16 pathid;
iucv_handle_t iucv_handle;
struct iucv_path *path;
struct mon_msg *msg_array[MON_MSGLIM];
unsigned int write_index;
unsigned int read_index;
@ -75,8 +74,6 @@ static unsigned long mon_dcss_end;
static DECLARE_WAIT_QUEUE_HEAD(mon_read_wait_queue);
static DECLARE_WAIT_QUEUE_HEAD(mon_conn_wait_queue);
static u8 iucv_host[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static u8 user_data_connect[16] = {
/* Version code, must be 0x01 for shared mode */
0x01,
@ -100,8 +97,7 @@ static u8 user_data_sever[16] = {
* Create the 8 bytes EBCDIC DCSS segment name from
* an ASCII name, incl. padding
*/
static inline void
dcss_mkname(char *ascii_name, char *ebcdic_name)
static inline void dcss_mkname(char *ascii_name, char *ebcdic_name)
{
int i;
@ -119,8 +115,7 @@ dcss_mkname(char *ascii_name, char *ebcdic_name)
* print appropriate error message for segment_load()/segment_type()
* return code
*/
static void
mon_segment_warn(int rc, char* seg_name)
static void mon_segment_warn(int rc, char* seg_name)
{
switch (rc) {
case -ENOENT:
@ -166,44 +161,37 @@ mon_segment_warn(int rc, char* seg_name)
}
}
static inline unsigned long
mon_mca_start(struct mon_msg *monmsg)
static inline unsigned long mon_mca_start(struct mon_msg *monmsg)
{
return monmsg->local_eib.ln1msg1.iprmmsg1_u32;
return *(u32 *) &monmsg->msg.rmmsg;
}
static inline unsigned long
mon_mca_end(struct mon_msg *monmsg)
static inline unsigned long mon_mca_end(struct mon_msg *monmsg)
{
return monmsg->local_eib.ln1msg2.ipbfln1f;
return *(u32 *) &monmsg->msg.rmmsg[4];
}
static inline u8
mon_mca_type(struct mon_msg *monmsg, u8 index)
static inline u8 mon_mca_type(struct mon_msg *monmsg, u8 index)
{
return *((u8 *) mon_mca_start(monmsg) + monmsg->mca_offset + index);
}
static inline u32
mon_mca_size(struct mon_msg *monmsg)
static inline u32 mon_mca_size(struct mon_msg *monmsg)
{
return mon_mca_end(monmsg) - mon_mca_start(monmsg) + 1;
}
static inline u32
mon_rec_start(struct mon_msg *monmsg)
static inline u32 mon_rec_start(struct mon_msg *monmsg)
{
return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 4));
}
static inline u32
mon_rec_end(struct mon_msg *monmsg)
static inline u32 mon_rec_end(struct mon_msg *monmsg)
{
return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 8));
}
static inline int
mon_check_mca(struct mon_msg *monmsg)
static inline int mon_check_mca(struct mon_msg *monmsg)
{
if ((mon_rec_end(monmsg) <= mon_rec_start(monmsg)) ||
(mon_rec_start(monmsg) < mon_dcss_start) ||
@ -221,20 +209,17 @@ mon_check_mca(struct mon_msg *monmsg)
return 0;
}
static inline int
mon_send_reply(struct mon_msg *monmsg, struct mon_private *monpriv)
static inline int mon_send_reply(struct mon_msg *monmsg,
struct mon_private *monpriv)
{
u8 prmmsg[8];
int rc;
P_DEBUG("read, REPLY: pathid = 0x%04X, msgid = 0x%08X, trgcls = "
"0x%08X\n\n",
monmsg->local_eib.ippathid, monmsg->local_eib.ipmsgid,
monmsg->local_eib.iptrgcls);
rc = iucv_reply_prmmsg(monmsg->local_eib.ippathid,
monmsg->local_eib.ipmsgid,
monmsg->local_eib.iptrgcls,
0, prmmsg);
monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class);
rc = iucv_message_reply(monpriv->path, &monmsg->msg,
IUCV_IPRMDATA, NULL, 0);
atomic_dec(&monpriv->msglim_count);
if (likely(!monmsg->msglim_reached)) {
monmsg->pos = 0;
@ -251,10 +236,19 @@ mon_send_reply(struct mon_msg *monmsg, struct mon_private *monpriv)
return 0;
}
static inline struct mon_private *
mon_alloc_mem(void)
static inline void mon_free_mem(struct mon_private *monpriv)
{
int i,j;
int i;
for (i = 0; i < MON_MSGLIM; i++)
if (monpriv->msg_array[i])
kfree(monpriv->msg_array[i]);
kfree(monpriv);
}
static inline struct mon_private *mon_alloc_mem(void)
{
int i;
struct mon_private *monpriv;
monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL);
@ -267,16 +261,15 @@ mon_alloc_mem(void)
GFP_KERNEL);
if (!monpriv->msg_array[i]) {
P_ERROR("open, no memory for msg_array\n");
for (j = 0; j < i; j++)
kfree(monpriv->msg_array[j]);
mon_free_mem(monpriv);
return NULL;
}
}
return monpriv;
}
static inline void
mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv)
static inline void mon_read_debug(struct mon_msg *monmsg,
struct mon_private *monpriv)
{
#ifdef MON_DEBUG
u8 msg_type[2], mca_type;
@ -284,7 +277,7 @@ mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv)
records_len = mon_rec_end(monmsg) - mon_rec_start(monmsg) + 1;
memcpy(msg_type, &monmsg->local_eib.iptrgcls, 2);
memcpy(msg_type, &monmsg->msg.class, 2);
EBCASC(msg_type, 2);
mca_type = mon_mca_type(monmsg, 0);
EBCASC(&mca_type, 1);
@ -292,8 +285,7 @@ mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv)
P_DEBUG("read, mon_read_index = %i, mon_write_index = %i\n",
monpriv->read_index, monpriv->write_index);
P_DEBUG("read, pathid = 0x%04X, msgid = 0x%08X, trgcls = 0x%08X\n",
monmsg->local_eib.ippathid, monmsg->local_eib.ipmsgid,
monmsg->local_eib.iptrgcls);
monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class);
P_DEBUG("read, msg_type = '%c%c', mca_type = '%c' / 0x%X / 0x%X\n",
msg_type[0], msg_type[1], mca_type ? mca_type : 'X',
mon_mca_type(monmsg, 1), mon_mca_type(monmsg, 2));
@ -306,8 +298,7 @@ mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv)
#endif
}
static inline void
mon_next_mca(struct mon_msg *monmsg)
static inline void mon_next_mca(struct mon_msg *monmsg)
{
if (likely((mon_mca_size(monmsg) - monmsg->mca_offset) == 12))
return;
@ -316,8 +307,7 @@ mon_next_mca(struct mon_msg *monmsg)
monmsg->pos = 0;
}
static inline struct mon_msg *
mon_next_message(struct mon_private *monpriv)
static inline struct mon_msg *mon_next_message(struct mon_private *monpriv)
{
struct mon_msg *monmsg;
@ -342,39 +332,37 @@ mon_next_message(struct mon_private *monpriv)
/******************************************************************************
* IUCV handler *
*****************************************************************************/
static void
mon_iucv_ConnectionComplete(iucv_ConnectionComplete *eib, void *pgm_data)
static void mon_iucv_path_complete(struct iucv_path *path, u8 ipuser[16])
{
struct mon_private *monpriv = (struct mon_private *) pgm_data;
struct mon_private *monpriv = path->private;
P_DEBUG("IUCV connection completed\n");
P_DEBUG("IUCV ACCEPT (from *MONITOR): Version = 0x%02X, Event = "
"0x%02X, Sample = 0x%02X\n",
eib->ipuser[0], eib->ipuser[1], eib->ipuser[2]);
ipuser[0], ipuser[1], ipuser[2]);
atomic_set(&monpriv->iucv_connected, 1);
wake_up(&mon_conn_wait_queue);
}
static void
mon_iucv_ConnectionSevered(iucv_ConnectionSevered *eib, void *pgm_data)
static void mon_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
{
struct mon_private *monpriv = (struct mon_private *) pgm_data;
struct mon_private *monpriv = path->private;
P_ERROR("IUCV connection severed with rc = 0x%X\n",
(u8) eib->ipuser[0]);
P_ERROR("IUCV connection severed with rc = 0x%X\n", ipuser[0]);
iucv_path_sever(path, NULL);
atomic_set(&monpriv->iucv_severed, 1);
wake_up(&mon_conn_wait_queue);
wake_up_interruptible(&mon_read_wait_queue);
}
static void
mon_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data)
static void mon_iucv_message_pending(struct iucv_path *path,
struct iucv_message *msg)
{
struct mon_private *monpriv = (struct mon_private *) pgm_data;
struct mon_private *monpriv = path->private;
P_DEBUG("IUCV message pending\n");
memcpy(&monpriv->msg_array[monpriv->write_index]->local_eib, eib,
sizeof(iucv_MessagePending));
memcpy(&monpriv->msg_array[monpriv->write_index]->msg,
msg, sizeof(*msg));
if (atomic_inc_return(&monpriv->msglim_count) == MON_MSGLIM) {
P_WARNING("IUCV message pending, message limit (%i) reached\n",
MON_MSGLIM);
@ -385,54 +373,45 @@ mon_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data)
wake_up_interruptible(&mon_read_wait_queue);
}
static iucv_interrupt_ops_t mon_iucvops = {
.ConnectionComplete = mon_iucv_ConnectionComplete,
.ConnectionSevered = mon_iucv_ConnectionSevered,
.MessagePending = mon_iucv_MessagePending,
static struct iucv_handler monreader_iucv_handler = {
.path_complete = mon_iucv_path_complete,
.path_severed = mon_iucv_path_severed,
.message_pending = mon_iucv_message_pending,
};
/******************************************************************************
* file operations *
*****************************************************************************/
static int
mon_open(struct inode *inode, struct file *filp)
static int mon_open(struct inode *inode, struct file *filp)
{
int rc, i;
struct mon_private *monpriv;
int rc;
/*
* only one user allowed
*/
rc = -EBUSY;
if (test_and_set_bit(MON_IN_USE, &mon_in_use))
return -EBUSY;
goto out;
rc = -ENOMEM;
monpriv = mon_alloc_mem();
if (!monpriv)
return -ENOMEM;
goto out_use;
/*
* Register with IUCV and connect to *MONITOR service
* Connect to *MONITOR service
*/
monpriv->iucv_handle = iucv_register_program("my_monreader ",
MON_SERVICE,
NULL,
&mon_iucvops,
monpriv);
if (!monpriv->iucv_handle) {
P_ERROR("failed to register with iucv driver\n");
rc = -EIO;
goto out_error;
}
P_INFO("open, registered with IUCV\n");
rc = iucv_connect(&monpriv->pathid, MON_MSGLIM, user_data_connect,
MON_SERVICE, iucv_host, IPRMDATA, NULL, NULL,
monpriv->iucv_handle, NULL);
monpriv->path = iucv_path_alloc(MON_MSGLIM, IUCV_IPRMDATA, GFP_KERNEL);
if (!monpriv->path)
goto out_priv;
rc = iucv_path_connect(monpriv->path, &monreader_iucv_handler,
MON_SERVICE, NULL, user_data_connect, monpriv);
if (rc) {
P_ERROR("iucv connection to *MONITOR failed with "
"IPUSER SEVER code = %i\n", rc);
rc = -EIO;
goto out_unregister;
goto out_path;
}
/*
* Wait for connection confirmation
@ -444,24 +423,23 @@ mon_open(struct inode *inode, struct file *filp)
atomic_set(&monpriv->iucv_severed, 0);
atomic_set(&monpriv->iucv_connected, 0);
rc = -EIO;
goto out_unregister;
goto out_path;
}
P_INFO("open, established connection to *MONITOR service\n\n");
filp->private_data = monpriv;
return nonseekable_open(inode, filp);
out_unregister:
iucv_unregister_program(monpriv->iucv_handle);
out_error:
for (i = 0; i < MON_MSGLIM; i++)
kfree(monpriv->msg_array[i]);
kfree(monpriv);
out_path:
kfree(monpriv->path);
out_priv:
mon_free_mem(monpriv);
out_use:
clear_bit(MON_IN_USE, &mon_in_use);
out:
return rc;
}
static int
mon_close(struct inode *inode, struct file *filp)
static int mon_close(struct inode *inode, struct file *filp)
{
int rc, i;
struct mon_private *monpriv = filp->private_data;
@ -469,18 +447,12 @@ mon_close(struct inode *inode, struct file *filp)
/*
* Close IUCV connection and unregister
*/
rc = iucv_sever(monpriv->pathid, user_data_sever);
rc = iucv_path_sever(monpriv->path, user_data_sever);
if (rc)
P_ERROR("close, iucv_sever failed with rc = %i\n", rc);
else
P_INFO("close, terminated connection to *MONITOR service\n");
rc = iucv_unregister_program(monpriv->iucv_handle);
if (rc)
P_ERROR("close, iucv_unregister failed with rc = %i\n", rc);
else
P_INFO("close, unregistered with IUCV\n");
atomic_set(&monpriv->iucv_severed, 0);
atomic_set(&monpriv->iucv_connected, 0);
atomic_set(&monpriv->read_ready, 0);
@ -495,8 +467,8 @@ mon_close(struct inode *inode, struct file *filp)
return 0;
}
static ssize_t
mon_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
static ssize_t mon_read(struct file *filp, char __user *data,
size_t count, loff_t *ppos)
{
struct mon_private *monpriv = filp->private_data;
struct mon_msg *monmsg;
@ -563,8 +535,7 @@ mon_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
return count;
}
static unsigned int
mon_poll(struct file *filp, struct poll_table_struct *p)
static unsigned int mon_poll(struct file *filp, struct poll_table_struct *p)
{
struct mon_private *monpriv = filp->private_data;
@ -593,8 +564,7 @@ static struct miscdevice mon_dev = {
/******************************************************************************
* module init/exit *
*****************************************************************************/
static int __init
mon_init(void)
static int __init mon_init(void)
{
int rc;
@ -603,22 +573,34 @@ mon_init(void)
return -ENODEV;
}
/*
* Register with IUCV and connect to *MONITOR service
*/
rc = iucv_register(&monreader_iucv_handler, 1);
if (rc) {
P_ERROR("failed to register with iucv driver\n");
return rc;
}
P_INFO("open, registered with IUCV\n");
rc = segment_type(mon_dcss_name);
if (rc < 0) {
mon_segment_warn(rc, mon_dcss_name);
return rc;
goto out_iucv;
}
if (rc != SEG_TYPE_SC) {
P_ERROR("segment %s has unsupported type, should be SC\n",
mon_dcss_name);
return -EINVAL;
rc = -EINVAL;
goto out_iucv;
}
rc = segment_load(mon_dcss_name, SEGMENT_SHARED,
&mon_dcss_start, &mon_dcss_end);
if (rc < 0) {
mon_segment_warn(rc, mon_dcss_name);
return -EINVAL;
rc = -EINVAL;
goto out_iucv;
}
dcss_mkname(mon_dcss_name, &user_data_connect[8]);
@ -634,14 +616,16 @@ mon_init(void)
out:
segment_unload(mon_dcss_name);
out_iucv:
iucv_unregister(&monreader_iucv_handler, 1);
return rc;
}
static void __exit
mon_exit(void)
static void __exit mon_exit(void)
{
segment_unload(mon_dcss_name);
WARN_ON(misc_deregister(&mon_dev) != 0);
iucv_unregister(&monreader_iucv_handler, 1);
return;
}

View File

@ -3,7 +3,7 @@
* character device driver for reading z/VM system service records
*
*
* Copyright (C) 2004 IBM Corporation
* Copyright 2004 IBM Corporation
* character device driver for reading z/VM system service records,
* Version 1.0
* Author(s): Xenia Tkatschow <xenia@us.ibm.com>
@ -21,7 +21,7 @@
#include <asm/cpcmd.h>
#include <asm/debug.h>
#include <asm/ebcdic.h>
#include "../net/iucv.h"
#include <net/iucv/iucv.h>
#include <linux/kmod.h>
#include <linux/cdev.h>
#include <linux/device.h>
@ -60,12 +60,11 @@ struct vmlogrdr_priv_t {
char system_service[8];
char internal_name[8];
char recording_name[8];
u16 pathid;
struct iucv_path *path;
int connection_established;
int iucv_path_severed;
iucv_MessagePending local_interrupt_buffer;
struct iucv_message local_interrupt_buffer;
atomic_t receive_ready;
iucv_handle_t iucv_handle;
int minor_num;
char * buffer;
char * current_position;
@ -97,37 +96,19 @@ static struct file_operations vmlogrdr_fops = {
};
static u8 iucvMagic[16] = {
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
static void vmlogrdr_iucv_path_complete(struct iucv_path *, u8 ipuser[16]);
static void vmlogrdr_iucv_path_severed(struct iucv_path *, u8 ipuser[16]);
static void vmlogrdr_iucv_message_pending(struct iucv_path *,
struct iucv_message *);
static struct iucv_handler vmlogrdr_iucv_handler = {
.path_complete = vmlogrdr_iucv_path_complete,
.path_severed = vmlogrdr_iucv_path_severed,
.message_pending = vmlogrdr_iucv_message_pending,
};
static u8 mask[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
static u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static void
vmlogrdr_iucv_ConnectionComplete(iucv_ConnectionComplete *eib, void *pgm_data);
static void
vmlogrdr_iucv_ConnectionSevered(iucv_ConnectionSevered *eib, void *pgm_data);
static void
vmlogrdr_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data);
static iucv_interrupt_ops_t vmlogrdr_iucvops = {
.ConnectionComplete = vmlogrdr_iucv_ConnectionComplete,
.ConnectionSevered = vmlogrdr_iucv_ConnectionSevered,
.MessagePending = vmlogrdr_iucv_MessagePending,
};
static DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue);
static DECLARE_WAIT_QUEUE_HEAD(read_wait_queue);
@ -176,28 +157,29 @@ static struct cdev *vmlogrdr_cdev = NULL;
static int recording_class_AB;
static void
vmlogrdr_iucv_ConnectionComplete (iucv_ConnectionComplete * eib,
void * pgm_data)
static void vmlogrdr_iucv_path_complete(struct iucv_path *path, u8 ipuser[16])
{
struct vmlogrdr_priv_t * logptr = pgm_data;
struct vmlogrdr_priv_t * logptr = path->private;
spin_lock(&logptr->priv_lock);
logptr->connection_established = 1;
spin_unlock(&logptr->priv_lock);
wake_up(&conn_wait_queue);
return;
}
static void
vmlogrdr_iucv_ConnectionSevered (iucv_ConnectionSevered * eib, void * pgm_data)
static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
{
u8 reason = (u8) eib->ipuser[8];
struct vmlogrdr_priv_t * logptr = pgm_data;
struct vmlogrdr_priv_t * logptr = path->private;
u8 reason = (u8) ipuser[8];
printk (KERN_ERR "vmlogrdr: connection severed with"
" reason %i\n", reason);
iucv_path_sever(path, NULL);
kfree(path);
logptr->path = NULL;
spin_lock(&logptr->priv_lock);
logptr->connection_established = 0;
logptr->iucv_path_severed = 1;
@ -209,10 +191,10 @@ vmlogrdr_iucv_ConnectionSevered (iucv_ConnectionSevered * eib, void * pgm_data)
}
static void
vmlogrdr_iucv_MessagePending (iucv_MessagePending * eib, void * pgm_data)
static void vmlogrdr_iucv_message_pending(struct iucv_path *path,
struct iucv_message *msg)
{
struct vmlogrdr_priv_t * logptr = pgm_data;
struct vmlogrdr_priv_t * logptr = path->private;
/*
* This function is the bottom half so it should be quick.
@ -220,15 +202,15 @@ vmlogrdr_iucv_MessagePending (iucv_MessagePending * eib, void * pgm_data)
* the usage count
*/
spin_lock(&logptr->priv_lock);
memcpy(&(logptr->local_interrupt_buffer), eib, sizeof(*eib));
memcpy(&logptr->local_interrupt_buffer, msg, sizeof(*msg));
atomic_inc(&logptr->receive_ready);
spin_unlock(&logptr->priv_lock);
wake_up_interruptible(&read_wait_queue);
}
static int
vmlogrdr_get_recording_class_AB(void) {
static int vmlogrdr_get_recording_class_AB(void)
{
char cp_command[]="QUERY COMMAND RECORDING ";
char cp_response[80];
char *tail;
@ -258,8 +240,9 @@ vmlogrdr_get_recording_class_AB(void) {
}
static int
vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) {
static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
int action, int purge)
{
char cp_command[80];
char cp_response[160];
@ -317,8 +300,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) {
}
static int
vmlogrdr_open (struct inode *inode, struct file *filp)
static int vmlogrdr_open (struct inode *inode, struct file *filp)
{
int dev_num = 0;
struct vmlogrdr_priv_t * logptr = NULL;
@ -328,10 +310,7 @@ vmlogrdr_open (struct inode *inode, struct file *filp)
dev_num = iminor(inode);
if (dev_num > MAXMINOR)
return -ENODEV;
logptr = &sys_ser[dev_num];
if (logptr == NULL)
return -ENODEV;
/*
* only allow for blocking reads to be open
@ -344,52 +323,38 @@ vmlogrdr_open (struct inode *inode, struct file *filp)
if (logptr->dev_in_use) {
spin_unlock_bh(&logptr->priv_lock);
return -EBUSY;
} else {
logptr->dev_in_use = 1;
spin_unlock_bh(&logptr->priv_lock);
}
logptr->dev_in_use = 1;
logptr->connection_established = 0;
logptr->iucv_path_severed = 0;
atomic_set(&logptr->receive_ready, 0);
logptr->buffer_free = 1;
spin_unlock_bh(&logptr->priv_lock);
/* set the file options */
filp->private_data = logptr;
filp->f_op = &vmlogrdr_fops;
/* start recording for this service*/
ret=0;
if (logptr->autorecording)
if (logptr->autorecording) {
ret = vmlogrdr_recording(logptr,1,logptr->autopurge);
if (ret)
printk (KERN_WARNING "vmlogrdr: failed to start "
"recording automatically\n");
/* Register with iucv driver */
logptr->iucv_handle = iucv_register_program(iucvMagic,
logptr->system_service, mask, &vmlogrdr_iucvops,
logptr);
if (logptr->iucv_handle == NULL) {
printk (KERN_ERR "vmlogrdr: failed to register with"
"iucv driver\n");
goto not_registered;
if (ret)
printk (KERN_WARNING "vmlogrdr: failed to start "
"recording automatically\n");
}
/* create connection to the system service */
spin_lock_bh(&logptr->priv_lock);
logptr->connection_established = 0;
logptr->iucv_path_severed = 0;
spin_unlock_bh(&logptr->priv_lock);
connect_rc = iucv_connect (&(logptr->pathid), 10, iucvMagic,
logptr->system_service, iucv_host, 0,
NULL, NULL,
logptr->iucv_handle, NULL);
logptr->path = iucv_path_alloc(10, 0, GFP_KERNEL);
if (!logptr->path)
goto out_dev;
connect_rc = iucv_path_connect(logptr->path, &vmlogrdr_iucv_handler,
logptr->system_service, NULL, NULL,
logptr);
if (connect_rc) {
printk (KERN_ERR "vmlogrdr: iucv connection to %s "
"failed with rc %i \n", logptr->system_service,
connect_rc);
goto not_connected;
goto out_path;
}
/* We've issued the connect and now we must wait for a
@ -398,35 +363,28 @@ vmlogrdr_open (struct inode *inode, struct file *filp)
*/
wait_event(conn_wait_queue, (logptr->connection_established)
|| (logptr->iucv_path_severed));
if (logptr->iucv_path_severed) {
goto not_connected;
}
if (logptr->iucv_path_severed)
goto out_record;
return nonseekable_open(inode, filp);
not_connected:
iucv_unregister_program(logptr->iucv_handle);
logptr->iucv_handle = NULL;
not_registered:
out_record:
if (logptr->autorecording)
vmlogrdr_recording(logptr,0,logptr->autopurge);
out_path:
kfree(logptr->path); /* kfree(NULL) is ok. */
logptr->path = NULL;
out_dev:
logptr->dev_in_use = 0;
return -EIO;
}
static int
vmlogrdr_release (struct inode *inode, struct file *filp)
static int vmlogrdr_release (struct inode *inode, struct file *filp)
{
int ret;
struct vmlogrdr_priv_t * logptr = filp->private_data;
iucv_unregister_program(logptr->iucv_handle);
logptr->iucv_handle = NULL;
if (logptr->autorecording) {
ret = vmlogrdr_recording(logptr,0,logptr->autopurge);
if (ret)
@ -439,8 +397,8 @@ vmlogrdr_release (struct inode *inode, struct file *filp)
}
static int
vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) {
static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv)
{
int rc, *temp;
/* we need to keep track of two data sizes here:
* The number of bytes we need to receive from iucv and
@ -461,8 +419,7 @@ vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) {
* We need to return the total length of the record
* + size of FENCE in the first 4 bytes of the buffer.
*/
iucv_data_count =
priv->local_interrupt_buffer.ln1msg2.ipbfln1f;
iucv_data_count = priv->local_interrupt_buffer.length;
user_data_count = sizeof(int);
temp = (int*)priv->buffer;
*temp= iucv_data_count + sizeof(FENCE);
@ -474,14 +431,10 @@ vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) {
*/
if (iucv_data_count > NET_BUFFER_SIZE)
iucv_data_count = NET_BUFFER_SIZE;
rc = iucv_receive(priv->pathid,
priv->local_interrupt_buffer.ipmsgid,
priv->local_interrupt_buffer.iptrgcls,
buffer,
iucv_data_count,
NULL,
NULL,
&priv->residual_length);
rc = iucv_message_receive(priv->path,
&priv->local_interrupt_buffer,
0, buffer, iucv_data_count,
&priv->residual_length);
spin_unlock_bh(&priv->priv_lock);
/* An rc of 5 indicates that the record was bigger then
* the buffer, which is OK for us. A 9 indicates that the
@ -513,8 +466,8 @@ vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) {
}
static ssize_t
vmlogrdr_read(struct file *filp, char __user *data, size_t count, loff_t * ppos)
static ssize_t vmlogrdr_read(struct file *filp, char __user *data,
size_t count, loff_t * ppos)
{
int rc;
struct vmlogrdr_priv_t * priv = filp->private_data;
@ -546,8 +499,10 @@ vmlogrdr_read(struct file *filp, char __user *data, size_t count, loff_t * ppos)
return count;
}
static ssize_t
vmlogrdr_autopurge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
static ssize_t vmlogrdr_autopurge_store(struct device * dev,
struct device_attribute *attr,
const char * buf, size_t count)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
ssize_t ret = count;
@ -565,8 +520,10 @@ vmlogrdr_autopurge_store(struct device * dev, struct device_attribute *attr, con
}
static ssize_t
vmlogrdr_autopurge_show(struct device *dev, struct device_attribute *attr, char *buf) {
static ssize_t vmlogrdr_autopurge_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
return sprintf(buf, "%u\n", priv->autopurge);
}
@ -576,8 +533,10 @@ static DEVICE_ATTR(autopurge, 0644, vmlogrdr_autopurge_show,
vmlogrdr_autopurge_store);
static ssize_t
vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
static ssize_t vmlogrdr_purge_store(struct device * dev,
struct device_attribute *attr,
const char * buf, size_t count)
{
char cp_command[80];
char cp_response[80];
@ -617,9 +576,10 @@ vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const c
static DEVICE_ATTR(purge, 0200, NULL, vmlogrdr_purge_store);
static ssize_t
vmlogrdr_autorecording_store(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count) {
static ssize_t vmlogrdr_autorecording_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
ssize_t ret = count;
@ -637,8 +597,10 @@ vmlogrdr_autorecording_store(struct device *dev, struct device_attribute *attr,
}
static ssize_t
vmlogrdr_autorecording_show(struct device *dev, struct device_attribute *attr, char *buf) {
static ssize_t vmlogrdr_autorecording_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
return sprintf(buf, "%u\n", priv->autorecording);
}
@ -648,9 +610,10 @@ static DEVICE_ATTR(autorecording, 0644, vmlogrdr_autorecording_show,
vmlogrdr_autorecording_store);
static ssize_t
vmlogrdr_recording_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
static ssize_t vmlogrdr_recording_store(struct device * dev,
struct device_attribute *attr,
const char * buf, size_t count)
{
struct vmlogrdr_priv_t *priv = dev->driver_data;
ssize_t ret;
@ -675,8 +638,9 @@ vmlogrdr_recording_store(struct device * dev, struct device_attribute *attr, con
static DEVICE_ATTR(recording, 0200, NULL, vmlogrdr_recording_store);
static ssize_t
vmlogrdr_recording_status_show(struct device_driver *driver, char *buf) {
static ssize_t vmlogrdr_recording_status_show(struct device_driver *driver,
char *buf)
{
char cp_command[] = "QUERY RECORDING ";
int len;
@ -709,52 +673,63 @@ static struct device_driver vmlogrdr_driver = {
};
static int
vmlogrdr_register_driver(void) {
static int vmlogrdr_register_driver(void)
{
int ret;
/* Register with iucv driver */
ret = iucv_register(&vmlogrdr_iucv_handler, 1);
if (ret) {
printk (KERN_ERR "vmlogrdr: failed to register with"
"iucv driver\n");
goto out;
}
ret = driver_register(&vmlogrdr_driver);
if (ret) {
printk(KERN_ERR "vmlogrdr: failed to register driver.\n");
return ret;
goto out_iucv;
}
ret = driver_create_file(&vmlogrdr_driver,
&driver_attr_recording_status);
if (ret) {
printk(KERN_ERR "vmlogrdr: failed to add driver attribute.\n");
goto unregdriver;
goto out_driver;
}
vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr");
if (IS_ERR(vmlogrdr_class)) {
printk(KERN_ERR "vmlogrdr: failed to create class.\n");
ret=PTR_ERR(vmlogrdr_class);
vmlogrdr_class=NULL;
goto unregattr;
ret = PTR_ERR(vmlogrdr_class);
vmlogrdr_class = NULL;
goto out_attr;
}
return 0;
unregattr:
out_attr:
driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status);
unregdriver:
out_driver:
driver_unregister(&vmlogrdr_driver);
out_iucv:
iucv_unregister(&vmlogrdr_iucv_handler, 1);
out:
return ret;
}
static void
vmlogrdr_unregister_driver(void) {
static void vmlogrdr_unregister_driver(void)
{
class_destroy(vmlogrdr_class);
vmlogrdr_class = NULL;
driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status);
driver_unregister(&vmlogrdr_driver);
return;
iucv_unregister(&vmlogrdr_iucv_handler, 1);
}
static int
vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
{
struct device *dev;
int ret;
@ -803,9 +778,10 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
}
static int
vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) {
class_device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num));
static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv)
{
class_device_destroy(vmlogrdr_class,
MKDEV(vmlogrdr_major, priv->minor_num));
if (priv->device != NULL) {
sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group);
device_unregister(priv->device);
@ -815,8 +791,8 @@ vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) {
}
static int
vmlogrdr_register_cdev(dev_t dev) {
static int vmlogrdr_register_cdev(dev_t dev)
{
int rc = 0;
vmlogrdr_cdev = cdev_alloc();
if (!vmlogrdr_cdev) {
@ -836,9 +812,10 @@ vmlogrdr_register_cdev(dev_t dev) {
}
static void
vmlogrdr_cleanup(void) {
static void vmlogrdr_cleanup(void)
{
int i;
if (vmlogrdr_cdev) {
cdev_del(vmlogrdr_cdev);
vmlogrdr_cdev=NULL;
@ -855,8 +832,7 @@ vmlogrdr_cleanup(void) {
}
static int
vmlogrdr_init(void)
static int vmlogrdr_init(void)
{
int rc;
int i;
@ -906,8 +882,7 @@ vmlogrdr_init(void)
}
static void
vmlogrdr_exit(void)
static void vmlogrdr_exit(void)
{
vmlogrdr_cleanup();
printk (KERN_INFO "vmlogrdr: driver unloaded\n");

View File

@ -22,13 +22,6 @@ config CTC
available. This option is also available as a module which will be
called ctc.ko. If you do not know what it is, it's safe to say "Y".
config IUCV
tristate "IUCV support (VM only)"
help
Select this option if you want to use inter-user communication
under VM or VIF. If unsure, say "Y" to enable a fast communication
link between VM guests.
config NETIUCV
tristate "IUCV network device support (VM only)"
depends on IUCV && NETDEVICES

View File

@ -4,7 +4,6 @@
ctc-objs := ctcmain.o ctcdbug.o
obj-$(CONFIG_IUCV) += iucv.o
obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o

File diff suppressed because it is too large Load Diff

View File

@ -1,849 +0,0 @@
/*
* drivers/s390/net/iucv.h
* IUCV base support.
*
* S390 version
* Copyright (C) 2000 IBM Corporation
* Author(s):Alan Altmark (Alan_Altmark@us.ibm.com)
* Xenia Tkatschow (xenia@us.ibm.com)
*
*
* Functionality:
* To explore any of the IUCV functions, one must first register
* their program using iucv_register_program(). Once your program has
* successfully completed a register, it can exploit the other functions.
* For furthur reference on all IUCV functionality, refer to the
* CP Programming Services book, also available on the web
* thru www.ibm.com/s390/vm/pubs, manual # SC24-5760
*
* Definition of Return Codes
* -All positive return codes including zero are reflected back
* from CP except for iucv_register_program. The definition of each
* return code can be found in CP Programming Services book.
* Also available on the web thru www.ibm.com/s390/vm/pubs, manual # SC24-5760
* - Return Code of:
* (-EINVAL) Invalid value
* (-ENOMEM) storage allocation failed
* pgmask defined in iucv_register_program will be set depending on input
* paramters.
*
*/
#include <linux/types.h>
#include <asm/debug.h>
/**
* Debug Facility stuff
*/
#define IUCV_DBF_SETUP_NAME "iucv_setup"
#define IUCV_DBF_SETUP_LEN 32
#define IUCV_DBF_SETUP_PAGES 2
#define IUCV_DBF_SETUP_NR_AREAS 1
#define IUCV_DBF_SETUP_LEVEL 3
#define IUCV_DBF_DATA_NAME "iucv_data"
#define IUCV_DBF_DATA_LEN 128
#define IUCV_DBF_DATA_PAGES 2
#define IUCV_DBF_DATA_NR_AREAS 1
#define IUCV_DBF_DATA_LEVEL 2
#define IUCV_DBF_TRACE_NAME "iucv_trace"
#define IUCV_DBF_TRACE_LEN 16
#define IUCV_DBF_TRACE_PAGES 4
#define IUCV_DBF_TRACE_NR_AREAS 1
#define IUCV_DBF_TRACE_LEVEL 3
#define IUCV_DBF_TEXT(name,level,text) \
do { \
debug_text_event(iucv_dbf_##name,level,text); \
} while (0)
#define IUCV_DBF_HEX(name,level,addr,len) \
do { \
debug_event(iucv_dbf_##name,level,(void*)(addr),len); \
} while (0)
DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf);
#define IUCV_DBF_TEXT_(name,level,text...) \
do { \
char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \
sprintf(iucv_dbf_txt_buf, text); \
debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \
put_cpu_var(iucv_dbf_txt_buf); \
} while (0)
#define IUCV_DBF_SPRINTF(name,level,text...) \
do { \
debug_sprintf_event(iucv_dbf_trace, level, ##text ); \
debug_sprintf_event(iucv_dbf_trace, level, text ); \
} while (0)
/**
* some more debug stuff
*/
#define IUCV_HEXDUMP16(importance,header,ptr) \
PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
"%02x %02x %02x %02x %02x %02x %02x %02x\n", \
*(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \
*(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \
*(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \
*(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \
*(((char*)ptr)+12),*(((char*)ptr)+13), \
*(((char*)ptr)+14),*(((char*)ptr)+15)); \
PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
"%02x %02x %02x %02x %02x %02x %02x %02x\n", \
*(((char*)ptr)+16),*(((char*)ptr)+17), \
*(((char*)ptr)+18),*(((char*)ptr)+19), \
*(((char*)ptr)+20),*(((char*)ptr)+21), \
*(((char*)ptr)+22),*(((char*)ptr)+23), \
*(((char*)ptr)+24),*(((char*)ptr)+25), \
*(((char*)ptr)+26),*(((char*)ptr)+27), \
*(((char*)ptr)+28),*(((char*)ptr)+29), \
*(((char*)ptr)+30),*(((char*)ptr)+31));
static inline void
iucv_hex_dump(unsigned char *buf, size_t len)
{
size_t i;
for (i = 0; i < len; i++) {
if (i && !(i % 16))
printk("\n");
printk("%02x ", *(buf + i));
}
printk("\n");
}
/**
* end of debug stuff
*/
#define uchar unsigned char
#define ushort unsigned short
#define ulong unsigned long
#define iucv_handle_t void *
/* flags1:
* All flags are defined in the field IPFLAGS1 of each function
* and can be found in CP Programming Services.
* IPLOCAL - Indicates the connect can only be satisfied on the
* local system
* IPPRTY - Indicates a priority message
* IPQUSCE - Indicates you do not want to receive messages on a
* path until an iucv_resume is issued
* IPRMDATA - Indicates that the message is in the parameter list
*/
#define IPLOCAL 0x01
#define IPPRTY 0x20
#define IPQUSCE 0x40
#define IPRMDATA 0x80
/* flags1_out:
* All flags are defined in the output field of IPFLAGS1 for each function
* and can be found in CP Programming Services.
* IPNORPY - Specifies this is a one-way message and no reply is expected.
* IPPRTY - Indicates a priority message is permitted. Defined in flags1.
*/
#define IPNORPY 0x10
#define Nonpriority_MessagePendingInterruptsFlag 0x80
#define Priority_MessagePendingInterruptsFlag 0x40
#define Nonpriority_MessageCompletionInterruptsFlag 0x20
#define Priority_MessageCompletionInterruptsFlag 0x10
#define IUCVControlInterruptsFlag 0x08
#define AllInterrupts 0xf8
/*
* Mapping of external interrupt buffers should be used with the corresponding
* interrupt types.
* Names: iucv_ConnectionPending -> connection pending
* iucv_ConnectionComplete -> connection complete
* iucv_ConnectionSevered -> connection severed
* iucv_ConnectionQuiesced -> connection quiesced
* iucv_ConnectionResumed -> connection resumed
* iucv_MessagePending -> message pending
* iucv_MessageComplete -> message complete
*/
typedef struct {
u16 ippathid;
uchar ipflags1;
uchar iptype;
u16 ipmsglim;
u16 res1;
uchar ipvmid[8];
uchar ipuser[16];
u32 res3;
uchar ippollfg;
uchar res4[3];
} iucv_ConnectionPending;
typedef struct {
u16 ippathid;
uchar ipflags1;
uchar iptype;
u16 ipmsglim;
u16 res1;
uchar res2[8];
uchar ipuser[16];
u32 res3;
uchar ippollfg;
uchar res4[3];
} iucv_ConnectionComplete;
typedef struct {
u16 ippathid;
uchar res1;
uchar iptype;
u32 res2;
uchar res3[8];
uchar ipuser[16];
u32 res4;
uchar ippollfg;
uchar res5[3];
} iucv_ConnectionSevered;
typedef struct {
u16 ippathid;
uchar res1;
uchar iptype;
u32 res2;
uchar res3[8];
uchar ipuser[16];
u32 res4;
uchar ippollfg;
uchar res5[3];
} iucv_ConnectionQuiesced;
typedef struct {
u16 ippathid;
uchar res1;
uchar iptype;
u32 res2;
uchar res3[8];
uchar ipuser[16];
u32 res4;
uchar ippollfg;
uchar res5[3];
} iucv_ConnectionResumed;
typedef struct {
u16 ippathid;
uchar ipflags1;
uchar iptype;
u32 ipmsgid;
u32 iptrgcls;
union u2 {
u32 iprmmsg1_u32;
uchar iprmmsg1[4];
} ln1msg1;
union u1 {
u32 ipbfln1f;
uchar iprmmsg2[4];
} ln1msg2;
u32 res1[3];
u32 ipbfln2f;
uchar ippollfg;
uchar res2[3];
} iucv_MessagePending;
typedef struct {
u16 ippathid;
uchar ipflags1;
uchar iptype;
u32 ipmsgid;
u32 ipaudit;
uchar iprmmsg[8];
u32 ipsrccls;
u32 ipmsgtag;
u32 res;
u32 ipbfln2f;
uchar ippollfg;
uchar res2[3];
} iucv_MessageComplete;
/*
* iucv_interrupt_ops_t: Is a vector of functions that handle
* IUCV interrupts.
* Parameter list:
* eib - is a pointer to a 40-byte area described
* with one of the structures above.
* pgm_data - this data is strictly for the
* interrupt handler that is passed by
* the application. This may be an address
* or token.
*/
typedef struct {
void (*ConnectionPending) (iucv_ConnectionPending * eib,
void *pgm_data);
void (*ConnectionComplete) (iucv_ConnectionComplete * eib,
void *pgm_data);
void (*ConnectionSevered) (iucv_ConnectionSevered * eib,
void *pgm_data);
void (*ConnectionQuiesced) (iucv_ConnectionQuiesced * eib,
void *pgm_data);
void (*ConnectionResumed) (iucv_ConnectionResumed * eib,
void *pgm_data);
void (*MessagePending) (iucv_MessagePending * eib, void *pgm_data);
void (*MessageComplete) (iucv_MessageComplete * eib, void *pgm_data);
} iucv_interrupt_ops_t;
/*
*iucv_array_t : Defines buffer array.
* Inside the array may be 31- bit addresses and 31-bit lengths.
*/
typedef struct {
u32 address;
u32 length;
} iucv_array_t __attribute__ ((aligned (8)));
extern struct bus_type iucv_bus;
extern struct device *iucv_root;
/* -prototypes- */
/*
* Name: iucv_register_program
* Purpose: Registers an application with IUCV
* Input: prmname - user identification
* userid - machine identification
* pgmmask - indicates which bits in the prmname and userid combined will be
* used to determine who is given control
* ops - address of vector of interrupt handlers
* pgm_data- application data passed to interrupt handlers
* Output: NA
* Return: address of handler
* (0) - Error occurred, registration not completed.
* NOTE: Exact cause of failure will be recorded in syslog.
*/
iucv_handle_t iucv_register_program (uchar pgmname[16],
uchar userid[8],
uchar pgmmask[24],
iucv_interrupt_ops_t * ops,
void *pgm_data);
/*
* Name: iucv_unregister_program
* Purpose: Unregister application with IUCV
* Input: address of handler
* Output: NA
* Return: (0) - Normal return
* (-EINVAL) - Internal error, wild pointer
*/
int iucv_unregister_program (iucv_handle_t handle);
/*
* Name: iucv_accept
* Purpose: This function is issued after the user receives a Connection Pending external
* interrupt and now wishes to complete the IUCV communication path.
* Input: pathid - u16 , Path identification number
* msglim_reqstd - u16, The number of outstanding messages requested.
* user_data - uchar[16], Data specified by the iucv_connect function.
* flags1 - int, Contains options for this path.
* -IPPRTY - 0x20- Specifies if you want to send priority message.
* -IPRMDATA - 0x80, Specifies whether your program can handle a message
* in the parameter list.
* -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being
* established.
* handle - iucv_handle_t, Address of handler.
* pgm_data - void *, Application data passed to interrupt handlers.
* flags1_out - int * Contains information about the path
* - IPPRTY - 0x20, Indicates you may send priority messages.
* msglim - *u16, Number of outstanding messages.
* Output: return code from CP IUCV call.
*/
int iucv_accept (u16 pathid,
u16 msglim_reqstd,
uchar user_data[16],
int flags1,
iucv_handle_t handle,
void *pgm_data, int *flags1_out, u16 * msglim);
/*
* Name: iucv_connect
* Purpose: This function establishes an IUCV path. Although the connect may complete
* successfully, you are not able to use the path until you receive an IUCV
* Connection Complete external interrupt.
* Input: pathid - u16 *, Path identification number
* msglim_reqstd - u16, Number of outstanding messages requested
* user_data - uchar[16], 16-byte user data
* userid - uchar[8], User identification
* system_name - uchar[8], 8-byte identifying the system name
* flags1 - int, Contains options for this path.
* -IPPRTY - 0x20, Specifies if you want to send priority message.
* -IPRMDATA - 0x80, Specifies whether your program can handle a message
* in the parameter list.
* -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being
* established.
* -IPLOCAL - 0X01, Allows an application to force the partner to be on
* the local system. If local is specified then target class cannot be
* specified.
* flags1_out - int * Contains information about the path
* - IPPRTY - 0x20, Indicates you may send priority messages.
* msglim - * u16, Number of outstanding messages
* handle - iucv_handle_t, Address of handler
* pgm_data - void *, Application data passed to interrupt handlers
* Output: return code from CP IUCV call
* rc - return code from iucv_declare_buffer
* -EINVAL - Invalid handle passed by application
* -EINVAL - Pathid address is NULL
* add_pathid_result - Return code from internal function add_pathid
*/
int
iucv_connect (u16 * pathid,
u16 msglim_reqstd,
uchar user_data[16],
uchar userid[8],
uchar system_name[8],
int flags1,
int *flags1_out,
u16 * msglim, iucv_handle_t handle, void *pgm_data);
/*
* Name: iucv_purge
* Purpose: This function cancels a message that you have sent.
* Input: pathid - Path identification number.
* msgid - Specifies the message ID of the message to be purged.
* srccls - Specifies the source message class.
* Output: audit - Contains information about asynchronous error
* that may have affected the normal completion
* of this message.
* Return: Return code from CP IUCV call.
*/
int iucv_purge (u16 pathid, u32 msgid, u32 srccls, __u32 *audit);
/*
* Name: iucv_query_maxconn
* Purpose: This function determines the maximum number of communication paths you
* may establish.
* Return: maxconn - ulong, Maximum number of connection the virtual machine may
* establish.
*/
ulong iucv_query_maxconn (void);
/*
* Name: iucv_query_bufsize
* Purpose: This function determines how large an external interrupt
* buffer IUCV requires to store information.
* Return: bufsize - ulong, Size of external interrupt buffer.
*/
ulong iucv_query_bufsize (void);
/*
* Name: iucv_quiesce
* Purpose: This function temporarily suspends incoming messages on an
* IUCV path. You can later reactivate the path by invoking
* the iucv_resume function.
* Input: pathid - Path identification number
* user_data - 16-bytes of user data
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_quiesce (u16 pathid, uchar user_data[16]);
/*
* Name: iucv_receive
* Purpose: This function receives messages that are being sent to you
* over established paths. Data will be returned in buffer for length of
* buflen.
* Input:
* pathid - Path identification number.
* buffer - Address of buffer to receive.
* buflen - Length of buffer to receive.
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* Output:
* flags1_out: int *, Contains information about this path.
* IPNORPY - 0x10 Specifies this is a one-way message and no reply is
* expected.
* IPPRTY - 0x20 Specifies if you want to send priority message.
* IPRMDATA - 0x80 specifies the data is contained in the parameter list
* residual_buffer - address of buffer updated by the number
* of bytes you have received.
* residual_length -
* Contains one of the following values, if the receive buffer is:
* The same length as the message, this field is zero.
* Longer than the message, this field contains the number of
* bytes remaining in the buffer.
* Shorter than the message, this field contains the residual
* count (that is, the number of bytes remaining in the
* message that does not fit into the buffer. In this
* case b2f0_result = 5.
* Return: Return code from CP IUCV call.
* (-EINVAL) - buffer address is pointing to NULL
*/
int iucv_receive (u16 pathid,
u32 msgid,
u32 trgcls,
void *buffer,
ulong buflen,
int *flags1_out,
ulong * residual_buffer, ulong * residual_length);
/*
* Name: iucv_receive_array
* Purpose: This function receives messages that are being sent to you
* over established paths. Data will be returned in first buffer for
* length of first buffer.
* Input: pathid - Path identification number.
* msgid - specifies the message ID.
* trgcls - Specifies target class.
* buffer - Address of array of buffers.
* buflen - Total length of buffers.
* Output:
* flags1_out: int *, Contains information about this path.
* IPNORPY - 0x10 Specifies this is a one-way message and no reply is
* expected.
* IPPRTY - 0x20 Specifies if you want to send priority message.
* IPRMDATA - 0x80 specifies the data is contained in the parameter list
* residual_buffer - address points to the current list entry IUCV
* is working on.
* residual_length -
* Contains one of the following values, if the receive buffer is:
* The same length as the message, this field is zero.
* Longer than the message, this field contains the number of
* bytes remaining in the buffer.
* Shorter than the message, this field contains the residual
* count (that is, the number of bytes remaining in the
* message that does not fit into the buffer. In this
* case b2f0_result = 5.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_receive_array (u16 pathid,
u32 msgid,
u32 trgcls,
iucv_array_t * buffer,
ulong buflen,
int *flags1_out,
ulong * residual_buffer, ulong * residual_length);
/*
* Name: iucv_reject
* Purpose: The reject function refuses a specified message. Between the
* time you are notified of a message and the time that you
* complete the message, the message may be rejected.
* Input: pathid - Path identification number.
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_reject (u16 pathid, u32 msgid, u32 trgcls);
/*
* Name: iucv_reply
* Purpose: This function responds to the two-way messages that you
* receive. You must identify completely the message to
* which you wish to reply. ie, pathid, msgid, and trgcls.
* Input: pathid - Path identification number.
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* flags1 - Option for path.
* IPPRTY- 0x20, Specifies if you want to send priority message.
* buffer - Address of reply buffer.
* buflen - Length of reply buffer.
* Output: residual_buffer - Address of buffer updated by the number
* of bytes you have moved.
* residual_length - Contains one of the following values:
* If the answer buffer is the same length as the reply, this field
* contains zero.
* If the answer buffer is longer than the reply, this field contains
* the number of bytes remaining in the buffer.
* If the answer buffer is shorter than the reply, this field contains
* a residual count (that is, the number of bytes remianing in the
* reply that does not fit into the buffer. In this
* case b2f0_result = 5.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_reply (u16 pathid,
u32 msgid,
u32 trgcls,
int flags1,
void *buffer, ulong buflen, ulong * residual_buffer,
ulong * residual_length);
/*
* Name: iucv_reply_array
* Purpose: This function responds to the two-way messages that you
* receive. You must identify completely the message to
* which you wish to reply. ie, pathid, msgid, and trgcls.
* The array identifies a list of addresses and lengths of
* discontiguous buffers that contains the reply data.
* Input: pathid - Path identification number
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* flags1 - Option for path.
* IPPRTY- 0x20, Specifies if you want to send priority message.
* buffer - Address of array of reply buffers.
* buflen - Total length of reply buffers.
* Output: residual_buffer - Address of buffer which IUCV is currently working on.
* residual_length - Contains one of the following values:
* If the answer buffer is the same length as the reply, this field
* contains zero.
* If the answer buffer is longer than the reply, this field contains
* the number of bytes remaining in the buffer.
* If the answer buffer is shorter than the reply, this field contains
* a residual count (that is, the number of bytes remianing in the
* reply that does not fit into the buffer. In this
* case b2f0_result = 5.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_reply_array (u16 pathid,
u32 msgid,
u32 trgcls,
int flags1,
iucv_array_t * buffer,
ulong buflen, ulong * residual_address,
ulong * residual_length);
/*
* Name: iucv_reply_prmmsg
* Purpose: This function responds to the two-way messages that you
* receive. You must identify completely the message to
* which you wish to reply. ie, pathid, msgid, and trgcls.
* Prmmsg signifies the data is moved into the
* parameter list.
* Input: pathid - Path identification number.
* msgid - Specifies the message ID.
* trgcls - Specifies target class.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* prmmsg - 8-bytes of data to be placed into the parameter.
* list.
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_reply_prmmsg (u16 pathid,
u32 msgid, u32 trgcls, int flags1, uchar prmmsg[8]);
/*
* Name: iucv_resume
* Purpose: This function restores communications over a quiesced path
* Input: pathid - Path identification number.
* user_data - 16-bytes of user data.
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_resume (u16 pathid, uchar user_data[16]);
/*
* Name: iucv_send
* Purpose: This function transmits data to another application.
* Data to be transmitted is in a buffer and this is a
* one-way message and the receiver will not reply to the
* message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* buffer - Address of send buffer.
* buflen - Length of send buffer.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_send (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls, u32 msgtag, int flags1, void *buffer, ulong buflen);
/*
* Name: iucv_send_array
* Purpose: This function transmits data to another application.
* The contents of buffer is the address of the array of
* addresses and lengths of discontiguous buffers that hold
* the message text. This is a one-way message and the
* receiver will not reply to the message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated witht the message.
* flags1 - Option for path.
* IPPRTY- specifies if you want to send priority message.
* buffer - Address of array of send buffers.
* buflen - Total length of send buffers.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_send_array (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
int flags1, iucv_array_t * buffer, ulong buflen);
/*
* Name: iucv_send_prmmsg
* Purpose: This function transmits data to another application.
* Prmmsg specifies that the 8-bytes of data are to be moved
* into the parameter list. This is a one-way message and the
* receiver will not reply to the message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 specifies if you want to send priority message.
* prmmsg - 8-bytes of data to be placed into parameter list.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
*/
int iucv_send_prmmsg (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls, u32 msgtag, int flags1, uchar prmmsg[8]);
/*
* Name: iucv_send2way
* Purpose: This function transmits data to another application.
* Data to be transmitted is in a buffer. The receiver
* of the send is expected to reply to the message and
* a buffer is provided into which IUCV moves the reply
* to this message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* buffer - Address of send buffer.
* buflen - Length of send buffer.
* ansbuf - Address of buffer into which IUCV moves the reply of
* this message.
* anslen - Address of length of buffer.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer or ansbuf address is NULL.
*/
int iucv_send2way (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
int flags1,
void *buffer, ulong buflen, void *ansbuf, ulong anslen);
/*
* Name: iucv_send2way_array
* Purpose: This function transmits data to another application.
* The contents of buffer is the address of the array of
* addresses and lengths of discontiguous buffers that hold
* the message text. The receiver of the send is expected to
* reply to the message and a buffer is provided into which
* IUCV moves the reply to this message.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* buffer - Sddress of array of send buffers.
* buflen - Total length of send buffers.
* ansbuf - Address of array of buffer into which IUCV moves the reply
* of this message.
* anslen - Address of length reply buffers.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_send2way_array (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
int flags1,
iucv_array_t * buffer,
ulong buflen, iucv_array_t * ansbuf, ulong anslen);
/*
* Name: iucv_send2way_prmmsg
* Purpose: This function transmits data to another application.
* Prmmsg specifies that the 8-bytes of data are to be moved
* into the parameter list. This is a two-way message and the
* receiver of the message is expected to reply. A buffer
* is provided into which IUCV moves the reply to this
* message.
* Input: pathid - Rath identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 Specifies if you want to send priority message.
* prmmsg - 8-bytes of data to be placed in parameter list.
* ansbuf - Address of buffer into which IUCV moves the reply of
* this message.
* anslen - Address of length of buffer.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Buffer address is NULL.
*/
int iucv_send2way_prmmsg (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
ulong flags1,
uchar prmmsg[8], void *ansbuf, ulong anslen);
/*
* Name: iucv_send2way_prmmsg_array
* Purpose: This function transmits data to another application.
* Prmmsg specifies that the 8-bytes of data are to be moved
* into the parameter list. This is a two-way message and the
* receiver of the message is expected to reply. A buffer
* is provided into which IUCV moves the reply to this
* message. The contents of ansbuf is the address of the
* array of addresses and lengths of discontiguous buffers
* that contain the reply.
* Input: pathid - Path identification number.
* trgcls - Specifies target class.
* srccls - Specifies the source message class.
* msgtag - Specifies a tag to be associated with the message.
* flags1 - Option for path.
* IPPRTY- 0x20 specifies if you want to send priority message.
* prmmsg - 8-bytes of data to be placed into the parameter list.
* ansbuf - Address of array of buffer into which IUCV moves the reply
* of this message.
* anslen - Address of length of reply buffers.
* Output: msgid - Specifies the message ID.
* Return: Return code from CP IUCV call.
* (-EINVAL) - Ansbuf address is NULL.
*/
int iucv_send2way_prmmsg_array (u16 pathid,
u32 * msgid,
u32 trgcls,
u32 srccls,
u32 msgtag,
int flags1,
uchar prmmsg[8],
iucv_array_t * ansbuf, ulong anslen);
/*
* Name: iucv_setmask
* Purpose: This function enables or disables the following IUCV
* external interruptions: Nonpriority and priority message
* interrupts, nonpriority and priority reply interrupts.
* Input: SetMaskFlag - options for interrupts
* 0x80 - Nonpriority_MessagePendingInterruptsFlag
* 0x40 - Priority_MessagePendingInterruptsFlag
* 0x20 - Nonpriority_MessageCompletionInterruptsFlag
* 0x10 - Priority_MessageCompletionInterruptsFlag
* 0x08 - IUCVControlInterruptsFlag
* Output: NA
* Return: Return code from CP IUCV call.
*/
int iucv_setmask (int SetMaskFlag);
/*
* Name: iucv_sever
* Purpose: This function terminates an IUCV path.
* Input: pathid - Path identification number.
* user_data - 16-bytes of user data.
* Output: NA
* Return: Return code from CP IUCV call.
* (-EINVAL) - Interal error, wild pointer.
*/
int iucv_sever (u16 pathid, uchar user_data[16]);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*
* IUCV special message driver
*
* Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* This program is free software; you can redistribute it and/or modify
@ -23,10 +23,10 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <net/iucv/iucv.h>
#include <asm/cpcmd.h>
#include <asm/ebcdic.h>
#include "iucv.h"
#include "smsgiucv.h"
struct smsg_callback {
struct list_head list;
@ -39,38 +39,46 @@ MODULE_AUTHOR
("(C) 2003 IBM Corporation by Martin Schwidefsky (schwidefsky@de.ibm.com)");
MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver");
static iucv_handle_t smsg_handle;
static unsigned short smsg_pathid;
static struct iucv_path *smsg_path;
static DEFINE_SPINLOCK(smsg_list_lock);
static struct list_head smsg_list = LIST_HEAD_INIT(smsg_list);
static void
smsg_connection_complete(iucv_ConnectionComplete *eib, void *pgm_data)
static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]);
static void smsg_message_pending(struct iucv_path *, struct iucv_message *);
static struct iucv_handler smsg_handler = {
.path_pending = smsg_path_pending,
.message_pending = smsg_message_pending,
};
static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8],
u8 ipuser[16])
{
if (strncmp(ipvmid, "*MSG ", sizeof(ipvmid)) != 0)
return -EINVAL;
/* Path pending from *MSG. */
return iucv_path_accept(path, &smsg_handler, "SMSGIUCV ", NULL);
}
static void
smsg_message_pending(iucv_MessagePending *eib, void *pgm_data)
static void smsg_message_pending(struct iucv_path *path,
struct iucv_message *msg)
{
struct smsg_callback *cb;
unsigned char *msg;
unsigned char *buffer;
unsigned char sender[9];
unsigned short len;
int rc, i;
len = eib->ln1msg2.ipbfln1f;
msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA);
if (!msg) {
iucv_reject(eib->ippathid, eib->ipmsgid, eib->iptrgcls);
buffer = kmalloc(msg->length + 1, GFP_ATOMIC | GFP_DMA);
if (!buffer) {
iucv_message_reject(path, msg);
return;
}
rc = iucv_receive(eib->ippathid, eib->ipmsgid, eib->iptrgcls,
msg, len, NULL, NULL, NULL);
rc = iucv_message_receive(path, msg, 0, buffer, msg->length, NULL);
if (rc == 0) {
msg[len] = 0;
EBCASC(msg, len);
memcpy(sender, msg, 8);
buffer[msg->length] = 0;
EBCASC(buffer, msg->length);
memcpy(sender, buffer, 8);
sender[8] = 0;
/* Remove trailing whitespace from the sender name. */
for (i = 7; i >= 0; i--) {
@ -80,27 +88,17 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data)
}
spin_lock(&smsg_list_lock);
list_for_each_entry(cb, &smsg_list, list)
if (strncmp(msg + 8, cb->prefix, cb->len) == 0) {
cb->callback(sender, msg + 8);
if (strncmp(buffer + 8, cb->prefix, cb->len) == 0) {
cb->callback(sender, buffer + 8);
break;
}
spin_unlock(&smsg_list_lock);
}
kfree(msg);
kfree(buffer);
}
static iucv_interrupt_ops_t smsg_ops = {
.ConnectionComplete = smsg_connection_complete,
.MessagePending = smsg_message_pending,
};
static struct device_driver smsg_driver = {
.name = "SMSGIUCV",
.bus = &iucv_bus,
};
int
smsg_register_callback(char *prefix, void (*callback)(char *from, char *str))
int smsg_register_callback(char *prefix,
void (*callback)(char *from, char *str))
{
struct smsg_callback *cb;
@ -110,18 +108,18 @@ smsg_register_callback(char *prefix, void (*callback)(char *from, char *str))
cb->prefix = prefix;
cb->len = strlen(prefix);
cb->callback = callback;
spin_lock(&smsg_list_lock);
spin_lock_bh(&smsg_list_lock);
list_add_tail(&cb->list, &smsg_list);
spin_unlock(&smsg_list_lock);
spin_unlock_bh(&smsg_list_lock);
return 0;
}
void
smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str))
void smsg_unregister_callback(char *prefix,
void (*callback)(char *from, char *str))
{
struct smsg_callback *cb, *tmp;
spin_lock(&smsg_list_lock);
spin_lock_bh(&smsg_list_lock);
cb = NULL;
list_for_each_entry(tmp, &smsg_list, list)
if (tmp->callback == callback &&
@ -130,55 +128,58 @@ smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str))
list_del(&cb->list);
break;
}
spin_unlock(&smsg_list_lock);
spin_unlock_bh(&smsg_list_lock);
kfree(cb);
}
static void __exit
smsg_exit(void)
static struct device_driver smsg_driver = {
.name = "SMSGIUCV",
.bus = &iucv_bus,
};
static void __exit smsg_exit(void)
{
if (smsg_handle > 0) {
cpcmd("SET SMSG OFF", NULL, 0, NULL);
iucv_sever(smsg_pathid, NULL);
iucv_unregister_program(smsg_handle);
driver_unregister(&smsg_driver);
}
return;
cpcmd("SET SMSG IUCV", NULL, 0, NULL);
iucv_unregister(&smsg_handler, 1);
driver_unregister(&smsg_driver);
}
static int __init
smsg_init(void)
static int __init smsg_init(void)
{
static unsigned char pgmmask[24] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
int rc;
rc = driver_register(&smsg_driver);
if (rc != 0) {
printk(KERN_ERR "SMSGIUCV: failed to register driver.\n");
return rc;
}
smsg_handle = iucv_register_program("SMSGIUCV ", "*MSG ",
pgmmask, &smsg_ops, NULL);
if (!smsg_handle) {
if (rc != 0)
goto out;
rc = iucv_register(&smsg_handler, 1);
if (rc) {
printk(KERN_ERR "SMSGIUCV: failed to register to iucv");
driver_unregister(&smsg_driver);
return -EIO; /* better errno ? */
rc = -EIO; /* better errno ? */
goto out_driver;
}
rc = iucv_connect (&smsg_pathid, 255, NULL, "*MSG ", NULL, 0,
NULL, NULL, smsg_handle, NULL);
smsg_path = iucv_path_alloc(255, 0, GFP_KERNEL);
if (!smsg_path) {
rc = -ENOMEM;
goto out_register;
}
rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ",
NULL, NULL, NULL);
if (rc) {
printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG");
iucv_unregister_program(smsg_handle);
driver_unregister(&smsg_driver);
smsg_handle = NULL;
return -EIO;
rc = -EIO; /* better errno ? */
goto out_free;
}
cpcmd("SET SMSG IUCV", NULL, 0, NULL);
return 0;
out_free:
iucv_path_free(smsg_path);
out_register:
iucv_unregister(&smsg_handler, 1);
out_driver:
driver_unregister(&smsg_driver);
out:
return rc;
}
module_init(smsg_init);

View File

@ -828,9 +828,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
mutex_unlock(&crypt_stat->cs_tfm_mutex);
goto out;
}
crypto_blkcipher_set_flags(crypt_stat->tfm,
(ECRYPTFS_DEFAULT_CHAINING_MODE
| CRYPTO_TFM_REQ_WEAK_KEY));
crypto_blkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY);
mutex_unlock(&crypt_stat->cs_tfm_mutex);
rc = 0;
out:

View File

@ -176,7 +176,6 @@ ecryptfs_get_key_payload_data(struct key *key)
#define ECRYPTFS_FILE_SIZE_BYTES 8
#define ECRYPTFS_DEFAULT_CIPHER "aes"
#define ECRYPTFS_DEFAULT_KEY_BYTES 16
#define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC
#define ECRYPTFS_DEFAULT_HASH "md5"
#define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C
#define ECRYPTFS_TAG_11_PACKET_TYPE 0xED

View File

@ -18,8 +18,8 @@ struct module;
struct seq_file;
struct crypto_type {
unsigned int (*ctxsize)(struct crypto_alg *alg);
int (*init)(struct crypto_tfm *tfm);
unsigned int (*ctxsize)(struct crypto_alg *alg, u32 type, u32 mask);
int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask);
void (*exit)(struct crypto_tfm *tfm);
void (*show)(struct seq_file *m, struct crypto_alg *alg);
};
@ -93,7 +93,8 @@ struct crypto_template *crypto_lookup_template(const char *name);
int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
struct crypto_instance *inst);
void crypto_drop_spawn(struct crypto_spawn *spawn);
struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn);
struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
u32 mask);
struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len,
u32 type, u32 mask);
@ -132,11 +133,28 @@ static inline void *crypto_blkcipher_ctx_aligned(struct crypto_blkcipher *tfm)
return crypto_tfm_ctx_aligned(&tfm->base);
}
static inline struct crypto_cipher *crypto_spawn_cipher(
struct crypto_spawn *spawn)
{
u32 type = CRYPTO_ALG_TYPE_CIPHER;
u32 mask = CRYPTO_ALG_TYPE_MASK;
return __crypto_cipher_cast(crypto_spawn_tfm(spawn, type, mask));
}
static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm)
{
return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher;
}
static inline struct crypto_hash *crypto_spawn_hash(struct crypto_spawn *spawn)
{
u32 type = CRYPTO_ALG_TYPE_HASH;
u32 mask = CRYPTO_ALG_TYPE_HASH_MASK;
return __crypto_hash_cast(crypto_spawn_tfm(spawn, type, mask));
}
static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm)
{
return crypto_tfm_ctx_aligned(&tfm->base);

View File

@ -6,9 +6,7 @@
#ifndef _LINUX_ATMARP_H
#define _LINUX_ATMARP_H
#ifdef __KERNEL__
#include <linux/types.h>
#endif
#include <linux/atmapi.h>
#include <linux/atmioc.h>

View File

@ -51,15 +51,9 @@
/*
* Transform masks and values (for crt_flags).
*/
#define CRYPTO_TFM_MODE_MASK 0x000000ff
#define CRYPTO_TFM_REQ_MASK 0x000fff00
#define CRYPTO_TFM_RES_MASK 0xfff00000
#define CRYPTO_TFM_MODE_ECB 0x00000001
#define CRYPTO_TFM_MODE_CBC 0x00000002
#define CRYPTO_TFM_MODE_CFB 0x00000004
#define CRYPTO_TFM_MODE_CTR 0x00000008
#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
#define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200
#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
@ -71,12 +65,8 @@
/*
* Miscellaneous stuff.
*/
#define CRYPTO_UNSPEC 0
#define CRYPTO_MAX_ALG_NAME 64
#define CRYPTO_DIR_ENCRYPT 1
#define CRYPTO_DIR_DECRYPT 0
/*
* The macro CRYPTO_MINALIGN_ATTR (along with the void * type in the actual
* declaration) is used to ensure that the crypto_tfm context structure is
@ -148,19 +138,6 @@ struct cipher_alg {
unsigned int keylen);
void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes) __deprecated;
unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes) __deprecated;
unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes) __deprecated;
unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
unsigned int nbytes) __deprecated;
};
struct digest_alg {
@ -243,11 +220,6 @@ int crypto_unregister_alg(struct crypto_alg *alg);
#ifdef CONFIG_CRYPTO
int crypto_has_alg(const char *name, u32 type, u32 mask);
#else
static inline int crypto_alg_available(const char *name, u32 flags)
{
return 0;
}
static inline int crypto_has_alg(const char *name, u32 type, u32 mask)
{
return 0;
@ -339,13 +311,18 @@ struct crypto_tfm {
void *__crt_ctx[] CRYPTO_MINALIGN_ATTR;
};
#define crypto_cipher crypto_tfm
#define crypto_comp crypto_tfm
struct crypto_blkcipher {
struct crypto_tfm base;
};
struct crypto_cipher {
struct crypto_tfm base;
};
struct crypto_comp {
struct crypto_tfm base;
};
struct crypto_hash {
struct crypto_tfm base;
};
@ -395,40 +372,11 @@ static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
}
static unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
__deprecated;
static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
return tfm->__crt_alg->cra_cipher.cia_min_keysize;
}
static unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
__deprecated;
static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
return tfm->__crt_alg->cra_cipher.cia_max_keysize;
}
static unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) __deprecated;
static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
return tfm->crt_cipher.cit_ivsize;
}
static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_blocksize;
}
static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
return tfm->__crt_alg->cra_digest.dia_digestsize;
}
static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_alignmask;
@ -633,7 +581,7 @@ static inline struct crypto_cipher *crypto_alloc_cipher(const char *alg_name,
static inline struct crypto_tfm *crypto_cipher_tfm(struct crypto_cipher *tfm)
{
return tfm;
return &tfm->base;
}
static inline void crypto_free_cipher(struct crypto_cipher *tfm)
@ -809,76 +757,6 @@ static inline int crypto_hash_setkey(struct crypto_hash *hash,
return crypto_hash_crt(hash)->setkey(hash, key, keylen);
}
static int crypto_cipher_encrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes) __deprecated;
static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
}
static int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv) __deprecated;
static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
}
static int crypto_cipher_decrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes) __deprecated;
static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
}
static int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv) __deprecated;
static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
}
static void crypto_cipher_set_iv(struct crypto_tfm *tfm,
const u8 *src, unsigned int len) __deprecated;
static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
const u8 *src, unsigned int len)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
memcpy(tfm->crt_cipher.cit_iv, src, len);
}
static void crypto_cipher_get_iv(struct crypto_tfm *tfm,
u8 *dst, unsigned int len) __deprecated;
static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
u8 *dst, unsigned int len)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
memcpy(dst, tfm->crt_cipher.cit_iv, len);
}
static inline struct crypto_comp *__crypto_comp_cast(struct crypto_tfm *tfm)
{
return (struct crypto_comp *)tfm;
@ -903,7 +781,7 @@ static inline struct crypto_comp *crypto_alloc_comp(const char *alg_name,
static inline struct crypto_tfm *crypto_comp_tfm(struct crypto_comp *tfm)
{
return tfm;
return &tfm->base;
}
static inline void crypto_free_comp(struct crypto_comp *tfm)
@ -934,14 +812,16 @@ static inline int crypto_comp_compress(struct crypto_comp *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
return crypto_comp_crt(tfm)->cot_compress(tfm, src, slen, dst, dlen);
return crypto_comp_crt(tfm)->cot_compress(crypto_comp_tfm(tfm),
src, slen, dst, dlen);
}
static inline int crypto_comp_decompress(struct crypto_comp *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
return crypto_comp_crt(tfm)->cot_decompress(tfm, src, slen, dst, dlen);
return crypto_comp_crt(tfm)->cot_decompress(crypto_comp_tfm(tfm),
src, slen, dst, dlen);
}
#endif /* _LINUX_CRYPTO_H */

View File

@ -41,6 +41,7 @@ struct sockaddr_ll
#define PACKET_RX_RING 5
#define PACKET_STATISTICS 6
#define PACKET_COPY_THRESH 7
#define PACKET_AUXDATA 8
struct tpacket_stats
{
@ -48,6 +49,15 @@ struct tpacket_stats
unsigned int tp_drops;
};
struct tpacket_auxdata
{
__u32 tp_status;
__u32 tp_len;
__u32 tp_snaplen;
__u16 tp_mac;
__u16 tp_net;
};
struct tpacket_hdr
{
unsigned long tp_status;

View File

@ -24,7 +24,7 @@
struct poll_table_struct;
struct inode;
#define NPROTO 32 /* should be enough for now.. */
#define NPROTO 33 /* should be enough for now.. */
#define SYS_SOCKET 1 /* sys_socket(2) */
#define SYS_BIND 2 /* sys_bind(2) */

View File

@ -589,7 +589,7 @@ extern int dev_open(struct net_device *dev);
extern int dev_close(struct net_device *dev);
extern int dev_queue_xmit(struct sk_buff *skb);
extern int register_netdevice(struct net_device *dev);
extern int unregister_netdevice(struct net_device *dev);
extern void unregister_netdevice(struct net_device *dev);
extern void free_netdev(struct net_device *dev);
extern void synchronize_net(void);
extern int register_netdevice_notifier(struct notifier_block *nb);

View File

@ -33,6 +33,7 @@ header-y += xt_tcpmss.h
header-y += xt_tcpudp.h
header-y += xt_SECMARK.h
header-y += xt_CONNSECMARK.h
header-y += xt_TCPMSS.h
unifdef-y += nf_conntrack_common.h
unifdef-y += nf_conntrack_ftp.h

View File

@ -0,0 +1,21 @@
#ifndef _NF_CONNTRACK_SANE_H
#define _NF_CONNTRACK_SANE_H
/* SANE tracking. */
#ifdef __KERNEL__
#define SANE_PORT 6566
enum sane_state {
SANE_STATE_NORMAL,
SANE_STATE_START_REQUESTED,
};
/* This structure exists only once per master */
struct nf_ct_sane_master {
enum sane_state state;
};
#endif /* __KERNEL__ */
#endif /* _NF_CONNTRACK_SANE_H */

View File

@ -27,6 +27,9 @@ enum tcp_conntrack {
/* This sender sent FIN first */
#define IP_CT_TCP_FLAG_CLOSE_INIT 0x04
/* Be liberal in window checking */
#define IP_CT_TCP_FLAG_BE_LIBERAL 0x08
#ifdef __KERNEL__
struct ip_ct_tcp_state {
@ -34,7 +37,6 @@ struct ip_ct_tcp_state {
u_int32_t td_maxend; /* max of ack + max(win, 1) */
u_int32_t td_maxwin; /* max(win) */
u_int8_t td_scale; /* window scale factor */
u_int8_t loose; /* used when connection picked up from the middle */
u_int8_t flags; /* per direction options */
};

View File

@ -0,0 +1,10 @@
#ifndef _XT_TCPMSS_H
#define _XT_TCPMSS_H
struct xt_tcpmss_info {
u_int16_t mss;
};
#define XT_TCPMSS_CLAMP_PMTU 0xffff
#endif /* _XT_TCPMSS_H */

View File

@ -16,6 +16,7 @@ enum ip_nat_manip_type
#define IP_NAT_RANGE_MAP_IPS 1
#define IP_NAT_RANGE_PROTO_SPECIFIED 2
#define IP_NAT_RANGE_PROTO_RANDOM 4 /* add randomness to "port" selection */
/* NAT sequence number modifications */
struct ip_nat_seq {

View File

@ -272,25 +272,9 @@ ipt_get_target(struct ipt_entry *e)
#include <linux/init.h>
extern void ipt_init(void) __init;
#define ipt_register_target(tgt) \
({ (tgt)->family = AF_INET; \
xt_register_target(tgt); })
#define ipt_unregister_target(tgt) xt_unregister_target(tgt)
#define ipt_register_match(mtch) \
({ (mtch)->family = AF_INET; \
xt_register_match(mtch); })
#define ipt_unregister_match(mtch) xt_unregister_match(mtch)
//#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl)
//#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl)
extern int ipt_register_table(struct ipt_table *table,
extern int ipt_register_table(struct xt_table *table,
const struct ipt_replace *repl);
extern void ipt_unregister_table(struct ipt_table *table);
/* net/sched/ipt.c: Gimme access to your targets! Gets target->me. */
extern struct ipt_target *ipt_find_target(const char *name, u8 revision);
extern void ipt_unregister_table(struct xt_table *table);
/* Standard entry. */
struct ipt_standard
@ -315,7 +299,7 @@ extern unsigned int ipt_do_table(struct sk_buff **pskb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
struct ipt_table *table);
struct xt_table *table);
#define IPT_ALIGN(s) XT_ALIGN(s)

View File

@ -1,10 +1,9 @@
#ifndef _IPT_TCPMSS_H
#define _IPT_TCPMSS_H
struct ipt_tcpmss_info {
u_int16_t mss;
};
#include <linux/netfilter/xt_TCPMSS.h>
#define IPT_TCPMSS_CLAMP_PMTU 0xffff
#define ipt_tcpmss_info xt_tcpmss_info
#define IPT_TCPMSS_CLAMP_PMTU XT_TCPMSS_CLAMP_PMTU
#endif /*_IPT_TCPMSS_H*/

View File

@ -104,6 +104,25 @@ struct ip6t_entry
unsigned char elems[0];
};
/* Standard entry */
struct ip6t_standard
{
struct ip6t_entry entry;
struct ip6t_standard_target target;
};
struct ip6t_error_target
{
struct ip6t_entry_target target;
char errorname[IP6T_FUNCTION_MAXNAMELEN];
};
struct ip6t_error
{
struct ip6t_entry entry;
struct ip6t_error_target target;
};
/*
* New IP firewall options for [gs]etsockopt at the RAW IP level.
* Unlike BSD Linux inherits IP options so you don't have to use
@ -286,24 +305,14 @@ ip6t_get_target(struct ip6t_entry *e)
#include <linux/init.h>
extern void ip6t_init(void) __init;
#define ip6t_register_target(tgt) \
({ (tgt)->family = AF_INET6; \
xt_register_target(tgt); })
#define ip6t_unregister_target(tgt) xt_unregister_target(tgt)
#define ip6t_register_match(match) \
({ (match)->family = AF_INET6; \
xt_register_match(match); })
#define ip6t_unregister_match(match) xt_unregister_match(match)
extern int ip6t_register_table(struct ip6t_table *table,
extern int ip6t_register_table(struct xt_table *table,
const struct ip6t_replace *repl);
extern void ip6t_unregister_table(struct ip6t_table *table);
extern void ip6t_unregister_table(struct xt_table *table);
extern unsigned int ip6t_do_table(struct sk_buff **pskb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
struct ip6t_table *table);
struct xt_table *table);
/* Check for an extension */
extern int ip6t_ext_hdr(u8 nexthdr);

View File

@ -0,0 +1,15 @@
#ifndef _IP6T_MH_H
#define _IP6T_MH_H
/* MH matching stuff */
struct ip6t_mh
{
u_int8_t types[2]; /* MH type range */
u_int8_t invflags; /* Inverse flags */
};
/* Values for "invflags" field in struct ip6t_mh. */
#define IP6T_MH_INV_TYPE 0x01 /* Invert the sense of type. */
#define IP6T_MH_INV_MASK 0x01 /* All possible flags. */
#endif /*_IP6T_MH_H*/

View File

@ -251,7 +251,8 @@ struct sadb_x_sec_ctx {
#define SADB_X_SPDEXPIRE 21
#define SADB_X_SPDDELETE2 22
#define SADB_X_NAT_T_NEW_MAPPING 23
#define SADB_MAX 23
#define SADB_X_MIGRATE 24
#define SADB_MAX 24
/* Security Association flags */
#define SADB_SAFLAGS_PFS 1
@ -297,6 +298,7 @@ struct sadb_x_sec_ctx {
#define SADB_X_EALG_BLOWFISHCBC 7
#define SADB_EALG_NULL 11
#define SADB_X_EALG_AESCBC 12
#define SADB_X_EALG_CAMELLIACBC 22
#define SADB_EALG_MAX 253 /* last EALG */
/* private allocations should use 249-255 (RFC2407) */
#define SADB_X_EALG_SERPENTCBC 252 /* draft-ietf-ipsec-ciph-aes-cbc-00 */

View File

@ -187,7 +187,8 @@ struct ucred {
#define AF_LLC 26 /* Linux LLC */
#define AF_TIPC 30 /* TIPC sockets */
#define AF_BLUETOOTH 31 /* Bluetooth sockets */
#define AF_MAX 32 /* For now.. */
#define AF_IUCV 32 /* IUCV sockets */
#define AF_MAX 33 /* For now.. */
/* Protocol families, same as address families. */
#define PF_UNSPEC AF_UNSPEC
@ -220,6 +221,7 @@ struct ucred {
#define PF_LLC AF_LLC
#define PF_TIPC AF_TIPC
#define PF_BLUETOOTH AF_BLUETOOTH
#define PF_IUCV AF_IUCV
#define PF_MAX AF_MAX
/* Maximum queue length specifiable by listen. */

View File

@ -699,7 +699,8 @@ enum {
NET_X25_CALL_REQUEST_TIMEOUT=2,
NET_X25_RESET_REQUEST_TIMEOUT=3,
NET_X25_CLEAR_REQUEST_TIMEOUT=4,
NET_X25_ACK_HOLD_BACK_TIMEOUT=5
NET_X25_ACK_HOLD_BACK_TIMEOUT=5,
NET_X25_FORWARD=6
};
/* /proc/sys/net/token-ring */

View File

@ -316,7 +316,7 @@ struct tcp_sock {
struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */
struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/
struct tcp_sack_block recv_sack_cache[4];
struct tcp_sack_block_wire recv_sack_cache[4];
/* from STCP, retrans queue hinting */
struct sk_buff* lost_skb_hint;

View File

@ -516,9 +516,6 @@ struct wan_device {
/* Public functions available for device drivers */
extern int register_wan_device(struct wan_device *wandev);
extern int unregister_wan_device(char *name);
__be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev);
int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev,
unsigned short type);
/* Proc interface functions. These must not be called by the drivers! */
extern int wanrouter_proc_init(void);
@ -527,11 +524,6 @@ extern int wanrouter_proc_add(struct wan_device *wandev);
extern int wanrouter_proc_delete(struct wan_device *wandev);
extern int wanrouter_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
extern void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
extern void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
/* Public Data */
/* list of registered devices */
extern struct wan_device *wanrouter_router_devlist;

View File

@ -178,6 +178,9 @@ enum {
XFRM_MSG_REPORT,
#define XFRM_MSG_REPORT XFRM_MSG_REPORT
XFRM_MSG_MIGRATE,
#define XFRM_MSG_MIGRATE XFRM_MSG_MIGRATE
__XFRM_MSG_MAX
};
#define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
@ -256,6 +259,7 @@ enum xfrm_attr_type_t {
XFRMA_COADDR, /* xfrm_address_t */
XFRMA_LASTUSED,
XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */
XFRMA_MIGRATE,
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
@ -351,6 +355,19 @@ struct xfrm_user_report {
struct xfrm_selector sel;
};
struct xfrm_user_migrate {
xfrm_address_t old_daddr;
xfrm_address_t old_saddr;
xfrm_address_t new_daddr;
xfrm_address_t new_saddr;
__u8 proto;
__u8 mode;
__u16 reserved;
__u32 reqid;
__u16 old_family;
__u16 new_family;
};
#ifndef __KERNEL__
/* backwards compatibility for userspace */
#define XFRMGRP_ACQUIRE 1
@ -375,6 +392,8 @@ enum xfrm_nlgroups {
#define XFRMNLGRP_AEVENTS XFRMNLGRP_AEVENTS
XFRMNLGRP_REPORT,
#define XFRMNLGRP_REPORT XFRMNLGRP_REPORT
XFRMNLGRP_MIGRATE,
#define XFRMNLGRP_MIGRATE XFRMNLGRP_MIGRATE
__XFRMNLGRP_MAX
};
#define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1)

View File

@ -34,12 +34,13 @@
#include <asm/byteorder.h>
/* This is for all connections with a full identity, no wildcards.
* New scheme, half the table is for TIME_WAIT, the other half is
* for the rest. I'll experiment with dynamic table growth later.
* One chain is dedicated to TIME_WAIT sockets.
* I'll experiment with dynamic table growth later.
*/
struct inet_ehash_bucket {
rwlock_t lock;
struct hlist_head chain;
struct hlist_head twchain;
};
/* There are a few simple rules, which allow for local port reuse by
@ -97,8 +98,7 @@ struct inet_hashinfo {
*
* TCP_ESTABLISHED <= sk->sk_state < TCP_CLOSE
*
* First half of the table is for sockets not in TIME_WAIT, second half
* is for TIME_WAIT sockets only.
* TIME_WAIT sockets use a separate chain (twchain).
*/
struct inet_ehash_bucket *ehash;
@ -369,7 +369,7 @@ static inline struct sock *
}
/* Must check for a TIME_WAIT'er before going to listener hash. */
sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
sk_for_each(sk, node, &head->twchain) {
if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
goto hit;
}

106
include/net/iucv/af_iucv.h Normal file
View File

@ -0,0 +1,106 @@
/*
* Copyright 2006 IBM Corporation
* IUCV protocol stack for Linux on zSeries
* Version 1.0
* Author(s): Jennifer Hunt <jenhunt@us.ibm.com>
*
*/
#ifndef __AFIUCV_H
#define __AFIUCV_H
#include <asm/types.h>
#include <asm/byteorder.h>
#include <linux/list.h>
#include <linux/poll.h>
#include <linux/socket.h>
#ifndef AF_IUCV
#define AF_IUCV 32
#define PF_IUCV AF_IUCV
#endif
/* Connection and socket states */
enum {
IUCV_CONNECTED = 1,
IUCV_OPEN,
IUCV_BOUND,
IUCV_LISTEN,
IUCV_SEVERED,
IUCV_DISCONN,
IUCV_CLOSED
};
#define IUCV_QUEUELEN_DEFAULT 65535
#define IUCV_CONN_TIMEOUT (HZ * 40)
#define IUCV_DISCONN_TIMEOUT (HZ * 2)
#define IUCV_CONN_IDLE_TIMEOUT (HZ * 60)
#define IUCV_BUFSIZE_DEFAULT 32768
/* IUCV socket address */
struct sockaddr_iucv {
sa_family_t siucv_family;
unsigned short siucv_port; /* Reserved */
unsigned int siucv_addr; /* Reserved */
char siucv_nodeid[8]; /* Reserved */
char siucv_user_id[8]; /* Guest User Id */
char siucv_name[8]; /* Application Name */
};
/* Common socket structures and functions */
#define iucv_sk(__sk) ((struct iucv_sock *) __sk)
struct iucv_sock {
struct sock sk;
char src_user_id[8];
char src_name[8];
char dst_user_id[8];
char dst_name[8];
struct list_head accept_q;
struct sock *parent;
struct iucv_path *path;
struct sk_buff_head send_skb_q;
unsigned int send_tag;
};
struct iucv_sock_list {
struct hlist_head head;
rwlock_t lock;
atomic_t autobind_name;
};
static void iucv_sock_destruct(struct sock *sk);
static void iucv_sock_cleanup_listen(struct sock *parent);
static void iucv_sock_kill(struct sock *sk);
static void iucv_sock_close(struct sock *sk);
static int iucv_sock_create(struct socket *sock, int proto);
static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
int addr_len);
static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
int alen, int flags);
static int iucv_sock_listen(struct socket *sock, int backlog);
static int iucv_sock_accept(struct socket *sock, struct socket *newsock,
int flags);
static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr,
int *len, int peer);
static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len);
static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags);
unsigned int iucv_sock_poll(struct file *file, struct socket *sock,
poll_table *wait);
static int iucv_sock_release(struct socket *sock);
static int iucv_sock_shutdown(struct socket *sock, int how);
void iucv_sock_link(struct iucv_sock_list *l, struct sock *s);
void iucv_sock_unlink(struct iucv_sock_list *l, struct sock *s);
int iucv_sock_wait_state(struct sock *sk, int state, int state2,
unsigned long timeo);
int iucv_sock_wait_cnt(struct sock *sk, unsigned long timeo);
void iucv_accept_enqueue(struct sock *parent, struct sock *sk);
void iucv_accept_unlink(struct sock *sk);
struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock);
#endif /* __IUCV_H */

415
include/net/iucv/iucv.h Normal file
View File

@ -0,0 +1,415 @@
/*
* drivers/s390/net/iucv.h
* IUCV base support.
*
* S390 version
* Copyright 2000, 2006 IBM Corporation
* Author(s):Alan Altmark (Alan_Altmark@us.ibm.com)
* Xenia Tkatschow (xenia@us.ibm.com)
* Rewritten for af_iucv:
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*
*
* Functionality:
* To explore any of the IUCV functions, one must first register their
* program using iucv_register(). Once your program has successfully
* completed a register, it can exploit the other functions.
* For furthur reference on all IUCV functionality, refer to the
* CP Programming Services book, also available on the web thru
* www.ibm.com/s390/vm/pubs, manual # SC24-5760
*
* Definition of Return Codes
* - All positive return codes including zero are reflected back
* from CP. The definition of each return code can be found in
* CP Programming Services book.
* - Return Code of:
* -EINVAL: Invalid value
* -ENOMEM: storage allocation failed
*/
#include <linux/types.h>
#include <asm/debug.h>
/*
* IUCV option flags usable by device drivers:
*
* IUCV_IPRMDATA Indicates that your program can handle a message in the
* parameter list / a message is sent in the parameter list.
* Used for iucv_path_accept, iucv_path_connect,
* iucv_message_reply, iucv_message_send, iucv_message_send2way.
* IUCV_IPQUSCE Indicates that you do not want to receive messages on this
* path until an iucv_path_resume is issued.
* Used for iucv_path_accept, iucv_path_connect.
* IUCV_IPBUFLST Indicates that an address list is used for the message data.
* Used for iucv_message_receive, iucv_message_send,
* iucv_message_send2way.
* IUCV_IPPRTY Specifies that you want to send priority messages.
* Used for iucv_path_accept, iucv_path_connect,
* iucv_message_reply, iucv_message_send, iucv_message_send2way.
* IUCV_IPSYNC Indicates a synchronous send request.
* Used for iucv_message_send, iucv_message_send2way.
* IUCV_IPANSLST Indicates that an address list is used for the reply data.
* Used for iucv_message_reply, iucv_message_send2way.
* IUCV_IPLOCAL Specifies that the communication partner has to be on the
* local system. If local is specified no target class can be
* specified.
* Used for iucv_path_connect.
*
* All flags are defined in the input field IPFLAGS1 of each function
* and can be found in CP Programming Services.
*/
#define IUCV_IPRMDATA 0x80
#define IUCV_IPQUSCE 0x40
#define IUCV_IPBUFLST 0x40
#define IUCV_IPPRTY 0x20
#define IUCV_IPANSLST 0x08
#define IUCV_IPSYNC 0x04
#define IUCV_IPLOCAL 0x01
/*
* iucv_array : Defines buffer array.
* Inside the array may be 31- bit addresses and 31-bit lengths.
* Use a pointer to an iucv_array as the buffer, reply or answer
* parameter on iucv_message_send, iucv_message_send2way, iucv_message_receive
* and iucv_message_reply if IUCV_IPBUFLST or IUCV_IPANSLST are used.
*/
struct iucv_array {
u32 address;
u32 length;
} __attribute__ ((aligned (8)));
extern struct bus_type iucv_bus;
extern struct device *iucv_root;
/*
* struct iucv_path
* pathid: 16 bit path identification
* msglim: 16 bit message limit
* flags: properties of the path: IPRMDATA, IPQUSCE, IPPRTY
* handler: address of iucv handler structure
* private: private information of the handler associated with the path
* list: list_head for the iucv_handler path list.
*/
struct iucv_path {
u16 pathid;
u16 msglim;
u8 flags;
void *private;
struct iucv_handler *handler;
struct list_head list;
};
/*
* struct iucv_message
* id: 32 bit message id
* audit: 32 bit error information of purged or replied messages
* class: 32 bit target class of a message (source class for replies)
* tag: 32 bit tag to be associated with the message
* length: 32 bit length of the message / reply
* reply_size: 32 bit maximum allowed length of the reply
* rmmsg: 8 byte inline message
* flags: message properties (IUCV_IPPRTY)
*/
struct iucv_message {
u32 id;
u32 audit;
u32 class;
u32 tag;
u32 length;
u32 reply_size;
u8 rmmsg[8];
u8 flags;
};
/*
* struct iucv_handler
*
* A vector of functions that handle IUCV interrupts. Each functions gets
* a parameter area as defined by the CP Programming Services and private
* pointer that is provided by the user of the interface.
*/
struct iucv_handler {
/*
* The path_pending function is called after an iucv interrupt
* type 0x01 has been received. The base code allocates a path
* structure and "asks" the handler if this path belongs to the
* handler. To accept the path the path_pending function needs
* to call iucv_path_accept and return 0. If the callback returns
* a value != 0 the iucv base code will continue with the next
* handler. The order in which the path_pending functions are
* called is the order of the registration of the iucv handlers
* to the base code.
*/
int (*path_pending)(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]);
/*
* The path_complete function is called after an iucv interrupt
* type 0x02 has been received for a path that has been established
* for this handler with iucv_path_connect and got accepted by the
* peer with iucv_path_accept.
*/
void (*path_complete)(struct iucv_path *, u8 ipuser[16]);
/*
* The path_severed function is called after an iucv interrupt
* type 0x03 has been received. The communication peer shutdown
* his end of the communication path. The path still exists and
* remaining messages can be received until a iucv_path_sever
* shuts down the other end of the path as well.
*/
void (*path_severed)(struct iucv_path *, u8 ipuser[16]);
/*
* The path_quiesced function is called after an icuv interrupt
* type 0x04 has been received. The communication peer has quiesced
* the path. Delivery of messages is stopped until iucv_path_resume
* has been called.
*/
void (*path_quiesced)(struct iucv_path *, u8 ipuser[16]);
/*
* The path_resumed function is called after an icuv interrupt
* type 0x05 has been received. The communication peer has resumed
* the path.
*/
void (*path_resumed)(struct iucv_path *, u8 ipuser[16]);
/*
* The message_pending function is called after an icuv interrupt
* type 0x06 or type 0x07 has been received. A new message is
* availabe and can be received with iucv_message_receive.
*/
void (*message_pending)(struct iucv_path *, struct iucv_message *);
/*
* The message_complete function is called after an icuv interrupt
* type 0x08 or type 0x09 has been received. A message send with
* iucv_message_send2way has been replied to. The reply can be
* received with iucv_message_receive.
*/
void (*message_complete)(struct iucv_path *, struct iucv_message *);
struct list_head list;
struct list_head paths;
};
/**
* iucv_register:
* @handler: address of iucv handler structure
* @smp: != 0 indicates that the handler can deal with out of order messages
*
* Registers a driver with IUCV.
*
* Returns 0 on success, -ENOMEM if the memory allocation for the pathid
* table failed, or -EIO if IUCV_DECLARE_BUFFER failed on all cpus.
*/
int iucv_register(struct iucv_handler *handler, int smp);
/**
* iucv_unregister
* @handler: address of iucv handler structure
* @smp: != 0 indicates that the handler can deal with out of order messages
*
* Unregister driver from IUCV.
*/
void iucv_unregister(struct iucv_handler *handle, int smp);
/**
* iucv_path_alloc
* @msglim: initial message limit
* @flags: initial flags
* @gfp: kmalloc allocation flag
*
* Allocate a new path structure for use with iucv_connect.
*
* Returns NULL if the memory allocation failed or a pointer to the
* path structure.
*/
static inline struct iucv_path *iucv_path_alloc(u16 msglim, u8 flags, gfp_t gfp)
{
struct iucv_path *path;
path = kzalloc(sizeof(struct iucv_path), gfp);
if (path) {
path->msglim = msglim;
path->flags = flags;
}
return path;
}
/**
* iucv_path_free
* @path: address of iucv path structure
*
* Frees a path structure.
*/
static inline void iucv_path_free(struct iucv_path *path)
{
kfree(path);
}
/**
* iucv_path_accept
* @path: address of iucv path structure
* @handler: address of iucv handler structure
* @userdata: 16 bytes of data reflected to the communication partner
* @private: private data passed to interrupt handlers for this path
*
* This function is issued after the user received a connection pending
* external interrupt and now wishes to complete the IUCV communication path.
*
* Returns the result of the CP IUCV call.
*/
int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler,
u8 userdata[16], void *private);
/**
* iucv_path_connect
* @path: address of iucv path structure
* @handler: address of iucv handler structure
* @userid: 8-byte user identification
* @system: 8-byte target system identification
* @userdata: 16 bytes of data reflected to the communication partner
* @private: private data passed to interrupt handlers for this path
*
* This function establishes an IUCV path. Although the connect may complete
* successfully, you are not able to use the path until you receive an IUCV
* Connection Complete external interrupt.
*
* Returns the result of the CP IUCV call.
*/
int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler,
u8 userid[8], u8 system[8], u8 userdata[16],
void *private);
/**
* iucv_path_quiesce:
* @path: address of iucv path structure
* @userdata: 16 bytes of data reflected to the communication partner
*
* This function temporarily suspends incoming messages on an IUCV path.
* You can later reactivate the path by invoking the iucv_resume function.
*
* Returns the result from the CP IUCV call.
*/
int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16]);
/**
* iucv_path_resume:
* @path: address of iucv path structure
* @userdata: 16 bytes of data reflected to the communication partner
*
* This function resumes incoming messages on an IUCV path that has
* been stopped with iucv_path_quiesce.
*
* Returns the result from the CP IUCV call.
*/
int iucv_path_resume(struct iucv_path *path, u8 userdata[16]);
/**
* iucv_path_sever
* @path: address of iucv path structure
* @userdata: 16 bytes of data reflected to the communication partner
*
* This function terminates an IUCV path.
*
* Returns the result from the CP IUCV call.
*/
int iucv_path_sever(struct iucv_path *path, u8 userdata[16]);
/**
* iucv_message_purge
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @srccls: source class of message
*
* Cancels a message you have sent.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
u32 srccls);
/**
* iucv_message_receive
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @flags: flags that affect how the message is received (IUCV_IPBUFLST)
* @buffer: address of data buffer or address of struct iucv_array
* @size: length of data buffer
* @residual:
*
* This function receives messages that are being sent to you over
* established paths. This function will deal with RMDATA messages
* embedded in struct iucv_message as well.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
u8 flags, void *buffer, size_t size, size_t *residual);
/**
* iucv_message_reject
* @path: address of iucv path structure
* @msg: address of iucv msg structure
*
* The reject function refuses a specified message. Between the time you
* are notified of a message and the time that you complete the message,
* the message may be rejected.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg);
/**
* iucv_message_reply
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @flags: how the reply is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
* @reply: address of data buffer or address of struct iucv_array
* @size: length of reply data buffer
*
* This function responds to the two-way messages that you receive. You
* must identify completely the message to which you wish to reply. ie,
* pathid, msgid, and trgcls. Prmmsg signifies the data is moved into
* the parameter list.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
u8 flags, void *reply, size_t size);
/**
* iucv_message_send
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
* @srccls: source class of message
* @buffer: address of data buffer or address of struct iucv_array
* @size: length of send buffer
*
* This function transmits data to another application. Data to be
* transmitted is in a buffer and this is a one-way message and the
* receiver will not reply to the message.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
u8 flags, u32 srccls, void *buffer, size_t size);
/**
* iucv_message_send2way
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @flags: how the message is sent and the reply is received
* (IUCV_IPRMDATA, IUCV_IPBUFLST, IUCV_IPPRTY, IUCV_ANSLST)
* @srccls: source class of message
* @buffer: address of data buffer or address of struct iucv_array
* @size: length of send buffer
* @ansbuf: address of answer buffer or address of struct iucv_array
* @asize: size of reply buffer
*
* This function transmits data to another application. Data to be
* transmitted is in a buffer. The receiver of the send is expected to
* reply to the message and a buffer is provided into which IUCV moves
* the reply to this message.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
u8 flags, u32 srccls, void *buffer, size_t size,
void *answer, size_t asize, size_t *residual);

View File

@ -45,6 +45,7 @@ union nf_conntrack_expect_proto {
#include <linux/netfilter/nf_conntrack_ftp.h>
#include <linux/netfilter/nf_conntrack_pptp.h>
#include <linux/netfilter/nf_conntrack_h323.h>
#include <linux/netfilter/nf_conntrack_sane.h>
/* per conntrack: application helper private data */
union nf_conntrack_help {
@ -52,6 +53,7 @@ union nf_conntrack_help {
struct nf_ct_ftp_master ct_ftp_info;
struct nf_ct_pptp_master ct_pptp_info;
struct nf_ct_h323_master ct_h323_info;
struct nf_ct_sane_master ct_sane_info;
};
#include <linux/types.h>

View File

@ -16,6 +16,7 @@ enum nf_nat_manip_type
#define IP_NAT_RANGE_MAP_IPS 1
#define IP_NAT_RANGE_PROTO_SPECIFIED 2
#define IP_NAT_RANGE_PROTO_RANDOM 4
/* NAT sequence number modifications */
struct nf_nat_seq {

View File

@ -146,7 +146,8 @@ static inline char rt_tos2priority(u8 tos)
static inline int ip_route_connect(struct rtable **rp, __be32 dst,
__be32 src, u32 tos, int oif, u8 protocol,
__be16 sport, __be16 dport, struct sock *sk)
__be16 sport, __be16 dport, struct sock *sk,
int flags)
{
struct flowi fl = { .oif = oif,
.nl_u = { .ip4_u = { .daddr = dst,
@ -168,7 +169,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
*rp = NULL;
}
security_sk_classify_flow(sk, &fl);
return ip_route_output_flow(rp, &fl, sk, 0);
return ip_route_output_flow(rp, &fl, sk, flags);
}
static inline int ip_route_newports(struct rtable **rp, u8 protocol,

View File

@ -802,9 +802,8 @@ static inline void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
/*
* Calculate(/check) TCP checksum
*/
static inline __sum16 tcp_v4_check(struct tcphdr *th, int len,
__be32 saddr, __be32 daddr,
__wsum base)
static inline __sum16 tcp_v4_check(int len, __be32 saddr,
__be32 daddr, __wsum base)
{
return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
}

View File

@ -161,6 +161,14 @@ struct x25_sock {
unsigned long vc_facil_mask; /* inc_call facilities mask */
};
struct x25_forward {
struct list_head node;
unsigned int lci;
struct net_device *dev1;
struct net_device *dev2;
atomic_t refcnt;
};
static inline struct x25_sock *x25_sk(const struct sock *sk)
{
return (struct x25_sock *)sk;
@ -172,6 +180,7 @@ extern int sysctl_x25_call_request_timeout;
extern int sysctl_x25_reset_request_timeout;
extern int sysctl_x25_clear_request_timeout;
extern int sysctl_x25_ack_holdback_timeout;
extern int sysctl_x25_forward;
extern int x25_addr_ntoa(unsigned char *, struct x25_address *,
struct x25_address *);
@ -198,6 +207,13 @@ extern int x25_negotiate_facilities(struct sk_buff *, struct sock *,
struct x25_dte_facilities *);
extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *);
/* x25_forward.c */
extern void x25_clear_forward_by_lci(unsigned int lci);
extern void x25_clear_forward_by_dev(struct net_device *);
extern int x25_forward_data(int, struct x25_neigh *, struct sk_buff *);
extern int x25_forward_call(struct x25_address *, struct x25_neigh *,
struct sk_buff *, int);
/* x25_in.c */
extern int x25_process_rx_frame(struct sock *, struct sk_buff *);
extern int x25_backlog_rcv(struct sock *, struct sk_buff *);
@ -282,6 +298,8 @@ extern struct hlist_head x25_list;
extern rwlock_t x25_list_lock;
extern struct list_head x25_route_list;
extern rwlock_t x25_route_list_lock;
extern struct list_head x25_forward_list;
extern rwlock_t x25_forward_list_lock;
extern int x25_proc_init(void);
extern void x25_proc_exit(void);

View File

@ -252,10 +252,13 @@ struct xfrm_state_afinfo {
xfrm_address_t *daddr, xfrm_address_t *saddr);
int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
int (*output)(struct sk_buff *skb);
};
extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family);
extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
extern void xfrm_state_delete_tunnel(struct xfrm_state *x);
@ -359,6 +362,19 @@ struct xfrm_policy
struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
};
struct xfrm_migrate {
xfrm_address_t old_daddr;
xfrm_address_t old_saddr;
xfrm_address_t new_daddr;
xfrm_address_t new_saddr;
u8 proto;
u8 mode;
u16 reserved;
u32 reqid;
u16 old_family;
u16 new_family;
};
#define XFRM_KM_TIMEOUT 30
/* which seqno */
#define XFRM_REPLAY_SEQ 1
@ -385,6 +401,7 @@ struct xfrm_mgr
int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
int (*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
int (*migrate)(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_bundles);
};
extern int xfrm_register_km(struct xfrm_mgr *km);
@ -985,6 +1002,16 @@ extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
struct flowi *fl, int family, int strict);
extern void xfrm_init_pmtu(struct dst_entry *dst);
#ifdef CONFIG_XFRM_MIGRATE
extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
struct xfrm_migrate *m, int num_bundles);
extern struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m);
extern struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x,
struct xfrm_migrate *m);
extern int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
struct xfrm_migrate *m, int num_bundles);
#endif
extern wait_queue_head_t km_waitq;
extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid);
@ -1050,5 +1077,25 @@ static inline void xfrm_aevent_doreplay(struct xfrm_state *x)
xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
#ifdef CONFIG_XFRM_MIGRATE
static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
{
return (struct xfrm_algo *)kmemdup(orig, sizeof(*orig) + orig->alg_key_len, GFP_KERNEL);
}
static inline void xfrm_states_put(struct xfrm_state **states, int n)
{
int i;
for (i = 0; i < n; i++)
xfrm_state_put(*(states + i));
}
static inline void xfrm_states_delete(struct xfrm_state **states, int n)
{
int i;
for (i = 0; i < n; i++)
xfrm_state_delete(*(states + i));
}
#endif
#endif /* _NET_XFRM_H */

View File

@ -37,6 +37,7 @@ config NETDEBUG
source "net/packet/Kconfig"
source "net/unix/Kconfig"
source "net/xfrm/Kconfig"
source "net/iucv/Kconfig"
config INET
bool "TCP/IP networking"

View File

@ -47,6 +47,7 @@ obj-$(CONFIG_IP_SCTP) += sctp/
obj-$(CONFIG_IEEE80211) += ieee80211/
obj-$(CONFIG_TIPC) += tipc/
obj-$(CONFIG_NETLABEL) += netlabel/
obj-$(CONFIG_IUCV) += iucv/
ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_SYSCTL) += sysctl_net.o

View File

@ -816,7 +816,8 @@ static void __exit atm_exit(void)
proto_unregister(&vcc_proto);
}
module_init(atm_init);
subsys_initcall(atm_init);
module_exit(atm_exit);
MODULE_LICENSE("GPL");

View File

@ -949,44 +949,29 @@ static ctl_table brnf_net_table[] = {
};
#endif
int br_netfilter_init(void)
int __init br_netfilter_init(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) {
int ret;
if ((ret = nf_register_hook(&br_nf_ops[i])) >= 0)
continue;
while (i--)
nf_unregister_hook(&br_nf_ops[i]);
int ret;
ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
if (ret < 0)
return ret;
}
#ifdef CONFIG_SYSCTL
brnf_sysctl_header = register_sysctl_table(brnf_net_table, 0);
if (brnf_sysctl_header == NULL) {
printk(KERN_WARNING
"br_netfilter: can't register to sysctl.\n");
for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++)
nf_unregister_hook(&br_nf_ops[i]);
return -EFAULT;
nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
return -ENOMEM;
}
#endif
printk(KERN_NOTICE "Bridge firewalling registered\n");
return 0;
}
void br_netfilter_fini(void)
{
int i;
for (i = ARRAY_SIZE(br_nf_ops) - 1; i >= 0; i--)
nf_unregister_hook(&br_nf_ops[i]);
nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
#ifdef CONFIG_SYSCTL
unregister_sysctl_table(brnf_sysctl_header);
#endif

View File

@ -45,7 +45,7 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por
nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
if (nlh == NULL)
return -ENOBUFS;
return -EMSGSIZE;
hdr = nlmsg_data(nlh);
hdr->ifi_family = AF_BRIDGE;
@ -72,7 +72,8 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por
return nlmsg_end(skb, nlh);
nla_put_failure:
return nlmsg_cancel(skb, nlh);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
/*
@ -89,9 +90,12 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port)
goto errout;
err = br_fill_ifinfo(skb, port, 0, 0, event, 0);
/* failure implies BUG in br_nlmsg_size() */
BUG_ON(err < 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in br_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
errout:
if (err < 0)

View File

@ -93,6 +93,7 @@ static int ebt_ip_check(const char *tablename, unsigned int hookmask,
return -EINVAL;
if (info->protocol != IPPROTO_TCP &&
info->protocol != IPPROTO_UDP &&
info->protocol != IPPROTO_UDPLITE &&
info->protocol != IPPROTO_SCTP &&
info->protocol != IPPROTO_DCCP)
return -EINVAL;

View File

@ -96,6 +96,7 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
NIPQUAD(ih->daddr), ih->tos, ih->protocol);
if (ih->protocol == IPPROTO_TCP ||
ih->protocol == IPPROTO_UDP ||
ih->protocol == IPPROTO_UDPLITE ||
ih->protocol == IPPROTO_SCTP ||
ih->protocol == IPPROTO_DCCP) {
struct tcpudphdr _ports, *pptr;

View File

@ -3247,7 +3247,7 @@ void synchronize_net(void)
* unregister_netdev() instead of this.
*/
int unregister_netdevice(struct net_device *dev)
void unregister_netdevice(struct net_device *dev)
{
struct net_device *d, **dp;
@ -3258,7 +3258,9 @@ int unregister_netdevice(struct net_device *dev)
if (dev->reg_state == NETREG_UNINITIALIZED) {
printk(KERN_DEBUG "unregister_netdevice: device %s/%p never "
"was registered\n", dev->name, dev);
return -ENODEV;
WARN_ON(1);
return;
}
BUG_ON(dev->reg_state != NETREG_REGISTERED);
@ -3280,11 +3282,7 @@ int unregister_netdevice(struct net_device *dev)
break;
}
}
if (!d) {
printk(KERN_ERR "unregister net_device: '%s' not found\n",
dev->name);
return -ENODEV;
}
BUG_ON(!d);
dev->reg_state = NETREG_UNREGISTERING;
@ -3316,7 +3314,6 @@ int unregister_netdevice(struct net_device *dev)
synchronize_net();
dev_put(dev);
return 0;
}
/**

View File

@ -99,7 +99,14 @@ static void dst_run_gc(unsigned long dummy)
printk("dst_total: %d/%d %ld\n",
atomic_read(&dst_total), delayed, dst_gc_timer_expires);
#endif
mod_timer(&dst_gc_timer, jiffies + dst_gc_timer_expires);
/* if the next desired timer is more than 4 seconds in the future
* then round the timer to whole seconds
*/
if (dst_gc_timer_expires > 4*HZ)
mod_timer(&dst_gc_timer,
round_jiffies(jiffies + dst_gc_timer_expires));
else
mod_timer(&dst_gc_timer, jiffies + dst_gc_timer_expires);
out:
spin_unlock(&dst_lock);

View File

@ -331,7 +331,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags);
if (nlh == NULL)
return -1;
return -EMSGSIZE;
frh = nlmsg_data(nlh);
frh->table = rule->table;
@ -359,7 +359,8 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
return nlmsg_end(skb, nlh);
nla_put_failure:
return nlmsg_cancel(skb, nlh);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family)
@ -405,9 +406,12 @@ static void notify_rule_change(int event, struct fib_rule *rule,
goto errout;
err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops);
/* failure implies BUG in fib_rule_nlmsg_size() */
BUG_ON(err < 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in fib_rule_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
errout:
if (err < 0)

View File

@ -696,7 +696,10 @@ static void neigh_periodic_timer(unsigned long arg)
if (!expire)
expire = 1;
mod_timer(&tbl->gc_timer, now + expire);
if (expire>HZ)
mod_timer(&tbl->gc_timer, round_jiffies(now + expire));
else
mod_timer(&tbl->gc_timer, now + expire);
write_unlock(&tbl->lock);
}
@ -1637,7 +1640,7 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags);
if (nlh == NULL)
return -ENOBUFS;
return -EMSGSIZE;
ndtmsg = nlmsg_data(nlh);
@ -1706,7 +1709,8 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
nla_put_failure:
read_unlock_bh(&tbl->lock);
return nlmsg_cancel(skb, nlh);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
static int neightbl_fill_param_info(struct sk_buff *skb,
@ -1720,7 +1724,7 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags);
if (nlh == NULL)
return -ENOBUFS;
return -EMSGSIZE;
ndtmsg = nlmsg_data(nlh);
@ -1737,7 +1741,8 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
return nlmsg_end(skb, nlh);
errout:
read_unlock_bh(&tbl->lock);
return nlmsg_cancel(skb, nlh);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
@ -1955,7 +1960,7 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
if (nlh == NULL)
return -ENOBUFS;
return -EMSGSIZE;
ndm = nlmsg_data(nlh);
ndm->ndm_family = neigh->ops->family;
@ -1987,7 +1992,8 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
return nlmsg_end(skb, nlh);
nla_put_failure:
return nlmsg_cancel(skb, nlh);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
@ -2429,9 +2435,12 @@ static void __neigh_notify(struct neighbour *n, int type, int flags)
goto errout;
err = neigh_fill_info(skb, n, 0, 0, type, flags);
/* failure implies BUG in neigh_nlmsg_size() */
BUG_ON(err < 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in neigh_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
errout:
if (err < 0)

View File

@ -320,7 +320,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
if (nlh == NULL)
return -ENOBUFS;
return -EMSGSIZE;
ifm = nlmsg_data(nlh);
ifm->ifi_family = AF_UNSPEC;
@ -384,7 +384,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
return nlmsg_end(skb, nlh);
nla_put_failure:
return nlmsg_cancel(skb, nlh);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
@ -633,9 +634,12 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK,
NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0);
/* failure impilies BUG in if_nlmsg_size or wireless_rtnetlink_get */
BUG_ON(err < 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size */
WARN_ON(err == -EMSGSIZE);
kfree_skb(nskb);
goto errout;
}
err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
errout:
kfree(iw_buf);
@ -678,9 +682,12 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
goto errout;
err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0);
/* failure implies BUG in if_nlmsg_size() */
BUG_ON(err < 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
errout:
if (err < 0)

View File

@ -479,7 +479,8 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
ccid3_pr_debug("%s(%p), s=%u, w_init=%llu, "
"R_sample=%dus, X=%u\n", dccp_role(sk),
sk, hctx->ccid3hctx_s, w_init,
sk, hctx->ccid3hctx_s,
(unsigned long long)w_init,
(int)r_sample,
(unsigned)(hctx->ccid3hctx_x >> 6));
@ -1005,7 +1006,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
DCCP_BUG_ON(r_sample < 0);
if (unlikely(r_sample <= t_elapsed))
DCCP_WARN("r_sample=%ldus, t_elapsed=%ldus\n",
r_sample, t_elapsed);
(long)r_sample, (long)t_elapsed);
else
r_sample -= t_elapsed;
CCID3_RTT_SANITY_CHECK(r_sample);

View File

@ -72,7 +72,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
tmp = ip_route_connect(&rt, nexthop, inet->saddr,
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
IPPROTO_DCCP,
inet->sport, usin->sin_port, sk);
inet->sport, usin->sin_port, sk, 1);
if (tmp < 0)
return tmp;

View File

@ -1041,7 +1041,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
err = xfrm_lookup(&dst, &fl, sk, 0);
err = xfrm_lookup(&dst, &fl, sk, 1);
if (err < 0)
goto failure;

View File

@ -1024,7 +1024,6 @@ static int __init dccp_init(void)
do {
dccp_hashinfo.ehash_size = (1UL << ehash_order) * PAGE_SIZE /
sizeof(struct inet_ehash_bucket);
dccp_hashinfo.ehash_size >>= 1;
while (dccp_hashinfo.ehash_size &
(dccp_hashinfo.ehash_size - 1))
dccp_hashinfo.ehash_size--;
@ -1037,9 +1036,10 @@ static int __init dccp_init(void)
goto out_free_bind_bucket_cachep;
}
for (i = 0; i < (dccp_hashinfo.ehash_size << 1); i++) {
for (i = 0; i < dccp_hashinfo.ehash_size; i++) {
rwlock_init(&dccp_hashinfo.ehash[i].lock);
INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain);
INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].twchain);
}
bhash_order = ehash_order;

View File

@ -749,7 +749,7 @@ static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
if (nlh == NULL)
return -ENOBUFS;
return -EMSGSIZE;
ifm = nlmsg_data(nlh);
ifm->ifa_family = AF_DECnet;
@ -768,7 +768,8 @@ static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
return nlmsg_end(skb, nlh);
nla_put_failure:
return nlmsg_cancel(skb, nlh);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
@ -781,9 +782,12 @@ static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
goto errout;
err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0);
/* failure implies BUG in dn_ifaddr_nlmsg_size() */
BUG_ON(err < 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in dn_ifaddr_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
errout:
if (err < 0)

View File

@ -350,7 +350,7 @@ static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
nlmsg_failure:
rtattr_failure:
skb_trim(skb, b - skb->data);
return -1;
return -EMSGSIZE;
}
@ -368,9 +368,12 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id,
f->fn_type, f->fn_scope, &f->fn_key, z,
DN_FIB_INFO(f), 0);
/* failure implies BUG in dn_fib_nlmsg_size() */
BUG_ON(err < 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in dn_fib_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
errout:
if (err < 0)

View File

@ -1007,7 +1007,7 @@ static int inet_sk_reselect_saddr(struct sock *sk)
RT_CONN_FLAGS(sk),
sk->sk_bound_dev_if,
sk->sk_protocol,
inet->sport, inet->dport, sk);
inet->sport, inet->dport, sk, 0);
if (err)
return err;

View File

@ -49,7 +49,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr,
RT_CONN_FLAGS(sk), oif,
sk->sk_protocol,
inet->sport, usin->sin_port, sk);
inet->sport, usin->sin_port, sk, 1);
if (err)
return err;
if ((rt->rt_flags & RTCF_BROADCAST) && !sock_flag(sk, SOCK_BROADCAST)) {

View File

@ -1140,7 +1140,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
if (nlh == NULL)
return -ENOBUFS;
return -EMSGSIZE;
ifm = nlmsg_data(nlh);
ifm->ifa_family = AF_INET;
@ -1167,7 +1167,8 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
return nlmsg_end(skb, nlh);
nla_put_failure:
return nlmsg_cancel(skb, nlh);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
@ -1225,9 +1226,12 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
goto errout;
err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0);
/* failure implies BUG in inet_nlmsg_size() */
BUG_ON(err < 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in inet_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
errout:
if (err < 0)

View File

@ -314,9 +314,12 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
err = fib_dump_info(skb, info->pid, seq, event, tb_id,
fa->fa_type, fa->fa_scope, key, dst_len,
fa->fa_tos, fa->fa_info, 0);
/* failure implies BUG in fib_nlmsg_size() */
BUG_ON(err < 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in fib_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE,
info->nlh, GFP_KERNEL);
errout:
@ -960,7 +963,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
if (nlh == NULL)
return -ENOBUFS;
return -EMSGSIZE;
rtm = nlmsg_data(nlh);
rtm->rtm_family = AF_INET;
@ -1031,7 +1034,8 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
return nlmsg_end(skb, nlh);
nla_put_failure:
return nlmsg_cancel(skb, nlh);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
/*

View File

@ -455,6 +455,8 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
skb = add_grhead(skb, pmc, type, &pgr);
first = 0;
}
if (!skb)
return NULL;
psrc = (__be32 *)skb_put(skb, sizeof(__be32));
*psrc = psf->sf_inaddr;
scount++; stotal++;

View File

@ -153,7 +153,7 @@ static int inet_csk_diag_fill(struct sock *sk,
rtattr_failure:
nlmsg_failure:
skb_trim(skb, b - skb->data);
return -1;
return -EMSGSIZE;
}
static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
@ -209,7 +209,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
return skb->len;
nlmsg_failure:
skb_trim(skb, previous_tail - skb->data);
return -1;
return -EMSGSIZE;
}
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
@ -274,11 +274,14 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
if (!rep)
goto out;
if (sk_diag_fill(sk, rep, req->idiag_ext,
NETLINK_CB(in_skb).pid,
nlh->nlmsg_seq, 0, nlh) <= 0)
BUG();
err = sk_diag_fill(sk, rep, req->idiag_ext,
NETLINK_CB(in_skb).pid,
nlh->nlmsg_seq, 0, nlh);
if (err < 0) {
WARN_ON(err == -EMSGSIZE);
kfree_skb(rep);
goto out;
}
err = netlink_unicast(idiagnl, rep, NETLINK_CB(in_skb).pid,
MSG_DONTWAIT);
if (err > 0)
@ -775,7 +778,7 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
struct inet_timewait_sock *tw;
inet_twsk_for_each(tw, node,
&hashinfo->ehash[i + hashinfo->ehash_size].chain) {
&head->twchain) {
if (num < s_num)
goto next_dying;

View File

@ -212,7 +212,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
write_lock(&head->lock);
/* Check TIME-WAIT sockets first. */
sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) {
sk_for_each(sk2, node, &head->twchain) {
tw = inet_twsk(sk2);
if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {

View File

@ -78,8 +78,8 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
if (__sk_del_node_init(sk))
sock_prot_dec_use(sk->sk_prot);
/* Step 3: Hash TW into TIMEWAIT half of established hash table. */
inet_twsk_add_node(tw, &(ehead + hashinfo->ehash_size)->chain);
/* Step 3: Hash TW into TIMEWAIT chain. */
inet_twsk_add_node(tw, &ehead->twchain);
atomic_inc(&tw->tw_refcnt);
write_unlock(&ehead->lock);

View File

@ -1008,7 +1008,8 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
goto done;
dev = t->dev;
}
err = unregister_netdevice(dev);
unregister_netdevice(dev);
err = 0;
break;
default:

View File

@ -754,7 +754,8 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
goto done;
dev = t->dev;
}
err = unregister_netdevice(dev);
unregister_netdevice(dev);
err = 0;
break;
default:

View File

@ -361,32 +361,6 @@ config IP_NF_TARGET_ULOG
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_TCPMSS
tristate "TCPMSS target support"
depends on IP_NF_IPTABLES
---help---
This option adds a `TCPMSS' target, which allows you to alter the
MSS value of TCP SYN packets, to control the maximum size for that
connection (usually limiting it to your outgoing interface's MTU
minus 40).
This is used to overcome criminally braindead ISPs or servers which
block ICMP Fragmentation Needed packets. The symptoms of this
problem are that everything works fine from your Linux
firewall/router, but machines behind it can never exchange large
packets:
1) Web browsers connect, then hang with no data received.
2) Small mail works fine, but large emails hang.
3) ssh works fine, but scp hangs after initial handshaking.
Workaround: activate this option and add a rule to your firewall
configuration like:
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu
To compile it as a module, choose M here. If unsure, say N.
# NAT + specific targets: ip_conntrack
config IP_NF_NAT
tristate "Full NAT"

View File

@ -103,7 +103,6 @@ obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o

View File

@ -50,12 +50,9 @@ static DEFINE_RWLOCK(tcp_lock);
If it's non-zero, we mark only out of window RST segments as INVALID. */
int ip_ct_tcp_be_liberal __read_mostly = 0;
/* When connection is picked up from the middle, how many packets are required
to pass in each direction when we assume we are in sync - if any side uses
window scaling, we lost the game.
If it is set to zero, we disable picking up already established
/* If it is set to zero, we disable picking up already established
connections. */
int ip_ct_tcp_loose __read_mostly = 3;
int ip_ct_tcp_loose __read_mostly = 1;
/* Max number of the retransmitted packets without receiving an (acceptable)
ACK from the destination. If this number is reached, a shorter timer
@ -694,11 +691,10 @@ static int tcp_in_window(struct ip_ct_tcp *state,
before(sack, receiver->td_end + 1),
after(ack, receiver->td_end - MAXACKWINDOW(sender)));
if (sender->loose || receiver->loose ||
(before(seq, sender->td_maxend + 1) &&
after(end, sender->td_end - receiver->td_maxwin - 1) &&
before(sack, receiver->td_end + 1) &&
after(ack, receiver->td_end - MAXACKWINDOW(sender)))) {
if (before(seq, sender->td_maxend + 1) &&
after(end, sender->td_end - receiver->td_maxwin - 1) &&
before(sack, receiver->td_end + 1) &&
after(ack, receiver->td_end - MAXACKWINDOW(sender))) {
/*
* Take into account window scaling (RFC 1323).
*/
@ -743,15 +739,13 @@ static int tcp_in_window(struct ip_ct_tcp *state,
state->retrans = 0;
}
}
/*
* Close the window of disabled window tracking :-)
*/
if (sender->loose)
sender->loose--;
res = 1;
} else {
if (LOG_INVALID(IPPROTO_TCP))
res = 0;
if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
ip_ct_tcp_be_liberal)
res = 1;
if (!res && LOG_INVALID(IPPROTO_TCP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
"ip_ct_tcp: %s ",
before(seq, sender->td_maxend + 1) ?
@ -762,8 +756,6 @@ static int tcp_in_window(struct ip_ct_tcp *state,
: "ACK is over the upper bound (ACKed data not seen yet)"
: "SEQ is under the lower bound (already ACKed data retransmitted)"
: "SEQ is over the upper bound (over the window of the receiver)");
res = ip_ct_tcp_be_liberal;
}
DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
@ -1105,8 +1097,6 @@ static int tcp_new(struct ip_conntrack *conntrack,
tcp_options(skb, iph, th, &conntrack->proto.tcp.seen[0]);
conntrack->proto.tcp.seen[1].flags = 0;
conntrack->proto.tcp.seen[0].loose =
conntrack->proto.tcp.seen[1].loose = 0;
} else if (ip_ct_tcp_loose == 0) {
/* Don't try to pick up connections. */
return 0;
@ -1127,11 +1117,11 @@ static int tcp_new(struct ip_conntrack *conntrack,
conntrack->proto.tcp.seen[0].td_maxwin;
conntrack->proto.tcp.seen[0].td_scale = 0;
/* We assume SACK. Should we assume window scaling too? */
/* We assume SACK and liberal window checking to handle
* window scaling */
conntrack->proto.tcp.seen[0].flags =
conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
conntrack->proto.tcp.seen[0].loose =
conntrack->proto.tcp.seen[1].loose = ip_ct_tcp_loose;
conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
IP_CT_TCP_FLAG_BE_LIBERAL;
}
conntrack->proto.tcp.seen[1].td_end = 0;

View File

@ -246,8 +246,9 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
if (maniptype == IP_NAT_MANIP_SRC) {
if (find_appropriate_src(orig_tuple, tuple, range)) {
DEBUGP("get_unique_tuple: Found current src map\n");
if (!ip_nat_used_tuple(tuple, conntrack))
return;
if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
if (!ip_nat_used_tuple(tuple, conntrack))
return;
}
}
@ -261,6 +262,13 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
proto = ip_nat_proto_find_get(orig_tuple->dst.protonum);
/* Change protocol info to have some randomization */
if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
proto->unique_tuple(tuple, range, maniptype, conntrack);
ip_nat_proto_put(proto);
return;
}
/* Only bother mapping if it's not already in range and unique */
if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
|| proto->in_range(tuple, maniptype, &range->min, &range->max))

View File

@ -183,7 +183,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb,
datalen = (*pskb)->len - iph->ihl*4;
if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
tcph->check = 0;
tcph->check = tcp_v4_check(tcph, datalen,
tcph->check = tcp_v4_check(datalen,
iph->saddr, iph->daddr,
csum_partial((char *)tcph,
datalen, 0));

Some files were not shown because too many files have changed in this diff Show More