Commit 7b8dd6a0 authored by David S. Miller's avatar David S. Miller

Merge davem@nuts.davemloft.net:/disk1/BK/net-2.6

into kernel.bkbits.net:/home/davem/net-2.6
parents ed407526 684a493b
...@@ -187,6 +187,7 @@ Original developers of the crypto algorithms: ...@@ -187,6 +187,7 @@ Original developers of the crypto algorithms:
Brian Gladman (AES) Brian Gladman (AES)
Kartikey Mahendra Bhatt (CAST6) Kartikey Mahendra Bhatt (CAST6)
Jon Oberheide (ARC4) Jon Oberheide (ARC4)
Jouni Malinen (Michael MIC)
SHA1 algorithm contributors: SHA1 algorithm contributors:
Jean-Francois Dive Jean-Francois Dive
......
...@@ -161,6 +161,15 @@ config CRYPTO_DEFLATE ...@@ -161,6 +161,15 @@ config CRYPTO_DEFLATE
You will most probably want this if using IPSec. You will most probably want this if using IPSec.
config CRYPTO_MICHAEL_MIC
tristate "Michael MIC keyed digest algorithm"
depends on CRYPTO
help
Michael MIC is used for message integrity protection in TKIP
(IEEE 802.11i). This algorithm is required for TKIP, but it
should not be used for other purposes because of the weakness
of the algorithm.
config CRYPTO_TEST config CRYPTO_TEST
tristate "Testing module" tristate "Testing module"
depends on CRYPTO depends on CRYPTO
......
...@@ -23,5 +23,6 @@ obj-$(CONFIG_CRYPTO_CAST5) += cast5.o ...@@ -23,5 +23,6 @@ obj-$(CONFIG_CRYPTO_CAST5) += cast5.o
obj-$(CONFIG_CRYPTO_CAST6) += cast6.o obj-$(CONFIG_CRYPTO_CAST6) += cast6.o
obj-$(CONFIG_CRYPTO_ARC4) += arc4.o obj-$(CONFIG_CRYPTO_ARC4) += arc4.o
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
...@@ -45,10 +45,6 @@ static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u ...@@ -45,10 +45,6 @@ static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u
k = 0; k = 0;
} }
/* TODO: dump the first 768 bytes generated as recommended
by Ilya Mironov (http://eprint.iacr.org/2002/067/) to
increase the statistical strength of the state table */
return 0; return 0;
} }
......
...@@ -42,6 +42,15 @@ static void final(struct crypto_tfm *tfm, u8 *out) ...@@ -42,6 +42,15 @@ static void final(struct crypto_tfm *tfm, u8 *out)
tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out);
} }
static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
{
u32 flags;
if (tfm->__crt_alg->cra_digest.dia_setkey == NULL)
return -ENOSYS;
return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm),
key, keylen, &flags);
}
static void digest(struct crypto_tfm *tfm, static void digest(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg, u8 *out) struct scatterlist *sg, unsigned int nsg, u8 *out)
{ {
...@@ -72,6 +81,7 @@ int crypto_init_digest_ops(struct crypto_tfm *tfm) ...@@ -72,6 +81,7 @@ int crypto_init_digest_ops(struct crypto_tfm *tfm)
ops->dit_update = update; ops->dit_update = update;
ops->dit_final = final; ops->dit_final = final;
ops->dit_digest = digest; ops->dit_digest = digest;
ops->dit_setkey = setkey;
return crypto_alloc_hmac_block(tfm); return crypto_alloc_hmac_block(tfm);
} }
......
/*
* Cryptographic API
*
* Michael MIC (IEEE 802.11i/TKIP) keyed digest
*
* Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/crypto.h>
struct michael_mic_ctx {
u8 pending[4];
size_t pending_len;
u32 l, r;
};
static inline u32 rotl(u32 val, int bits)
{
return (val << bits) | (val >> (32 - bits));
}
static inline u32 rotr(u32 val, int bits)
{
return (val >> bits) | (val << (32 - bits));
}
static inline u32 xswap(u32 val)
{
return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
}
#define michael_block(l, r) \
do { \
r ^= rotl(l, 17); \
l += r; \
r ^= xswap(l); \
l += r; \
r ^= rotl(l, 3); \
l += r; \
r ^= rotr(l, 2); \
l += r; \
} while (0)
static inline u32 get_le32(const u8 *p)
{
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
}
static inline void put_le32(u8 *p, u32 v)
{
p[0] = v;
p[1] = v >> 8;
p[2] = v >> 16;
p[3] = v >> 24;
}
static void michael_init(void *ctx)
{
struct michael_mic_ctx *mctx = ctx;
mctx->pending_len = 0;
}
static void michael_update(void *ctx, const u8 *data, unsigned int len)
{
struct michael_mic_ctx *mctx = ctx;
if (mctx->pending_len) {
int flen = 4 - mctx->pending_len;
if (flen > len)
flen = len;
memcpy(&mctx->pending[mctx->pending_len], data, flen);
mctx->pending_len += flen;
data += flen;
len -= flen;
if (mctx->pending_len < 4)
return;
mctx->l ^= get_le32(mctx->pending);
michael_block(mctx->l, mctx->r);
mctx->pending_len = 0;
}
while (len >= 4) {
mctx->l ^= get_le32(data);
michael_block(mctx->l, mctx->r);
data += 4;
len -= 4;
}
if (len > 0) {
mctx->pending_len = len;
memcpy(mctx->pending, data, len);
}
}
static void michael_final(void *ctx, u8 *out)
{
struct michael_mic_ctx *mctx = ctx;
u8 *data = mctx->pending;
/* Last block and padding (0x5a, 4..7 x 0) */
switch (mctx->pending_len) {
case 0:
mctx->l ^= 0x5a;
break;
case 1:
mctx->l ^= data[0] | 0x5a00;
break;
case 2:
mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000;
break;
case 3:
mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) |
0x5a000000;
break;
}
michael_block(mctx->l, mctx->r);
/* l ^= 0; */
michael_block(mctx->l, mctx->r);
put_le32(out, mctx->l);
put_le32(out + 4, mctx->r);
}
static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen,
u32 *flags)
{
struct michael_mic_ctx *mctx = ctx;
if (keylen != 8) {
if (flags)
*flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
mctx->l = get_le32(key);
mctx->r = get_le32(key + 4);
return 0;
}
static struct crypto_alg michael_mic_alg = {
.cra_name = "michael_mic",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = 8,
.cra_ctxsize = sizeof(struct michael_mic_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list),
.cra_u = { .digest = {
.dia_digestsize = 8,
.dia_init = michael_init,
.dia_update = michael_update,
.dia_final = michael_final,
.dia_setkey = michael_setkey } }
};
static int __init michael_mic_init(void)
{
return crypto_register_alg(&michael_mic_alg);
}
static void __exit michael_mic_exit(void)
{
crypto_unregister_alg(&michael_mic_alg);
}
module_init(michael_mic_init);
module_exit(michael_mic_exit);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Michael MIC");
MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>");
...@@ -61,7 +61,7 @@ static char *tvmem; ...@@ -61,7 +61,7 @@ static char *tvmem;
static char *check[] = { static char *check[] = {
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
"arc4", "deflate", NULL "arc4", "michael_mic", "deflate", NULL
}; };
static void static void
...@@ -112,6 +112,10 @@ test_hash (char * algo, struct hash_testvec * template, unsigned int tcount) ...@@ -112,6 +112,10 @@ test_hash (char * algo, struct hash_testvec * template, unsigned int tcount)
sg[0].length = hash_tv[i].psize; 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_update (tfm, sg, 1); crypto_digest_update (tfm, sg, 1);
crypto_digest_final (tfm, result); crypto_digest_final (tfm, result);
...@@ -568,6 +572,8 @@ do_test(void) ...@@ -568,6 +572,8 @@ do_test(void)
test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
#endif #endif
test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
break; break;
case 1: case 1:
...@@ -647,6 +653,10 @@ do_test(void) ...@@ -647,6 +653,10 @@ do_test(void)
test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS);
break; break;
case 17:
test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
break;
#ifdef CONFIG_CRYPTO_HMAC #ifdef CONFIG_CRYPTO_HMAC
case 100: case 100:
test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
......
...@@ -30,6 +30,8 @@ struct hash_testvec { ...@@ -30,6 +30,8 @@ struct hash_testvec {
char digest[MAX_DIGEST_SIZE]; char digest[MAX_DIGEST_SIZE];
unsigned char np; unsigned char np;
unsigned char tap[MAX_TAP]; unsigned char tap[MAX_TAP];
char key[128]; /* only used with keyed hash algorithms */
unsigned char ksize;
}; };
struct hmac_testvec { struct hmac_testvec {
...@@ -1719,4 +1721,54 @@ struct comp_testvec deflate_decomp_tv_template[] = { ...@@ -1719,4 +1721,54 @@ struct comp_testvec deflate_decomp_tv_template[] = {
}, },
}; };
/*
* Michael MIC test vectors from IEEE 802.11i
*/
#define MICHAEL_MIC_TEST_VECTORS 6
struct hash_testvec michael_mic_tv_template[] =
{
{
.key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
.ksize = 8,
.plaintext = { },
.psize = 0,
.digest = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 }
},
{
.key = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 },
.ksize = 8,
.plaintext = { 'M' },
.psize = 1,
.digest = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f }
},
{
.key = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f },
.ksize = 8,
.plaintext = { 'M', 'i' },
.psize = 2,
.digest = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 }
},
{
.key = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 },
.ksize = 8,
.plaintext = { 'M', 'i', 'c' },
.psize = 3,
.digest = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb }
},
{
.key = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb },
.ksize = 8,
.plaintext = { 'M', 'i', 'c', 'h' },
.psize = 4,
.digest = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 }
},
{
.key = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 },
.ksize = 8,
.plaintext = { 'M', 'i', 'c', 'h', 'a', 'e', 'l' },
.psize = 7,
.digest = { 0x0a, 0x94, 0x2b, 0x12, 0x4e, 0xca, 0xa5, 0x46 },
}
};
#endif /* _CRYPTO_TCRYPT_H */ #endif /* _CRYPTO_TCRYPT_H */
...@@ -73,6 +73,9 @@ static struct usb_device_id bluetooth_ids[] = { ...@@ -73,6 +73,9 @@ static struct usb_device_id bluetooth_ids[] = {
/* Generic Bluetooth USB device */ /* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) }, { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
/* AVM BlueFRITZ! USB v2.0 */
{ USB_DEVICE(0x057c, 0x3800) },
/* Ericsson with non-standard id */ /* Ericsson with non-standard id */
{ USB_DEVICE(0x0bdb, 0x1002) }, { USB_DEVICE(0x0bdb, 0x1002) },
......
...@@ -1986,13 +1986,18 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd, ...@@ -1986,13 +1986,18 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
} }
/* Bluetooth ioctls */ /* Bluetooth ioctls */
#define HCIUARTSETPROTO _IOW('U', 200, int) #define HCIUARTSETPROTO _IOW('U', 200, int)
#define HCIUARTGETPROTO _IOR('U', 201, int) #define HCIUARTGETPROTO _IOR('U', 201, int)
#define BNEPCONNADD _IOW('B', 200, int) #define BNEPCONNADD _IOW('B', 200, int)
#define BNEPCONNDEL _IOW('B', 201, int) #define BNEPCONNDEL _IOW('B', 201, int)
#define BNEPGETCONNLIST _IOR('B', 210, int) #define BNEPGETCONNLIST _IOR('B', 210, int)
#define BNEPGETCONNINFO _IOR('B', 211, int) #define BNEPGETCONNINFO _IOR('B', 211, int)
#define CMTPCONNADD _IOW('C', 200, int)
#define CMTPCONNDEL _IOW('C', 201, int)
#define CMTPGETCONNLIST _IOR('C', 210, int)
#define CMTPGETCONNINFO _IOR('C', 211, int)
struct floppy_struct32 { struct floppy_struct32 {
compat_uint_t size; compat_uint_t size;
......
...@@ -618,6 +618,10 @@ COMPATIBLE_IOCTL(BNEPCONNADD) ...@@ -618,6 +618,10 @@ COMPATIBLE_IOCTL(BNEPCONNADD)
COMPATIBLE_IOCTL(BNEPCONNDEL) COMPATIBLE_IOCTL(BNEPCONNDEL)
COMPATIBLE_IOCTL(BNEPGETCONNLIST) COMPATIBLE_IOCTL(BNEPGETCONNLIST)
COMPATIBLE_IOCTL(BNEPGETCONNINFO) COMPATIBLE_IOCTL(BNEPGETCONNINFO)
COMPATIBLE_IOCTL(CMTPCONNADD)
COMPATIBLE_IOCTL(CMTPCONNDEL)
COMPATIBLE_IOCTL(CMTPGETCONNLIST)
COMPATIBLE_IOCTL(CMTPGETCONNINFO)
/* Misc. */ /* Misc. */
COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */ COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */ COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
......
...@@ -76,6 +76,8 @@ struct digest_alg { ...@@ -76,6 +76,8 @@ struct digest_alg {
void (*dia_init)(void *ctx); void (*dia_init)(void *ctx);
void (*dia_update)(void *ctx, const u8 *data, unsigned int len); void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
void (*dia_final)(void *ctx, u8 *out); void (*dia_final)(void *ctx, u8 *out);
int (*dia_setkey)(void *ctx, const u8 *key,
unsigned int keylen, u32 *flags);
}; };
struct compress_alg { struct compress_alg {
...@@ -157,6 +159,8 @@ struct digest_tfm { ...@@ -157,6 +159,8 @@ struct digest_tfm {
void (*dit_final)(struct crypto_tfm *tfm, u8 *out); void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
unsigned int nsg, u8 *out); unsigned int nsg, u8 *out);
int (*dit_setkey)(struct crypto_tfm *tfm,
const u8 *key, unsigned int keylen);
#ifdef CONFIG_CRYPTO_HMAC #ifdef CONFIG_CRYPTO_HMAC
void *dit_hmac_block; void *dit_hmac_block;
#endif #endif
...@@ -282,6 +286,15 @@ static inline void crypto_digest_digest(struct crypto_tfm *tfm, ...@@ -282,6 +286,15 @@ static inline void crypto_digest_digest(struct crypto_tfm *tfm,
tfm->crt_digest.dit_digest(tfm, sg, nsg, out); tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
} }
static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
const u8 *key, unsigned int keylen)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
if (tfm->crt_digest.dit_setkey == NULL)
return -ENOSYS;
return tfm->crt_digest.dit_setkey(tfm, key, keylen);
}
static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
const u8 *key, unsigned int keylen) const u8 *key, unsigned int keylen)
{ {
......
...@@ -166,7 +166,7 @@ struct xfrm_policy_afinfo { ...@@ -166,7 +166,7 @@ struct xfrm_policy_afinfo {
struct dst_ops *dst_ops; struct dst_ops *dst_ops;
void (*garbage_collect)(void); void (*garbage_collect)(void);
int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl); int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
struct dst_entry *(*find_bundle)(struct flowi *fl, struct rtable *rt, struct xfrm_policy *policy); struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
int (*bundle_create)(struct xfrm_policy *policy, int (*bundle_create)(struct xfrm_policy *policy,
struct xfrm_state **xfrm, struct xfrm_state **xfrm,
int nx, int nx,
......
...@@ -52,7 +52,7 @@ static ssize_t show_inquiry_cache(struct class_device *cdev, char *buf) ...@@ -52,7 +52,7 @@ static ssize_t show_inquiry_cache(struct class_device *cdev, char *buf)
n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x 0x%.2x %u\n", n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x 0x%.2x %u\n",
batostr(&bdaddr), batostr(&bdaddr),
info->pscan_rep_mode, info->pscan_period_mode, info->pscan_mode, info->pscan_rep_mode, info->pscan_period_mode, info->pscan_mode,
info->dev_class[0], info->dev_class[1], info->dev_class[2], info->dev_class[2], info->dev_class[1], info->dev_class[0],
info->clock_offset, 0, e->timestamp); info->clock_offset, 0, e->timestamp);
} }
......
...@@ -43,14 +43,10 @@ static int __xfrm4_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl) ...@@ -43,14 +43,10 @@ static int __xfrm4_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl)
} }
static struct dst_entry * static struct dst_entry *
__xfrm4_find_bundle(struct flowi *fl, struct rtable *rt, struct xfrm_policy *policy) __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
{ {
struct dst_entry *dst; struct dst_entry *dst;
if (!fl->fl4_src)
fl->fl4_src = rt->rt_src;
if (!fl->fl4_dst)
fl->fl4_dst = rt->rt_dst;
read_lock_bh(&policy->lock); read_lock_bh(&policy->lock);
for (dst = policy->bundles; dst; dst = dst->next) { for (dst = policy->bundles; dst; dst = dst->next) {
struct xfrm_dst *xdst = (struct xfrm_dst*)dst; struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
......
...@@ -52,7 +52,7 @@ static int __xfrm6_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl) ...@@ -52,7 +52,7 @@ static int __xfrm6_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl)
} }
static struct dst_entry * static struct dst_entry *
__xfrm6_find_bundle(struct flowi *fl, struct rtable *rt, struct xfrm_policy *policy) __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
{ {
struct dst_entry *dst; struct dst_entry *dst;
......
...@@ -21,9 +21,11 @@ ...@@ -21,9 +21,11 @@
* created test case so that I was able to fix nasty bug * created test case so that I was able to fix nasty bug
* Wilfried Weissmann * Wilfried Weissmann
* spotted bug in dequeue code and helped with fix * spotted bug in dequeue code and helped with fix
* Jiri Fojtasek
* fixed requeue routine
* and many others. thanks. * and many others. thanks.
* *
* $Id: sch_htb.c,v 1.24 2003/07/28 15:25:23 devik Exp devik $ * $Id: sch_htb.c,v 1.25 2003/12/07 11:08:25 devik Exp devik $
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -74,7 +76,7 @@ ...@@ -74,7 +76,7 @@
#define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */ #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
#define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock) #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
#define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock) #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
#define HTB_VER 0x3000f /* major must be matched with number suplied by TC as version */ #define HTB_VER 0x30010 /* major must be matched with number suplied by TC as version */
#if HTB_VER >> 16 != TC_HTB_PROTOVER #if HTB_VER >> 16 != TC_HTB_PROTOVER
#error "Mismatched sch_htb.c and pkt_sch.h" #error "Mismatched sch_htb.c and pkt_sch.h"
...@@ -708,7 +710,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) ...@@ -708,7 +710,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
sch->q.qlen++; sch->q.qlen++;
sch->stats.packets++; sch->stats.bytes += skb->len; sch->stats.packets++; sch->stats.bytes += skb->len;
HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",htb_classid(cl),skb); HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb);
return NET_XMIT_SUCCESS; return NET_XMIT_SUCCESS;
} }
...@@ -717,16 +719,18 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch) ...@@ -717,16 +719,18 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
{ {
struct htb_sched *q = (struct htb_sched *)sch->data; struct htb_sched *q = (struct htb_sched *)sch->data;
struct htb_class *cl = htb_classify(skb,sch); struct htb_class *cl = htb_classify(skb,sch);
struct sk_buff *tskb;
if (cl == HTB_DIRECT || !cl) { if (cl == HTB_DIRECT || !cl) {
/* enqueue to helper queue */ /* enqueue to helper queue */
if (q->direct_queue.qlen < q->direct_qlen && cl) { if (q->direct_queue.qlen < q->direct_qlen && cl) {
__skb_queue_tail(&q->direct_queue, skb); __skb_queue_head(&q->direct_queue, skb);
q->direct_pkts++;
} else { } else {
kfree_skb (skb); __skb_queue_head(&q->direct_queue, skb);
sch->stats.drops++; tskb = __skb_dequeue_tail(&q->direct_queue);
return NET_XMIT_DROP; kfree_skb (tskb);
sch->stats.drops++;
return NET_XMIT_CN;
} }
} else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) { } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
sch->stats.drops++; sch->stats.drops++;
...@@ -736,7 +740,7 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch) ...@@ -736,7 +740,7 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
htb_activate (q,cl); htb_activate (q,cl);
sch->q.qlen++; sch->q.qlen++;
HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",htb_classid(cl),skb); HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb);
return NET_XMIT_SUCCESS; return NET_XMIT_SUCCESS;
} }
...@@ -1487,7 +1491,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, ...@@ -1487,7 +1491,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
cl->magic = HTB_CMAGIC; cl->magic = HTB_CMAGIC;
#endif #endif
/* create leaf qdisc early because it uses kmalloc(GPF_KERNEL) /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL)
so that can't be used inside of sch_tree_lock so that can't be used inside of sch_tree_lock
-- thanks to Karlis Peisenieks */ -- thanks to Karlis Peisenieks */
new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
......
...@@ -646,13 +646,13 @@ xfrm_tmpl_resolve(struct xfrm_policy *policy, struct flowi *fl, ...@@ -646,13 +646,13 @@ xfrm_tmpl_resolve(struct xfrm_policy *policy, struct flowi *fl,
*/ */
static struct dst_entry * static struct dst_entry *
xfrm_find_bundle(struct flowi *fl, struct rtable *rt, struct xfrm_policy *policy, unsigned short family) xfrm_find_bundle(struct flowi *fl, struct xfrm_policy *policy, unsigned short family)
{ {
struct dst_entry *x; struct dst_entry *x;
struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family); struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
if (unlikely(afinfo == NULL)) if (unlikely(afinfo == NULL))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
x = afinfo->find_bundle(fl, rt, policy); x = afinfo->find_bundle(fl, policy);
xfrm_policy_put_afinfo(afinfo); xfrm_policy_put_afinfo(afinfo);
return x; return x;
} }
...@@ -762,7 +762,7 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, ...@@ -762,7 +762,7 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
* LATER: help from flow cache. It is optional, this * LATER: help from flow cache. It is optional, this
* is required only for output policy. * is required only for output policy.
*/ */
dst = xfrm_find_bundle(fl, rt, policy, family); dst = xfrm_find_bundle(fl, policy, family);
if (IS_ERR(dst)) { if (IS_ERR(dst)) {
xfrm_pol_put(policy); xfrm_pol_put(policy);
return PTR_ERR(dst); return PTR_ERR(dst);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment