Netdev List
 help / color / mirror / Atom feed
* Re: [net-next-2.6 PATCH] net: fast consecutive name allocation
From: Stephen Hemminger @ 2009-11-13 22:29 UTC (permalink / raw)
  To: Octavian Purdila; +Cc: Eric Dumazet, netdev
In-Reply-To: <200911131151.31677.opurdila@ixiacom.com>

On Fri, 13 Nov 2009 11:51:31 +0200
Octavian Purdila <opurdila@ixiacom.com> wrote:

> For us the usecase is creating interfaces that get used by applications that 
> generate all sorts of traffic. This allows us to simulate realistic end user 
> traffic (e.g. coming from a full blown stack). That sounds reasonable to us :)

So it is lots of pseudo-devices for a special purpose test machine.
That's great use of Linux, but not a case worth optimizing for in the mainline kernel.

^ permalink raw reply

* Re: [net-next-2.6 PATCH] allow access to sysfs_groups member
From: Stephen Hemminger @ 2009-11-13 22:27 UTC (permalink / raw)
  To: Kurt Van Dijck; +Cc: Oliver Hartkopp, Wolfgang Grandegger, netdev
In-Reply-To: <20091113105157.GA322@e-circ.dyndns.org>

On Fri, 13 Nov 2009 11:51:57 +0100
Kurt Van Dijck <kurt.van.dijck@eia.be> wrote:

> +/* Add a sysfs group to the netdev groups */
> +int netdev_sysfs_add_group(struct net_device *net,
> +		struct attribute_group *grp)
> +{
> +	struct attribute_group **groups = net->sysfs_groups;
> +	struct attribute_group **end;
> +
> +	/* end pointer, with room for null terminator */
> +	end = &net->sysfs_groups[ARRAY_SIZE(net->sysfs_groups) - 1];
> +	for (; groups < end; ++groups) {
> +		if (!*groups) {
> +			*groups = grp;
> +			return 0;
> +		}
> +	}
> +	return -ENOSPC;
> +}
> +EXPORT_SYMBOL(netdev_sysfs_add_group);

EXPORT_SYMBOL_GPL() for all device/sysfs related stuff.

Also, need some way to BUG() if this is done after device has
been registered.  

Another way to add sub-directories which is what bridge, bonding,
and others do is to use another kobject. I think this is what you
want for the case of two CAN objects under one netdevice.

^ permalink raw reply

* Re: [PATCH 04/10] AOE: use rcu to find network device
From: Stephen Hemminger @ 2009-11-13 22:24 UTC (permalink / raw)
  To: Ed Cashin; +Cc: ecashin, davem, harvey.harrison, bzolnier, netdev
In-Reply-To: <11632bada28093377596d63180fe6c1c@coraid.com>

On Fri, 13 Nov 2009 16:39:49 -0500
Ed Cashin <ecashin@coraid.com> wrote:

> I will be testing the patch below on Monday.  It is based on Stephen
> Hemminger's starter patch (Thanks!).  It adds handling for the case
> where all of the local network interfaces have become unusable.  In
> that case, sent packets and retransmitted packets are effectively
> dropped, and the driver's handling of ethernet's unreliability takes
> care of things as usual.  If a local interface becomes usable in time
> no I/O will fail.
> 
> After testing I'll make a proper changelog entry.  In brief this patch
> allows the aoe driver to correctly take references on the net_device's
> that it uses, handle their removal via a callback, and handle their
> complete absence, too.

Looks good, good luck with testing.

^ permalink raw reply

* Re: [PATCH] niu.c: Use correct length in strncmp
From: David Miller @ 2009-11-13 22:10 UTC (permalink / raw)
  To: joe; +Cc: netdev
In-Reply-To: <1257825945.12852.89.camel@Joe-Laptop.home>

From: Joe Perches <joe@perches.com>
Date: Mon, 09 Nov 2009 20:05:45 -0800

> Untested, no hardware
> 
> Signed-off-by: Joe Perches <joe@perches.com>

Applied to net-next-2.6, thanks.

^ permalink raw reply

* Re: net 01/02: allow to propagate errors through ->ndo_hard_start_xmit()
From: David Miller @ 2009-11-13 22:10 UTC (permalink / raw)
  To: kaber; +Cc: netdev
In-Reply-To: <4AF99156.9050301@trash.net>

From: Patrick McHardy <kaber@trash.net>
Date: Tue, 10 Nov 2009 17:14:14 +0100

> The following two patches add support for error propagation
> through ->ndo_hard_start_xmit() and use it to propagate qdisc
> submission state through VLAN and macvlan devices.

Both applied to net-next-2.6, thanks.

^ permalink raw reply

* Re: [PATCH] check the return value of ndo_select_queue()
From: David Miller @ 2009-11-13 22:09 UTC (permalink / raw)
  To: eric.dumazet; +Cc: xiaosuo, netdev
In-Reply-To: <4AF8E165.6000801@gmail.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 10 Nov 2009 04:43:33 +0100

> Changli Gao a écrit :
>> check the return value of ndo_select_queue()
>> 
>> Check the return value of ndo_select_queue(). If the value isn't smaller
>> than the real_num_tx_queues, print a warning message, and reset it to zero.
>> 
>> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
> 
> Acked-by: Eric Dumazet <eric.dumazet@gmail.com>

This patch does not apply properly to net-next-2.6, the dev_pick_tx()
function looks a lot different now.

Please respin this patch and resubmit, thank you.

^ permalink raw reply

* Those gpio-mdio patches...
From: David Miller @ 2009-11-13 21:59 UTC (permalink / raw)
  To: lsorense; +Cc: netdev


Please don't fix the issue that way.  If the routine is returning a
true or false value, make it return a 'bool' instead of an 'int'.
That way we don't have to "accept something other than 0 and 1"

Thanks.

^ permalink raw reply

* Re: [PATCH] tcp: provide more information on the tcp receive_queue bugs
From: David Miller @ 2009-11-13 21:56 UTC (permalink / raw)
  To: ilpo.jarvinen; +Cc: herbert, arjan, netdev
In-Reply-To: <alpine.DEB.2.00.0911091053200.13479@melkinpaasi.cs.helsinki.fi>

From: "Ilpo Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Mon, 9 Nov 2009 11:19:18 +0200 (EET)

> The addition of rcv_nxt allows to discern whether the skb
> was out of place or tp->copied. Also catch fancy combination
> of flags if necessary (sadly we might miss the actual causer
> flags as it might have already returned).
> 
> Btw, we perhaps would want to forward copied_seq in
> somewhere or otherwise we might have some nice loop with
> WARN stuff within but where to do that safely I don't
> know at this stage until more is known (but it is not
> made significantly worse by this patch).
> 
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>

Applied to net-2.6, thanks a lot!

^ permalink raw reply

* Re: [PATCH 04/10] AOE: use rcu to find network device
From: Ed Cashin @ 2009-11-13 21:39 UTC (permalink / raw)
  To: ecashin, shemminger, davem, harvey.harrison, bzolnier, netdev
In-Reply-To: <a30adfc1658e1d5f2f35fee1bb89b364@coraid.com>

[-- Attachment #1: Type: text/plain, Size: 671 bytes --]

I will be testing the patch below on Monday.  It is based on Stephen
Hemminger's starter patch (Thanks!).  It adds handling for the case
where all of the local network interfaces have become unusable.  In
that case, sent packets and retransmitted packets are effectively
dropped, and the driver's handling of ethernet's unreliability takes
care of things as usual.  If a local interface becomes usable in time
no I/O will fail.

After testing I'll make a proper changelog entry.  In brief this patch
allows the aoe driver to correctly take references on the net_device's
that it uses, handle their removal via a callback, and handle their
complete absence, too.

-- 
  Ed

[-- Attachment #2: Type: text/plain, Size: 5048 bytes --]

diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index db195ab..315d36b 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -186,6 +186,7 @@ void aoecmd_ata_rsp(struct sk_buff *);
 void aoecmd_cfg_rsp(struct sk_buff *);
 void aoecmd_sleepwork(struct work_struct *);
 void aoecmd_cleanslate(struct aoedev *);
+void aoecmd_flushnet(struct aoedev *, struct net_device *);
 struct sk_buff *aoecmd_ata_id(struct aoedev *);
 
 int aoedev_init(void);
@@ -194,6 +195,7 @@ struct aoedev *aoedev_by_aoeaddr(int maj, int min);
 struct aoedev *aoedev_by_sysminor_m(ulong sysminor);
 void aoedev_downdev(struct aoedev *d);
 int aoedev_flush(const char __user *str, size_t size);
+void aoedev_ejectnet(struct net_device *);
 
 int aoenet_init(void);
 void aoenet_exit(void);
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 965ece2..060c8d6 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -93,16 +93,16 @@ put_lba(struct aoe_atahdr *ah, sector_t lba)
 	ah->lba5 = lba >>= 8;
 }
 
-static void
+static struct net_device *
 ifrotate(struct aoetgt *t)
 {
 	t->ifp++;
 	if (t->ifp >= &t->ifs[NAOEIFS] || t->ifp->nd == NULL)
 		t->ifp = t->ifs;
-	if (t->ifp->nd == NULL) {
-		printk(KERN_INFO "aoe: no interface to rotate to\n");
-		BUG();
-	}
+	if (t->ifp->nd == NULL && net_ratelimit())
+		printk(KERN_WARNING
+			"aoe: no local interface to send through\n");
+	return t->ifp->nd;
 }
 
 static void
@@ -336,7 +336,8 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
 	char buf[128];
 	u32 n;
 
-	ifrotate(t);
+	if (!ifrotate(t))
+		return;		/* no usable local network interfaces */
 	n = newtag(t);
 	skb = f->skb;
 	h = (struct aoe_hdr *) skb_mac_header(skb);
@@ -413,6 +414,8 @@ addif(struct aoetgt *t, struct net_device *nd)
 	p = getif(t, NULL);
 	if (!p)
 		return NULL;
+
+	dev_hold(nd);
 	p->nd = nd;
 	p->maxbcnt = DEFAULTBCNT;
 	p->lost = 0;
@@ -424,12 +427,30 @@ static void
 ejectif(struct aoetgt *t, struct aoeif *ifp)
 {
 	struct aoeif *e;
+	struct net_device *nd;
 	ulong n;
 
 	e = t->ifs + NAOEIFS - 1;
+	nd = e->nd;
 	n = (e - ifp) * sizeof *ifp;
 	memmove(ifp, ifp+1, n);
 	e->nd = NULL;
+	dev_put(nd);
+}
+
+void
+aoecmd_flushnet(struct aoedev *d, struct net_device *nd)
+{
+	struct aoetgt **tt, **te;
+	tt = d->targets;
+	te = tt + NTARGETS;
+	for (; tt < te && *tt; tt++) {
+		struct aoetgt *t = *tt;
+		struct aoeif *ifp;
+
+		if ( (ifp = getif(t, nd)) )
+			ejectif(t, ifp);
+	}
 }
 
 static int
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index fa67027..6754db0 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -162,6 +162,21 @@ aoedev_flush(const char __user *str, size_t cnt)
 	return 0;
 }
 
+void
+aoedev_ejectnet(struct net_device *nd)
+{
+	struct aoedev *d;
+	unsigned long flags;
+
+	spin_lock_irqsave(&devlist_lock, flags);
+	for (d = devlist; d; d = d->next) {
+		spin_lock(&d->lock);
+		aoecmd_flushnet(d, nd);
+		spin_unlock(&d->lock);
+	}
+	spin_unlock_irqrestore(&d->lock, flags);
+}
+
 /* I'm not really sure that this is a realistic problem, but if the
 network driver goes gonzo let's just leak memory after complaining. */
 static void
diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c
index 7f83ad9..5f6c072 100644
--- a/drivers/block/aoe/aoemain.c
+++ b/drivers/block/aoe/aoemain.c
@@ -8,6 +8,8 @@
 #include <linux/blkdev.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/notifier.h>
+#include <linux/netdevice.h>
 #include "aoe.h"
 
 MODULE_LICENSE("GPL");
@@ -54,11 +56,29 @@ discover_timer(ulong vp)
 	}
 }
 
+/* Callback on change of state of network device. */
+static int
+aoe_device_event(struct notifier_block *unused,
+		unsigned long event, void *ptr)
+{
+	struct net_device *nd = ptr;
+
+	if (event == NETDEV_UNREGISTER)
+		aoedev_ejectnet(nd);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block aoe_notifier = {
+	.notifier_call = aoe_device_event,
+};
+
 static void
 aoe_exit(void)
 {
 	discover_timer(TKILL);
 
+	unregister_netdevice_notifier(&aoe_notifier);
 	aoenet_exit();
 	unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
 	aoechr_exit();
@@ -83,6 +103,9 @@ aoe_init(void)
 	ret = aoenet_init();
 	if (ret)
 		goto net_fail;
+	ret = register_netdevice_notifier(&aoe_notifier);
+	if (ret)
+		goto notifier_fail;
 	ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
 	if (ret < 0) {
 		printk(KERN_ERR "aoe: can't register major\n");
@@ -94,6 +117,8 @@ aoe_init(void)
 	return 0;
 
  blkreg_fail:
+	unregister_netdevice_notifier(&aoe_notifier);
+ notifier_fail:
 	aoenet_exit();
  net_fail:
 	aoeblk_exit();
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index ce0d62c..cc3872c 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -90,7 +90,10 @@ aoenet_xmit(struct sk_buff_head *queue)
 
 	skb_queue_walk_safe(queue, skb, tmp) {
 		__skb_unlink(skb, queue);
-		dev_queue_xmit(skb);
+		if (skb->dev)
+			dev_queue_xmit(skb);
+		else
+			dev_kfree_skb(skb);
 	}
 }
 

^ permalink raw reply related

* Re: [PATCH 0/3] macvlan: support for guest vm direct rx/tx
From: Stephen Hemminger @ 2009-11-13 21:27 UTC (permalink / raw)
  To: Patrick Mullaney
  Cc: kaber, netdev, alacrityvm-devel, linux-kernel, arnd, bridge
In-Reply-To: <20091113195201.11184.25766.stgit@mimic.site>

On Fri, 13 Nov 2009 14:55:06 -0500
Patrick Mullaney <pmullaney@novell.com> wrote:

> These patches allow other modules to override the receive
> path of a macvlan. This is being done to support guest
> VMs operating directly over a macvlan. Routines to allow
> creation and deletion of macvlans from in-kernel modules
> were also exposed/added.

Which guest VM, how will it use it? The kernel is not in the business
of providing infrastructure for out of tree patches.

Also, macvlan should really being calling netif_receive_skb()
not going through another queue/softirq cycle.

^ permalink raw reply

* Re: large packet loss take2 2.6.31.x
From: Jarek Poplawski @ 2009-11-13 21:16 UTC (permalink / raw)
  To: Caleb Cushing; +Cc: Frans Pop, Andi Kleen, linux-kernel, netdev
In-Reply-To: <81bfc67a0911130825o6d9b93b2he70677157ad889f2@mail.gmail.com>

On Fri, Nov 13, 2009 at 11:25:25AM -0500, Caleb Cushing wrote:
> > So I assume it's your only network device on this box and according
> > to these reports it's 192.168.1.3 with 192.168.1.1 as the gateway,
> > and your only change is kernel on this 192.168.1.3 box, right?
> 
> yes, and semi obviously that router is my box (LinkSys wrt 54gl
> openwrt kamikaze 8.09.1.
> 
> > Since the loss is seen on the first hop already, it seems it should be
> > enough to query 192.168.1.1 only - did you try this? If so, does this
> > happen from the beginning of the test or after many loops? Could you
> > try to repeat this wireshark dump with more data than before (but just
> > to be sure there are a few unanswered pings). If possible it would be
> > nice to have wireshark or tcpdump data from 192.168.1.1 too, while
> > pinged from 192.168.1.3. Please, send it gzipped to bugzilla only plus
> > ifconfig eth0 before and after the test (and let us know here).
> 
> same bug? or new bug? I can see what I can do to get a tcpdump from
> the router.  yes I tried that, I can tell within the first 10 pings. I
> should say I don't notice it on every kernel boot, it's ~80% of
> reboots (but that's pulled from my behind). but I haven't noticed it
> on gfa31221 at all. it's reproducible in 31.6 too (arch just added
> that).

Might be the same bugzilla report, I guess. We need to establish if
these pings reach 192.168.1.1, so a short test and tcpdump without any
special options just to get a few lost cases as seen on both sides.
(And ifconfigs before and after the test.)

Btw, could you check with lsmod if usbserial module is loaded before
this test? I'd like to verify this git bisection result. (If the
module is loaded or you have CONFIG_USB_SERIAL=y instead of m, try to
recompile the kernel with this option turned off, for this test.)

Thanks,
Jarek P.

^ permalink raw reply

* r8169: Fix receive buffer length when MTU is between 1515 and 1536 (Was: r8169: fix driver drop incoming packets >= 1515 ...)
From: Raimonds Cicans @ 2009-11-13 20:52 UTC (permalink / raw)
  To: romieu; +Cc: netdev

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



[-- Attachment #2: r8169-mtu1536-v2.patch --]
[-- Type: text/plain, Size: 1443 bytes --]

In r8169 driver MTU is used to calculate receive buffer size.
Receive buffer size is used to configure hardware incoming packet filter.

For jumbo frames:
Receive buffer size = Max frame size = MTU + 14 (ethernet header) + 4
(vlan header) + 4 (ethernet checksum) = MTU + 22

Bug:
driver for all MTU up to 1536 use receive buffer size 1536

As you can see from formula, this mean all IP packets > 1536 - 22
(for vlan tagged, 1536 - 18 for not tagged) are dropped by hardware
filter.

Example:

host_good>  ifconfig eth0 mtu 1536
host_r8169> ifconfig eth0 mtu 1536
host_good>  ping host_r8169
Ok
host_good>  ping -s 1500 host_r8169
Fail
host_good>  ifconfig eth0 mtu 7000
host_r8169> ifconfig eth0 mtu 7000
host_good>  ping -s 1500 host_r8169
Ok


Bonus: got rid of magic number 8

Signed-off-by: Raimonds Cicans <ray@apollo.lv>

---

--- linux-2.6.31/drivers/net/r8169.c.orig	2009-11-06 21:52:12.722326601 +0200
+++ linux-2.6.31/drivers/net/r8169.c	2009-11-06 22:09:17.242224014 +0200
@@ -2229,9 +2229,9 @@ static void __devexit rtl8169_remove_one
 static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
 				  struct net_device *dev)
 {
-	unsigned int mtu = dev->mtu;
+	unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
 
-	tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
+	tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
 }
 
 static int rtl8169_open(struct net_device *dev)

^ permalink raw reply

* [PATCH 3/3] macvlan: allow in-kernel modules to create and manage macvlan devices
From: Patrick Mullaney @ 2009-11-13 19:55 UTC (permalink / raw)
  To: kaber, netdev; +Cc: alacrityvm-devel, linux-kernel, arnd, bridge
In-Reply-To: <20091113195201.11184.25766.stgit@mimic.site>

The macvlan driver didn't allow for creation/deletion of devices
by other in-kernel modules. This patch provides common routines
for both in-kernel and netlink based management. This patch
also enables macvlan device support for gro for lower level
devices that support gro.

Signed-off-by: Patrick Mullaney <pmullaney@novell.com>
---

 drivers/net/macvlan.c   |   72 ++++++++++++++++++++++++++++++++---------------
 include/linux/macvlan.h |    4 +++
 2 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 3425e12..bb180d0 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -210,7 +210,7 @@ static const struct header_ops macvlan_hard_header_ops = {
 	.cache_update	= eth_header_cache_update,
 };
 
-static int macvlan_open(struct net_device *dev)
+int macvlan_open(struct net_device *dev)
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct net_device *lowerdev = vlan->lowerdev;
@@ -237,7 +237,7 @@ out:
 	return err;
 }
 
-static int macvlan_stop(struct net_device *dev)
+int macvlan_stop(struct net_device *dev)
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct net_device *lowerdev = vlan->lowerdev;
@@ -318,7 +318,7 @@ static struct lock_class_key macvlan_netdev_addr_lock_key;
 #define MACVLAN_FEATURES \
 	(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
 	 NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \
-	 NETIF_F_TSO_ECN | NETIF_F_TSO6)
+	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO)
 
 #define MACVLAN_STATE_MASK \
 	((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
@@ -454,6 +454,44 @@ int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
 }
 EXPORT_SYMBOL_GPL(macvlan_validate);
 
+int macvlan_link_lowerdev(struct net_device *dev,
+			  struct net_device *lowerdev)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	struct macvlan_port *port;
+	int err = 0;
+
+	if (lowerdev->macvlan_port == NULL) {
+		err = macvlan_port_create(lowerdev);
+		if (err < 0)
+			return err;
+	}
+	port = lowerdev->macvlan_port;
+
+	vlan->lowerdev = lowerdev;
+	vlan->dev      = dev;
+	vlan->port     = port;
+	vlan->receive  = netif_rx;
+
+	macvlan_init(dev);
+
+	list_add_tail(&vlan->list, &port->vlans);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(macvlan_link_lowerdev);
+
+void macvlan_unlink_lowerdev(struct net_device *dev)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	struct macvlan_port *port = vlan->port;
+
+	list_del(&vlan->list);
+
+	if (list_empty(&port->vlans))
+		macvlan_port_destroy(port->dev);
+}
+EXPORT_SYMBOL_GPL(macvlan_unlink_lowerdev);
+
 static int macvlan_get_tx_queues(struct net *net,
 				 struct nlattr *tb[],
 				 unsigned int *num_tx_queues,
@@ -504,38 +542,26 @@ int macvlan_newlink(struct net_device *dev,
 	if (!tb[IFLA_ADDRESS])
 		random_ether_addr(dev->dev_addr);
 
-	if (lowerdev->macvlan_port == NULL) {
-		err = macvlan_port_create(lowerdev);
-		if (err < 0)
-			return err;
-	}
-	port = lowerdev->macvlan_port;
-
-	vlan->lowerdev = lowerdev;
-	vlan->dev      = dev;
-	vlan->port     = port;
-	vlan->receive  = netif_rx;
+	err = macvlan_link_lowerdev(dev, lowerdev);
+	if (err < 0)
+		return err;
 
 	err = register_netdevice(dev);
-	if (err < 0)
+	if (err < 0) {
+		macvlan_unlink_lowerdev(dev);
 		return err;
+	}
 
-	list_add_tail(&vlan->list, &port->vlans);
 	netif_stacked_transfer_operstate(dev, lowerdev);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(macvlan_newlink);
 
 void macvlan_dellink(struct net_device *dev)
 {
-	struct macvlan_dev *vlan = netdev_priv(dev);
-	struct macvlan_port *port = vlan->port;
-
-	list_del(&vlan->list);
+	macvlan_unlink_lowerdev(dev);
 	unregister_netdevice(dev);
-
-	if (list_empty(&port->vlans))
-		macvlan_port_destroy(port->dev);
 }
 EXPORT_SYMBOL_GPL(macvlan_dellink);
 
diff --git a/include/linux/macvlan.h b/include/linux/macvlan.h
index 3f3c6c3..27f56d9 100644
--- a/include/linux/macvlan.h
+++ b/include/linux/macvlan.h
@@ -24,6 +24,10 @@ struct macvlan_dev {
 };
 
 extern int macvlan_start_xmit(struct sk_buff *skb, struct net_device *dev);
+extern int macvlan_link_lowerdev(struct net_device *dev,
+				 struct net_device *lowerdev);
+
+extern void macvlan_unlink_lowerdev(struct net_device *dev);
 
 extern void macvlan_setup(struct net_device *dev);
 


^ permalink raw reply related

* [PATCH 2/3] macvlan:  derived from Arnd Bergmann's patch for macvtap
From: Patrick Mullaney @ 2009-11-13 19:55 UTC (permalink / raw)
  To: kaber, netdev; +Cc: alacrityvm-devel, linux-kernel, arnd, bridge
In-Reply-To: <20091113195201.11184.25766.stgit@mimic.site>

This patch includes only the basic framework for overriding the
receive path and the macvlan header was moved to allow modules
outside of driver/net to use it.

Signed-off-by: Patrick Mullaney <pmullaney@novell.com>
---

 drivers/net/macvlan.c   |   41 ++++++++++++++++-------------------------
 include/linux/macvlan.h |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 25 deletions(-)
 create mode 100644 include/linux/macvlan.h

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 41dc71f..3425e12 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -30,22 +30,7 @@
 #include <linux/if_macvlan.h>
 #include <net/rtnetlink.h>
 
-#define MACVLAN_HASH_SIZE	(1 << BITS_PER_BYTE)
-
-struct macvlan_port {
-	struct net_device	*dev;
-	struct hlist_head	vlan_hash[MACVLAN_HASH_SIZE];
-	struct list_head	vlans;
-};
-
-struct macvlan_dev {
-	struct net_device	*dev;
-	struct list_head	list;
-	struct hlist_node	hlist;
-	struct macvlan_port	*port;
-	struct net_device	*lowerdev;
-};
-
+#include <linux/macvlan.h>
 
 static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
 					       const unsigned char *addr)
@@ -135,7 +120,7 @@ static void macvlan_broadcast(struct sk_buff *skb,
 			else
 				nskb->pkt_type = PACKET_MULTICAST;
 
-			netif_rx(nskb);
+			vlan->receive(nskb);
 		}
 	}
 }
@@ -180,12 +165,12 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
 	skb->dev = dev;
 	skb->pkt_type = PACKET_HOST;
 
-	netif_rx(skb);
+	vlan->receive(skb);
 	return NULL;
 }
 
-static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
-				      struct net_device *dev)
+netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
+			       struct net_device *dev)
 {
 	int i = skb_get_queue_mapping(skb);
 	struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
@@ -204,6 +189,7 @@ static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
 
 	return NETDEV_TX_OK;
 }
+EXPORT_SYMBOL_GPL(macvlan_start_xmit);
 
 static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
 			       unsigned short type, const void *daddr,
@@ -414,7 +400,7 @@ static const struct net_device_ops macvlan_netdev_ops = {
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
-static void macvlan_setup(struct net_device *dev)
+void macvlan_setup(struct net_device *dev)
 {
 	ether_setup(dev);
 
@@ -425,6 +411,7 @@ static void macvlan_setup(struct net_device *dev)
 	dev->ethtool_ops	= &macvlan_ethtool_ops;
 	dev->tx_queue_len	= 0;
 }
+EXPORT_SYMBOL_GPL(macvlan_setup);
 
 static int macvlan_port_create(struct net_device *dev)
 {
@@ -455,7 +442,7 @@ static void macvlan_port_destroy(struct net_device *dev)
 	kfree(port);
 }
 
-static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
+int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
 {
 	if (tb[IFLA_ADDRESS]) {
 		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
@@ -465,6 +452,7 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(macvlan_validate);
 
 static int macvlan_get_tx_queues(struct net *net,
 				 struct nlattr *tb[],
@@ -485,8 +473,8 @@ static int macvlan_get_tx_queues(struct net *net,
 	return 0;
 }
 
-static int macvlan_newlink(struct net_device *dev,
-			   struct nlattr *tb[], struct nlattr *data[])
+int macvlan_newlink(struct net_device *dev,
+		    struct nlattr *tb[], struct nlattr *data[])
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct macvlan_port *port;
@@ -526,6 +514,7 @@ static int macvlan_newlink(struct net_device *dev,
 	vlan->lowerdev = lowerdev;
 	vlan->dev      = dev;
 	vlan->port     = port;
+	vlan->receive  = netif_rx;
 
 	err = register_netdevice(dev);
 	if (err < 0)
@@ -535,8 +524,9 @@ static int macvlan_newlink(struct net_device *dev,
 	netif_stacked_transfer_operstate(dev, lowerdev);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(macvlan_newlink);
 
-static void macvlan_dellink(struct net_device *dev)
+void macvlan_dellink(struct net_device *dev)
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct macvlan_port *port = vlan->port;
@@ -547,6 +537,7 @@ static void macvlan_dellink(struct net_device *dev)
 	if (list_empty(&port->vlans))
 		macvlan_port_destroy(port->dev);
 }
+EXPORT_SYMBOL_GPL(macvlan_dellink);
 
 static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
 	.kind		= "macvlan",
diff --git a/include/linux/macvlan.h b/include/linux/macvlan.h
new file mode 100644
index 0000000..3f3c6c3
--- /dev/null
+++ b/include/linux/macvlan.h
@@ -0,0 +1,37 @@
+#ifndef _MACVLAN_H
+#define _MACVLAN_H
+
+#include <linux/netdevice.h>
+#include <linux/netlink.h>
+#include <linux/list.h>
+
+#define MACVLAN_HASH_SIZE	(1 << BITS_PER_BYTE)
+
+struct macvlan_port {
+	struct net_device	*dev;
+	struct hlist_head	vlan_hash[MACVLAN_HASH_SIZE];
+	struct list_head	vlans;
+};
+
+struct macvlan_dev {
+	struct net_device	*dev;
+	struct list_head	list;
+	struct hlist_node	hlist;
+	struct macvlan_port	*port;
+	struct net_device	*lowerdev;
+
+	int (*receive)(struct sk_buff *skb);
+};
+
+extern int macvlan_start_xmit(struct sk_buff *skb, struct net_device *dev);
+
+extern void macvlan_setup(struct net_device *dev);
+
+extern int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]);
+
+extern int macvlan_newlink(struct net_device *dev,
+		struct nlattr *tb[], struct nlattr *data[]);
+
+extern void macvlan_dellink(struct net_device *dev);
+
+#endif /* _MACVLAN_H */


^ permalink raw reply related

* [PATCH 1/3] netdevice: provide common routine for macvlan and vlan operstate management
From: Patrick Mullaney @ 2009-11-13 19:55 UTC (permalink / raw)
  To: kaber, netdev; +Cc: alacrityvm-devel, linux-kernel, arnd, bridge
In-Reply-To: <20091113195201.11184.25766.stgit@mimic.site>

Provide common routine for the transition of operational state for a leaf
device during a root device transition.

Signed-off-by: Patrick Mullaney <pmullaney@novell.com>
---

 drivers/net/macvlan.c     |   24 +++---------------------
 include/linux/netdevice.h |    3 +++
 net/8021q/vlan.c          |   29 ++++-------------------------
 net/core/dev.c            |   27 +++++++++++++++++++++++++++
 4 files changed, 37 insertions(+), 46 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 3aabfd9..41dc71f 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -455,25 +455,6 @@ static void macvlan_port_destroy(struct net_device *dev)
 	kfree(port);
 }
 
-static void macvlan_transfer_operstate(struct net_device *dev)
-{
-	struct macvlan_dev *vlan = netdev_priv(dev);
-	const struct net_device *lowerdev = vlan->lowerdev;
-
-	if (lowerdev->operstate == IF_OPER_DORMANT)
-		netif_dormant_on(dev);
-	else
-		netif_dormant_off(dev);
-
-	if (netif_carrier_ok(lowerdev)) {
-		if (!netif_carrier_ok(dev))
-			netif_carrier_on(dev);
-	} else {
-		if (netif_carrier_ok(dev))
-			netif_carrier_off(dev);
-	}
-}
-
 static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
 {
 	if (tb[IFLA_ADDRESS]) {
@@ -551,7 +532,7 @@ static int macvlan_newlink(struct net_device *dev,
 		return err;
 
 	list_add_tail(&vlan->list, &port->vlans);
-	macvlan_transfer_operstate(dev);
+	netif_stacked_transfer_operstate(dev, lowerdev);
 	return 0;
 }
 
@@ -591,7 +572,8 @@ static int macvlan_device_event(struct notifier_block *unused,
 	switch (event) {
 	case NETDEV_CHANGE:
 		list_for_each_entry(vlan, &port->vlans, list)
-			macvlan_transfer_operstate(vlan->dev);
+			netif_stacked_transfer_operstate(vlan->dev,
+							 vlan->lowerdev);
 		break;
 	case NETDEV_FEAT_CHANGE:
 		list_for_each_entry(vlan, &port->vlans, list) {
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 812a5f3..1587715 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1914,6 +1914,9 @@ unsigned long netdev_increment_features(unsigned long all, unsigned long one,
 					unsigned long mask);
 unsigned long netdev_fix_features(unsigned long features, const char *name);
 
+void netif_stacked_transfer_operstate(const struct net_device *rootdev,
+					struct net_device *dev);
+
 static inline int net_gso_ok(int features, int gso_type)
 {
 	int feature = gso_type << NETIF_F_GSO_SHIFT;
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 8836575..8157b32 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -183,27 +183,6 @@ void unregister_vlan_dev(struct net_device *dev)
 	dev_put(real_dev);
 }
 
-static void vlan_transfer_operstate(const struct net_device *dev,
-				    struct net_device *vlandev)
-{
-	/* Have to respect userspace enforced dormant state
-	 * of real device, also must allow supplicant running
-	 * on VLAN device
-	 */
-	if (dev->operstate == IF_OPER_DORMANT)
-		netif_dormant_on(vlandev);
-	else
-		netif_dormant_off(vlandev);
-
-	if (netif_carrier_ok(dev)) {
-		if (!netif_carrier_ok(vlandev))
-			netif_carrier_on(vlandev);
-	} else {
-		if (netif_carrier_ok(vlandev))
-			netif_carrier_off(vlandev);
-	}
-}
-
 int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
 {
 	const char *name = real_dev->name;
@@ -261,7 +240,7 @@ int register_vlan_dev(struct net_device *dev)
 	/* Account for reference in struct vlan_dev_info */
 	dev_hold(real_dev);
 
-	vlan_transfer_operstate(real_dev, dev);
+	netif_stacked_transfer_operstate(real_dev, dev);
 	linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
 
 	/* So, got the sucker initialized, now lets place
@@ -447,7 +426,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 			if (!vlandev)
 				continue;
 
-			vlan_transfer_operstate(dev, vlandev);
+			netif_stacked_transfer_operstate(dev, vlandev);
 		}
 		break;
 
@@ -503,7 +482,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 				continue;
 
 			dev_change_flags(vlandev, flgs & ~IFF_UP);
-			vlan_transfer_operstate(dev, vlandev);
+			netif_stacked_transfer_operstate(dev, vlandev);
 		}
 		break;
 
@@ -519,7 +498,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 				continue;
 
 			dev_change_flags(vlandev, flgs | IFF_UP);
-			vlan_transfer_operstate(dev, vlandev);
+			netif_stacked_transfer_operstate(dev, vlandev);
 		}
 		break;
 
diff --git a/net/core/dev.c b/net/core/dev.c
index b8f74cf..21e6f09 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4746,6 +4746,33 @@ unsigned long netdev_fix_features(unsigned long features, const char *name)
 EXPORT_SYMBOL(netdev_fix_features);
 
 /**
+ *	netif_stacked_transfer_operstate -	transfer operstate
+ *	@rootdev: the root or lower level device to transfer state from
+ *	@dev: the device to transfer operstate to
+ *
+ *	Transfer operational state from root to device. This is normally
+ *	called when a stacking relationship exists between the root
+ *	device and the device(a leaf device).
+ */
+void netif_stacked_transfer_operstate(const struct net_device *rootdev,
+					struct net_device *dev)
+{
+	if (rootdev->operstate == IF_OPER_DORMANT)
+		netif_dormant_on(dev);
+	else
+		netif_dormant_off(dev);
+
+	if (netif_carrier_ok(rootdev)) {
+		if (!netif_carrier_ok(dev))
+			netif_carrier_on(dev);
+	} else {
+		if (netif_carrier_ok(dev))
+			netif_carrier_off(dev);
+	}
+}
+EXPORT_SYMBOL(netif_stacked_transfer_operstate);
+
+/**
  *	register_netdevice	- register a network device
  *	@dev: device to register
  *

^ permalink raw reply related

* [PATCH 0/3] macvlan: support for guest vm direct rx/tx
From: Patrick Mullaney @ 2009-11-13 19:55 UTC (permalink / raw)
  To: kaber, netdev; +Cc: alacrityvm-devel, linux-kernel, arnd, bridge
In-Reply-To: <4AFAD86A.9070506@trash.net>

(Applies to net-2.6.git/master:1dfc5827)

These patches allow other modules to override the receive
path of a macvlan. This is being done to support guest
VMs operating directly over a macvlan. Routines to allow
creation and deletion of macvlans from in-kernel modules
were also exposed/added.

---

Patrick Mullaney (3):
      macvlan: allow in-kernel modules to create and manage macvlan devices
      macvlan:  derived from Arnd Bergmann's patch for macvtap
      netdevice: provide common routine for macvlan and vlan operstate management


 drivers/net/macvlan.c     |  135 ++++++++++++++++++++++-----------------------
 include/linux/macvlan.h   |   41 ++++++++++++++
 include/linux/netdevice.h |    3 +
 net/8021q/vlan.c          |   29 +---------
 net/core/dev.c            |   27 +++++++++
 5 files changed, 142 insertions(+), 93 deletions(-)
 create mode 100644 include/linux/macvlan.h


^ permalink raw reply

* Re: [net-next-2.6 PATCH v6 3/7 RFC] TCPCT part 1c: sysctl_tcp_cookie_size, socket option TCP_COOKIE_TRANSACTIONS
From: William Allen Simpson @ 2009-11-13 19:45 UTC (permalink / raw)
  To: Joe Perches; +Cc: Linux Kernel Network Developers
In-Reply-To: <1258137443.16857.124.camel@Joe-Laptop.home>

Joe Perches wrote:
> On Thu, 2009-11-12 at 23:31 -0500, William Allen Simpson wrote:
>> Define sysctl (tcp_cookie_size) to turn on and off the cookie option
>> default globally, instead of a compiled configuration option.
> []
> 
>> +#define TCP_COOKIE_MIN		 8		/*  64-bits */
>> +#define TCP_COOKIE_MAX		16		/* 128-bits */
> 
> perhaps something like:
> 
> static const int TCP_COOKIE_MIN = 8;
> static const int TCP_COOKIE_MAX = 16;
> 
> []
> 
>> --- a/net/ipv4/sysctl_net_ipv4.c
>> +++ b/net/ipv4/sysctl_net_ipv4.c
>> @@ -714,6 +714,14 @@ static struct ctl_table ipv4_table[] = {
>>  	},
>>  	{
>>  		.ctl_name	= CTL_UNNUMBERED,
>> +		.procname	= "tcp_cookie_size",
>> +		.data		= &sysctl_tcp_cookie_size,
>> +		.maxlen		= sizeof(int),
>> +		.mode		= 0644,
>> +		.proc_handler	= proc_dointvec
> 
> with proc_dointvec_minmax
> 
> 		.extra1		= &TCP_COOKIE_MIN,
> 		.extra2		= &TCP_COOKIE_MAX,
> 
> or even adding proc_dointvec_minmax_even
> might save some cycles during cookie handling.
> 
Well, that would have to be proc_dointvec_minmax_even_zero(), as the
valid values can be 0, 8, 10, 12, 14, or 16.  But my guess (based on
experience owning an ISP and teaching student operators) is that folks
will remember to turn it off (0) or on (1) or "bigger" (255), and not
really care about the finer gradations.

Error messages have a tendency to scroll off the screen and be forgotten.

And it seems to me a case of "premature optimization" -- it might save
1 or 2 tests in the order I've listed them in tcp_cookie_size_check(),
those tests only happen on the SYN the first time the _client_ calls,
and the result is saved for the future.  See part 1f:

+	u8 cookie_size = (!tp->rx_opt.cookie_out_never && cvp != NULL)
+			 ? tcp_cookie_size_check(cvp->cookie_desired)
+			 : 0;

[]

+			/* Remember for future incarnations. */
+			cvp->cookie_desired = cookie_size;

On the server side, we have to test during parsing anyway.  I never trust
any data that comes over the network....

^ permalink raw reply

* Re: [net-next-2.6 PATCH v6 3/7 RFC] TCPCT part 1c: sysctl_tcp_cookie_size, socket option TCP_COOKIE_TRANSACTIONS
From: Joe Perches @ 2009-11-13 18:37 UTC (permalink / raw)
  To: William Allen Simpson; +Cc: Linux Kernel Network Developers
In-Reply-To: <4AFCE13B.4060006@gmail.com>

On Thu, 2009-11-12 at 23:31 -0500, William Allen Simpson wrote:
> Define sysctl (tcp_cookie_size) to turn on and off the cookie option
> default globally, instead of a compiled configuration option.
[]

> +#define TCP_COOKIE_MIN		 8		/*  64-bits */
> +#define TCP_COOKIE_MAX		16		/* 128-bits */

perhaps something like:

static const int TCP_COOKIE_MIN = 8;
static const int TCP_COOKIE_MAX = 16;

[]

> --- a/net/ipv4/sysctl_net_ipv4.c
> +++ b/net/ipv4/sysctl_net_ipv4.c
> @@ -714,6 +714,14 @@ static struct ctl_table ipv4_table[] = {
>  	},
>  	{
>  		.ctl_name	= CTL_UNNUMBERED,
> +		.procname	= "tcp_cookie_size",
> +		.data		= &sysctl_tcp_cookie_size,
> +		.maxlen		= sizeof(int),
> +		.mode		= 0644,
> +		.proc_handler	= proc_dointvec

with proc_dointvec_minmax

		.extra1		= &TCP_COOKIE_MIN,
		.extra2		= &TCP_COOKIE_MAX,

or even adding proc_dointvec_minmax_even
might save some cycles during cookie handling.



^ permalink raw reply

* Re: [net-next-2.6 PATCH v6 2/7 RFC] TCPCT part 1b: generate Responder Cookie
From: Joe Perches @ 2009-11-13 18:04 UTC (permalink / raw)
  To: William Allen Simpson
  Cc: Linux Kernel Network Developers, Eric Dumazet, Paul E. McKenney
In-Reply-To: <4AFD728F.4030206@gmail.com>

On Fri, 2009-11-13 at 09:51 -0500, William Allen Simpson wrote:
> Since Eric says it can be inside the locked path, I can do away with
> that entirely, and just use the result (bakery) pointer itself.  Saves a
> memcpy, too.
> Here's my revised attempt (untested).  Any other technical corrections?

Just one, thanks for persisting.

> +	if (unlikely(time_after_eq(jiffy, tcp_secret_generating->expires))) {
> +		spin_lock_bh(&tcp_secret_locker);
> +		if (!time_after_eq(jiffy, tcp_secret_generating->expires)) {
[]
> +			spin_unlock_bh(&tcp_secret_locker);
> +		} else {
[]
> +			spin_unlock_bh(&tcp_secret_locker);
[removed comments]
> +		}

perhaps deleting the two unlocks above and moving it
to the same indent level here is trivially better.

		spin_unlock_bh(&tcp_secret_locker);



^ permalink raw reply

* [PATCH]remove deprecated and not used: print_mac()
From: Marin Mitov @ 2009-11-13 17:58 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, linux-kernel

Hi all,

The function print_mac in net/ethernet/eth.c is marked __deprecated
and not used. Remove it.

The patch is against 2.6.32-rc7.

Signed-off-by: Marin Mitov <mitov@issp.bas.bg>

=====================================================================
--- a/include/linux/if_ether.h	2009-11-13 19:16:15.000000000 +0200
+++ b/include/linux/if_ether.h	2009-11-13 19:18:25.000000000 +0200
@@ -136,10 +136,6 @@
 
 extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
 
-/*
- *	Display a 6 byte device address (MAC) in a readable format.
- */
-extern char *print_mac(char *buf, const unsigned char *addr) __deprecated;
 #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
 #define MAC_BUF_SIZE	18
 #define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE]

--- a/net/ethernet/eth.c	2009-11-13 19:16:30.000000000 +0200
+++ b/net/ethernet/eth.c	2009-11-13 19:20:31.000000000 +0200
@@ -393,10 +393,3 @@
 	return ((ssize_t) l);
 }
 EXPORT_SYMBOL(sysfs_format_mac);
-
-char *print_mac(char *buf, const unsigned char *addr)
-{
-	_format_mac_addr(buf, MAC_BUF_SIZE, addr, ETH_ALEN);
-	return buf;
-}
-EXPORT_SYMBOL(print_mac);

^ permalink raw reply

* Re: [PATCH] net/can: add driver for mscan family & mpc52xx_mscan
From: Grant Likely @ 2009-11-13 17:39 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: netdev, socketcan-core, linuxppc-dev, Wolfgang Grandegger,
	David Miller
In-Reply-To: <1258128892-28800-1-git-send-email-w.sang@pengutronix.de>

On Fri, Nov 13, 2009 at 9:14 AM, Wolfram Sang <w.sang@pengutronix.de> wrote:
> Taken from socketcan-svn, fixed remaining todos, cleaned up, tested with a
> phyCORE-MPC5200B-IO and a custom board.
>
> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> Cc: Wolfgang Grandegger <wg@grandegger.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: David Miller <davem@davemloft.net>

I don't see any locking in this driver.  What keeps the mscan_isr or
other routines from conflicting with each other?  What is the
concurrency model for CAN devices?

More comments below.  I don't have the background to delve into the
CAN details, but I can make some comments on the general structure of
the driver.

g.

> ---
>
> +static struct of_device_id mpc52xx_cdm_ids[] __devinitdata = {
> +       { .compatible = "fsl,mpc5200-cdm", },
> +       { .compatible = "fsl,mpc5200b-cdm", },
> +       {}
> +};

You can drop the 'b' line. The 'b' version is compatible with the
original, and all in-tree 5200b files claim compatibility with the
non-'b' version.

> +
> +/*
> + * Get the frequency of the external oscillator clock connected
> + * to the SYS_XTAL_IN pin, or return 0 if it cannot be determined.
> + */
> +static unsigned int  __devinit mpc52xx_can_xtal_freq(struct of_device *of)
> +{
> +       struct mpc52xx_cdm  __iomem *cdm;
> +       struct device_node *np_cdm;
> +       unsigned int freq;
> +       u32 val;
> +
> +       freq = mpc5xxx_get_bus_frequency(of->node);
> +       if (!freq)
> +               return 0;
> +
> +       /*
> +        * Determine SYS_XTAL_IN frequency from the clock domain settings
> +        */
> +       np_cdm = of_find_matching_node(NULL, mpc52xx_cdm_ids);
> +       if (!np_cdm) {
> +               dev_err(&of->dev, "can't get clock node!\n");
> +               return 0;
> +       }
> +       cdm = of_iomap(np_cdm, 0);
> +       of_node_put(np_cdm);
> +
> +       if (in_8(&cdm->ipb_clk_sel) & 0x1)
> +               freq *= 2;
> +       val  = in_be32(&cdm->rstcfg);
> +       if (val & (1 << 5))
> +               freq *= 8;
> +       else
> +               freq *= 4;

freq *= (val & (1 << 5)) ? 8 : 4;

> +       if (val & (1 << 6))
> +               freq /= 12;
> +       else
> +               freq /= 16;

Ditto.

> +
> +       iounmap(cdm);
> +
> +       return freq;
> +}
> +
> +/*
> + * Get frequency of the MSCAN clock source
> + *
> + * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock (IP_CLK)
> + * can be selected. According to the MPC5200 user's manual, the oscillator
> + * clock is the better choice as it has less jitter but due to a hardware
> + * bug, it can not be selected for the old MPC5200 Rev. A chips.
> + */
> +
> +static unsigned int  __devinit mpc52xx_can_clock_freq(struct of_device *of,
> +                                                     int clock_src)
> +{
> +       unsigned int pvr;
> +
> +       pvr = mfspr(SPRN_PVR);
> +
> +       if (clock_src == MSCAN_CLKSRC_BUS || pvr == 0x80822011)
> +               return mpc5xxx_get_bus_frequency(of->node);
> +
> +       return mpc52xx_can_xtal_freq(of);
> +}

mpc52xx_can_xtal_freq() is only used by this function.  Do they need
to be separate?

> +static int __devinit mpc5xxx_can_probe(struct of_device *ofdev,
> +                                      const struct of_device_id *id)
> +{
> +       struct device_node *np = ofdev->node;
> +       struct net_device *dev;
> +       struct mscan_priv *priv;
> +       void __iomem *base;
> +       const char *clk_src;
> +       int err, irq, clock_src;
> +
> +       base = of_iomap(ofdev->node, 0);
> +       if (!base) {
> +               dev_err(&ofdev->dev, "couldn't ioremap\n");
> +               err = -ENOMEM;
> +               goto exit_release_mem;
> +       }
> +
> +       irq = irq_of_parse_and_map(np, 0);
> +       if (!irq) {
> +               dev_err(&ofdev->dev, "no irq found\n");
> +               err = -ENODEV;
> +               goto exit_unmap_mem;
> +       }
> +
> +       dev = alloc_mscandev();
> +       if (!dev) {
> +               err = -ENOMEM;
> +               goto exit_dispose_irq;
> +       }
> +
> +       priv = netdev_priv(dev);
> +       priv->reg_base = base;
> +       dev->irq = irq;
> +
> +       /*
> +        * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock
> +        * (IP_CLK) can be selected as MSCAN clock source. According to
> +        * the MPC5200 user's manual, the oscillator clock is the better
> +        * choice as it has less jitter. For this reason, it is selected
> +        * by default.
> +        */
> +       clk_src = of_get_property(np, "fsl,mscan-clk-src", NULL);
> +       if (clk_src && strcmp(clk_src, "ip") == 0)

Should protect against non-null.  strncmp() maybe?


> +static struct of_device_id __devinitdata mpc5xxx_can_table[] = {
> +       {.compatible = "fsl,mpc5200-mscan"},
> +       {.compatible = "fsl,mpc5200b-mscan"},
> +       {},
> +};

Ditto here; the 'b' version can be dropped.

> +static int mscan_set_mode(struct net_device *dev, u8 mode)
> +{
> +       struct mscan_priv *priv = netdev_priv(dev);
> +       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
> +       int ret = 0;
> +       int i;
> +       u8 canctl1;
> +
> +       if (mode != MSCAN_NORMAL_MODE) {
> +
> +               if (priv->tx_active) {
> +                       /* Abort transfers before going to sleep */#
> +                       out_8(&regs->cantarq, priv->tx_active);
> +                       /* Suppress TX done interrupts */
> +                       out_8(&regs->cantier, 0);
> +               }
> +
> +               canctl1 = in_8(&regs->canctl1);
> +               if ((mode & MSCAN_SLPRQ) && (canctl1 & MSCAN_SLPAK) == 0) {
> +                       out_8(&regs->canctl0,
> +                             in_8(&regs->canctl0) | MSCAN_SLPRQ);
> +                       for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
> +                               if (in_8(&regs->canctl1) & MSCAN_SLPAK)
> +                                       break;
> +                               udelay(100);

Ugh.  Can you sleep instead?  This burns a lot of CPU cycles to no purpose.

> +                       }
> +                       /*
> +                        * The mscan controller will fail to enter sleep mode,
> +                        * while there are irregular activities on bus, like
> +                        * somebody keeps retransmitting. This behavior is
> +                        * undocumented and seems to differ between mscan built
> +                        * in mpc5200b and mpc5200. We proceed in that case,
> +                        * since otherwise the slprq will be kept set and the
> +                        * controller will get stuck. NOTE: INITRQ or CSWAI
> +                        * will abort all active transmit actions, if still
> +                        * any, at once.
> +                        */
> +                       if (i >= MSCAN_SET_MODE_RETRIES)
> +                               dev_dbg(dev->dev.parent,
> +                                       "device failed to enter sleep mode. "
> +                                       "We proceed anyhow.\n");
> +                       else
> +                               priv->can.state = CAN_STATE_SLEEPING;
> +               }
> +
> +               if ((mode & MSCAN_INITRQ) && (canctl1 & MSCAN_INITAK) == 0) {
> +                       out_8(&regs->canctl0,
> +                             in_8(&regs->canctl0) | MSCAN_INITRQ);
> +                       for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
> +                               if (in_8(&regs->canctl1) & MSCAN_INITAK)
> +                                       break;
> +                       }
> +                       if (i >= MSCAN_SET_MODE_RETRIES)
> +                               ret = -ENODEV;
> +               }
> +               if (!ret)
> +                       priv->can.state = CAN_STATE_STOPPED;
> +
> +               if (mode & MSCAN_CSWAI)
> +                       out_8(&regs->canctl0,
> +                             in_8(&regs->canctl0) | MSCAN_CSWAI);
> +
> +       } else {
> +               canctl1 = in_8(&regs->canctl1);
> +               if (canctl1 & (MSCAN_SLPAK | MSCAN_INITAK)) {
> +                       out_8(&regs->canctl0, in_8(&regs->canctl0) &
> +                             ~(MSCAN_SLPRQ | MSCAN_INITRQ));
> +                       for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
> +                               canctl1 = in_8(&regs->canctl1);
> +                               if (!(canctl1 & (MSCAN_INITAK | MSCAN_SLPAK)))
> +                                       break;
> +                       }
> +                       if (i >= MSCAN_SET_MODE_RETRIES)
> +                               ret = -ENODEV;
> +                       else
> +                               priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +               }
> +       }
> +       return ret;
> +}

[snip]

> +static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode)
> +{
> +
> +       struct mscan_priv *priv = netdev_priv(dev);
> +       int ret = 0;
> +
> +       if (!priv->open_time)
> +               return -EINVAL;
> +
> +       switch (mode) {
> +       case CAN_MODE_SLEEP:
> +       case CAN_MODE_STOP:
> +               netif_stop_queue(dev);
> +               mscan_set_mode(dev,
> +                              (mode ==
> +                               CAN_MODE_STOP) ? MSCAN_INIT_MODE :
> +                              MSCAN_SLEEP_MODE);

A little hard on the eyes.  Can you rework to not spill over 4 lines?
(ie. calc mode flag on the line above?)

> +               break;
> +       case CAN_MODE_START:
> +               if (priv->can.state <= CAN_STATE_BUS_OFF)
> +                       mscan_set_mode(dev, MSCAN_INIT_MODE);
> +               ret = mscan_start(dev);
> +               if (ret)
> +                       break;
> +               if (netif_queue_stopped(dev))
> +                       netif_wake_queue(dev);
> +               break;
> +
> +       default:
> +               ret = -EOPNOTSUPP;
> +               break;
> +       }
> +       return ret;
> +}

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: Lots of tcp_recvmsg warnings in kerneloops list
From: Eric Dumazet @ 2009-11-13 17:34 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Ilpo Järvinen, David Miller, netdev, Herbert Xu
In-Reply-To: <20091113091013.2bef993e@s6510>

Stephen Hemminger a écrit :
> Has anyone looked into this? Is there a fix? Should it be sent to stable?
> 
> http://kerneloops.org/searchweek.php?search=tcp_recvmsg
> --

Only debugging AFAIK, no discoveries yet.




commit c62f4c453ab4b0240ab857bfd089da2c01ad91e7
Author: Arjan van de Ven <arjan@linux.intel.com>
Date:   Thu Oct 22 21:37:56 2009 -0700

    net: use WARN() for the WARN_ON in commit b6b39e8f3fbbb
    
    Commit b6b39e8f3fbbb (tcp: Try to catch MSG_PEEK bug) added a printk()
    to the WARN_ON() that's in tcp.c. This patch changes this combination
    to WARN(); the advantage of WARN() is that the printk message shows up
    inside the message, so that kerneloops.org will collect the message.
    
    In addition, this gets rid of an extra if() statement.
    
    Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

commit b6b39e8f3fbbb31001b836afec87bcaf4811a7bf
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date:   Mon Oct 19 19:41:06 2009 +0000

    tcp: Try to catch MSG_PEEK bug
    
    This patch tries to print out more information when we hit the
    MSG_PEEK bug in tcp_recvmsg.  It's been around since at least
    2005 and it's about time that we finally fix it.
    
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: David S. Miller <davem@davemloft.net>


^ permalink raw reply

* Re: large packet loss take2 2.6.31.x
From: Caleb Cushing @ 2009-11-13 17:21 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: Frans Pop, Andi Kleen, linux-kernel, netdev
In-Reply-To: <81bfc67a0911130825o6d9b93b2he70677157ad889f2@mail.gmail.com>

any specific switches I should run tcpdump with? or any other tests I
should be trying while capturing? (on either end).

-- 
Caleb Cushing

http://xenoterracide.blogspot.com

^ permalink raw reply

* Lots of tcp_recvmsg warnings in kerneloops list
From: Stephen Hemminger @ 2009-11-13 17:10 UTC (permalink / raw)
  To: Ilpo Järvinen, David Miller; +Cc: netdev

Has anyone looked into this? Is there a fix? Should it be sent to stable?

http://kerneloops.org/searchweek.php?search=tcp_recvmsg

^ permalink raw reply

* Re: [net-next-2.6 PATCH v6 6/7 RFC] TCPCT part 1f: Initiator Cookie => Responder
From: William Allen Simpson @ 2009-11-13 16:51 UTC (permalink / raw)
  To: Linux Kernel Network Developers; +Cc: Eric Dumazet, Joe Perches
In-Reply-To: <4AFCF134.2060208@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 148 bytes --]

Moving the initialization (and destruction) to part 1d makes this about as
short and easy to analyze as possible.  Any more technical observations?

[-- Attachment #2: TCPCT+1f6+.patch --]
[-- Type: text/plain, Size: 9516 bytes --]

diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index e59fa5a..e1553d3 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -370,15 +370,45 @@ static inline int tcp_urg_mode(const struct tcp_sock *tp)
 #define OPTION_TS		(1 << 1)
 #define OPTION_MD5		(1 << 2)
 #define OPTION_WSCALE		(1 << 3)
+#define OPTION_COOKIE_EXTENSION	(1 << 4)
 
 struct tcp_out_options {
 	u8 options;		/* bit field of OPTION_* */
 	u8 ws;			/* window scale, 0 to disable */
 	u8 num_sack_blocks;	/* number of SACK blocks to include */
+	u8 hash_size;		/* bytes in hash_location */
 	u16 mss;		/* 0 to disable */
 	__u32 tsval, tsecr;	/* need to include OPTION_TS */
+	__u8 *hash_location;	/* temporary pointer, overloaded */
 };
 
+/* The sysctl int routines are generic, so check consistency here.
+ */
+static u8 tcp_cookie_size_check(u8 desired)
+{
+	if (desired > 0) {
+		/* previously specified */
+		return desired;
+	}
+	if (sysctl_tcp_cookie_size <= 0) {
+		/* no default specified */
+		return 0;
+	}
+	if (sysctl_tcp_cookie_size < TCP_COOKIE_MIN) {
+		/* value too small, increase to minimum */
+		return TCP_COOKIE_MIN;
+	}
+	if (sysctl_tcp_cookie_size > TCP_COOKIE_MAX) {
+		/* value too large, decrease to maximum */
+		return TCP_COOKIE_MAX;
+	}
+	if (0x1 & sysctl_tcp_cookie_size) {
+		/* 8-bit multiple, illegal, fix it */
+		return (u8)(sysctl_tcp_cookie_size + 0x1);
+	}
+	return (u8)sysctl_tcp_cookie_size;
+}
+
 /* Write previously computed TCP options to the packet.
  *
  * Beware: Something in the Internet is very sensitive to the ordering of
@@ -393,17 +423,34 @@ struct tcp_out_options {
  * (but it may well be that other scenarios fail similarly).
  */
 static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
-			      const struct tcp_out_options *opts,
-			      __u8 **md5_hash) {
-	if (unlikely(OPTION_MD5 & opts->options)) {
-		*ptr++ = htonl((TCPOPT_NOP << 24) |
-			       (TCPOPT_NOP << 16) |
-			       (TCPOPT_MD5SIG << 8) |
-			       TCPOLEN_MD5SIG);
-		*md5_hash = (__u8 *)ptr;
+			      struct tcp_out_options *opts)
+{
+	u8 options = opts->options;	/* mungable copy */
+
+	/* Having both authentication and cookies for security is redundant,
+	 * and there's certainly not enough room.  Instead, the cookie-less
+	 * extension variant is proposed.
+	 *
+	 * Consider the pessimal case with authentication.  The options
+	 * could look like:
+	 *   COOKIE|MD5(20) + MSS(4) + SACK|TS(12) + WSCALE(4) == 40
+	 */
+	if (unlikely(OPTION_MD5 & options)) {
+		if (unlikely(OPTION_COOKIE_EXTENSION & options)) {
+			*ptr++ = htonl((TCPOPT_COOKIE << 24) |
+				       (TCPOLEN_COOKIE_BASE << 16) |
+				       (TCPOPT_MD5SIG << 8) |
+				       TCPOLEN_MD5SIG);
+		} else {
+			*ptr++ = htonl((TCPOPT_NOP << 24) |
+				       (TCPOPT_NOP << 16) |
+				       (TCPOPT_MD5SIG << 8) |
+				       TCPOLEN_MD5SIG);
+		}
+		options &= ~OPTION_COOKIE_EXTENSION;
+		/* overload cookie hash location */
+		opts->hash_location = (__u8 *)ptr;
 		ptr += 4;
-	} else {
-		*md5_hash = NULL;
 	}
 
 	if (unlikely(opts->mss)) {
@@ -412,12 +459,13 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
 			       opts->mss);
 	}
 
-	if (likely(OPTION_TS & opts->options)) {
-		if (unlikely(OPTION_SACK_ADVERTISE & opts->options)) {
+	if (likely(OPTION_TS & options)) {
+		if (unlikely(OPTION_SACK_ADVERTISE & options)) {
 			*ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
 				       (TCPOLEN_SACK_PERM << 16) |
 				       (TCPOPT_TIMESTAMP << 8) |
 				       TCPOLEN_TIMESTAMP);
+			options &= ~OPTION_SACK_ADVERTISE;
 		} else {
 			*ptr++ = htonl((TCPOPT_NOP << 24) |
 				       (TCPOPT_NOP << 16) |
@@ -428,15 +476,52 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
 		*ptr++ = htonl(opts->tsecr);
 	}
 
-	if (unlikely(OPTION_SACK_ADVERTISE & opts->options &&
-		     !(OPTION_TS & opts->options))) {
+	/* Specification requires after timestamp, so do it now.
+	 *
+	 * Consider the pessimal case without authentication.  The options
+	 * could look like:
+	 *   MSS(4) + SACK|TS(12) + COOKIE(20) + WSCALE(4) == 40
+	 */
+	if (unlikely(OPTION_COOKIE_EXTENSION & options)) {
+		__u8 *cookie_copy = opts->hash_location;
+		u8 cookie_size = opts->hash_size;
+
+		if (unlikely(0x1 & cookie_size)) {
+			/* 8-bit multiple, illegal, ignore */
+			cookie_size = 0;
+		} else if (likely(0x2 & cookie_size)) {
+			__u8 *p = (__u8 *)ptr;
+
+			/* 16-bit multiple */
+			*p++ = TCPOPT_COOKIE;
+			*p++ = TCPOLEN_COOKIE_BASE + cookie_size;
+			*p++ = *cookie_copy++;
+			*p++ = *cookie_copy++;
+			ptr++;
+			cookie_size -= 2;
+		} else {
+			/* 32-bit multiple */
+			*ptr++ = htonl(((TCPOPT_NOP << 24) |
+					(TCPOPT_NOP << 16) |
+					(TCPOPT_COOKIE << 8) |
+					TCPOLEN_COOKIE_BASE) +
+				       cookie_size);
+		}
+
+		if (cookie_size > 0) {
+			memcpy(ptr, cookie_copy, cookie_size);
+			ptr += (cookie_size >> 2);
+		}
+	}
+
+	if (unlikely(OPTION_SACK_ADVERTISE & options)) {
 		*ptr++ = htonl((TCPOPT_NOP << 24) |
 			       (TCPOPT_NOP << 16) |
 			       (TCPOPT_SACK_PERM << 8) |
 			       TCPOLEN_SACK_PERM);
 	}
 
-	if (unlikely(OPTION_WSCALE & opts->options)) {
+	if (unlikely(OPTION_WSCALE & options)) {
 		*ptr++ = htonl((TCPOPT_NOP << 24) |
 			       (TCPOPT_WINDOW << 16) |
 			       (TCPOLEN_WINDOW << 8) |
@@ -471,8 +556,12 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb,
 				struct tcp_out_options *opts,
 				struct tcp_md5sig_key **md5) {
 	struct tcp_sock *tp = tcp_sk(sk);
-	unsigned size = 0;
+	struct tcp_cookie_values *cvp = tp->cookie_values;
 	struct dst_entry *dst = __sk_dst_get(sk);
+	unsigned size = 0;
+	u8 cookie_size = (!tp->rx_opt.cookie_out_never && cvp != NULL)
+			 ? tcp_cookie_size_check(cvp->cookie_desired)
+			 : 0;
 
 #ifdef CONFIG_TCP_MD5SIG
 	*md5 = tp->af_specific->md5_lookup(sk, sk);
@@ -517,6 +606,53 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb,
 			size += TCPOLEN_SACKPERM_ALIGNED;
 	}
 
+	/* Note that timestamps are required by the specification.
+	 *
+	 * Odd numbers of bytes are prohibited by the specification, ensuring
+	 * that the cookie is 16-bit aligned, and the resulting cookie pair is
+	 * 32-bit aligned.
+	 */
+	if (*md5 == NULL
+	 && (OPTION_TS & opts->options)
+	 && cookie_size > 0) {
+		int need = TCPOLEN_COOKIE_BASE + cookie_size;
+		int remaining = MAX_TCP_OPTION_SPACE - size;
+
+		if (0x2 & need) {
+			/* 32-bit multiple */
+			need += 2; /* NOPs */
+
+			if (need > remaining) {
+				/* try shrinking cookie to fit */
+				cookie_size -= 2;
+				need -= 4;
+			}
+		}
+		while (need > remaining && TCP_COOKIE_MIN <= cookie_size) {
+			cookie_size -= 4;
+			need -= 4;
+		}
+		if (TCP_COOKIE_MIN <= cookie_size) {
+			opts->options |= OPTION_COOKIE_EXTENSION;
+			opts->hash_location = (__u8 *)&cvp->cookie_pair[0];
+			opts->hash_size = cookie_size;
+
+			/* Remember for future incarnations. */
+			cvp->cookie_desired = cookie_size;
+
+			if (cvp->cookie_desired != cvp->cookie_pair_size) {
+				/* Currently use random bytes as a nonce,
+				 * assuming these are completely unpredictable
+				 * by hostile users of the same system.
+				 */
+				get_random_bytes(&cvp->cookie_pair[0],
+						 cookie_size);
+				cvp->cookie_pair_size = cookie_size;
+			}
+
+			size += need;
+		}
+	}
 	return size;
 }
 
@@ -632,7 +768,6 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 	struct tcp_out_options opts;
 	unsigned tcp_options_size, tcp_header_size;
 	struct tcp_md5sig_key *md5;
-	__u8 *md5_hash_location;
 	struct tcphdr *th;
 	int err;
 
@@ -703,7 +838,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 		}
 	}
 
-	tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location);
+	tcp_options_write((__be32 *)(th + 1), tp, &opts);
 	if (likely((tcb->flags & TCPCB_FLAG_SYN) == 0))
 		TCP_ECN_send(sk, skb, tcp_header_size);
 
@@ -711,7 +846,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 	/* Calculate the MD5 hash, as we have all we need now */
 	if (md5) {
 		sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
-		tp->af_specific->calc_md5_hash(md5_hash_location,
+		tp->af_specific->calc_md5_hash(opts.hash_location,
 					       md5, sk, NULL, skb);
 	}
 #endif
@@ -2235,14 +2370,13 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
 				struct request_sock *req,
 				struct request_values *rvp)
 {
+	struct tcp_out_options opts;
 	struct inet_request_sock *ireq = inet_rsk(req);
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcphdr *th;
-	int tcp_header_size;
-	struct tcp_out_options opts;
 	struct sk_buff *skb;
 	struct tcp_md5sig_key *md5;
-	__u8 *md5_hash_location;
+	int tcp_header_size;
 	int mss;
 
 	skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC);
@@ -2303,14 +2437,14 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
 
 	/* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
 	th->window = htons(min(req->rcv_wnd, 65535U));
-	tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location);
+	tcp_options_write((__be32 *)(th + 1), tp, &opts);
 	th->doff = (tcp_header_size >> 2);
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
 
 #ifdef CONFIG_TCP_MD5SIG
 	/* Okay, we have all we need - do the md5 hash if needed */
 	if (md5) {
-		tcp_rsk(req)->af_specific->calc_md5_hash(md5_hash_location,
+		tcp_rsk(req)->af_specific->calc_md5_hash(opts.hash_location,
 					       md5, NULL, req, skb);
 	}
 #endif
-- 
1.6.3.3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox