netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: IPsec and EAGAIN
From: Herbert Xu @ 2006-06-13 11:44 UTC (permalink / raw)
  To: James Ring; +Cc: netdev
In-Reply-To: <61418.152.91.8.100.1150177885.squirrel@webmail.jdns.org>

James Ring <sjr@jdns.org> wrote:
> 
> I have a couple of questions: are there any patches out which solve this
> problem?

This is on our todo list but AFAIK there aren't patches for it yet.

> http://sourceforge.net/mailarchive/message.php?msg_id=8621194

This patch can lock up your machine when this function is entered in an
unsleepable context.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [RFT 0/5] sky2: suspend/resume patchlets
From: Jeff Garzik @ 2006-06-13 13:22 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Linus Torvalds, netdev
In-Reply-To: <20060613081726.695812000@localhost.localdomain>

Stephen Hemminger wrote:
> There were a several problems buried in suspend/resume. The real
> failure was caused by the idle timer not being stopped/restarted.
> But several other races, and cleanups were needed.
> 
> Since I don't have a machine that will suspend successfully with
> that hardware, I can't test it.


All five patches look OK to me.  Did Linus get the patches?  The emails 
were sent to linus@osdl.org not torvalds@osdl.org.

	Jeff




^ permalink raw reply

* Re: [RFC/PATCH 2/2] update sunrpc to use in-kernel sockets API
From: James Morris @ 2006-06-13 14:07 UTC (permalink / raw)
  To: Sridhar Samudrala; +Cc: netdev, linux-kernel
In-Reply-To: <448E42AE.1010901@us.ibm.com>

On Mon, 12 Jun 2006, Sridhar Samudrala wrote:

> > > -	sendpage = sock->ops->sendpage ? : sock_no_sendpage;
> > > +	sendpage = kernel_sendpage ? : sock_no_sendpage;
> > >     
> > 
> > This is not equivalent.
> > 
> >   
> Actually, we could make this a simple assignment as we check for
> sock->ops->sendpage in
> kernel_sendpage().
>    sendpage = kernel_sendpage;

No, the code there is setting different values for sendpage depending on 
whether the page is in high memory or not.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply

* Re: [RFC/PATCH 1/2] in-kernel sockets API
From: Jan Engelhardt @ 2006-06-13 14:58 UTC (permalink / raw)
  To: Sridhar Samudrala; +Cc: netdev, linux-kernel
In-Reply-To: <1150156562.19929.32.camel@w-sridhar2.beaverton.ibm.com>


>+extern int kernel_ioctl(struct socket *sock, int cmd, unsigned long arg);
>+

I would prefer naming it kernel_sock_ioctl, since (general) ioctl often 
done on fds (or struct file * for that matter) rather than sockets.



Jan Engelhardt
-- 

^ permalink raw reply

* Re: 2.6.17: networking bug??
From: Mark Lord @ 2006-06-13 15:00 UTC (permalink / raw)
  To: Mark Lord; +Cc: Linux Kernel, netdev, Linus Torvalds
In-Reply-To: <448ECB09.3010308@rtr.ca>

Mark Lord wrote:
..
> The differences I see are widely varying "window sizes".
> What would cause this?

This is from (working) 2.6.16.18:
> IP silvy.localnet.56224 > 216-145-246-23.rev.dls.net.www: . ack 1 win 1460 <nop,nop,timestamp 730448 134760199>
> IP silvy.localnet.56224 > 216-145-246-23.rev.dls.net.www: P 1:607(606) ack 1 win 1460 <nop,nop,timestamp 730448 134760199>
> IP 216-145-246-23.rev.dls.net.www > silvy.localnet.56224: P 1:206(205) ack 607 win 32798 <nop,nop,timestamp 134760217 730448>
> IP silvy.localnet.56224 > 216-145-246-23.rev.dls.net.www: . ack 206 win 1728 <nop,nop,timestamp 730626 134760217> 

This is from (failing) 2.6.17-rc6-git2:
> IP silvy.localnet.33472 > 216-145-246-23.rev.dls.net.www: . ack 1 win 92 <nop,nop,timestamp 4294759337 134771817>
> IP silvy.localnet.33472 > 216-145-246-23.rev.dls.net.www: P 1:607(606) ack 1 win 92 <nop,nop,timestamp 4294759337 134771817>
> IP silvy.localnet.33472 > 216-145-246-23.rev.dls.net.www: P 1:607(606) ack 1 win 92 <nop,nop,timestamp 4294760162 134771817>
> IP 216-145-246-23.rev.dls.net.www > silvy.localnet.33472: . ack 607 win 32798 <nop,nop,timestamp 134771918 4294760162> 

Both kernels default to /proc/sys/net/ipv4/tcp_window_scaling == 1,
and 2.6.16.18 works regardless of whether I turn it off/on again.

But 2.6.17-rc6-git2 fails to work with the webserver at www.everymac.com
when /proc/sys/net/ipv4/tcp_window_scaling == 1.  Setting this to 0
"fixes" the problem.

BUG.

^ permalink raw reply

* Re: [PATCH] [2.6.17-rc6] Section mismatch in drivers/net/ne.o during modpost
From: Randy.Dunlap @ 2006-06-13 15:11 UTC (permalink / raw)
  To: Keith Owens; +Cc: mikpe, akpm, jgarzik, linux-kernel, netdev
In-Reply-To: <10735.1150176929@kao2.melbourne.sgi.com>

On Tue, 13 Jun 2006 15:35:29 +1000 Keith Owens wrote:

> Mikael Pettersson (on Sun, 11 Jun 2006 02:51:21 +0200 (MEST)) wrote:
> >On Sat, 10 Jun 2006 12:13:35 -0700, Randy.Dunlap wrote:
> >>On Sat, 10 Jun 2006 14:11:42 +0200 (MEST) Mikael Pettersson wrote:
> >>
> >>> While compiling 2.6.17-rc6 for a 486 with an NE2000 ISA ethernet card, I got:
> >>> 
> >>> WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x158) and 'ne_block_input'
> >>> WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x176) and 'ne_block_input'
> >>> WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x183) and 'ne_block_input'
> >>> WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x1ea) and 'ne_block_input'
> >>> WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x251) and 'ne_block_input'
> >>> WARNING: drivers/net/ne.o - Section mismatch: reference to .init.text: from .text between 'init_module' (at offset 0x266) and 'ne_block_input'
> >>> WARNING: drivers/net/ne.o - Section mismatch: reference to .init.text: from .text between 'init_module' (at offset 0x29b) and 'ne_block_input'
> >>> 
> >>> Not sure how serious this is; the driver seems to work fine later on.
> >>
> >>Doesn't look serious.  init_module() is not __init, but it calls
> >>some __init functions and touches some __initdata.
> >>
> >>BTW, I would be happy to see some consistent results from modpost
> >>section checking.  I don't see all of these warnings (I see only 1)
> >>when using gcc 3.3.6.  What gcc version are you using?
> >>Does that matter?  (not directed at anyone in particular)
> >
> >The messages above are from when I used gcc-4.1.1.
> >With gcc-3.2.3 I only see a single warning.
> 
> Probably over enthusiastic gcc inlining.  gcc 4 will inline functions
> that are not declared as inline.  That is not so bad, except that some
> versions of gcc will ignore a mismatch in function attributes and
> inline a __init function into normal text, generating additional
> section mismatches.  For a specific example, see
> 
> http://marc.theaimsgroup.com/?l=linux-kernel&m=113824309203482&w=2

Yes, I am seeing lots of that.  :(

---
~Randy

^ permalink raw reply

* Re: 2.6.17: networking bug??
From: Mark Lord @ 2006-06-13 15:28 UTC (permalink / raw)
  To: Linux Kernel; +Cc: netdev, Linus Torvalds
In-Reply-To: <448ED2FC.2040704@rtr.ca>

Mmm.  I notice that 2.6.17 has a new sysctl related
to this stuff:  /proc/sys/net/ipv4/tcp_workaround_signed_windows

It makes no difference whatsoever for me here
when varied while /proc/sys/net/ipv4/tcp_window_scaling==1.

The site www.everymac.com is still not browseable until
setting /proc/sys/net/ipv4/tcp_window_scaling===0.

There's one other difference I see in the tcpdump traces.
The first packets from each trace below show different
values for "wscale".  The old (working) kernels use "wscale 2",
whereas 2.6.17 uses "wscale 6".  In both cases, the value
seen in /proc/sys/net/ipv4/tcp_adv_win_scale is 2.

This is from (working) 2.6.16.18:
> 
> IP silvy.localnet.56224 > 216-145-246-23.rev.dls.net.www: S 2933486277:2933486277(0) win 5840 <mss 1460,sackOK,timestamp 730285 0,nop,wscale 2>
> IP 216-145-246-23.rev.dls.net.www > silvy.localnet.56224: S 2545625510:2545625510(0) ack 2933486278 win 65535 <mss 1452,nop,wscale 1,nop,nop,timestamp 134760199 730285>
> IP silvy.localnet.56224 > 216-145-246-23.rev.dls.net.www: . ack 1 win 1460 <nop,nop,timestamp 730448 134760199>
> IP silvy.localnet.56224 > 216-145-246-23.rev.dls.net.www: P 1:607(606) ack 1 win 1460 <nop,nop,timestamp 730448 134760199>
> IP 216-145-246-23.rev.dls.net.www > silvy.localnet.56224: P 1:206(205) ack 607 win 32798 <nop,nop,timestamp 134760217 730448>
> IP silvy.localnet.56224 > 216-145-246-23.rev.dls.net.www: . ack 206 win 1728 <nop,nop,timestamp 730626 134760217> 

This is from (failing) 2.6.17-rc6-git2:
> 
> IP silvy.localnet.33472 > 216-145-246-23.rev.dls.net.www: S 3000518105:3000518105(0) win 5840 <mss 1460,sackOK,timestamp 4294759165 0,nop,wscale 6>
> IP 216-145-246-23.rev.dls.net.www > silvy.localnet.33472: S 3368494549:3368494549(0) ack 3000518106 win 65535 <mss 1452,nop,wscale 1,nop,nop,timestamp 134771817 4294759165> 
> IP silvy.localnet.33472 > 216-145-246-23.rev.dls.net.www: . ack 1 win 92 <nop,nop,timestamp 4294759337 134771817>
> IP silvy.localnet.33472 > 216-145-246-23.rev.dls.net.www: P 1:607(606) ack 1 win 92 <nop,nop,timestamp 4294759337 134771817>
> IP silvy.localnet.33472 > 216-145-246-23.rev.dls.net.www: P 1:607(606) ack 1 win 92 <nop,nop,timestamp 4294760162 134771817>
> IP 216-145-246-23.rev.dls.net.www > silvy.localnet.33472: . ack 607 win 32798 <nop,nop,timestamp 134771918 4294760162> 

Something is broken somewhere.

^ permalink raw reply

* [PATCH 0/2] AES-XCBC-MAC
From: Kazunori MIYAZAWA @ 2006-06-13 15:43 UTC (permalink / raw)
  To: David Miller, Herbert Xu; +Cc: netdev, usagi-core

Hello, 

I send two patches which introduce AES-XCBC-MAC.
I changed approach to implement it with introducing
abstruct interface "keyed_hash" into crypto_tfm.
Both HMAC and XCBC use the interface.

I put kht_* outside of crt_u because keyed_hash uses
pure digest algorithm or encryption algorithm.
I think it is reasonable.

If these patches are accepted, I will send glue patches
to IPsec stack.

These are against linux-2.6.17-rc6.

Thank you,

#Yoshifuji-san, would you ack these patch again?

--
Kazunori Miyazawa



^ permalink raw reply

* [PATCH 1/2] AES-XCBC-MAC
From: Kazunori MIYAZAWA @ 2006-06-13 15:44 UTC (permalink / raw)
  To: David Miller, Herbert Xu; +Cc: netdev, usagi-core

This is preparation to introduce AES-XCBC-MAC.
- introducing common interface "keyed hash"
- making HMAC use the interface

---
commit 9c6b9affbacf12fc1e32868eaa14fef279b2696c
tree 67b19707fae179e20bfb8060444f287d0bda7bb1
parent 650fb8382287f7990d5127a82a54295139224606
author Kazunori MIYAZAWA <kazunori@miyazawa.org> Tue, 13 Jun 2006 10:02:54 +0900
committer Kazunori MIYAZAWA <kazunori@miyazawa.org> Tue, 13 Jun 2006 10:02:54 +0900

 crypto/digest.c        |   23 +++++++++++++++++++----
 crypto/hmac.c          |   36 +++++++++++++++++++++++++-----------
 crypto/tcrypt.c        |    2 +-
 include/linux/crypto.h |   31 +++++++++++++++++++++++++------
 4 files changed, 70 insertions(+), 22 deletions(-)

diff --git a/crypto/digest.c b/crypto/digest.c
index d9b6ac9..66bc263 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -85,11 +85,13 @@ static void digest(struct crypto_tfm *tf
 
 int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
 {
-	return flags ? -EINVAL : 0;
+	tfm->crt_digest.cit_mode = flags & CRYPTO_TFM_MODE_MASK;
+	return 0;
 }
 
 int crypto_init_digest_ops(struct crypto_tfm *tfm)
 {
+	int ret = 0;
 	struct digest_tfm *ops = &tfm->crt_digest;
 	
 	ops->dit_init	= init;
@@ -97,11 +99,24 @@ int crypto_init_digest_ops(struct crypto
 	ops->dit_final	= final;
 	ops->dit_digest	= digest;
 	ops->dit_setkey	= setkey;
-	
-	return crypto_alloc_hmac_block(tfm);
+
+#ifdef CONFIG_CRYPTO_HMAC
+	if (tfm->crt_digest.cit_mode & CRYPTO_TFM_MODE_HMAC) {
+		ret = crypto_alloc_hmac_block(tfm);
+		tfm->crt_keyedhash.kht_init = crypto_hmac_init;
+		tfm->crt_keyedhash.kht_update = crypto_hmac_update;
+		tfm->crt_keyedhash.kht_final = crypto_hmac_final;
+		tfm->crt_keyedhash.keyed_hash = crypto_hmac;
+		tfm->crt_keyedhash.kht_digestsize = crypto_tfm_alg_digestsize;
+	}
+#endif
+	return ret;
 }
 
 void crypto_exit_digest_ops(struct crypto_tfm *tfm)
 {
-	crypto_free_hmac_block(tfm);
+#ifdef CONFIG_CRYPTO_HMAC
+	if (tfm->crt_digest.cit_mode & CRYPTO_TFM_MODE_HMAC)
+		crypto_free_hmac_block(tfm);
+#endif
 }
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 46120de..d9610ca 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -34,10 +34,10 @@ int crypto_alloc_hmac_block(struct crypt
 	int ret = 0;
 
 	BUG_ON(!crypto_tfm_alg_blocksize(tfm));
-	
-	tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
+
+	tfm->crt_keyedhash.kht_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
 	                                         GFP_KERNEL);
-	if (tfm->crt_digest.dit_hmac_block == NULL)
+	if (tfm->crt_keyedhash.kht_hmac_block == NULL)
 		ret = -ENOMEM;
 
 	return ret;
@@ -46,14 +46,16 @@ int crypto_alloc_hmac_block(struct crypt
 
 void crypto_free_hmac_block(struct crypto_tfm *tfm)
 {
-	kfree(tfm->crt_digest.dit_hmac_block);
+	kfree(tfm->crt_keyedhash.kht_hmac_block);
 }
 
-void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
+int crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
 {
 	unsigned int i;
 	struct scatterlist tmp;
-	char *ipad = tfm->crt_digest.dit_hmac_block;
+	char *ipad = tfm->crt_keyedhash.kht_hmac_block;
+
+	BUG_ON(ipad == NULL);
 	
 	if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
 		hash_key(tfm, key, *keylen);
@@ -70,6 +72,8 @@ void crypto_hmac_init(struct crypto_tfm 
 	
 	crypto_digest_init(tfm);
 	crypto_digest_update(tfm, &tmp, 1);
+
+	return 0;
 }
 
 void crypto_hmac_update(struct crypto_tfm *tfm,
@@ -78,13 +82,15 @@ void crypto_hmac_update(struct crypto_tf
 	crypto_digest_update(tfm, sg, nsg);
 }
 
-void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
+int crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
                        unsigned int *keylen, u8 *out)
 {
 	unsigned int i;
 	struct scatterlist tmp;
-	char *opad = tfm->crt_digest.dit_hmac_block;
+	char *opad = tfm->crt_keyedhash.kht_hmac_block;
 	
+	BUG_ON(opad == NULL);
+
 	if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
 		hash_key(tfm, key, *keylen);
 		*keylen = crypto_tfm_alg_digestsize(tfm);
@@ -107,14 +113,22 @@ void crypto_hmac_final(struct crypto_tfm
 	
 	crypto_digest_update(tfm, &tmp, 1);
 	crypto_digest_final(tfm, out);
+
+	return 0;
 }
 
-void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
+int crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
                  struct scatterlist *sg, unsigned int nsg, u8 *out)
 {
-	crypto_hmac_init(tfm, key, keylen);
+	int ret = 0;
+
+	ret = crypto_hmac_init(tfm, key, keylen);
+	if (ret != 0)
+		return ret;
 	crypto_hmac_update(tfm, sg, nsg);
-	crypto_hmac_final(tfm, key, keylen, out);
+	ret = crypto_hmac_final(tfm, key, keylen, out);
+
+	return ret;
 }
 
 EXPORT_SYMBOL_GPL(crypto_hmac_init);
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 49e344f..37aeced 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -180,7 +180,7 @@ static void test_hmac(char *algo, struct
 	struct hmac_testvec *hmac_tv;
 	unsigned int tsize, klen;
 
-	tfm = crypto_alloc_tfm(algo, 0);
+	tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_HMAC);
 	if (tfm == NULL) {
 		printk("failed to load transform for %s\n", algo);
 		return;
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 0ab1bc1..1ade651 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -44,6 +44,7 @@
 #define CRYPTO_TFM_MODE_CBC		0x00000002
 #define CRYPTO_TFM_MODE_CFB		0x00000004
 #define CRYPTO_TFM_MODE_CTR		0x00000008
+#define CRYPTO_TFM_MODE_HMAC		0x00000080
 
 #define CRYPTO_TFM_REQ_WEAK_KEY		0x00000100
 #define CRYPTO_TFM_REQ_MAY_SLEEP	0x00000200
@@ -192,6 +193,7 @@ struct cipher_tfm {
 };
 
 struct digest_tfm {
+	u32 cit_mode;
 	void (*dit_init)(struct crypto_tfm *tfm);
 	void (*dit_update)(struct crypto_tfm *tfm,
 	                   struct scatterlist *sg, unsigned int nsg);
@@ -200,9 +202,6 @@ struct digest_tfm {
 	                   unsigned int nsg, u8 *out);
 	int (*dit_setkey)(struct crypto_tfm *tfm,
 	                  const u8 *key, unsigned int keylen);
-#ifdef CONFIG_CRYPTO_HMAC
-	void *dit_hmac_block;
-#endif
 };
 
 struct compress_tfm {
@@ -218,6 +217,23 @@ struct compress_tfm {
 #define crt_digest	crt_u.digest
 #define crt_compress	crt_u.compress
 
+#if defined(CONFIG_CRYPTO_HMAC)
+
+#define kht_hmac_block	kht_u.hmac_block
+
+struct keyed_hash_tfm {
+	int (*kht_init)(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
+	void (*kht_update)(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg);
+	int (*kht_final)(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, u8 *out);
+	int (*keyed_hash)(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
+			 struct scatterlist *sg, unsigned int nsg, u8 *out);
+	unsigned int (*kht_digestsize)(struct crypto_tfm *tfm);
+	union {
+		void *hmac_block;
+	} kht_u;
+};
+#endif
+
 struct crypto_tfm {
 
 	u32 crt_flags;
@@ -228,6 +244,9 @@ struct crypto_tfm {
 		struct compress_tfm compress;
 	} crt_u;
 	
+#if defined(CONFIG_CRYPTO_HMAC)
+	struct keyed_hash_tfm crt_keyedhash;
+#endif	
 	struct crypto_alg *__crt_alg;
 
 	char __crt_ctx[] __attribute__ ((__aligned__));
@@ -431,12 +450,12 @@ static inline int crypto_comp_decompress
  * HMAC support.
  */
 #ifdef CONFIG_CRYPTO_HMAC
-void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
+int crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
 void crypto_hmac_update(struct crypto_tfm *tfm,
                         struct scatterlist *sg, unsigned int nsg);
-void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
+int crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
                        unsigned int *keylen, u8 *out);
-void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
+int crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
                  struct scatterlist *sg, unsigned int nsg, u8 *out);
 #endif	/* CONFIG_CRYPTO_HMAC */
 



^ permalink raw reply related

* [PATCH 2/2] AES-XCBC-MAC
From: Kazunori MIYAZAWA @ 2006-06-13 15:44 UTC (permalink / raw)
  To: David Miller, Herbert Xu; +Cc: netdev, usagi-core

This patch introduces AES-XCBC-MAC using the "keyed hash" interface.
It accordingly depends on the previous patch.

Signed-off-by: Kazunori MIYAZAWA <miyazawa@linux-ipv6.org>

---
commit f23d1b52e77f339a9eaa89a1b913d6373fe60fb6
tree bab6efc5808414f13dcefb4bb164c3e111000fa3
parent 9c6b9affbacf12fc1e32868eaa14fef279b2696c
author Kazunori MIYAZAWA <kazunori@miyazawa.org> Tue, 13 Jun 2006 10:05:50 +0900
committer Kazunori MIYAZAWA <kazunori@miyazawa.org> Tue, 13 Jun 2006 10:05:50 +0900

 crypto/Kconfig         |    9 ++
 crypto/Makefile        |    1 
 crypto/cipher.c        |   20 ++++
 crypto/internal.h      |   16 +++
 crypto/tcrypt.c        |   99 +++++++++++++++++++++
 crypto/tcrypt.h        |   80 +++++++++++++++++
 crypto/xcbc.c          |  230 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/crypto.h |   30 ++++++
 8 files changed, 482 insertions(+), 3 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index c442f2e..8dc28e9 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -16,6 +16,15 @@ config CRYPTO_HMAC
 	  HMAC: Keyed-Hashing for Message Authentication (RFC2104).
 	  This is required for IPSec.
 
+config CRYPTO_XCBC
+	bool "XCBC support"
+	depends on CRYPTO && EXPERIMENTAL
+	help
+	  XCBC: Keyed-Hashing with encryption algorithm
+		http://www.ietf.org/rfc/rfc3566.txt
+		http://csrc.nist.gov/encryption/modes/proposedmodes/
+                 xcbc-mac/xcbc-mac-spec.pdf
+
 config CRYPTO_NULL
 	tristate "Null algorithms"
 	depends on CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index d287b9e..781712d 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_CRYPTO) += api.o scatterwal
 			$(proc-crypto-y)
 
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
+obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o
 obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
 obj-$(CONFIG_CRYPTO_MD4) += md4.o
 obj-$(CONFIG_CRYPTO_MD5) += md5.o
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 65bcea0..5605216 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -402,6 +402,7 @@ int crypto_init_cipher_ops(struct crypto
 		break;
 		
 	case CRYPTO_TFM_MODE_CBC:
+	case CRYPTO_TFM_MODE_XCBC:
 		ops->cit_encrypt = cbc_encrypt;
 		ops->cit_decrypt = cbc_decrypt;
 		ops->cit_encrypt_iv = cbc_encrypt_iv;
@@ -426,7 +427,7 @@ int crypto_init_cipher_ops(struct crypto
 		BUG();
 	}
 	
-	if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) {
+	if (ops->cit_mode & (CRYPTO_TFM_MODE_CBC | CRYPTO_TFM_MODE_XCBC)) {
 		unsigned long align;
 		unsigned long addr;
 	    	
@@ -453,6 +454,16 @@ int crypto_init_cipher_ops(struct crypto
 		addr = ALIGN(addr, align);
 		addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align);
 		ops->cit_iv = (void *)addr;
+#ifdef CONFIG_CRYPTO_XCBC
+		if (ops->cit_mode & CRYPTO_TFM_MODE_XCBC) {
+			tfm->crt_keyedhash.kht_init = crypto_xcbc_init;
+			tfm->crt_keyedhash.kht_update = crypto_xcbc_update;
+			tfm->crt_keyedhash.kht_final = crypto_xcbc_final;
+			tfm->crt_keyedhash.keyed_hash = crypto_xcbc;
+			tfm->crt_keyedhash.kht_digestsize = crypto_tfm_alg_blocksize;
+			ret = crypto_alloc_xcbc_block(tfm);
+		}
+#endif
 	}
 
 out:	
@@ -461,4 +472,11 @@ out:	
 
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
 {
+#ifdef CONFIG_CRYPTO_XCBC
+	struct cipher_tfm *ops = &tfm->crt_cipher;
+	if (ops->cit_mode & CRYPTO_TFM_MODE_CBC &&
+		ops->cit_mode & CRYPTO_TFM_MODE_XCBC) {
+		crypto_free_xcbc_block(tfm);
+	}
+#endif
 }
diff --git a/crypto/internal.h b/crypto/internal.h
index 959e602..cc4244f 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -62,6 +62,22 @@ static inline void crypto_free_hmac_bloc
 { }
 #endif
 
+#ifdef CONFIG_CRYPTO_XCBC
+int crypto_alloc_xcbc_block(struct crypto_tfm *tfm);
+static inline void crypto_free_xcbc_block(struct crypto_tfm *tfm)
+{
+	kfree(tfm->crt_keyedhash.kht_xcbc_block);
+}
+#else
+static inline int crypto_alloc_xcbc_block(struct crypto_tfm *tfm)
+{
+	return 0;
+}
+
+static inline void crypto_free_xcbc_block(struct crypto_tfm *tfm)
+{ }
+#endif
+
 #ifdef CONFIG_PROC_FS
 void __init crypto_init_proc(void);
 #else
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 37aeced..0b4117a 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -253,6 +253,102 @@ out:
 
 #endif	/* CONFIG_CRYPTO_HMAC */
 
+#ifdef CONFIG_CRYPTO_XCBC
+
+static void
+test_xcbc(char *algo, struct xcbc_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 xcbc_testvec *xcbc_tv;
+	unsigned int tsize, klen;
+	u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
+			    0x02020202, 0x02020202, 0x02020202, 0x02020202,
+			    0x03030303, 0x03030303, 0x03030303, 0x03030303}; 
+
+	tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_XCBC);
+	if (tfm == NULL) {
+		printk("failed to load transform for %s\n", algo);
+		return;
+	}
+
+	tfm->crt_keyedhash.kht_xcbc_const = (u8*)ks;
+
+	printk("\ntesting xcbc_%s\n", algo);
+	
+	tsize = sizeof (struct xcbc_testvec);
+	tsize *= tcount;
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+
+	memcpy(tvmem, template, tsize);
+	xcbc_tv = (void *) tvmem;
+
+	for (i = 0; i < tcount; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = xcbc_tv[i].plaintext;
+		klen = xcbc_tv[i].ksize;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = offset_in_page(p);
+		sg[0].length = xcbc_tv[i].psize;
+
+		crypto_xcbc(tfm, xcbc_tv[i].key, &klen, sg, 1, result);
+
+		hexdump(result, crypto_tfm_alg_blocksize(tfm));
+		printk("%s\n",
+		       memcmp(result, xcbc_tv[i].digest,
+			      crypto_tfm_alg_blocksize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	printk("\ntesting xcbc_%s across pages\n", algo);
+
+	memset(xbuf, 0, XBUFSIZE);
+	
+	j = 0;
+	for (i = 0; i < tcount; i++) {
+		if (xcbc_tv[i].np) {
+			j++;
+			printk ("test %u:\n",j);
+			memset (result, 0, 64);
+
+			temp = 0;
+			klen = xcbc_tv[i].ksize;
+			for (k = 0; k < xcbc_tv[i].np; k++) {
+				memcpy (&xbuf[IDX[k]], xcbc_tv[i].plaintext + temp, 
+						xcbc_tv[i].tap[k]);	
+				temp += xcbc_tv[i].tap[k];
+				p = &xbuf[IDX[k]];
+				sg[k].page = virt_to_page (p);
+				sg[k].offset = offset_in_page (p);
+				sg[k].length = xcbc_tv[i].tap[k];
+			}
+
+			crypto_xcbc(tfm, xcbc_tv[i].key, &klen, sg, xcbc_tv[i].np, 
+					result);
+			hexdump(result, crypto_tfm_alg_blocksize(tfm));
+			
+			printk("%s\n",
+				memcmp(result, xcbc_tv[i].digest,
+					crypto_tfm_alg_blocksize(tfm)) ? "fail" : 
+				"pass");
+		}
+	}
+out:
+	crypto_free_tfm(tfm);
+}
+
+#endif	/* CONFIG_CRYPTO_XCBC */
+
+
 static void test_cipher(char *algo, int mode, int enc,
 			struct cipher_testvec *template, unsigned int tcount)
 {
@@ -857,6 +953,9 @@ static void do_test(void)
 		test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
 		test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
 		test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
+#endif		
+#ifdef CONFIG_CRYPTO_XCBC
+		test_xcbc("aes", aes_xcbc_tv_template, XCBC_AES_TEST_VECTORS);
 #endif
 
 		test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index 1f683ba..6c1361f 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -46,6 +46,16 @@ struct hmac_testvec {
 	unsigned char np;
 };
 
+struct xcbc_testvec {	
+	char key[128];
+	unsigned char ksize;
+	char plaintext[128];
+	unsigned char psize;
+	char digest[MAX_DIGEST_SIZE];
+	unsigned char np;
+	unsigned char tap[MAX_TAP];		
+};
+
 struct cipher_testvec {
 	char key[MAX_KEYLEN] __attribute__ ((__aligned__(4)));
 	char iv[MAX_IVLEN];
@@ -941,6 +951,76 @@ static struct hmac_testvec hmac_sha256_t
 
 #endif	/* CONFIG_CRYPTO_HMAC */
 
+#define XCBC_AES_TEST_VECTORS 6
+
+#ifdef CONFIG_CRYPTO_XCBC
+static struct xcbc_testvec aes_xcbc_tv_template[] = {
+	{
+		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		.ksize	= 16,
+		.plaintext	= { [0 ... 127] = 0 },
+		.psize	= 0,
+		.digest = { 0x75, 0xf0, 0x25, 0x1d, 0x52, 0x8a, 0xc0, 0x1c,
+			    0x45, 0x73, 0xdf, 0xd5, 0x84, 0xd7, 0x9f, 0x29 },
+	}, {
+		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		.ksize	= 16,
+		.plaintext	= { 0x00, 0x01, 0x02 },
+		.psize	= 3,
+		.digest	= { 0x5b, 0x37, 0x65, 0x80, 0xae, 0x2f, 0x19, 0xaf,
+			    0xe7, 0x21, 0x9c, 0xee, 0xf1, 0x72, 0x75, 0x6f },
+	} , {
+		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		.ksize	= 16,
+		.plaintext	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		.psize	= 16,
+		.digest = { 0xd2, 0xa2, 0x46, 0xfa, 0x34, 0x9b, 0x68, 0xa7,
+			    0x99, 0x98, 0xa4, 0x39, 0x4f, 0xf7, 0xa2, 0x63 },
+	}, {
+		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		.ksize	= 16,
+		.plaintext	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+			    0x10, 0x11, 0x12, 0x13 },
+		.psize	= 20,
+		.digest = { 0x47, 0xf5, 0x1b, 0x45, 0x64, 0x96, 0x62, 0x15,
+			    0xb8, 0x98, 0x5c, 0x63, 0x05, 0x5e, 0xd3, 0x08 },
+		.np	= 2,
+		.tap	= {10, 10},
+	}, {
+		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		.ksize	= 16,
+		.plaintext	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+			    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+			    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+		.psize	= 32,
+		.digest = { 0xf5, 0x4f, 0x0e, 0xc8, 0xd2, 0xb9, 0xf3, 0xd3,
+			    0x68, 0x07, 0x73, 0x4b, 0xd5, 0x28, 0x3f, 0xd4 },
+	}, {
+		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		.ksize	= 16,
+		.plaintext	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+			    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+			    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+			    0x20, 0x21 },
+		.psize	= 34,
+		.digest = { 0xbe, 0xcb, 0xb3, 0xbc, 0xcd, 0xb5, 0x18, 0xa3,
+			    0x06, 0x77, 0xd5, 0x48, 0x1f, 0xb6, 0xb4, 0xd8 },
+		.np	= 2,
+		.tap	= {17,17},
+	}
+};
+#endif
+
 /*
  * DES test vectors.
  */
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
new file mode 100644
index 0000000..0cc23f0
--- /dev/null
+++ b/crypto/xcbc.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C)2005,2006 USAGI/WIDE Project
+ * 
+ * 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.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author:
+ * 	Kazunori Miyazawa <miyazawa@linux-ipv6.org>
+ */
+
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+
+struct xcbc_ops {
+	unsigned int len;
+	u8 *prev;
+};
+
+int crypto_alloc_xcbc_block(struct crypto_tfm *tfm)
+{
+	struct xcbc_ops *ops;
+
+	BUG_ON(!crypto_tfm_alg_blocksize(tfm));
+
+	ops = kmalloc(sizeof(*ops) + crypto_tfm_alg_blocksize(tfm), GFP_KERNEL);
+	if (ops == NULL)
+		return -ENOMEM;
+	ops->len = 0;
+	ops->prev = (u8*)(ops + 1);
+
+	tfm->crt_keyedhash.kht_xcbc_block = ops;
+	tfm->crt_keyedhash.kht_xcbc_const = NULL;
+
+	return 0;
+}
+
+static int _crypto_xcbc_init(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
+{
+	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+	u8 key1[bsize];
+	int err;
+
+	if (!(tfm->crt_cipher.cit_mode & CRYPTO_TFM_MODE_XCBC))
+		return -EINVAL;
+
+	if (keylen != crypto_tfm_alg_blocksize(tfm))
+		return -EINVAL;
+
+	if ((err = crypto_cipher_setkey(tfm, key, keylen)))
+	    return err;
+
+	tfm->__crt_alg->cra_cipher.cia_encrypt(crypto_tfm_ctx(tfm), key1,
+			(const u8*)tfm->crt_keyedhash.kht_xcbc_const);
+
+	return crypto_cipher_setkey(tfm, key1, bsize);
+
+}
+
+int crypto_xcbc_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
+{
+	struct xcbc_ops *ops = (struct xcbc_ops*)tfm->crt_keyedhash.kht_xcbc_block;
+
+	if (tfm->crt_keyedhash.kht_xcbc_const == NULL) 
+		return -EINVAL;
+
+	ops->len = 0;
+	memset(ops->prev, 0, crypto_tfm_alg_blocksize(tfm));
+	memset(tfm->crt_cipher.cit_iv, 0, crypto_tfm_alg_blocksize(tfm));
+	return _crypto_xcbc_init(tfm, key, *keylen);
+}
+
+void crypto_xcbc_update(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg)
+{
+	struct xcbc_ops *ops = (struct xcbc_ops*)tfm->crt_keyedhash.kht_xcbc_block;
+	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+	unsigned int i;
+
+	if (!(tfm->crt_cipher.cit_mode & CRYPTO_TFM_MODE_XCBC))
+		return;
+ 
+	for(i = 0; i < nsg; i++) {
+
+		struct page *pg = sg[i].page;
+		unsigned int offset = sg[i].offset;
+		unsigned int slen = sg[i].length;
+
+		while (slen > 0) {
+			unsigned int len = min(slen, ((unsigned int)(PAGE_SIZE)) - offset);
+			char *p = crypto_kmap(pg, 0) + offset;
+
+			/* checking the data can fill the block */
+			if ((ops->len + len) <= bsize) {
+				memcpy(ops->prev + ops->len, p, len);
+				ops->len += len;
+				slen -= len;
+
+				/* checking the rest of the page */
+				if (len + offset >= PAGE_SIZE) {
+					offset = 0;
+					pg++;
+				} else
+					offset += len;
+
+				crypto_kunmap(p, 0);
+				crypto_yield(tfm);
+				continue;
+			}
+
+			/* filling ops->prev with new data and encrypting it */
+			memcpy(ops->prev + ops->len, p, bsize - ops->len);
+			len -= bsize - ops->len;
+			p += bsize - ops->len;
+			tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv,
+							ops->prev);
+			tfm->__crt_alg->cra_cipher.cia_encrypt(
+				crypto_tfm_ctx(tfm), tfm->crt_cipher.cit_iv,
+				tfm->crt_cipher.cit_iv);
+
+			/* clearing the length */
+			ops->len = 0;
+
+			/* encrypting the rest of data */
+			while (len > bsize) {
+				tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, p);
+				tfm->__crt_alg->cra_cipher.cia_encrypt(
+					crypto_tfm_ctx(tfm), tfm->crt_cipher.cit_iv,
+					tfm->crt_cipher.cit_iv);
+				p += bsize;
+				len -= bsize;
+			}
+
+			/* keeping the surplus of blocksize */
+			if (len) {
+				memcpy(ops->prev, p, len);
+				ops->len = len;
+			}
+			crypto_kunmap(p, 0);
+			crypto_yield(tfm);
+			slen -= min(slen, ((unsigned int)(PAGE_SIZE)) - offset);
+			offset = 0;
+			pg++;
+		}
+	}
+}
+
+int crypto_xcbc_final(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, u8 *out)
+{
+	struct xcbc_ops *ops = (struct xcbc_ops*)tfm->crt_keyedhash.kht_xcbc_block;
+	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+	int ret = 0;
+
+	if (!(tfm->crt_cipher.cit_mode & CRYPTO_TFM_MODE_XCBC))
+		return -EINVAL;
+
+	if (*keylen != bsize)
+		return -EINVAL;
+
+	if (ops->len == bsize) {
+		u8 key2[bsize];
+
+		if ((ret = crypto_cipher_setkey(tfm, key, *keylen)))
+			return ret;
+
+		tfm->__crt_alg->cra_cipher.cia_encrypt(crypto_tfm_ctx(tfm), key2,
+				(const u8*)(tfm->crt_keyedhash.kht_xcbc_const+bsize));
+		tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, ops->prev);
+		tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, key2);
+
+		_crypto_xcbc_init(tfm, key, *keylen);
+
+		tfm->__crt_alg->cra_cipher.cia_encrypt(crypto_tfm_ctx(tfm), out, tfm->crt_cipher.cit_iv);
+	} else {
+		u8 key3[bsize];
+		unsigned int rlen;
+		u8 *p = ops->prev + ops->len;
+		*p = 0x80;
+		p++;
+
+		rlen = bsize - ops->len -1;
+		if (rlen)
+			memset(p, 0, rlen);
+
+		if ((ret = crypto_cipher_setkey(tfm, key, *keylen)))
+			return ret;
+
+		tfm->__crt_alg->cra_cipher.cia_encrypt(crypto_tfm_ctx(tfm), key3,
+				(const u8*)(tfm->crt_keyedhash.kht_xcbc_const+bsize*2));
+
+		tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, ops->prev);
+		tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, key3);
+		_crypto_xcbc_init(tfm, key, *keylen);
+		tfm->__crt_alg->cra_cipher.cia_encrypt(crypto_tfm_ctx(tfm), out, tfm->crt_cipher.cit_iv);
+	}
+
+	return ret;
+}
+
+int crypto_xcbc(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
+		struct scatterlist *sg, unsigned int nsg, u8 *out)
+{
+	int ret = 0;
+
+	ret = crypto_xcbc_init(tfm, key, keylen);
+	if (ret)
+		return ret;
+	crypto_xcbc_update(tfm, sg, nsg);
+	ret = crypto_xcbc_final(tfm, key, keylen, out);
+
+	return ret;
+}
+
+EXPORT_SYMBOL_GPL(crypto_xcbc_init);
+EXPORT_SYMBOL_GPL(crypto_xcbc_update);
+EXPORT_SYMBOL_GPL(crypto_xcbc_final);
+EXPORT_SYMBOL_GPL(crypto_xcbc);
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 1ade651..c4bc3c2 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -45,6 +45,7 @@
 #define CRYPTO_TFM_MODE_CFB		0x00000004
 #define CRYPTO_TFM_MODE_CTR		0x00000008
 #define CRYPTO_TFM_MODE_HMAC		0x00000080
+#define CRYPTO_TFM_MODE_XCBC		0x00000080
 
 #define CRYPTO_TFM_REQ_WEAK_KEY		0x00000100
 #define CRYPTO_TFM_REQ_MAY_SLEEP	0x00000200
@@ -217,9 +218,22 @@ struct compress_tfm {
 #define crt_digest	crt_u.digest
 #define crt_compress	crt_u.compress
 
-#if defined(CONFIG_CRYPTO_HMAC)
+#if defined(CONFIG_CRYPTO_HMAC) || defined(CONFIG_CRYPTO_XCBC)
+struct cit_xcbc_ctx {
+	/*
+	 * XCBC needs 3 constants for the derived keys.
+	 * Each lengh of those must equal the cipher
+	 * block size so that cit_xcbc_const's length is
+	 * 3 times of the blocksize and it contains
+	 * concantinated constants.
+	 */
+	void *_block;
+	u8 *_const;
+};
 
 #define kht_hmac_block	kht_u.hmac_block
+#define kht_xcbc_block	kht_u.xcbc_ctx._block
+#define kht_xcbc_const	kht_u.xcbc_ctx._const
 
 struct keyed_hash_tfm {
 	int (*kht_init)(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
@@ -230,6 +244,7 @@ struct keyed_hash_tfm {
 	unsigned int (*kht_digestsize)(struct crypto_tfm *tfm);
 	union {
 		void *hmac_block;
+		struct cit_xcbc_ctx xcbc_ctx;
 	} kht_u;
 };
 #endif
@@ -459,5 +474,16 @@ int crypto_hmac(struct crypto_tfm *tfm, 
                  struct scatterlist *sg, unsigned int nsg, u8 *out);
 #endif	/* CONFIG_CRYPTO_HMAC */
 
-#endif	/* _LINUX_CRYPTO_H */
+/*
+ *  * XCBC support
+ *   */
+#ifdef CONFIG_CRYPTO_XCBC
+int crypto_xcbc_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
+void crypto_xcbc_update(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg);
+int crypto_xcbc_final(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, u8
+		*out);
+int crypto_xcbc(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
+		                struct scatterlist *sg, unsigned int nsg, u8 *out);
+#endif /* CONFIG_CRYPTO_XCBC */
+#endif  /* _LINUX_CRYPTO_H */
 



^ permalink raw reply related

* HELP! Slip Interface losing packets. Looking for contractor to fix.
From: Butler, Gerald @ 2006-06-13 15:48 UTC (permalink / raw)
  To: netdev, linux-kernel, linux-serial


Hello,


 	We have a custom compiled Linux Kernel running oh RHEL 3.1


 		[root@st0056_1 root]# uname -a
 		Linux st0056_1 2.4.21-32.0.1.ELcustom #12 SMP Wed Sep 14 11:55:22 EDT 2005 i686 i686 i386 GNU/Linux


 	We compiled in SLIP support using the standard RHEL kernel supplied by Redhat. Unfortunately, RH does not support SLIP. We are experiencing problems that we believe are a kernel issue (either SLIP or SERIAL) and are interested in hiring a contractor to diagnose the problem and provide a kernel patch to the kernel we are using (if necessary). We do not want to upgrade or change distributions at this time (business/practicality reasons).


 	If you are interested, please send an e-mail with your resume (doc, odf, or plain text) to 'gerald.edward.butler@gmail.com' (I'll provide a private e-mail address to interested parties).


 	The company website is here: http://www.sterlingjewelers.com/


 Thank You,
 



 	Gerald Butler
 	Project Manager - Store Systems
 	Sterling Inc
 




The information contained in this e-mail message is privileged and/or
confidential and is intended only for the use of the individual or entity
named above.  If the reader of this message is not the intended
recipient, or the employee or agent responsible to deliver it to the
intended recipient, you are hereby notified that any dissemination,
distribution or copying of this communication is strictly prohibited.
If you have received this communication in error, please immediately
notify us by telephone (330-668-5000), and destroy the original
message.  Thank you.


^ permalink raw reply

* Re: http://bugzilla.kernel.org/show_bug.cgi?id=6197
From: Patrick McHardy @ 2006-06-13 15:57 UTC (permalink / raw)
  To: Andrew Morton; +Cc: netdev
In-Reply-To: <20060611055132.2930b95f.akpm@osdl.org>

Andrew Morton wrote:
> The reporter claims this is a netfilter bug.
> 

ipt_IMQ                 1949  36
imq                     4023  0

He patched his kernel with the IMQ device, which is known to cause all
kinds of weird problems.

^ permalink raw reply

* Re: [PATCH 1/2] AES-XCBC-MAC
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-06-13 16:10 UTC (permalink / raw)
  To: kazunori; +Cc: davem, herbert, netdev, usagi-core, yoshfuji
In-Reply-To: <1150213440.4200.36.camel@hookipa>

In article <1150213440.4200.36.camel@hookipa> (at Wed, 14 Jun 2006 00:44:00 +0900), Kazunori MIYAZAWA <kazunori@miyazawa.org> says:

> This is preparation to introduce AES-XCBC-MAC.
> - introducing common interface "keyed hash"
> - making HMAC use the interface

Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>

BTW, why not sign off?

-- 
YOSHIFUJI Hideaki @ USAGI Project  <yoshfuji@linux-ipv6.org>
GPG-FP  : 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply

* Re: [PATCH 2/2] AES-XCBC-MAC
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-06-13 16:19 UTC (permalink / raw)
  To: kazunori; +Cc: davem, herbert, netdev, usagi-core
In-Reply-To: <1150213447.4200.37.camel@hookipa>

In article <1150213447.4200.37.camel@hookipa> (at Wed, 14 Jun 2006 00:44:06 +0900), Kazunori MIYAZAWA <kazunori@miyazawa.org> says:

> This patch introduces AES-XCBC-MAC using the "keyed hash" interface.
> It accordingly depends on the previous patch.
> 
> Signed-off-by: Kazunori MIYAZAWA <miyazawa@linux-ipv6.org>
Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>

--yoshfuji

^ permalink raw reply

* Re: [RFC/PATCH 2/2] update sunrpc to use in-kernel sockets API
From: Sridhar Samudrala @ 2006-06-13 16:20 UTC (permalink / raw)
  To: James Morris; +Cc: netdev, linux-kernel
In-Reply-To: <Pine.LNX.4.64.0606131006250.3553@d.namei>

On Tue, 2006-06-13 at 10:07 -0400, James Morris wrote:
> On Mon, 12 Jun 2006, Sridhar Samudrala wrote:
> 
> > > > -	sendpage = sock->ops->sendpage ? : sock_no_sendpage;
> > > > +	sendpage = kernel_sendpage ? : sock_no_sendpage;
> > > >     
> > > 
> > > This is not equivalent.
> > > 
> > >   
> > Actually, we could make this a simple assignment as we check for
> > sock->ops->sendpage in
> > kernel_sendpage().
> >    sendpage = kernel_sendpage;
> 
> No, the code there is setting different values for sendpage depending on 
> whether the page is in high memory or not.

I guess you are referring to the following if stmt in xs_sendpages()
           if (PageHighMem(*ppage))
                   sendpage = sock_no_sendpage;
           err = sendpage(sock, *ppage, base, len, flags);

My patch doesn't touch this section of the code and this is called 
after the assignment we are talking about. So we should be using the
right sendpage in the actual call.

See the updated revised patch.

Thanks
Sridhar

diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -388,7 +388,7 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	/* send head */
 	if (slen == xdr->head[0].iov_len)
 		flags = 0;
-	len = sock->ops->sendpage(sock, rqstp->rq_respages[0], 0, xdr->head[0].iov_len, flags);
+	len = kernel_sendpage(sock, rqstp->rq_respages[0], 0, xdr->head[0].iov_len, flags);
 	if (len != xdr->head[0].iov_len)
 		goto out;
 	slen -= xdr->head[0].iov_len;
@@ -400,7 +400,7 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	while (pglen > 0) {
 		if (slen == size)
 			flags = 0;
-		result = sock->ops->sendpage(sock, *ppage, base, size, flags);
+		result = kernel_sendpage(sock, *ppage, base, size, flags);
 		if (result > 0)
 			len += result;
 		if (result != size)
@@ -413,7 +413,7 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	}
 	/* send tail */
 	if (xdr->tail[0].iov_len) {
-		result = sock->ops->sendpage(sock, rqstp->rq_respages[rqstp->rq_restailpage], 
+		result = kernel_sendpage(sock, rqstp->rq_respages[rqstp->rq_restailpage], 
 					     ((unsigned long)xdr->tail[0].iov_base)& (PAGE_SIZE-1),
 					     xdr->tail[0].iov_len, 0);
 
@@ -434,13 +434,10 @@ out:
 static int
 svc_recv_available(struct svc_sock *svsk)
 {
-	mm_segment_t	oldfs;
 	struct socket	*sock = svsk->sk_sock;
 	int		avail, err;
 
-	oldfs = get_fs(); set_fs(KERNEL_DS);
-	err = sock->ops->ioctl(sock, TIOCINQ, (unsigned long) &avail);
-	set_fs(oldfs);
+	err = kernel_ioctl(sock, TIOCINQ, (unsigned long) &avail);
 
 	return (err >= 0)? avail : err;
 }
@@ -472,7 +469,7 @@ svc_recvfrom(struct svc_rqst *rqstp, str
 	 * at accept time. FIXME
 	 */
 	alen = sizeof(rqstp->rq_addr);
-	sock->ops->getname(sock, (struct sockaddr *)&rqstp->rq_addr, &alen, 1);
+	kernel_getpeername(sock, (struct sockaddr *)&rqstp->rq_addr, &alen);
 
 	dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
 		rqstp->rq_sock, iov[0].iov_base, iov[0].iov_len, len);
@@ -758,7 +755,6 @@ svc_tcp_accept(struct svc_sock *svsk)
 	struct svc_serv	*serv = svsk->sk_server;
 	struct socket	*sock = svsk->sk_sock;
 	struct socket	*newsock;
-	const struct proto_ops *ops;
 	struct svc_sock	*newsvsk;
 	int		err, slen;
 
@@ -766,29 +762,23 @@ svc_tcp_accept(struct svc_sock *svsk)
 	if (!sock)
 		return;
 
-	err = sock_create_lite(PF_INET, SOCK_STREAM, IPPROTO_TCP, &newsock);
-	if (err) {
+	clear_bit(SK_CONN, &svsk->sk_flags);
+	err = kernel_accept(sock, &newsock, O_NONBLOCK);
+	if (err < 0) {
 		if (err == -ENOMEM)
 			printk(KERN_WARNING "%s: no more sockets!\n",
 			       serv->sv_name);
-		return;
-	}
-
-	dprintk("svc: tcp_accept %p allocated\n", newsock);
-	newsock->ops = ops = sock->ops;
-
-	clear_bit(SK_CONN, &svsk->sk_flags);
-	if ((err = ops->accept(sock, newsock, O_NONBLOCK)) < 0) {
-		if (err != -EAGAIN && net_ratelimit())
+		else if (err != -EAGAIN && net_ratelimit())
 			printk(KERN_WARNING "%s: accept failed (err %d)!\n",
 				   serv->sv_name, -err);
-		goto failed;		/* aborted connection or whatever */
+		return;
 	}
+
 	set_bit(SK_CONN, &svsk->sk_flags);
 	svc_sock_enqueue(svsk);
 
 	slen = sizeof(sin);
-	err = ops->getname(newsock, (struct sockaddr *) &sin, &slen, 1);
+	err = kernel_getpeername(newsock, (struct sockaddr *) &sin, &slen);
 	if (err < 0) {
 		if (net_ratelimit())
 			printk(KERN_WARNING "%s: peername failed (err %d)!\n",
@@ -1407,14 +1397,14 @@ svc_create_socket(struct svc_serv *serv,
 	if (sin != NULL) {
 		if (type == SOCK_STREAM)
 			sock->sk->sk_reuse = 1; /* allow address reuse */
-		error = sock->ops->bind(sock, (struct sockaddr *) sin,
+		error = kernel_bind(sock, (struct sockaddr *) sin,
 						sizeof(*sin));
 		if (error < 0)
 			goto bummer;
 	}
 
 	if (protocol == IPPROTO_TCP) {
-		if ((error = sock->ops->listen(sock, 64)) < 0)
+		if ((error = kernel_listen(sock, 64)) < 0)
 			goto bummer;
 	}
 
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -207,7 +207,7 @@ static inline int xs_sendpages(struct so
 		base &= ~PAGE_CACHE_MASK;
 	}
 
-	sendpage = sock->ops->sendpage ? : sock_no_sendpage;
+	sendpage = kernel_sendpage;
 	do {
 		int flags = XS_SENDMSG_FLAGS;
 
@@ -952,7 +952,7 @@ static int xs_bindresvport(struct rpc_xp
 
 	do {
 		myaddr.sin_port = htons(port);
-		err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
+		err = kernel_bind(sock, (struct sockaddr *) &myaddr,
 						sizeof(myaddr));
 		if (err == 0) {
 			xprt->port = port;
@@ -1047,7 +1047,7 @@ static void xs_tcp_reuse_connection(stru
 	 */
 	memset(&any, 0, sizeof(any));
 	any.sa_family = AF_UNSPEC;
-	result = sock->ops->connect(sock, &any, sizeof(any), 0);
+	result = kernel_connect(sock, &any, sizeof(any), 0);
 	if (result)
 		dprintk("RPC:      AF_UNSPEC connect return code %d\n",
 				result);
@@ -1117,7 +1117,7 @@ static void xs_tcp_connect_worker(void *
 	/* Tell the socket layer to start connecting... */
 	xprt->stat.connect_count++;
 	xprt->stat.connect_start = jiffies;
-	status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
+	status = kernel_connect(sock, (struct sockaddr *) &xprt->addr,
 			sizeof(xprt->addr), O_NONBLOCK);
 	dprintk("RPC: %p  connect status %d connected %d sock state %d\n",
 			xprt, -status, xprt_connected(xprt), sock->sk->sk_state);





^ permalink raw reply

* Re: [PATCH 03/16] 64bit resource: fix up printks for resources in networks drivers
From: Jesse Brandeburg @ 2006-06-13 16:24 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Greg Kroah-Hartman, NetDEV list
In-Reply-To: <11501586871870-git-send-email-greg@kroah.com>

First, added netdev,

On 6/12/06, Greg KH <greg@kroah.com> wrote:
> From: Greg Kroah-Hartman <gregkh@suse.de>
>
> This is needed if we wish to change the size of the resource structures.
>
> Based on an original patch from Vivek Goyal <vgoyal@in.ibm.com>
>
> Cc: Vivek Goyal <vgoyal@in.ibm.com>
> Cc: Andrew Morton <akpm@osdl.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
> ---
>  drivers/net/3c59x.c            |    6 ++++--
>  drivers/net/8139cp.c           |    9 +++++----
>  drivers/net/8139too.c          |    6 +++---
>  drivers/net/e100.c             |    4 ++--
>  drivers/net/skge.c             |    4 ++--
>  drivers/net/sky2.c             |    6 +++---
>  drivers/net/tulip/de2104x.c    |    9 +++++----
>  drivers/net/tulip/tulip_core.c |    6 +++---
>  drivers/net/typhoon.c          |    5 +++--
>  drivers/net/wan/dscc4.c        |   12 ++++++------
>  drivers/net/wan/pc300_drv.c    |    4 ++--
>  11 files changed, 38 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/net/e100.c b/drivers/net/e100.c
> index 31ac001..0c0bd67 100644
> --- a/drivers/net/e100.c
> +++ b/drivers/net/e100.c
> @@ -2678,9 +2678,9 @@ #endif
>                 goto err_out_free;
>         }
>
> -       DPRINTK(PROBE, INFO, "addr 0x%lx, irq %d, "
> +       DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, "
>                 "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
> -               pci_resource_start(pdev, 0), pdev->irq,
> +               (unsigned long long)pci_resource_start(pdev, 0), pdev->irq,
>                 netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
>                 netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);

color me confused, but why is this change necessary for e100?  e100
can not support 64 bit BARs, so it seems to me to make little sense to
cast to unsigned long long.  e100 is 32 bit the whole way through.

Jesse

^ permalink raw reply

* Re: [RFC/PATCH 1/2] in-kernel sockets API
From: Sridhar Samudrala @ 2006-06-13 16:27 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netdev, linux-kernel
In-Reply-To: <Pine.LNX.4.61.0606131657050.14789@yvahk01.tjqt.qr>

On Tue, 2006-06-13 at 16:58 +0200, Jan Engelhardt wrote:
> >+extern int kernel_ioctl(struct socket *sock, int cmd, unsigned long arg);
> >+
> 
> I would prefer naming it kernel_sock_ioctl, since (general) ioctl often 
> done on fds (or struct file * for that matter) rather than sockets.

I agree that this is misleading.
My original preference was to use ksock_ prefix for all these wrapper
functions. But just to be consistent with the existing kernel_sendmsg
and kernel_recvmsg, i used kernel_ prefix.
If it is OK, i could rename them also to use the ksock_ prefix to make
them all consistent and also indicating that we are operating on sockets.
If not, i will go with kernel_sock_ioctl().

Thanks
Sridhar



^ permalink raw reply

* Re: HELP! Slip Interface losing packets. Looking for contractor to fix.
From: Paul Fulghum @ 2006-06-13 16:32 UTC (permalink / raw)
  To: Butler, Gerald; +Cc: netdev, linux-kernel, linux-serial
In-Reply-To: <7697221D47CA0545961FA7846257369103A860C8@ex01.jewels.local>

Butler, Gerald wrote:
> ... a custom compiled Linux Kernel running oh RHEL 3.1

If you post more details (precise description
of hardware setup, problem, and
method of reproducing) you might get a patch for free.

-- 
Paul Fulghum
Microgate Systems, Ltd.

^ permalink raw reply

* Re: [PATCH 03/16] 64bit resource: fix up printks for resources in networks drivers
From: Greg KH @ 2006-06-13 16:30 UTC (permalink / raw)
  To: Jesse Brandeburg; +Cc: Greg KH, linux-kernel, NetDEV list
In-Reply-To: <4807377b0606130924i4b5ea36aq83b8db050831bea4@mail.gmail.com>

On Tue, Jun 13, 2006 at 09:24:55AM -0700, Jesse Brandeburg wrote:
> First, added netdev,
> 
> On 6/12/06, Greg KH <greg@kroah.com> wrote:
> >From: Greg Kroah-Hartman <gregkh@suse.de>
> >
> >This is needed if we wish to change the size of the resource structures.
> >
> >Based on an original patch from Vivek Goyal <vgoyal@in.ibm.com>
> >
> >Cc: Vivek Goyal <vgoyal@in.ibm.com>
> >Cc: Andrew Morton <akpm@osdl.org>
> >Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
> >---
> > drivers/net/3c59x.c            |    6 ++++--
> > drivers/net/8139cp.c           |    9 +++++----
> > drivers/net/8139too.c          |    6 +++---
> > drivers/net/e100.c             |    4 ++--
> > drivers/net/skge.c             |    4 ++--
> > drivers/net/sky2.c             |    6 +++---
> > drivers/net/tulip/de2104x.c    |    9 +++++----
> > drivers/net/tulip/tulip_core.c |    6 +++---
> > drivers/net/typhoon.c          |    5 +++--
> > drivers/net/wan/dscc4.c        |   12 ++++++------
> > drivers/net/wan/pc300_drv.c    |    4 ++--
> > 11 files changed, 38 insertions(+), 33 deletions(-)
> >
> >diff --git a/drivers/net/e100.c b/drivers/net/e100.c
> >index 31ac001..0c0bd67 100644
> >--- a/drivers/net/e100.c
> >+++ b/drivers/net/e100.c
> >@@ -2678,9 +2678,9 @@ #endif
> >                goto err_out_free;
> >        }
> >
> >-       DPRINTK(PROBE, INFO, "addr 0x%lx, irq %d, "
> >+       DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, "
> >                "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
> >-               pci_resource_start(pdev, 0), pdev->irq,
> >+               (unsigned long long)pci_resource_start(pdev, 0), pdev->irq,
> >                netdev->dev_addr[0], netdev->dev_addr[1], 
> >                netdev->dev_addr[2],
> >                netdev->dev_addr[3], netdev->dev_addr[4], 
> >                netdev->dev_addr[5]);
> 
> color me confused, but why is this change necessary for e100?  e100
> can not support 64 bit BARs, so it seems to me to make little sense to
> cast to unsigned long long.  e100 is 32 bit the whole way through.

Because the result of pci_resource_start() just became either u32 or u64
depending on a config option, and so, to keep everything sane, we just
always cast it to unsigned long long, which makes everyone happy.

Hope this helps,

greg k-h

^ permalink raw reply

* Re: [IPV6]: Fix RTNLGRP_IPV6_IFINFO netlink notifications
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-06-13 16:39 UTC (permalink / raw)
  To: kaber, davem; +Cc: netdev, yoshfuji
In-Reply-To: <448EE1CA.7020603@trash.net>

In article <448EE1CA.7020603@trash.net> (at Tue, 13 Jun 2006 18:03:22 +0200), Patrick McHardy <kaber@trash.net> says:

> Yes, thats better. I also thing we shouldn't return -EINVAL but
> -ENOSPC or something like that, -EINVAL usually indicated that
> the user sent an invalid message, which isn't the case here.
> Maybe a WARN_ON would also be appropriate, since this condition
> always means there is a bug.

Yes, but that's another issue.
Of course, you can cook up patch for it.


> > How about this?
> > 
> > +/* Maximum length of ifinfomsg attributes */
> > +#define INET6_IFINFO_RTA_SPACE \
> > +		RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \
:
> This doesn't seem to account for IFLA_LINK. Other than that it looks
> fine too me.

[IPV6]: Sum real space for RTAs.

This patch fixes RTNLGRP_IPV6_IFINFO netlink notifications.
Issue pointed out by Patrick McHardy <kaber@trash.net>.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 445006e..c2c26fa 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2860,6 +2860,11 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
 	return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen);
 }
 
+/* Maximum length of ifa_cacheinfo attributes */
+#define INET6_IFADDR_RTA_SPACE \
+		RTA_SPACE(16) /* IFA_ADDRESS */ + \
+		RTA_SPACE(sizeof(struct ifa_cacheinfo)) /* CACHEINFO */
+
 static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
 			     u32 pid, u32 seq, int event, unsigned int flags)
 {
@@ -3092,7 +3097,7 @@ static int inet6_dump_ifacaddr(struct sk
 static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
 {
 	struct sk_buff *skb;
-	int size = NLMSG_SPACE(sizeof(struct ifaddrmsg)+128);
+	int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE);
 
 	skb = alloc_skb(size, GFP_ATOMIC);
 	if (!skb) {
@@ -3142,6 +3147,17 @@ #endif
 #endif
 }
 
+/* Maximum length of ifinfomsg attributes */
+#define INET6_IFINFO_RTA_SPACE \
+		RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \
+		RTA_SPACE(MAX_ADDR_LEN) /* ADDRESS */ +	\
+		RTA_SPACE(sizeof(u32)) /* MTU */ + \
+		RTA_SPACE(sizeof(int)) /* LINK */ + \
+		RTA_SPACE(0) /* PROTINFO */ + \
+		RTA_SPACE(sizeof(u32)) /* FLAGS */ + \
+		RTA_SPACE(sizeof(struct ifla_cacheinfo)) /* CACHEINFO */ + \
+		RTA_SPACE(sizeof(__s32[DEVCONF_MAX])) /* CONF */
+
 static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 
 			     u32 pid, u32 seq, int event, unsigned int flags)
 {
@@ -3235,8 +3251,7 @@ static int inet6_dump_ifinfo(struct sk_b
 void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
 {
 	struct sk_buff *skb;
-	/* 128 bytes ?? */
-	int size = NLMSG_SPACE(sizeof(struct ifinfomsg)+128);
+	int size = NLMSG_SPACE(sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE);
 	
 	skb = alloc_skb(size, GFP_ATOMIC);
 	if (!skb) {
@@ -3252,6 +3267,11 @@ void inet6_ifinfo_notify(int event, stru
 	netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFINFO, GFP_ATOMIC);
 }
 
+/* Maximum length of prefix_cacheinfo attributes */
+#define INET6_PREFIX_RTA_SPACE \
+		RTA_SPACE(sizeof(((struct prefix_info *)NULL)->prefix)) /* ADDRESS */ + \
+		RTA_SPACE(sizeof(struct prefix_cacheinfo)) /* CACHEINFO */
+
 static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
 			struct prefix_info *pinfo, u32 pid, u32 seq, 
 			int event, unsigned int flags)
@@ -3296,7 +3316,7 @@ static void inet6_prefix_notify(int even
 			 struct prefix_info *pinfo)
 {
 	struct sk_buff *skb;
-	int size = NLMSG_SPACE(sizeof(struct prefixmsg)+128);
+	int size = NLMSG_SPACE(sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE);
 
 	skb = alloc_skb(size, GFP_ATOMIC);
 	if (!skb) {

^ permalink raw reply related

* Re: [RFT 0/5] sky2: suspend/resume patchlets
From: Linus Torvalds @ 2006-06-13 16:38 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Jeff Garzik, netdev, David S. Miller
In-Reply-To: <20060613081726.695812000@localhost.localdomain>


[ Davem - see the final conclusion: this might not be a driver bug as much 
  as a netconsole problem, where netconsole might perhaps continue sendign 
  on a device that really can't take it any more? ]

On Tue, 13 Jun 2006, Stephen Hemminger wrote:
>
> There were a several problems buried in suspend/resume. The real
> failure was caused by the idle timer not being stopped/restarted.
> But several other races, and cleanups were needed.
> 
> Since I don't have a machine that will suspend successfully with
> that hardware, I can't test it.

With this, I get a page-fault in sky2_tx_complete+0x91 (with traceback to 
sky2_poll, net_rx_action, do_softirq, do_IRQ, skb_release_data, kfree_skb, 
sky2_rx_clean, sky2_down, sky2_suspend, pci_device_suspend, all the way 
down to suspend_device()).

So an IRQ happened while the sky2 driver was doign sky2_rx_clean, which is 
just _after_ it did "sky2_tx_clean()", and then the TX side was unhappy 
for some reason.

Again, the driver has actually tried to disable its _own_ irq, but that 
doesn't much help. Also, with write posting, even its own irq might have 
gotten delayed (ie if you really want to synchronize irq's, you need to 
read from the device, and then also wait a bit to see that the irq isn't 
being posted int he _other_ direction), but in the presense of shared 
irq's, it just doesn't do anything at all.

I can't seem to get a bigger VGA console on the Mac mini, so I'm unable to 
see the exact register values.

Btw, this probably happens with my patch too, and is likely 
timing-related.

Oh, and to make matters worse, I also enabled netconsole (in order to see 
what goes wrong), which is probably what brought on the horrid timing 
issue (ie packets going out _just_ at the right time saying "shutting 
down sky2")

Btw, that "sky2_tx_complete+0x91" seems to be 

	loop:
		inc    %edx
		mov    0x9c(%ecx),%eax
	**	movzwl 0x4(%eax),%eax	**
		cmp    %eax,%edx
		jb loop

which in turn is:

                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                        struct tx_ring_info *fre;
                        fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE);
                        pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
                                       skb_shinfo(skb)->frags[i].size,
                                       PCI_DMA_TODEVICE);
                }

since pci_unmap_page() is a no-op here ;)

So it looks like it's the "skb_shinfo(skb)->nr_frags" access that oopses.

Which probably means that

	skb = re->skb;

just got garbage (rememebr: the pci_unmap_single() directly after it is 
_also_ a no-op, so it wouldn't oops there).

I dunno the details. I'd have _expected_ tx_cons to be equal to tx_prod 
here (since we just did a sky2_tx_clean() before), and the loop to not 
have been entered at all, but I wonder if maybe it's the netconsole that 
doesn't honor "netif_stop_queue()"?

Dunno.

			Linus

^ permalink raw reply

* Re: Network Performance Comparison between Linux 2.4 and 2.6
From: Rick Jones @ 2006-06-13 16:44 UTC (permalink / raw)
  To: Bharath; +Cc: netdev
In-Reply-To: <c4166a920606130408m7780f956i814abb2d3f5aaf78@mail.gmail.com>

> I have included the throughput figures for bridging for both 2.4 and
> 2.6 kernels in the table below.
> Packet Size(bytes)            2.4.31(Mbps)          2.6.16(Mbps)
> ------------------------------------------------------------------------------------------ 
> 
> 64                                     2.11                       2.19
> 128                                    3.59                       3.75
> 256                                    6.33                       6.48
> 512                                   10.93                      11.16
> 1024                                 17.49                      17.33
> 1280                                 20.00                      19.83
> 1518                                 22.09                      19.91
> 
> About the tests, the MIPS malta board has two D-Link PCI ethernet
> cards. A bridge br0 is configured over the two ethernet interfaces (
> eth0 and eth1). There is an external traffic generator that is
> configured to generate packets of above mentioned sizes and to measure
> the throughput correspondingly.
> 
> Please let me know if you need any more information.

It would be good to include mention of the CPU utilization of the system 
under test, even if it is just to say "the CPU was 100% utilized.

rick jones
http://www.netperf.org/

^ permalink raw reply

* Re: 2.6.17: networking bug??
From: Mark Lord @ 2006-06-13 16:58 UTC (permalink / raw)
  To: Linux Kernel; +Cc: netdev, Linus Torvalds
In-Reply-To: <448ED9B3.8050506@rtr.ca>

..
> The site www.everymac.com is still not browseable until
> setting /proc/sys/net/ipv4/tcp_window_scaling===0.
> 
> There's one other difference I see in the tcpdump traces.
> The first packets from each trace below show different
> values for "wscale".  The old (working) kernels use "wscale 2",
> whereas 2.6.17 uses "wscale 6".  In both cases, the value
> seen in /proc/sys/net/ipv4/tcp_adv_win_scale is 2.

Okay.  More progress here.  The calculation of the "wscale" values
is based on the "tcp_rmem" sysctl numbers.

The defaults for these *differ* between 2.6.16.18 and 2.6.17-rc*.

2.6.16: 4096    87380    174760  
2.6.17: 4096    87380   2097152

If I change the tcp_rmem setting on 2.6.17 to match the old value,
then the website www.everymac.com becomes accessible again:

echo 4096 87380 174760 > /proc/sys/net/ipv4/tcp_rmem

Looking at diffs between 2.6.16 and 2.6.17, I see a big rework
of the tcp_rmem code in linux/net/ipv4/tcp.c

Looks like something got broken there, or possibly the wscale
calculations have a bug that is only triggered by the new rmem values ??



^ permalink raw reply

* Re: 2.6.17: networking bug??
From: Mark Lord @ 2006-06-13 17:22 UTC (permalink / raw)
  To: Linux Kernel; +Cc: netdev, Linus Torvalds, jheffner, davem
In-Reply-To: <448EEE9D.10105@rtr.ca>

Mark Lord wrote:
> ..
>> The site www.everymac.com is still not browseable until
>> setting /proc/sys/net/ipv4/tcp_window_scaling===0.
>>
>> There's one other difference I see in the tcpdump traces.
>> The first packets from each trace below show different
>> values for "wscale".  The old (working) kernels use "wscale 2",
>> whereas 2.6.17 uses "wscale 6".  In both cases, the value
>> seen in /proc/sys/net/ipv4/tcp_adv_win_scale is 2.
> 
> Okay.  More progress here.  The calculation of the "wscale" values
> is based on the "tcp_rmem" sysctl numbers.
> 
> The defaults for these *differ* between 2.6.16.18 and 2.6.17-rc*.
> 
> 2.6.16: 4096    87380    174760
> 2.6.17: 4096    87380   2097152
> 
> If I change the tcp_rmem setting on 2.6.17 to match the old value,
> then the website www.everymac.com becomes accessible again:
> 
> echo 4096 87380 174760 > /proc/sys/net/ipv4/tcp_rmem
> 
> Looking at diffs between 2.6.16 and 2.6.17, I see a big rework
> of the tcp_rmem code in linux/net/ipv4/tcp.c
> 
> Looks like something got broken there, or possibly the wscale
> calculations have a bug that is only triggered by the new rmem values ??
> 

Okay, here's the blob that broke it.

> [TCP]: Set default max buffers from memory pool size
> author	John Heffner <jheffner@psc.edu>
> 	Sat, 25 Mar 2006 09:34:07 +0000 (01:34 -0800)
> committer	David S. Miller <davem@davemloft.net>
> 	Sat, 25 Mar 2006 09:34:07 +0000 (01:34 -0800)
> commit	7b4f4b5ebceab67ce440a61081a69f0265e17c2a
> tree	ac02c685ce23f2440fecbebaa5b55cd47947c03e	tree
> parent	2babf9daae4a3561f3264638a22ac7d0b14a6f52	commit | commitdiff
> [TCP]: Set default max buffers from memory pool size
> 
> This patch sets the maximum TCP buffer sizes (available to automatic
> buffer tuning, not to setsockopt) based on the TCP memory pool size.
> The maximum sndbuf and rcvbuf each will be up to 4 MB, but no more
> than 1/128 of the memory pressure threshold.
> 
> Signed-off-by: John Heffner <jheffner@psc.edu>
> Signed-off-by: David S. Miller <davem@davemloft.net>

John / David:  Any ideas on what's gone awry here?




^ permalink raw reply

* Netchannels: alternative TCP/IP stack?
From: Evgeniy Polyakov @ 2006-06-13 17:33 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <20060608171555.GA10273@2ka.mipt.ru>

Hello, developers.

I've implemented simple rfc793 TCP/IP stack, which is currently tested
in userspace through packet socket. After ISO (~650Mb) transfer over 
gigabit ethernet between two Linux boxes, file was not corrupted.

I would even say that stack is really trivial (1800 lines of code, 42K
of sources where TCP state machine takes about 12K), but it includes:
* routing table for src/dst IP and MAC addresses (O(n) access).
	It includes static destination routing and ARP cache.
	No dynamic ARP probes.
* socket-like (actually netchannel-like) interface for data reading.
* ethernet sending/receiving support.
* IP sending/receiving support.
* TCP (rfc793) state machine implementation.
* UDP code (not tested).

Current code does not have options and TCP extensions, ack generation
does not use any heueristics, no congestion control, no prediction
(although I have some doubts about that idea), no ICMP. 
Sending was not tested yet.
Next option in agenda is to check various loss and reordering
issues. Then I plan to implement PAWS and timestamp TCP option.
MSS option would be usefull too.

I want to run various tests with congestions to collect some statistic
about generic TCP/IP behaviour, so I would like to ask
how much it will be frowned upon if I will use that simple stack for
netchannels (I plan to use only alternative TCP part with generic Linux
routing tables, IP and ethernet processing and so on)
and if miracle happens (it happens sometimes) and results will be better
than it is now [1] (it is planned if paid job will not get all the time)
and I will start pushing it upstream?
Or is it better to just make lobotomy right now?

1. Netchannel benchmarks vs. socket code.
http://tservice.net.ru/~s0mbre/old/?section=projects&item=netchannel

Thank you.

-- 
	Evgeniy Polyakov

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).