* [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
* 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 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-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
* 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] 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 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
* [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 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 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
[parent not found: <20101208040559.20639.qmail@stuge.se>]
[parent not found: <1291809485.5421.0.camel@maxim-laptop>]
* [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
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 a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).