diff options
| author | David S. Miller <davem@nuts.ninka.net> | 2003-03-30 13:13:05 -0800 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2003-03-30 13:13:05 -0800 |
| commit | f5d6da7d1edd0d380a3bad4d88c1901050e18bf1 (patch) | |
| tree | 20910d121c9c2b58491f0179f6479dc2444c7562 | |
| parent | b527eea4dc049bca0dd5d63de6555d8622965ba8 (diff) | |
| parent | e99122d248d5f22aa2466a53c29997386ac2865f (diff) | |
Merge nuts.ninka.net:/home/davem/src/BK/network-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
| -rw-r--r-- | crypto/Kconfig | 10 | ||||
| -rw-r--r-- | crypto/Makefile | 1 | ||||
| -rw-r--r-- | crypto/api.c | 2 | ||||
| -rw-r--r-- | crypto/compress.c | 31 | ||||
| -rw-r--r-- | crypto/crypto_null.c | 10 | ||||
| -rw-r--r-- | crypto/deflate.c | 224 | ||||
| -rw-r--r-- | crypto/digest.c | 2 | ||||
| -rw-r--r-- | crypto/internal.h | 5 | ||||
| -rw-r--r-- | crypto/proc.c | 3 | ||||
| -rw-r--r-- | crypto/tcrypt.c | 87 | ||||
| -rw-r--r-- | crypto/tcrypt.h | 100 | ||||
| -rw-r--r-- | drivers/net/Kconfig | 2 | ||||
| -rw-r--r-- | include/linux/crypto.h | 31 | ||||
| -rw-r--r-- | include/net/protocol.h | 1 | ||||
| -rw-r--r-- | include/net/sock.h | 15 | ||||
| -rw-r--r-- | lib/Kconfig | 9 | ||||
| -rw-r--r-- | net/Kconfig | 16 | ||||
| -rw-r--r-- | net/core/Makefile | 4 | ||||
| -rw-r--r-- | net/core/filter.c | 4 | ||||
| -rw-r--r-- | net/core/sock.c | 11 | ||||
| -rw-r--r-- | net/ipv4/tcp_minisocks.c | 6 | ||||
| -rw-r--r-- | net/ipv4/udp.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ah6.c | 5 | ||||
| -rw-r--r-- | net/ipv6/esp6.c | 27 | ||||
| -rw-r--r-- | net/ipv6/ip6_input.c | 18 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 7 | ||||
| -rw-r--r-- | net/ipv6/raw.c | 3 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 1 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 4 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_input.c | 10 | ||||
| -rw-r--r-- | net/netsyms.c | 2 | ||||
| -rw-r--r-- | net/packet/af_packet.c | 10 | ||||
| -rw-r--r-- | net/sctp/ipv6.c | 1 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 1 |
34 files changed, 537 insertions, 128 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index 8b81dcd7da4b..ef70c8cd2a99 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -131,6 +131,16 @@ config CRYPTO_AES See http://csrc.nist.gov/encryption/aes/ for more information. +config CRYPTO_DEFLATE + tristate "Deflate compression algorithm" + depends on CRYPTO + default y if INET_IPCOMP=y || INET_IPCOMP=m + help + This is the Deflate algorithm (RFC1951), specified for use in + IPSec with the IPCOMP protocol (RFC3173, RFC2394). + + You will most probably want this if using IPSec. + config CRYPTO_TEST tristate "Testing module" depends on CRYPTO diff --git a/crypto/Makefile b/crypto/Makefile index 8e7e3a8cf735..464a7f077094 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -20,5 +20,6 @@ obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o obj-$(CONFIG_CRYPTO_AES) += aes.o +obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff --git a/crypto/api.c b/crypto/api.c index 0c00daba80d8..4eec20b963d9 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -127,7 +127,7 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) if (tfm == NULL) goto out_put; - memset(tfm, 0, sizeof(*tfm)); + memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize); tfm->__crt_alg = alg; diff --git a/crypto/compress.c b/crypto/compress.c index 7baaae047941..eb36d9364da3 100644 --- a/crypto/compress.c +++ b/crypto/compress.c @@ -18,29 +18,46 @@ #include <linux/string.h> #include "internal.h" -static void crypto_compress(struct crypto_tfm *tfm) +static int crypto_compress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) { - tfm->__crt_alg->cra_compress.coa_compress(); + return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm), + src, slen, dst, + dlen); } -static void crypto_decompress(struct crypto_tfm *tfm) +static int crypto_decompress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) { - tfm->__crt_alg->cra_compress.coa_decompress(); + return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm), + src, slen, dst, + dlen); } int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags) { - return crypto_cipher_flags(flags) ? -EINVAL : 0; + return flags ? -EINVAL : 0; } int crypto_init_compress_ops(struct crypto_tfm *tfm) { + int ret = 0; struct compress_tfm *ops = &tfm->crt_compress; + ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm)); + if (ret) + goto out; + ops->cot_compress = crypto_compress; ops->cot_decompress = crypto_decompress; - return 0; + +out: + return ret; } void crypto_exit_compress_ops(struct crypto_tfm *tfm) -{ } +{ + tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm)); +} diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c index 8d66c7fd5a6d..f8e26d167406 100644 --- a/crypto/crypto_null.c +++ b/crypto/crypto_null.c @@ -26,11 +26,13 @@ #define NULL_BLOCK_SIZE 1 #define NULL_DIGEST_SIZE 0 -static void null_compress(void) -{ } +static int null_compress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ return 0; } -static void null_decompress(void) -{ } +static int null_decompress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ return 0; } static void null_init(void *ctx) { } diff --git a/crypto/deflate.c b/crypto/deflate.c new file mode 100644 index 000000000000..49cd5708d763 --- /dev/null +++ b/crypto/deflate.c @@ -0,0 +1,224 @@ +/* + * Cryptographic API. + * + * Deflate algorithm (RFC 1951), implemented here primarily for use + * by IPCOMP (RFC 3173 & RFC 2394). + * + * Copyright (c) 2003 James Morris <jmorris@intercode.com.au> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * FIXME: deflate transforms will require up to a total of about 436k of kernel + * memory on i386 (390k for compression, the rest for decompression), as the + * current zlib kernel code uses a worst case pre-allocation system by default. + * This needs to be fixed so that the amount of memory required is properly + * related to the winbits and memlevel parameters. + * + * The default winbits of 11 should suit most packets, and it may be something + * to configure on a per-tfm basis in the future. + * + * Currently, compression history is not maintained between tfm calls, as + * it is not needed for IPCOMP and keeps the code simpler. It can be + * implemented if someone wants it. + */ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/crypto.h> +#include <linux/zlib.h> +#include <linux/vmalloc.h> +#include <linux/interrupt.h> +#include <linux/mm.h> +#include <linux/net.h> + +#define DEFLATE_DEF_LEVEL Z_DEFAULT_COMPRESSION +#define DEFLATE_DEF_WINBITS 11 +#define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL + +struct deflate_ctx { + int comp_initialized; + int decomp_initialized; + struct z_stream_s comp_stream; + struct z_stream_s decomp_stream; +}; + +static inline int deflate_gfp(void) +{ + return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; +} + +static int deflate_init(void *ctx) +{ + return 0; +} + +static void deflate_exit(void *ctx) +{ + struct deflate_ctx *dctx = ctx; + + if (dctx->comp_initialized) + vfree(dctx->comp_stream.workspace); + if (dctx->decomp_initialized) + kfree(dctx->decomp_stream.workspace); +} + +/* + * Lazy initialization to make interface simple without allocating + * un-needed workspaces. Thus can be called in softirq context. + */ +static int deflate_comp_init(struct deflate_ctx *ctx) +{ + int ret = 0; + struct z_stream_s *stream = &ctx->comp_stream; + + stream->workspace = __vmalloc(zlib_deflate_workspacesize(), + deflate_gfp()|__GFP_HIGHMEM, + PAGE_KERNEL); + if (!stream->workspace ) { + ret = -ENOMEM; + goto out; + } + memset(stream->workspace, 0, sizeof(stream->workspace)); + ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED, + -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL, + Z_DEFAULT_STRATEGY); + if (ret != Z_OK) { + ret = -EINVAL; + goto out_free; + } + ctx->comp_initialized = 1; +out: + return ret; +out_free: + vfree(stream->workspace); + goto out; +} + +static int deflate_decomp_init(struct deflate_ctx *ctx) +{ + int ret = 0; + struct z_stream_s *stream = &ctx->decomp_stream; + + stream->workspace = kmalloc(zlib_inflate_workspacesize(), + deflate_gfp()); + if (!stream->workspace ) { + ret = -ENOMEM; + goto out; + } + memset(stream->workspace, 0, sizeof(stream->workspace)); + ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS); + if (ret != Z_OK) { + ret = -EINVAL; + goto out_free; + } + ctx->decomp_initialized = 1; +out: + return ret; +out_free: + kfree(stream->workspace); + goto out; +} + +static int deflate_compress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + int ret = 0; + struct deflate_ctx *dctx = ctx; + struct z_stream_s *stream = &dctx->comp_stream; + + if (!dctx->comp_initialized) { + ret = deflate_comp_init(dctx); + if (ret) + goto out; + } + + ret = zlib_deflateReset(stream); + if (ret != Z_OK) { + ret = -EINVAL; + goto out; + } + + stream->next_in = (u8 *)src; + stream->avail_in = slen; + stream->next_out = (u8 *)dst; + stream->avail_out = *dlen; + + ret = zlib_deflate(stream, Z_FINISH); + if (ret != Z_STREAM_END) { + ret = -EINVAL; + goto out; + } + ret = 0; + *dlen = stream->total_out; +out: + return ret; +} + +static int deflate_decompress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + + int ret = 0; + struct deflate_ctx *dctx = ctx; + struct z_stream_s *stream = &dctx->decomp_stream; + + if (!dctx->decomp_initialized) { + ret = deflate_decomp_init(dctx); + if (ret) + goto out; + } + + ret = zlib_inflateReset(stream); + if (ret != Z_OK) { + ret = -EINVAL; + goto out; + } + + stream->next_in = (u8 *)src; + stream->avail_in = slen; + stream->next_out = (u8 *)dst; + stream->avail_out = *dlen; + + ret = zlib_inflate(stream, Z_FINISH); + if (ret != Z_STREAM_END) { + ret = -EINVAL; + goto out; + } + ret = 0; + *dlen = stream->total_out; +out: + return ret; +} + +static struct crypto_alg alg = { + .cra_name = "deflate", + .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, + .cra_ctxsize = sizeof(struct deflate_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .compress = { + .coa_init = deflate_init, + .coa_exit = deflate_exit, + .coa_compress = deflate_compress, + .coa_decompress = deflate_decompress } } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP"); +MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); + diff --git a/crypto/digest.c b/crypto/digest.c index e82470a472be..a62327d3c37b 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -61,7 +61,7 @@ static void digest(struct crypto_tfm *tfm, int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) { - return crypto_cipher_flags(flags) ? -EINVAL : 0; + return flags ? -EINVAL : 0; } int crypto_init_digest_ops(struct crypto_tfm *tfm) diff --git a/crypto/internal.h b/crypto/internal.h index a19fdb1de503..b67c0ee8fe54 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -41,11 +41,6 @@ static inline void crypto_yield(struct crypto_tfm *tfm) cond_resched(); } -static inline u32 crypto_cipher_flags(u32 flags) -{ - return flags & (CRYPTO_TFM_MODE_MASK|CRYPTO_TFM_REQ_WEAK_KEY); -} - static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) { return (void *)&tfm[1]; diff --git a/crypto/proc.c b/crypto/proc.c index f51a3ccf52db..124a3a270938 100644 --- a/crypto/proc.c +++ b/crypto/proc.c @@ -54,10 +54,10 @@ static int c_show(struct seq_file *m, void *p) seq_printf(m, "name : %s\n", alg->cra_name); seq_printf(m, "module : %s\n", module_name(alg->cra_module)); - seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { case CRYPTO_ALG_TYPE_CIPHER: + seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); seq_printf(m, "min keysize : %u\n", alg->cra_cipher.cia_min_keysize); seq_printf(m, "max keysize : %u\n", @@ -67,6 +67,7 @@ static int c_show(struct seq_file *m, void *p) break; case CRYPTO_ALG_TYPE_DIGEST: + seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); seq_printf(m, "digestsize : %u\n", alg->cra_digest.dia_digestsize); break; diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index a45e574528f7..c2a513c2de66 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -48,7 +48,7 @@ static char *tvmem; static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", - "twofish", "serpent", "sha384", "sha512", "md4", "aes", + "twofish", "serpent", "sha384", "sha512", "md4", "aes", "deflate", NULL }; @@ -2193,6 +2193,86 @@ out: } static void +test_deflate(void) +{ + unsigned int i; + char result[COMP_BUF_SIZE]; + struct crypto_tfm *tfm; + struct comp_testvec *tv; + unsigned int tsize; + + printk("\ntesting deflate compression\n"); + + tsize = sizeof (deflate_comp_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + return; + } + + memcpy(tvmem, deflate_comp_tv_template, tsize); + tv = (void *) tvmem; + + tfm = crypto_alloc_tfm("deflate", 0); + if (tfm == NULL) { + printk("failed to load transform for deflate\n"); + return; + } + + for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) { + int ilen, ret, dlen = COMP_BUF_SIZE; + + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + ilen = tv[i].inlen; + ret = crypto_comp_compress(tfm, tv[i].input, + ilen, result, &dlen); + if (ret) { + printk("fail: ret=%d\n", ret); + continue; + } + hexdump(result, dlen); + printk("%s (ratio %d:%d)\n", + memcmp(result, tv[i].output, dlen) ? "fail" : "pass", + ilen, dlen); + } + + printk("\ntesting deflate decompression\n"); + + tsize = sizeof (deflate_decomp_tv_template); + if (tsize > TVMEMSIZE) { + printk("template (%u) too big for tvmem (%u)\n", tsize, + TVMEMSIZE); + goto out; + } + + memcpy(tvmem, deflate_decomp_tv_template, tsize); + tv = (void *) tvmem; + + for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) { + int ilen, ret, dlen = COMP_BUF_SIZE; + + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); + + ilen = tv[i].inlen; + ret = crypto_comp_decompress(tfm, tv[i].input, + ilen, result, &dlen); + if (ret) { + printk("fail: ret=%d\n", ret); + continue; + } + hexdump(result, dlen); + printk("%s (ratio %d:%d)\n", + memcmp(result, tv[i].output, dlen) ? "fail" : "pass", + ilen, dlen); + } +out: + crypto_free_tfm(tfm); +} + +static void test_available(void) { char **name = check; @@ -2223,6 +2303,7 @@ do_test(void) test_aes(); test_sha384(); test_sha512(); + test_deflate(); #ifdef CONFIG_CRYPTO_HMAC test_hmac_md5(); test_hmac_sha1(); @@ -2278,6 +2359,10 @@ do_test(void) test_sha512(); break; + case 13: + test_deflate(); + break; + #ifdef CONFIG_CRYPTO_HMAC case 100: test_hmac_md5(); diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h index b8e328e90545..35419e458116 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h @@ -1682,4 +1682,104 @@ struct aes_tv aes_dec_tv_template[] = { }, }; +/* + * Compression stuff. + */ +#define COMP_BUF_SIZE 512 + +struct comp_testvec { + int inlen, outlen; + char input[COMP_BUF_SIZE]; + char output[COMP_BUF_SIZE]; +}; + +/* + * Deflate test vectors (null-terminated strings). + * Params: winbits=11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL. + */ +#define DEFLATE_COMP_TEST_VECTORS 2 +#define DEFLATE_DECOMP_TEST_VECTORS 2 + +struct comp_testvec deflate_comp_tv_template[] = { + { + 70, 38, + + "Join us now and share the software " + "Join us now and share the software ", + + { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56, + 0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51, + 0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9, + 0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07, + 0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 + }, + }, + + { + 191, 122, + + "This document describes a compression method based on the DEFLATE" + "compression algorithm. This document defines the application of " + "the DEFLATE algorithm to the IP Payload Compression Protocol.", + + { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04, + 0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09, + 0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8, + 0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49, + 0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27, + 0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2, + 0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad, + 0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4, + 0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b, + 0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f, + 0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf, + 0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02, + 0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98, + 0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a, + 0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79, + 0xfa, 0x02 }, + }, +}; + +struct comp_testvec deflate_decomp_tv_template[] = { + { + 122, 191, + + { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04, + 0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09, + 0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8, + 0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49, + 0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27, + 0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2, + 0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad, + 0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4, + 0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b, + 0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f, + 0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf, + 0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02, + 0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98, + 0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a, + 0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79, + 0xfa, 0x02 }, + + "This document describes a compression method based on the DEFLATE" + "compression algorithm. This document defines the application of " + "the DEFLATE algorithm to the IP Payload Compression Protocol.", + }, + + { + 38, 70, + + { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56, + 0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51, + 0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9, + 0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07, + 0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 + }, + + "Join us now and share the software " + "Join us now and share the software ", + }, +}; + #endif /* _CRYPTO_TCRYPT_H */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 7d9ab385a1ab..647058a6397a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2262,7 +2262,7 @@ config PPP_MULTILINK config PPP_FILTER bool "PPP filtering" - depends on PPP && FILTER + depends on PPP help Say Y here if you want to be able to filter the packets passing over PPP interfaces. This allows you to control which packets count as diff --git a/include/linux/crypto.h b/include/linux/crypto.h index e7c775fb160a..07820d52922d 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -31,7 +31,6 @@ #define CRYPTO_ALG_TYPE_DIGEST 0x00000002 #define CRYPTO_ALG_TYPE_COMPRESS 0x00000004 - /* * Transform masks and values (for crt_flags). */ @@ -45,14 +44,12 @@ #define CRYPTO_TFM_MODE_CTR 0x00000008 #define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 - #define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 #define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 #define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 #define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000 #define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000 - /* * Miscellaneous stuff. */ @@ -83,8 +80,12 @@ struct digest_alg { }; struct compress_alg { - void (*coa_compress)(void); - void (*coa_decompress)(void); + int (*coa_init)(void *ctx); + void (*coa_exit)(void *ctx); + int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); + int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); }; #define cra_cipher cra_u.cipher @@ -162,8 +163,12 @@ struct digest_tfm { }; struct compress_tfm { - void (*cot_compress)(struct crypto_tfm *tfm); - void (*cot_decompress)(struct crypto_tfm *tfm); + int (*cot_compress)(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); + int (*cot_decompress)(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); }; #define crt_cipher crt_u.cipher @@ -336,16 +341,20 @@ static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm, memcpy(dst, tfm->crt_cipher.cit_iv, len); } -static inline void crypto_comp_compress(struct crypto_tfm *tfm) +static inline int crypto_comp_compress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); - tfm->crt_compress.cot_compress(tfm); + return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen); } -static inline void crypto_comp_decompress(struct crypto_tfm *tfm) +static inline int crypto_comp_decompress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); - tfm->crt_compress.cot_decompress(tfm); + return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen); } /* diff --git a/include/net/protocol.h b/include/net/protocol.h index f2b31f62312d..6f493c4a23cc 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -50,6 +50,7 @@ struct inet6_protocol struct inet6_skb_parm *opt, int type, int code, int offset, __u32 info); + int no_policy; }; #endif diff --git a/include/net/sock.h b/include/net/sock.h index df20f44552bf..6235779cc456 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -48,9 +48,7 @@ #include <linux/skbuff.h> /* struct sk_buff */ #include <linux/security.h> -#ifdef CONFIG_FILTER #include <linux/filter.h> -#endif #include <asm/atomic.h> #include <net/dst.h> @@ -174,10 +172,8 @@ struct sock { long rcvtimeo; long sndtimeo; -#ifdef CONFIG_FILTER /* Socket Filtering Instructions */ struct sk_filter *filter; -#endif /* CONFIG_FILTER */ /* This is where all the private (optional) areas that don't * overlap will eventually live. @@ -456,8 +452,6 @@ extern void sock_def_destruct(struct sock *); /* Initialise core socket variables */ extern void sock_init_data(struct socket *sock, struct sock *sk); -#ifdef CONFIG_FILTER - /** * __sk_filter - run a packet through a socket filter * @sk: sock associated with &sk_buff @@ -524,15 +518,6 @@ static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) atomic_add(sk_filter_len(fp), &sk->omem_alloc); } -#else - -static inline int __sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) -{ - return 0; -} - -#endif /* CONFIG_FILTER */ - static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) { int err; diff --git a/lib/Kconfig b/lib/Kconfig index 918ab1dfec25..1203bd92136c 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -17,13 +17,14 @@ config CRC32 # config ZLIB_INFLATE tristate - default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y - default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m + default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y || CRYPTO_DEFLATE=y + default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m || CRYPTO_DEFLATE=m config ZLIB_DEFLATE tristate - default m if PPP_DEFLATE!=y && JFFS2_FS!=y && (PPP_DEFLATE=m || JFFS2_FS=m) - default y if PPP_DEFLATE=y || JFFS2_FS=y + default m if PPP_DEFLATE!=y && JFFS2_FS!=y && CRYPTO_DEFLATE!=y && \ + (PPP_DEFLATE=m || JFFS2_FS=m || CRYPTO_DEFLATE=m) + default y if PPP_DEFLATE=y || JFFS2_FS=y || CRYPTO_DEFLATE=y endmenu diff --git a/net/Kconfig b/net/Kconfig index f5cf59c91665..d791c61fcc61 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -118,22 +118,6 @@ config NETFILTER_DEBUG You can say Y here if you want to get additional messages useful in debugging the netfilter code. -config FILTER - bool "Socket Filtering" - ---help--- - The Linux Socket Filter is derived from the Berkeley Packet Filter. - If you say Y here, user-space programs can attach a filter to any - socket and thereby tell the kernel that it should allow or disallow - certain types of data to get through the socket. Linux Socket - Filtering works on all socket types except TCP for now. See the - text file <file:Documentation/networking/filter.txt> for more - information. - - You need to say Y here if you want to use PPP packet filtering - (see the CONFIG_PPP_FILTER option below). - - If unsure, say N. - config UNIX tristate "Unix domain sockets" ---help--- diff --git a/net/core/Makefile b/net/core/Makefile index ffbb63e471a4..b9fc9654b14f 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -10,9 +10,7 @@ obj-y += sysctl_net_core.o endif endif -obj-$(CONFIG_FILTER) += filter.o - -obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o rtnetlink.o utils.o link_watch.o +obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o rtnetlink.o utils.o link_watch.o filter.o obj-$(CONFIG_NETFILTER) += netfilter.o obj-$(CONFIG_NET_DIVERT) += dv.o diff --git a/net/core/filter.c b/net/core/filter.c index bfa23ac6348e..0ad6dc93d7ec 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -15,9 +15,6 @@ * Andi Kleen - Fix a few bad bugs and races. */ -#include <linux/config.h> -#if defined(CONFIG_FILTER) - #include <linux/module.h> #include <linux/types.h> #include <linux/sched.h> @@ -495,4 +492,3 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) return (err); } -#endif /* CONFIG_FILTER */ diff --git a/net/core/sock.c b/net/core/sock.c index da9bfa3ac520..7e7bf7a9ad84 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -119,9 +119,7 @@ #include <net/sock.h> #include <linux/ipsec.h> -#ifdef CONFIG_FILTER #include <linux/filter.h> -#endif #ifdef CONFIG_INET #include <net/tcp.h> @@ -168,9 +166,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) { struct sock *sk=sock->sk; -#ifdef CONFIG_FILTER struct sk_filter *filter; -#endif int val; int valbool; struct linger ling; @@ -381,7 +377,6 @@ int sock_setsockopt(struct socket *sock, int level, int optname, #endif -#ifdef CONFIG_FILTER case SO_ATTACH_FILTER: ret = -EINVAL; if (optlen == sizeof(struct sock_fprog)) { @@ -407,7 +402,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, spin_unlock_bh(&sk->lock.slock); ret = -ENONET; break; -#endif + /* We implement the SO_SNDLOWAT etc to not be settable (1003.1g 5.3) */ default: @@ -614,20 +609,16 @@ struct sock *sk_alloc(int family, int priority, int zero_it, kmem_cache_t *slab) void sk_free(struct sock *sk) { -#ifdef CONFIG_FILTER struct sk_filter *filter; -#endif if (sk->destruct) sk->destruct(sk); -#ifdef CONFIG_FILTER filter = sk->filter; if (filter) { sk_filter_release(sk, filter); sk->filter = NULL; } -#endif if (atomic_read(&sk->omem_alloc)) printk(KERN_DEBUG "sk_free: optmem leakage (%d bytes) detected.\n", atomic_read(&sk->omem_alloc)); diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index ef70735bbebc..f493a21f2f82 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -645,9 +645,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, if(newsk != NULL) { struct tcp_opt *newtp; -#ifdef CONFIG_FILTER struct sk_filter *filter; -#endif memcpy(newsk, sk, sizeof(struct tcp_sock)); newsk->state = TCP_SYN_RECV; @@ -677,10 +675,10 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, newsk->callback_lock = RW_LOCK_UNLOCKED; skb_queue_head_init(&newsk->error_queue); newsk->write_space = tcp_write_space; -#ifdef CONFIG_FILTER + if ((filter = newsk->filter) != NULL) sk_filter_charge(newsk, filter); -#endif + if (unlikely(xfrm_sk_clone_policy(newsk))) { /* It is still raw copy of parent, so invalidate * destructor and make plain sk_free() */ diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 1be52464ff65..29212d8160f2 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -951,7 +951,6 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) return -1; } -#if defined(CONFIG_FILTER) if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) { if (__udp_checksum_complete(skb)) { UDP_INC_STATS_BH(UdpInErrors); @@ -960,7 +959,6 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) } skb->ip_summed = CHECKSUM_UNNECESSARY; } -#endif if (sock_queue_rcv_skb(sk,skb)<0) { UDP_INC_STATS_BH(UdpInErrors); diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index e35069d8e75d..f1c7436efb14 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -199,7 +199,7 @@ int ah6_input(struct xfrm_state *x, struct sk_buff *skb) } } - nexthdr = ah->nexthdr; + nexthdr = ((struct ipv6hdr*)tmp_hdr)->nexthdr = ah->nexthdr; skb->nh.raw = skb_pull(skb, (ah->hdrlen+2)<<2); memcpy(skb->nh.raw, tmp_hdr, hdr_len); skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); @@ -287,7 +287,7 @@ static int ah6_init_state(struct xfrm_state *x, void *args) x->props.header_len = XFRM_ALIGN8(ahp->icv_trunc_len + AH_HLEN_NOICV); if (x->props.mode) - x->props.header_len += 20; + x->props.header_len += 40; x->data = ahp; return 0; @@ -330,6 +330,7 @@ static struct xfrm_type ah6_type = static struct inet6_protocol ah6_protocol = { .handler = xfrm6_rcv, .err_handler = ah6_err, + .no_policy = 1, }; int __init ah6_init(void) diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 19450a5025d2..fdc88cc1ea58 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -108,7 +108,7 @@ int esp6_output(struct sk_buff *skb) struct dst_entry *dst = skb->dst; struct xfrm_state *x = dst->xfrm; struct ipv6hdr *iph = NULL, *top_iph; - struct ip_esp_hdr *esph; + struct ipv6_esp_hdr *esph; struct crypto_tfm *tfm; struct esp_data *esp; struct sk_buff *trailer; @@ -154,7 +154,7 @@ int esp6_output(struct sk_buff *skb) esp = x->data; alen = esp->auth.icv_trunc_len; tfm = esp->conf.tfm; - blksize = crypto_tfm_alg_blocksize(tfm); + blksize = (crypto_tfm_alg_blocksize(tfm) + 3) & ~3; clen = (clen + 2 + blksize-1)&~(blksize-1); if (esp->conf.padlen) clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1); @@ -176,7 +176,7 @@ int esp6_output(struct sk_buff *skb) if (x->props.mode) { iph = skb->nh.ipv6h; top_iph = (struct ipv6hdr*)skb_push(skb, x->props.header_len); - esph = (struct ip_esp_hdr*)(top_iph+1); + esph = (struct ipv6_esp_hdr*)(top_iph+1); *(u8*)(trailer->tail - 1) = IPPROTO_IPV6; top_iph->version = 6; top_iph->priority = iph->priority; @@ -184,13 +184,13 @@ int esp6_output(struct sk_buff *skb) top_iph->flow_lbl[1] = iph->flow_lbl[1]; top_iph->flow_lbl[2] = iph->flow_lbl[2]; top_iph->nexthdr = IPPROTO_ESP; - top_iph->payload_len = htons(skb->len + alen); + top_iph->payload_len = htons(skb->len + alen - sizeof(struct ipv6hdr)); top_iph->hop_limit = iph->hop_limit; - memcpy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr, sizeof(struct ipv6hdr)); - memcpy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr, sizeof(struct ipv6hdr)); + memcpy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr, sizeof(struct in6_addr)); + memcpy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr, sizeof(struct in6_addr)); } else { /* XXX exthdr */ - esph = (struct ip_esp_hdr*)skb_push(skb, x->props.header_len); + esph = (struct ipv6_esp_hdr*)skb_push(skb, x->props.header_len); skb->h.raw = (unsigned char*)esph; top_iph = (struct ipv6hdr*)skb_push(skb, hdr_len); memcpy(top_iph, iph, hdr_len); @@ -257,7 +257,7 @@ error_nolock: int esp6_input(struct xfrm_state *x, struct sk_buff *skb) { struct ipv6hdr *iph; - struct ip_esp_hdr *esph; + struct ipv6_esp_hdr *esph; struct esp_data *esp = x->data; struct sk_buff *trailer; int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm); @@ -269,7 +269,7 @@ int esp6_input(struct xfrm_state *x, struct sk_buff *skb) u8 ret_nexthdr = 0; unsigned char *tmp_hdr = NULL; - if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) + if (!pskb_may_pull(skb, sizeof(struct ipv6_esp_hdr))) goto out; if (elen <= 0 || (elen & (blksize-1))) @@ -301,7 +301,7 @@ int esp6_input(struct xfrm_state *x, struct sk_buff *skb) skb->ip_summed = CHECKSUM_NONE; - esph = (struct ip_esp_hdr*)skb->data; + esph = (struct ipv6_esp_hdr*)skb->data; iph = skb->nh.ipv6h; /* Get ivec. This can be wrong, check against another impls. */ @@ -336,7 +336,7 @@ int esp6_input(struct xfrm_state *x, struct sk_buff *skb) } /* ... check padding bits here. Silly. :-) */ - ret_nexthdr = nexthdr[1]; + ret_nexthdr = ((struct ipv6hdr*)tmp_hdr)->nexthdr = nexthdr[1]; pskb_trim(skb, skb->len - alen - padlen - 2); skb->h.raw = skb_pull(skb, 8 + esp->conf.ivlen); skb->nh.raw += 8 + esp->conf.ivlen; @@ -370,7 +370,7 @@ void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, int type, int code, int offset, __u32 info) { struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; - struct ip_esp_hdr *esph = (struct ip_esp_hdr*)(skb->data+offset); + struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset); struct xfrm_state *x; if (type != ICMPV6_DEST_UNREACH || @@ -416,7 +416,7 @@ int esp6_init_state(struct xfrm_state *x, void *args) if (x->aalg->alg_key_len == 0 || x->aalg->alg_key_len > 512) goto error; } - if (x->ealg == NULL || x->ealg->alg_key_len == 0) + if (x->ealg == NULL) goto error; esp = kmalloc(sizeof(*esp), GFP_KERNEL); @@ -499,6 +499,7 @@ static struct xfrm_type esp6_type = static struct inet6_protocol esp6_protocol = { .handler = xfrm6_rcv, .err_handler = esp6_err, + .no_policy = 1, }; int __init esp6_init(void) diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 810c302cb387..ed8efd6a3822 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -43,6 +43,7 @@ #include <net/ndisc.h> #include <net/ip6_route.h> #include <net/addrconf.h> +#include <net/xfrm.h> @@ -149,7 +150,14 @@ resubmit: hash = nexthdr & (MAX_INET_PROTOS - 1); if ((ipprot = inet6_protos[hash]) != NULL) { - int ret = ipprot->handler(&skb); + int ret; + + if (!ipprot->no_policy && + !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { + kfree_skb(skb); + return 0; + } + ret = ipprot->handler(&skb); if (ret < 0) { nexthdr = -ret; goto resubmit; @@ -157,9 +165,11 @@ resubmit: IP6_INC_STATS_BH(Ip6InDelivers); } else { if (!raw_sk) { - IP6_INC_STATS_BH(Ip6InUnknownProtos); - icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, - offsetof(struct ipv6hdr, nexthdr)); + if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { + IP6_INC_STATS_BH(Ip6InUnknownProtos); + icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, + offsetof(struct ipv6hdr, nexthdr)); + } } else { IP6_INC_STATS_BH(Ip6InDelivers); kfree_skb(skb); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 02206d65a768..9fe6459d4a29 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -50,6 +50,7 @@ #include <net/addrconf.h> #include <net/rawv6.h> #include <net/icmp.h> +#include <net/xfrm.h> static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr) { @@ -747,6 +748,9 @@ int ip6_forward(struct sk_buff *skb) if (ipv6_devconf.forwarding == 0) goto error; + if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) + goto drop; + skb->ip_summed = CHECKSUM_NONE; /* @@ -781,6 +785,9 @@ int ip6_forward(struct sk_buff *skb) return -ETIMEDOUT; } + if (!xfrm6_route_forward(skb)) + goto drop; + /* IPv6 specs say nothing about it, but it is clear that we cannot send redirects to source routed frames. */ diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 296d333795c5..2615647db316 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -273,7 +273,6 @@ void rawv6_err(struct sock *sk, struct sk_buff *skb, static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) { -#if defined(CONFIG_FILTER) if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) { if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) { /* FIXME: increment a raw6 drops counter here */ @@ -282,7 +281,7 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) } skb->ip_summed = CHECKSUM_UNNECESSARY; } -#endif + /* Charge it to the socket. */ if (sock_queue_rcv_skb(sk,skb)<0) { /* FIXME: increment a raw6 drops counter here */ diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 95e98d2df1af..64fc399d0708 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -2193,6 +2193,7 @@ struct proto tcpv6_prot = { static struct inet6_protocol tcpv6_protocol = { .handler = tcp_v6_rcv, .err_handler = tcp_v6_err, + .no_policy = 1, }; extern struct proto_ops inet6_stream_ops; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index f84c94ca4edb..9632131bb34a 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -547,7 +547,6 @@ static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) return -1; } -#if defined(CONFIG_FILTER) if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) { if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) { UDP6_INC_STATS_BH(UdpInErrors); @@ -556,7 +555,7 @@ static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) } skb->ip_summed = CHECKSUM_UNNECESSARY; } -#endif + if (sock_queue_rcv_skb(sk,skb)<0) { UDP6_INC_STATS_BH(UdpInErrors); kfree_skb(skb); @@ -955,6 +954,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg static struct inet6_protocol udpv6_protocol = { .handler = udpv6_rcv, .err_handler = udpv6_err, + .no_policy = 1, }; #define LINE_LEN 190 diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index ba453ac35bd5..6cad1a2c4c59 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -186,6 +186,8 @@ int xfrm6_rcv(struct sk_buff **pskb) xfrm_vec[xfrm_nr++] = x; + iph = skb->nh.ipv6h; + if (x->props.mode) { /* XXX */ if (iph->nexthdr != IPPROTO_IPV6) goto drop; @@ -199,9 +201,11 @@ int xfrm6_rcv(struct sk_buff **pskb) goto drop; } while (!err); - memcpy(skb->nh.raw, tmp_hdr, hdr_len); - skb->nh.raw[nh_offset] = nexthdr; - skb->nh.ipv6h->payload_len = htons(hdr_len + skb->len - sizeof(struct ipv6hdr)); + if (!decaps) { + memcpy(skb->nh.raw, tmp_hdr, hdr_len); + skb->nh.raw[nh_offset] = nexthdr; + skb->nh.ipv6h->payload_len = htons(hdr_len + skb->len - sizeof(struct ipv6hdr)); + } /* Allocate new secpath or COW existing one. */ if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) { diff --git a/net/netsyms.c b/net/netsyms.c index 195e6ee803d6..56db7f1ca615 100644 --- a/net/netsyms.c +++ b/net/netsyms.c @@ -171,10 +171,8 @@ EXPORT_SYMBOL(sock_kfree_s); EXPORT_SYMBOL(sock_map_fd); EXPORT_SYMBOL(sockfd_lookup); -#ifdef CONFIG_FILTER EXPORT_SYMBOL(sk_run_filter); EXPORT_SYMBOL(sk_chk_filter); -#endif EXPORT_SYMBOL(neigh_table_init); EXPORT_SYMBOL(neigh_table_clear); diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 86d20f6852a1..c0b3bcf55d8d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -401,9 +401,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packe struct packet_opt *po; u8 * skb_head = skb->data; int skb_len = skb->len; -#ifdef CONFIG_FILTER unsigned snaplen; -#endif if (skb->pkt_type == PACKET_LOOPBACK) goto drop; @@ -429,7 +427,6 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packe } } -#ifdef CONFIG_FILTER snaplen = skb->len; if (sk->filter) { @@ -446,7 +443,6 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packe if (snaplen > res) snaplen = res; } -#endif /* CONFIG_FILTER */ if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) goto drop_n_acct; @@ -475,10 +471,8 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packe if (dev->hard_header_parse) sll->sll_halen = dev->hard_header_parse(skb, sll->sll_addr); -#ifdef CONFIG_FILTER if (pskb_trim(skb, snaplen)) goto drop_n_acct; -#endif skb_set_owner_r(skb, sk); skb->dev = NULL; @@ -494,9 +488,7 @@ drop_n_acct: po->stats.tp_drops++; spin_unlock(&sk->receive_queue.lock); -#ifdef CONFIG_FILTER drop_n_restore: -#endif if (skb_head != skb->data && skb_shared(skb)) { skb->data = skb_head; skb->len = skb_len; @@ -539,7 +531,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct pack snaplen = skb->len; -#ifdef CONFIG_FILTER if (sk->filter) { unsigned res = snaplen; struct sk_filter *filter; @@ -554,7 +545,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct pack if (snaplen > res) snaplen = res; } -#endif if (sk->type == SOCK_DGRAM) { macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index f19d625f7d3b..17604c139456 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -680,6 +680,7 @@ static int sctp6_rcv(struct sk_buff **pskb) static struct inet6_protocol sctpv6_protocol = { .handler = sctp6_rcv, .err_handler = sctp_v6_err, + .no_policy = 1, }; static struct sctp_af sctp_ipv6_specific = { diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index a1c98e3618cc..3ac1a6aabdf5 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -776,6 +776,7 @@ static struct inet_protosw sctp_stream_protosw = { static struct inet_protocol sctp_protocol = { .handler = sctp_rcv, .err_handler = sctp_v4_err, + .no_policy = 1, }; /* IPv4 address related functions. */ |
