All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5 V2] Firewire networking assorted fixes
@ 2010-11-29  2:09 Maxim Levitsky
  2010-11-29  2:09 ` [PATCH 1/5] firewire: ohci: restore GUID on resume Maxim Levitsky
                   ` (7 more replies)
  0 siblings, 8 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-11-29  2:09 UTC (permalink / raw)
  To: linux1394-devel; +Cc: Stefan Richter, netdev

Hi,

This is updated version of the patches.
I updated the changelogs, addressed comments on patch #2

Best regards,
	Maxim Levitsky


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 1/5] firewire: ohci: restore GUID on resume.
  2010-11-29  2:09 [PATCH 0/5 V2] Firewire networking assorted fixes Maxim Levitsky
@ 2010-11-29  2:09 ` Maxim Levitsky
  2010-11-29  2:09 ` [PATCH 2/5] firewire: ohci: restart ISO DMA contexts on resume from low power mode Maxim Levitsky
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-11-29  2:09 UTC (permalink / raw)
  To: linux1394-devel; +Cc: Stefan Richter, netdev, Maxim Levitsky

Some lousy BIOSes, e.g. my Aspire 5720 BIOS forget to restore
the GUID register on resume from ram.

Fix that by setting it to the last value that
was read from it.

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
---
 drivers/firewire/ohci.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 6dd56cd..0fbadb7 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -3240,6 +3240,13 @@ static int pci_resume(struct pci_dev *dev)
 		return err;
 	}
 
+	/* Some systems don't setup GUID register on resume from ram  */
+	if (!reg_read(ohci, OHCI1394_GUIDLo) &&
+					!reg_read(ohci, OHCI1394_GUIDHi)) {
+		reg_write(ohci, OHCI1394_GUIDLo, (u32)ohci->card.guid);
+		reg_write(ohci, OHCI1394_GUIDHi, (u32)(ohci->card.guid >> 32));
+	}
+
 	return ohci_enable(&ohci->card, NULL, 0);
 }
 #endif
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 2/5] firewire: ohci: restart ISO DMA contexts on resume from low power mode
  2010-11-29  2:09 [PATCH 0/5 V2] Firewire networking assorted fixes Maxim Levitsky
  2010-11-29  2:09 ` [PATCH 1/5] firewire: ohci: restore GUID on resume Maxim Levitsky
@ 2010-11-29  2:09 ` Maxim Levitsky
  2010-11-29  2:09 ` [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries Maxim Levitsky
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-11-29  2:09 UTC (permalink / raw)
  To: linux1394-devel; +Cc: Stefan Richter, netdev, Maxim Levitsky

Restore ISO channels DMA so that ISO channels could continue
to work after resume from ram/disk.

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
---
 drivers/firewire/ohci.c |   54 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 0fbadb7..f5889d5 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -40,6 +40,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/time.h>
+#include <linux/bitops.h>
 
 #include <asm/byteorder.h>
 #include <asm/page.h>
@@ -152,6 +153,7 @@ struct context {
 	descriptor_callback_t callback;
 
 	struct tasklet_struct tasklet;
+	bool active;
 };
 
 #define IT_HEADER_SY(v)          ((v) <<  0)
@@ -167,6 +169,9 @@ struct iso_context {
 	int excess_bytes;
 	void *header;
 	size_t header_length;
+
+	u8 sync;
+	u8 tags;
 };
 
 #define CONFIG_ROM_SIZE 1024
@@ -183,7 +188,8 @@ struct fw_ohci {
 	u32 bus_time;
 	bool is_root;
 	bool csr_state_setclear_abdicate;
-
+	int n_ir;
+	int n_it;
 	/*
 	 * Spinlock for accessing fw_ohci data.  Never call out of
 	 * this driver with this lock held.
@@ -1156,6 +1162,7 @@ static struct descriptor *context_get_descriptors(struct context *ctx,
 static void context_run(struct context *ctx, u32 extra)
 {
 	struct fw_ohci *ohci = ctx->ohci;
+	ctx->active = true;
 
 	reg_write(ohci, COMMAND_PTR(ctx->regs),
 		  le32_to_cpu(ctx->last->branch_address));
@@ -1187,6 +1194,7 @@ static void context_stop(struct context *ctx)
 	u32 reg;
 	int i;
 
+	ctx->active = false;
 	reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
 	flush_writes(ctx->ohci);
 
@@ -2614,6 +2622,10 @@ static int ohci_start_iso(struct fw_iso_context *base,
 		reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index);
 		reg_write(ohci, CONTEXT_MATCH(ctx->context.regs), match);
 		context_run(&ctx->context, control);
+
+		ctx->sync = sync;
+		ctx->tags = tags;
+
 		break;
 	}
 
@@ -2711,6 +2723,26 @@ static int ohci_set_iso_channels(struct fw_iso_context *base, u64 *channels)
 	return ret;
 }
 
+#ifdef CONFIG_PM
+static void ohci_resume_iso_dma(struct fw_ohci *ohci)
+{
+	int i;
+	struct iso_context *ctx;
+
+	for (i = 0 ; i < ohci->n_ir ; i++) {
+		ctx = &ohci->ir_context_list[i];
+		if (ctx->context.active)
+			ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags);
+	}
+
+	for (i = 0 ; i < ohci->n_it ; i++) {
+		ctx = &ohci->it_context_list[i];
+		if (ctx->context.active)
+			ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags);
+	}
+}
+#endif
+
 static int queue_iso_transmit(struct iso_context *ctx,
 			      struct fw_iso_packet *packet,
 			      struct fw_iso_buffer *buffer,
@@ -3020,7 +3052,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
 	struct fw_ohci *ohci;
 	u32 bus_options, max_receive, link_speed, version;
 	u64 guid;
-	int i, err, n_ir, n_it;
+	int i, err;
 	size_t size;
 
 	ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
@@ -3092,15 +3124,15 @@ static int __devinit pci_probe(struct pci_dev *dev,
 	ohci->ir_context_channels = ~0ULL;
 	ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet);
 	reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0);
-	n_ir = hweight32(ohci->ir_context_mask);
-	size = sizeof(struct iso_context) * n_ir;
+	ohci->n_ir = hweight32(ohci->ir_context_mask);
+	size = sizeof(struct iso_context) * ohci->n_ir;
 	ohci->ir_context_list = kzalloc(size, GFP_KERNEL);
 
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
 	ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
-	n_it = hweight32(ohci->it_context_mask);
-	size = sizeof(struct iso_context) * n_it;
+	ohci->n_it = hweight32(ohci->it_context_mask);
+	size = sizeof(struct iso_context) * ohci->n_it;
 	ohci->it_context_list = kzalloc(size, GFP_KERNEL);
 
 	if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) {
@@ -3132,7 +3164,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
 	fw_notify("Added fw-ohci device %s, OHCI v%x.%x, "
 		  "%d IR + %d IT contexts, quirks 0x%x\n",
 		  dev_name(&dev->dev), version >> 16, version & 0xff,
-		  n_ir, n_it, ohci->quirks);
+		  ohci->n_ir, ohci->n_it, ohci->quirks);
 
 	return 0;
 
@@ -3247,7 +3279,13 @@ static int pci_resume(struct pci_dev *dev)
 		reg_write(ohci, OHCI1394_GUIDHi, (u32)(ohci->card.guid >> 32));
 	}
 
-	return ohci_enable(&ohci->card, NULL, 0);
+	err = ohci_enable(&ohci->card, NULL, 0);
+
+	if (err)
+		return err;
+
+	ohci_resume_iso_dma(ohci);
+	return 0;
 }
 #endif
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
  2010-11-29  2:09 [PATCH 0/5 V2] Firewire networking assorted fixes Maxim Levitsky
  2010-11-29  2:09 ` [PATCH 1/5] firewire: ohci: restore GUID on resume Maxim Levitsky
  2010-11-29  2:09 ` [PATCH 2/5] firewire: ohci: restart ISO DMA contexts on resume from low power mode Maxim Levitsky
@ 2010-11-29  2:09 ` Maxim Levitsky
  2010-12-04 23:15   ` Maxim Levitsky
  2011-01-07 12:47   ` [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries Maxim Levitsky
  2010-11-29  2:09 ` [PATCH 4/5] firewire: net: invalidate ARP entries of removed nodes Maxim Levitsky
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-11-29  2:09 UTC (permalink / raw)
  To: linux1394-devel
  Cc: Stefan Richter, netdev, Maxim Levitsky, David S. Miller,
	Alexey Kuznetsov, James Morris, Patrick McHardy

IPv4 over firewire needs to be able to remove ARP entries
from the ARP cache that belong to nodes that are removed, because
IPv4 over firewire uses ARP packets for private information
about nodes.

This information becomes invalid as soon as node drops
off the bus and when it reconnects, its only possible
to start takling to is after it responded to an ARP packet.
But ARP cache prevents such packets from being sent.

CC: netdev@vger.kernel.org
CC: "David S. Miller" <davem@davemloft.net>
CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
CC: James Morris <jmorris@namei.org>
CC: Patrick McHardy <kaber@trash.net>


Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
---
 include/net/arp.h |    1 +
 net/ipv4/arp.c    |   29 ++++++++++++++++++-----------
 2 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/include/net/arp.h b/include/net/arp.h
index f4cf6ce..91f0568 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
 				  const unsigned char *src_hw,
 				  const unsigned char *target_hw);
 extern void arp_xmit(struct sk_buff *skb);
+int arp_invalidate(struct net_device *dev, __be32 ip);
 
 #endif	/* _ARP_H */
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index d8e540c..35b1272 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1142,6 +1142,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
 	return err;
 }
 
+int arp_invalidate(struct net_device *dev, __be32 ip)
+{
+	int err = -ENXIO;
+	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
+
+	if (neigh) {
+		if (neigh->nud_state & ~NUD_NOARP)
+			err = neigh_update(neigh, NULL, NUD_FAILED,
+					   NEIGH_UPDATE_F_OVERRIDE|
+					   NEIGH_UPDATE_F_ADMIN);
+		neigh_release(neigh);
+	}
+
+	return err;
+}
+EXPORT_SYMBOL(arp_invalidate);
+
 static int arp_req_delete_public(struct net *net, struct arpreq *r,
 		struct net_device *dev)
 {
@@ -1162,7 +1179,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
 {
 	int err;
 	__be32 ip;
-	struct neighbour *neigh;
 
 	if (r->arp_flags & ATF_PUBL)
 		return arp_req_delete_public(net, r, dev);
@@ -1180,16 +1196,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
 		if (!dev)
 			return -EINVAL;
 	}
-	err = -ENXIO;
-	neigh = neigh_lookup(&arp_tbl, &ip, dev);
-	if (neigh) {
-		if (neigh->nud_state & ~NUD_NOARP)
-			err = neigh_update(neigh, NULL, NUD_FAILED,
-					   NEIGH_UPDATE_F_OVERRIDE|
-					   NEIGH_UPDATE_F_ADMIN);
-		neigh_release(neigh);
-	}
-	return err;
+	return arp_invalidate(dev, ip);
 }
 
 /*
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 4/5] firewire: net: invalidate ARP entries of removed nodes.
  2010-11-29  2:09 [PATCH 0/5 V2] Firewire networking assorted fixes Maxim Levitsky
                   ` (2 preceding siblings ...)
  2010-11-29  2:09 ` [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries Maxim Levitsky
@ 2010-11-29  2:09 ` Maxim Levitsky
  2010-11-29  2:09 ` [PATCH 5/5] firewire: net: ratelimit error messages Maxim Levitsky
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-11-29  2:09 UTC (permalink / raw)
  To: linux1394-devel; +Cc: Stefan Richter, netdev, Maxim Levitsky

This makes it possible to resume communication with
a node that dropped off the bus for a brief period.
Otherwice communication will only be possible after
ARP cache entry timeouts

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
---
 drivers/firewire/net.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 1a467a9..d422519 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -189,6 +189,7 @@ struct fwnet_peer {
 	struct fwnet_device *dev;
 	u64 guid;
 	u64 fifo;
+	__be32 ip;
 
 	/* guarded by dev->lock */
 	struct list_head pd_list; /* received partial datagrams */
@@ -568,6 +569,8 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
 				peer->speed = sspd;
 			if (peer->max_payload > max_payload)
 				peer->max_payload = max_payload;
+
+			peer->ip = arp1394->sip;
 		}
 		spin_unlock_irqrestore(&dev->lock, flags);
 
@@ -1443,6 +1446,7 @@ static int fwnet_add_peer(struct fwnet_device *dev,
 	peer->dev = dev;
 	peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4];
 	peer->fifo = FWNET_NO_FIFO_ADDR;
+	peer->ip = 0;
 	INIT_LIST_HEAD(&peer->pd_list);
 	peer->pdg_size = 0;
 	peer->datagram_label = 0;
@@ -1558,6 +1562,9 @@ static int fwnet_remove(struct device *_dev)
 
 	mutex_lock(&fwnet_device_mutex);
 
+	if (dev->netdev && peer->ip)
+		arp_invalidate(dev->netdev, peer->ip);
+
 	fwnet_remove_peer(peer);
 
 	if (list_empty(&dev->peer_list)) {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 5/5] firewire: net: ratelimit error messages
  2010-11-29  2:09 [PATCH 0/5 V2] Firewire networking assorted fixes Maxim Levitsky
                   ` (3 preceding siblings ...)
  2010-11-29  2:09 ` [PATCH 4/5] firewire: net: invalidate ARP entries of removed nodes Maxim Levitsky
@ 2010-11-29  2:09 ` Maxim Levitsky
  2010-11-29 15:02 ` [PATCH 0/5 V2] Firewire networking assorted fixes Stefan Richter
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-11-29  2:09 UTC (permalink / raw)
  To: linux1394-devel; +Cc: Stefan Richter, netdev, Maxim Levitsky

Unfortunelly its easy to trigger such error messages
by removing the cable while sending streams of data
over the link.

Such errors are normal, and therefore this patch
stops firewire-net from flooding the kernel log
with these errors,
by combining series of same errors together.


Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
---
 drivers/firewire/net.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index d422519..ac563d6 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -999,15 +999,23 @@ static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask)
 static void fwnet_write_complete(struct fw_card *card, int rcode,
 				 void *payload, size_t length, void *data)
 {
-	struct fwnet_packet_task *ptask;
-
-	ptask = data;
+	struct fwnet_packet_task *ptask = data;
+	static unsigned long j;
+	static int last_rcode, errors_skipped;
 
 	if (rcode == RCODE_COMPLETE) {
 		fwnet_transmit_packet_done(ptask);
 	} else {
-		fw_error("fwnet_write_complete: failed: %x\n", rcode);
 		fwnet_transmit_packet_failed(ptask);
+
+		if (printk_timed_ratelimit(&j,  1000) || rcode != last_rcode) {
+			fw_error("fwnet_write_complete: "
+				"failed: %x (skipped %d)\n", rcode, errors_skipped);
+
+			errors_skipped = 0;
+			last_rcode = rcode;
+		} else
+			errors_skipped++;
 	}
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH 0/5 V2] Firewire networking assorted fixes
  2010-11-29  2:09 [PATCH 0/5 V2] Firewire networking assorted fixes Maxim Levitsky
                   ` (4 preceding siblings ...)
  2010-11-29  2:09 ` [PATCH 5/5] firewire: net: ratelimit error messages Maxim Levitsky
@ 2010-11-29 15:02 ` Stefan Richter
  2010-12-04 23:14 ` Maxim Levitsky
  2010-12-08  3:32 ` Maxim Levitsky
  7 siblings, 0 replies; 32+ messages in thread
From: Stefan Richter @ 2010-11-29 15:02 UTC (permalink / raw)
  To: Maxim Levitsky; +Cc: linux1394-devel, netdev

On Nov 29 Maxim Levitsky wrote:
> This is updated version of the patches.
> I updated the changelogs, addressed comments on patch #2

I haven't applied and tested these patches yet but they look good to me.

Regarding 3/5 (and 4/5 which depends on it), I need of course an ack
from an IPv4 maintainer, or a comment on how to do it differently if
desired.

Patch 5/5 looks good for the next one or two kernel releases. If
progress with firewire-net/-ohci stabilization keeps going like it does
at the moment, we can later remove this logging entirely.  (There is
still the cancel_packet issue to tackle in fw-ohci/-core.)
-- 
Stefan Richter
-=====-==-=- =-== ===-=
http://arcgraph.de/sr/

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 0/5 V2] Firewire networking assorted fixes
  2010-11-29  2:09 [PATCH 0/5 V2] Firewire networking assorted fixes Maxim Levitsky
                   ` (5 preceding siblings ...)
  2010-11-29 15:02 ` [PATCH 0/5 V2] Firewire networking assorted fixes Stefan Richter
@ 2010-12-04 23:14 ` Maxim Levitsky
  2010-12-08  3:32 ` Maxim Levitsky
  7 siblings, 0 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-12-04 23:14 UTC (permalink / raw)
  To: linux1394-devel; +Cc: Stefan Richter, netdev

On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> Hi,
> 
> This is updated version of the patches.
> I updated the changelogs, addressed comments on patch #2
> 
> Best regards,
> 	Maxim Levitsky
> 

Any update?

Best regards,
	Maxim Levitsky


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
  2010-11-29  2:09 ` [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries Maxim Levitsky
@ 2010-12-04 23:15   ` Maxim Levitsky
  2010-12-05  8:19     ` Eric Dumazet
  2011-01-07 12:47   ` [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries Maxim Levitsky
  1 sibling, 1 reply; 32+ messages in thread
From: Maxim Levitsky @ 2010-12-04 23:15 UTC (permalink / raw)
  To: linux1394-devel
  Cc: Stefan Richter, netdev, David S. Miller, Alexey Kuznetsov,
	James Morris, Patrick McHardy

On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> IPv4 over firewire needs to be able to remove ARP entries
> from the ARP cache that belong to nodes that are removed, because
> IPv4 over firewire uses ARP packets for private information
> about nodes.
> 
> This information becomes invalid as soon as node drops
> off the bus and when it reconnects, its only possible
> to start takling to is after it responded to an ARP packet.
> But ARP cache prevents such packets from being sent.
> 
> CC: netdev@vger.kernel.org
> CC: "David S. Miller" <davem@davemloft.net>
> CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> CC: James Morris <jmorris@namei.org>
> CC: Patrick McHardy <kaber@trash.net>

Anybody?

Best regards,
	Maxim Levitsky
> 
> 
> Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> ---
>  include/net/arp.h |    1 +
>  net/ipv4/arp.c    |   29 ++++++++++++++++++-----------
>  2 files changed, 19 insertions(+), 11 deletions(-)
> 
> diff --git a/include/net/arp.h b/include/net/arp.h
> index f4cf6ce..91f0568 100644
> --- a/include/net/arp.h
> +++ b/include/net/arp.h
> @@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
>  				  const unsigned char *src_hw,
>  				  const unsigned char *target_hw);
>  extern void arp_xmit(struct sk_buff *skb);
> +int arp_invalidate(struct net_device *dev, __be32 ip);
>  
>  #endif	/* _ARP_H */
> diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> index d8e540c..35b1272 100644
> --- a/net/ipv4/arp.c
> +++ b/net/ipv4/arp.c
> @@ -1142,6 +1142,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
>  	return err;
>  }
>  
> +int arp_invalidate(struct net_device *dev, __be32 ip)
> +{
> +	int err = -ENXIO;
> +	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
> +
> +	if (neigh) {
> +		if (neigh->nud_state & ~NUD_NOARP)
> +			err = neigh_update(neigh, NULL, NUD_FAILED,
> +					   NEIGH_UPDATE_F_OVERRIDE|
> +					   NEIGH_UPDATE_F_ADMIN);
> +		neigh_release(neigh);
> +	}
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(arp_invalidate);
> +
>  static int arp_req_delete_public(struct net *net, struct arpreq *r,
>  		struct net_device *dev)
>  {
> @@ -1162,7 +1179,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
>  {
>  	int err;
>  	__be32 ip;
> -	struct neighbour *neigh;
>  
>  	if (r->arp_flags & ATF_PUBL)
>  		return arp_req_delete_public(net, r, dev);
> @@ -1180,16 +1196,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
>  		if (!dev)
>  			return -EINVAL;
>  	}
> -	err = -ENXIO;
> -	neigh = neigh_lookup(&arp_tbl, &ip, dev);
> -	if (neigh) {
> -		if (neigh->nud_state & ~NUD_NOARP)
> -			err = neigh_update(neigh, NULL, NUD_FAILED,
> -					   NEIGH_UPDATE_F_OVERRIDE|
> -					   NEIGH_UPDATE_F_ADMIN);
> -		neigh_release(neigh);
> -	}
> -	return err;
> +	return arp_invalidate(dev, ip);
>  }
>  
>  /*



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
  2010-12-04 23:15   ` Maxim Levitsky
@ 2010-12-05  8:19     ` Eric Dumazet
  2010-12-05 11:23       ` [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() Eric Dumazet
  0 siblings, 1 reply; 32+ messages in thread
From: Eric Dumazet @ 2010-12-05  8:19 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: linux1394-devel, Stefan Richter, netdev, David S. Miller,
	Alexey Kuznetsov, James Morris, Patrick McHardy

Le dimanche 05 décembre 2010 à 01:15 +0200, Maxim Levitsky a écrit :
> On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> > IPv4 over firewire needs to be able to remove ARP entries
> > from the ARP cache that belong to nodes that are removed, because
> > IPv4 over firewire uses ARP packets for private information
> > about nodes.
> > 
> > This information becomes invalid as soon as node drops
> > off the bus and when it reconnects, its only possible
> > to start takling to is after it responded to an ARP packet.
> > But ARP cache prevents such packets from being sent.
> > 
> > CC: netdev@vger.kernel.org
> > CC: "David S. Miller" <davem@davemloft.net>
> > CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> > CC: James Morris <jmorris@namei.org>
> > CC: Patrick McHardy <kaber@trash.net>
> 
> Anybody?
> 
> Best regards,
> 	Maxim Levitsky
> > 
> > 
> > Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> > ---
> >  include/net/arp.h |    1 +
> >  net/ipv4/arp.c    |   29 ++++++++++++++++++-----------
> >  2 files changed, 19 insertions(+), 11 deletions(-)
> > 
> > diff --git a/include/net/arp.h b/include/net/arp.h
> > index f4cf6ce..91f0568 100644
> > --- a/include/net/arp.h
> > +++ b/include/net/arp.h
> > @@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
> >  				  const unsigned char *src_hw,
> >  				  const unsigned char *target_hw);
> >  extern void arp_xmit(struct sk_buff *skb);
> > +int arp_invalidate(struct net_device *dev, __be32 ip);
> >  
> >  #endif	/* _ARP_H */
> > diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> > index d8e540c..35b1272 100644
> > --- a/net/ipv4/arp.c
> > +++ b/net/ipv4/arp.c
> > @@ -1142,6 +1142,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
> >  	return err;
> >  }
> >  
> > +int arp_invalidate(struct net_device *dev, __be32 ip)
> > +{
> > +	int err = -ENXIO;
> > +	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > +
> > +	if (neigh) {
> > +		if (neigh->nud_state & ~NUD_NOARP)
> > +			err = neigh_update(neigh, NULL, NUD_FAILED,
> > +					   NEIGH_UPDATE_F_OVERRIDE|
> > +					   NEIGH_UPDATE_F_ADMIN);
> > +		neigh_release(neigh);
> > +	}
> > +
> > +	return err;
> > +}
> > +EXPORT_SYMBOL(arp_invalidate);
> > +
> >  static int arp_req_delete_public(struct net *net, struct arpreq *r,
> >  		struct net_device *dev)
> >  {
> > @@ -1162,7 +1179,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> >  {
> >  	int err;
> >  	__be32 ip;
> > -	struct neighbour *neigh;
> >  
> >  	if (r->arp_flags & ATF_PUBL)
> >  		return arp_req_delete_public(net, r, dev);
> > @@ -1180,16 +1196,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> >  		if (!dev)
> >  			return -EINVAL;
> >  	}
> > -	err = -ENXIO;
> > -	neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > -	if (neigh) {
> > -		if (neigh->nud_state & ~NUD_NOARP)
> > -			err = neigh_update(neigh, NULL, NUD_FAILED,
> > -					   NEIGH_UPDATE_F_OVERRIDE|
> > -					   NEIGH_UPDATE_F_ADMIN);
> > -		neigh_release(neigh);
> > -	}
> > -	return err;
> > +	return arp_invalidate(dev, ip);
> >  }
> >  
> >  /*
> 

Hmm..

If somebody can explain why RTNL is held in arp_ioctl() (and therefore
in arp_req_delete()), we might first remove RTNL use in arp_ioctl() so
that your patch can be applied.

Right now it is not good, because RTNL wont be necessarly held when you
are going to call arp_invalidate() ?






^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
  2010-12-05  8:19     ` Eric Dumazet
@ 2010-12-05 11:23       ` Eric Dumazet
  2010-12-05 12:03         ` [PATCH net-2.6] llc: fix a device refcount imbalance Eric Dumazet
  2010-12-08 18:05         ` [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() David Miller
  0 siblings, 2 replies; 32+ messages in thread
From: Eric Dumazet @ 2010-12-05 11:23 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: linux1394-devel, Stefan Richter, netdev, David S. Miller,
	Alexey Kuznetsov, James Morris, Patrick McHardy

Le dimanche 05 décembre 2010 à 09:19 +0100, Eric Dumazet a écrit :

> Hmm..
> 
> If somebody can explain why RTNL is held in arp_ioctl() (and therefore
> in arp_req_delete()), we might first remove RTNL use in arp_ioctl() so
> that your patch can be applied.
> 
> Right now it is not good, because RTNL wont be necessarly held when you
> are going to call arp_invalidate() ?

While doing this analysis, I found a refcount bug in llc, I'll send a
patch for net-2.6

Meanwhile, here is the patch for net-next-2.6

Your patch then can be applied after mine.

Thanks

[PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()

dev_getbyhwaddr() was called under RTNL.

Rename it to dev_getbyhwaddr_rcu() and change all its caller to now use
RCU locking instead of RTNL.

Change arp_ioctl() to use RCU instead of RTNL locking.

Note: this fix a dev refcount bug in llc

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/linux/netdevice.h      |    3 ++-
 net/core/dev.c                 |   17 +++++++----------
 net/ieee802154/af_ieee802154.c |    6 +++---
 net/ipv4/arp.c                 |   17 +++++++++--------
 net/llc/af_llc.c               |   11 ++++++-----
 5 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index a9ac5dc..d31bc3c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1360,7 +1360,8 @@ static inline struct net_device *first_net_device(struct net *net)
 
 extern int 			netdev_boot_setup_check(struct net_device *dev);
 extern unsigned long		netdev_boot_base(const char *prefix, int unit);
-extern struct net_device    *dev_getbyhwaddr(struct net *net, unsigned short type, char *hwaddr);
+extern struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
+					      const char *hwaddr);
 extern struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);
 extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type);
 extern void		dev_add_pack(struct packet_type *pt);
diff --git a/net/core/dev.c b/net/core/dev.c
index cd24374..8630142 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -743,34 +743,31 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex)
 EXPORT_SYMBOL(dev_get_by_index);
 
 /**
- *	dev_getbyhwaddr - find a device by its hardware address
+ *	dev_getbyhwaddr_rcu - find a device by its hardware address
  *	@net: the applicable net namespace
  *	@type: media type of device
  *	@ha: hardware address
  *
  *	Search for an interface by MAC address. Returns NULL if the device
- *	is not found or a pointer to the device. The caller must hold the
- *	rtnl semaphore. The returned device has not had its ref count increased
+ *	is not found or a pointer to the device. The caller must hold RCU
+ *	The returned device has not had its ref count increased
  *	and the caller must therefore be careful about locking
  *
- *	BUGS:
- *	If the API was consistent this would be __dev_get_by_hwaddr
  */
 
-struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *ha)
+struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
+				       const char *ha)
 {
 	struct net_device *dev;
 
-	ASSERT_RTNL();
-
-	for_each_netdev(net, dev)
+	for_each_netdev_rcu(net, dev)
 		if (dev->type == type &&
 		    !memcmp(dev->dev_addr, ha, dev->addr_len))
 			return dev;
 
 	return NULL;
 }
-EXPORT_SYMBOL(dev_getbyhwaddr);
+EXPORT_SYMBOL(dev_getbyhwaddr_rcu);
 
 struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type)
 {
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
index 93c91b6..6df6ecf 100644
--- a/net/ieee802154/af_ieee802154.c
+++ b/net/ieee802154/af_ieee802154.c
@@ -52,11 +52,11 @@ struct net_device *ieee802154_get_dev(struct net *net,
 
 	switch (addr->addr_type) {
 	case IEEE802154_ADDR_LONG:
-		rtnl_lock();
-		dev = dev_getbyhwaddr(net, ARPHRD_IEEE802154, addr->hwaddr);
+		rcu_read_lock();
+		dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, addr->hwaddr);
 		if (dev)
 			dev_hold(dev);
-		rtnl_unlock();
+		rcu_read_unlock();
 		break;
 	case IEEE802154_ADDR_SHORT:
 		if (addr->pan_id == 0xffff ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 7833f17..ec0966f 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1017,13 +1017,14 @@ static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on)
 		IPV4_DEVCONF_ALL(net, PROXY_ARP) = on;
 		return 0;
 	}
-	if (__in_dev_get_rtnl(dev)) {
-		IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on);
+	if (__in_dev_get_rcu(dev)) {
+		IN_DEV_CONF_SET(__in_dev_get_rcu(dev), PROXY_ARP, on);
 		return 0;
 	}
 	return -ENXIO;
 }
 
+/* must be called with rcu_read_lock() */
 static int arp_req_set_public(struct net *net, struct arpreq *r,
 		struct net_device *dev)
 {
@@ -1033,7 +1034,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
 	if (mask && mask != htonl(0xFFFFFFFF))
 		return -EINVAL;
 	if (!dev && (r->arp_flags & ATF_COM)) {
-		dev = dev_getbyhwaddr(net, r->arp_ha.sa_family,
+		dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family,
 				      r->arp_ha.sa_data);
 		if (!dev)
 			return -ENODEV;
@@ -1225,10 +1226,10 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 	if (!(r.arp_flags & ATF_NETMASK))
 		((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr =
 							   htonl(0xFFFFFFFFUL);
-	rtnl_lock();
+	rcu_read_lock();
 	if (r.arp_dev[0]) {
 		err = -ENODEV;
-		dev = __dev_get_by_name(net, r.arp_dev);
+		dev = dev_get_by_name_rcu(net, r.arp_dev);
 		if (dev == NULL)
 			goto out;
 
@@ -1252,12 +1253,12 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 		break;
 	case SIOCGARP:
 		err = arp_req_get(&r, dev);
-		if (!err && copy_to_user(arg, &r, sizeof(r)))
-			err = -EFAULT;
 		break;
 	}
 out:
-	rtnl_unlock();
+	rcu_read_unlock();
+	if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r)))
+		err = -EFAULT;
 	return err;
 }
 
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 5826129..dfd3a64 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -316,9 +316,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
 	if (unlikely(addr->sllc_family != AF_LLC))
 		goto out;
 	rc = -ENODEV;
-	rtnl_lock();
+	rcu_read_lock();
 	if (sk->sk_bound_dev_if) {
-		llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+		llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
 		if (llc->dev) {
 			if (!addr->sllc_arphrd)
 				addr->sllc_arphrd = llc->dev->type;
@@ -329,14 +329,15 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
 			    !llc_mac_match(addr->sllc_mac,
 					   llc->dev->dev_addr)) {
 				rc = -EINVAL;
-				dev_put(llc->dev);
 				llc->dev = NULL;
 			}
 		}
 	} else
-		llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd,
+		llc->dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd,
 					   addr->sllc_mac);
-	rtnl_unlock();
+	if (llc->dev)
+		dev_hold(llc->dev);
+	rcu_read_unlock();
 	if (!llc->dev)
 		goto out;
 	if (!addr->sllc_sap) {



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH net-2.6] llc: fix a device refcount imbalance
  2010-12-05 11:23       ` [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() Eric Dumazet
@ 2010-12-05 12:03         ` Eric Dumazet
  2010-12-08 17:59           ` David Miller
  2010-12-08 18:05         ` [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() David Miller
  1 sibling, 1 reply; 32+ messages in thread
From: Eric Dumazet @ 2010-12-05 12:03 UTC (permalink / raw)
  To: Maxim Levitsky, David Miller
  Cc: linux1394-devel, Stefan Richter, netdev, Alexey Kuznetsov,
	James Morris, Patrick McHardy, Octavian Purdila, stable

Le dimanche 05 décembre 2010 à 12:23 +0100, Eric Dumazet a écrit :
> Le dimanche 05 décembre 2010 à 09:19 +0100, Eric Dumazet a écrit :
> 
> > Hmm..
> > 
> > If somebody can explain why RTNL is held in arp_ioctl() (and therefore
> > in arp_req_delete()), we might first remove RTNL use in arp_ioctl() so
> > that your patch can be applied.
> > 
> > Right now it is not good, because RTNL wont be necessarly held when you
> > are going to call arp_invalidate() ?
> 
> While doing this analysis, I found a refcount bug in llc, I'll send a
> patch for net-2.6

Oh well, of course I must first fix the bug in net-2.6, and wait David
pull the fix in net-next-2.6 before sending this rcu conversion.

Note: this patch should be sent to stable teams (2.6.34 and up)

[PATCH net-2.6] llc: fix a device refcount imbalance

commit abf9d537fea225 (llc: add support for SO_BINDTODEVICE) added one
refcount imbalance in llc_ui_bind(), because dev_getbyhwaddr() doesnt
take a reference on device, while dev_get_by_index() does.

Fix this using RCU locking. And since an RCU conversion will be done for
2.6.38 for dev_getbyhwaddr(), put the rcu_read_lock/unlock exactly at
their final place.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: stable@kernel.org
Cc: Octavian Purdila <opurdila@ixiacom.com>
---
 net/llc/af_llc.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 5826129..e35dbe5 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -317,8 +317,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
 		goto out;
 	rc = -ENODEV;
 	rtnl_lock();
+	rcu_read_lock();
 	if (sk->sk_bound_dev_if) {
-		llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+		llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
 		if (llc->dev) {
 			if (!addr->sllc_arphrd)
 				addr->sllc_arphrd = llc->dev->type;
@@ -329,13 +330,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
 			    !llc_mac_match(addr->sllc_mac,
 					   llc->dev->dev_addr)) {
 				rc = -EINVAL;
-				dev_put(llc->dev);
 				llc->dev = NULL;
 			}
 		}
 	} else
 		llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd,
 					   addr->sllc_mac);
+	rcu_read_unlock();
 	rtnl_unlock();
 	if (!llc->dev)
 		goto out;



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH 0/5 V2] Firewire networking assorted fixes
  2010-11-29  2:09 [PATCH 0/5 V2] Firewire networking assorted fixes Maxim Levitsky
                   ` (6 preceding siblings ...)
  2010-12-04 23:14 ` Maxim Levitsky
@ 2010-12-08  3:32 ` Maxim Levitsky
  2010-12-09  1:42   ` Maxim Levitsky
       [not found]   ` <20101208040559.20639.qmail@stuge.se>
  7 siblings, 2 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-12-08  3:32 UTC (permalink / raw)
  To: linux1394-devel; +Cc: Stefan Richter, netdev

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

On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> Hi,
> 
> This is updated version of the patches.
> I updated the changelogs, addressed comments on patch #2
> 
> Best regards,
> 	Maxim Levitsky
> 

Today I have achieved the ultimate goal,
full support of firewire networking via NetworkManager.

Currently it is patched with few hacks but much less that I expected.

I also had to patch dhclient as it unfortunately sends raw packets
together with hardware header (ethernet of course...)

I will soon clean up these hacks to turn them into patches and send to
developers.

The kernel side needs only the attached patch.
It adds the link state detection to firewire-net

Just for fun, this is screenshot that proves that NM works:
http://img210.imageshack.us/img210/6019/screenshotdjk.png

Of course, I still need to clean up the patches to NM and dhclient, so
more correctly I am not fully done yet.

Best regards,
	Maxim Levitsky

[-- Attachment #2: 0001-firewire-net-add-carrier-detection.patch --]
[-- Type: text/x-patch, Size: 2575 bytes --]

>From d42274653bc06583871ec3230f8308236aff92c2 Mon Sep 17 00:00:00 2001
From: Maxim Levitsky <maximlevitsky@gmail.com>
Date: Wed, 8 Dec 2010 04:22:57 +0200
Subject: [PATCH] firewire: net: add carrier detection

To make userland, eg NM work with firewire
we need to be able if cable is plugged or not.

Simple and correct way of doing that is just couning number
of peers.

No peers - no link and vise versa.

Best regards,
	Maxim Levitsky
---
 drivers/firewire/net.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index ac563d6..67bad9c 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -178,6 +178,7 @@ struct fwnet_device {
 
 	/* Number of tx datagrams that have been queued but not yet acked */
 	int queued_datagrams;
+	int peer_count;
 
 	struct list_head peer_list;
 	struct fw_card *card;
@@ -1408,6 +1409,10 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu)
 	return 0;
 }
 
+static const struct ethtool_ops fwnet_ethtool_ops = {
+	.get_link	= ethtool_op_get_link,
+};
+
 static const struct net_device_ops fwnet_netdev_ops = {
 	.ndo_open       = fwnet_open,
 	.ndo_stop	= fwnet_stop,
@@ -1426,6 +1431,8 @@ static void fwnet_init_dev(struct net_device *net)
 	net->hard_header_len	= FWNET_HLEN;
 	net->type		= ARPHRD_IEEE1394;
 	net->tx_queue_len	= FWNET_TX_QUEUE_LEN;
+	net->ethtool_ops	= &fwnet_ethtool_ops;
+
 }
 
 /* caller must hold fwnet_device_mutex */
@@ -1467,6 +1474,7 @@ static int fwnet_add_peer(struct fwnet_device *dev,
 
 	spin_lock_irq(&dev->lock);
 	list_add_tail(&peer->peer_link, &dev->peer_list);
+	dev->peer_count++;
 	spin_unlock_irq(&dev->lock);
 
 	return 0;
@@ -1538,6 +1546,9 @@ static int fwnet_probe(struct device *_dev)
 		unregister_netdev(net);
 		list_del(&dev->dev_link);
 	}
+
+	if (dev->peer_count > 1)
+		netif_carrier_on(net);
  out:
 	if (ret && allocated_netdev)
 		free_netdev(net);
@@ -1553,6 +1564,7 @@ static void fwnet_remove_peer(struct fwnet_peer *peer)
 
 	spin_lock_irq(&peer->dev->lock);
 	list_del(&peer->peer_link);
+	peer->dev->peer_count--;
 	spin_unlock_irq(&peer->dev->lock);
 
 	list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)
@@ -1575,6 +1587,11 @@ static int fwnet_remove(struct device *_dev)
 
 	fwnet_remove_peer(peer);
 
+	/* If we serve just one node, that means we lost link
+		with outer world */
+	if (dev->peer_count == 1)
+		netif_carrier_off(dev->netdev);
+
 	if (list_empty(&dev->peer_list)) {
 		net = dev->netdev;
 		unregister_netdev(net);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH net-2.6] llc: fix a device refcount imbalance
  2010-12-05 12:03         ` [PATCH net-2.6] llc: fix a device refcount imbalance Eric Dumazet
@ 2010-12-08 17:59           ` David Miller
  2010-12-09  3:46             ` Maxim Levitsky
  0 siblings, 1 reply; 32+ messages in thread
From: David Miller @ 2010-12-08 17:59 UTC (permalink / raw)
  To: eric.dumazet
  Cc: maximlevitsky, linux1394-devel, stefanr, netdev, kuznet, jmorris,
	kaber, opurdila, stable

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 05 Dec 2010 13:03:26 +0100

> [PATCH net-2.6] llc: fix a device refcount imbalance
> 
> commit abf9d537fea225 (llc: add support for SO_BINDTODEVICE) added one
> refcount imbalance in llc_ui_bind(), because dev_getbyhwaddr() doesnt
> take a reference on device, while dev_get_by_index() does.
> 
> Fix this using RCU locking. And since an RCU conversion will be done for
> 2.6.38 for dev_getbyhwaddr(), put the rcu_read_lock/unlock exactly at
> their final place.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied and queued up for -stable.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
  2010-12-05 11:23       ` [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() Eric Dumazet
  2010-12-05 12:03         ` [PATCH net-2.6] llc: fix a device refcount imbalance Eric Dumazet
@ 2010-12-08 18:05         ` David Miller
  2010-12-08 18:07           ` Eric Dumazet
  1 sibling, 1 reply; 32+ messages in thread
From: David Miller @ 2010-12-08 18:05 UTC (permalink / raw)
  To: eric.dumazet
  Cc: maximlevitsky, linux1394-devel, stefanr, netdev, kuznet, jmorris, kaber

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 05 Dec 2010 12:23:53 +0100

> [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
> 
> dev_getbyhwaddr() was called under RTNL.
> 
> Rename it to dev_getbyhwaddr_rcu() and change all its caller to now use
> RCU locking instead of RTNL.
> 
> Change arp_ioctl() to use RCU instead of RTNL locking.
> 
> Note: this fix a dev refcount bug in llc
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied, thanks Eric.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
  2010-12-08 18:05         ` [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() David Miller
@ 2010-12-08 18:07           ` Eric Dumazet
  2010-12-08 18:10             ` David Miller
  0 siblings, 1 reply; 32+ messages in thread
From: Eric Dumazet @ 2010-12-08 18:07 UTC (permalink / raw)
  To: David Miller
  Cc: maximlevitsky, linux1394-devel, stefanr, netdev, kuznet, jmorris, kaber

Le mercredi 08 décembre 2010 à 10:05 -0800, David Miller a écrit :
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Sun, 05 Dec 2010 12:23:53 +0100
> 
> > [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
> > 
> > dev_getbyhwaddr() was called under RTNL.
> > 
> > Rename it to dev_getbyhwaddr_rcu() and change all its caller to now use
> > RCU locking instead of RTNL.
> > 
> > Change arp_ioctl() to use RCU instead of RTNL locking.
> > 
> > Note: this fix a dev refcount bug in llc
> > 
> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> 
> Applied, thanks Eric.

Hmm, dont you want I resubmit it after the "llc: fix a device refcount
imbalance" patch pulled from net-2.6 ?

Sorry for the mess...



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
  2010-12-08 18:07           ` Eric Dumazet
@ 2010-12-08 18:10             ` David Miller
  2010-12-08 18:11               ` Eric Dumazet
  0 siblings, 1 reply; 32+ messages in thread
From: David Miller @ 2010-12-08 18:10 UTC (permalink / raw)
  To: eric.dumazet
  Cc: maximlevitsky, linux1394-devel, stefanr, netdev, kuznet, jmorris, kaber

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 08 Dec 2010 19:07:34 +0100

> Le mercredi 08 décembre 2010 à 10:05 -0800, David Miller a écrit :
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Sun, 05 Dec 2010 12:23:53 +0100
>> 
>> > [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
>> > 
>> > dev_getbyhwaddr() was called under RTNL.
>> > 
>> > Rename it to dev_getbyhwaddr_rcu() and change all its caller to now use
>> > RCU locking instead of RTNL.
>> > 
>> > Change arp_ioctl() to use RCU instead of RTNL locking.
>> > 
>> > Note: this fix a dev refcount bug in llc
>> > 
>> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>> 
>> Applied, thanks Eric.
> 
> Hmm, dont you want I resubmit it after the "llc: fix a device refcount
> imbalance" patch pulled from net-2.6 ?
> 
> Sorry for the mess...

I know about the conflict and will resolve it when I do a merge in
the next hour or so.

Don't worry about this.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
  2010-12-08 18:10             ` David Miller
@ 2010-12-08 18:11               ` Eric Dumazet
  0 siblings, 0 replies; 32+ messages in thread
From: Eric Dumazet @ 2010-12-08 18:11 UTC (permalink / raw)
  To: David Miller
  Cc: maximlevitsky, linux1394-devel, stefanr, netdev, kuznet, jmorris, kaber

Le mercredi 08 décembre 2010 à 10:10 -0800, David Miller a écrit :

> I know about the conflict and will resolve it when I do a merge in
> the next hour or so.
> 
> Don't worry about this.

Ah thats great, thanks !




^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 0/5 V2] Firewire networking assorted fixes
  2010-12-08  3:32 ` Maxim Levitsky
@ 2010-12-09  1:42   ` Maxim Levitsky
       [not found]   ` <20101208040559.20639.qmail@stuge.se>
  1 sibling, 0 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-12-09  1:42 UTC (permalink / raw)
  To: linux1394-devel; +Cc: Stefan Richter, netdev

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

On Wed, 2010-12-08 at 05:32 +0200, Maxim Levitsky wrote:
> On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> > Hi,
> > 
> > This is updated version of the patches.
> > I updated the changelogs, addressed comments on patch #2
> > 
> > Best regards,
> > 	Maxim Levitsky
> > 
> 
> Today I have achieved the ultimate goal,
> full support of firewire networking via NetworkManager.
> 
> Currently it is patched with few hacks but much less that I expected.
> 
> I also had to patch dhclient as it unfortunately sends raw packets
> together with hardware header (ethernet of course...)
> 
> I will soon clean up these hacks to turn them into patches and send to
> developers.
> 
> The kernel side needs only the attached patch.
> It adds the link state detection to firewire-net
> 
> Just for fun, this is screenshot that proves that NM works:
> http://img210.imageshack.us/img210/6019/screenshotdjk.png

And cleaned up patches that add the support attached.
Will send these to NM and dhcp ML soon.

Best regards,
	Maxim Levitsky


[-- Attachment #2: 0001-Add-support-for-RFC2855-DHCP-over-IEEE1394.patch --]
[-- Type: text/x-patch, Size: 9407 bytes --]

>From 09750594f8c861d58762969d4fe1f1b3b81b0b5f Mon Sep 17 00:00:00 2001
From: Maxim Levitsky <maximlevitsky@gmail.com>
Date: Thu, 9 Dec 2010 02:49:23 +0200
Subject: [PATCH] Add support for RFC2855, DHCP over IEEE1394

---
 client/dhclient.c    |   18 ++++++++++
 common/Makefile.dist |    6 ++-
 common/discover.c    |   15 ++++++--
 common/firewire.c    |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++
 common/lpf.c         |    9 ++++-
 common/packet.c      |   13 +++++++
 includes/dhcpd.h     |    7 ++++
 7 files changed, 151 insertions(+), 7 deletions(-)
 create mode 100644 common/firewire.c

diff --git a/client/dhclient.c b/client/dhclient.c
index a9a0993..5f079b3 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -1890,6 +1890,24 @@ void make_client_options (client, lease, type, sid, rip, prl, op)
 		client -> requested_address.len = 0;
 	}
 
+#ifdef HAVE_ARPHRD_IEEE1394
+	/* Per RFC2855, send hardware address inside client identifier
+		by default*/
+	if (client -> interface -> hw_address.hbuf [0] == ARPHRD_IEEE1394) {
+		i = DHO_DHCP_CLIENT_IDENTIFIER;
+		if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash,
+						&i, 0, MDL) &&
+			make_const_option_cache(&oc, NULL,
+				&client -> interface -> hw_address.hbuf [1], 8,
+						option, MDL)))
+			log_error ("can't make requested address cache.");
+		else {
+			save_option (&dhcp_universe, *op, oc);
+			option_cache_dereference (&oc, MDL);
+		}
+		option_dereference(&option, MDL);
+	}
+#endif
 	i = DHO_DHCP_MESSAGE_TYPE;
 	if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash, &i, 0,
 				      MDL) &&
diff --git a/common/Makefile.dist b/common/Makefile.dist
index 2b9faee..52f280b 100644
--- a/common/Makefile.dist
+++ b/common/Makefile.dist
@@ -23,11 +23,13 @@
 CATMANPAGES = dhcp-options.cat5 dhcp-eval.cat5
 SEDMANPAGES = dhcp-options.man5 dhcp-eval.man5
 SRC    = raw.c parse.c nit.c icmp.c dispatch.c conflex.c upf.c bpf.c socket.c \
-	 lpf.c dlpi.c packet.c tr.c ethernet.c memory.c print.c options.c \
+	 lpf.c dlpi.c packet.c tr.c ethernet.c firewire.c \
+	 memory.c print.c options.c \
 	 inet.c tree.c tables.c alloc.c fddi.c ctrace.c dns.c resolv.c \
 	 execute.c discover.c comapi.c
 OBJ    = raw.o parse.o nit.o icmp.o dispatch.o conflex.o upf.o bpf.o socket.o \
-	 lpf.o dlpi.o packet.o tr.o ethernet.o memory.o print.o options.o \
+	 lpf.o dlpi.o packet.o tr.o ethernet.o firewire.o \
+	 memory.o print.o options.o \
 	 inet.o tree.o tables.o alloc.o fddi.o ctrace.o dns.o resolv.o \
 	 execute.o discover.o comapi.o
 MAN    = dhcp-options.5 dhcp-eval.5
diff --git a/common/discover.c b/common/discover.c
index 69d23b1..979b1c4 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -471,15 +471,22 @@ void discover_interfaces (state)
 		     case ARPHRD_SIT:
 			/* ignore IPv6-in-IPv4 interfaces. */
 #endif
-#ifdef HAVE_ARPHRD_IEEE1394
-		     case ARPHRD_IEEE1394:
-			/* ignore IEEE1394 interfaces. */
-#endif
 #ifdef HAVE_ARPHRD_LOOPBACK
 		      case ARPHRD_LOOPBACK:
 			/* ignore loopback interface */
 			break;
 #endif
+#ifdef HAVE_ARPHRD_IEEE1394
+		     case ARPHRD_IEEE1394:
+			/* According to RFC2855, we set hlen to 0,
+			but store hardware address in the client ID,
+			so store hardware address but set len to 0 */
+			tmp -> hw_address.hlen = 1;
+			tmp -> hw_address.hbuf [0] = ARPHRD_IEEE1394;
+			memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 8);
+			break;
+#endif
+
 
 		      case ARPHRD_ETHER:
 			tmp -> hw_address.hlen = 7;
diff --git a/common/firewire.c b/common/firewire.c
new file mode 100644
index 0000000..f11efd2
--- /dev/null
+++ b/common/firewire.c
@@ -0,0 +1,90 @@
+/* firewire.c
+
+Based on ethernet.c
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ *   Internet Systems Consortium, Inc.
+ *   950 Charter Street
+ *   Redwood City, CA 94063
+ *   <info@isc.org>
+ *   https://www.isc.org/
+ *
+ * This software has been written for Internet Systems Consortium
+ * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
+ * To learn more about Internet Systems Consortium, see
+ * ``https://www.isc.org/''.  To learn more about Vixie Enterprises,
+ * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
+ * ``http://www.nominum.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"$Id: firewire.c,v 1.8.140.1 2009/07/23 21:43:33 sar Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+
+#if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING)
+#include "includes/netinet/if_ether.h"
+#endif /* PACKET_ASSEMBLY || PACKET_DECODING */
+
+#define FWNET_ALEN 8
+struct fwnet_header {
+	unsigned char h_dest[FWNET_ALEN];	/* destination address */
+	uint16_t h_proto;		/* packet type ID field */
+} __attribute__((packed));
+
+#if defined (PACKET_ASSEMBLY)
+/* Assemble an hardware header... */
+
+void assemble_fw_header (struct interface_info *interface,
+			unsigned char *buf,
+			unsigned *bufix,
+			struct hardware *to)
+{
+  struct fwnet_header hdr;
+  memset(hdr.h_dest, 0xFF, FWNET_ALEN);
+  hdr.h_proto = htons (ETHERTYPE_IP);
+  memcpy (&buf [*bufix], &hdr, sizeof(hdr));
+  *bufix += sizeof(hdr);
+}
+
+#endif /* PACKET_ASSEMBLY */
+
+#ifdef PACKET_DECODING
+/* Decode a hardware header... */
+
+ssize_t decode_fw_header(struct interface_info *interface,
+				unsigned char *buf,
+				unsigned bufix,
+				struct hardware *from)
+{
+  struct fwnet_header hdr;
+  memcpy(&hdr, buf + bufix, sizeof(hdr));
+
+#ifdef USERLAND_FILTER
+  if (ntohs (hdr.h_proto) != ETHERTYPE_IP)
+	  return -1;
+#endif
+
+  memcpy(&from->hbuf[1], hdr.h_dest, FWNET_ALEN);
+  from->hlen = FWNET_ALEN + 1;
+  return sizeof(hdr);
+}
+
+#endif /* PACKET_DECODING */
diff --git a/common/lpf.c b/common/lpf.c
index 5922660..a3fafef 100644
--- a/common/lpf.c
+++ b/common/lpf.c
@@ -181,6 +181,13 @@ void if_register_receive (info)
 		lpf_tr_filter_setup (info);
 	else
 #endif
+#if defined (HAVE_ARPHRD_IEEE1394)
+	/* FIXME: this currently piggybacks on TR no-op filter, as
+		generic filter don't work for FW */
+	if (info -> hw_address.hbuf[0] == ARPHRD_IEEE1394)
+		lpf_tr_filter_setup (info);
+	else
+#endif
 		lpf_gen_filter_setup (info);
 
 	if (!quiet_interface_discovery)
@@ -245,7 +252,7 @@ static void lpf_gen_filter_setup (info)
 	}
 }
 
-#if defined (HAVE_TR_SUPPORT)
+#if defined (HAVE_TR_SUPPORT) || defined (HAVE_ARPHRD_IEEE1394)
 static void lpf_tr_filter_setup (info)
 	struct interface_info *info;
 {
diff --git a/common/packet.c b/common/packet.c
index 4c878a6..378114e 100644
--- a/common/packet.c
+++ b/common/packet.c
@@ -111,6 +111,8 @@ void assemble_hw_header (interface, buf, bufix, to)
 	unsigned *bufix;
 	struct hardware *to;
 {
+
+
 #if defined (HAVE_TR_SUPPORT)
 	if (interface -> hw_address.hbuf [0] == HTYPE_IEEE802)
 		assemble_tr_header (interface, buf, bufix, to);
@@ -121,6 +123,11 @@ void assemble_hw_header (interface, buf, bufix, to)
 		     assemble_fddi_header (interface, buf, bufix, to);
 	else
 #endif
+#if defined (HAVE_ARPHRD_IEEE1394)
+	     if (interface -> hw_address.hbuf [0] == ARPHRD_IEEE1394)
+		     assemble_fw_header(interface, buf, bufix, to);
+#endif
+	else
 		assemble_ethernet_header (interface, buf, bufix, to);
 
 }
@@ -198,6 +205,7 @@ ssize_t decode_hw_header (interface, buf, bufix, from)
      unsigned bufix;
      struct hardware *from;
 {
+
 #if defined (HAVE_TR_SUPPORT)
 	if (interface -> hw_address.hbuf [0] == HTYPE_IEEE802)
 		return decode_tr_header (interface, buf, bufix, from);
@@ -208,6 +216,11 @@ ssize_t decode_hw_header (interface, buf, bufix, from)
 		     return decode_fddi_header (interface, buf, bufix, from);
 	else
 #endif
+#if defined (HAVE_ARPHRD_IEEE1394)
+	     if (interface -> hw_address.hbuf [0] == ARPHRD_IEEE1394)
+		     return decode_fw_header (interface, buf, bufix, from);
+#endif
+	else
 		return decode_ethernet_header (interface, buf, bufix, from);
 }
 
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index 50b899c..95b119a 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -2135,6 +2135,13 @@ ssize_t decode_tr_header PROTO ((struct interface_info *,
 				 unsigned char *,
 				 unsigned, struct hardware *));
 
+/* firewire.c */
+void assemble_fw_header PROTO ((struct interface_info *, unsigned char *,
+				unsigned *, struct hardware *));
+ssize_t decode_fw_header PROTO ((struct interface_info *,
+				 unsigned char *,
+				 unsigned, struct hardware *));
+
 /* dhxpxlt.c */
 void convert_statement PROTO ((struct parse *));
 void convert_host_statement PROTO ((struct parse *, jrefproto));
-- 
1.7.1


[-- Attachment #3: 0001-NM-allow-use-of-IPV4-over-firewire.patch --]
[-- Type: text/x-patch, Size: 1097 bytes --]

>From 93129738ca8450899e416420f630aee17c8301d5 Mon Sep 17 00:00:00 2001
From: Maxim Levitsky <maximlevitsky@gmail.com>
Date: Thu, 9 Dec 2010 00:30:55 +0200
Subject: [PATCH] NM: allow use of IPV4 over firewire

Don't ignore these devices since NM
works just fine with them iff the dhclient
works.
Patches are posted to make it work with
firewire networking link

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
---
 src/nm-udev-manager.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c
index ff0ef68..3cd2970 100644
--- a/src/nm-udev-manager.c
+++ b/src/nm-udev-manager.c
@@ -408,7 +408,9 @@ net_add (NMUdevManager *self, GUdevDevice *device)
 	g_return_if_fail (device != NULL);
 
 	etype = g_udev_device_get_sysfs_attr_as_int (device, "type");
-	if (etype != 1) {
+
+	/* firewire devices are similiar to ethernet, so allow them too */
+	if (etype != 1 && etype != 24) {
 		nm_log_dbg (LOGD_HW, "ignoring interface with type %d", etype);
 		return; /* Not using ethernet encapsulation, don't care */
 	}
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH net-2.6] llc: fix a device refcount imbalance
  2010-12-08 17:59           ` David Miller
@ 2010-12-09  3:46             ` Maxim Levitsky
  2010-12-16 21:49               ` Maxim Levitsky
  0 siblings, 1 reply; 32+ messages in thread
From: Maxim Levitsky @ 2010-12-09  3:46 UTC (permalink / raw)
  To: David Miller
  Cc: eric.dumazet, linux1394-devel, stefanr, netdev, kuznet, jmorris,
	kaber, opurdila, stable

On Wed, 2010-12-08 at 09:59 -0800, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Sun, 05 Dec 2010 13:03:26 +0100
> 
> > [PATCH net-2.6] llc: fix a device refcount imbalance
> > 
> > commit abf9d537fea225 (llc: add support for SO_BINDTODEVICE) added one
> > refcount imbalance in llc_ui_bind(), because dev_getbyhwaddr() doesnt
> > take a reference on device, while dev_get_by_index() does.
> > 
> > Fix this using RCU locking. And since an RCU conversion will be done for
> > 2.6.38 for dev_getbyhwaddr(), put the rcu_read_lock/unlock exactly at
> > their final place.
> > 
> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> 
> Applied and queued up for -stable.

Hi,

Could I kindly ask if my patch is accepted?

Best regards,
	Maxim Levitsky


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH update] firewire: net: add carrier detection
       [not found]     ` <1291809485.5421.0.camel@maxim-laptop>
@ 2010-12-12 17:09       ` Stefan Richter
  2010-12-12 23:05         ` Ben Hutchings
  0 siblings, 1 reply; 32+ messages in thread
From: Stefan Richter @ 2010-12-12 17:09 UTC (permalink / raw)
  To: Maxim Levitsky; +Cc: Peter Stuge, linux1394-devel, netdev

From: Maxim Levitsky <maximlevitsky@gmail.com>

To make userland, e.g. NetworkManager work with firewire, we need to
detect whether cable is plugged or not.  Simple and correct way of doing
that is just counting number of peers.  No peers - no link and vice
versa.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
---
Update:  Moved netif_carrier_on/off calls into lock-protected sections.

 drivers/firewire/net.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

Index: b/drivers/firewire/net.c
===================================================================
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -179,6 +179,7 @@ struct fwnet_device {
 	/* Number of tx datagrams that have been queued but not yet acked */
 	int queued_datagrams;
 
+	int peer_count;
 	struct list_head peer_list;
 	struct fw_card *card;
 	struct net_device *netdev;
@@ -1405,6 +1406,10 @@ static int fwnet_change_mtu(struct net_d
 	return 0;
 }
 
+static const struct ethtool_ops fwnet_ethtool_ops = {
+	.get_link	= ethtool_op_get_link,
+};
+
 static const struct net_device_ops fwnet_netdev_ops = {
 	.ndo_open       = fwnet_open,
 	.ndo_stop	= fwnet_stop,
@@ -1423,6 +1428,7 @@ static void fwnet_init_dev(struct net_de
 	net->hard_header_len	= FWNET_HLEN;
 	net->type		= ARPHRD_IEEE1394;
 	net->tx_queue_len	= FWNET_TX_QUEUE_LEN;
+	net->ethtool_ops	= &fwnet_ethtool_ops;
 }
 
 /* caller must hold fwnet_device_mutex */
@@ -1463,6 +1469,8 @@ static int fwnet_add_peer(struct fwnet_d
 
 	spin_lock_irq(&dev->lock);
 	list_add_tail(&peer->peer_link, &dev->peer_list);
+	if (++dev->peer_count > 1)
+		netif_carrier_on(dev->netdev);
 	spin_unlock_irq(&dev->lock);
 
 	return 0;
@@ -1549,6 +1557,8 @@ static void fwnet_remove_peer(struct fwn
 
 	spin_lock_irq(&peer->dev->lock);
 	list_del(&peer->peer_link);
+	if (--peer->dev->peer_count == 1)
+		netif_carrier_off(peer->dev->netdev);
 	spin_unlock_irq(&peer->dev->lock);
 
 	list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)


-- 
Stefan Richter
-=====-==-=- ==-- -==--
http://arcgraph.de/sr/

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH update] firewire: net: add carrier detection
  2010-12-12 17:09       ` [PATCH update] firewire: net: add carrier detection Stefan Richter
@ 2010-12-12 23:05         ` Ben Hutchings
  2010-12-13  0:46           ` [PATCH update 2] " Stefan Richter
  0 siblings, 1 reply; 32+ messages in thread
From: Ben Hutchings @ 2010-12-12 23:05 UTC (permalink / raw)
  To: Stefan Richter; +Cc: Maxim Levitsky, Peter Stuge, linux1394-devel, netdev

On Sun, 2010-12-12 at 18:09 +0100, Stefan Richter wrote:
> From: Maxim Levitsky <maximlevitsky@gmail.com>
> 
> To make userland, e.g. NetworkManager work with firewire, we need to
> detect whether cable is plugged or not.  Simple and correct way of doing
> that is just counting number of peers.  No peers - no link and vice
> versa.
[...]

NM doesn't use ETHTOOL_GLINK so you don't need to implement
ethtool_ops::get_link.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH update 2] firewire: net: add carrier detection
  2010-12-12 23:05         ` Ben Hutchings
@ 2010-12-13  0:46           ` Stefan Richter
  2010-12-13 23:01             ` [PATCH update 3] " Stefan Richter
  0 siblings, 1 reply; 32+ messages in thread
From: Stefan Richter @ 2010-12-13  0:46 UTC (permalink / raw)
  To: Ben Hutchings, Maxim Levitsky; +Cc: netdev, linux1394-devel, Peter Stuge

From: Maxim Levitsky <maximlevitsky@gmail.com>

To make userland, e.g. NetworkManager work with firewire, we need to
detect whether cable is plugged or not.  Simple and correct way of doing
that is just counting number of peers.  No peers - no link and vice
versa.

(Stefan R.:  Drop ethtool_ops.get_link)

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
---
Update 2:  Removed ethtool related hunks; dev->peer_count does not need
to be accessed within the spinlock as I first thought; reduced pointer
reference depth in fwnet_remove_peer.

Maxim, do you observe a remaining need for a get_link implementation?
I can't tell, I use rather minimal userland that doesn't care for link
status.

 drivers/firewire/net.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

Index: b/drivers/firewire/net.c
===================================================================
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -179,6 +179,7 @@ struct fwnet_device {
 	/* Number of tx datagrams that have been queued but not yet acked */
 	int queued_datagrams;
 
+	int peer_count;
 	struct list_head peer_list;
 	struct fw_card *card;
 	struct net_device *netdev;
@@ -1465,6 +1466,10 @@ static int fwnet_add_peer(struct fwnet_d
 	list_add_tail(&peer->peer_link, &dev->peer_list);
 	spin_unlock_irq(&dev->lock);
 
+	/* dev->peer_count acess is serialized by fwnet_device_mutex. */
+	if (++dev->peer_count > 1)
+		netif_carrier_on(dev->netdev);
+
 	return 0;
 }
 
@@ -1543,13 +1548,16 @@ static int fwnet_probe(struct device *_d
 	return ret;
 }
 
-static void fwnet_remove_peer(struct fwnet_peer *peer)
+static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
 {
 	struct fwnet_partial_datagram *pd, *pd_next;
 
-	spin_lock_irq(&peer->dev->lock);
+	if (--dev->peer_count == 1)
+		netif_carrier_off(dev->netdev);
+
+	spin_lock_irq(&dev->lock);
 	list_del(&peer->peer_link);
-	spin_unlock_irq(&peer->dev->lock);
+	spin_unlock_irq(&dev->lock);
 
 	list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)
 		fwnet_pd_delete(pd);
@@ -1566,7 +1574,7 @@ static int fwnet_remove(struct device *_
 
 	mutex_lock(&fwnet_device_mutex);
 
-	fwnet_remove_peer(peer);
+	fwnet_remove_peer(peer, dev);
 
 	if (list_empty(&dev->peer_list)) {
 		net = dev->netdev;


-- 
Stefan Richter
-=====-==-=- ==-- -==-=
http://arcgraph.de/sr/

------------------------------------------------------------------------------
Oracle to DB2 Conversion Guide: Learn learn about native support for PL/SQL,
new data types, scalar functions, improved concurrency, built-in packages, 
OCI, SQL*Plus, data movement tools, best practices and more.
http://p.sf.net/sfu/oracle-sfdev2dev 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH update 3] firewire: net: add carrier detection
  2010-12-13  0:46           ` [PATCH update 2] " Stefan Richter
@ 2010-12-13 23:01             ` Stefan Richter
  2010-12-14 23:46               ` Maxim Levitsky
  2010-12-16  1:17               ` Dan Williams
  0 siblings, 2 replies; 32+ messages in thread
From: Stefan Richter @ 2010-12-13 23:01 UTC (permalink / raw)
  To: Maxim Levitsky; +Cc: Ben Hutchings, netdev, linux1394-devel, Peter Stuge

From: Maxim Levitsky <maximlevitsky@gmail.com>

To make userland, e.g. NetworkManager work with firewire, we need to
detect whether cable is plugged or not.  Simple and correct way of doing
that is just counting number of peers.  No peers - no link and vice
versa.

(Stefan R.:  Combined peer_count inc/dec with tests, added link-down
recognition in fwnet_open, added include.)

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
---
Update 3: added fwnet_open (ifup) hunk

 drivers/firewire/net.c |   29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

Index: b/drivers/firewire/net.c
===================================================================
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -9,6 +9,7 @@
 #include <linux/bug.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/firewire.h>
 #include <linux/firewire-constants.h>
 #include <linux/highmem.h>
@@ -179,6 +180,7 @@ struct fwnet_device {
 	/* Number of tx datagrams that have been queued but not yet acked */
 	int queued_datagrams;
 
+	int peer_count;
 	struct list_head peer_list;
 	struct fw_card *card;
 	struct net_device *netdev;
@@ -1234,6 +1236,13 @@ static int fwnet_open(struct net_device 
 	}
 	netif_start_queue(net);
 
+	mutex_lock(&fwnet_device_mutex);
+	if (dev->peer_count > 1)
+		netif_carrier_on(net);
+	else
+		netif_carrier_off(net);
+	mutex_unlock(&fwnet_device_mutex);
+
 	return 0;
 }
 
@@ -1412,6 +1421,10 @@ static const struct net_device_ops fwnet
 	.ndo_change_mtu = fwnet_change_mtu,
 };
 
+static const struct ethtool_ops fwnet_ethtool_ops = {
+	.get_link	= ethtool_op_get_link,
+};
+
 static void fwnet_init_dev(struct net_device *net)
 {
 	net->header_ops		= &fwnet_header_ops;
@@ -1423,6 +1436,7 @@ static void fwnet_init_dev(struct net_de
 	net->hard_header_len	= FWNET_HLEN;
 	net->type		= ARPHRD_IEEE1394;
 	net->tx_queue_len	= FWNET_TX_QUEUE_LEN;
+	net->ethtool_ops	= &fwnet_ethtool_ops;
 }
 
 /* caller must hold fwnet_device_mutex */
@@ -1465,6 +1479,10 @@ static int fwnet_add_peer(struct fwnet_d
 	list_add_tail(&peer->peer_link, &dev->peer_list);
 	spin_unlock_irq(&dev->lock);
 
+	/* serialized by fwnet_device_mutex */
+	if (++dev->peer_count > 1)
+		netif_carrier_on(dev->netdev);
+
 	return 0;
 }
 
@@ -1543,13 +1561,16 @@ static int fwnet_probe(struct device *_d
 	return ret;
 }
 
-static void fwnet_remove_peer(struct fwnet_peer *peer)
+static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
 {
 	struct fwnet_partial_datagram *pd, *pd_next;
 
-	spin_lock_irq(&peer->dev->lock);
+	if (--dev->peer_count == 1)
+		netif_carrier_off(dev->netdev);
+
+	spin_lock_irq(&dev->lock);
 	list_del(&peer->peer_link);
-	spin_unlock_irq(&peer->dev->lock);
+	spin_unlock_irq(&dev->lock);
 
 	list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)
 		fwnet_pd_delete(pd);
@@ -1566,7 +1587,7 @@ static int fwnet_remove(struct device *_
 
 	mutex_lock(&fwnet_device_mutex);
 
-	fwnet_remove_peer(peer);
+	fwnet_remove_peer(peer, dev);
 
 	if (list_empty(&dev->peer_list)) {
 		net = dev->netdev;


-- 
Stefan Richter
-=====-==-=- ==-- -==-=
http://arcgraph.de/sr/

------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH update 3] firewire: net: add carrier detection
  2010-12-13 23:01             ` [PATCH update 3] " Stefan Richter
@ 2010-12-14 23:46               ` Maxim Levitsky
  2010-12-16  1:17               ` Dan Williams
  1 sibling, 0 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-12-14 23:46 UTC (permalink / raw)
  To: Stefan Richter; +Cc: Ben Hutchings, Peter Stuge, linux1394-devel, netdev

On Tue, 2010-12-14 at 00:01 +0100, Stefan Richter wrote:
> From: Maxim Levitsky <maximlevitsky@gmail.com>
> 
> To make userland, e.g. NetworkManager work with firewire, we need to
> detect whether cable is plugged or not.  Simple and correct way of doing
> that is just counting number of peers.  No peers - no link and vice
> versa.
> 
> (Stefan R.:  Combined peer_count inc/dec with tests, added link-down
> recognition in fwnet_open, added include.)
> 
> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
> ---
> Update 3: added fwnet_open (ifup) hunk

Thank you very much.
I tested this just in case, and it works just fine.
Especially thanks for the missing carrier state initialization,
Just one note, since you pretty much rewrite that little patch, it would
be correct to attribute you as an author of it.
I was recently (and still am) busy with my DVB card, so I didn't test my
original patch enough.

Beyond this patch, firewire networking is pretty much complete.

The only missing parts are IPV6 and multicast, and the latter works by
using broadcast which for all means is enough.

> 
>  drivers/firewire/net.c |   29 +++++++++++++++++++++++++----
>  1 file changed, 25 insertions(+), 4 deletions(-)
> 
> Index: b/drivers/firewire/net.c
> ===================================================================
> --- a/drivers/firewire/net.c
> +++ b/drivers/firewire/net.c
> @@ -9,6 +9,7 @@
>  #include <linux/bug.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
> +#include <linux/ethtool.h>
>  #include <linux/firewire.h>
>  #include <linux/firewire-constants.h>
>  #include <linux/highmem.h>
> @@ -179,6 +180,7 @@ struct fwnet_device {
>  	/* Number of tx datagrams that have been queued but not yet acked */
>  	int queued_datagrams;
>  
> +	int peer_count;
>  	struct list_head peer_list;
>  	struct fw_card *card;
>  	struct net_device *netdev;
> @@ -1234,6 +1236,13 @@ static int fwnet_open(struct net_device 
>  	}
>  	netif_start_queue(net);
>  
> +	mutex_lock(&fwnet_device_mutex);
> +	if (dev->peer_count > 1)
> +		netif_carrier_on(net);
> +	else
> +		netif_carrier_off(net);
> +	mutex_unlock(&fwnet_device_mutex);
> +
>  	return 0;
>  }
>  
> @@ -1412,6 +1421,10 @@ static const struct net_device_ops fwnet
>  	.ndo_change_mtu = fwnet_change_mtu,
>  };
>  
> +static const struct ethtool_ops fwnet_ethtool_ops = {
> +	.get_link	= ethtool_op_get_link,
> +};
> +
>  static void fwnet_init_dev(struct net_device *net)
>  {
>  	net->header_ops		= &fwnet_header_ops;
> @@ -1423,6 +1436,7 @@ static void fwnet_init_dev(struct net_de
>  	net->hard_header_len	= FWNET_HLEN;
>  	net->type		= ARPHRD_IEEE1394;
>  	net->tx_queue_len	= FWNET_TX_QUEUE_LEN;
> +	net->ethtool_ops	= &fwnet_ethtool_ops;
>  }
>  
>  /* caller must hold fwnet_device_mutex */
> @@ -1465,6 +1479,10 @@ static int fwnet_add_peer(struct fwnet_d
>  	list_add_tail(&peer->peer_link, &dev->peer_list);
>  	spin_unlock_irq(&dev->lock);
>  
> +	/* serialized by fwnet_device_mutex */
> +	if (++dev->peer_count > 1)
> +		netif_carrier_on(dev->netdev);
> +
>  	return 0;
>  }
>  
> @@ -1543,13 +1561,16 @@ static int fwnet_probe(struct device *_d
>  	return ret;
>  }
>  
> -static void fwnet_remove_peer(struct fwnet_peer *peer)
> +static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
>  {
>  	struct fwnet_partial_datagram *pd, *pd_next;
>  
> -	spin_lock_irq(&peer->dev->lock);
> +	if (--dev->peer_count == 1)
> +		netif_carrier_off(dev->netdev);
> +
> +	spin_lock_irq(&dev->lock);
>  	list_del(&peer->peer_link);
> -	spin_unlock_irq(&peer->dev->lock);
> +	spin_unlock_irq(&dev->lock);
>  
>  	list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)
>  		fwnet_pd_delete(pd);
> @@ -1566,7 +1587,7 @@ static int fwnet_remove(struct device *_
>  
>  	mutex_lock(&fwnet_device_mutex);
>  
> -	fwnet_remove_peer(peer);
> +	fwnet_remove_peer(peer, dev);
>  
>  	if (list_empty(&dev->peer_list)) {
>  		net = dev->netdev;
> 
> 



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH update 3] firewire: net: add carrier detection
  2010-12-13 23:01             ` [PATCH update 3] " Stefan Richter
  2010-12-14 23:46               ` Maxim Levitsky
@ 2010-12-16  1:17               ` Dan Williams
  1 sibling, 0 replies; 32+ messages in thread
From: Dan Williams @ 2010-12-16  1:17 UTC (permalink / raw)
  To: Stefan Richter; +Cc: Ben Hutchings, netdev, linux1394-devel, Peter Stuge

On Tue, 2010-12-14 at 00:01 +0100, Stefan Richter wrote:
> From: Maxim Levitsky <maximlevitsky@gmail.com>
> 
> To make userland, e.g. NetworkManager work with firewire, we need to
> detect whether cable is plugged or not.  Simple and correct way of doing
> that is just counting number of peers.  No peers - no link and vice
> versa.

Oh you rock.  Good stuff.

Dan

> (Stefan R.:  Combined peer_count inc/dec with tests, added link-down
> recognition in fwnet_open, added include.)
> 
> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
> ---
> Update 3: added fwnet_open (ifup) hunk
> 
>  drivers/firewire/net.c |   29 +++++++++++++++++++++++++----
>  1 file changed, 25 insertions(+), 4 deletions(-)
> 
> Index: b/drivers/firewire/net.c
> ===================================================================
> --- a/drivers/firewire/net.c
> +++ b/drivers/firewire/net.c
> @@ -9,6 +9,7 @@
>  #include <linux/bug.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
> +#include <linux/ethtool.h>
>  #include <linux/firewire.h>
>  #include <linux/firewire-constants.h>
>  #include <linux/highmem.h>
> @@ -179,6 +180,7 @@ struct fwnet_device {
>  	/* Number of tx datagrams that have been queued but not yet acked */
>  	int queued_datagrams;
>  
> +	int peer_count;
>  	struct list_head peer_list;
>  	struct fw_card *card;
>  	struct net_device *netdev;
> @@ -1234,6 +1236,13 @@ static int fwnet_open(struct net_device 
>  	}
>  	netif_start_queue(net);
>  
> +	mutex_lock(&fwnet_device_mutex);
> +	if (dev->peer_count > 1)
> +		netif_carrier_on(net);
> +	else
> +		netif_carrier_off(net);
> +	mutex_unlock(&fwnet_device_mutex);
> +
>  	return 0;
>  }
>  
> @@ -1412,6 +1421,10 @@ static const struct net_device_ops fwnet
>  	.ndo_change_mtu = fwnet_change_mtu,
>  };
>  
> +static const struct ethtool_ops fwnet_ethtool_ops = {
> +	.get_link	= ethtool_op_get_link,
> +};
> +
>  static void fwnet_init_dev(struct net_device *net)
>  {
>  	net->header_ops		= &fwnet_header_ops;
> @@ -1423,6 +1436,7 @@ static void fwnet_init_dev(struct net_de
>  	net->hard_header_len	= FWNET_HLEN;
>  	net->type		= ARPHRD_IEEE1394;
>  	net->tx_queue_len	= FWNET_TX_QUEUE_LEN;
> +	net->ethtool_ops	= &fwnet_ethtool_ops;
>  }
>  
>  /* caller must hold fwnet_device_mutex */
> @@ -1465,6 +1479,10 @@ static int fwnet_add_peer(struct fwnet_d
>  	list_add_tail(&peer->peer_link, &dev->peer_list);
>  	spin_unlock_irq(&dev->lock);
>  
> +	/* serialized by fwnet_device_mutex */
> +	if (++dev->peer_count > 1)
> +		netif_carrier_on(dev->netdev);
> +
>  	return 0;
>  }
>  
> @@ -1543,13 +1561,16 @@ static int fwnet_probe(struct device *_d
>  	return ret;
>  }
>  
> -static void fwnet_remove_peer(struct fwnet_peer *peer)
> +static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
>  {
>  	struct fwnet_partial_datagram *pd, *pd_next;
>  
> -	spin_lock_irq(&peer->dev->lock);
> +	if (--dev->peer_count == 1)
> +		netif_carrier_off(dev->netdev);
> +
> +	spin_lock_irq(&dev->lock);
>  	list_del(&peer->peer_link);
> -	spin_unlock_irq(&peer->dev->lock);
> +	spin_unlock_irq(&dev->lock);
>  
>  	list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)
>  		fwnet_pd_delete(pd);
> @@ -1566,7 +1587,7 @@ static int fwnet_remove(struct device *_
>  
>  	mutex_lock(&fwnet_device_mutex);
>  
> -	fwnet_remove_peer(peer);
> +	fwnet_remove_peer(peer, dev);
>  
>  	if (list_empty(&dev->peer_list)) {
>  		net = dev->netdev;
> 
> 



------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH net-2.6] llc: fix a device refcount imbalance
  2010-12-09  3:46             ` Maxim Levitsky
@ 2010-12-16 21:49               ` Maxim Levitsky
  0 siblings, 0 replies; 32+ messages in thread
From: Maxim Levitsky @ 2010-12-16 21:49 UTC (permalink / raw)
  To: David Miller
  Cc: eric.dumazet, linux1394-devel, stefanr, netdev, kuznet, jmorris,
	kaber, opurdila, stable

On Thu, 2010-12-09 at 05:46 +0200, Maxim Levitsky wrote:
> On Wed, 2010-12-08 at 09:59 -0800, David Miller wrote:
> > From: Eric Dumazet <eric.dumazet@gmail.com>
> > Date: Sun, 05 Dec 2010 13:03:26 +0100
> > 
> > > [PATCH net-2.6] llc: fix a device refcount imbalance
> > > 
> > > commit abf9d537fea225 (llc: add support for SO_BINDTODEVICE) added one
> > > refcount imbalance in llc_ui_bind(), because dev_getbyhwaddr() doesnt
> > > take a reference on device, while dev_get_by_index() does.
> > > 
> > > Fix this using RCU locking. And since an RCU conversion will be done for
> > > 2.6.38 for dev_getbyhwaddr(), put the rcu_read_lock/unlock exactly at
> > > their final place.
> > > 
> > > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> > 
> > Applied and queued up for -stable.
> 
> Hi,
> 
> Could I kindly ask if my patch is accepted?
> 
> Best regards,
> 	Maxim Levitsky
> 

Anybody?

Best regards,
	Maxim Levitsky


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
  2010-11-29  2:09 ` [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries Maxim Levitsky
  2010-12-04 23:15   ` Maxim Levitsky
@ 2011-01-07 12:47   ` Maxim Levitsky
  2011-01-07 12:57     ` Eric Dumazet
  1 sibling, 1 reply; 32+ messages in thread
From: Maxim Levitsky @ 2011-01-07 12:47 UTC (permalink / raw)
  To: linux1394-devel
  Cc: Stefan Richter, netdev, David S. Miller, Alexey Kuznetsov,
	James Morris, Patrick McHardy

On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> IPv4 over firewire needs to be able to remove ARP entries
> from the ARP cache that belong to nodes that are removed, because
> IPv4 over firewire uses ARP packets for private information
> about nodes.
> 
> This information becomes invalid as soon as node drops
> off the bus and when it reconnects, its only possible
> to start takling to is after it responded to an ARP packet.
> But ARP cache prevents such packets from being sent.
> 
> CC: netdev@vger.kernel.org
> CC: "David S. Miller" <davem@davemloft.net>
> CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> CC: James Morris <jmorris@namei.org>
> CC: Patrick McHardy <kaber@trash.net>

Anybody?

Best regards,
	Maxim Levitsky

> 
> 
> Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> ---
>  include/net/arp.h |    1 +
>  net/ipv4/arp.c    |   29 ++++++++++++++++++-----------
>  2 files changed, 19 insertions(+), 11 deletions(-)
> 
> diff --git a/include/net/arp.h b/include/net/arp.h
> index f4cf6ce..91f0568 100644
> --- a/include/net/arp.h
> +++ b/include/net/arp.h
> @@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
>  				  const unsigned char *src_hw,
>  				  const unsigned char *target_hw);
>  extern void arp_xmit(struct sk_buff *skb);
> +int arp_invalidate(struct net_device *dev, __be32 ip);
>  
>  #endif	/* _ARP_H */
> diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> index d8e540c..35b1272 100644
> --- a/net/ipv4/arp.c
> +++ b/net/ipv4/arp.c
> @@ -1142,6 +1142,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
>  	return err;
>  }
>  
> +int arp_invalidate(struct net_device *dev, __be32 ip)
> +{
> +	int err = -ENXIO;
> +	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
> +
> +	if (neigh) {
> +		if (neigh->nud_state & ~NUD_NOARP)
> +			err = neigh_update(neigh, NULL, NUD_FAILED,
> +					   NEIGH_UPDATE_F_OVERRIDE|
> +					   NEIGH_UPDATE_F_ADMIN);
> +		neigh_release(neigh);
> +	}
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(arp_invalidate);
> +
>  static int arp_req_delete_public(struct net *net, struct arpreq *r,
>  		struct net_device *dev)
>  {
> @@ -1162,7 +1179,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
>  {
>  	int err;
>  	__be32 ip;
> -	struct neighbour *neigh;
>  
>  	if (r->arp_flags & ATF_PUBL)
>  		return arp_req_delete_public(net, r, dev);
> @@ -1180,16 +1196,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
>  		if (!dev)
>  			return -EINVAL;
>  	}
> -	err = -ENXIO;
> -	neigh = neigh_lookup(&arp_tbl, &ip, dev);
> -	if (neigh) {
> -		if (neigh->nud_state & ~NUD_NOARP)
> -			err = neigh_update(neigh, NULL, NUD_FAILED,
> -					   NEIGH_UPDATE_F_OVERRIDE|
> -					   NEIGH_UPDATE_F_ADMIN);
> -		neigh_release(neigh);
> -	}
> -	return err;
> +	return arp_invalidate(dev, ip);
>  }
>  
>  /*



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
  2011-01-07 12:47   ` [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries Maxim Levitsky
@ 2011-01-07 12:57     ` Eric Dumazet
  2011-01-07 13:15       ` Maxim Levitsky
  2011-01-08 23:57       ` Maxim Levitsky
  0 siblings, 2 replies; 32+ messages in thread
From: Eric Dumazet @ 2011-01-07 12:57 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: netdev, Morris, Patrick McHardy, Stefan Richter, James,
	Alexey Kuznetsov, linux1394-devel, David S. Miller

Le vendredi 07 janvier 2011 à 14:47 +0200, Maxim Levitsky a écrit :
> On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> > IPv4 over firewire needs to be able to remove ARP entries
> > from the ARP cache that belong to nodes that are removed, because
> > IPv4 over firewire uses ARP packets for private information
> > about nodes.
> > 
> > This information becomes invalid as soon as node drops
> > off the bus and when it reconnects, its only possible
> > to start takling to is after it responded to an ARP packet.
> > But ARP cache prevents such packets from being sent.
> > 
> > CC: netdev@vger.kernel.org
> > CC: "David S. Miller" <davem@davemloft.net>
> > CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> > CC: James Morris <jmorris@namei.org>
> > CC: Patrick McHardy <kaber@trash.net>
> 
> Anybody?
> 
> Best regards,
> 	Maxim Levitsky
> 
> > 
> > 
> > Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> > ---
> >  include/net/arp.h |    1 +
> >  net/ipv4/arp.c    |   29 ++++++++++++++++++-----------
> >  2 files changed, 19 insertions(+), 11 deletions(-)
> > 
> > diff --git a/include/net/arp.h b/include/net/arp.h
> > index f4cf6ce..91f0568 100644
> > --- a/include/net/arp.h
> > +++ b/include/net/arp.h
> > @@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
> >  				  const unsigned char *src_hw,
> >  				  const unsigned char *target_hw);
> >  extern void arp_xmit(struct sk_buff *skb);
> > +int arp_invalidate(struct net_device *dev, __be32 ip);
> >  
> >  #endif	/* _ARP_H */
> > diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> > index d8e540c..35b1272 100644
> > --- a/net/ipv4/arp.c
> > +++ b/net/ipv4/arp.c
> > @@ -1142,6 +1142,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
> >  	return err;
> >  }
> >  
> > +int arp_invalidate(struct net_device *dev, __be32 ip)
> > +{
> > +	int err = -ENXIO;
> > +	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > +
> > +	if (neigh) {
> > +		if (neigh->nud_state & ~NUD_NOARP)
> > +			err = neigh_update(neigh, NULL, NUD_FAILED,
> > +					   NEIGH_UPDATE_F_OVERRIDE|
> > +					   NEIGH_UPDATE_F_ADMIN);
> > +		neigh_release(neigh);
> > +	}
> > +
> > +	return err;
> > +}
> > +EXPORT_SYMBOL(arp_invalidate);
> > +
> >  static int arp_req_delete_public(struct net *net, struct arpreq *r,
> >  		struct net_device *dev)
> >  {
> > @@ -1162,7 +1179,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> >  {
> >  	int err;
> >  	__be32 ip;
> > -	struct neighbour *neigh;
> >  
> >  	if (r->arp_flags & ATF_PUBL)
> >  		return arp_req_delete_public(net, r, dev);
> > @@ -1180,16 +1196,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> >  		if (!dev)
> >  			return -EINVAL;
> >  	}
> > -	err = -ENXIO;
> > -	neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > -	if (neigh) {
> > -		if (neigh->nud_state & ~NUD_NOARP)
> > -			err = neigh_update(neigh, NULL, NUD_FAILED,
> > -					   NEIGH_UPDATE_F_OVERRIDE|
> > -					   NEIGH_UPDATE_F_ADMIN);
> > -		neigh_release(neigh);
> > -	}
> > -	return err;
> > +	return arp_invalidate(dev, ip);
> >  }
> >  
> >  /*
> 

Hi Maxim

You were supposed to respin your patch after my commit :

(941666c2e3e0f9f6a1 net: RCU conversion of dev_getbyhwaddr() and
arp_ioctl())

Thanks



------------------------------------------------------------------------------
Gaining the trust of online customers is vital for the success of any company
that requires sensitive data to be transmitted over the Web.   Learn how to 
best implement a security strategy that keeps consumers' information secure 
and instills the confidence they need to proceed with transactions.
http://p.sf.net/sfu/oracle-sfdevnl 
_______________________________________________
mailing list linux1394-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux1394-devel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
  2011-01-07 12:57     ` Eric Dumazet
@ 2011-01-07 13:15       ` Maxim Levitsky
  2011-01-08 23:57       ` Maxim Levitsky
  1 sibling, 0 replies; 32+ messages in thread
From: Maxim Levitsky @ 2011-01-07 13:15 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: linux1394-devel, Stefan Richter, netdev, David S. Miller,
	Alexey Kuznetsov, James Morris, Patrick McHardy

On Fri, 2011-01-07 at 13:57 +0100, Eric Dumazet wrote:
> Le vendredi 07 janvier 2011 à 14:47 +0200, Maxim Levitsky a écrit :
> > On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> > > IPv4 over firewire needs to be able to remove ARP entries
> > > from the ARP cache that belong to nodes that are removed, because
> > > IPv4 over firewire uses ARP packets for private information
> > > about nodes.
> > > 
> > > This information becomes invalid as soon as node drops
> > > off the bus and when it reconnects, its only possible
> > > to start takling to is after it responded to an ARP packet.
> > > But ARP cache prevents such packets from being sent.
> > > 
> > > CC: netdev@vger.kernel.org
> > > CC: "David S. Miller" <davem@davemloft.net>
> > > CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> > > CC: James Morris <jmorris@namei.org>
> > > CC: Patrick McHardy <kaber@trash.net>
> > 
> > Anybody?
> > 
> > Best regards,
> > 	Maxim Levitsky
> > 
> > > 
> > > 
> > > Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> > > ---
> > >  include/net/arp.h |    1 +
> > >  net/ipv4/arp.c    |   29 ++++++++++++++++++-----------
> > >  2 files changed, 19 insertions(+), 11 deletions(-)
> > > 
> > > diff --git a/include/net/arp.h b/include/net/arp.h
> > > index f4cf6ce..91f0568 100644
> > > --- a/include/net/arp.h
> > > +++ b/include/net/arp.h
> > > @@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
> > >  				  const unsigned char *src_hw,
> > >  				  const unsigned char *target_hw);
> > >  extern void arp_xmit(struct sk_buff *skb);
> > > +int arp_invalidate(struct net_device *dev, __be32 ip);
> > >  
> > >  #endif	/* _ARP_H */
> > > diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> > > index d8e540c..35b1272 100644
> > > --- a/net/ipv4/arp.c
> > > +++ b/net/ipv4/arp.c
> > > @@ -1142,6 +1142,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
> > >  	return err;
> > >  }
> > >  
> > > +int arp_invalidate(struct net_device *dev, __be32 ip)
> > > +{
> > > +	int err = -ENXIO;
> > > +	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > > +
> > > +	if (neigh) {
> > > +		if (neigh->nud_state & ~NUD_NOARP)
> > > +			err = neigh_update(neigh, NULL, NUD_FAILED,
> > > +					   NEIGH_UPDATE_F_OVERRIDE|
> > > +					   NEIGH_UPDATE_F_ADMIN);
> > > +		neigh_release(neigh);
> > > +	}
> > > +
> > > +	return err;
> > > +}
> > > +EXPORT_SYMBOL(arp_invalidate);
> > > +
> > >  static int arp_req_delete_public(struct net *net, struct arpreq *r,
> > >  		struct net_device *dev)
> > >  {
> > > @@ -1162,7 +1179,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> > >  {
> > >  	int err;
> > >  	__be32 ip;
> > > -	struct neighbour *neigh;
> > >  
> > >  	if (r->arp_flags & ATF_PUBL)
> > >  		return arp_req_delete_public(net, r, dev);
> > > @@ -1180,16 +1196,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> > >  		if (!dev)
> > >  			return -EINVAL;
> > >  	}
> > > -	err = -ENXIO;
> > > -	neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > > -	if (neigh) {
> > > -		if (neigh->nud_state & ~NUD_NOARP)
> > > -			err = neigh_update(neigh, NULL, NUD_FAILED,
> > > -					   NEIGH_UPDATE_F_OVERRIDE|
> > > -					   NEIGH_UPDATE_F_ADMIN);
> > > -		neigh_release(neigh);
> > > -	}
> > > -	return err;
> > > +	return arp_invalidate(dev, ip);
> > >  }
> > >  
> > >  /*
> > 
> 
> Hi Maxim
> 
> You were supposed to respin your patch after my commit :
> 
> (941666c2e3e0f9f6a1 net: RCU conversion of dev_getbyhwaddr() and
> arp_ioctl())
> 
> Thanks


Will do very soon.

Best regards,
	Maxim Levitsky


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
  2011-01-07 12:57     ` Eric Dumazet
  2011-01-07 13:15       ` Maxim Levitsky
@ 2011-01-08 23:57       ` Maxim Levitsky
  2011-01-11  0:11         ` David Miller
  1 sibling, 1 reply; 32+ messages in thread
From: Maxim Levitsky @ 2011-01-08 23:57 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: linux1394-devel, Stefan Richter, netdev, David S. Miller,
	Alexey Kuznetsov, James Morris, Patrick McHardy

On Fri, 2011-01-07 at 13:57 +0100, Eric Dumazet wrote:
> Le vendredi 07 janvier 2011 à 14:47 +0200, Maxim Levitsky a écrit :
> > On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> > > IPv4 over firewire needs to be able to remove ARP entries
> > > from the ARP cache that belong to nodes that are removed, because
> > > IPv4 over firewire uses ARP packets for private information
> > > about nodes.
> > > 
> > > This information becomes invalid as soon as node drops
> > > off the bus and when it reconnects, its only possible
> > > to start takling to is after it responded to an ARP packet.
> > > But ARP cache prevents such packets from being sent.
> > > 
> > > CC: netdev@vger.kernel.org
> > > CC: "David S. Miller" <davem@davemloft.net>
> > > CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> > > CC: James Morris <jmorris@namei.org>
> > > CC: Patrick McHardy <kaber@trash.net>
> > 
> > Anybody?
> > 
> > Best regards,
> > 	Maxim Levitsky
> > 
> > > 
> > > 
> > > Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> > > ---
> > >  include/net/arp.h |    1 +
> > >  net/ipv4/arp.c    |   29 ++++++++++++++++++-----------
> > >  2 files changed, 19 insertions(+), 11 deletions(-)
> > > 
> > > diff --git a/include/net/arp.h b/include/net/arp.h
> > > index f4cf6ce..91f0568 100644
> > > --- a/include/net/arp.h
> > > +++ b/include/net/arp.h
> > > @@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
> > >  				  const unsigned char *src_hw,
> > >  				  const unsigned char *target_hw);
> > >  extern void arp_xmit(struct sk_buff *skb);
> > > +int arp_invalidate(struct net_device *dev, __be32 ip);
> > >  
> > >  #endif	/* _ARP_H */
> > > diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> > > index d8e540c..35b1272 100644
> > > --- a/net/ipv4/arp.c
> > > +++ b/net/ipv4/arp.c
> > > @@ -1142,6 +1142,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
> > >  	return err;
> > >  }
> > >  
> > > +int arp_invalidate(struct net_device *dev, __be32 ip)
> > > +{
> > > +	int err = -ENXIO;
> > > +	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > > +
> > > +	if (neigh) {
> > > +		if (neigh->nud_state & ~NUD_NOARP)
> > > +			err = neigh_update(neigh, NULL, NUD_FAILED,
> > > +					   NEIGH_UPDATE_F_OVERRIDE|
> > > +					   NEIGH_UPDATE_F_ADMIN);
> > > +		neigh_release(neigh);
> > > +	}
> > > +
> > > +	return err;
> > > +}
> > > +EXPORT_SYMBOL(arp_invalidate);
> > > +
> > >  static int arp_req_delete_public(struct net *net, struct arpreq *r,
> > >  		struct net_device *dev)
> > >  {
> > > @@ -1162,7 +1179,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> > >  {
> > >  	int err;
> > >  	__be32 ip;
> > > -	struct neighbour *neigh;
> > >  
> > >  	if (r->arp_flags & ATF_PUBL)
> > >  		return arp_req_delete_public(net, r, dev);
> > > @@ -1180,16 +1196,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> > >  		if (!dev)
> > >  			return -EINVAL;
> > >  	}
> > > -	err = -ENXIO;
> > > -	neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > > -	if (neigh) {
> > > -		if (neigh->nud_state & ~NUD_NOARP)
> > > -			err = neigh_update(neigh, NULL, NUD_FAILED,
> > > -					   NEIGH_UPDATE_F_OVERRIDE|
> > > -					   NEIGH_UPDATE_F_ADMIN);
> > > -		neigh_release(neigh);
> > > -	}
> > > -	return err;
> > > +	return arp_invalidate(dev, ip);
> > >  }
> > >  
> > >  /*
> > 
> 
> Hi Maxim
> 
> You were supposed to respin your patch after my commit :
> 
> (941666c2e3e0f9f6a1 net: RCU conversion of dev_getbyhwaddr() and
> arp_ioctl())
> 
> Thanks

Hi,

After looking at the code (and honestly its hard to work with it as it
has no documentation at all), I think I don't need any changes in my
patch.

Here is the latest version for I use with the above commit applied (it
is in mainline now).

---

commit 7da91d68d78b6a44ba6337be3b29b22ba2909b9e
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Nov 27 00:50:45 2010 +0200

    NET: IPV4: ARP: allow to invalidate specific ARP entries
    
    IPv4 over firewire needs to be able to remove ARP entries
    from the ARP cache that belong to nodes that are removed, because
    IPv4 over firewire uses ARP packets for private information
    about nodes.
    
    This information becomes invalid as soon as node drops
    off the bus and when it reconnects, its only possible
    to start takling to is after it responded to an ARP packet.
    But ARP cache prevents such packets from being sent.
    
    CC: netdev@vger.kernel.org
    CC: "David S. Miller" <davem@davemloft.net>
    CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
    CC: James Morris <jmorris@namei.org>
    CC: Patrick McHardy <kaber@trash.net>
    
    
    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>

diff --git a/include/net/arp.h b/include/net/arp.h
index f4cf6ce..91f0568 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
 				  const unsigned char *src_hw,
 				  const unsigned char *target_hw);
 extern void arp_xmit(struct sk_buff *skb);
+int arp_invalidate(struct net_device *dev, __be32 ip);
 
 #endif	/* _ARP_H */
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index a2fc7b9..e941c75 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1143,6 +1143,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
 	return err;
 }
 
+int arp_invalidate(struct net_device *dev, __be32 ip)
+{
+	int err = -ENXIO;
+	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
+
+	if (neigh) {
+		if (neigh->nud_state & ~NUD_NOARP)
+			err = neigh_update(neigh, NULL, NUD_FAILED,
+					   NEIGH_UPDATE_F_OVERRIDE|
+					   NEIGH_UPDATE_F_ADMIN);
+		neigh_release(neigh);
+	}
+
+	return err;
+}
+EXPORT_SYMBOL(arp_invalidate);
+
 static int arp_req_delete_public(struct net *net, struct arpreq *r,
 		struct net_device *dev)
 {
@@ -1163,7 +1180,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
 {
 	int err;
 	__be32 ip;
-	struct neighbour *neigh;
 
 	if (r->arp_flags & ATF_PUBL)
 		return arp_req_delete_public(net, r, dev);
@@ -1181,16 +1197,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
 		if (!dev)
 			return -EINVAL;
 	}
-	err = -ENXIO;
-	neigh = neigh_lookup(&arp_tbl, &ip, dev);
-	if (neigh) {
-		if (neigh->nud_state & ~NUD_NOARP)
-			err = neigh_update(neigh, NULL, NUD_FAILED,
-					   NEIGH_UPDATE_F_OVERRIDE|
-					   NEIGH_UPDATE_F_ADMIN);
-		neigh_release(neigh);
-	}
-	return err;
+	return arp_invalidate(dev, ip);
 }
 
 /*





^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
  2011-01-08 23:57       ` Maxim Levitsky
@ 2011-01-11  0:11         ` David Miller
  0 siblings, 0 replies; 32+ messages in thread
From: David Miller @ 2011-01-11  0:11 UTC (permalink / raw)
  To: maximlevitsky
  Cc: eric.dumazet, linux1394-devel, stefanr, netdev, kuznet, jmorris, kaber

From: Maxim Levitsky <maximlevitsky@gmail.com>
Date: Sun, 09 Jan 2011 01:57:12 +0200

>     NET: IPV4: ARP: allow to invalidate specific ARP entries
>     
>     IPv4 over firewire needs to be able to remove ARP entries
>     from the ARP cache that belong to nodes that are removed, because
>     IPv4 over firewire uses ARP packets for private information
>     about nodes.
>     
>     This information becomes invalid as soon as node drops
>     off the bus and when it reconnects, its only possible
>     to start takling to is after it responded to an ARP packet.
>     But ARP cache prevents such packets from being sent.
>     
>     Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>

Applied, thanks.

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2011-01-11  0:10 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-29  2:09 [PATCH 0/5 V2] Firewire networking assorted fixes Maxim Levitsky
2010-11-29  2:09 ` [PATCH 1/5] firewire: ohci: restore GUID on resume Maxim Levitsky
2010-11-29  2:09 ` [PATCH 2/5] firewire: ohci: restart ISO DMA contexts on resume from low power mode Maxim Levitsky
2010-11-29  2:09 ` [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries Maxim Levitsky
2010-12-04 23:15   ` Maxim Levitsky
2010-12-05  8:19     ` Eric Dumazet
2010-12-05 11:23       ` [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() Eric Dumazet
2010-12-05 12:03         ` [PATCH net-2.6] llc: fix a device refcount imbalance Eric Dumazet
2010-12-08 17:59           ` David Miller
2010-12-09  3:46             ` Maxim Levitsky
2010-12-16 21:49               ` Maxim Levitsky
2010-12-08 18:05         ` [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl() David Miller
2010-12-08 18:07           ` Eric Dumazet
2010-12-08 18:10             ` David Miller
2010-12-08 18:11               ` Eric Dumazet
2011-01-07 12:47   ` [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries Maxim Levitsky
2011-01-07 12:57     ` Eric Dumazet
2011-01-07 13:15       ` Maxim Levitsky
2011-01-08 23:57       ` Maxim Levitsky
2011-01-11  0:11         ` David Miller
2010-11-29  2:09 ` [PATCH 4/5] firewire: net: invalidate ARP entries of removed nodes Maxim Levitsky
2010-11-29  2:09 ` [PATCH 5/5] firewire: net: ratelimit error messages Maxim Levitsky
2010-11-29 15:02 ` [PATCH 0/5 V2] Firewire networking assorted fixes Stefan Richter
2010-12-04 23:14 ` Maxim Levitsky
2010-12-08  3:32 ` Maxim Levitsky
2010-12-09  1:42   ` Maxim Levitsky
     [not found]   ` <20101208040559.20639.qmail@stuge.se>
     [not found]     ` <1291809485.5421.0.camel@maxim-laptop>
2010-12-12 17:09       ` [PATCH update] firewire: net: add carrier detection Stefan Richter
2010-12-12 23:05         ` Ben Hutchings
2010-12-13  0:46           ` [PATCH update 2] " Stefan Richter
2010-12-13 23:01             ` [PATCH update 3] " Stefan Richter
2010-12-14 23:46               ` Maxim Levitsky
2010-12-16  1:17               ` Dan Williams

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.