Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
This commit is contained in:
424
crypto/tcrypt.c
424
crypto/tcrypt.c
@@ -12,8 +12,9 @@
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* 14 - 09 - 2003
|
||||
* Rewritten by Kartikey Mahendra Bhatt
|
||||
* 2004-08-09 Added cipher speed tests (Reyk Floeter <reyk@vantronix.net>)
|
||||
* 2003-09-14 Rewritten by Kartikey Mahendra Bhatt
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
@@ -25,12 +26,15 @@
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include "tcrypt.h"
|
||||
|
||||
/*
|
||||
* Need to kmalloc() memory for testing kmap().
|
||||
*/
|
||||
#define TVMEMSIZE 4096
|
||||
#define TVMEMSIZE 16384
|
||||
#define XBUFSIZE 32768
|
||||
|
||||
/*
|
||||
@@ -55,6 +59,11 @@
|
||||
|
||||
static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
|
||||
|
||||
/*
|
||||
* Used by test_cipher_speed()
|
||||
*/
|
||||
static unsigned int sec;
|
||||
|
||||
static int mode;
|
||||
static char *xbuf;
|
||||
static char *tvmem;
|
||||
@@ -66,8 +75,7 @@ static char *check[] = {
|
||||
"khazad", "wp512", "wp384", "wp256", "tnepres", NULL
|
||||
};
|
||||
|
||||
static void
|
||||
hexdump(unsigned char *buf, unsigned int len)
|
||||
static void hexdump(unsigned char *buf, unsigned int len)
|
||||
{
|
||||
while (len--)
|
||||
printk("%02x", *buf++);
|
||||
@@ -75,20 +83,20 @@ hexdump(unsigned char *buf, unsigned int len)
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_hash (char * algo, struct hash_testvec * template, unsigned int tcount)
|
||||
static void test_hash(char *algo, struct hash_testvec *template,
|
||||
unsigned int tcount)
|
||||
{
|
||||
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;
|
||||
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);
|
||||
printk("\ntesting %s\n", algo);
|
||||
|
||||
tsize = sizeof (struct hash_testvec);
|
||||
tsize = sizeof(struct hash_testvec);
|
||||
tsize *= tcount;
|
||||
|
||||
if (tsize > TVMEMSIZE) {
|
||||
@@ -97,7 +105,7 @@ test_hash (char * algo, struct hash_testvec * template, unsigned int tcount)
|
||||
}
|
||||
|
||||
memcpy(tvmem, template, tsize);
|
||||
hash_tv = (void *) tvmem;
|
||||
hash_tv = (void *)tvmem;
|
||||
tfm = crypto_alloc_tfm(algo, 0);
|
||||
if (tfm == NULL) {
|
||||
printk("failed to load transform for %s\n", algo);
|
||||
@@ -105,70 +113,71 @@ test_hash (char * algo, struct hash_testvec * template, unsigned int tcount)
|
||||
}
|
||||
|
||||
for (i = 0; i < tcount; i++) {
|
||||
printk ("test %u:\n", i + 1);
|
||||
memset (result, 0, 64);
|
||||
printk("test %u:\n", i + 1);
|
||||
memset(result, 0, 64);
|
||||
|
||||
p = hash_tv[i].plaintext;
|
||||
sg[0].page = virt_to_page (p);
|
||||
sg[0].offset = offset_in_page (p);
|
||||
sg[0].page = virt_to_page(p);
|
||||
sg[0].offset = offset_in_page(p);
|
||||
sg[0].length = hash_tv[i].psize;
|
||||
|
||||
crypto_digest_init (tfm);
|
||||
crypto_digest_init(tfm);
|
||||
if (tfm->crt_u.digest.dit_setkey) {
|
||||
crypto_digest_setkey (tfm, hash_tv[i].key,
|
||||
hash_tv[i].ksize);
|
||||
crypto_digest_setkey(tfm, hash_tv[i].key,
|
||||
hash_tv[i].ksize);
|
||||
}
|
||||
crypto_digest_update (tfm, sg, 1);
|
||||
crypto_digest_final (tfm, result);
|
||||
crypto_digest_update(tfm, sg, 1);
|
||||
crypto_digest_final(tfm, result);
|
||||
|
||||
hexdump (result, crypto_tfm_alg_digestsize (tfm));
|
||||
hexdump(result, crypto_tfm_alg_digestsize(tfm));
|
||||
printk("%s\n",
|
||||
memcmp(result, hash_tv[i].digest,
|
||||
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
|
||||
"pass");
|
||||
memcmp(result, hash_tv[i].digest,
|
||||
crypto_tfm_alg_digestsize(tfm)) ?
|
||||
"fail" : "pass");
|
||||
}
|
||||
|
||||
printk ("testing %s across pages\n", algo);
|
||||
printk("testing %s across pages\n", algo);
|
||||
|
||||
/* setup the dummy buffer first */
|
||||
memset(xbuf, 0, XBUFSIZE);
|
||||
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);
|
||||
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]);
|
||||
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].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);
|
||||
crypto_digest_digest(tfm, sg, hash_tv[i].np, result);
|
||||
|
||||
hexdump (result, crypto_tfm_alg_digestsize (tfm));
|
||||
hexdump(result, crypto_tfm_alg_digestsize(tfm));
|
||||
printk("%s\n",
|
||||
memcmp(result, hash_tv[i].digest,
|
||||
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
|
||||
"pass");
|
||||
memcmp(result, hash_tv[i].digest,
|
||||
crypto_tfm_alg_digestsize(tfm)) ?
|
||||
"fail" : "pass");
|
||||
}
|
||||
}
|
||||
|
||||
crypto_free_tfm (tfm);
|
||||
crypto_free_tfm(tfm);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_CRYPTO_HMAC
|
||||
|
||||
static void
|
||||
test_hmac(char *algo, struct hmac_testvec * template, unsigned int tcount)
|
||||
static void test_hmac(char *algo, struct hmac_testvec *template,
|
||||
unsigned int tcount)
|
||||
{
|
||||
char *p;
|
||||
unsigned int i, j, k, temp;
|
||||
@@ -186,7 +195,7 @@ test_hmac(char *algo, struct hmac_testvec * template, unsigned int tcount)
|
||||
|
||||
printk("\ntesting hmac_%s\n", algo);
|
||||
|
||||
tsize = sizeof (struct hmac_testvec);
|
||||
tsize = sizeof(struct hmac_testvec);
|
||||
tsize *= tcount;
|
||||
if (tsize > TVMEMSIZE) {
|
||||
printk("template (%u) too big for tvmem (%u)\n", tsize,
|
||||
@@ -195,7 +204,7 @@ test_hmac(char *algo, struct hmac_testvec * template, unsigned int tcount)
|
||||
}
|
||||
|
||||
memcpy(tvmem, template, tsize);
|
||||
hmac_tv = (void *) tvmem;
|
||||
hmac_tv = (void *)tvmem;
|
||||
|
||||
for (i = 0; i < tcount; i++) {
|
||||
printk("test %u:\n", i + 1);
|
||||
@@ -224,29 +233,30 @@ test_hmac(char *algo, struct hmac_testvec * template, unsigned int tcount)
|
||||
for (i = 0; i < tcount; i++) {
|
||||
if (hmac_tv[i].np) {
|
||||
j++;
|
||||
printk ("test %u:\n",j);
|
||||
memset (result, 0, 64);
|
||||
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]);
|
||||
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].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);
|
||||
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");
|
||||
memcmp(result, hmac_tv[i].digest,
|
||||
crypto_tfm_alg_digestsize(tfm)) ?
|
||||
"fail" : "pass");
|
||||
}
|
||||
}
|
||||
out:
|
||||
@@ -255,8 +265,8 @@ out:
|
||||
|
||||
#endif /* CONFIG_CRYPTO_HMAC */
|
||||
|
||||
static void
|
||||
test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, unsigned int tcount)
|
||||
static void test_cipher(char *algo, int mode, int enc,
|
||||
struct cipher_testvec *template, unsigned int tcount)
|
||||
{
|
||||
unsigned int ret, i, j, k, temp;
|
||||
unsigned int tsize;
|
||||
@@ -265,18 +275,18 @@ test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, un
|
||||
char *key;
|
||||
struct cipher_testvec *cipher_tv;
|
||||
struct scatterlist sg[8];
|
||||
char e[11], m[4];
|
||||
const char *e, *m;
|
||||
|
||||
if (enc == ENCRYPT)
|
||||
strncpy(e, "encryption", 11);
|
||||
e = "encryption";
|
||||
else
|
||||
strncpy(e, "decryption", 11);
|
||||
e = "decryption";
|
||||
if (mode == MODE_ECB)
|
||||
strncpy(m, "ECB", 4);
|
||||
m = "ECB";
|
||||
else
|
||||
strncpy(m, "CBC", 4);
|
||||
m = "CBC";
|
||||
|
||||
printk("\ntesting %s %s %s \n", algo, m, e);
|
||||
printk("\ntesting %s %s %s\n", algo, m, e);
|
||||
|
||||
tsize = sizeof (struct cipher_testvec);
|
||||
tsize *= tcount;
|
||||
@@ -288,12 +298,12 @@ test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, un
|
||||
}
|
||||
|
||||
memcpy(tvmem, template, tsize);
|
||||
cipher_tv = (void *) tvmem;
|
||||
cipher_tv = (void *)tvmem;
|
||||
|
||||
if (mode)
|
||||
tfm = crypto_alloc_tfm (algo, 0);
|
||||
tfm = crypto_alloc_tfm(algo, 0);
|
||||
else
|
||||
tfm = crypto_alloc_tfm (algo, CRYPTO_TFM_MODE_CBC);
|
||||
tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_CBC);
|
||||
|
||||
if (tfm == NULL) {
|
||||
printk("failed to load transform for %s %s\n", algo, m);
|
||||
@@ -327,7 +337,7 @@ test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, un
|
||||
|
||||
if (!mode) {
|
||||
crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
|
||||
crypto_tfm_alg_ivsize (tfm));
|
||||
crypto_tfm_alg_ivsize(tfm));
|
||||
}
|
||||
|
||||
if (enc)
|
||||
@@ -345,12 +355,12 @@ test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, un
|
||||
hexdump(q, cipher_tv[i].rlen);
|
||||
|
||||
printk("%s\n",
|
||||
memcmp(q, cipher_tv[i].result, cipher_tv[i].rlen) ? "fail" :
|
||||
"pass");
|
||||
memcmp(q, cipher_tv[i].result,
|
||||
cipher_tv[i].rlen) ? "fail" : "pass");
|
||||
}
|
||||
}
|
||||
|
||||
printk("\ntesting %s %s %s across pages (chunking) \n", algo, m, e);
|
||||
printk("\ntesting %s %s %s across pages (chunking)\n", algo, m, e);
|
||||
memset(xbuf, 0, XBUFSIZE);
|
||||
|
||||
j = 0;
|
||||
@@ -375,18 +385,19 @@ test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, un
|
||||
|
||||
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]);
|
||||
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].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));
|
||||
crypto_tfm_alg_ivsize(tfm));
|
||||
}
|
||||
|
||||
if (enc)
|
||||
@@ -417,8 +428,169 @@ out:
|
||||
crypto_free_tfm(tfm);
|
||||
}
|
||||
|
||||
static void
|
||||
test_deflate(void)
|
||||
static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
|
||||
int blen, int sec)
|
||||
{
|
||||
struct scatterlist sg[8];
|
||||
unsigned long start, end;
|
||||
int bcount;
|
||||
int ret;
|
||||
|
||||
sg[0].page = virt_to_page(p);
|
||||
sg[0].offset = offset_in_page(p);
|
||||
sg[0].length = blen;
|
||||
|
||||
for (start = jiffies, end = start + sec * HZ, bcount = 0;
|
||||
time_before(jiffies, end); bcount++) {
|
||||
if (enc)
|
||||
ret = crypto_cipher_encrypt(tfm, sg, sg, blen);
|
||||
else
|
||||
ret = crypto_cipher_decrypt(tfm, sg, sg, blen);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
printk("%d operations in %d seconds (%ld bytes)\n",
|
||||
bcount, sec, (long)bcount * blen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p,
|
||||
int blen)
|
||||
{
|
||||
struct scatterlist sg[8];
|
||||
unsigned long cycles = 0;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
sg[0].page = virt_to_page(p);
|
||||
sg[0].offset = offset_in_page(p);
|
||||
sg[0].length = blen;
|
||||
|
||||
local_bh_disable();
|
||||
local_irq_disable();
|
||||
|
||||
/* Warm-up run. */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (enc)
|
||||
ret = crypto_cipher_encrypt(tfm, sg, sg, blen);
|
||||
else
|
||||
ret = crypto_cipher_decrypt(tfm, sg, sg, blen);
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* The real thing. */
|
||||
for (i = 0; i < 8; i++) {
|
||||
cycles_t start, end;
|
||||
|
||||
start = get_cycles();
|
||||
if (enc)
|
||||
ret = crypto_cipher_encrypt(tfm, sg, sg, blen);
|
||||
else
|
||||
ret = crypto_cipher_decrypt(tfm, sg, sg, blen);
|
||||
end = get_cycles();
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
cycles += end - start;
|
||||
}
|
||||
|
||||
out:
|
||||
local_irq_enable();
|
||||
local_bh_enable();
|
||||
|
||||
if (ret == 0)
|
||||
printk("1 operation in %lu cycles (%d bytes)\n",
|
||||
(cycles + 4) / 8, blen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void test_cipher_speed(char *algo, int mode, int enc, unsigned int sec,
|
||||
struct cipher_testvec *template,
|
||||
unsigned int tcount, struct cipher_speed *speed)
|
||||
{
|
||||
unsigned int ret, i, j, iv_len;
|
||||
unsigned char *key, *p, iv[128];
|
||||
struct crypto_tfm *tfm;
|
||||
const char *e, *m;
|
||||
|
||||
if (enc == ENCRYPT)
|
||||
e = "encryption";
|
||||
else
|
||||
e = "decryption";
|
||||
if (mode == MODE_ECB)
|
||||
m = "ECB";
|
||||
else
|
||||
m = "CBC";
|
||||
|
||||
printk("\ntesting speed of %s %s %s\n", algo, m, e);
|
||||
|
||||
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 %s %s\n", algo, m);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; speed[i].klen != 0; i++) {
|
||||
if ((speed[i].blen + speed[i].klen) > TVMEMSIZE) {
|
||||
printk("template (%u) too big for tvmem (%u)\n",
|
||||
speed[i].blen + speed[i].klen, TVMEMSIZE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
printk("test %u (%d bit key, %d byte blocks): ", i,
|
||||
speed[i].klen * 8, speed[i].blen);
|
||||
|
||||
memset(tvmem, 0xff, speed[i].klen + speed[i].blen);
|
||||
|
||||
/* set key, plain text and IV */
|
||||
key = (unsigned char *)tvmem;
|
||||
for (j = 0; j < tcount; j++) {
|
||||
if (template[j].klen == speed[i].klen) {
|
||||
key = template[j].key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p = (unsigned char *)tvmem + speed[i].klen;
|
||||
|
||||
ret = crypto_cipher_setkey(tfm, key, speed[i].klen);
|
||||
if (ret) {
|
||||
printk("setkey() failed flags=%x\n", tfm->crt_flags);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!mode) {
|
||||
iv_len = crypto_tfm_alg_ivsize(tfm);
|
||||
memset(&iv, 0xff, iv_len);
|
||||
crypto_cipher_set_iv(tfm, iv, iv_len);
|
||||
}
|
||||
|
||||
if (sec)
|
||||
ret = test_cipher_jiffies(tfm, enc, p, speed[i].blen,
|
||||
sec);
|
||||
else
|
||||
ret = test_cipher_cycles(tfm, enc, p, speed[i].blen);
|
||||
|
||||
if (ret) {
|
||||
printk("%s() failed flags=%x\n", e, tfm->crt_flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
crypto_free_tfm(tfm);
|
||||
}
|
||||
|
||||
static void test_deflate(void)
|
||||
{
|
||||
unsigned int i;
|
||||
char result[COMP_BUF_SIZE];
|
||||
@@ -436,7 +608,7 @@ test_deflate(void)
|
||||
}
|
||||
|
||||
memcpy(tvmem, deflate_comp_tv_template, tsize);
|
||||
tv = (void *) tvmem;
|
||||
tv = (void *)tvmem;
|
||||
|
||||
tfm = crypto_alloc_tfm("deflate", 0);
|
||||
if (tfm == NULL) {
|
||||
@@ -473,7 +645,7 @@ test_deflate(void)
|
||||
}
|
||||
|
||||
memcpy(tvmem, deflate_decomp_tv_template, tsize);
|
||||
tv = (void *) tvmem;
|
||||
tv = (void *)tvmem;
|
||||
|
||||
for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) {
|
||||
int ilen, ret, dlen = COMP_BUF_SIZE;
|
||||
@@ -497,8 +669,7 @@ out:
|
||||
crypto_free_tfm(tfm);
|
||||
}
|
||||
|
||||
static void
|
||||
test_crc32c(void)
|
||||
static void test_crc32c(void)
|
||||
{
|
||||
#define NUMVEC 6
|
||||
#define VECSIZE 40
|
||||
@@ -598,8 +769,7 @@ test_crc32c(void)
|
||||
printk("crc32c test complete\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_available(void)
|
||||
static void test_available(void)
|
||||
{
|
||||
char **name = check;
|
||||
|
||||
@@ -611,8 +781,7 @@ test_available(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test(void)
|
||||
static void do_test(void)
|
||||
{
|
||||
switch (mode) {
|
||||
|
||||
@@ -623,13 +792,13 @@ do_test(void)
|
||||
|
||||
//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);
|
||||
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_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);
|
||||
|
||||
@@ -726,7 +895,7 @@ do_test(void)
|
||||
|
||||
case 4:
|
||||
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_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
@@ -863,6 +1032,69 @@ do_test(void)
|
||||
|
||||
#endif
|
||||
|
||||
case 200:
|
||||
test_cipher_speed("aes", MODE_ECB, ENCRYPT, sec, NULL, 0,
|
||||
aes_speed_template);
|
||||
test_cipher_speed("aes", MODE_ECB, DECRYPT, sec, NULL, 0,
|
||||
aes_speed_template);
|
||||
test_cipher_speed("aes", MODE_CBC, ENCRYPT, sec, NULL, 0,
|
||||
aes_speed_template);
|
||||
test_cipher_speed("aes", MODE_CBC, DECRYPT, sec, NULL, 0,
|
||||
aes_speed_template);
|
||||
break;
|
||||
|
||||
case 201:
|
||||
test_cipher_speed("des3_ede", MODE_ECB, ENCRYPT, sec,
|
||||
des3_ede_enc_tv_template,
|
||||
DES3_EDE_ENC_TEST_VECTORS,
|
||||
des3_ede_speed_template);
|
||||
test_cipher_speed("des3_ede", MODE_ECB, DECRYPT, sec,
|
||||
des3_ede_dec_tv_template,
|
||||
DES3_EDE_DEC_TEST_VECTORS,
|
||||
des3_ede_speed_template);
|
||||
test_cipher_speed("des3_ede", MODE_CBC, ENCRYPT, sec,
|
||||
des3_ede_enc_tv_template,
|
||||
DES3_EDE_ENC_TEST_VECTORS,
|
||||
des3_ede_speed_template);
|
||||
test_cipher_speed("des3_ede", MODE_CBC, DECRYPT, sec,
|
||||
des3_ede_dec_tv_template,
|
||||
DES3_EDE_DEC_TEST_VECTORS,
|
||||
des3_ede_speed_template);
|
||||
break;
|
||||
|
||||
case 202:
|
||||
test_cipher_speed("twofish", MODE_ECB, ENCRYPT, sec, NULL, 0,
|
||||
twofish_speed_template);
|
||||
test_cipher_speed("twofish", MODE_ECB, DECRYPT, sec, NULL, 0,
|
||||
twofish_speed_template);
|
||||
test_cipher_speed("twofish", MODE_CBC, ENCRYPT, sec, NULL, 0,
|
||||
twofish_speed_template);
|
||||
test_cipher_speed("twofish", MODE_CBC, DECRYPT, sec, NULL, 0,
|
||||
twofish_speed_template);
|
||||
break;
|
||||
|
||||
case 203:
|
||||
test_cipher_speed("blowfish", MODE_ECB, ENCRYPT, sec, NULL, 0,
|
||||
blowfish_speed_template);
|
||||
test_cipher_speed("blowfish", MODE_ECB, DECRYPT, sec, NULL, 0,
|
||||
blowfish_speed_template);
|
||||
test_cipher_speed("blowfish", MODE_CBC, ENCRYPT, sec, NULL, 0,
|
||||
blowfish_speed_template);
|
||||
test_cipher_speed("blowfish", MODE_CBC, DECRYPT, sec, NULL, 0,
|
||||
blowfish_speed_template);
|
||||
break;
|
||||
|
||||
case 204:
|
||||
test_cipher_speed("des", MODE_ECB, ENCRYPT, sec, NULL, 0,
|
||||
des_speed_template);
|
||||
test_cipher_speed("des", MODE_ECB, DECRYPT, sec, NULL, 0,
|
||||
des_speed_template);
|
||||
test_cipher_speed("des", MODE_CBC, ENCRYPT, sec, NULL, 0,
|
||||
des_speed_template);
|
||||
test_cipher_speed("des", MODE_CBC, DECRYPT, sec, NULL, 0,
|
||||
des_speed_template);
|
||||
break;
|
||||
|
||||
case 1000:
|
||||
test_available();
|
||||
break;
|
||||
@@ -874,8 +1106,7 @@ do_test(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int __init
|
||||
init(void)
|
||||
static int __init init(void)
|
||||
{
|
||||
tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL);
|
||||
if (tvmem == NULL)
|
||||
@@ -904,6 +1135,9 @@ module_init(init);
|
||||
module_exit(fini);
|
||||
|
||||
module_param(mode, int, 0);
|
||||
module_param(sec, uint, 0);
|
||||
MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
|
||||
"(defaults to zero which uses CPU cycles instead)");
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Quick & dirty crypto testing module");
|
||||
|
149
crypto/tcrypt.h
149
crypto/tcrypt.h
@@ -12,7 +12,8 @@
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* 14 - 09 - 2003 Changes by Kartikey Mahendra Bhatt
|
||||
* 2004-08-09 Cipher speed tests by Reyk Floeter <reyk@vantronix.net>
|
||||
* 2003-09-14 Changes by Kartikey Mahendra Bhatt
|
||||
*
|
||||
*/
|
||||
#ifndef _CRYPTO_TCRYPT_H
|
||||
@@ -58,6 +59,11 @@ struct cipher_testvec {
|
||||
unsigned char tap[MAX_TAP];
|
||||
};
|
||||
|
||||
struct cipher_speed {
|
||||
unsigned char klen;
|
||||
unsigned int blen;
|
||||
};
|
||||
|
||||
/*
|
||||
* MD4 test vectors from RFC1320
|
||||
*/
|
||||
@@ -221,7 +227,7 @@ static struct hash_testvec sha384_tv_template[] = {
|
||||
0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b},
|
||||
}, {
|
||||
.plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
||||
.psize = 112,
|
||||
.digest = { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
|
||||
0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
|
||||
@@ -1578,8 +1584,7 @@ static struct cipher_testvec tf_cbc_dec_tv_template[] = {
|
||||
#define TNEPRES_ENC_TEST_VECTORS 4
|
||||
#define TNEPRES_DEC_TEST_VECTORS 4
|
||||
|
||||
static struct cipher_testvec serpent_enc_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec serpent_enc_tv_template[] = {
|
||||
{
|
||||
.input = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
@@ -1620,8 +1625,7 @@ static struct cipher_testvec serpent_enc_tv_template[] =
|
||||
},
|
||||
};
|
||||
|
||||
static struct cipher_testvec tnepres_enc_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec tnepres_enc_tv_template[] = {
|
||||
{ /* KeySize=128, PT=0, I=1 */
|
||||
.input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
@@ -1671,8 +1675,7 @@ static struct cipher_testvec tnepres_enc_tv_template[] =
|
||||
};
|
||||
|
||||
|
||||
static struct cipher_testvec serpent_dec_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec serpent_dec_tv_template[] = {
|
||||
{
|
||||
.input = { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
|
||||
0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 },
|
||||
@@ -1713,8 +1716,7 @@ static struct cipher_testvec serpent_dec_tv_template[] =
|
||||
},
|
||||
};
|
||||
|
||||
static struct cipher_testvec tnepres_dec_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec tnepres_dec_tv_template[] = {
|
||||
{
|
||||
.input = { 0x41, 0xcc, 0x6b, 0x31, 0x59, 0x31, 0x45, 0x97,
|
||||
0x6d, 0x6f, 0xbb, 0x38, 0x4b, 0x37, 0x21, 0x28 },
|
||||
@@ -1760,8 +1762,7 @@ static struct cipher_testvec tnepres_dec_tv_template[] =
|
||||
#define CAST6_ENC_TEST_VECTORS 3
|
||||
#define CAST6_DEC_TEST_VECTORS 3
|
||||
|
||||
static struct cipher_testvec cast6_enc_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec cast6_enc_tv_template[] = {
|
||||
{
|
||||
.key = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
|
||||
0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d },
|
||||
@@ -1795,8 +1796,7 @@ static struct cipher_testvec cast6_enc_tv_template[] =
|
||||
},
|
||||
};
|
||||
|
||||
static struct cipher_testvec cast6_dec_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec cast6_dec_tv_template[] = {
|
||||
{
|
||||
.key = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
|
||||
0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d },
|
||||
@@ -1915,8 +1915,7 @@ static struct cipher_testvec aes_dec_tv_template[] = {
|
||||
#define CAST5_ENC_TEST_VECTORS 3
|
||||
#define CAST5_DEC_TEST_VECTORS 3
|
||||
|
||||
static struct cipher_testvec cast5_enc_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec cast5_enc_tv_template[] = {
|
||||
{
|
||||
.key = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
|
||||
0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a },
|
||||
@@ -1943,8 +1942,7 @@ static struct cipher_testvec cast5_enc_tv_template[] =
|
||||
},
|
||||
};
|
||||
|
||||
static struct cipher_testvec cast5_dec_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec cast5_dec_tv_template[] = {
|
||||
{
|
||||
.key = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
|
||||
0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a },
|
||||
@@ -1977,8 +1975,7 @@ static struct cipher_testvec cast5_dec_tv_template[] =
|
||||
#define ARC4_ENC_TEST_VECTORS 7
|
||||
#define ARC4_DEC_TEST_VECTORS 7
|
||||
|
||||
static struct cipher_testvec arc4_enc_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec arc4_enc_tv_template[] = {
|
||||
{
|
||||
.key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
|
||||
.klen = 8,
|
||||
@@ -2044,8 +2041,7 @@ static struct cipher_testvec arc4_enc_tv_template[] =
|
||||
},
|
||||
};
|
||||
|
||||
static struct cipher_testvec arc4_dec_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec arc4_dec_tv_template[] = {
|
||||
{
|
||||
.key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
|
||||
.klen = 8,
|
||||
@@ -2117,8 +2113,7 @@ static struct cipher_testvec arc4_dec_tv_template[] =
|
||||
#define TEA_ENC_TEST_VECTORS 4
|
||||
#define TEA_DEC_TEST_VECTORS 4
|
||||
|
||||
static struct cipher_testvec tea_enc_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec tea_enc_tv_template[] = {
|
||||
{
|
||||
.key = { [0 ... 15] = 0x00 },
|
||||
.klen = 16,
|
||||
@@ -2161,8 +2156,7 @@ static struct cipher_testvec tea_enc_tv_template[] =
|
||||
}
|
||||
};
|
||||
|
||||
static struct cipher_testvec tea_dec_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec tea_dec_tv_template[] = {
|
||||
{
|
||||
.key = { [0 ... 15] = 0x00 },
|
||||
.klen = 16,
|
||||
@@ -2183,8 +2177,8 @@ static struct cipher_testvec tea_dec_tv_template[] =
|
||||
0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
|
||||
.klen = 16,
|
||||
.input = { 0xbe, 0x7a, 0xbb, 0x81, 0x95, 0x2d, 0x1f, 0x1e,
|
||||
0xdd, 0x89, 0xa1, 0x25, 0x04, 0x21, 0xdf, 0x95 },
|
||||
.ilen = 16,
|
||||
0xdd, 0x89, 0xa1, 0x25, 0x04, 0x21, 0xdf, 0x95 },
|
||||
.ilen = 16,
|
||||
.result = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
|
||||
0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
|
||||
.rlen = 16,
|
||||
@@ -2193,9 +2187,9 @@ static struct cipher_testvec tea_dec_tv_template[] =
|
||||
0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
|
||||
.klen = 16,
|
||||
.input = { 0xe0, 0x4d, 0x5d, 0x3c, 0xb7, 0x8c, 0x36, 0x47,
|
||||
0x94, 0x18, 0x95, 0x91, 0xa9, 0xfc, 0x49, 0xf8,
|
||||
0x44, 0xd1, 0x2d, 0xc2, 0x99, 0xb8, 0x08, 0x2a,
|
||||
0x07, 0x89, 0x73, 0xc2, 0x45, 0x92, 0xc6, 0x90 },
|
||||
0x94, 0x18, 0x95, 0x91, 0xa9, 0xfc, 0x49, 0xf8,
|
||||
0x44, 0xd1, 0x2d, 0xc2, 0x99, 0xb8, 0x08, 0x2a,
|
||||
0x07, 0x89, 0x73, 0xc2, 0x45, 0x92, 0xc6, 0x90 },
|
||||
.ilen = 32,
|
||||
.result = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
|
||||
0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
|
||||
@@ -2211,8 +2205,7 @@ static struct cipher_testvec tea_dec_tv_template[] =
|
||||
#define XTEA_ENC_TEST_VECTORS 4
|
||||
#define XTEA_DEC_TEST_VECTORS 4
|
||||
|
||||
static struct cipher_testvec xtea_enc_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec xtea_enc_tv_template[] = {
|
||||
{
|
||||
.key = { [0 ... 15] = 0x00 },
|
||||
.klen = 16,
|
||||
@@ -2255,8 +2248,7 @@ static struct cipher_testvec xtea_enc_tv_template[] =
|
||||
}
|
||||
};
|
||||
|
||||
static struct cipher_testvec xtea_dec_tv_template[] =
|
||||
{
|
||||
static struct cipher_testvec xtea_dec_tv_template[] = {
|
||||
{
|
||||
.key = { [0 ... 15] = 0x00 },
|
||||
.klen = 16,
|
||||
@@ -2697,8 +2689,7 @@ static struct comp_testvec deflate_decomp_tv_template[] = {
|
||||
*/
|
||||
#define MICHAEL_MIC_TEST_VECTORS 6
|
||||
|
||||
static struct hash_testvec michael_mic_tv_template[] =
|
||||
{
|
||||
static struct hash_testvec michael_mic_tv_template[] = {
|
||||
{
|
||||
.key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
.ksize = 8,
|
||||
@@ -2743,4 +2734,88 @@ static struct hash_testvec michael_mic_tv_template[] =
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Cipher speed tests
|
||||
*/
|
||||
static struct cipher_speed aes_speed_template[] = {
|
||||
{ .klen = 16, .blen = 16, },
|
||||
{ .klen = 16, .blen = 64, },
|
||||
{ .klen = 16, .blen = 256, },
|
||||
{ .klen = 16, .blen = 1024, },
|
||||
{ .klen = 16, .blen = 8192, },
|
||||
{ .klen = 24, .blen = 16, },
|
||||
{ .klen = 24, .blen = 64, },
|
||||
{ .klen = 24, .blen = 256, },
|
||||
{ .klen = 24, .blen = 1024, },
|
||||
{ .klen = 24, .blen = 8192, },
|
||||
{ .klen = 32, .blen = 16, },
|
||||
{ .klen = 32, .blen = 64, },
|
||||
{ .klen = 32, .blen = 256, },
|
||||
{ .klen = 32, .blen = 1024, },
|
||||
{ .klen = 32, .blen = 8192, },
|
||||
|
||||
/* End marker */
|
||||
{ .klen = 0, .blen = 0, }
|
||||
};
|
||||
|
||||
static struct cipher_speed des3_ede_speed_template[] = {
|
||||
{ .klen = 24, .blen = 16, },
|
||||
{ .klen = 24, .blen = 64, },
|
||||
{ .klen = 24, .blen = 256, },
|
||||
{ .klen = 24, .blen = 1024, },
|
||||
{ .klen = 24, .blen = 8192, },
|
||||
|
||||
/* End marker */
|
||||
{ .klen = 0, .blen = 0, }
|
||||
};
|
||||
|
||||
static struct cipher_speed twofish_speed_template[] = {
|
||||
{ .klen = 16, .blen = 16, },
|
||||
{ .klen = 16, .blen = 64, },
|
||||
{ .klen = 16, .blen = 256, },
|
||||
{ .klen = 16, .blen = 1024, },
|
||||
{ .klen = 16, .blen = 8192, },
|
||||
{ .klen = 24, .blen = 16, },
|
||||
{ .klen = 24, .blen = 64, },
|
||||
{ .klen = 24, .blen = 256, },
|
||||
{ .klen = 24, .blen = 1024, },
|
||||
{ .klen = 24, .blen = 8192, },
|
||||
{ .klen = 32, .blen = 16, },
|
||||
{ .klen = 32, .blen = 64, },
|
||||
{ .klen = 32, .blen = 256, },
|
||||
{ .klen = 32, .blen = 1024, },
|
||||
{ .klen = 32, .blen = 8192, },
|
||||
|
||||
/* End marker */
|
||||
{ .klen = 0, .blen = 0, }
|
||||
};
|
||||
|
||||
static struct cipher_speed blowfish_speed_template[] = {
|
||||
/* Don't support blowfish keys > 256 bit in this test */
|
||||
{ .klen = 8, .blen = 16, },
|
||||
{ .klen = 8, .blen = 64, },
|
||||
{ .klen = 8, .blen = 256, },
|
||||
{ .klen = 8, .blen = 1024, },
|
||||
{ .klen = 8, .blen = 8192, },
|
||||
{ .klen = 32, .blen = 16, },
|
||||
{ .klen = 32, .blen = 64, },
|
||||
{ .klen = 32, .blen = 256, },
|
||||
{ .klen = 32, .blen = 1024, },
|
||||
{ .klen = 32, .blen = 8192, },
|
||||
|
||||
/* End marker */
|
||||
{ .klen = 0, .blen = 0, }
|
||||
};
|
||||
|
||||
static struct cipher_speed des_speed_template[] = {
|
||||
{ .klen = 8, .blen = 16, },
|
||||
{ .klen = 8, .blen = 64, },
|
||||
{ .klen = 8, .blen = 256, },
|
||||
{ .klen = 8, .blen = 1024, },
|
||||
{ .klen = 8, .blen = 8192, },
|
||||
|
||||
/* End marker */
|
||||
{ .klen = 0, .blen = 0, }
|
||||
};
|
||||
|
||||
#endif /* _CRYPTO_TCRYPT_H */
|
||||
|
@@ -1109,8 +1109,7 @@ struct net_device * __init ltpc_probe(void)
|
||||
inb_p(io+1);
|
||||
inb_p(io+3);
|
||||
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(2*HZ/100);
|
||||
msleep(20);
|
||||
|
||||
inb_p(io+0);
|
||||
inb_p(io+2);
|
||||
@@ -1120,8 +1119,7 @@ struct net_device * __init ltpc_probe(void)
|
||||
inb_p(io+5); /* enable dma */
|
||||
inb_p(io+6); /* tri-state interrupt line */
|
||||
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(HZ);
|
||||
ssleep(1);
|
||||
|
||||
/* now, figure out which dma channel we're using, unless it's
|
||||
already been specified */
|
||||
|
@@ -41,7 +41,7 @@
|
||||
struct divert_blk;
|
||||
struct vlan_group;
|
||||
struct ethtool_ops;
|
||||
struct netpoll;
|
||||
struct netpoll_info;
|
||||
/* source back-compat hooks */
|
||||
#define SET_ETHTOOL_OPS(netdev,ops) \
|
||||
( (netdev)->ethtool_ops = (ops) )
|
||||
@@ -468,7 +468,7 @@ struct net_device
|
||||
unsigned char *haddr);
|
||||
int (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
|
||||
#ifdef CONFIG_NETPOLL
|
||||
struct netpoll *np;
|
||||
struct netpoll_info *npinfo;
|
||||
#endif
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
void (*poll_controller)(struct net_device *dev);
|
||||
|
@@ -18,7 +18,6 @@ struct clusterip_config;
|
||||
struct ipt_clusterip_tgt_info {
|
||||
|
||||
u_int32_t flags;
|
||||
struct clusterip_config *config;
|
||||
|
||||
/* only relevant for new ones */
|
||||
u_int8_t clustermac[6];
|
||||
@@ -27,6 +26,8 @@ struct ipt_clusterip_tgt_info {
|
||||
u_int16_t local_nodes[CLUSTERIP_MAX_NODES];
|
||||
enum clusterip_hashmode hash_mode;
|
||||
u_int32_t hash_initval;
|
||||
|
||||
struct clusterip_config *config;
|
||||
};
|
||||
|
||||
#endif /*_IPT_CLUSTERIP_H_target*/
|
||||
|
@@ -16,14 +16,19 @@ struct netpoll;
|
||||
struct netpoll {
|
||||
struct net_device *dev;
|
||||
char dev_name[16], *name;
|
||||
int rx_flags;
|
||||
void (*rx_hook)(struct netpoll *, int, char *, int);
|
||||
void (*drop)(struct sk_buff *skb);
|
||||
u32 local_ip, remote_ip;
|
||||
u16 local_port, remote_port;
|
||||
unsigned char local_mac[6], remote_mac[6];
|
||||
};
|
||||
|
||||
struct netpoll_info {
|
||||
spinlock_t poll_lock;
|
||||
int poll_owner;
|
||||
int rx_flags;
|
||||
spinlock_t rx_lock;
|
||||
struct netpoll *rx_np; /* netpoll that registered an rx_hook */
|
||||
};
|
||||
|
||||
void netpoll_poll(struct netpoll *np);
|
||||
@@ -39,22 +44,35 @@ void netpoll_queue(struct sk_buff *skb);
|
||||
#ifdef CONFIG_NETPOLL
|
||||
static inline int netpoll_rx(struct sk_buff *skb)
|
||||
{
|
||||
return skb->dev->np && skb->dev->np->rx_flags && __netpoll_rx(skb);
|
||||
struct netpoll_info *npinfo = skb->dev->npinfo;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (!npinfo || (!npinfo->rx_np && !npinfo->rx_flags))
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&npinfo->rx_lock, flags);
|
||||
/* check rx_flags again with the lock held */
|
||||
if (npinfo->rx_flags && __netpoll_rx(skb))
|
||||
ret = 1;
|
||||
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void netpoll_poll_lock(struct net_device *dev)
|
||||
{
|
||||
if (dev->np) {
|
||||
spin_lock(&dev->np->poll_lock);
|
||||
dev->np->poll_owner = smp_processor_id();
|
||||
if (dev->npinfo) {
|
||||
spin_lock(&dev->npinfo->poll_lock);
|
||||
dev->npinfo->poll_owner = smp_processor_id();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void netpoll_poll_unlock(struct net_device *dev)
|
||||
{
|
||||
if (dev->np) {
|
||||
spin_unlock(&dev->np->poll_lock);
|
||||
dev->np->poll_owner = -1;
|
||||
if (dev->npinfo) {
|
||||
dev->npinfo->poll_owner = -1;
|
||||
spin_unlock(&dev->npinfo->poll_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,6 +4,8 @@
|
||||
* History
|
||||
* mar/20/00 Daniela Squassoni Disabling/enabling of facilities
|
||||
* negotiation.
|
||||
* apr/02/05 Shaun Pereira Selective sub address matching with
|
||||
* call user data
|
||||
*/
|
||||
|
||||
#ifndef X25_KERNEL_H
|
||||
@@ -16,6 +18,9 @@
|
||||
#define SIOCX25GCALLUSERDATA (SIOCPROTOPRIVATE + 4)
|
||||
#define SIOCX25SCALLUSERDATA (SIOCPROTOPRIVATE + 5)
|
||||
#define SIOCX25GCAUSEDIAG (SIOCPROTOPRIVATE + 6)
|
||||
#define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7)
|
||||
#define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8)
|
||||
#define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9)
|
||||
|
||||
/*
|
||||
* Values for {get,set}sockopt.
|
||||
@@ -109,4 +114,11 @@ struct x25_causediag {
|
||||
unsigned char diagnostic;
|
||||
};
|
||||
|
||||
/*
|
||||
* Further optional call user data match length selection
|
||||
*/
|
||||
struct x25_subaddr {
|
||||
unsigned int cudmatchlength;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -79,6 +79,8 @@ enum {
|
||||
#define X25_DEFAULT_PACKET_SIZE X25_PS128 /* Default Packet Size */
|
||||
#define X25_DEFAULT_THROUGHPUT 0x0A /* Deafult Throughput */
|
||||
#define X25_DEFAULT_REVERSE 0x00 /* Default Reverse Charging */
|
||||
#define X25_DENY_ACCPT_APPRV 0x01 /* Default value */
|
||||
#define X25_ALLOW_ACCPT_APPRV 0x00 /* Control enabled */
|
||||
|
||||
#define X25_SMODULUS 8
|
||||
#define X25_EMODULUS 128
|
||||
@@ -94,7 +96,7 @@ enum {
|
||||
#define X25_FAC_CLASS_C 0x80
|
||||
#define X25_FAC_CLASS_D 0xC0
|
||||
|
||||
#define X25_FAC_REVERSE 0x01
|
||||
#define X25_FAC_REVERSE 0x01 /* also fast select */
|
||||
#define X25_FAC_THROUGHPUT 0x02
|
||||
#define X25_FAC_PACKET_SIZE 0x42
|
||||
#define X25_FAC_WINDOW_SIZE 0x43
|
||||
@@ -134,8 +136,8 @@ struct x25_sock {
|
||||
struct sock sk;
|
||||
struct x25_address source_addr, dest_addr;
|
||||
struct x25_neigh *neighbour;
|
||||
unsigned int lci;
|
||||
unsigned char state, condition, qbitincl, intflag;
|
||||
unsigned int lci, cudmatchlength;
|
||||
unsigned char state, condition, qbitincl, intflag, accptapprv;
|
||||
unsigned short vs, vr, va, vl;
|
||||
unsigned long t2, t21, t22, t23;
|
||||
unsigned short fraglen;
|
||||
@@ -242,7 +244,6 @@ extern int x25_validate_nr(struct sock *, unsigned short);
|
||||
extern void x25_write_internal(struct sock *, int);
|
||||
extern int x25_decode(struct sock *, struct sk_buff *, int *, int *, int *, int *, int *);
|
||||
extern void x25_disconnect(struct sock *, int, unsigned char, unsigned char);
|
||||
extern int x25_check_calluserdata(struct x25_calluserdata *,struct x25_calluserdata *);
|
||||
|
||||
/* x25_timer.c */
|
||||
extern void x25_start_heartbeat(struct sock *);
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include <net/datalink.h>
|
||||
#include <net/psnap.h>
|
||||
#include <linux/atalk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
@@ -462,8 +463,7 @@ void aarp_probe_network(struct atalk_iface *atif)
|
||||
aarp_send_probe(atif->dev, &atif->address);
|
||||
|
||||
/* Defer 1/10th */
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule_timeout(HZ / 10);
|
||||
msleep(100);
|
||||
|
||||
if (atif->status & ATIF_PROBE_FAIL)
|
||||
break;
|
||||
@@ -510,9 +510,8 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa)
|
||||
aarp_send_probe(atif->dev, sa);
|
||||
|
||||
/* Defer 1/10th */
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
write_unlock_bh(&aarp_lock);
|
||||
schedule_timeout(HZ / 10);
|
||||
msleep(100);
|
||||
write_lock_bh(&aarp_lock);
|
||||
|
||||
if (entry->status & ATIF_PROBE_FAIL)
|
||||
|
@@ -859,8 +859,7 @@ static int translate_table(struct ebt_replace *repl,
|
||||
if (repl->valid_hooks & (1 << i))
|
||||
if (check_chainloops(newinfo->hook_entry[i],
|
||||
cl_s, udc_cnt, i, newinfo->entries)) {
|
||||
if (cl_s)
|
||||
vfree(cl_s);
|
||||
vfree(cl_s);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -883,8 +882,7 @@ static int translate_table(struct ebt_replace *repl,
|
||||
EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
|
||||
ebt_cleanup_entry, &i);
|
||||
}
|
||||
if (cl_s)
|
||||
vfree(cl_s);
|
||||
vfree(cl_s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1030,8 +1028,7 @@ static int do_replace(void __user *user, unsigned int len)
|
||||
}
|
||||
vfree(table);
|
||||
|
||||
if (counterstmp)
|
||||
vfree(counterstmp);
|
||||
vfree(counterstmp);
|
||||
return ret;
|
||||
|
||||
free_unlock:
|
||||
@@ -1040,8 +1037,7 @@ free_iterate:
|
||||
EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
|
||||
ebt_cleanup_entry, NULL);
|
||||
free_counterstmp:
|
||||
if (counterstmp)
|
||||
vfree(counterstmp);
|
||||
vfree(counterstmp);
|
||||
/* can be initialized in translate_table() */
|
||||
if (newinfo->chainstack) {
|
||||
for (i = 0; i < num_possible_cpus(); i++)
|
||||
@@ -1049,11 +1045,9 @@ free_counterstmp:
|
||||
vfree(newinfo->chainstack);
|
||||
}
|
||||
free_entries:
|
||||
if (newinfo->entries)
|
||||
vfree(newinfo->entries);
|
||||
vfree(newinfo->entries);
|
||||
free_newinfo:
|
||||
if (newinfo)
|
||||
vfree(newinfo);
|
||||
vfree(newinfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1213,8 +1207,7 @@ void ebt_unregister_table(struct ebt_table *table)
|
||||
down(&ebt_mutex);
|
||||
LIST_DELETE(&ebt_tables, table);
|
||||
up(&ebt_mutex);
|
||||
if (table->private->entries)
|
||||
vfree(table->private->entries);
|
||||
vfree(table->private->entries);
|
||||
if (table->private->chainstack) {
|
||||
for (i = 0; i < num_possible_cpus(); i++)
|
||||
vfree(table->private->chainstack[i]);
|
||||
|
@@ -130,19 +130,20 @@ static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
|
||||
*/
|
||||
static void poll_napi(struct netpoll *np)
|
||||
{
|
||||
struct netpoll_info *npinfo = np->dev->npinfo;
|
||||
int budget = 16;
|
||||
|
||||
if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
|
||||
np->poll_owner != smp_processor_id() &&
|
||||
spin_trylock(&np->poll_lock)) {
|
||||
np->rx_flags |= NETPOLL_RX_DROP;
|
||||
npinfo->poll_owner != smp_processor_id() &&
|
||||
spin_trylock(&npinfo->poll_lock)) {
|
||||
npinfo->rx_flags |= NETPOLL_RX_DROP;
|
||||
atomic_inc(&trapped);
|
||||
|
||||
np->dev->poll(np->dev, &budget);
|
||||
|
||||
atomic_dec(&trapped);
|
||||
np->rx_flags &= ~NETPOLL_RX_DROP;
|
||||
spin_unlock(&np->poll_lock);
|
||||
npinfo->rx_flags &= ~NETPOLL_RX_DROP;
|
||||
spin_unlock(&npinfo->poll_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,6 +246,7 @@ repeat:
|
||||
static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
|
||||
{
|
||||
int status;
|
||||
struct netpoll_info *npinfo;
|
||||
|
||||
repeat:
|
||||
if(!np || !np->dev || !netif_running(np->dev)) {
|
||||
@@ -253,8 +255,9 @@ repeat:
|
||||
}
|
||||
|
||||
/* avoid recursion */
|
||||
if(np->poll_owner == smp_processor_id() ||
|
||||
np->dev->xmit_lock_owner == smp_processor_id()) {
|
||||
npinfo = np->dev->npinfo;
|
||||
if (npinfo->poll_owner == smp_processor_id() ||
|
||||
np->dev->xmit_lock_owner == smp_processor_id()) {
|
||||
if (np->drop)
|
||||
np->drop(skb);
|
||||
else
|
||||
@@ -341,14 +344,22 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
|
||||
|
||||
static void arp_reply(struct sk_buff *skb)
|
||||
{
|
||||
struct netpoll_info *npinfo = skb->dev->npinfo;
|
||||
struct arphdr *arp;
|
||||
unsigned char *arp_ptr;
|
||||
int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
|
||||
u32 sip, tip;
|
||||
unsigned long flags;
|
||||
struct sk_buff *send_skb;
|
||||
struct netpoll *np = skb->dev->np;
|
||||
struct netpoll *np = NULL;
|
||||
|
||||
if (!np) return;
|
||||
spin_lock_irqsave(&npinfo->rx_lock, flags);
|
||||
if (npinfo->rx_np && npinfo->rx_np->dev == skb->dev)
|
||||
np = npinfo->rx_np;
|
||||
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
|
||||
|
||||
if (!np)
|
||||
return;
|
||||
|
||||
/* No arp on this interface */
|
||||
if (skb->dev->flags & IFF_NOARP)
|
||||
@@ -429,9 +440,9 @@ int __netpoll_rx(struct sk_buff *skb)
|
||||
int proto, len, ulen;
|
||||
struct iphdr *iph;
|
||||
struct udphdr *uh;
|
||||
struct netpoll *np = skb->dev->np;
|
||||
struct netpoll *np = skb->dev->npinfo->rx_np;
|
||||
|
||||
if (!np->rx_hook)
|
||||
if (!np)
|
||||
goto out;
|
||||
if (skb->dev->type != ARPHRD_ETHER)
|
||||
goto out;
|
||||
@@ -611,9 +622,8 @@ int netpoll_setup(struct netpoll *np)
|
||||
{
|
||||
struct net_device *ndev = NULL;
|
||||
struct in_device *in_dev;
|
||||
|
||||
np->poll_lock = SPIN_LOCK_UNLOCKED;
|
||||
np->poll_owner = -1;
|
||||
struct netpoll_info *npinfo;
|
||||
unsigned long flags;
|
||||
|
||||
if (np->dev_name)
|
||||
ndev = dev_get_by_name(np->dev_name);
|
||||
@@ -624,7 +634,17 @@ int netpoll_setup(struct netpoll *np)
|
||||
}
|
||||
|
||||
np->dev = ndev;
|
||||
ndev->np = np;
|
||||
if (!ndev->npinfo) {
|
||||
npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL);
|
||||
if (!npinfo)
|
||||
goto release;
|
||||
|
||||
npinfo->rx_np = NULL;
|
||||
npinfo->poll_lock = SPIN_LOCK_UNLOCKED;
|
||||
npinfo->poll_owner = -1;
|
||||
npinfo->rx_lock = SPIN_LOCK_UNLOCKED;
|
||||
} else
|
||||
npinfo = ndev->npinfo;
|
||||
|
||||
if (!ndev->poll_controller) {
|
||||
printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
|
||||
@@ -692,13 +712,20 @@ int netpoll_setup(struct netpoll *np)
|
||||
np->name, HIPQUAD(np->local_ip));
|
||||
}
|
||||
|
||||
if(np->rx_hook)
|
||||
np->rx_flags = NETPOLL_RX_ENABLED;
|
||||
if (np->rx_hook) {
|
||||
spin_lock_irqsave(&npinfo->rx_lock, flags);
|
||||
npinfo->rx_flags |= NETPOLL_RX_ENABLED;
|
||||
npinfo->rx_np = np;
|
||||
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
|
||||
}
|
||||
/* last thing to do is link it to the net device structure */
|
||||
ndev->npinfo = npinfo;
|
||||
|
||||
return 0;
|
||||
|
||||
release:
|
||||
ndev->np = NULL;
|
||||
if (!ndev->npinfo)
|
||||
kfree(npinfo);
|
||||
np->dev = NULL;
|
||||
dev_put(ndev);
|
||||
return -1;
|
||||
@@ -706,9 +733,20 @@ int netpoll_setup(struct netpoll *np)
|
||||
|
||||
void netpoll_cleanup(struct netpoll *np)
|
||||
{
|
||||
if (np->dev)
|
||||
np->dev->np = NULL;
|
||||
dev_put(np->dev);
|
||||
struct netpoll_info *npinfo;
|
||||
unsigned long flags;
|
||||
|
||||
if (np->dev) {
|
||||
npinfo = np->dev->npinfo;
|
||||
if (npinfo && npinfo->rx_np == np) {
|
||||
spin_lock_irqsave(&npinfo->rx_lock, flags);
|
||||
npinfo->rx_np = NULL;
|
||||
npinfo->rx_flags &= ~NETPOLL_RX_ENABLED;
|
||||
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
|
||||
}
|
||||
dev_put(np->dev);
|
||||
}
|
||||
|
||||
np->dev = NULL;
|
||||
}
|
||||
|
||||
|
@@ -339,7 +339,7 @@ target(struct sk_buff **pskb,
|
||||
* error messages (RELATED) and information requests (see below) */
|
||||
if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP
|
||||
&& (ctinfo == IP_CT_RELATED
|
||||
|| ctinfo == IP_CT_IS_REPLY+IP_CT_IS_REPLY))
|
||||
|| ctinfo == IP_CT_RELATED+IP_CT_IS_REPLY))
|
||||
return IPT_CONTINUE;
|
||||
|
||||
/* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO,
|
||||
|
@@ -1767,7 +1767,7 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
|
||||
struct in_device *in_dev,
|
||||
u32 daddr, u32 saddr, u32 tos)
|
||||
{
|
||||
struct rtable* rth;
|
||||
struct rtable* rth = NULL;
|
||||
int err;
|
||||
unsigned hash;
|
||||
|
||||
@@ -1794,7 +1794,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
|
||||
u32 daddr, u32 saddr, u32 tos)
|
||||
{
|
||||
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
|
||||
struct rtable* rth;
|
||||
struct rtable* rth = NULL;
|
||||
unsigned char hop, hopcount, lasthop;
|
||||
int err = -EINVAL;
|
||||
unsigned int hash;
|
||||
@@ -2239,7 +2239,7 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
|
||||
struct net_device *dev_out,
|
||||
unsigned flags)
|
||||
{
|
||||
struct rtable *rth;
|
||||
struct rtable *rth = NULL;
|
||||
int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
|
||||
unsigned hash;
|
||||
if (err == 0) {
|
||||
@@ -2267,7 +2267,7 @@ static inline int ip_mkroute_output(struct rtable** rp,
|
||||
unsigned char hop;
|
||||
unsigned hash;
|
||||
int err = -EINVAL;
|
||||
struct rtable *rth;
|
||||
struct rtable *rth = NULL;
|
||||
|
||||
if (res->fi && res->fi->fib_nhs > 1) {
|
||||
unsigned char hopcount = res->fi->fib_nhs;
|
||||
|
@@ -383,9 +383,8 @@ int sock_map_fd(struct socket *sock)
|
||||
goto out;
|
||||
}
|
||||
|
||||
sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
|
||||
this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
|
||||
this.name = name;
|
||||
this.len = strlen(name);
|
||||
this.hash = SOCK_INODE(sock)->i_ino;
|
||||
|
||||
file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
|
||||
|
108
net/x25/af_x25.c
108
net/x25/af_x25.c
@@ -29,6 +29,10 @@
|
||||
* 2000-11-14 Henner Eisen Closing datalink from NETDEV_GOING_DOWN
|
||||
* 2002-10-06 Arnaldo C. Melo Get rid of cli/sti, move proc stuff to
|
||||
* x25_proc.c, using seq_file
|
||||
* 2005-04-02 Shaun Pereira Selective sub address matching
|
||||
* with call user data
|
||||
* 2005-04-15 Shaun Pereira Fast select with no restriction on
|
||||
* response
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
@@ -219,7 +223,8 @@ static void x25_insert_socket(struct sock *sk)
|
||||
* Note: if a listening socket has cud set it must only get calls
|
||||
* with matching cud.
|
||||
*/
|
||||
static struct sock *x25_find_listener(struct x25_address *addr, struct x25_calluserdata *calluserdata)
|
||||
static struct sock *x25_find_listener(struct x25_address *addr,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct sock *s;
|
||||
struct sock *next_best;
|
||||
@@ -230,22 +235,23 @@ static struct sock *x25_find_listener(struct x25_address *addr, struct x25_callu
|
||||
|
||||
sk_for_each(s, node, &x25_list)
|
||||
if ((!strcmp(addr->x25_addr,
|
||||
x25_sk(s)->source_addr.x25_addr) ||
|
||||
!strcmp(addr->x25_addr,
|
||||
null_x25_address.x25_addr)) &&
|
||||
s->sk_state == TCP_LISTEN) {
|
||||
|
||||
x25_sk(s)->source_addr.x25_addr) ||
|
||||
!strcmp(addr->x25_addr,
|
||||
null_x25_address.x25_addr)) &&
|
||||
s->sk_state == TCP_LISTEN) {
|
||||
/*
|
||||
* Found a listening socket, now check the incoming
|
||||
* call user data vs this sockets call user data
|
||||
*/
|
||||
if (x25_check_calluserdata(&x25_sk(s)->calluserdata, calluserdata)) {
|
||||
sock_hold(s);
|
||||
goto found;
|
||||
}
|
||||
if (x25_sk(s)->calluserdata.cudlength == 0) {
|
||||
if(skb->len > 0 && x25_sk(s)->cudmatchlength > 0) {
|
||||
if((memcmp(x25_sk(s)->calluserdata.cuddata,
|
||||
skb->data,
|
||||
x25_sk(s)->cudmatchlength)) == 0) {
|
||||
sock_hold(s);
|
||||
goto found;
|
||||
}
|
||||
} else
|
||||
next_best = s;
|
||||
}
|
||||
}
|
||||
if (next_best) {
|
||||
s = next_best;
|
||||
@@ -497,6 +503,9 @@ static int x25_create(struct socket *sock, int protocol)
|
||||
x25->t23 = sysctl_x25_clear_request_timeout;
|
||||
x25->t2 = sysctl_x25_ack_holdback_timeout;
|
||||
x25->state = X25_STATE_0;
|
||||
x25->cudmatchlength = 0;
|
||||
x25->accptapprv = X25_DENY_ACCPT_APPRV; /* normally no cud */
|
||||
/* on call accept */
|
||||
|
||||
x25->facilities.winsize_in = X25_DEFAULT_WINDOW_SIZE;
|
||||
x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
|
||||
@@ -545,6 +554,8 @@ static struct sock *x25_make_new(struct sock *osk)
|
||||
x25->t2 = ox25->t2;
|
||||
x25->facilities = ox25->facilities;
|
||||
x25->qbitincl = ox25->qbitincl;
|
||||
x25->cudmatchlength = ox25->cudmatchlength;
|
||||
x25->accptapprv = ox25->accptapprv;
|
||||
|
||||
x25_init_timers(sk);
|
||||
out:
|
||||
@@ -822,7 +833,6 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
|
||||
struct x25_sock *makex25;
|
||||
struct x25_address source_addr, dest_addr;
|
||||
struct x25_facilities facilities;
|
||||
struct x25_calluserdata calluserdata;
|
||||
int len, rc;
|
||||
|
||||
/*
|
||||
@@ -844,20 +854,11 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
|
||||
len = skb->data[0] + 1;
|
||||
skb_pull(skb,len);
|
||||
|
||||
/*
|
||||
* Incoming Call User Data.
|
||||
*/
|
||||
if (skb->len >= 0) {
|
||||
memcpy(calluserdata.cuddata, skb->data, skb->len);
|
||||
calluserdata.cudlength = skb->len;
|
||||
}
|
||||
|
||||
skb_push(skb,len);
|
||||
|
||||
/*
|
||||
* Find a listener for the particular address/cud pair.
|
||||
*/
|
||||
sk = x25_find_listener(&source_addr,&calluserdata);
|
||||
sk = x25_find_listener(&source_addr,skb);
|
||||
skb_push(skb,len);
|
||||
|
||||
/*
|
||||
* We can't accept the Call Request.
|
||||
@@ -900,11 +901,23 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
|
||||
makex25->neighbour = nb;
|
||||
makex25->facilities = facilities;
|
||||
makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask;
|
||||
makex25->calluserdata = calluserdata;
|
||||
/* ensure no reverse facil on accept */
|
||||
makex25->vc_facil_mask &= ~X25_MASK_REVERSE;
|
||||
makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;
|
||||
|
||||
x25_write_internal(make, X25_CALL_ACCEPTED);
|
||||
/* Normally all calls are accepted immediatly */
|
||||
if(makex25->accptapprv & X25_DENY_ACCPT_APPRV) {
|
||||
x25_write_internal(make, X25_CALL_ACCEPTED);
|
||||
makex25->state = X25_STATE_3;
|
||||
}
|
||||
|
||||
makex25->state = X25_STATE_3;
|
||||
/*
|
||||
* Incoming Call User Data.
|
||||
*/
|
||||
if (skb->len >= 0) {
|
||||
memcpy(makex25->calluserdata.cuddata, skb->data, skb->len);
|
||||
makex25->calluserdata.cudlength = skb->len;
|
||||
}
|
||||
|
||||
sk->sk_ack_backlog++;
|
||||
|
||||
@@ -1288,7 +1301,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
||||
if (facilities.throughput < 0x03 ||
|
||||
facilities.throughput > 0xDD)
|
||||
break;
|
||||
if (facilities.reverse && facilities.reverse != 1)
|
||||
if (facilities.reverse &&
|
||||
(facilities.reverse | 0x81)!= 0x81)
|
||||
break;
|
||||
x25->facilities = facilities;
|
||||
rc = 0;
|
||||
@@ -1325,6 +1339,44 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
||||
break;
|
||||
}
|
||||
|
||||
case SIOCX25SCUDMATCHLEN: {
|
||||
struct x25_subaddr sub_addr;
|
||||
rc = -EINVAL;
|
||||
if(sk->sk_state != TCP_CLOSE)
|
||||
break;
|
||||
rc = -EFAULT;
|
||||
if (copy_from_user(&sub_addr, argp,
|
||||
sizeof(sub_addr)))
|
||||
break;
|
||||
rc = -EINVAL;
|
||||
if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN)
|
||||
break;
|
||||
x25->cudmatchlength = sub_addr.cudmatchlength;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case SIOCX25CALLACCPTAPPRV: {
|
||||
rc = -EINVAL;
|
||||
if (sk->sk_state != TCP_CLOSE)
|
||||
break;
|
||||
x25->accptapprv = X25_ALLOW_ACCPT_APPRV;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case SIOCX25SENDCALLACCPT: {
|
||||
rc = -EINVAL;
|
||||
if (sk->sk_state != TCP_ESTABLISHED)
|
||||
break;
|
||||
if (x25->accptapprv) /* must call accptapprv above */
|
||||
break;
|
||||
x25_write_internal(sk, X25_CALL_ACCEPTED);
|
||||
x25->state = X25_STATE_3;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
rc = dev_ioctl(cmd, argp);
|
||||
break;
|
||||
|
@@ -17,6 +17,8 @@
|
||||
* X.25 001 Split from x25_subr.c
|
||||
* mar/20/00 Daniela Squassoni Disabling/enabling of facilities
|
||||
* negotiation.
|
||||
* apr/14/05 Shaun Pereira - Allow fast select with no restriction
|
||||
* on response.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -43,9 +45,31 @@ int x25_parse_facilities(struct sk_buff *skb,
|
||||
case X25_FAC_CLASS_A:
|
||||
switch (*p) {
|
||||
case X25_FAC_REVERSE:
|
||||
facilities->reverse = p[1] & 0x01;
|
||||
*vc_fac_mask |= X25_MASK_REVERSE;
|
||||
break;
|
||||
if((p[1] & 0x81) == 0x81) {
|
||||
facilities->reverse = p[1] & 0x81;
|
||||
*vc_fac_mask |= X25_MASK_REVERSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if((p[1] & 0x01) == 0x01) {
|
||||
facilities->reverse = p[1] & 0x01;
|
||||
*vc_fac_mask |= X25_MASK_REVERSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if((p[1] & 0x80) == 0x80) {
|
||||
facilities->reverse = p[1] & 0x80;
|
||||
*vc_fac_mask |= X25_MASK_REVERSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(p[1] == 0x00) {
|
||||
facilities->reverse
|
||||
= X25_DEFAULT_REVERSE;
|
||||
*vc_fac_mask |= X25_MASK_REVERSE;
|
||||
break;
|
||||
}
|
||||
|
||||
case X25_FAC_THROUGHPUT:
|
||||
facilities->throughput = p[1];
|
||||
*vc_fac_mask |= X25_MASK_THROUGHPUT;
|
||||
@@ -122,7 +146,7 @@ int x25_create_facilities(unsigned char *buffer,
|
||||
|
||||
if (facilities->reverse && (facil_mask & X25_MASK_REVERSE)) {
|
||||
*p++ = X25_FAC_REVERSE;
|
||||
*p++ = !!facilities->reverse;
|
||||
*p++ = facilities->reverse;
|
||||
}
|
||||
|
||||
if (facilities->throughput && (facil_mask & X25_MASK_THROUGHPUT)) {
|
||||
@@ -171,7 +195,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
|
||||
/*
|
||||
* They want reverse charging, we won't accept it.
|
||||
*/
|
||||
if (theirs.reverse && ours->reverse) {
|
||||
if ((theirs.reverse & 0x01 ) && (ours->reverse & 0x01)) {
|
||||
SOCK_DEBUG(sk, "X.25: rejecting reverse charging request");
|
||||
return -1;
|
||||
}
|
||||
|
@@ -19,6 +19,8 @@
|
||||
* mar/20/00 Daniela Squassoni Disabling/enabling of facilities
|
||||
* negotiation.
|
||||
* jun/24/01 Arnaldo C. Melo use skb_queue_purge, cleanups
|
||||
* apr/04/15 Shaun Pereira Fast select with no
|
||||
* restriction on response.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -127,8 +129,12 @@ void x25_write_internal(struct sock *sk, int frametype)
|
||||
len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN +
|
||||
X25_MAX_CUD_LEN;
|
||||
break;
|
||||
case X25_CALL_ACCEPTED:
|
||||
len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
|
||||
case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */
|
||||
if(x25->facilities.reverse & 0x80) {
|
||||
len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
|
||||
} else {
|
||||
len += 1 + X25_MAX_FAC_LEN;
|
||||
}
|
||||
break;
|
||||
case X25_CLEAR_REQUEST:
|
||||
case X25_RESET_REQUEST:
|
||||
@@ -203,9 +209,16 @@ void x25_write_internal(struct sock *sk, int frametype)
|
||||
x25->vc_facil_mask);
|
||||
dptr = skb_put(skb, len);
|
||||
memcpy(dptr, facilities, len);
|
||||
dptr = skb_put(skb, x25->calluserdata.cudlength);
|
||||
memcpy(dptr, x25->calluserdata.cuddata,
|
||||
x25->calluserdata.cudlength);
|
||||
|
||||
/* fast select with no restriction on response
|
||||
allows call user data. Userland must
|
||||
ensure it is ours and not theirs */
|
||||
if(x25->facilities.reverse & 0x80) {
|
||||
dptr = skb_put(skb,
|
||||
x25->calluserdata.cudlength);
|
||||
memcpy(dptr, x25->calluserdata.cuddata,
|
||||
x25->calluserdata.cudlength);
|
||||
}
|
||||
x25->calluserdata.cudlength = 0;
|
||||
break;
|
||||
|
||||
@@ -354,21 +367,3 @@ void x25_check_rbuf(struct sock *sk)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare 2 calluserdata structures, used to find correct listening sockets
|
||||
* when call user data is used.
|
||||
*/
|
||||
int x25_check_calluserdata(struct x25_calluserdata *ours, struct x25_calluserdata *theirs)
|
||||
{
|
||||
int i;
|
||||
if (ours->cudlength != theirs->cudlength)
|
||||
return 0;
|
||||
|
||||
for (i=0;i<ours->cudlength;i++) {
|
||||
if (ours->cuddata[i] != theirs->cuddata[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user