Commit 0bbe34be authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/disk1/davem/BK/network-2.6

into nuts.ninka.net:/disk1/davem/BK/net-2.6
parents 88891ed3 b1dd647f
......@@ -678,4 +678,23 @@ IPv6 Update by:
Pekka Savola <pekkas@netcore.fi>
YOSHIFUJI Hideaki / USAGI Project <yoshfuji@linux-ipv6.org>
/proc/sys/net/bridge/* Variables:
bridge-nf-call-arptables - BOOLEAN
1 : pass bridged ARP traffic to arptables' FORWARD chain.
0 : disable this.
Default: 1
bridge-nf-call-iptables - BOOLEAN
1 : pass bridged IPv4 traffic to iptables' chains.
0 : disable this.
Default: 1
bridge-nf-filter-vlan-tagged - BOOLEAN
1 : pass bridged vlan-tagged ARP/IP traffic to arptables/iptables.
0 : disable this.
Default: 1
$Id: ip-sysctl.txt,v 1.20 2001/12/13 09:00:18 davem Exp $
......@@ -6,2384 +6,409 @@
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
* Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/scatterlist.h>
#include <linux/string.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
#include "tcrypt.h"
/*
* Need to kmalloc() memory for testing kmap().
*/
#define TVMEMSIZE 4096
#define XBUFSIZE 32768
/*
* Indexes into the xbuf to simulate cross-page access.
*/
#define IDX1 37
#define IDX2 32400
#define IDX3 1
#define IDX4 8193
#define IDX5 22222
#define IDX6 17101
#define IDX7 27333
#define IDX8 3000
static int mode;
static char *xbuf;
static char *tvmem;
static char *check[] = {
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
"deflate", NULL
};
static void
hexdump(unsigned char *buf, unsigned int len)
{
while (len--)
printk("%02x", *buf++);
printk("\n");
}
static void
test_md5(void)
{
char *p;
unsigned int i;
struct scatterlist sg[2];
char result[128];
struct crypto_tfm *tfm;
struct md5_testvec *md5_tv;
unsigned int tsize;
printk("\ntesting md5\n");
tsize = sizeof (md5_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, md5_tv_template, tsize);
md5_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("md5", 0);
if (tfm == NULL) {
printk("failed to load transform for md5\n");
return;
}
for (i = 0; i < MD5_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = md5_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = strlen(md5_tv[i].plaintext);
crypto_digest_init(tfm);
crypto_digest_update(tfm, sg, 1);
crypto_digest_final(tfm, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, md5_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
printk("\ntesting md5 across pages\n");
/* setup the dummy buffer first */
memset(xbuf, 0, XBUFSIZE);
memcpy(&xbuf[IDX1], "abcdefghijklm", 13);
memcpy(&xbuf[IDX2], "nopqrstuvwxyz", 13);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 13;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 13;
memset(result, 0, sizeof (result));
crypto_digest_digest(tfm, sg, 2, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, md5_tv[4].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
crypto_free_tfm(tfm);
}
#ifdef CONFIG_CRYPTO_HMAC
static void
test_hmac_md5(void)
{
char *p;
unsigned int i, klen;
struct scatterlist sg[2];
char result[128];
struct crypto_tfm *tfm;
struct hmac_md5_testvec *hmac_md5_tv;
unsigned int tsize;
tfm = crypto_alloc_tfm("md5", 0);
if (tfm == NULL) {
printk("failed to load transform for md5\n");
return;
}
printk("\ntesting hmac_md5\n");
tsize = sizeof (hmac_md5_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, hmac_md5_tv_template, tsize);
hmac_md5_tv = (void *) tvmem;
for (i = 0; i < HMAC_MD5_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = hmac_md5_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = strlen(hmac_md5_tv[i].plaintext);
klen = strlen(hmac_md5_tv[i].key);
crypto_hmac(tfm, hmac_md5_tv[i].key, &klen, sg, 1, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, hmac_md5_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
printk("\ntesting hmac_md5 across pages\n");
memset(xbuf, 0, XBUFSIZE);
memcpy(&xbuf[IDX1], "what do ya want ", 16);
memcpy(&xbuf[IDX2], "for nothing?", 12);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 16;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 12;
memset(result, 0, sizeof (result));
klen = strlen(hmac_md5_tv[7].key);
crypto_hmac(tfm, hmac_md5_tv[7].key, &klen, sg, 2, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, hmac_md5_tv[7].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
out:
crypto_free_tfm(tfm);
}
static void
test_hmac_sha1(void)
{
char *p;
unsigned int i, klen;
struct crypto_tfm *tfm;
struct hmac_sha1_testvec *hmac_sha1_tv;
struct scatterlist sg[2];
unsigned int tsize;
char result[SHA1_DIGEST_SIZE];
tfm = crypto_alloc_tfm("sha1", 0);
if (tfm == NULL) {
printk("failed to load transform for sha1\n");
return;
}
printk("\ntesting hmac_sha1\n");
tsize = sizeof (hmac_sha1_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, hmac_sha1_tv_template, tsize);
hmac_sha1_tv = (void *) tvmem;
for (i = 0; i < HMAC_SHA1_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = hmac_sha1_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = strlen(hmac_sha1_tv[i].plaintext);
klen = strlen(hmac_sha1_tv[i].key);
crypto_hmac(tfm, hmac_sha1_tv[i].key, &klen, sg, 1, result);
hexdump(result, sizeof (result));
printk("%s\n",
memcmp(result, hmac_sha1_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
printk("\ntesting hmac_sha1 across pages\n");
/* setup the dummy buffer first */
memset(xbuf, 0, XBUFSIZE);
memcpy(&xbuf[IDX1], "what do ya want ", 16);
memcpy(&xbuf[IDX2], "for nothing?", 12);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 16;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 12;
memset(result, 0, sizeof (result));
klen = strlen(hmac_sha1_tv[7].key);
crypto_hmac(tfm, hmac_sha1_tv[7].key, &klen, sg, 2, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, hmac_sha1_tv[7].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
out:
crypto_free_tfm(tfm);
}
static void
test_hmac_sha256(void)
{
char *p;
unsigned int i, klen;
struct crypto_tfm *tfm;
struct hmac_sha256_testvec *hmac_sha256_tv;
struct scatterlist sg[2];
unsigned int tsize;
char result[SHA256_DIGEST_SIZE];
tfm = crypto_alloc_tfm("sha256", 0);
if (tfm == NULL) {
printk("failed to load transform for sha256\n");
return;
}
printk("\ntesting hmac_sha256\n");
tsize = sizeof (hmac_sha256_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, hmac_sha256_tv_template, tsize);
hmac_sha256_tv = (void *) tvmem;
for (i = 0; i < HMAC_SHA256_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = hmac_sha256_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = strlen(hmac_sha256_tv[i].plaintext);
klen = strlen(hmac_sha256_tv[i].key);
hexdump(hmac_sha256_tv[i].key, strlen(hmac_sha256_tv[i].key));
crypto_hmac(tfm, hmac_sha256_tv[i].key, &klen, sg, 1, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, hmac_sha256_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
}
out:
crypto_free_tfm(tfm);
}
#endif /* CONFIG_CRYPTO_HMAC */
static void
test_md4(void)
{
char *p;
unsigned int i;
struct scatterlist sg[1];
char result[128];
struct crypto_tfm *tfm;
struct md4_testvec *md4_tv;
unsigned int tsize;
printk("\ntesting md4\n");
tsize = sizeof (md4_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, md4_tv_template, tsize);
md4_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("md4", 0);
if (tfm == NULL) {
printk("failed to load transform for md4\n");
return;
}
for (i = 0; i < MD4_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = md4_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = strlen(md4_tv[i].plaintext);
crypto_digest_digest(tfm, sg, 1, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, md4_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
crypto_free_tfm(tfm);
}
static void
test_sha1(void)
{
char *p;
unsigned int i;
struct crypto_tfm *tfm;
struct sha1_testvec *sha1_tv;
struct scatterlist sg[2];
unsigned int tsize;
char result[SHA1_DIGEST_SIZE];
printk("\ntesting sha1\n");
tsize = sizeof (sha1_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, sha1_tv_template, tsize);
sha1_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("sha1", 0);
if (tfm == NULL) {
printk("failed to load transform for sha1\n");
return;
}
for (i = 0; i < SHA1_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = sha1_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = strlen(sha1_tv[i].plaintext);
crypto_digest_init(tfm);
crypto_digest_update(tfm, sg, 1);
crypto_digest_final(tfm, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, sha1_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
printk("\ntesting sha1 across pages\n");
/* setup the dummy buffer first */
memset(xbuf, 0, XBUFSIZE);
memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28);
memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 28;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 28;
memset(result, 0, sizeof (result));
crypto_digest_digest(tfm, sg, 2, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, sha1_tv[1].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
crypto_free_tfm(tfm);
}
static void
test_sha256(void)
{
char *p;
unsigned int i;
struct crypto_tfm *tfm;
struct sha256_testvec *sha256_tv;
struct scatterlist sg[2];
unsigned int tsize;
char result[SHA256_DIGEST_SIZE];
printk("\ntesting sha256\n");
tsize = sizeof (sha256_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, sha256_tv_template, tsize);
sha256_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("sha256", 0);
if (tfm == NULL) {
printk("failed to load transform for sha256\n");
return;
}
for (i = 0; i < SHA256_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = sha256_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = strlen(sha256_tv[i].plaintext);
crypto_digest_init(tfm);
crypto_digest_update(tfm, sg, 1);
crypto_digest_final(tfm, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, sha256_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
printk("\ntesting sha256 across pages\n");
/* setup the dummy buffer first */
memset(xbuf, 0, XBUFSIZE);
memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28);
memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 28;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 28;
memset(result, 0, sizeof (result));
crypto_digest_digest(tfm, sg, 2, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, sha256_tv[1].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
crypto_free_tfm(tfm);
}
static void
test_sha384(void)
{
char *p;
unsigned int i;
struct crypto_tfm *tfm;
struct sha384_testvec *sha384_tv;
struct scatterlist sg[2];
unsigned int tsize;
char result[SHA384_DIGEST_SIZE];
printk("\ntesting sha384\n");
tsize = sizeof (sha384_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, sha384_tv_template, tsize);
sha384_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("sha384", 0);
if (tfm == NULL) {
printk("failed to load transform for sha384\n");
return;
}
for (i = 0; i < SHA384_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = sha384_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = strlen(sha384_tv[i].plaintext);
crypto_digest_init(tfm);
crypto_digest_update(tfm, sg, 1);
crypto_digest_final(tfm, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, sha384_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
crypto_free_tfm(tfm);
}
static void
test_sha512(void)
{
char *p;
unsigned int i;
struct crypto_tfm *tfm;
struct sha512_testvec *sha512_tv;
struct scatterlist sg[2];
unsigned int tsize;
char result[SHA512_DIGEST_SIZE];
printk("\ntesting sha512\n");
tsize = sizeof (sha512_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, sha512_tv_template, tsize);
sha512_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("sha512", 0);
if (tfm == NULL) {
printk("failed to load transform for sha512\n");
return;
}
for (i = 0; i < SHA512_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = sha512_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = strlen(sha512_tv[i].plaintext);
crypto_digest_init(tfm);
crypto_digest_update(tfm, sg, 1);
crypto_digest_final(tfm, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, sha512_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
crypto_free_tfm(tfm);
}
void
test_des(void)
{
unsigned int ret, i, len;
unsigned int tsize;
char *p, *q;
struct crypto_tfm *tfm;
char *key;
char res[8];
struct des_tv *des_tv;
struct scatterlist sg[8];
printk("\ntesting des encryption\n");
tsize = sizeof (des_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, des_enc_tv_template, tsize);
des_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("des", 0);
if (tfm == NULL) {
printk("failed to load transform for des (default ecb)\n");
return;
}
for (i = 0; i < DES_ENC_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
key = des_tv[i].key;
tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!des_tv[i].fail)
goto out;
}
len = des_tv[i].len;
p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = len;
ret = crypto_cipher_encrypt(tfm, sg, sg, len);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, len);
printk("%s\n",
memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
}
printk("\ntesting des ecb encryption across pages\n");
i = 5;
key = des_tv[i].key;
tfm->crt_flags = 0;
hexdump(key, 8);
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/* setup the dummy buffer first */
memset(xbuf, 0, sizeof (xbuf));
memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8);
memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 8;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 8;
ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
printk("page 1\n");
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, 8);
printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass");
printk("page 2\n");
q = kmap(sg[1].page) + sg[1].offset;
hexdump(q, 8);
printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass");
printk("\ntesting des ecb encryption chunking scenario A\n");
/*
* Scenario A:
*
* F1 F2 F3
* [8 + 6] [2 + 8] [8]
* ^^^^^^ ^
* a b c
*
* Chunking should begin at a, then end with b, and
* continue encrypting at an offset of 2 until c.
*
*/
i = 7;
key = des_tv[i].key;
tfm->crt_flags = 0;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/* setup the dummy buffer first */
memset(xbuf, 0, sizeof (xbuf));
/* Frag 1: 8 + 6 */
memcpy(&xbuf[IDX3], des_tv[i].plaintext, 14);
/* Frag 2: 2 + 8 */
memcpy(&xbuf[IDX4], des_tv[i].plaintext + 14, 10);
/* Frag 3: 8 */
memcpy(&xbuf[IDX5], des_tv[i].plaintext + 24, 8);
p = &xbuf[IDX3];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 14;
p = &xbuf[IDX4];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 10;
p = &xbuf[IDX5];
sg[2].page = virt_to_page(p);
sg[2].offset = offset_in_page(p);
sg[2].length = 8;
ret = crypto_cipher_encrypt(tfm, sg, sg, 32);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
printk("page 1\n");
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, 14);
printk("%s\n", memcmp(q, des_tv[i].result, 14) ? "fail" : "pass");
printk("page 2\n");
q = kmap(sg[1].page) + sg[1].offset;
hexdump(q, 10);
printk("%s\n", memcmp(q, des_tv[i].result + 14, 10) ? "fail" : "pass");
printk("page 3\n");
q = kmap(sg[2].page) + sg[2].offset;
hexdump(q, 8);
printk("%s\n", memcmp(q, des_tv[i].result + 24, 8) ? "fail" : "pass");
printk("\ntesting des ecb encryption chunking scenario B\n");
/*
* Scenario B:
*
* F1 F2 F3 F4
* [2] [1] [3] [2 + 8 + 8]
*/
i = 7;
key = des_tv[i].key;
tfm->crt_flags = 0;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/* setup the dummy buffer first */
memset(xbuf, 0, sizeof (xbuf));
/* Frag 1: 2 */
memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2);
/* Frag 2: 1 */
memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 1);
/* Frag 3: 3 */
memcpy(&xbuf[IDX5], des_tv[i].plaintext + 3, 3);
/* Frag 4: 2 + 8 + 8 */
memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 18);
p = &xbuf[IDX3];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 2;
p = &xbuf[IDX4];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 1;
p = &xbuf[IDX5];
sg[2].page = virt_to_page(p);
sg[2].offset = offset_in_page(p);
sg[2].length = 3;
p = &xbuf[IDX6];
sg[3].page = virt_to_page(p);
sg[3].offset = offset_in_page(p);
sg[3].length = 18;
ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
printk("page 1\n");
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, 2);
printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass");
printk("page 2\n");
q = kmap(sg[1].page) + sg[1].offset;
hexdump(q, 1);
printk("%s\n", memcmp(q, des_tv[i].result + 2, 1) ? "fail" : "pass");
printk("page 3\n");
q = kmap(sg[2].page) + sg[2].offset;
hexdump(q, 3);
printk("%s\n", memcmp(q, des_tv[i].result + 3, 3) ? "fail" : "pass");
printk("page 4\n");
q = kmap(sg[3].page) + sg[3].offset;
hexdump(q, 18);
printk("%s\n", memcmp(q, des_tv[i].result + 6, 18) ? "fail" : "pass");
printk("\ntesting des ecb encryption chunking scenario C\n");
/*
* Scenario B:
*
* F1 F2 F3 F4 F5
* [2] [2] [2] [2] [8]
*/
i = 7;
key = des_tv[i].key;
tfm->crt_flags = 0;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/* setup the dummy buffer first */
memset(xbuf, 0, sizeof (xbuf));
/* Frag 1: 2 */
memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2);
/* Frag 2: 2 */
memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 2);
/* Frag 3: 2 */
memcpy(&xbuf[IDX5], des_tv[i].plaintext + 4, 2);
/* Frag 4: 2 */
memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 2);
/* Frag 5: 8 */
memcpy(&xbuf[IDX7], des_tv[i].plaintext + 8, 8);
p = &xbuf[IDX3];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 2;
p = &xbuf[IDX4];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 2;
p = &xbuf[IDX5];
sg[2].page = virt_to_page(p);
sg[2].offset = offset_in_page(p);
sg[2].length = 2;
p = &xbuf[IDX6];
sg[3].page = virt_to_page(p);
sg[3].offset = offset_in_page(p);
sg[3].length = 2;
p = &xbuf[IDX7];
sg[4].page = virt_to_page(p);
sg[4].offset = offset_in_page(p);
sg[4].length = 8;
ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
printk("page 1\n");
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, 2);
printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass");
printk("page 2\n");
q = kmap(sg[1].page) + sg[1].offset;
hexdump(q, 2);
printk("%s\n", memcmp(q, des_tv[i].result + 2, 2) ? "fail" : "pass");
printk("page 3\n");
q = kmap(sg[2].page) + sg[2].offset;
hexdump(q, 2);
printk("%s\n", memcmp(q, des_tv[i].result + 4, 2) ? "fail" : "pass");
printk("page 4\n");
q = kmap(sg[3].page) + sg[3].offset;
hexdump(q, 2);
printk("%s\n", memcmp(q, des_tv[i].result + 6, 2) ? "fail" : "pass");
printk("page 5\n");
q = kmap(sg[4].page) + sg[4].offset;
hexdump(q, 8);
printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass");
printk("\ntesting des ecb encryption chunking scenario D\n");
/*
* Scenario D, torture test, one byte per frag.
*/
i = 7;
key = des_tv[i].key;
tfm->crt_flags = 0;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/* setup the dummy buffer first */
memset(xbuf, 0, XBUFSIZE);
xbuf[IDX1] = des_tv[i].plaintext[0];
xbuf[IDX2] = des_tv[i].plaintext[1];
xbuf[IDX3] = des_tv[i].plaintext[2];
xbuf[IDX4] = des_tv[i].plaintext[3];
xbuf[IDX5] = des_tv[i].plaintext[4];
xbuf[IDX6] = des_tv[i].plaintext[5];
xbuf[IDX7] = des_tv[i].plaintext[6];
xbuf[IDX8] = des_tv[i].plaintext[7];
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 1;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 1;
p = &xbuf[IDX3];
sg[2].page = virt_to_page(p);
sg[2].offset = offset_in_page(p);
sg[2].length = 1;
p = &xbuf[IDX4];
sg[3].page = virt_to_page(p);
sg[3].offset = offset_in_page(p);
sg[3].length = 1;
p = &xbuf[IDX5];
sg[4].page = virt_to_page(p);
sg[4].offset = offset_in_page(p);
sg[4].length = 1;
p = &xbuf[IDX6];
sg[5].page = virt_to_page(p);
sg[5].offset = offset_in_page(p);
sg[5].length = 1;
p = &xbuf[IDX7];
sg[6].page = virt_to_page(p);
sg[6].offset = offset_in_page(p);
sg[6].length = 1;
p = &xbuf[IDX8];
sg[7].page = virt_to_page(p);
sg[7].offset = offset_in_page(p);
sg[7].length = 1;
ret = crypto_cipher_encrypt(tfm, sg, sg, 8);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
for (i = 0; i < 8; i++)
res[i] = *(char *) (kmap(sg[i].page) + sg[i].offset);
hexdump(res, 8);
printk("%s\n", memcmp(res, des_tv[7].result, 8) ? "fail" : "pass");
printk("\ntesting des decryption\n");
tsize = sizeof (des_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, des_dec_tv_template, tsize);
des_tv = (void *) tvmem;
for (i = 0; i < DES_DEC_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
key = des_tv[i].key;
tfm->crt_flags = 0;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
len = des_tv[i].len;
p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = len;
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("des_decrypt() failed flags=%x\n",
tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, len);
printk("%s\n",
memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
}
printk("\ntesting des ecb decryption across pages\n");
i = 6;
key = des_tv[i].key;
tfm->crt_flags = 0;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/* setup the dummy buffer first */
memset(xbuf, 0, sizeof (xbuf));
memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8);
memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 8;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 8;
ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
printk("page 1\n");
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, 8);
printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass");
printk("page 2\n");
q = kmap(sg[1].page) + sg[1].offset;
hexdump(q, 8);
printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass");
/*
* Scenario E:
*
* F1 F2 F3
* [3] [5 + 7] [1]
*
*/
printk("\ntesting des ecb decryption chunking scenario E\n");
i = 2;
key = des_tv[i].key;
tfm->crt_flags = 0;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/* setup the dummy buffer first */
memset(xbuf, 0, sizeof (xbuf));
memcpy(&xbuf[IDX1], des_tv[i].plaintext, 3);
memcpy(&xbuf[IDX2], des_tv[i].plaintext + 3, 12);
memcpy(&xbuf[IDX3], des_tv[i].plaintext + 15, 1);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 3;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 12;
p = &xbuf[IDX3];
sg[2].page = virt_to_page(p);
sg[2].offset = offset_in_page(p);
sg[2].length = 1;
ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
printk("page 1\n");
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, 3);
printk("%s\n", memcmp(q, des_tv[i].result, 3) ? "fail" : "pass");
printk("page 2\n");
q = kmap(sg[1].page) + sg[1].offset;
hexdump(q, 12);
printk("%s\n", memcmp(q, des_tv[i].result + 3, 12) ? "fail" : "pass");
printk("page 3\n");
q = kmap(sg[2].page) + sg[2].offset;
hexdump(q, 1);
printk("%s\n", memcmp(q, des_tv[i].result + 15, 1) ? "fail" : "pass");
crypto_free_tfm(tfm);
tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC);
if (tfm == NULL) {
printk("failed to load transform for des cbc\n");
return;
}
printk("\ntesting des cbc encryption\n");
tsize = sizeof (des_cbc_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, des_cbc_enc_tv_template, tsize);
des_tv = (void *) tvmem;
crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
crypto_cipher_get_iv(tfm, res, crypto_tfm_alg_ivsize(tfm));
if (memcmp(res, des_tv[i].iv, sizeof(res))) {
printk("crypto_cipher_[set|get]_iv() failed\n");
goto out;
}
for (i = 0; i < DES_CBC_ENC_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
key = des_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
len = des_tv[i].len;
p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = len;
crypto_cipher_set_iv(tfm, des_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, sg, len);
if (ret) {
printk("des_cbc_encrypt() failed flags=%x\n",
tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, len);
printk("%s\n",
memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
}
crypto_free_tfm(tfm);
/*
* Scenario F:
*
* F1 F2
* [8 + 5] [3 + 8]
*
*/
printk("\ntesting des cbc encryption chunking scenario F\n");
i = 4;
tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC);
if (tfm == NULL) {
printk("failed to load transform for CRYPTO_ALG_DES_CCB\n");
return;
}
tfm->crt_flags = 0;
key = des_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/* setup the dummy buffer first */
memset(xbuf, 0, sizeof (xbuf));
memcpy(&xbuf[IDX1], des_tv[i].plaintext, 13);
memcpy(&xbuf[IDX2], des_tv[i].plaintext + 13, 11);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 13;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 11;
crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
if (ret) {
printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
printk("page 1\n");
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, 13);
printk("%s\n", memcmp(q, des_tv[i].result, 13) ? "fail" : "pass");
printk("page 2\n");
q = kmap(sg[1].page) + sg[1].offset;
hexdump(q, 11);
printk("%s\n", memcmp(q, des_tv[i].result + 13, 11) ? "fail" : "pass");
tsize = sizeof (des_cbc_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, des_cbc_dec_tv_template, tsize);
des_tv = (void *) tvmem;
printk("\ntesting des cbc decryption\n");
for (i = 0; i < DES_CBC_DEC_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
tfm->crt_flags = 0;
key = des_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
len = des_tv[i].len;
p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = len;
crypto_cipher_set_iv(tfm, des_tv[i].iv,
crypto_tfm_alg_blocksize(tfm));
ret = crypto_cipher_decrypt(tfm, sg, sg, len);
if (ret) {
printk("des_cbc_decrypt() failed flags=%x\n",
tfm->crt_flags);
goto out;
}
hexdump(tfm->crt_cipher.cit_iv, 8);
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, len);
printk("%s\n",
memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
}
/*
* Scenario G:
*
* F1 F2
* [4] [4]
*
*/
printk("\ntesting des cbc decryption chunking scenario G\n");
i = 3;
tfm->crt_flags = 0;
key = des_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, 8);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/* setup the dummy buffer first */
memset(xbuf, 0, sizeof (xbuf));
memcpy(&xbuf[IDX1], des_tv[i].plaintext, 4);
memcpy(&xbuf[IDX2], des_tv[i].plaintext + 4, 4);
p = &xbuf[IDX1];
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = 4;
p = &xbuf[IDX2];
sg[1].page = virt_to_page(p);
sg[1].offset = offset_in_page(p);
sg[1].length = 4;
crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_decrypt(tfm, sg, sg, 8);
if (ret) {
printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
printk("page 1\n");
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, 4);
printk("%s\n", memcmp(q, des_tv[i].result, 4) ? "fail" : "pass");
printk("page 2\n");
q = kmap(sg[1].page) + sg[1].offset;
hexdump(q, 4);
printk("%s\n", memcmp(q, des_tv[i].result + 4, 4) ? "fail" : "pass");
out:
crypto_free_tfm(tfm);
}
void
test_des3_ede(void)
{
unsigned int ret, i, len;
unsigned int tsize;
char *p, *q;
struct crypto_tfm *tfm;
char *key;
/*char res[8]; */
struct des_tv *des_tv;
struct scatterlist sg[8];
printk("\ntesting des3 ede encryption\n");
tsize = sizeof (des3_ede_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, des3_ede_enc_tv_template, tsize);
des_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("des3_ede", CRYPTO_TFM_MODE_ECB);
if (tfm == NULL) {
printk("failed to load transform for 3des ecb\n");
return;
}
for (i = 0; i < DES3_EDE_ENC_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
key = des_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, 24);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!des_tv[i].fail)
goto out;
}
len = des_tv[i].len;
p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = len;
ret = crypto_cipher_encrypt(tfm, sg, sg, len);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, len);
printk("%s\n",
memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
}
printk("\ntesting des3 ede decryption\n");
tsize = sizeof (des3_ede_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, des3_ede_dec_tv_template, tsize);
des_tv = (void *) tvmem;
for (i = 0; i < DES3_EDE_DEC_TEST_VECTORS; i++) {
printk("test %u:\n", i + 1);
key = des_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, 24);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!des_tv[i].fail)
goto out;
}
len = des_tv[i].len;
p = des_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = len;
ret = crypto_cipher_decrypt(tfm, sg, sg, len);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, len);
printk("%s\n",
memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
}
out:
crypto_free_tfm(tfm);
}
void
test_blowfish(void)
{
unsigned int ret, i;
unsigned int tsize;
char *p, *q;
struct crypto_tfm *tfm;
char *key;
struct bf_tv *bf_tv;
struct scatterlist sg[1];
printk("\ntesting blowfish encryption\n");
tsize = sizeof (bf_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, bf_enc_tv_template, tsize);
bf_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("blowfish", 0);
if (tfm == NULL) {
printk("failed to load transform for blowfish (default ecb)\n");
return;
}
for (i = 0; i < BF_ENC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, bf_tv[i].keylen * 8);
key = bf_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!bf_tv[i].fail)
goto out;
}
p = bf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = bf_tv[i].plen;
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, bf_tv[i].rlen);
printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ?
"fail" : "pass");
}
printk("\ntesting blowfish decryption\n");
tsize = sizeof (bf_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, bf_dec_tv_template, tsize);
bf_tv = (void *) tvmem;
for (i = 0; i < BF_DEC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, bf_tv[i].keylen * 8);
key = bf_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!bf_tv[i].fail)
goto out;
}
p = bf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = bf_tv[i].plen;
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, bf_tv[i].rlen);
printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ?
"fail" : "pass");
}
crypto_free_tfm(tfm);
tfm = crypto_alloc_tfm("blowfish", CRYPTO_TFM_MODE_CBC);
if (tfm == NULL) {
printk("failed to load transform for blowfish cbc\n");
return;
}
printk("\ntesting blowfish cbc encryption\n");
tsize = sizeof (bf_cbc_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, bf_cbc_enc_tv_template, tsize);
bf_tv = (void *) tvmem;
for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, bf_tv[i].keylen * 8);
key = bf_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
p = bf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = bf_tv[i].plen;
crypto_cipher_set_iv(tfm, bf_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("blowfish_cbc_encrypt() failed flags=%x\n",
tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, bf_tv[i].rlen);
printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen)
? "fail" : "pass");
}
printk("\ntesting blowfish cbc decryption\n");
tsize = sizeof (bf_cbc_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, bf_cbc_dec_tv_template, tsize);
bf_tv = (void *) tvmem;
for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, bf_tv[i].keylen * 8);
key = bf_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
p = bf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = bf_tv[i].plen;
crypto_cipher_set_iv(tfm, bf_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("blowfish_cbc_decrypt() failed flags=%x\n",
tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, bf_tv[i].rlen);
printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen)
? "fail" : "pass");
}
out:
crypto_free_tfm(tfm);
}
void
test_twofish(void)
{
unsigned int ret, i;
unsigned int tsize;
char *p, *q;
struct crypto_tfm *tfm;
char *key;
struct tf_tv *tf_tv;
struct scatterlist sg[1];
printk("\ntesting twofish encryption\n");
tsize = sizeof (tf_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, tf_enc_tv_template, tsize);
tf_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("twofish", 0);
if (tfm == NULL) {
printk("failed to load transform for blowfish (default ecb)\n");
return;
}
for (i = 0; i < TF_ENC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, tf_tv[i].keylen * 8);
key = tf_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!tf_tv[i].fail)
goto out;
}
p = tf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = tf_tv[i].plen;
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, tf_tv[i].rlen);
printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ?
"fail" : "pass");
}
printk("\ntesting twofish decryption\n");
tsize = sizeof (tf_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, tf_dec_tv_template, tsize);
tf_tv = (void *) tvmem;
for (i = 0; i < TF_DEC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, tf_tv[i].keylen * 8);
key = tf_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!tf_tv[i].fail)
goto out;
}
p = tf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = tf_tv[i].plen;
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, tf_tv[i].rlen);
printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ?
"fail" : "pass");
}
crypto_free_tfm(tfm);
tfm = crypto_alloc_tfm("twofish", CRYPTO_TFM_MODE_CBC);
if (tfm == NULL) {
printk("failed to load transform for twofish cbc\n");
return;
}
printk("\ntesting twofish cbc encryption\n");
tsize = sizeof (tf_cbc_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, tf_cbc_enc_tv_template, tsize);
tf_tv = (void *) tvmem;
for (i = 0; i < TF_CBC_ENC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, tf_tv[i].keylen * 8);
key = tf_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
p = tf_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = tf_tv[i].plen;
crypto_cipher_set_iv(tfm, tf_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("blowfish_cbc_encrypt() failed flags=%x\n",
tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, tf_tv[i].rlen);
printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen)
? "fail" : "pass");
}
printk("\ntesting twofish cbc decryption\n");
tsize = sizeof (tf_cbc_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, tf_cbc_dec_tv_template, tsize);
tf_tv = (void *) tvmem;
for (i = 0; i < TF_CBC_DEC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, tf_tv[i].keylen * 8);
*
* 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.
*
* 14 - 09 - 2003
* Rewritten by Kartikey Mahendra Bhatt
*/
key = tf_tv[i].key;
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/scatterlist.h>
#include <linux/string.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
#include "tcrypt.h"
ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
goto out;
}
/*
* Need to kmalloc() memory for testing kmap().
*/
#define TVMEMSIZE 4096
#define XBUFSIZE 32768
p = tf_tv[i].plaintext;
/*
* Indexes into the xbuf to simulate cross-page access.
*/
#define IDX1 37
#define IDX2 32400
#define IDX3 1
#define IDX4 8193
#define IDX5 22222
#define IDX6 17101
#define IDX7 27333
#define IDX8 3000
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = tf_tv[i].plen;
/*
* Used by test_cipher()
*/
#define ENCRYPT 1
#define DECRYPT 0
#define MODE_ECB 1
#define MODE_CBC 0
crypto_cipher_set_iv(tfm, tf_tv[i].iv,
crypto_tfm_alg_ivsize(tfm));
static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("blowfish_cbc_decrypt() failed flags=%x\n",
tfm->crt_flags);
goto out;
}
static int mode;
static char *xbuf;
static char *tvmem;
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, tf_tv[i].rlen);
static char *check[] = {
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
"deflate", NULL
};
printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen)
? "fail" : "pass");
}
static void
hexdump(unsigned char *buf, unsigned int len)
{
while (len--)
printk("%02x", *buf++);
out:
crypto_free_tfm(tfm);
printk("\n");
}
void
test_serpent(void)
static void
test_hash (char * algo, struct hash_testvec * template, unsigned int tcount)
{
unsigned int ret, i, tsize;
u8 *p, *q, *key;
struct crypto_tfm *tfm;
struct serpent_tv *serp_tv;
struct scatterlist sg[1];
printk("\ntesting serpent encryption\n");
tfm = crypto_alloc_tfm("serpent", 0);
if (tfm == NULL) {
printk("failed to load transform for serpent (default ecb)\n");
char *p;
unsigned int i, j, k, temp;
struct scatterlist sg[8];
char result[64];
struct crypto_tfm *tfm;
struct hash_testvec *hash_tv;
unsigned int tsize;
printk("\ntesting %s\n", algo);
tsize = sizeof (struct hash_testvec);
tsize *= tcount;
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE);
return;
}
tsize = sizeof (serpent_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
memcpy(tvmem, template, tsize);
hash_tv = (void *) tvmem;
tfm = crypto_alloc_tfm(algo, 0);
if (tfm == NULL) {
printk("failed to load transform for %s\n", algo);
return;
}
memcpy(tvmem, serpent_enc_tv_template, tsize);
serp_tv = (void *) tvmem;
for (i = 0; i < SERPENT_ENC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8);
key = serp_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!serp_tv[i].fail)
goto out;
}
p = serp_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = sizeof(serp_tv[i].plaintext);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, sizeof(serp_tv[i].result));
for (i = 0; i < tcount; i++) {
printk ("test %u:\n", i + 1);
memset (result, 0, 64);
printk("%s\n", memcmp(q, serp_tv[i].result,
sizeof(serp_tv[i].result)) ? "fail" : "pass");
}
p = hash_tv[i].plaintext;
sg[0].page = virt_to_page (p);
sg[0].offset = offset_in_page (p);
sg[0].length = hash_tv[i].psize;
printk("\ntesting serpent decryption\n");
crypto_digest_init (tfm);
crypto_digest_update (tfm, sg, 1);
crypto_digest_final (tfm, result);
tsize = sizeof (serpent_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
hexdump (result, crypto_tfm_alg_digestsize (tfm));
printk("%s\n",
memcmp(result, hash_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
memcpy(tvmem, serpent_dec_tv_template, tsize);
serp_tv = (void *) tvmem;
for (i = 0; i < SERPENT_DEC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8);
key = serp_tv[i].key;
printk ("testing %s across pages\n", algo);
ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!serp_tv[i].fail)
goto out;
}
p = serp_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = sizeof(serp_tv[i].plaintext);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
/* setup the dummy buffer first */
memset(xbuf, 0, XBUFSIZE);
j = 0;
for (i = 0; i < tcount; i++) {
if (hash_tv[i].np) {
j++;
printk ("test %u:\n", j);
memset (result, 0, 64);
temp = 0;
for (k = 0; k < hash_tv[i].np; k++) {
memcpy (&xbuf[IDX[k]], hash_tv[i].plaintext + temp,
hash_tv[i].tap[k]);
temp += hash_tv[i].tap[k];
p = &xbuf[IDX[k]];
sg[k].page = virt_to_page (p);
sg[k].offset = offset_in_page (p);
sg[k].length = hash_tv[i].tap[k];
}
crypto_digest_digest (tfm, sg, hash_tv[i].np, result);
hexdump (result, crypto_tfm_alg_digestsize (tfm));
printk("%s\n",
memcmp(result, hash_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, sizeof(serp_tv[i].result));
printk("%s\n", memcmp(q, serp_tv[i].result,
sizeof(serp_tv[i].result)) ? "fail" : "pass");
}
out:
crypto_free_tfm(tfm);
crypto_free_tfm (tfm);
}
#ifdef CONFIG_CRYPTO_HMAC
static void
test_cast6(void)
test_hmac(char *algo, struct hmac_testvec * template, unsigned int tcount)
{
unsigned int ret, i, tsize;
u8 *p, *q, *key;
char *p;
unsigned int i, j, k, temp;
struct scatterlist sg[8];
char result[64];
struct crypto_tfm *tfm;
struct cast6_tv *cast_tv;
struct scatterlist sg[1];
printk("\ntesting cast6 encryption\n");
struct hmac_testvec *hmac_tv;
unsigned int tsize, klen;
tfm = crypto_alloc_tfm("cast6", 0);
tfm = crypto_alloc_tfm(algo, 0);
if (tfm == NULL) {
printk("failed to load transform for cast6 (default ecb)\n");
printk("failed to load transform for %s\n", algo);
return;
}
tsize = sizeof (cast6_enc_tv_template);
printk("\ntesting hmac_%s\n", algo);
tsize = sizeof (struct hmac_testvec);
tsize *= tcount;
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
goto out;
}
memcpy(tvmem, cast6_enc_tv_template, tsize);
cast_tv = (void *) tvmem;
for (i = 0; i < CAST6_ENC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n", i + 1, cast_tv[i].keylen * 8);
key = cast_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, cast_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
memcpy(tvmem, template, tsize);
hmac_tv = (void *) tvmem;
if (!cast_tv[i].fail)
goto out;
}
for (i = 0; i < tcount; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = cast_tv[i].plaintext;
p = hmac_tv[i].plaintext;
klen = hmac_tv[i].ksize;
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = sizeof(cast_tv[i].plaintext);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, sizeof(cast_tv[i].result));
printk("%s\n", memcmp(q, cast_tv[i].result,
sizeof(cast_tv[i].result)) ? "fail" : "pass");
}
sg[0].offset = offset_in_page(p);
sg[0].length = hmac_tv[i].psize;
printk("\ntesting cast6 decryption\n");
crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result);
tsize = sizeof (cast6_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, hmac_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
memcpy(tvmem, cast6_dec_tv_template, tsize);
cast_tv = (void *) tvmem;
for (i = 0; i < CAST6_DEC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n", i + 1, cast_tv[i].keylen * 8);
key = cast_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, cast_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!cast_tv[i].fail)
goto out;
}
printk("\ntesting hmac_%s across pages\n", algo);
p = cast_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = sizeof(cast_tv[i].plaintext);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
memset(xbuf, 0, XBUFSIZE);
j = 0;
for (i = 0; i < tcount; i++) {
if (hmac_tv[i].np) {
j++;
printk ("test %u:\n",j);
memset (result, 0, 64);
temp = 0;
klen = hmac_tv[i].ksize;
for (k = 0; k < hmac_tv[i].np; k++) {
memcpy (&xbuf[IDX[k]], hmac_tv[i].plaintext + temp,
hmac_tv[i].tap[k]);
temp += hmac_tv[i].tap[k];
p = &xbuf[IDX[k]];
sg[k].page = virt_to_page (p);
sg[k].offset = offset_in_page (p);
sg[k].length = hmac_tv[i].tap[k];
}
crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, hmac_tv[i].np,
result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, hmac_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, sizeof(cast_tv[i].result));
printk("%s\n", memcmp(q, cast_tv[i].result,
sizeof(cast_tv[i].result)) ? "fail" : "pass");
}
out:
crypto_free_tfm(tfm);
}
#endif /* CONFIG_CRYPTO_HMAC */
void
test_aes(void)
test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, unsigned int tcount)
{
unsigned int ret, i;
unsigned int ret, i, j, k, temp;
unsigned int tsize;
char *p, *q;
struct crypto_tfm *tfm;
char *key;
struct aes_tv *aes_tv;
struct scatterlist sg[1];
printk("\ntesting aes encryption\n");
tsize = sizeof (aes_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, aes_enc_tv_template, tsize);
aes_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("aes", 0);
if (tfm == NULL) {
printk("failed to load transform for aes (default ecb)\n");
return;
}
for (i = 0; i < AES_ENC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, aes_tv[i].keylen * 8);
key = aes_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!aes_tv[i].fail)
goto out;
}
struct cipher_testvec *cipher_tv;
struct scatterlist sg[8];
char e[11], m[4];
p = aes_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = aes_tv[i].plen;
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
if (enc == ENCRYPT)
strncpy(e, "encryption", 11);
else
strncpy(e, "decryption", 11);
if (mode == MODE_ECB)
strncpy(m, "ECB", 4);
else
strncpy(m, "CBC", 4);
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, aes_tv[i].rlen);
printk("\ntesting %s %s %s \n", algo, m, e);
printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ?
"fail" : "pass");
}
tsize = sizeof (struct cipher_testvec);
tsize *= tcount;
printk("\ntesting aes decryption\n");
tsize = sizeof (aes_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, aes_dec_tv_template, tsize);
aes_tv = (void *) tvmem;
for (i = 0; i < AES_DEC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n",
i + 1, aes_tv[i].keylen * 8);
key = aes_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!aes_tv[i].fail)
goto out;
}
p = aes_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = aes_tv[i].plen;
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, aes_tv[i].rlen);
printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ?
"fail" : "pass");
}
out:
crypto_free_tfm(tfm);
}
void
test_cast5(void)
{
unsigned int ret, i, tsize;
u8 *p, *q, *key;
struct crypto_tfm *tfm;
struct cast5_tv *c5_tv;
struct scatterlist sg[1];
printk("\ntesting cast5 encryption\n");
memcpy(tvmem, template, tsize);
cipher_tv = (void *) tvmem;
tfm = crypto_alloc_tfm("cast5", 0);
if (mode)
tfm = crypto_alloc_tfm (algo, 0);
else
tfm = crypto_alloc_tfm (algo, CRYPTO_TFM_MODE_CBC);
if (tfm == NULL) {
printk("failed to load transform for cast5 (default ecb)\n");
return;
}
tsize = sizeof (cast5_enc_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
printk("failed to load transform for %s %s\n", algo, m);
return;
}
memcpy(tvmem, cast5_enc_tv_template, tsize);
c5_tv = (void *) tvmem;
for (i = 0; i < CAST5_ENC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n", i + 1, c5_tv[i].keylen * 8);
key = c5_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, c5_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!c5_tv[i].fail)
j = 0;
for (i = 0; i < tcount; i++) {
if (!(cipher_tv[i].np)) {
j++;
printk("test %u (%d bit key):\n",
j, cipher_tv[i].klen * 8);
tfm->crt_flags = 0;
if (cipher_tv[i].wk)
tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
key = cipher_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!cipher_tv[i].fail)
goto out;
}
p = cipher_tv[i].input;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = cipher_tv[i].ilen;
if (!mode) {
crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
crypto_tfm_alg_ivsize (tfm));
}
if (enc)
ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
else
ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
if (ret) {
printk("%s () failed flags=%x\n", e, tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, cipher_tv[i].rlen);
printk("%s\n",
memcmp(q, cipher_tv[i].result, cipher_tv[i].rlen) ? "fail" :
"pass");
}
p = c5_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = sizeof(c5_tv[i].plaintext);
ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("encrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, sizeof(c5_tv[i].ciphertext));
printk("%s\n", memcmp(q, c5_tv[i].ciphertext,
sizeof(c5_tv[i].ciphertext)) ? "fail" : "pass");
}
tsize = sizeof (cast5_dec_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, cast5_dec_tv_template, tsize);
c5_tv = (void *) tvmem;
for (i = 0; i < CAST5_DEC_TEST_VECTORS; i++) {
printk("test %u (%d bit key):\n", i + 1, c5_tv[i].keylen * 8);
key = c5_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, c5_tv[i].keylen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!c5_tv[i].fail)
printk("\ntesting %s %s %s across pages (chunking) \n", algo, m, e);
memset(xbuf, 0, XBUFSIZE);
j = 0;
for (i = 0; i < tcount; i++) {
if (cipher_tv[i].np) {
j++;
printk("test %u (%d bit key):\n",
j, cipher_tv[i].klen * 8);
tfm->crt_flags = 0;
if (cipher_tv[i].wk)
tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
key = cipher_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!cipher_tv[i].fail)
goto out;
}
temp = 0;
for (k = 0; k < cipher_tv[i].np; k++) {
memcpy (&xbuf[IDX[k]], cipher_tv[i].input + temp,
cipher_tv[i].tap[k]);
temp += cipher_tv[i].tap[k];
p = &xbuf[IDX[k]];
sg[k].page = virt_to_page (p);
sg[k].offset = offset_in_page (p);
sg[k].length = cipher_tv[i].tap[k];
}
if (!mode) {
crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
crypto_tfm_alg_ivsize (tfm));
}
if (enc)
ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
else
ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
if (ret) {
printk("%s () failed flags=%x\n", e, tfm->crt_flags);
goto out;
}
}
p = c5_tv[i].plaintext;
sg[0].page = virt_to_page(p);
sg[0].offset = ((long) p & ~PAGE_MASK);
sg[0].length = sizeof(c5_tv[i].plaintext);
ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
if (ret) {
printk("decrypt() failed flags=%x\n", tfm->crt_flags);
goto out;
temp = 0;
for (k = 0; k < cipher_tv[i].np; k++) {
printk("page %u\n", k);
q = kmap(sg[k].page) + sg[k].offset;
hexdump(q, cipher_tv[i].tap[k]);
printk("%s\n",
memcmp(q, cipher_tv[i].result + temp,
cipher_tv[i].tap[k]) ? "fail" :
"pass");
temp += cipher_tv[i].tap[k];
}
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, sizeof(c5_tv[i].ciphertext));
printk("%s\n", memcmp(q, c5_tv[i].ciphertext,
sizeof(c5_tv[i].ciphertext)) ? "fail" : "pass");
}
out:
crypto_free_tfm (tfm);
crypto_free_tfm(tfm);
}
static void
......@@ -2485,75 +510,118 @@ do_test(void)
switch (mode) {
case 0:
test_md5();
test_sha1();
test_des();
test_des3_ede();
test_md4();
test_sha256();
test_blowfish();
test_twofish();
test_serpent();
test_cast6();
test_aes();
test_sha384();
test_sha512();
test_deflate();
test_cast5();
test_cast6();
test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
//DES
test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS);
test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
//DES3_EDE
test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
//BLOWFISH
test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS);
test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS);
//TWOFISH
test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS);
test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS);
test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
//SERPENT
test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS);
test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS);
//AES
test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
//CAST5
test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS);
//CAST6
test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS);
test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS);
test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
test_deflate();
#ifdef CONFIG_CRYPTO_HMAC
test_hmac_md5();
test_hmac_sha1();
test_hmac_sha256();
test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
#endif
break;
case 1:
test_md5();
test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
break;
case 2:
test_sha1();
test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
break;
case 3:
test_des();
test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS);
test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
break;
case 4:
test_des3_ede();
test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
break;
case 5:
test_md4();
test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
break;
case 6:
test_sha256();
test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
break;
case 7:
test_blowfish();
test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS);
test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS);
break;
case 8:
test_twofish();
test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS);
test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS);
test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
break;
case 9:
test_serpent();
break;
case 10:
test_aes();
test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
break;
case 11:
test_sha384();
test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
break;
case 12:
test_sha512();
test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
break;
case 13:
......@@ -2561,24 +629,26 @@ do_test(void)
break;
case 14:
test_cast5();
test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS);
break;
case 15:
test_cast6();
test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS);
test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS);
break;
#ifdef CONFIG_CRYPTO_HMAC
case 100:
test_hmac_md5();
test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
break;
case 101:
test_hmac_sha1();
test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
break;
case 102:
test_hmac_sha256();
test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
break;
#endif
......@@ -2614,7 +684,14 @@ init(void)
return 0;
}
/*
* If an init function is provided, an exit function must also be provided
* to allow module unload.
*/
static void __exit fini(void) { }
module_init(init);
module_exit(fini);
MODULE_PARM(mode, "i");
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1151,3 +1151,4 @@ module_exit(pppoe_exit);
MODULE_AUTHOR("Michal Ostrowski <mostrows@speakeasy.net>");
MODULE_DESCRIPTION("PPP over Ethernet driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_NETPROTO(PF_PPPOX);
......@@ -579,6 +579,14 @@ enum {
NET_SCTP_MAX_BURST = 12,
};
/* /proc/sys/net/bridge */
enum {
NET_BRIDGE_NF_CALL_ARPTABLES = 1,
NET_BRIDGE_NF_CALL_IPTABLES = 2,
NET_BRIDGE_NF_CALL_IP6TABLES = 3,
NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4,
};
/* CTL_PROC names: */
/* CTL_FS names: */
......
......@@ -227,8 +227,7 @@ extern void ax25_cb_add(ax25_cb *);
struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int);
struct sock *ax25_get_socket(ax25_address *, ax25_address *, int);
extern ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
extern struct sock *ax25_addr_match(ax25_address *);
extern void ax25_send_to_raw(struct sock *, struct sk_buff *, int);
extern void ax25_send_to_raw(ax25_address *, struct sk_buff *, int);
extern void ax25_destroy_socket(ax25_cb *);
extern ax25_cb *ax25_create_cb(void);
extern void ax25_fillin_cb(ax25_cb *, ax25_dev *);
......
......@@ -81,7 +81,12 @@ static inline int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, struct
return -1;
}
static inline void tcf_destroy(struct tcf_proto *tp)
{
tp->ops->destroy(tp);
module_put(tp->ops->owner);
kfree(tp);
}
extern int register_tcf_proto_ops(struct tcf_proto_ops *ops);
extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
......
......@@ -228,45 +228,25 @@ ax25_cb *ax25_find_cb(ax25_address *src_addr, ax25_address *dest_addr,
return NULL;
}
/*
* Look for any matching address - RAW sockets can bind to arbitrary names
*/
struct sock *ax25_addr_match(ax25_address *addr)
void ax25_send_to_raw(ax25_address *addr, struct sk_buff *skb, int proto)
{
struct sock *sk = NULL;
ax25_cb *s;
struct sk_buff *copy;
struct hlist_node *node;
spin_lock_bh(&ax25_list_lock);
ax25_for_each(s, node, &ax25_list) {
if (s->sk != NULL && ax25cmp(&s->source_addr, addr) == 0 &&
s->sk->sk_type == SOCK_RAW) {
sk = s->sk;
lock_sock(sk);
break;
}
}
spin_unlock_bh(&ax25_list_lock);
return sk;
}
void ax25_send_to_raw(struct sock *sk, struct sk_buff *skb, int proto)
{
struct sk_buff *copy;
struct hlist_node *node;
sk_for_each_from(sk, node)
if (sk->sk_type == SOCK_RAW &&
sk->sk_protocol == proto &&
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) {
s->sk->sk_type == SOCK_RAW &&
s->sk->sk_protocol == proto &&
s->ax25_dev->dev == skb->dev &&
atomic_read(&s->sk->sk_rmem_alloc) <= s->sk->sk_rcvbuf) {
if ((copy = skb_clone(skb, GFP_ATOMIC)) == NULL)
return;
if (sock_queue_rcv_skb(sk, copy) != 0)
continue;
if (sock_queue_rcv_skb(s->sk, copy) != 0)
kfree_skb(copy);
}
}
}
/*
......@@ -318,7 +298,7 @@ void ax25_destroy_socket(ax25_cb *ax25)
ax25_cb *sax25 = ax25_sk(skb->sk);
/* Queue the unaccepted socket for death */
sock_set_flag(skb->sk, SOCK_DEAD);
sock_orphan(skb->sk);
ax25_start_heartbeat(sax25);
sax25->state = AX25_STATE_0;
......@@ -913,6 +893,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
if (oax25->digipeat != NULL) {
if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
sk_free(sk);
ax25_cb_put(ax25);
return NULL;
}
......@@ -934,20 +915,25 @@ static int ax25_release(struct socket *sock)
return 0;
sock_hold(sk);
sock_orphan(sk);
lock_sock(sk);
ax25 = ax25_sk(sk);
if (sk->sk_type == SOCK_SEQPACKET) {
switch (ax25->state) {
case AX25_STATE_0:
release_sock(sk);
ax25_disconnect(ax25, 0);
lock_sock(sk);
ax25_destroy_socket(ax25);
break;
case AX25_STATE_1:
case AX25_STATE_2:
ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
release_sock(sk);
ax25_disconnect(ax25, 0);
lock_sock(sk);
ax25_destroy_socket(ax25);
break;
......@@ -980,7 +966,6 @@ static int ax25_release(struct socket *sock)
sk->sk_state = TCP_CLOSE;
sk->sk_shutdown |= SEND_SHUTDOWN;
sk->sk_state_change(sk);
sock_set_flag(sk, SOCK_DEAD);
sock_set_flag(sk, SOCK_DESTROY);
break;
......@@ -991,12 +976,10 @@ static int ax25_release(struct socket *sock)
sk->sk_state = TCP_CLOSE;
sk->sk_shutdown |= SEND_SHUTDOWN;
sk->sk_state_change(sk);
sock_set_flag(sk, SOCK_DEAD);
ax25_destroy_socket(ax25);
}
sock->sk = NULL;
sk->sk_socket = NULL; /* Not used, but we should do this */
release_sock(sk);
sock_put(sk);
......@@ -1334,11 +1317,13 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags)
release_sock(sk);
current->state = TASK_INTERRUPTIBLE;
if (flags & O_NONBLOCK)
if (flags & O_NONBLOCK) {
current->state = TASK_RUNNING;
remove_wait_queue(sk->sk_sleep, &wait);
return -EWOULDBLOCK;
}
if (!signal_pending(tsk)) {
schedule();
current->state = TASK_RUNNING;
lock_sock(sk);
continue;
}
......
......@@ -147,7 +147,6 @@ int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
}
if (ax25->sk != NULL && ax25->ax25_dev->values[AX25_VALUES_CONMODE] == 2) {
bh_lock_sock(ax25->sk);
if ((!ax25->pidincl && ax25->sk->sk_protocol == pid) ||
ax25->pidincl) {
if (sock_queue_rcv_skb(ax25->sk, skb) == 0)
......@@ -155,7 +154,6 @@ int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
else
ax25->condition |= AX25_COND_OWN_RX_BUSY;
}
bh_unlock_sock(ax25->sk);
}
return queued;
......@@ -195,7 +193,7 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
{
ax25_address src, dest, *next_digi = NULL;
int type = 0, mine = 0, dama;
struct sock *make, *sk, *raw;
struct sock *make, *sk;
ax25_digi dp, reverse_dp;
ax25_cb *ax25;
ax25_dev *ax25_dev;
......@@ -243,10 +241,7 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
if ((*skb->data & ~0x10) == AX25_UI && dp.lastrepeat + 1 == dp.ndigi) {
skb->h.raw = skb->data + 2; /* skip control and pid */
if ((raw = ax25_addr_match(&dest)) != NULL) {
ax25_send_to_raw(raw, skb, skb->data[1]);
release_sock(raw);
}
ax25_send_to_raw(&dest, skb, skb->data[1]);
if (!mine && ax25cmp(&dest, (ax25_address *)dev->broadcast) != 0) {
kfree_skb(skb);
......@@ -381,7 +376,6 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
sk->sk_ack_backlog++;
bh_unlock_sock(sk);
sock_put(sk);
} else {
if (!mine) {
kfree_skb(skb);
......@@ -407,6 +401,8 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
(ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
kfree_skb(skb);
ax25_destroy_socket(ax25);
if (sk)
sock_put(sk);
return 0;
}
......@@ -446,6 +442,7 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
if (sk) {
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_data_ready(sk, skb->len);
sock_put(sk);
} else
kfree_skb(skb);
......
......@@ -360,3 +360,4 @@ module_exit(bt_cleanup);
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
MODULE_LICENSE("GPL");
MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);
......@@ -707,4 +707,3 @@ module_exit(bnep_cleanup_module);
MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);
......@@ -35,6 +35,9 @@
#include <asm/uaccess.h>
#include <asm/checksum.h>
#include "br_private.h"
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
#define skb_origaddr(skb) (((struct bridge_skb_cb *) \
......@@ -47,10 +50,21 @@
#define has_bridge_parent(device) ((device)->br_port != NULL)
#define bridge_parent(device) ((device)->br_port->br->dev)
#define IS_VLAN_IP (skb->protocol == __constant_htons(ETH_P_8021Q) && \
hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP))
#define IS_VLAN_ARP (skb->protocol == __constant_htons(ETH_P_8021Q) && \
hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_ARP))
#ifdef CONFIG_SYSCTL
static struct ctl_table_header *brnf_sysctl_header;
static int brnf_call_iptables = 1;
static int brnf_call_arptables = 1;
static int brnf_filter_vlan_tagged = 1;
#else
#define brnf_filter_vlan_tagged 1
#endif
#define IS_VLAN_IP (skb->protocol == __constant_htons(ETH_P_8021Q) && \
hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP) && \
brnf_filter_vlan_tagged)
#define IS_VLAN_ARP (skb->protocol == __constant_htons(ETH_P_8021Q) && \
hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_ARP) && \
brnf_filter_vlan_tagged)
/* We need these fake structures to make netfilter happy --
* lots of places assume that skb->dst != NULL, which isn't
......@@ -74,8 +88,7 @@ static struct rtable __fake_rtable = {
.metrics = {[RTAX_MTU - 1] = 1500},
}
},
.rt_flags = 0
.rt_flags = 0,
};
......@@ -251,6 +264,11 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
struct sk_buff *skb = *pskb;
struct nf_bridge_info *nf_bridge;
#ifdef CONFIG_SYSCTL
if (!brnf_call_iptables)
return NF_ACCEPT;
#endif
if (skb->protocol != __constant_htons(ETH_P_IP)) {
struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)
((*pskb)->mac.ethernet);
......@@ -373,7 +391,7 @@ static int br_nf_forward_finish(struct sk_buff *skb)
* because of the ipt_physdev.c module. For ARP, indev and outdev are the
* bridge ports.
*/
static unsigned int br_nf_forward(unsigned int hook, struct sk_buff **pskb,
static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
......@@ -381,9 +399,13 @@ static unsigned int br_nf_forward(unsigned int hook, struct sk_buff **pskb,
struct nf_bridge_info *nf_bridge;
struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
if (skb->protocol != __constant_htons(ETH_P_IP) &&
skb->protocol != __constant_htons(ETH_P_ARP)) {
if (!IS_VLAN_IP && !IS_VLAN_ARP)
#ifdef CONFIG_SYSCTL
if (!skb->nf_bridge)
return NF_ACCEPT;
#endif
if (skb->protocol != __constant_htons(ETH_P_IP)) {
if (!IS_VLAN_IP)
return NF_ACCEPT;
skb_pull(*pskb, VLAN_HLEN);
(*pskb)->nh.raw += VLAN_HLEN;
......@@ -392,39 +414,58 @@ static unsigned int br_nf_forward(unsigned int hook, struct sk_buff **pskb,
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug ^= (1 << NF_BR_FORWARD);
#endif
if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP) {
nf_bridge = skb->nf_bridge;
if (skb->pkt_type == PACKET_OTHERHOST) {
skb->pkt_type = PACKET_HOST;
nf_bridge->mask |= BRNF_PKT_TYPE;
}
nf_bridge = skb->nf_bridge;
if (skb->pkt_type == PACKET_OTHERHOST) {
skb->pkt_type = PACKET_HOST;
nf_bridge->mask |= BRNF_PKT_TYPE;
}
/* The physdev module checks on this */
nf_bridge->mask |= BRNF_BRIDGED;
nf_bridge->physoutdev = skb->dev;
/* The physdev module checks on this */
nf_bridge->mask |= BRNF_BRIDGED;
nf_bridge->physoutdev = skb->dev;
NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(in),
bridge_parent(out), br_nf_forward_finish);
} else {
struct net_device **d = (struct net_device **)(skb->cb);
struct arphdr *arp = skb->nh.arph;
NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(in),
bridge_parent(out), br_nf_forward_finish);
if (arp->ar_pln != 4) {
if (IS_VLAN_ARP) {
skb_push(*pskb, VLAN_HLEN);
(*pskb)->nh.raw -= VLAN_HLEN;
}
return NF_STOLEN;
}
static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff *skb = *pskb;
struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
struct net_device **d = (struct net_device **)(skb->cb);
if (!brnf_call_arptables)
return NF_ACCEPT;
if (skb->protocol != __constant_htons(ETH_P_ARP)) {
if (!IS_VLAN_ARP)
return NF_ACCEPT;
skb_pull(*pskb, VLAN_HLEN);
(*pskb)->nh.raw += VLAN_HLEN;
}
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug ^= (1 << NF_BR_FORWARD);
#endif
if (skb->nh.arph->ar_pln != 4) {
if (IS_VLAN_ARP) {
skb_push(*pskb, VLAN_HLEN);
(*pskb)->nh.raw -= VLAN_HLEN;
}
*d = (struct net_device *)in;
NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
(struct net_device *)out, br_nf_forward_finish);
return NF_ACCEPT;
}
*d = (struct net_device *)in;
NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
(struct net_device *)out, br_nf_forward_finish);
return NF_STOLEN;
}
/* PF_BRIDGE/LOCAL_OUT ***********************************************/
static int br_nf_local_out_finish(struct sk_buff *skb)
{
......@@ -475,6 +516,11 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
struct nf_bridge_info *nf_bridge;
struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
#ifdef CONFIG_SYSCTL
if (!skb->nf_bridge)
return NF_ACCEPT;
#endif
if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP)
return NF_ACCEPT;
......@@ -485,6 +531,7 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
return NF_ACCEPT;
nf_bridge = skb->nf_bridge;
nf_bridge->physoutdev = skb->dev;
realindev = nf_bridge->physindev;
......@@ -567,6 +614,11 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
return NF_ACCEPT;
}
#ifdef CONFIG_SYSCTL
if (!nf_bridge)
return NF_ACCEPT;
#endif
if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP)
return NF_ACCEPT;
......@@ -632,6 +684,13 @@ static unsigned int ipv4_sabotage_out(unsigned int hook, struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff *skb = *pskb;
#ifdef CONFIG_SYSCTL
if (!brnf_call_iptables && !skb->nf_bridge)
return NF_ACCEPT;
#endif
if ((out->hard_start_xmit == br_dev_xmit &&
okfn != br_nf_forward_finish &&
okfn != br_nf_local_out_finish &&
......@@ -641,7 +700,6 @@ static unsigned int ipv4_sabotage_out(unsigned int hook, struct sk_buff **pskb,
VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
#endif
) {
struct sk_buff *skb = *pskb;
struct nf_bridge_info *nf_bridge;
if (!skb->nf_bridge && !nf_bridge_alloc(skb))
......@@ -687,7 +745,12 @@ static struct nf_hook_ops br_nf_ops[] = {
.pf = PF_BRIDGE,
.hooknum = NF_BR_LOCAL_IN,
.priority = NF_BR_PRI_BRNF, },
{ .hook = br_nf_forward,
{ .hook = br_nf_forward_ip,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_FORWARD,
.priority = NF_BR_PRI_BRNF - 1, },
{ .hook = br_nf_forward_arp,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_FORWARD,
......@@ -724,6 +787,69 @@ static struct nf_hook_ops br_nf_ops[] = {
.priority = NF_IP_PRI_FIRST, },
};
#ifdef CONFIG_SYSCTL
static
int brnf_sysctl_call_tables(ctl_table *ctl, int write, struct file * filp,
void *buffer, size_t *lenp)
{
int ret;
ret = proc_dointvec(ctl, write, filp, buffer, lenp);
if (write && *(int *)(ctl->data))
*(int *)(ctl->data) = 1;
return ret;
}
static ctl_table brnf_table[] = {
{
.ctl_name = NET_BRIDGE_NF_CALL_ARPTABLES,
.procname = "bridge-nf-call-arptables",
.data = &brnf_call_arptables,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &brnf_sysctl_call_tables,
},
{
.ctl_name = NET_BRIDGE_NF_CALL_IPTABLES,
.procname = "bridge-nf-call-iptables",
.data = &brnf_call_iptables,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &brnf_sysctl_call_tables,
},
{
.ctl_name = NET_BRIDGE_NF_FILTER_VLAN_TAGGED,
.procname = "bridge-nf-filter-vlan-tagged",
.data = &brnf_filter_vlan_tagged,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &brnf_sysctl_call_tables,
},
{ .ctl_name = 0 }
};
static ctl_table brnf_bridge_table[] = {
{
.ctl_name = NET_BRIDGE,
.procname = "bridge",
.mode = 0555,
.child = brnf_table,
},
{ .ctl_name = 0 }
};
static ctl_table brnf_net_table[] = {
{
.ctl_name = CTL_NET,
.procname = "net",
.mode = 0555,
.child = brnf_bridge_table,
},
{ .ctl_name = 0 }
};
#endif
int br_netfilter_init(void)
{
int i;
......@@ -740,6 +866,16 @@ int br_netfilter_init(void)
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;
}
#endif
printk(KERN_NOTICE "Bridge firewalling registered\n");
return 0;
......@@ -751,4 +887,7 @@ void br_netfilter_fini(void)
for (i = ARRAY_SIZE(br_nf_ops) - 1; i >= 0; i--)
nf_unregister_hook(&br_nf_ops[i]);
#ifdef CONFIG_SYSCTL
unregister_sysctl_table(brnf_sysctl_header);
#endif
}
......@@ -98,7 +98,7 @@ static int neigh_blackhole(struct sk_buff *skb)
/*
* It is random distribution in the interval (1/2)*base...(3/2)*base.
* It corresponds to default IPv6 settings and is not overridable,
* because it is really reasonbale choice.
* because it is really reasonable choice.
*/
unsigned long neigh_rand_reach_time(unsigned long base)
......@@ -120,7 +120,7 @@ static int neigh_forced_gc(struct neigh_table *tbl)
while ((n = *np) != NULL) {
/* Neighbour record may be discarded if:
- nobody refers to it.
- it is not premanent
- it is not permanent
- (NEW and probably wrong)
INCOMPLETE entries are kept at least for
n->parms->retrans_time, otherwise we could
......@@ -510,7 +510,7 @@ static void neigh_suspect(struct neighbour *neigh)
{
struct hh_cache *hh;
NEIGH_PRINTK2("neigh %p is suspecteded.\n", neigh);
NEIGH_PRINTK2("neigh %p is suspected.\n", neigh);
neigh->output = neigh->ops->output;
......@@ -537,7 +537,7 @@ static void neigh_connect(struct neighbour *neigh)
/*
Transitions NUD_STALE <-> NUD_REACHABLE do not occur
when fast path is built: we have no timers assotiated with
when fast path is built: we have no timers associated with
these states, we do not have time to check state when sending.
neigh_periodic_timer check periodically neigh->confirmed
time and moves NUD_REACHABLE -> NUD_STALE.
......@@ -962,7 +962,7 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst,
/* This function can be used in contexts, where only old dev_queue_xmit
worked, f.e. if you want to override normal output path (eql, shaper),
but resoltution is not made yet.
but resolution is not made yet.
*/
int neigh_compat_output(struct sk_buff *skb)
......
......@@ -207,9 +207,8 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
case ND_OPT_MTU:
case ND_OPT_REDIRECT_HDR:
if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
ND_PRINTK2((KERN_WARNING
"ndisc_parse_options(): duplicated ND6 option found: type=%d\n",
nd_opt->nd_opt_type));
ND_PRINTK2("ndisc_parse_options(): duplicated ND6 option found: type=%d\n",
nd_opt->nd_opt_type);
} else {
ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
}
......@@ -619,6 +618,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
1, &err);
if (skb == NULL) {
ND_PRINTK1("send_ns: alloc skb failed\n");
dst_release(dst);
return;
}
......@@ -1166,9 +1166,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
ND_PRINTK0("NDISC: router announcement with mtu = %d\n",
mtu);
}
}
if (in6_dev->cnf.mtu6 != mtu) {
} else if (in6_dev->cnf.mtu6 != mtu) {
in6_dev->cnf.mtu6 = mtu;
if (rt)
......
......@@ -532,7 +532,7 @@ static int nr_release(struct socket *sock)
sk->sk_state = TCP_CLOSE;
sk->sk_shutdown |= SEND_SHUTDOWN;
sk->sk_state_change(sk);
sock_set_flag(sk, SOCK_DEAD);
sock_orphan(sk);
sock_set_flag(sk, SOCK_DESTROY);
sk->sk_socket = NULL;
break;
......@@ -727,6 +727,8 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
lock_sock(sk);
continue;
}
current->state = TASK_RUNNING;
remove_wait_queue(sk->sk_sleep, &wait);
return -ERESTARTSYS;
}
current->state = TASK_RUNNING;
......@@ -780,13 +782,18 @@ static int nr_accept(struct socket *sock, struct socket *newsock, int flags)
current->state = TASK_INTERRUPTIBLE;
release_sock(sk);
if (flags & O_NONBLOCK)
if (flags & O_NONBLOCK) {
current->state = TASK_RUNNING;
remove_wait_queue(sk->sk_sleep, &wait);
return -EWOULDBLOCK;
}
if (!signal_pending(tsk)) {
schedule();
lock_sock(sk);
continue;
}
current->state = TASK_RUNNING;
remove_wait_queue(sk->sk_sleep, &wait);
return -ERESTARTSYS;
}
current->state = TASK_RUNNING;
......@@ -1377,7 +1384,7 @@ static int __init nr_proto_init(void)
{
int i;
if (nr_ndevs > 0x7fffffff/sizeof(struct net_device)) {
if (nr_ndevs > 0x7fffffff/sizeof(struct net_device *)) {
printk(KERN_ERR "NET/ROM: nr_proto_init - nr_ndevs parameter to large\n");
return -1;
}
......@@ -1405,6 +1412,7 @@ static int __init nr_proto_init(void)
dev->base_addr = i;
if (register_netdev(dev)) {
printk(KERN_ERR "NET/ROM: nr_proto_init - unable to register network device\n");
free_netdev(dev);
goto fail;
}
dev_nr[i] = dev;
......@@ -1433,8 +1441,10 @@ static int __init nr_proto_init(void)
return 0;
fail:
while (--i >= 0)
while (--i >= 0) {
unregister_netdev(dev_nr[i]);
free_netdev(dev_nr[i]);
}
kfree(dev_nr);
return -1;
}
......@@ -1474,8 +1484,10 @@ static void __exit nr_exit(void)
for (i = 0; i < nr_ndevs; i++) {
struct net_device *dev = dev_nr[i];
if (dev)
if (dev) {
unregister_netdev(dev);
free_netdev(dev);
}
}
kfree(dev_nr);
......
......@@ -204,7 +204,6 @@ void nr_setup(struct net_device *dev)
dev->hard_start_xmit = nr_xmit;
dev->open = nr_open;
dev->stop = nr_close;
dev->destructor = free_netdev;
dev->hard_header = nr_header;
dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
......
......@@ -246,6 +246,10 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
goto oom;
/* drop any routing info */
dst_release(skb->dst);
skb->dst = NULL;
spkt = (struct sockaddr_pkt*)skb->cb;
skb_push(skb, skb->data-skb->mac.raw);
......@@ -486,6 +490,9 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
skb_set_owner_r(skb, sk);
skb->dev = NULL;
dst_release(skb->dst);
skb->dst = NULL;
spin_lock(&sk->sk_receive_queue.lock);
po->stats.tp_packets++;
__skb_queue_tail(&sk->sk_receive_queue, skb);
......
......@@ -359,7 +359,7 @@ void rose_destroy_socket(struct sock *sk)
sk->sk_timer.data = (unsigned long)sk;
add_timer(&sk->sk_timer);
} else
sk_free(sk);
sock_put(sk);
}
/*
......@@ -634,7 +634,6 @@ static int rose_release(struct socket *sock)
}
sock->sk = NULL;
sk->sk_socket = NULL; /* Not used, but we should do this. **/
return 0;
}
......@@ -813,6 +812,8 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
schedule();
continue;
}
current->state = TASK_RUNNING;
remove_wait_queue(sk->sk_sleep, &wait);
return -ERESTARTSYS;
}
current->state = TASK_RUNNING;
......@@ -864,8 +865,11 @@ static int rose_accept(struct socket *sock, struct socket *newsock, int flags)
current->state = TASK_INTERRUPTIBLE;
release_sock(sk);
if (flags & O_NONBLOCK)
if (flags & O_NONBLOCK) {
current->state = TASK_RUNNING;
remove_wait_queue(sk->sk_sleep, &wait);
return -EWOULDBLOCK;
}
if (!signal_pending(tsk)) {
schedule();
lock_sock(sk);
......@@ -1482,7 +1486,7 @@ static int __init rose_proto_init(void)
rose_callsign = null_ax25_address;
if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device)) {
if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device *)) {
printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter to large\n");
return -1;
}
......@@ -1503,23 +1507,14 @@ static int __init rose_proto_init(void)
name, rose_setup);
if (!dev) {
printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate memory\n");
while (--i >= 0)
kfree(dev_rose[i]);
return -ENOMEM;
goto fail;
}
dev_rose[i] = dev;
}
for (i = 0; i < rose_ndevs; i++) {
if (register_netdev(dev_rose[i])) {
if (register_netdev(dev)) {
printk(KERN_ERR "ROSE: netdevice regeistration failed\n");
while (--i >= 0) {
unregister_netdev(dev_rose[i]);
kfree(dev_rose[i]);
return -EIO;
}
free_netdev(dev);
goto fail;
}
dev_rose[i] = dev;
}
sock_register(&rose_family_ops);
......@@ -1542,6 +1537,13 @@ static int __init rose_proto_init(void)
proc_net_fops_create("rose_routes", S_IRUGO, &rose_routes_fops);
return 0;
fail:
while (--i >= 0) {
unregister_netdev(dev_rose[i]);
free_netdev(dev_rose[i]);
}
kfree(dev_rose);
return -ENOMEM;
}
module_init(rose_proto_init);
......
......@@ -247,10 +247,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
*back = tp->next;
spin_unlock_bh(&dev->queue_lock);
write_unlock(&qdisc_tree_lock);
tp->ops->destroy(tp);
module_put(tp->ops->owner);
kfree(tp);
tcf_destroy(tp);
err = 0;
goto errout;
}
......
......@@ -162,7 +162,7 @@ static void destroy_filters(struct atm_flow_data *flow)
while ((filter = flow->filter_list)) {
DPRINTK("destroy_filters: destroying filter %p\n",filter);
flow->filter_list = filter->next;
filter->ops->destroy(filter);
tcf_destroy(filter);
}
}
......
......@@ -1705,7 +1705,7 @@ static void cbq_destroy_filters(struct cbq_class *cl)
while ((tp = cl->filter_list) != NULL) {
cl->filter_list = tp->next;
tp->ops->destroy(tp);
tcf_destroy(tp);
}
}
......
......@@ -752,7 +752,7 @@ csz_destroy(struct Qdisc* sch)
while ((tp = q->filter_list) != NULL) {
q->filter_list = tp->next;
tp->ops->destroy(tp);
tcf_destroy(tp);
}
}
......
......@@ -378,7 +378,7 @@ static void dsmark_destroy(struct Qdisc *sch)
while (p->filter_list) {
tp = p->filter_list;
p->filter_list = tp->next;
tp->ops->destroy(tp);
tcf_destroy(tp);
}
qdisc_destroy(p->q);
p->q = &noop_qdisc;
......
......@@ -1338,7 +1338,7 @@ static void htb_destroy_filters(struct tcf_proto **fl)
while ((tp = *fl) != NULL) {
*fl = tp->next;
tp->ops->destroy(tp);
tcf_destroy(tp);
}
}
......
......@@ -292,7 +292,7 @@ static void ingress_destroy(struct Qdisc *sch)
while (p->filter_list) {
tp = p->filter_list;
p->filter_list = tp->next;
tp->ops->destroy(tp);
tcf_destroy(tp);
}
memset(p, 0, sizeof(*p));
p->filter_list = NULL;
......
......@@ -162,7 +162,7 @@ prio_destroy(struct Qdisc* sch)
while ((tp = q->filter_list) != NULL) {
q->filter_list = tp->next;
tp->ops->destroy(tp);
tcf_destroy(tp);
}
for (prio=0; prio<q->bands; prio++) {
......
......@@ -108,6 +108,10 @@
Note that the peak rate TBF is much more tough: with MTU 1500
P_crit = 150Kbytes/sec. So, if you need greater peak
rates, use alpha with HZ=1000 :-)
With classful TBF, limit is just kept for backwards compatibility.
It is passed to the default bfifo qdisc - if the inner qdisc is
changed the limit is not effective anymore.
*/
struct tbf_sched_data
......@@ -136,7 +140,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data;
int ret;
if (skb->len > q->max_size || sch->stats.backlog + skb->len > q->limit) {
if (skb->len > q->max_size) {
sch->stats.drops++;
#ifdef CONFIG_NET_CLS_POLICE
if (sch->reshape_fail == NULL || sch->reshape_fail(skb, sch))
......@@ -152,7 +156,6 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
}
sch->q.qlen++;
sch->stats.backlog += skb->len;
sch->stats.bytes += skb->len;
sch->stats.packets++;
return 0;
......@@ -163,10 +166,8 @@ static int tbf_requeue(struct sk_buff *skb, struct Qdisc* sch)
struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data;
int ret;
if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) {
if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0)
sch->q.qlen++;
sch->stats.backlog += skb->len;
}
return ret;
}
......@@ -178,7 +179,6 @@ static unsigned int tbf_drop(struct Qdisc* sch)
if ((len = q->qdisc->ops->drop(q->qdisc)) != 0) {
sch->q.qlen--;
sch->stats.backlog -= len;
sch->stats.drops++;
}
return len;
......@@ -224,7 +224,6 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
q->t_c = now;
q->tokens = toks;
q->ptokens = ptoks;
sch->stats.backlog -= len;
sch->q.qlen--;
sch->flags &= ~TCQ_F_THROTTLED;
return skb;
......@@ -253,7 +252,6 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
/* When requeue fails skb is dropped */
sch->q.qlen--;
sch->stats.backlog -= len;
sch->stats.drops++;
}
......@@ -269,7 +267,6 @@ static void tbf_reset(struct Qdisc* sch)
qdisc_reset(q->qdisc);
sch->q.qlen = 0;
sch->stats.backlog = 0;
PSCHED_GET_TIME(q->t_c);
q->tokens = q->buffer;
q->ptokens = q->mtu;
......@@ -456,7 +453,6 @@ static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
*old = xchg(&q->qdisc, new);
qdisc_reset(*old);
sch->q.qlen = 0;
sch->stats.backlog = 0;
sch_tree_unlock(sch);
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment