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:
commit
f049274b01
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
80
crypto/api.c
80
crypto/api.c
@ -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)
|
||||
|
@ -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
1801
crypto/camellia.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
||||
|
447
crypto/cipher.c
447
crypto/cipher.c
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
423
crypto/fcrypt.c
Normal 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>");
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
11
crypto/lrw.c
11
crypto/lrw.c
@ -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
349
crypto/pcbc.c
Normal 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");
|
@ -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 */
|
||||
|
||||
|
538
crypto/tcrypt.h
538
crypto/tcrypt.h
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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) */
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
21
include/linux/netfilter/nf_conntrack_sane.h
Normal file
21
include/linux/netfilter/nf_conntrack_sane.h
Normal 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 */
|
@ -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 */
|
||||
};
|
||||
|
||||
|
10
include/linux/netfilter/xt_TCPMSS.h
Normal file
10
include/linux/netfilter/xt_TCPMSS.h
Normal 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 */
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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*/
|
||||
|
@ -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);
|
||||
|
15
include/linux/netfilter_ipv6/ip6t_mh.h
Normal file
15
include/linux/netfilter_ipv6/ip6t_mh.h
Normal 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*/
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
106
include/net/iucv/af_iucv.h
Normal 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
415
include/net/iucv/iucv.h
Normal 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);
|
@ -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>
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user