Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 02/19] ndisc: Move ndisc_opt_addr_space() to include/net/ndisc.h.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:47 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

This also makes ndisc_opt_addr_data() and ndisc_fill_addr_option()
use ndisc_opt_addr_space().

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 include/net/ndisc.h |    8 +++++++-
 net/ipv6/ndisc.c    |    7 +------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index ec48f42..745bf74 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -127,13 +127,19 @@ static int ndisc_addr_option_pad(unsigned short type)
 	}
 }
 
+static inline int ndisc_opt_addr_space(struct net_device *dev)
+{
+	return NDISC_OPT_SPACE(dev->addr_len +
+			       ndisc_addr_option_pad(dev->type));
+}
+
 static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
 				      struct net_device *dev)
 {
 	u8 *lladdr = (u8 *)(p + 1);
 	int lladdrlen = p->nd_opt_len << 3;
 	int prepad = ndisc_addr_option_pad(dev->type);
-	if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad))
+	if (lladdrlen != ndisc_opt_addr_space(dev))
 		return NULL;
 	return lladdr + prepad;
 }
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 49dfc2a..82ccf0a 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -143,17 +143,12 @@ struct neigh_table nd_tbl = {
 	.gc_thresh3 =	1024,
 };
 
-static inline int ndisc_opt_addr_space(struct net_device *dev)
-{
-	return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
-}
-
 static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
 				  struct net_device *dev)
 {
 	int pad   = ndisc_addr_option_pad(dev->type);
 	int data_len = dev->addr_len;
-	int space = NDISC_OPT_SPACE(data_len + pad);
+	int space = ndisc_opt_addr_space(dev);
 
 	opt[0] = type;
 	opt[1] = space>>3;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 01/19] ndisc: Reduce number of arguments for ndisc_fill_addr_option().
From: YOSHIFUJI Hideaki @ 2013-01-21 16:47 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Add pointer to struct net_device (dev) and remove
data_len (= dev->addr_len) and addr_type (= dev->type).

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 067a0d2..49dfc2a 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -148,10 +148,11 @@ static inline int ndisc_opt_addr_space(struct net_device *dev)
 	return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
 }
 
-static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
-				  unsigned short addr_type)
+static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
+				  struct net_device *dev)
 {
-	int pad   = ndisc_addr_option_pad(addr_type);
+	int pad   = ndisc_addr_option_pad(dev->type);
+	int data_len = dev->addr_len;
 	int space = NDISC_OPT_SPACE(data_len + pad);
 
 	opt[0] = type;
@@ -420,8 +421,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	}
 
 	if (llinfo)
-		ndisc_fill_addr_option(opt, llinfo, dev->dev_addr,
-				       dev->addr_len, dev->type);
+		ndisc_fill_addr_option(opt, llinfo, dev->dev_addr, dev);
 
 	hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len,
 					   IPPROTO_ICMPV6,
@@ -1469,8 +1469,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	 */
 
 	if (ha)
-		opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha,
-					     dev->addr_len, dev->type);
+		opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha, dev);
 
 	/*
 	 *	build redirect option and copy skb over to the new packet.
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 00/19] IPv6 NDISC Updates
From: YOSHIFUJI Hideaki @ 2013-01-21 16:47 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

This series of changes basically clean up NDISC logic,
especially on sender side.

We originally do For NS/NA/RS:
 1) build temporary ICMPv6 header
 2) ndisc_build_skb() with temporary ICMPv6 header and rather
    criptic arguments.
    - Calculate total length and allocate sk_buff
    - Build IPv6 header.
    - copy ICMPv6 header, additional data and ND options.
    - Fill-in ICMPv6 checksum.
    Here, structures defined for message format was not used
    at all, it is difficult to understand what is being sent,
    and it was not generic.
 3) __ndisc_send()
    - Allocate temporary dst.
    - Send it.

Several issues:
- We could not defer decision if we should/can send some ND
  option.
- It is hard to see the packet format at a glance.
- ICMPv6 header was built as temporary variable, and then
  copied to the buffer.
- Some code path for Redirect was not shared.

With these patches, we do:
 1) Calculate (or estimate) message length and option length.
 2) Allocate skb (via new ndisc_skb_alloc()).
 3) Fill-in ICMPv6 message directly using compound literals.
 4) Fill-in ICMPv6 checksum
 5) Build IPv6 header (including length)
 6) Send the packet (via ndisc_send_skb()).
    - allocate temporary dst and send it.

- We can defer calculating real length of the packet.
  For example, we can give up filling some option at when
  filling in.
- Message is built directly without temporary buffer.
- Structures defined for message format is easier to understand
  what is being built.
- NS/NA/RS/Redirect share same logic.
- Reduced code/data size:
	   text	   data	    bss	    dec	    hex	filename
	 265407	  14133	   3488	 283028	  45194	old/net/ipv6/ipv6.o
	 264955	  14109	   3488	 282552	  44fb8	new/net/ipv6/ipv6.o

YOSHIFUJI Hideaki (19):
  ndisc: Reduce number of arguments for ndisc_fill_addr_option().
  ndisc: Move ndisc_opt_addr_space() to include/net/ndisc.h.
  ndisc: Use skb_linearize() instead of pskb_may_pull(skb, skb->len).
  ndisc: Introduce ndisc_fill_redirect_hdr_option().
  ndisc: Introduce ndisc_alloc_skb() helper.
  ipv6: Unshare ip6_nd_hdr() and change return type to void.
  ndisc: Simplify arguments for ip6_nd_hdr().
  ndisc: Set skb->dev and skb->protocol inside ndisc_alloc_skb().
  ndisc: Remove dev argument for ndisc_send_skb().
  ndisc: Defer building IPv6 header.
  ndisc: Reset skb->trasport_headner inside ndisc_alloc_send_skb().
  ndisc: Calculate message body length and option length separately.
  ndisc: Make ndisc_fill_xxx_option() for sk_buff.
  ndisc: Remove icmp6h argument from ndisc_send_skb().
  ndisc: Use ndisc_send_skb() for redirect.
  ndisc: Fill in ICMPv6 checksum and IPv6 header in ndisc_send_skb().
  ndisc: Break down __ndisc_send().
  ndisc: Break down ndisc_build_skb() and build message directly.
  ndisc: Use compound literals to build redirect message.

 include/net/ipv6.h    |    7 --
 include/net/ndisc.h   |    8 +-
 net/ipv6/ip6_output.c |   33 -----
 net/ipv6/mcast.c      |   29 ++++-
 net/ipv6/ndisc.c      |  331 +++++++++++++++++++++++++------------------------
 5 files changed, 203 insertions(+), 205 deletions(-)

-- 
1.7.9.5

^ permalink raw reply

* Re: [PATCH] CMAC support for CryptoAPI, fixed patch issues, indent, and testmgr build issues
From: David Dillow @ 2013-01-21 16:40 UTC (permalink / raw)
  To: Tom St Denis; +Cc: linux-kernel, David Miller, linux-crypto, netdev
In-Reply-To: <436404741.94502.1358773048618.JavaMail.root@elliptictech.com>

[Apologies for the dupe, fixing stupid typo for netdev address...
-ENOCAFFEINE]

I hesitate to reward the squeaky wheel, but in the community spirit,
here goes...

Please fix the subject for future submissions. The subject should be a
short, one line description of the patch. It helps if the subject
includes the section of the code you are affecting. Also, if you are
resending a patch after addressing review comments, change the tag to
[PATCH v2] etc. will indicate that. For example:
	[PATCH v2] crypto: add support for the NIST CMAC hash

This keeps the maintainers from having to hand edit your patch, which
dramatically slows them down. The goal is to get to a patch that can be
applied as-is after review.

On Mon, 2013-01-21 at 07:57 -0500, Tom St Denis wrote:
> Hey all,
> 
> Here's an updated patch which addresses a couple of build issues and
> coding style complaints.  
> 
> I still can't get it to run via testmgr I get 
> 
> [  162.407807] alg: No test for cmac(aes) (cmac(aes-generic))
> 
> Despite the fact I have an entry for cmac(aes) (much like xcbc(aes)...).
> 
> Here's the patch to bring 3.8-rc4 up with CMAC ...

All of this commentary should go after the '---' separator; the
maintainer will have to hand edit it out otherwise. It's good
information, it's just the wrong place.

There should be a short description here of the patch, if needed. You
may be fine with the one line description in this case, or you could
point to the RFC, etc.

> Signed-off-by: Tom St Denis <tstdenis@elliptictech.com>
> 
> ---
>  crypto/Kconfig               |   8 ++
>  crypto/Makefile              |   1 +
>  crypto/cmac.c                | 317 +++++++++++++++++++++++++++++++++++++++++++
>  crypto/testmgr.c             |   9 ++
>  crypto/testmgr.h             |  52 +++++++
>  include/uapi/linux/pfkeyv2.h |   1 +
>  net/xfrm/xfrm_algo.c         |  17 +++

You may be asked to split out the net changes into a separate patch, but
since you are adding the user at the time you add the code, you may not.

>  7 files changed, 405 insertions(+)
>  create mode 100644 crypto/cmac.c
> 
> diff --git a/crypto/Kconfig b/crypto/Kconfig
> index 4641d95..5ac2c7f 100644
> --- a/crypto/Kconfig
> +++ b/crypto/Kconfig
> @@ -301,6 +301,14 @@ config CRYPTO_XCBC
>  		http://csrc.nist.gov/encryption/modes/proposedmodes/
>  		 xcbc-mac/xcbc-mac-spec.pdf
>  
> +config CRYPTO_CMAC
> +	tristate "CMAC support"
> +	depends on EXPERIMENTAL
> +	select CRYPTO_HASH
> +	select CRYPTO_MANAGER
> +	help
> +	  NIST CMAC cipher based MAC

Pointers to the docs as for XCBC above would be useful here.

> diff --git a/crypto/cmac.c b/crypto/cmac.c
> new file mode 100644
> index 0000000..1ffeea7
> --- /dev/null
> +++ b/crypto/cmac.c
> @@ -0,0 +1,317 @@
> +/*
> + * Copyright (C)2006 USAGI/WIDE Project

Add your copyright info, 2013?

> +static int crypto_cmac_digest_setkey(struct crypto_shash *parent,
> +					  const u8 *inkey, unsigned int keylen)
> +{
> +	unsigned long alignmask = crypto_shash_alignmask(parent);
> +	struct cmac_tfm_ctx *ctx = crypto_shash_ctx(parent);
> +	int bs = crypto_shash_blocksize(parent);
> +	u8 *consts = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
> +	int x, y, err = 0;
> +	u8 msb, mask;
> +
> +	switch (bs) {
> +	case 16:
> +		mask = 0x87;
> +		break;
> +	case 8:
> +		mask = 0x1B;
> +		break;
> +	default:
> +		return -EINVAL; /*  only support 64/128 bit block ciphers */

Checkpatch doesn't warn, but this comment would probably be preferred to
be on a line by itself.

> +	for (x = 0; x < 2; x++) {
> +		/* if msb(L * u^(x+1)) = 0 then just shift,
> +		otherwise shift and xor constant mask */

This comment is incorrectly formatted; I see checkpatch.pl from 3.7-rc4
didn't pick it up, which is interesting.
		/*
		 * if msb(L * u^(x+1)) = 0 then just shift,
		 * otherwise shift and xor constant mask
		 */

Though I'll note that doing 
	grep '/\*' crypto/*.c | grep -v '\*/' | less

provides evidence that it also commonly
		/* is msb....
		 */

> +		/* shift left */
> +		for (y = 0; y < (bs - 1); y++)
> +			consts[x*bs + y] =
> +				((consts[x*bs + y] << 1) |
> +				(consts[x*bs + y+1] >> 7)) & 255;

So, here is a case where you fixed two warnings at the same time, but
made one of them irrelevant in the process -- this should have braces
around the single statement. checkpatch.pl complained initially because
there was a one-line statement, but would not have complained if it
looked like you have it now. Also, probably want a spaces in the y+1, if
not the multiplication.

> +
> +		consts[x*bs + bs - 1] =
> +			((consts[x*bs + bs - 1] << 1) ^
> +			(msb ? mask : 0)) & 255;
> +
> +		/* copy up as require */

Minor English nit: required?

> +		if (x == 0)
> +			memcpy(&consts[(x+1)*bs], &consts[x*bs], bs);

perhaps some spacing, though I'm personally OK with it.

> diff --git a/crypto/testmgr.h b/crypto/testmgr.h
> index b5721e0..9688bfe 100644
> --- a/crypto/testmgr.h
> +++ b/crypto/testmgr.h
> @@ -1639,6 +1639,58 @@ static struct hash_testvec hmac_sha256_tv_template[] = {
>  	},
>  };
>  
> +#define CMAC_AES_TEST_VECTORS 4
> +
> +static struct hash_testvec aes_cmac128_tv_template[] = {
> +	{
> +		.key  = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab"
> +		"\xf7\x15\x88\x09\xcf\x4f\x3c",

There does seem to be some inconsistencies in the test vector
formatting, but it seems to be pretty common for the hex dumps to put 8
bytes in each part of the string, and to most line of the strings up.

Doing this alignment is how I found the missing \x in your first
submission.

> +		.plaintext = zeroed_string,
> +		.digest = "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f"
> +		"\xa3\x7d\x12\x9b\x75\x67\x46",
> +		.psize   = 0,
> +		.ksize   = 16,
> +	},
> +
> +	{

The rest of the file uses "}, { " between test vectors.


Because you are working in the networking code, you should cc netdev --
they need to review the following hunks. I don't know what the
allocation policy is for adding algorithm numbers in pfkeyv2, but they
would know if you are creating a conflict with other work.

> diff --git a/include/uapi/linux/pfkeyv2.h b/include/uapi/linux/pfkeyv2.h
> index 0b80c80..d61898e 100644
> --- a/include/uapi/linux/pfkeyv2.h
> +++ b/include/uapi/linux/pfkeyv2.h
> @@ -296,6 +296,7 @@ struct sadb_x_kmaddress {
>  #define SADB_X_AALG_SHA2_512HMAC	7
>  #define SADB_X_AALG_RIPEMD160HMAC	8
>  #define SADB_X_AALG_AES_XCBC_MAC	9
> +#define SADB_X_AALG_AES_CMAC_MAC	10
>  #define SADB_X_AALG_NULL		251	/* kame */
>  #define SADB_AALG_MAX			251
>  
> diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
> index 4ce2d93..bd6f227 100644
> --- a/net/xfrm/xfrm_algo.c
> +++ b/net/xfrm/xfrm_algo.c
> @@ -265,6 +265,23 @@ static struct xfrm_algo_desc aalg_list[] = {
>  	}
>  },
>  {
> +	.name = "cmac(aes)",
> +
> +	.uinfo = {
> +		.auth = {
> +			.icv_truncbits = 96,
> +			.icv_fullbits = 128,
> +		}
> +	},
> +
> +	.desc = {
> +		.sadb_alg_id = SADB_X_AALG_AES_CMAC_MAC,
> +		.sadb_alg_ivlen = 0,
> +		.sadb_alg_minbits = 128,
> +		.sadb_alg_maxbits = 128
> +	}
> +},
> +{
>  	.name = "xcbc(aes)",
>  
>  	.uinfo = {

^ permalink raw reply

* Re: [PATCH] Add support for netconsole driver used on bridge device with, VIF attached
From: Ian Campbell @ 2013-01-21 16:40 UTC (permalink / raw)
  To: yuval.shaia@oracle.com
  Cc: xen-devel@lists.xensource.com, netdev@vger.kernel.org
In-Reply-To: <50FD6E17.1010309@oracle.com>

On Mon, 2013-01-21 at 16:34 +0000, yuval.shaia@oracle.com wrote:
> When starting a VM which has virtual interface attached to the same 
> bridge (i.e vif = [type=netfront,bridge=xenbr0'] in vm.cfg) which is 
> used for netconsole the
> following message appears (after about 60 seconds) and VM creation 
> operation fails.
>       Error: Device 0 (vif) could not be connected. Hotplug scripts not 
> working.

I'm not sure how this can relate netconsole since this happens before
the guest even runs, doesn't it?

> Note:
> When trying to do the opposite, i.e. first create VM and then run
> netconsole we got the error #524 - vif2.0 doesn't support polling,
> aborting.
> 
> The following patch (to latest kernel) fix this bug by adding 
> implementation to ndo_poll_controller.

Surely this is needed in netfront not netback?

BT, you patch is whitespace damanged, please see
Documentation/SubmittingPatches and Documentation/email-clients.txt for
tips. Please also run checkpatch.pl.

Ian.

> 00
> 01-Add-support-for-netconsole-driver-used-on-bridge-dev.patch
> 0 2001
> From: Yuval <yuval.shaia@oracle.com>
> Date: Tue, 8 Jan 2013 10:08:45 +0200
> Subject: [PATCH] Add support for netconsole driver used on bridge device 
> with
>   VIF attached
> 
> Signed-off-by: Yuval <yuval.shaia@oracle.com>
> ---
>   drivers/net/xen-netback/interface.c |    8 ++++++++
>   1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/net/xen-netback/interface.c 
> b/drivers/net/xen-netback/interface.c
> index 601ae2a..10751f5 100644
> --- a/drivers/net/xen-netback/interface.c
> +++ b/drivers/net/xen-netback/interface.c
> @@ -179,6 +179,13 @@ static u32 xenvif_fix_features(struct net_device 
> *dev, u32 features)
>       return features;
>   }
> 
> +static void xenvif_poll_controller(struct net_device *dev)
> +{
> +    disable_irq(dev->irq);
> +    xenvif_interrupt(dev->irq, dev);
> +    enable_irq(dev->irq);
> +}
> +
>   static const struct xenvif_stat {
>       char name[ETH_GSTRING_LEN];
>       u16 offset;
> @@ -237,6 +244,7 @@ static const struct net_device_ops xenvif_netdev_ops = {
>       .ndo_stop    = xenvif_close,
>       .ndo_change_mtu    = xenvif_change_mtu,
>       .ndo_fix_features = xenvif_fix_features,
> +    .ndo_poll_controller = xenvif_poll_controller,
>   };
> 
>   struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,

^ permalink raw reply

* [PATCH] Add support for netconsole driver used on bridge device with, VIF attached
From: yuval.shaia @ 2013-01-21 16:34 UTC (permalink / raw)
  To: ian.campbell, xen-devel, netdev

When starting a VM which has virtual interface attached to the same 
bridge (i.e vif = [type=netfront,bridge=xenbr0'] in vm.cfg) which is 
used for netconsole the
following message appears (after about 60 seconds) and VM creation 
operation fails.
      Error: Device 0 (vif) could not be connected. Hotplug scripts not 
working.

Note:
When trying to do the opposite, i.e. first create VM and then run
netconsole we got the error #524 - vif2.0 doesn't support polling,
aborting.

The following patch (to latest kernel) fix this bug by adding 
implementation to ndo_poll_controller.

0001-Add-support-for-netconsole-driver-used-on-bridge-dev.patch
0 2001
From: Yuval <yuval.shaia@oracle.com>
Date: Tue, 8 Jan 2013 10:08:45 +0200
Subject: [PATCH] Add support for netconsole driver used on bridge device 
with
  VIF attached

Signed-off-by: Yuval <yuval.shaia@oracle.com>
---
  drivers/net/xen-netback/interface.c |    8 ++++++++
  1 file changed, 8 insertions(+)

diff --git a/drivers/net/xen-netback/interface.c 
b/drivers/net/xen-netback/interface.c
index 601ae2a..10751f5 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -179,6 +179,13 @@ static u32 xenvif_fix_features(struct net_device 
*dev, u32 features)
      return features;
  }

+static void xenvif_poll_controller(struct net_device *dev)
+{
+    disable_irq(dev->irq);
+    xenvif_interrupt(dev->irq, dev);
+    enable_irq(dev->irq);
+}
+
  static const struct xenvif_stat {
      char name[ETH_GSTRING_LEN];
      u16 offset;
@@ -237,6 +244,7 @@ static const struct net_device_ops xenvif_netdev_ops = {
      .ndo_stop    = xenvif_close,
      .ndo_change_mtu    = xenvif_change_mtu,
      .ndo_fix_features = xenvif_fix_features,
+    .ndo_poll_controller = xenvif_poll_controller,
  };

  struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
-- 
1.7.9.5

^ permalink raw reply related

* RE: [PATCH net 2/3] net: cdc_mbim: send ZLP after max sized NTBs
From: Alexey ORISHKO @ 2013-01-21 16:31 UTC (permalink / raw)
  To: Bjørn Mork, netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Greg Suarez,
	Oliver Neukum, Alexey Orishko
In-Reply-To: <1358783440-11459-3-git-send-email-bjorn-yOkvZcmFvRU@public.gmane.org>

> -----Original Message-----
> From: Bjørn Mork [mailto:bjorn@mork.no]
> 
> We normally avoid sending ZLPs by padding NTBs with a zero byte if the
> NTB is shorter than dwNtbOutMaxSize, resulting in a short USB packet
> instead of a ZLP.  But in the case where the NTB length is exactly
> dwNtbOutMaxSize and this is an exact multiplum of wMaxPacketSize, then
> we must send a ZLP.
> 
> This fixes an issue seen on a Sierra Wireless MC7710 device where the
> transmission would fail whenever we ended up padding the NTBs to max
> size.

If you add ZLP for NTBs of dwNtbOutMaxSize, you are heavily affecting CPU
load, increasing interrupt load by factor of 2 in high load traffic
scenario and possibly decreasing throughput for all other devices
which behaves correctly. 

Why should others pay for Sierra Wireless fault?

At least, do check VID/PID in usbnet and send ZLP only for malfunctioning 
devices.

Regards,
Alexey

^ permalink raw reply

* [PATCH net-next] Documentation: remove obsolete networking/multicast.txt file
From: Paul Gortmaker @ 2013-01-21 16:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Paul Gortmaker

The original intent of this file was to list limitations in
drivers/hardware relating to multicast use, back when some
modest hardware from the early 1990s did not support things
we might take for granted today.

I was intending to delete some now-gone MCA/token ring entries
in this file, but once I opened it, I found it only contained
information on the earliest (pre-2000) linux networking drivers.

Checking the git history shows that the file hasn't been touched
since 2005.  Clearly nobody is actively consulting this file
as a meaningful reference.

Rather than add a "YES YES YES" line for all of the drivers we
currently have, lets just take advantage of the fact that nobody
is using the file to delete it.

This has the side benefit of not having to do a line-by-line
deletion of the file content as each older driver is expired.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 Documentation/networking/00-INDEX      |  2 --
 Documentation/networking/multicast.txt | 63 ----------------------------------
 2 files changed, 65 deletions(-)
 delete mode 100644 Documentation/networking/multicast.txt

diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
index 2cc3c77..1abfff2 100644
--- a/Documentation/networking/00-INDEX
+++ b/Documentation/networking/00-INDEX
@@ -126,8 +126,6 @@ ltpc.txt
 	- the Apple or Farallon LocalTalk PC card driver
 mac80211-injection.txt
 	- HOWTO use packet injection with mac80211
-multicast.txt
-	- Behaviour of cards under Multicast
 multiqueue.txt
 	- HOWTO for multiqueue network device support.
 netconsole.txt
diff --git a/Documentation/networking/multicast.txt b/Documentation/networking/multicast.txt
deleted file mode 100644
index b06c8c6..0000000
--- a/Documentation/networking/multicast.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-Behaviour of Cards Under Multicast
-==================================
-
-This is how they currently behave, not what the hardware can do--for example,
-the Lance driver doesn't use its filter, even though the code for loading
-it is in the DEC Lance-based driver.
-
-The following are requirements for multicasting 
------------------------------------------------
-AppleTalk	Multicast	hardware filtering not important but
-				 avoid cards only doing promisc
-IP-Multicast	Multicast	hardware filters really help
-IP-MRoute	AllMulti	hardware filters are of no help
-
-
-Board		Multicast	AllMulti	Promisc		Filter
-------------------------------------------------------------------------
-3c501		YES		YES		YES		Software
-3c503		YES		YES		YES		Hardware
-3c505		YES		NO		YES		Hardware
-3c507		NO		NO		NO		N/A
-3c509		YES		YES		YES		Software
-3c59x		YES		YES		YES		Software
-ac3200		YES		YES		YES		Hardware
-apricot		YES		PROMISC		YES		Hardware
-arcnet		NO		NO		NO		N/A
-at1700		PROMISC		PROMISC		YES		Software
-atp		PROMISC		PROMISC		YES		Software
-cs89x0		YES		YES		YES		Software
-de4x5		YES		YES		YES		Hardware
-de600		NO		NO		NO		N/A
-de620		PROMISC		PROMISC		YES		Software
-depca		YES		PROMISC		YES		Hardware
-dmfe		YES		YES		YES		Software(*)
-e2100		YES		YES		YES		Hardware
-eepro		YES		PROMISC		YES		Hardware
-eexpress	NO		NO		NO		N/A
-ewrk3		YES		PROMISC		YES		Hardware
-hp-plus		YES		YES		YES		Hardware
-hp		YES		YES		YES		Hardware
-hp100		YES		YES		YES		Hardware
-ibmtr		NO		NO		NO		N/A
-ioc3-eth	YES		YES		YES		Hardware
-lance		YES		YES		YES		Software(#)
-ne		YES		YES		YES		Hardware
-ni52		<------------------ Buggy ------------------>
-ni65		YES		YES		YES		Software(#)
-seeq		NO		NO		NO		N/A
-sgiseek		<------------------ Buggy ------------------>
-smc-ultra	YES		YES		YES		Hardware
-sunlance	YES		YES		YES		Hardware
-tulip		YES		YES		YES		Hardware
-wavelan		YES		PROMISC		YES		Hardware
-wd		YES		YES		YES		Hardware
-xirc2ps_cs	YES		YES		YES		Hardware
-znet		YES		YES		YES		Software
-
-
-PROMISC = This multicast mode is in fact promiscuous mode. Avoid using
-cards who go PROMISC on any multicast in a multicast kernel.
-
-(#) = Hardware multicast support is not used yet.
-(*) = Hardware support for Davicom 9132 chipset only.
-- 
1.8.1

^ permalink raw reply related

* Re: [PATCH v4 2/3] net: split eth_mac_addr for better error handling
From: Stefan Hajnoczi @ 2013-01-21 16:13 UTC (permalink / raw)
  To: akong; +Cc: mst, kvm, netdev, qemu-devel, virtualization, davem
In-Reply-To: <1358649789-2338-3-git-send-email-akong@redhat.com>

On Sun, Jan 20, 2013 at 10:43:08AM +0800, akong@redhat.com wrote:
> From: Stefan Hajnoczi <stefanha@gmail.com>
> 
> When we set mac address, software mac address in system and hardware mac
> address all need to be updated. Current eth_mac_addr() doesn't allow
> callers to implement error handling nicely.
> 
> This patch split eth_mac_addr() to prepare part and real commit part,
> then we can prepare first, and try to change hardware address, then do
> the real commit if hardware address is set successfully.
> 
> Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
> Signed-off-by: Amos Kong <akong@redhat.com>
> ---
>  include/linux/etherdevice.h |  2 ++
>  net/ethernet/eth.c          | 43 ++++++++++++++++++++++++++++++++++++-------
>  2 files changed, 38 insertions(+), 7 deletions(-)

Feel free to make yourself author and put me just as Suggested-by:.  I
posted pseudo-code but didn't write the patch or test it, so it's fair
to say that credit goes to you. :)

Stefan

^ permalink raw reply

* [PATCH net-next 0/2 v2] Add support of multicast static tree
From: Nicolas Dichtel @ 2013-01-21 16:00 UTC (permalink / raw)
  To: dlstevens; +Cc: netdev, davem, netdev-owner
In-Reply-To: <OF894319C2.8EF01FDC-ON87257AFA.004BC5D6-85257AFA.004E0255@us.ibm.com>

The goal of this serie is to add the support of proxy multicast, ie being able
to build a static multicast tree. In other words, it adds the support of (*,G)
mf[6]c entries.

v2: use INADDR_ANY instead of 0 for IPv4 addresses

 include/linux/mroute.h       |   2 +-
 include/linux/mroute6.h      |   2 +-
 include/uapi/linux/in6.h     |  15 ++----
 include/uapi/linux/mroute.h  |   3 ++
 include/uapi/linux/mroute6.h |   3 ++
 net/ipv4/ipmr.c              | 119 +++++++++++++++++++++++++++++++++++-----
 net/ipv6/ip6mr.c             | 126 ++++++++++++++++++++++++++++++++++++++-----
 7 files changed, 231 insertions(+), 39 deletions(-)

Comments are welcome.

Regards,
Nicolas

^ permalink raw reply

* [PATCH net-next v2 1/2] mcast: define and use MRT[6]_MAX in ip[6]_mroute_opt()
From: Nicolas Dichtel @ 2013-01-21 16:00 UTC (permalink / raw)
  To: dlstevens; +Cc: netdev, davem, netdev-owner, Nicolas Dichtel
In-Reply-To: <1358784026-4071-1-git-send-email-nicolas.dichtel@6wind.com>

This will ease further addition of new MRT[6]_* values and avoid to update
in6.h each time.
Note that we reduce the maximum value from 210 to 209, but 210 does not match
any known value in ip[6]_mroute_setsockopt().

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: David L Stevens <dlstevens@us.ibm.com>
---
 include/linux/mroute.h       |  2 +-
 include/linux/mroute6.h      |  2 +-
 include/uapi/linux/in6.h     | 15 ++++-----------
 include/uapi/linux/mroute.h  |  1 +
 include/uapi/linux/mroute6.h |  1 +
 5 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index ea00d91..79aaa9f 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -9,7 +9,7 @@
 #ifdef CONFIG_IP_MROUTE
 static inline int ip_mroute_opt(int opt)
 {
-	return (opt >= MRT_BASE) && (opt <= MRT_BASE + 10);
+	return (opt >= MRT_BASE) && (opt <= MRT_MAX);
 }
 #else
 static inline int ip_mroute_opt(int opt)
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
index a223561..66982e7 100644
--- a/include/linux/mroute6.h
+++ b/include/linux/mroute6.h
@@ -10,7 +10,7 @@
 #ifdef CONFIG_IPV6_MROUTE
 static inline int ip6_mroute_opt(int opt)
 {
-	return (opt >= MRT6_BASE) && (opt <= MRT6_BASE + 10);
+	return (opt >= MRT6_BASE) && (opt <= MRT6_MAX);
 }
 #else
 static inline int ip6_mroute_opt(int opt)
diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h
index 5673b97..53b1d56 100644
--- a/include/uapi/linux/in6.h
+++ b/include/uapi/linux/in6.h
@@ -259,17 +259,10 @@ struct in6_flowlabel_req {
 
 /*
  * Multicast Routing:
- * see include/linux/mroute6.h.
+ * see include/uapi/linux/mroute6.h.
  *
- * MRT6_INIT			200
- * MRT6_DONE			201
- * MRT6_ADD_MIF			202
- * MRT6_DEL_MIF			203
- * MRT6_ADD_MFC			204
- * MRT6_DEL_MFC			205
- * MRT6_VERSION			206
- * MRT6_ASSERT			207
- * MRT6_PIM			208
- * (reserved)			209
+ * MRT6_BASE			200
+ * ...
+ * MRT6_MAX
  */
 #endif /* _UAPI_LINUX_IN6_H */
diff --git a/include/uapi/linux/mroute.h b/include/uapi/linux/mroute.h
index 1692999..1c11004 100644
--- a/include/uapi/linux/mroute.h
+++ b/include/uapi/linux/mroute.h
@@ -26,6 +26,7 @@
 #define MRT_ASSERT	(MRT_BASE+7)	/* Activate PIM assert mode		*/
 #define MRT_PIM		(MRT_BASE+8)	/* enable PIM code			*/
 #define MRT_TABLE	(MRT_BASE+9)	/* Specify mroute table ID		*/
+#define MRT_MAX		(MRT_BASE+9)
 
 #define SIOCGETVIFCNT	SIOCPROTOPRIVATE	/* IP protocol privates */
 #define SIOCGETSGCNT	(SIOCPROTOPRIVATE+1)
diff --git a/include/uapi/linux/mroute6.h b/include/uapi/linux/mroute6.h
index 3e89b5e..c206ae3 100644
--- a/include/uapi/linux/mroute6.h
+++ b/include/uapi/linux/mroute6.h
@@ -26,6 +26,7 @@
 #define MRT6_ASSERT	(MRT6_BASE+7)	/* Activate PIM assert mode		*/
 #define MRT6_PIM	(MRT6_BASE+8)	/* enable PIM code			*/
 #define MRT6_TABLE	(MRT6_BASE+9)	/* Specify mroute table ID		*/
+#define MRT6_MAX	(MRT6_BASE+9)
 
 #define SIOCGETMIFCNT_IN6	SIOCPROTOPRIVATE	/* IP protocol privates */
 #define SIOCGETSGCNT_IN6	(SIOCPROTOPRIVATE+1)
-- 
1.8.0.1

^ permalink raw reply related

* [PATCH net-next v2 2/2] mcast: add multicast proxy support (IPv4 and IPv6)
From: Nicolas Dichtel @ 2013-01-21 16:00 UTC (permalink / raw)
  To: dlstevens; +Cc: netdev, davem, netdev-owner, Nicolas Dichtel
In-Reply-To: <1358784026-4071-1-git-send-email-nicolas.dichtel@6wind.com>

This patch add the support of proxy multicast, ie being able to build a static
multicast tree. It adds the support of (*,*) and (*,G) entries.

The user should define an (*,*) entry which is not used for real forwarding.
This entry defines the upstream in iif and contains all interfaces from the
static tree in its oifs. It will be used to forward packet upstream when they
come from an interface belonging to the static tree.
Hence, the user should define (*,G) entries to build its static tree. Note that
upstream interface must be part of oifs: packets are sent to all oifs
interfaces except the input interface. This ensures to always join the whole
static tree, even if the packet is not coming from the upstream interface.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: David L Stevens <dlstevens@us.ibm.com>
---
 include/uapi/linux/mroute.h  |   4 +-
 include/uapi/linux/mroute6.h |   4 +-
 net/ipv4/ipmr.c              | 119 +++++++++++++++++++++++++++++++++++-----
 net/ipv6/ip6mr.c             | 126 ++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 225 insertions(+), 28 deletions(-)

diff --git a/include/uapi/linux/mroute.h b/include/uapi/linux/mroute.h
index 1c11004..a382d2c 100644
--- a/include/uapi/linux/mroute.h
+++ b/include/uapi/linux/mroute.h
@@ -26,7 +26,9 @@
 #define MRT_ASSERT	(MRT_BASE+7)	/* Activate PIM assert mode		*/
 #define MRT_PIM		(MRT_BASE+8)	/* enable PIM code			*/
 #define MRT_TABLE	(MRT_BASE+9)	/* Specify mroute table ID		*/
-#define MRT_MAX		(MRT_BASE+9)
+#define MRT_ADD_MFC_PROXY	(MRT_BASE+10)	/* Add a (*,*|G) mfc entry	*/
+#define MRT_DEL_MFC_PROXY	(MRT_BASE+11)	/* Del a (*,*|G) mfc entry	*/
+#define MRT_MAX		(MRT_BASE+11)
 
 #define SIOCGETVIFCNT	SIOCPROTOPRIVATE	/* IP protocol privates */
 #define SIOCGETSGCNT	(SIOCPROTOPRIVATE+1)
diff --git a/include/uapi/linux/mroute6.h b/include/uapi/linux/mroute6.h
index c206ae3..ce91215 100644
--- a/include/uapi/linux/mroute6.h
+++ b/include/uapi/linux/mroute6.h
@@ -26,7 +26,9 @@
 #define MRT6_ASSERT	(MRT6_BASE+7)	/* Activate PIM assert mode		*/
 #define MRT6_PIM	(MRT6_BASE+8)	/* enable PIM code			*/
 #define MRT6_TABLE	(MRT6_BASE+9)	/* Specify mroute table ID		*/
-#define MRT6_MAX	(MRT6_BASE+9)
+#define MRT6_ADD_MFC_PROXY	(MRT6_BASE+10)	/* Add a (*,*|G) mfc entry	*/
+#define MRT6_DEL_MFC_PROXY	(MRT6_BASE+11)	/* Del a (*,*|G) mfc entry	*/
+#define MRT6_MAX	(MRT6_BASE+11)
 
 #define SIOCGETMIFCNT_IN6	SIOCPROTOPRIVATE	/* IP protocol privates */
 #define SIOCGETSGCNT_IN6	(SIOCPROTOPRIVATE+1)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index a9454cb..4b5e226 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -828,6 +828,49 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt,
 	return NULL;
 }
 
+/* Look for a (*,*,oif) entry */
+static struct mfc_cache *ipmr_cache_find_any_parent(struct mr_table *mrt,
+						    int vifi)
+{
+	int line = MFC_HASH(INADDR_ANY, INADDR_ANY);
+	struct mfc_cache *c;
+
+	list_for_each_entry_rcu(c, &mrt->mfc_cache_array[line], list)
+		if (c->mfc_origin == INADDR_ANY &&
+		    c->mfc_mcastgrp == INADDR_ANY &&
+		    c->mfc_un.res.ttls[vifi] < 255)
+			return c;
+
+	return NULL;
+}
+
+/* Look for a (*,G) entry */
+static struct mfc_cache *ipmr_cache_find_any(struct mr_table *mrt,
+					     __be32 mcastgrp, int vifi)
+{
+	int line = MFC_HASH(mcastgrp, INADDR_ANY);
+	struct mfc_cache *c, *proxy;
+
+	if (mcastgrp == INADDR_ANY)
+		goto skip;
+
+	list_for_each_entry_rcu(c, &mrt->mfc_cache_array[line], list)
+		if (c->mfc_origin == INADDR_ANY &&
+		    c->mfc_mcastgrp == mcastgrp) {
+			if (c->mfc_un.res.ttls[vifi] < 255)
+				return c;
+
+			/* It's ok if the vifi is part of the static tree */
+			proxy = ipmr_cache_find_any_parent(mrt,
+							   c->mfc_parent);
+			if (proxy && proxy->mfc_un.res.ttls[vifi] < 255)
+				return c;
+		}
+
+skip:
+	return ipmr_cache_find_any_parent(mrt, vifi);
+}
+
 /*
  *	Allocate a multicast cache entry
  */
@@ -1053,7 +1096,7 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb)
  *	MFC cache manipulation by user space mroute daemon
  */
 
-static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc)
+static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc, int parent)
 {
 	int line;
 	struct mfc_cache *c, *next;
@@ -1062,7 +1105,8 @@ static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc)
 
 	list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[line], list) {
 		if (c->mfc_origin == mfc->mfcc_origin.s_addr &&
-		    c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) {
+		    c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr &&
+		    (parent == -1 || parent == c->mfc_parent)) {
 			list_del_rcu(&c->list);
 			mroute_netlink_event(mrt, c, RTM_DELROUTE);
 			ipmr_cache_free(c);
@@ -1073,7 +1117,7 @@ static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc)
 }
 
 static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
-			struct mfcctl *mfc, int mrtsock)
+			struct mfcctl *mfc, int mrtsock, int parent)
 {
 	bool found = false;
 	int line;
@@ -1086,7 +1130,8 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
 
 	list_for_each_entry(c, &mrt->mfc_cache_array[line], list) {
 		if (c->mfc_origin == mfc->mfcc_origin.s_addr &&
-		    c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) {
+		    c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr &&
+		    (parent == -1 || parent == c->mfc_parent)) {
 			found = true;
 			break;
 		}
@@ -1103,7 +1148,8 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
 		return 0;
 	}
 
-	if (!ipv4_is_multicast(mfc->mfcc_mcastgrp.s_addr))
+	if (mfc->mfcc_mcastgrp.s_addr != INADDR_ANY &&
+	    !ipv4_is_multicast(mfc->mfcc_mcastgrp.s_addr))
 		return -EINVAL;
 
 	c = ipmr_cache_alloc();
@@ -1218,7 +1264,7 @@ static void mrtsock_destruct(struct sock *sk)
 
 int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
 {
-	int ret;
+	int ret, parent = 0;
 	struct vifctl vif;
 	struct mfcctl mfc;
 	struct net *net = sock_net(sk);
@@ -1287,16 +1333,22 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
 		 */
 	case MRT_ADD_MFC:
 	case MRT_DEL_MFC:
+		parent = -1;
+	case MRT_ADD_MFC_PROXY:
+	case MRT_DEL_MFC_PROXY:
 		if (optlen != sizeof(mfc))
 			return -EINVAL;
 		if (copy_from_user(&mfc, optval, sizeof(mfc)))
 			return -EFAULT;
+		if (parent == 0)
+			parent = mfc.mfcc_parent;
 		rtnl_lock();
-		if (optname == MRT_DEL_MFC)
-			ret = ipmr_mfc_delete(mrt, &mfc);
+		if (optname == MRT_DEL_MFC || optname == MRT_DEL_MFC_PROXY)
+			ret = ipmr_mfc_delete(mrt, &mfc, parent);
 		else
 			ret = ipmr_mfc_add(net, mrt, &mfc,
-					   sk == rtnl_dereference(mrt->mroute_sk));
+					   sk == rtnl_dereference(mrt->mroute_sk),
+					   parent);
 		rtnl_unlock();
 		return ret;
 		/*
@@ -1749,17 +1801,28 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
 {
 	int psend = -1;
 	int vif, ct;
+	int true_vifi = ipmr_find_vif(mrt, skb->dev);
 
 	vif = cache->mfc_parent;
 	cache->mfc_un.res.pkt++;
 	cache->mfc_un.res.bytes += skb->len;
 
+	if (cache->mfc_origin == INADDR_ANY && true_vifi >= 0) {
+		struct mfc_cache *cache_proxy;
+
+		/* For an (*,G) entry, we only check that the incomming
+		 * interface is part of the static tree.
+		 */
+		cache_proxy = ipmr_cache_find_any_parent(mrt, vif);
+		if (cache_proxy &&
+		    cache_proxy->mfc_un.res.ttls[true_vifi] < 255)
+			goto forward;
+	}
+
 	/*
 	 * Wrong interface: drop packet and (maybe) send PIM assert.
 	 */
 	if (mrt->vif_table[vif].dev != skb->dev) {
-		int true_vifi;
-
 		if (rt_is_output_route(skb_rtable(skb))) {
 			/* It is our own packet, looped back.
 			 * Very complicated situation...
@@ -1776,7 +1839,6 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
 		}
 
 		cache->mfc_un.res.wrong_if++;
-		true_vifi = ipmr_find_vif(mrt, skb->dev);
 
 		if (true_vifi >= 0 && mrt->mroute_do_assert &&
 		    /* pimsm uses asserts, when switching from RPT to SPT,
@@ -1794,15 +1856,33 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
 		goto dont_forward;
 	}
 
+forward:
 	mrt->vif_table[vif].pkt_in++;
 	mrt->vif_table[vif].bytes_in += skb->len;
 
 	/*
 	 *	Forward the frame
 	 */
+	if (cache->mfc_origin == INADDR_ANY &&
+	    cache->mfc_mcastgrp == INADDR_ANY) {
+		if (true_vifi >= 0 &&
+		    true_vifi != cache->mfc_parent &&
+		    ip_hdr(skb)->ttl >
+				cache->mfc_un.res.ttls[cache->mfc_parent]) {
+			/* It's an (*,*) entry and the packet is not coming from
+			 * the upstream: forward the packet to the upstream
+			 * only.
+			 */
+			psend = cache->mfc_parent;
+			goto last_forward;
+		}
+		goto dont_forward;
+	}
 	for (ct = cache->mfc_un.res.maxvif - 1;
 	     ct >= cache->mfc_un.res.minvif; ct--) {
-		if (ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) {
+		/* For (*,G) entry, don't forward to the incoming interface */
+		if ((cache->mfc_origin != INADDR_ANY || ct != true_vifi) &&
+		    ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) {
 			if (psend != -1) {
 				struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 
@@ -1813,6 +1893,7 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
 			psend = ct;
 		}
 	}
+last_forward:
 	if (psend != -1) {
 		if (local) {
 			struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
@@ -1902,6 +1983,13 @@ int ip_mr_input(struct sk_buff *skb)
 
 	/* already under rcu_read_lock() */
 	cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr);
+	if (cache == NULL) {
+		int vif = ipmr_find_vif(mrt, skb->dev);
+
+		if (vif >= 0)
+			cache = ipmr_cache_find_any(mrt, ip_hdr(skb)->daddr,
+						    vif);
+	}
 
 	/*
 	 *	No usable cache entry
@@ -2107,7 +2195,12 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
 
 	rcu_read_lock();
 	cache = ipmr_cache_find(mrt, saddr, daddr);
+	if (cache == NULL && skb->dev) {
+		int vif = ipmr_find_vif(mrt, skb->dev);
 
+		if (vif >= 0)
+			cache = ipmr_cache_find_any(mrt, daddr, vif);
+	}
 	if (cache == NULL) {
 		struct sk_buff *skb2;
 		struct iphdr *iph;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 26dcdec..acc3249 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1017,6 +1017,50 @@ static struct mfc6_cache *ip6mr_cache_find(struct mr6_table *mrt,
 	return NULL;
 }
 
+/* Look for a (*,*,oif) entry */
+static struct mfc6_cache *ip6mr_cache_find_any_parent(struct mr6_table *mrt,
+						      mifi_t mifi)
+{
+	int line = MFC6_HASH(&in6addr_any, &in6addr_any);
+	struct mfc6_cache *c;
+
+	list_for_each_entry(c, &mrt->mfc6_cache_array[line], list)
+		if (ipv6_addr_any(&c->mf6c_origin) &&
+		    ipv6_addr_any(&c->mf6c_mcastgrp) &&
+		    (c->mfc_un.res.ttls[mifi] < 255))
+			return c;
+
+	return NULL;
+}
+
+/* Look for a (*,G) entry */
+static struct mfc6_cache *ip6mr_cache_find_any(struct mr6_table *mrt,
+					       struct in6_addr *mcastgrp,
+					       mifi_t mifi)
+{
+	int line = MFC6_HASH(mcastgrp, &in6addr_any);
+	struct mfc6_cache *c, *proxy;
+
+	if (ipv6_addr_any(mcastgrp))
+		goto skip;
+
+	list_for_each_entry(c, &mrt->mfc6_cache_array[line], list)
+		if (ipv6_addr_any(&c->mf6c_origin) &&
+		    ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp)) {
+			if (c->mfc_un.res.ttls[mifi] < 255)
+				return c;
+
+			/* It's ok if the mifi is part of the static tree */
+			proxy = ip6mr_cache_find_any_parent(mrt,
+							    c->mf6c_parent);
+			if (proxy && proxy->mfc_un.res.ttls[mifi] < 255)
+				return c;
+		}
+
+skip:
+	return ip6mr_cache_find_any_parent(mrt, mifi);
+}
+
 /*
  *	Allocate a multicast cache entry
  */
@@ -1247,7 +1291,8 @@ ip6mr_cache_unresolved(struct mr6_table *mrt, mifi_t mifi, struct sk_buff *skb)
  *	MFC6 cache manipulation by user space
  */
 
-static int ip6mr_mfc_delete(struct mr6_table *mrt, struct mf6cctl *mfc)
+static int ip6mr_mfc_delete(struct mr6_table *mrt, struct mf6cctl *mfc,
+			    int parent)
 {
 	int line;
 	struct mfc6_cache *c, *next;
@@ -1256,7 +1301,9 @@ static int ip6mr_mfc_delete(struct mr6_table *mrt, struct mf6cctl *mfc)
 
 	list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[line], list) {
 		if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
-		    ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) {
+		    ipv6_addr_equal(&c->mf6c_mcastgrp,
+				    &mfc->mf6cc_mcastgrp.sin6_addr) &&
+		    (parent == -1 || parent == c->mf6c_parent)) {
 			write_lock_bh(&mrt_lock);
 			list_del(&c->list);
 			write_unlock_bh(&mrt_lock);
@@ -1391,7 +1438,7 @@ void ip6_mr_cleanup(void)
 }
 
 static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
-			 struct mf6cctl *mfc, int mrtsock)
+			 struct mf6cctl *mfc, int mrtsock, int parent)
 {
 	bool found = false;
 	int line;
@@ -1413,7 +1460,9 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
 
 	list_for_each_entry(c, &mrt->mfc6_cache_array[line], list) {
 		if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
-		    ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) {
+		    ipv6_addr_equal(&c->mf6c_mcastgrp,
+				    &mfc->mf6cc_mcastgrp.sin6_addr) &&
+		    (parent == -1 || parent == mfc->mf6cc_parent)) {
 			found = true;
 			break;
 		}
@@ -1430,7 +1479,8 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
 		return 0;
 	}
 
-	if (!ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr))
+	if (!ipv6_addr_any(&mfc->mf6cc_mcastgrp.sin6_addr) &&
+	    !ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr))
 		return -EINVAL;
 
 	c = ip6mr_cache_alloc();
@@ -1596,7 +1646,7 @@ struct sock *mroute6_socket(struct net *net, struct sk_buff *skb)
 
 int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
 {
-	int ret;
+	int ret, parent = 0;
 	struct mif6ctl vif;
 	struct mf6cctl mfc;
 	mifi_t mifi;
@@ -1653,15 +1703,21 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
 	 */
 	case MRT6_ADD_MFC:
 	case MRT6_DEL_MFC:
+		parent = -1;
+	case MRT6_ADD_MFC_PROXY:
+	case MRT6_DEL_MFC_PROXY:
 		if (optlen < sizeof(mfc))
 			return -EINVAL;
 		if (copy_from_user(&mfc, optval, sizeof(mfc)))
 			return -EFAULT;
+		if (parent == 0)
+			parent = mfc.mf6cc_parent;
 		rtnl_lock();
-		if (optname == MRT6_DEL_MFC)
-			ret = ip6mr_mfc_delete(mrt, &mfc);
+		if (optname == MRT6_DEL_MFC || optname == MRT6_DEL_MFC_PROXY)
+			ret = ip6mr_mfc_delete(mrt, &mfc, parent);
 		else
-			ret = ip6mr_mfc_add(net, mrt, &mfc, sk == mrt->mroute6_sk);
+			ret = ip6mr_mfc_add(net, mrt, &mfc,
+					    sk == mrt->mroute6_sk, parent);
 		rtnl_unlock();
 		return ret;
 
@@ -2015,19 +2071,29 @@ static int ip6_mr_forward(struct net *net, struct mr6_table *mrt,
 {
 	int psend = -1;
 	int vif, ct;
+	int true_vifi = ip6mr_find_vif(mrt, skb->dev);
 
 	vif = cache->mf6c_parent;
 	cache->mfc_un.res.pkt++;
 	cache->mfc_un.res.bytes += skb->len;
 
+	if (ipv6_addr_any(&cache->mf6c_origin) && true_vifi >= 0) {
+		struct mfc6_cache *cache_proxy;
+
+		/* For an (*,G) entry, we only check that the incomming
+		 * interface is part of the static tree.
+		 */
+		cache_proxy = ip6mr_cache_find_any_parent(mrt, vif);
+		if (cache_proxy &&
+		    cache_proxy->mfc_un.res.ttls[true_vifi] < 255)
+			goto forward;
+	}
+
 	/*
 	 * Wrong interface: drop packet and (maybe) send PIM assert.
 	 */
 	if (mrt->vif6_table[vif].dev != skb->dev) {
-		int true_vifi;
-
 		cache->mfc_un.res.wrong_if++;
-		true_vifi = ip6mr_find_vif(mrt, skb->dev);
 
 		if (true_vifi >= 0 && mrt->mroute_do_assert &&
 		    /* pimsm uses asserts, when switching from RPT to SPT,
@@ -2045,14 +2111,32 @@ static int ip6_mr_forward(struct net *net, struct mr6_table *mrt,
 		goto dont_forward;
 	}
 
+forward:
 	mrt->vif6_table[vif].pkt_in++;
 	mrt->vif6_table[vif].bytes_in += skb->len;
 
 	/*
 	 *	Forward the frame
 	 */
+	if (ipv6_addr_any(&cache->mf6c_origin) &&
+	    ipv6_addr_any(&cache->mf6c_mcastgrp)) {
+		if (true_vifi >= 0 &&
+		    true_vifi != cache->mf6c_parent &&
+		    ipv6_hdr(skb)->hop_limit >
+				cache->mfc_un.res.ttls[cache->mf6c_parent]) {
+			/* It's an (*,*) entry and the packet is not coming from
+			 * the upstream: forward the packet to the upstream
+			 * only.
+			 */
+			psend = cache->mf6c_parent;
+			goto last_forward;
+		}
+		goto dont_forward;
+	}
 	for (ct = cache->mfc_un.res.maxvif - 1; ct >= cache->mfc_un.res.minvif; ct--) {
-		if (ipv6_hdr(skb)->hop_limit > cache->mfc_un.res.ttls[ct]) {
+		/* For (*,G) entry, don't forward to the incoming interface */
+		if ((!ipv6_addr_any(&cache->mf6c_origin) || ct != true_vifi) &&
+		    ipv6_hdr(skb)->hop_limit > cache->mfc_un.res.ttls[ct]) {
 			if (psend != -1) {
 				struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 				if (skb2)
@@ -2061,6 +2145,7 @@ static int ip6_mr_forward(struct net *net, struct mr6_table *mrt,
 			psend = ct;
 		}
 	}
+last_forward:
 	if (psend != -1) {
 		ip6mr_forward2(net, mrt, skb, cache, psend);
 		return 0;
@@ -2096,6 +2181,14 @@ int ip6_mr_input(struct sk_buff *skb)
 	read_lock(&mrt_lock);
 	cache = ip6mr_cache_find(mrt,
 				 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr);
+	if (cache == NULL) {
+		int vif = ip6mr_find_vif(mrt, skb->dev);
+
+		if (vif >= 0)
+			cache = ip6mr_cache_find_any(mrt,
+						     &ipv6_hdr(skb)->daddr,
+						     vif);
+	}
 
 	/*
 	 *	No usable cache entry
@@ -2183,6 +2276,13 @@ int ip6mr_get_route(struct net *net,
 
 	read_lock(&mrt_lock);
 	cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
+	if (!cache && skb->dev) {
+		int vif = ip6mr_find_vif(mrt, skb->dev);
+
+		if (vif >= 0)
+			cache = ip6mr_cache_find_any(mrt, &rt->rt6i_dst.addr,
+						     vif);
+	}
 
 	if (!cache) {
 		struct sk_buff *skb2;
-- 
1.8.0.1

^ permalink raw reply related

* Re: IPsec AH use of ahash
From: Tom St Denis @ 2013-01-21 16:05 UTC (permalink / raw)
  To: Chris Friesen
  Cc: Steven Rostedt, David Dillow, Borislav Petkov, linux-kernel,
	netdev
In-Reply-To: <50FD637F.2080604@genband.com>

----- Original Message -----
> From: "Chris Friesen" <chris.friesen@genband.com>
> To: "Tom St Denis" <tstdenis@elliptictech.com>
> Cc: "Steven Rostedt" <rostedt@goodmis.org>, "David Dillow" <dave@thedillows.org>, "Borislav Petkov" <bp@alien8.de>,
> linux-kernel@vger.kernel.org, netdev@vger.kernel.org
> Sent: Monday, 21 January, 2013 10:49:19 AM
> Subject: Re: IPsec AH use of ahash
> 
> On 01/21/2013 09:31 AM, Tom St Denis wrote:
> > ----- Original Message -----
> >> From: "Steven Rostedt"<rostedt@goodmis.org> To: "Tom St
> >> Denis"<tstdenis@elliptictech.com> Cc: "David
> >> Dillow"<dave@thedillows.org>, "Borislav Petkov"<bp@alien8.de>,
> >> linux-kernel@vger.kernel.org, netdev@vger.kernel.org Sent: Monday,
> >> 21 January, 2013 10:28:33 AM Subject: Re: IPsec AH use of ahash
> >>
> >> When I send a patch to another maintainer, and they tell me to fix
> >> the way I did the comments, I don't complain. I fix the comments
> >> and resend.
> >
> > Which is less of a problem when there is a timeliness factor.  In
> > the
> > business world people move on and don't work at that pace.
> 
> There can be an impedance mismatch between the "get it done to hit a
> deadline" business world and the "get it right no matter how long it
> takes" world of some open-source projects.

I think part of it is the nature of the job.  Here working with the kernel is a by-product of the atmosphere we're in (embedded hardware).  We're not per se a "Linux Shop" ...

So for our case when CMAC code was working and the patch fired off we were "done."  Granted now that bugs were found in the testmgr code spending time to fix it up was prudent.

The timeliness I was speaking of was to make sure that business windows are hit as well.  Had I had a rejection sooner when the project was still fresh and current it would have been no issue to re-spin the patches.
 
> However, many businesses have recognized that they get far more
> benefit
> from dealing with open-source than it costs them in designer time.
> 
>  From the point of view of my employer (I work in telecom) the
>  choices
> are either:
> 
> a) work with the kernel to get the code submitted into mainline
> b) keep the changes private and port them every time we upgrade
> 
> Over a decade or more my management has come to realize that option
> "a"
> is generally better in the long term, even if it's a bit more effort
> in
> the short term.
> 
> There are exceptions of course, and sometimes we just need to do a
> quick-and-dirty solution to get something out the door.

Yup agreed.  We don't plan to mainline our hardware drivers any time soon mostly because they're in flux too much and they're really only useful for businesses who order mostly custom designs (end home users wouldn't typically write drivers for them).

But at the same time we hit upon things in the kernel that prevent our private tree drivers from working (lacking CMAC for instance, or not being able to run AH-GMAC).  I'd like to see the CMAC issue move forward and then maybe contribute to the AH-AEAD front.

Tom

^ permalink raw reply

* [PATCH 1/2] usbnet: add new flag FLAG_NOARP for usb net devices
From: Wei Shuai @ 2013-01-21 16:00 UTC (permalink / raw)
  To: sshtylyov, dcbw, davem, peter, oneukum, gregkh, alexey.orishko,
	bjorn
  Cc: linux-usb, netdev, Wei Shuai

We do have some USB net devices, which cannot do ARP. 
so we can introduce a new flag FLAG_NOARP, then client drivers 
can easily handle this kind of devices


Signed-off-by: Wei Shuai <cpuwolf@gmail.com>
---
 drivers/net/usb/usbnet.c   |    4 ++++
 include/linux/usb/usbnet.h |    1 +
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 3d4bf01..f34b2eb 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1448,6 +1448,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 		if ((dev->driver_info->flags & FLAG_WWAN) != 0)
 			strcpy(net->name, "wwan%d");
 
+		/* devices that cannot do ARP */
+		if ((dev->driver_info->flags & FLAG_NOARP) != 0)
+			net->flags |= IFF_NOARP;
+
 		/* maybe the remote can't receive an Ethernet MTU */
 		if (net->mtu > (dev->hard_mtu - net->hard_header_len))
 			net->mtu = dev->hard_mtu - net->hard_header_len;
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index bd45eb7..5de7a22 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -100,6 +100,7 @@ struct driver_info {
 #define FLAG_LINK_INTR	0x0800		/* updates link (carrier) status */
 
 #define FLAG_POINTTOPOINT 0x1000	/* possibly use "usb%d" names */
+#define FLAG_NOARP	0x2000		/* device can't do ARP */
 
 /*
  * Indicates to usbnet, that USB driver accumulates multiple IP packets.
-- 
1.7.6.5

^ permalink raw reply related

* [PATCH 2/2] cdc_ncm: add support FLAG_NOARP for Infineon  modem platform
From: Wei Shuai @ 2013-01-21 16:00 UTC (permalink / raw)
  To: sshtylyov-Igf4POYTYCDQT0dZR+AlfA, dcbw-H+wXaHxf7aLQT0dZR+AlfA,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, peter-Y+HMSxxDrH8,
	oneukum-l3A5Bk7waGM, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	alexey.orishko-0IS4wlFg1OjSUeElwK9/Pw, bjorn-yOkvZcmFvRU
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	Wei Shuai
In-Reply-To: <1358784032-3897-1-git-send-email-cpuwolf-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Infineon(now Intel) HSPA Modem platform NCM cannot support ARP.
we can define a new common structure wwan_noarp_info.
Then more similiar NO ARP devices can be handled easily


Signed-off-by: Wei Shuai <cpuwolf-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/net/usb/cdc_ncm.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 71b6e92..2d699b6 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -1155,6 +1155,20 @@ static const struct driver_info wwan_info = {
 	.tx_fixup = cdc_ncm_tx_fixup,
 };
 
+/* Same as wwan_info, but with FLAG_NOARP  */
+static const struct driver_info wwan_noarp_info = {
+	.description = "Mobile Broadband Network Device (NO ARP)",
+	.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
+			| FLAG_WWAN | FLAG_NOARP,
+	.bind = cdc_ncm_bind,
+	.unbind = cdc_ncm_unbind,
+	.check_connect = cdc_ncm_check_connect,
+	.manage_power = usbnet_manage_power,
+	.status = cdc_ncm_status,
+	.rx_fixup = cdc_ncm_rx_fixup,
+	.tx_fixup = cdc_ncm_tx_fixup,
+};
+
 static const struct usb_device_id cdc_devs[] = {
 	/* Ericsson MBM devices like F5521gw */
 	{ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
@@ -1194,6 +1208,13 @@ static const struct usb_device_id cdc_devs[] = {
 	  .driver_info = (unsigned long)&wwan_info,
 	},
 
+	/* Infineon(now Intel) HSPA Modem platform */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443,
+		USB_CLASS_COMM,
+		USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
+	  .driver_info = (unsigned long)&wwan_noarp_info,
+	},
+
 	/* Generic CDC-NCM devices */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM,
 		USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
-- 
1.7.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH net 1/3] net: cdc_ncm: workaround for missing CDC Union
From: Bjørn Mork @ 2013-01-21 15:50 UTC (permalink / raw)
  To: netdev
  Cc: linux-usb, Greg Suarez, Alexey Orishko, Oliver Neukum,
	Bjørn Mork
In-Reply-To: <1358783440-11459-1-git-send-email-bjorn@mork.no>

Adding support for the MBIM mode in some Sierra Wireless devices.

Some Sierra Wireless firmwares support CDC MBIM but have no CDC
Union funtional descriptor. This violates the MBIM specification,
but we can easily work around the bug by looking at the Interface
Association Descriptor instead.  This is most likely what
Windows uses too, which explains how the firmware bug has gone
unnoticed until now.

This change will not affect any currently supported device
conforming to the NCM or MBIM specifications, as they must have
the CDC Union descriptor.

Cc: Greg Suarez <gsuarez@smithmicro.com>
Cc: Alexey Orishko <alexey.orishko@stericsson.com>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 drivers/net/usb/cdc_ncm.c |   27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 71b6e92..4041159 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -344,6 +344,23 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = {
 	.nway_reset = usbnet_nway_reset,
 };
 
+/* return first slave interface if an IAD matches the given master */
+static struct usb_interface *get_iad_slave(struct usb_device *udev,
+					   struct usb_interface *master) {
+	int i;
+	struct usb_interface_assoc_descriptor *iad;
+	u8 mnum = master->cur_altsetting->desc.bInterfaceNumber;
+
+	for (i = 0; i < USB_MAXIADS; i++) {
+		iad = udev->actconfig->intf_assoc[i];
+		if (!iad)
+			break;
+		if (iad->bFirstInterface == mnum && iad->bInterfaceCount == 2)
+			return usb_ifnum_to_if(udev, mnum + 1);
+	}
+	return NULL;
+}
+
 int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting)
 {
 	struct cdc_ncm_ctx *ctx;
@@ -435,6 +452,16 @@ advance:
 		len -= temp;
 	}
 
+	/* some buggy devices have an IAD but no CDC Union */
+	if (!ctx->union_desc) {
+		dev_dbg(&intf->dev, "missing CDC Union descriptor\n");
+		ctx->data = get_iad_slave(dev->udev, intf);
+		if (ctx->data) {
+			ctx->control = intf;
+			dev_dbg(&intf->dev, "got slave from IAD\n");
+		}
+	}
+
 	/* check if we got everything */
 	if ((ctx->control == NULL) || (ctx->data == NULL) ||
 	    ((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf))))
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH net 2/3] net: cdc_mbim: send ZLP after max sized NTBs
From: Bjørn Mork @ 2013-01-21 15:50 UTC (permalink / raw)
  To: netdev
  Cc: linux-usb, Greg Suarez, Alexey Orishko, Oliver Neukum,
	Bjørn Mork
In-Reply-To: <1358783440-11459-1-git-send-email-bjorn@mork.no>

We normally avoid sending ZLPs by padding NTBs with a zero byte
if the NTB is shorter than dwNtbOutMaxSize, resulting in a short
USB packet instead of a ZLP.  But in the case where the NTB length
is exactly dwNtbOutMaxSize and this is an exact multiplum of
wMaxPacketSize, then we must send a ZLP.

This fixes an issue seen on a Sierra Wireless MC7710 device
where the transmission would fail whenever we ended up padding
the NTBs to max size.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 drivers/net/usb/cdc_mbim.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 42f51c7..3a5673a 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -366,7 +366,7 @@ err:
 
 static const struct driver_info cdc_mbim_info = {
 	.description = "CDC MBIM",
-	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
+	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP,
 	.bind = cdc_mbim_bind,
 	.unbind = cdc_mbim_unbind,
 	.manage_power = cdc_mbim_manage_power,
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH net 3/3] net: cdc_ncm: fix error path for single interface probing
From: Bjørn Mork @ 2013-01-21 15:50 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Greg Suarez, Alexey Orishko,
	Oliver Neukum, Bjørn Mork
In-Reply-To: <1358783440-11459-1-git-send-email-bjorn-yOkvZcmFvRU@public.gmane.org>

commit bbc8d92 (net: cdc_ncm: add Huawei devices) implemented
support for devices with a single combined control and data
interface. Fix up the error path so that we do not double
release such interfaces in case of probing failures.

Signed-off-by: Bjørn Mork <bjorn-yOkvZcmFvRU@public.gmane.org>
---
 drivers/net/usb/cdc_ncm.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 4041159..2c4b41f 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -524,7 +524,8 @@ advance:
 error2:
 	usb_set_intfdata(ctx->control, NULL);
 	usb_set_intfdata(ctx->data, NULL);
-	usb_driver_release_interface(driver, ctx->data);
+	if (ctx->data != ctx->control)
+		usb_driver_release_interface(driver, ctx->data);
 error:
 	cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);
 	dev->data[0] = 0;
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH net 0/3] cdc_ncm and cdc_mbim fixes for 3.8
From: Bjørn Mork @ 2013-01-21 15:50 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Greg Suarez, Alexey Orishko,
	Oliver Neukum, Bjørn Mork

The 2 first patches in this series are required to make the Sierra
Wireless MC7710 card work in MBIM mode.  They may also be
required for other Qualcomm firmware based MBIM devices.

Patch #1 was previously posted as a standalone patch.  This version
is a replacement, removing a theoretical NULL pointer exception. 

Patch #3 fixes a bug I introduced in v3.7

Bjørn Mork (3):
  net: cdc_ncm: workaround for missing CDC Union
  net: cdc_mbim: send ZLP after max sized NTBs
  net: cdc_ncm: fix error path for single interface probing

 drivers/net/usb/cdc_mbim.c |    2 +-
 drivers/net/usb/cdc_ncm.c  |   30 +++++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 2 deletions(-)

-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: IPsec AH use of ahash
From: Chris Friesen @ 2013-01-21 15:49 UTC (permalink / raw)
  To: Tom St Denis
  Cc: Steven Rostedt, David Dillow, Borislav Petkov, linux-kernel,
	netdev
In-Reply-To: <1161725580.95543.1358782288077.JavaMail.root@elliptictech.com>

On 01/21/2013 09:31 AM, Tom St Denis wrote:
> ----- Original Message -----
>> From: "Steven Rostedt"<rostedt@goodmis.org> To: "Tom St
>> Denis"<tstdenis@elliptictech.com> Cc: "David
>> Dillow"<dave@thedillows.org>, "Borislav Petkov"<bp@alien8.de>,
>> linux-kernel@vger.kernel.org, netdev@vger.kernel.org Sent: Monday,
>> 21 January, 2013 10:28:33 AM Subject: Re: IPsec AH use of ahash
>>
>> When I send a patch to another maintainer, and they tell me to fix
>> the way I did the comments, I don't complain. I fix the comments
>> and resend.
>
> Which is less of a problem when there is a timeliness factor.  In the
> business world people move on and don't work at that pace.

There can be an impedance mismatch between the "get it done to hit a 
deadline" business world and the "get it right no matter how long it 
takes" world of some open-source projects.

However, many businesses have recognized that they get far more benefit 
from dealing with open-source than it costs them in designer time.

 From the point of view of my employer (I work in telecom) the choices 
are either:

a) work with the kernel to get the code submitted into mainline
b) keep the changes private and port them every time we upgrade

Over a decade or more my management has come to realize that option "a" 
is generally better in the long term, even if it's a bit more effort in 
the short term.

There are exceptions of course, and sometimes we just need to do a 
quick-and-dirty solution to get something out the door.

Chris

^ permalink raw reply

* Re: [patch v3] doc: add nf_conntrack sysctl api documentation
From: Jiri Pirko @ 2013-01-21 15:35 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: netdev, davem, rob, linux-doc, kuznet, jmorris, yoshfuji,
	netfilter-devel, netfilter, coreteam, fw, Neal Murphy
In-Reply-To: <20130121115202.GA5074@1984>

Mon, Jan 21, 2013 at 12:52:02PM CET, pablo@netfilter.org wrote:
>On Fri, Jan 18, 2013 at 10:05:08AM +0100, Jiri Pirko wrote:
>> I grepped through the code and picked bits about nf_conntrack sysctl api
>> and put that into one documentation file.
>
>Applied, thanks a lot Jiri.
>
>I have also included some grammar improvements that Neil Murphy has
>proposed (he seems to have accidentally trimmed off the CC list).

Okay, Thanks a lot Pablo

^ permalink raw reply

* Re: IPsec AH use of ahash
From: Tom St Denis @ 2013-01-21 15:31 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: David Dillow, Borislav Petkov, linux-kernel, netdev
In-Reply-To: <1358782113.21576.28.camel@gandalf.local.home>

----- Original Message -----
> From: "Steven Rostedt" <rostedt@goodmis.org>
> To: "Tom St Denis" <tstdenis@elliptictech.com>
> Cc: "David Dillow" <dave@thedillows.org>, "Borislav Petkov" <bp@alien8.de>, linux-kernel@vger.kernel.org,
> netdev@vger.kernel.org
> Sent: Monday, 21 January, 2013 10:28:33 AM
> Subject: Re: IPsec AH use of ahash
> 
> When I send a patch to another maintainer, and they tell me to fix
> the
> way I did the comments, I don't complain. I fix the comments and
> resend.

Which is less of a problem when there is a timeliness factor.  In the business world people move on and don't work at that pace.

Anyways, neither here nor there now.  

Tom

^ permalink raw reply

* Re: [PATCH net] net: cdc_ncm: workaround for missing CDC Union
From: Bjørn Mork @ 2013-01-21 15:28 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: Alexey Orishko, netdev, linux-usb, Greg Suarez, Alexey Orishko
In-Reply-To: <2214944.HMNV73jJm5@linux-5eaq.site>

Oliver Neukum <oneukum@suse.de> writes:
> On Monday 21 January 2013 15:47:13 Bjørn Mork wrote:
>> But I wonder if this isn't really a generic problem in usbnet.  The
>> FLAG_MULTI_PACKET test here seems completely bogus:
>> 
>>         if (length % dev->maxpacket == 0) {
>>                 if (!(info->flags & FLAG_SEND_ZLP)) {
>>                         if (!(info->flags & FLAG_MULTI_PACKET)) {
>>                                 urb->transfer_buffer_length++;
>>                                 if (skb_tailroom(skb)) {
>>                                         skb->data[skb->len] = 0;
>>                                         __skb_put(skb, 1);
>>                                 }
>>                         }
>>                 } else
>>                         urb->transfer_flags |= URB_ZERO_PACKET;
>>         }
>> 
>> Either the FLAG_MULTI_PACKET minidriver will have already padded the
>> buffer so that we do not hit (length % dev->maxpacket == 0), or we
>> should choose one of the alternatives: ZLP or padding.
>
> But we cannot simply call __skb_put for a complicated data frame.

Agreed.  But I believe the condition should be 

 if (!(info->flags & FLAG_SEND_ZLP) && !(info->flags & FLAG_MULTI_PACKET)) {
     ..
 } else {
     urb->transfer_flags |= URB_ZERO_PACKET;
 }

to ensure that we send the ZLP in this case.

> Besides you may want the current behavior.

Why? Does it ever make sense to prevent both the short packet and the
ZLP?


Bjørn

^ permalink raw reply

* Re: IPsec AH use of ahash
From: Steven Rostedt @ 2013-01-21 15:28 UTC (permalink / raw)
  To: Tom St Denis; +Cc: David Dillow, Borislav Petkov, linux-kernel, netdev
In-Reply-To: <1731098824.95194.1358779862449.JavaMail.root@elliptictech.com>

On Mon, 2013-01-21 at 09:51 -0500, Tom St Denis wrote:
> 
> ----- Original Message -----
> > From: "Steven Rostedt" <rostedt@goodmis.org>
> > To: "Tom St Denis" <tstdenis@elliptictech.com>
> > Cc: "David Dillow" <dave@thedillows.org>, "Borislav Petkov" <bp@alien8.de>, linux-kernel@vger.kernel.org,
> > netdev@vger.kernel.org
> > Sent: Monday, 21 January, 2013 9:37:41 AM
> > Subject: Re: IPsec AH use of ahash
> > > 
> > > I find that 73% of all stats are made up.
> > 
> > I was only talking about my own experience. I gave no numbers.
> 
> That was a joke.  You assumed that because I don't trim whitespace from multi-line comments [among other asinine code style issues] that I'm a bad developer.  Yet what actually happened was a build configuration error in which the file wasn't being compiled fully.

Heh, I got it. My point was that sloppy coding usually comes with
mistakes. I wasn't saying that your code is sloppy, or that all code
that checkpatch fails on is sloppy. But it's a way to clean things up.

Actually, there's been several times I found that cleaning up code that
checkpatch told me to fix, I would find a bug. Usually a silly error,
but something that would have needed to be fixed.

> 
> Let it go.

It's gone.

> > 
> > Some of checkpatch'es complaints are annoying. I'll grant you that.
> > And
> > checkpatch is more of a guideline than a strict rule. It's up to the
> > maintainer of the code to determine how much checkpatch should be
> > enforced.
> 
> That's not the impression I got from this weekends exchange.  

It's also up to the maintainer. Some maintainers are stricter than
others. And if they find that checkpatch is helpful, they may be more
inclined to push harder.

> 
> > For example, checkpatch complains on code like:
> > 
> > +       asm volatile (
> > +#ifdef CONFIG_X86_64
> > +                       "       xchg   %%rbx,%%rsp      \n"
> > +#else
> > +                       "       xchgl   %%ebx,%%esp     \n"
> > +#endif
> > +                       "       int3                    \n"
> > +                       "       .globl jprobe_return_end\n"
> > +                       "       jprobe_return_end:      \n"
> > +                       "       nop                     \n"::"b"
> > +                       (kcb->jprobe_saved_sp):"memory");
> > 
> > Because the white space before the '\n' is not needed. But adding
> > that
> > whitespace makes it easier to read the assembly.
> 
> So who gets to decide when/where to deviate from the rules?  

The maintainer does.

>  
> > When enforcing checkpatch makes the code less readable, that's when
> > it
> > should be ignored. But again, that's really up to the maintainer of
> > the
> > code to decide.
> 
> So we divine what the maintainer wants and doesn't want when we submit patches?  I think for me I'm going to follow them literally for now to avoid issues. 

The differences are really minor. And yes, sometimes you don't find out
until you send a patch to the maintainer. I've had to change patches to
others code because of this. But really, I never thought it was a big
deal. As a maintainer myself, I know that I want the code that I
maintain to be a certain way, because that makes me more efficient in
understanding the code. And I need to understand code that I didn't
write.

When I send a patch to another maintainer, and they tell me to fix the
way I did the comments, I don't complain. I fix the comments and resend.

-- Steve

^ permalink raw reply

* r8169 doing more work than napi weight
From: Timo Teras @ 2013-01-21 15:12 UTC (permalink / raw)
  To: Francois Romieu, netdev

Hi,

I'm getting:

WARNING: at linux-grsec/src/linux-3.4/net/core/dev.c:3875 net_rx_action+0xab/0x153()

on one of my r8169 boxes.

This would be the:
	WARN_ON_ONCE(work > weight); 

Now the only way this seems to be possible to happen is that the AMD
workaround triggers:
        if ((desc->opts2 & cpu_to_le32(0xfffe000)) &&
            (tp->mac_version == RTL_GIGA_MAC_VER_05)) {
                 desc->opts2 = 0;
                 cur_rx++;
        }

And yes, the hardware where the WARN_ON_ONCE triggers is indeed
RTL_GIGA_MAC_VER_05.

This would cause cur_rx to be incremented twice in the loop, but
rx_left not decremented accordingly.

As the work done is counted finally based on cur_rx, we might end up
returning more work done than what was our quota.

This has also the unwanted consequence of messing NAPI state as if more
work than quota was done then polling is stopped as the work == weight
does not trigger and the polling is not rescheduled.

Git log says that this workaround was copied from Realtek's r8168
driver, but I don't see anything like this there anymore.

I'm wondering if we should just delete the
	cur_rx++;
Or add:
	rx_left--;

Or just delete the whole block as obsolete. 'git log' says the problem
should have gone away by always using hardware Rx VLAN. See commit
05af214 "r8169: fix Ethernet Hangup for RTL8110SC rev d".

Thanks,
 Timo

^ 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