* [RFC PATCH 0/6] IPv6 over Firewire (PoC)
From: YOSHIFUJI Hideaki @ 2013-01-12 14:20 UTC (permalink / raw)
To: Stephan Gatzka, Stefan Richter; +Cc: netdev, linux1394-devel, yoshfuji
This is my proof of concept changes over the tree.
Code compiles, but untested.
Full changesets are also availble at:
http://www.linux-ipv6.org/gitweb/gitweb.cgi?p=gitroot/yoshfuji/linux-2.6-dev.git;a=shortlog;h=refs/heads/v3.7%2Bnet-next%2Bfirewire
I think firewire/net bits should be moved to firewire/net_core.c or something,
which is compiled statically even if FIREWIRE_NET = m.
YOSHIFUJI Hideaki (6):
ndisc: Move ndisc_opt_addr_space() to include/net/ndisc.h.
ndisc: Pass net_device to ndisc_fill_addr_option().
firewire net: Export fwnet_peerinfo structure for ieee1394-specific
peer information in ARP/NDP.
firewire net: Export peerinfo handlers.
firewire net: IPv6 support (RFC3146).
ipv6: IPv6 over IEEE1394 (RFC3146) support.
drivers/firewire/Kconfig | 8 +++
drivers/firewire/net.c | 125 ++++++++++++++++++++++++++++------------------
include/net/firewire.h | 21 ++++++++
include/net/ndisc.h | 20 +++++++-
net/ipv6/addrconf.c | 4 +-
net/ipv6/ndisc.c | 71 +++++++++++++++++++++-----
net/ipv6/route.c | 2 +
7 files changed, 188 insertions(+), 63 deletions(-)
create mode 100644 include/net/firewire.h
--
1.7.9.5
^ permalink raw reply
* [RFC PATCH 1/6] ndisc: Move ndisc_opt_addr_space() to include/net/ndisc.h.
From: YOSHIFUJI Hideaki @ 2013-01-12 14:21 UTC (permalink / raw)
To: Stephan Gatzka, Stefan Richter; +Cc: netdev, linux1394-devel, yoshfuji
ndisc_opt_addr_data() should use ndisc_opt_addr_space() and
centralizes calcuation of address space.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
include/net/ndisc.h | 8 +++++++-
net/ipv6/ndisc.c | 5 -----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 23b3a7c..3c53257 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -127,13 +127,19 @@ static int ndisc_addr_option_pad(unsigned short type)
}
}
+static inline int ndisc_opt_addr_space(struct net_device *dev)
+{
+ return NDISC_OPT_SPACE(dev->addr_len +
+ ndisc_addr_option_pad(dev->type));
+}
+
static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
struct net_device *dev)
{
u8 *lladdr = (u8 *)(p + 1);
int lladdrlen = p->nd_opt_len << 3;
int prepad = ndisc_addr_option_pad(dev->type);
- if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad))
+ if (lladdrlen != ndisc_opt_addr_space(dev))
return NULL;
return lladdr + prepad;
}
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 5733cd2..80c077c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -143,11 +143,6 @@ struct neigh_table nd_tbl = {
.gc_thresh3 = 1024,
};
-static inline int ndisc_opt_addr_space(struct net_device *dev)
-{
- return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
-}
-
static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
unsigned short addr_type)
{
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 2/6] ndisc: Pass net_device to ndisc_fill_addr_option().
From: YOSHIFUJI Hideaki @ 2013-01-12 14:21 UTC (permalink / raw)
To: Stephan Gatzka, Stefan Richter; +Cc: netdev, linux1394-devel, yoshfuji
In addition to reduction of number of arguments, this will be
used by upcoming IEEE1394 code.
CC: Stephan Gatzka <stephan.gatzka@gmail.com>
CC: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 80c077c..99cd286 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -143,10 +143,11 @@ struct neigh_table nd_tbl = {
.gc_thresh3 = 1024,
};
-static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
- unsigned short addr_type)
+static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
+ struct net_device *dev)
{
- int pad = ndisc_addr_option_pad(addr_type);
+ int pad = ndisc_addr_option_pad(dev->type);
+ int data_len = dev->addr_len;
int space = NDISC_OPT_SPACE(data_len + pad);
opt[0] = type;
@@ -415,8 +416,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
}
if (llinfo)
- ndisc_fill_addr_option(opt, llinfo, dev->dev_addr,
- dev->addr_len, dev->type);
+ ndisc_fill_addr_option(opt, llinfo, dev->dev_addr, dev);
hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len,
IPPROTO_ICMPV6,
@@ -1469,7 +1469,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
if (ha)
opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha,
- dev->addr_len, dev->type);
+ dev);
/*
* build redirect option and copy skb over to the new packet.
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 3/6] firewire net: Export fwnet_peerinfo structure for ieee1394-specific peer information in ARP/NDP.
From: YOSHIFUJI Hideaki @ 2013-01-12 14:21 UTC (permalink / raw)
To: Stephan Gatzka, Stefan Richter; +Cc: netdev, linux1394-devel, yoshfuji
Peer information consists of max_rec, spd and unicast_FIFO and
the wire format is shared between IPv4 (RFC2734) and IPv6 (RFC3146).
CC: Stephan Gatzka <stephan.gatzka@gmail.com>
CC: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
drivers/firewire/net.c | 24 ++++++++++++------------
include/net/firewire.h | 11 +++++++++++
2 files changed, 23 insertions(+), 12 deletions(-)
create mode 100644 include/net/firewire.h
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index e7a711f5..bd2d0de 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -28,6 +28,7 @@
#include <asm/unaligned.h>
#include <net/arp.h>
+#include <net/firewire.h>
/* rx limits */
#define FWNET_MAX_FRAGMENTS 30 /* arbitrary, > TX queue depth */
@@ -68,10 +69,8 @@ struct rfc2734_arp {
/* Above is exactly the same format as struct arphdr */
__be64 s_uniq_id; /* Sender's 64bit EUI */
- u8 max_rec; /* Sender's max packet size */
- u8 sspd; /* Sender's max speed */
- __be16 fifo_hi; /* hi 16bits of sender's FIFO addr */
- __be32 fifo_lo; /* lo 32bits of sender's FIFO addr */
+ struct fwnet_peerinfo info;
+
__be32 sip; /* Sender's IP Address */
__be32 tip; /* IP Address of requested hw addr */
} __packed;
@@ -547,17 +546,18 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
arp1394 = (struct rfc2734_arp *)skb->data;
arp = (struct arphdr *)skb->data;
arp_ptr = (unsigned char *)(arp + 1);
+
peer_guid = get_unaligned_be64(&arp1394->s_uniq_id);
- fifo_addr = (u64)get_unaligned_be16(&arp1394->fifo_hi) << 32
- | get_unaligned_be32(&arp1394->fifo_lo);
+ fifo_addr = (u64)get_unaligned_be16(&arp1394->info.fifo_hi) << 32
+ | get_unaligned_be32(&arp1394->info.fifo_lo);
- sspd = arp1394->sspd;
+ sspd = arp1394->info.sspd;
/* Sanity check. OS X 10.3 PPC reportedly sends 131. */
if (sspd > SCODE_3200) {
dev_notice(&net->dev, "sspd %x out of range\n", sspd);
sspd = SCODE_3200;
}
- max_payload = fwnet_max_payload(arp1394->max_rec, sspd);
+ max_payload = fwnet_max_payload(arp1394->info.max_rec, sspd);
spin_lock_irqsave(&dev->lock, flags);
peer = fwnet_peer_find_by_guid(dev, peer_guid);
@@ -1348,13 +1348,13 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
ipaddr = get_unaligned((__be32 *)(arp_ptr + FWNET_ALEN));
arp1394->hw_addr_len = RFC2734_HW_ADDR_LEN;
- arp1394->max_rec = dev->card->max_receive;
- arp1394->sspd = dev->card->link_speed;
+ arp1394->info.max_rec = dev->card->max_receive;
+ arp1394->info.sspd = dev->card->link_speed;
put_unaligned_be16(dev->local_fifo >> 32,
- &arp1394->fifo_hi);
+ &arp1394->info.fifo_hi);
put_unaligned_be32(dev->local_fifo & 0xffffffff,
- &arp1394->fifo_lo);
+ &arp1394->info.fifo_lo);
put_unaligned(ipaddr, &arp1394->sip);
}
diff --git a/include/net/firewire.h b/include/net/firewire.h
new file mode 100644
index 0000000..5e12b52
--- /dev/null
+++ b/include/net/firewire.h
@@ -0,0 +1,11 @@
+#ifndef _NET_FIREWIRE_H
+#define _NET_FIREWIRE_H
+
+struct fwnet_peerinfo {
+ u8 max_rec; /* Sender's max packet size */
+ u8 sspd; /* Sender's max speed */
+ __be16 fifo_hi; /* hi 16bits of sender's FIFO addr */
+ __be32 fifo_lo; /* lo 32bits of sender's FIFO addr */
+} __packed;
+
+#endif
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 4/6] firewire net: Export peerinfo handlers.
From: YOSHIFUJI Hideaki @ 2013-01-12 14:21 UTC (permalink / raw)
To: Stephan Gatzka, Stefan Richter; +Cc: netdev, linux1394-devel, yoshfuji
Extract peerinfo related code into separate functions and export them.
CC: Stephan Gatzka <stephan.gatzka@gmail.com>
CC: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
drivers/firewire/net.c | 106 ++++++++++++++++++++++++++++--------------------
include/net/firewire.h | 10 +++++
2 files changed, 73 insertions(+), 43 deletions(-)
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index bd2d0de..66c4f1c 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -506,6 +506,50 @@ static unsigned fwnet_max_payload(unsigned max_rec, unsigned speed)
return (1 << (max_rec + 1)) - RFC2374_FRAG_HDR_SIZE;
}
+struct fwnet_peer *fwnet_update_peerinfo(struct net_device *net,
+ __be64 *s_uniq_id,
+ const struct fwnet_peerinfo *info)
+{
+ struct fwnet_device *dev = netdev_priv(net);
+ u64 peer_guid;
+ u64 fifo_addr;
+ unsigned sspd;
+ u16 max_payload;
+ unsigned long flags;
+ struct fwnet_peer *peer;
+
+ peer_guid = get_unaligned_be64(s_uniq_id);
+ fifo_addr = (u64)get_unaligned_be16(&info->fifo_hi) << 32
+ | get_unaligned_be32(&info->fifo_lo);
+
+ sspd = info->sspd;
+ /* Sanity check. OS X 10.3 PPC reportedly sends 131. */
+ if (sspd > SCODE_3200) {
+ dev_notice(&net->dev, "sspd %x out of range\n", sspd);
+ sspd = SCODE_3200;
+ }
+ max_payload = fwnet_max_payload(info->max_rec, sspd);
+
+ spin_lock_irqsave(&dev->lock, flags);
+ peer = fwnet_peer_find_by_guid(dev, peer_guid);
+ if (peer) {
+ peer->fifo = fifo_addr;
+
+ if (peer->speed > sspd)
+ peer->speed = sspd;
+ if (peer->max_payload > max_payload)
+ peer->max_payload = max_payload;
+ }
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ if (!peer)
+ dev_notice(&net->dev,
+ "no peer for ARP packet from %016llx\n",
+ (unsigned long long)peer_guid);
+
+ return peer;
+}
+EXPORT_SYMBOL(fwnet_update_peerinfo);
static int fwnet_finish_incoming_packet(struct net_device *net,
struct sk_buff *skb, u16 source_node_id,
@@ -536,49 +580,16 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
struct rfc2734_arp *arp1394;
struct arphdr *arp;
unsigned char *arp_ptr;
- u64 fifo_addr;
- u64 peer_guid;
- unsigned sspd;
- u16 max_payload;
struct fwnet_peer *peer;
- unsigned long flags;
arp1394 = (struct rfc2734_arp *)skb->data;
arp = (struct arphdr *)skb->data;
arp_ptr = (unsigned char *)(arp + 1);
- peer_guid = get_unaligned_be64(&arp1394->s_uniq_id);
- fifo_addr = (u64)get_unaligned_be16(&arp1394->info.fifo_hi) << 32
- | get_unaligned_be32(&arp1394->info.fifo_lo);
-
- sspd = arp1394->info.sspd;
- /* Sanity check. OS X 10.3 PPC reportedly sends 131. */
- if (sspd > SCODE_3200) {
- dev_notice(&net->dev, "sspd %x out of range\n", sspd);
- sspd = SCODE_3200;
- }
- max_payload = fwnet_max_payload(arp1394->info.max_rec, sspd);
-
- spin_lock_irqsave(&dev->lock, flags);
- peer = fwnet_peer_find_by_guid(dev, peer_guid);
- if (peer) {
- peer->fifo = fifo_addr;
-
- if (peer->speed > sspd)
- peer->speed = sspd;
- if (peer->max_payload > max_payload)
- peer->max_payload = max_payload;
-
- peer->ip = arp1394->sip;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- if (!peer) {
- dev_notice(&net->dev,
- "no peer for ARP packet from %016llx\n",
- (unsigned long long)peer_guid);
+ peer = fwnet_update_peerinfo(net, &arp1394->s_uniq_id, &arp1394->info);
+ if (!peer)
goto no_peer;
- }
+ peer->ip = arp1394->sip;
/*
* Now that we're done with the 1394 specific stuff, we'll
@@ -1264,6 +1275,19 @@ static int fwnet_stop(struct net_device *net)
return 0;
}
+void fwnet_fill_peerinfo(const struct net_device *net, const __be64 *s_uniq_id,
+ struct fwnet_peerinfo *info)
+{
+ struct fwnet_device *dev = netdev_priv(net);
+
+ info->max_rec = dev->card->max_receive;
+ info->sspd = dev->card->link_speed;
+
+ put_unaligned_be16(dev->local_fifo >> 32, &info->fifo_hi);
+ put_unaligned_be32(dev->local_fifo & 0xffffffff, &info->fifo_lo);
+}
+EXPORT_SYMBOL(fwnet_fill_peerinfo);
+
static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
{
struct fwnet_header hdr_buf;
@@ -1347,14 +1371,10 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
ipaddr = get_unaligned((__be32 *)(arp_ptr + FWNET_ALEN));
- arp1394->hw_addr_len = RFC2734_HW_ADDR_LEN;
- arp1394->info.max_rec = dev->card->max_receive;
- arp1394->info.sspd = dev->card->link_speed;
+ arp1394->hw_addr_len = RFC2734_HW_ADDR_LEN;
+
+ fwnet_fill_peerinfo(net, NULL, &arp1394->info);
- put_unaligned_be16(dev->local_fifo >> 32,
- &arp1394->info.fifo_hi);
- put_unaligned_be32(dev->local_fifo & 0xffffffff,
- &arp1394->info.fifo_lo);
put_unaligned(ipaddr, &arp1394->sip);
}
diff --git a/include/net/firewire.h b/include/net/firewire.h
index 5e12b52..6f746d1 100644
--- a/include/net/firewire.h
+++ b/include/net/firewire.h
@@ -8,4 +8,14 @@ struct fwnet_peerinfo {
__be32 fifo_lo; /* lo 32bits of sender's FIFO addr */
} __packed;
+struct fwnet_peer;
+
+extern struct fwnet_peer *fwnet_update_peerinfo(struct net_device *net,
+ __be64 *s_uniq_id,
+ const struct fwnet_peerinfo *info);
+
+extern void fwnet_fill_peerinfo(const struct net_device *net,
+ const __be64 *s_uniq_id,
+ struct fwnet_peerinfo *info);
+
#endif
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: YOSHIFUJI Hideaki @ 2013-01-12 14:21 UTC (permalink / raw)
To: Stephan Gatzka, Stefan Richter; +Cc: netdev, linux1394-devel, yoshfuji
Send packets for IPv6 multicast via GASP.
CC: Stephan Gatzka <stephan.gatzka@gmail.com>
CC: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
drivers/firewire/Kconfig | 8 ++++++++
drivers/firewire/net.c | 13 ++++++++++---
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index 7224533..2e3018b 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -51,9 +51,17 @@ config FIREWIRE_NET
other implementations of RFC 2734 as found on several operating
systems. Multicast support is currently limited.
+ Optional IPv6 support is available if you say Y here.
+
To compile this driver as a module, say M here: The module will be
called firewire-net.
+config FIREWIRE_NET_IPV6
+ bool "IPv6 networking over 1394"
+ depends on FIREWIRE_NET=y
+ help
+ This enabless IPv6 over IEEE 1394, based on RFC 3146.
+
config FIREWIRE_NOSY
tristate "Nosy - a FireWire traffic sniffer for PCILynx cards"
depends on PCI
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 66c4f1c..a21d2f9 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -27,6 +27,8 @@
#include <linux/spinlock.h>
#include <asm/unaligned.h>
+#include <linux/ipv6.h>
+#include <net/addrconf.h>
#include <net/arp.h>
#include <net/firewire.h>
@@ -1329,13 +1331,18 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
dg_size = skb->len;
/*
- * Set the transmission type for the packet. ARP packets and IP
- * broadcast packets are sent via GASP.
+ * Set the transmission type for the packet. ARP packets, IPv4
+ * broadcast packets, IPv6 multicast packets are sent via GASP.
*/
if (memcmp(hdr_buf.h_dest, net->broadcast, FWNET_ALEN) == 0
|| proto == htons(ETH_P_ARP)
|| (proto == htons(ETH_P_IP)
- && IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) {
+ && IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))
+#if defined(CONFIG_FIREWIRE_NET_IPV6)
+ || (proto == htons(ETH_P_IPV6)
+ && ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))
+#endif
+ ) {
max_payload = dev->broadcast_xmt_max_payload;
datagram_label_ptr = &dev->broadcast_xmt_datagramlabel;
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: YOSHIFUJI Hideaki @ 2013-01-12 14:21 UTC (permalink / raw)
To: Stephan Gatzka, Stefan Richter; +Cc: netdev, linux1394-devel, yoshfuji
CC: Stephan Gatzka <stephan.gatzka@gmail.com>
CC: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
include/net/ndisc.h | 14 +++++++++++-
net/ipv6/addrconf.c | 4 +++-
net/ipv6/ndisc.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++----
net/ipv6/route.c | 2 ++
4 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 3c53257..1de4e0c 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -52,6 +52,7 @@ enum {
#include <linux/hash.h>
#include <net/neighbour.h>
+#include <net/firewire.h>
struct ctl_table;
struct inet6_dev;
@@ -127,10 +128,19 @@ static int ndisc_addr_option_pad(unsigned short type)
}
}
+static int ndisc_addr_option_postpad(unsigned short type)
+{
+ switch (type) {
+ case ARPHRD_IEEE1394: return sizeof(struct fwnet_peerinfo);
+ default: return 0;
+ }
+}
+
static inline int ndisc_opt_addr_space(struct net_device *dev)
{
return NDISC_OPT_SPACE(dev->addr_len +
- ndisc_addr_option_pad(dev->type));
+ ndisc_addr_option_pad(dev->type) +
+ ndisc_addr_option_postpad(dev->type));
}
static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
@@ -203,6 +213,8 @@ extern void ndisc_send_redirect(struct sk_buff *skb,
extern int ndisc_mc_map(const struct in6_addr *addr, char *buf,
struct net_device *dev, int dir);
+extern void ndisc_update_peerinfo(struct net_device *dev,
+ void *lladdr);
/*
* IGMP
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 408cac4a..9a0728a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1729,6 +1729,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
case ARPHRD_IPGRE:
return addrconf_ifid_gre(eui, dev);
case ARPHRD_IEEE802154:
+ case ARPHRD_IEEE1394:
return addrconf_ifid_eui64(eui, dev);
}
return -1;
@@ -2571,7 +2572,8 @@ static void addrconf_dev_config(struct net_device *dev)
(dev->type != ARPHRD_FDDI) &&
(dev->type != ARPHRD_ARCNET) &&
(dev->type != ARPHRD_INFINIBAND) &&
- (dev->type != ARPHRD_IEEE802154)) {
+ (dev->type != ARPHRD_IEEE802154) &&
+ (dev->type != ARPHRD_IEEE1394)) {
/* Alas, we support only Ethernet autoconfiguration. */
return;
}
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 99cd286..9a0ba9c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -72,6 +72,8 @@
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
+#include <net/firewire.h>
+
/* Set to 3 to get tracing... */
#define ND_DEBUG 1
@@ -143,6 +145,22 @@ struct neigh_table nd_tbl = {
.gc_thresh3 = 1024,
};
+#if defined(CONFIG_FIREWIRE_NET)
+static u8 *__ndisc_fill_addr_option_firewire_postpad(u8 *opt, int space, void *data,
+ struct net_device *dev)
+{
+ if (likely(space >= sizeof(struct fwnet_peerinfo))) {
+ fwnet_fill_peerinfo(dev, (__be64 *)data, (struct fwnet_peerinfo *)opt);
+ opt += sizeof(struct fwnet_peerinfo);
+ space -= sizeof(struct fwnet_peerinfo);
+ }
+ if (space > 0)
+ memset(opt, 0, space);
+
+ return opt + space;
+}
+#endif
+
static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
struct net_device *dev)
{
@@ -160,9 +178,20 @@ static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
memcpy(opt+2, data, data_len);
data_len += 2;
opt += data_len;
- if ((space -= data_len) > 0)
- memset(opt, 0, space);
- return opt + space;
+
+ if ((space -= data_len) > 0) {
+ switch (dev->type) {
+#if defined(CONFIG_FIREWIRE_NET)
+ case ARPHRD_IEEE1394:
+ opt = __ndisc_fill_addr_option_firewire_postpad(opt, space,
+ data, dev);
+#endif
+ default:
+ memset(opt, 0, space);
+ opt += space;
+ }
+ }
+ return opt;
}
static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
@@ -366,6 +395,19 @@ static void pndisc_destructor(struct pneigh_entry *n)
ipv6_dev_mc_dec(dev, &maddr);
}
+void ndisc_update_peerinfo(struct net_device *dev, void *lladdr)
+{
+#if defined(CONFIG_FIREWIRE_NET)
+ switch (dev->type) {
+ case ARPHRD_IEEE1394:
+ fwnet_update_peerinfo(dev, lladdr, (struct fwnet_peerinfo *)((__u64 *)lladdr + 1));
+ break;
+ default:
+ break;
+ }
+#endif
+}
+
static struct sk_buff *ndisc_build_skb(struct net_device *dev,
const struct in6_addr *daddr,
const struct in6_addr *saddr,
@@ -798,6 +840,9 @@ static void ndisc_recv_ns(struct sk_buff *skb)
neigh_update(neigh, lladdr, NUD_STALE,
NEIGH_UPDATE_F_WEAK_OVERRIDE|
NEIGH_UPDATE_F_OVERRIDE);
+
+ ndisc_update_peerinfo(dev, lladdr);
+
if (neigh || !dev->header_ops) {
ndisc_send_na(dev, neigh, saddr, &msg->target,
is_router,
@@ -905,6 +950,8 @@ static void ndisc_recv_na(struct sk_buff *skb)
NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
(msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0));
+ ndisc_update_peerinfo(dev, lladdr);
+
if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
/*
* Change: router to host
@@ -970,6 +1017,8 @@ static void ndisc_recv_rs(struct sk_buff *skb)
NEIGH_UPDATE_F_OVERRIDE|
NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
neigh_release(neigh);
+
+ ndisc_update_peerinfo(skb->dev, lladdr);
}
out:
return;
@@ -1223,6 +1272,8 @@ skip_linkparms:
NEIGH_UPDATE_F_OVERRIDE|
NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
NEIGH_UPDATE_F_ISROUTER);
+
+ ndisc_update_peerinfo(skb->dev, lladdr);
}
if (!ipv6_accept_ra(in6_dev))
@@ -1405,7 +1456,8 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
if (!ret)
goto release;
- if (dev->addr_len) {
+ /* XXX* We have not idea about IEEE1394 peer infomation */
+ if (dev->addr_len && dev->type != ARPHRD_IEEE1394) {
struct neighbour *neigh = dst_neigh_lookup(skb_dst(skb), target);
if (!neigh) {
ND_PRINTK(2, warn,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 621b68e..27c5127 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1795,6 +1795,8 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
NEIGH_UPDATE_F_ISROUTER))
);
+ ndisc_update_peerinfo(skb->dev, lladdr);
+
nrt = ip6_rt_copy(rt, &msg->dest);
if (!nrt)
goto out;
--
1.7.9.5
^ permalink raw reply related
* Re: IPv6 over firewire
From: Stefan Richter @ 2013-01-12 14:37 UTC (permalink / raw)
To: stephan.gatzka; +Cc: linux1394-devel, yoshfuji, netdev
In-Reply-To: <50F140F7.60503@gmail.com>
On Jan 12 Stephan Gatzka wrote:
> > Or the (optional!) callback could be a new member of struct ndisc_options.
>
> Hm, right now I have no opinion on that. Where does
> whatever_type *callback comes from? Is it an exported method of the
> firewire net driver or the new function pointer in struct netdevice?
The networking core or IPv6 core would never ever use an EXPORT() from an
interface driver like firewire-net or from a bus architecture driver like
firewire-core.
The interface driver uses definitions and declarations from the networking/
IP/ ARP... core:
- functions implemented in the core and EXPORTed from there,
- data types defined in core headers and filled with data by the
interface driver,
- callback function types defined in core headers, used in data types
which are defined in core headers; respective callbacks implemented in
interface drivers, pointers to the implementations filled in by the
interface drivers into respective data objects.
So the firewire-net bridge driver uses the firewire-core API below it and
the networking and IP APIs above it.
Whether a callback is needed at all is not obvious to me. If one is
needed, then it is not obvious to me whether it should be reachable via a
function pointer in struct net_device, or via a function pointer in one of
the pointer table structs that are appended to struct net_device, or via a
function pointer in e.g. struct ndisc_options, or via a function pointer
typed argument of a function which is EXPORTed by the networking/ IPv6
core.
> > However, does net/ipv6/ndisc.c really need to be aware of the RFC 3146
> > Neighbor Discovery related packet header layouts? Isn't it possible to
> > rewrite these headers in-place in drivers/firewire/net.c?
>
>
> Yes, it it possible, but yoshfuji strongly voted against rewriting ndisc
> packets in firewire net driver to maintain extensibility to protocols.
> Especially IPSEC can just not work if I rewrite the packets in the driver.
OK, then net/ipv6/ndisc.c shall be taught to write (and read?) those
packets, and drivers/firewire/net.c shall fill in all data that are going
to be needed by ndisc.c into new arguments of existing or new exported
core functions, or into new members of whichever networking struct
would be most suitable for that. Or the networking core gets to those
data indirectly by calling a callback.
Apparently the Linux IPv6 core needs to learn a little bit about RFC 3146.
But it doesn't need to (and should not) learn anything about the Linux
IEEE 1394 implementation, that's what I am trying to convey. :-)
--
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
^ permalink raw reply
* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: Stephan Gatzka @ 2013-01-12 14:40 UTC (permalink / raw)
To: YOSHIFUJI Hideaki; +Cc: Stefan Richter, netdev, linux1394-devel
In-Reply-To: <50F17178.3090705@linux-ipv6.org>
That looks good to me and is more or less exactly I wanted to do.
> diff --git a/include/net/ndisc.h b/include/net/ndisc.h
> index 3c53257..1de4e0c 100644
> --- a/include/net/ndisc.h
> +++ b/include/net/ndisc.h
> @@ -52,6 +52,7 @@ enum {
> #include <linux/hash.h>
>
> #include <net/neighbour.h>
> +#include <net/firewire.h>
-- snip --
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index 99cd286..9a0ba9c 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -72,6 +72,8 @@
> #include <linux/netfilter.h>
> #include <linux/netfilter_ipv6.h>
>
> +#include <net/firewire.h>
-- snip --
But now we have to include firewire.h in the ndisc code. The advantage
is that we the firewire_net structure is now private.
Regards,
Stephan
^ permalink raw reply
* Re: IPv6 over firewire
From: Stephan Gatzka @ 2013-01-12 14:42 UTC (permalink / raw)
To: Stefan Richter; +Cc: linux1394-devel, yoshfuji, netdev
In-Reply-To: <20130112153755.3fd96d58@stein>
> Apparently the Linux IPv6 core needs to learn a little bit about RFC 3146.
> But it doesn't need to (and should not) learn anything about the Linux
> IEEE 1394 implementation, that's what I am trying to convey. :-)
>
That is something I'm absolutely with you. :)
^ permalink raw reply
* Re: [RFC PATCH 3/6] firewire net: Export fwnet_peerinfo structure for ieee1394-specific peer information in ARP/NDP.
From: Stefan Richter @ 2013-01-12 14:59 UTC (permalink / raw)
To: YOSHIFUJI Hideaki; +Cc: Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <50F17162.4060005@linux-ipv6.org>
On Jan 12 YOSHIFUJI Hideaki wrote:
[...]
> --- /dev/null
> +++ b/include/net/firewire.h
> @@ -0,0 +1,11 @@
> +#ifndef _NET_FIREWIRE_H
> +#define _NET_FIREWIRE_H
> +
> +struct fwnet_peerinfo {
> + u8 max_rec; /* Sender's max packet size */
> + u8 sspd; /* Sender's max speed */
> + __be16 fifo_hi; /* hi 16bits of sender's FIFO addr */
> + __be32 fifo_lo; /* lo 32bits of sender's FIFO addr */
> +} __packed;
> +
> +#endif
If it is deemed necessary to put definitions of on-the-wire formats of the
RFC 2734 or RFC 3146 encapsulations into include/net/, then fine by me.
--
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
^ permalink raw reply
* Re: [RFC PATCH 4/6] firewire net: Export peerinfo handlers.
From: Stefan Richter @ 2013-01-12 15:01 UTC (permalink / raw)
To: YOSHIFUJI Hideaki; +Cc: Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <50F1716A.90401@linux-ipv6.org>
On Jan 12 YOSHIFUJI Hideaki wrote:
[...]
> --- a/drivers/firewire/net.c
> +++ b/drivers/firewire/net.c
[...]
> +EXPORT_SYMBOL(fwnet_update_peerinfo);
[...]
> +EXPORT_SYMBOL(fwnet_fill_peerinfo);
I disagree. drivers/firewire/net.c is no place for EXPORTs.
--
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
^ permalink raw reply
* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stefan Richter @ 2013-01-12 15:22 UTC (permalink / raw)
To: YOSHIFUJI Hideaki; +Cc: Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <50F17171.3050105@linux-ipv6.org>
On Jan 12 YOSHIFUJI Hideaki wrote:
> Send packets for IPv6 multicast via GASP.
>
> CC: Stephan Gatzka <stephan.gatzka@gmail.com>
> CC: Stefan Richter <stefanr@s5r6.in-berlin.de>
> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> ---
> drivers/firewire/Kconfig | 8 ++++++++
> drivers/firewire/net.c | 13 ++++++++++---
> 2 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
> index 7224533..2e3018b 100644
> --- a/drivers/firewire/Kconfig
> +++ b/drivers/firewire/Kconfig
> @@ -51,9 +51,17 @@ config FIREWIRE_NET
> other implementations of RFC 2734 as found on several operating
> systems. Multicast support is currently limited.
>
> + Optional IPv6 support is available if you say Y here.
> +
This is a bit premature. At least one thing which is still missing (also
missing in Stephan's patch from previous week) is the RFC 3146 clause 5
Configuration ROM entry.
> To compile this driver as a module, say M here: The module will be
> called firewire-net.
>
> +config FIREWIRE_NET_IPV6
> + bool "IPv6 networking over 1394"
> + depends on FIREWIRE_NET=y
> + help
> + This enabless IPv6 over IEEE 1394, based on RFC 3146.
> +
I would rather like this to be like an invisible option which is
automatically on if IPV6=y || (IPV6=m && FIREWIRE_NET=m), and off
otherwise.
Or, as alluded to in my other post, it is going to be written such that
- if IPV6=n, FIREWIRE_NET can be n, y, or m. RFC 3146 support won't be
built in in any case.
- If IPV6=y, FIREWIRE_NET can be n, y, or m. RFC 3146 support will be
built in.
- If IPV6=m, FIREWIRE_NET can be only n or m. RFC 3146 support will be
built in in the latter case.
> config FIREWIRE_NOSY
> tristate "Nosy - a FireWire traffic sniffer for PCILynx cards"
> depends on PCI
> diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
> index 66c4f1c..a21d2f9 100644
> --- a/drivers/firewire/net.c
> +++ b/drivers/firewire/net.c
> @@ -27,6 +27,8 @@
> #include <linux/spinlock.h>
>
> #include <asm/unaligned.h>
> +#include <linux/ipv6.h>
> +#include <net/addrconf.h>
> #include <net/arp.h>
> #include <net/firewire.h>
>
> @@ -1329,13 +1331,18 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
> dg_size = skb->len;
>
> /*
> - * Set the transmission type for the packet. ARP packets and IP
> - * broadcast packets are sent via GASP.
> + * Set the transmission type for the packet. ARP packets, IPv4
> + * broadcast packets, IPv6 multicast packets are sent via GASP.
> */
> if (memcmp(hdr_buf.h_dest, net->broadcast, FWNET_ALEN) == 0
> || proto == htons(ETH_P_ARP)
> || (proto == htons(ETH_P_IP)
> - && IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) {
> + && IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))
> +#if defined(CONFIG_FIREWIRE_NET_IPV6)
> + || (proto == htons(ETH_P_IPV6)
> + && ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))
> +#endif
> + ) {
> max_payload = dev->broadcast_xmt_max_payload;
> datagram_label_ptr = &dev->broadcast_xmt_datagramlabel;
>
This hunk is fine with me.
--
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
^ permalink raw reply
* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: Stefan Richter @ 2013-01-12 15:47 UTC (permalink / raw)
To: YOSHIFUJI Hideaki; +Cc: Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <50F17178.3090705@linux-ipv6.org>
On Jan 12 YOSHIFUJI Hideaki wrote:
> CC: Stephan Gatzka <stephan.gatzka@gmail.com>
> CC: Stefan Richter <stefanr@s5r6.in-berlin.de>
> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> ---
> include/net/ndisc.h | 14 +++++++++++-
> net/ipv6/addrconf.c | 4 +++-
> net/ipv6/ndisc.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++----
> net/ipv6/route.c | 2 ++
> 4 files changed, 74 insertions(+), 6 deletions(-)
>
> diff --git a/include/net/ndisc.h b/include/net/ndisc.h
> index 3c53257..1de4e0c 100644
> --- a/include/net/ndisc.h
> +++ b/include/net/ndisc.h
> @@ -52,6 +52,7 @@ enum {
> #include <linux/hash.h>
>
> #include <net/neighbour.h>
> +#include <net/firewire.h>
>
> struct ctl_table;
> struct inet6_dev;
> @@ -127,10 +128,19 @@ static int ndisc_addr_option_pad(unsigned short type)
> }
> }
>
> +static int ndisc_addr_option_postpad(unsigned short type)
> +{
> + switch (type) {
> + case ARPHRD_IEEE1394: return sizeof(struct fwnet_peerinfo);
> + default: return 0;
> + }
> +}
> +
> static inline int ndisc_opt_addr_space(struct net_device *dev)
> {
> return NDISC_OPT_SPACE(dev->addr_len +
> - ndisc_addr_option_pad(dev->type));
> + ndisc_addr_option_pad(dev->type) +
> + ndisc_addr_option_postpad(dev->type));
> }
>
> static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
> @@ -203,6 +213,8 @@ extern void ndisc_send_redirect(struct sk_buff *skb,
> extern int ndisc_mc_map(const struct in6_addr *addr, char *buf,
> struct net_device *dev, int dir);
>
> +extern void ndisc_update_peerinfo(struct net_device *dev,
> + void *lladdr);
>
> /*
> * IGMP
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 408cac4a..9a0728a 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -1729,6 +1729,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
> case ARPHRD_IPGRE:
> return addrconf_ifid_gre(eui, dev);
> case ARPHRD_IEEE802154:
> + case ARPHRD_IEEE1394:
> return addrconf_ifid_eui64(eui, dev);
> }
> return -1;
> @@ -2571,7 +2572,8 @@ static void addrconf_dev_config(struct net_device *dev)
> (dev->type != ARPHRD_FDDI) &&
> (dev->type != ARPHRD_ARCNET) &&
> (dev->type != ARPHRD_INFINIBAND) &&
> - (dev->type != ARPHRD_IEEE802154)) {
> + (dev->type != ARPHRD_IEEE802154) &&
> + (dev->type != ARPHRD_IEEE1394)) {
> /* Alas, we support only Ethernet autoconfiguration. */
> return;
> }
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index 99cd286..9a0ba9c 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -72,6 +72,8 @@
> #include <linux/netfilter.h>
> #include <linux/netfilter_ipv6.h>
>
> +#include <net/firewire.h>
> +
> /* Set to 3 to get tracing... */
> #define ND_DEBUG 1
>
> @@ -143,6 +145,22 @@ struct neigh_table nd_tbl = {
> .gc_thresh3 = 1024,
> };
>
> +#if defined(CONFIG_FIREWIRE_NET)
> +static u8 *__ndisc_fill_addr_option_firewire_postpad(u8 *opt, int space, void *data,
> + struct net_device *dev)
> +{
> + if (likely(space >= sizeof(struct fwnet_peerinfo))) {
> + fwnet_fill_peerinfo(dev, (__be64 *)data, (struct fwnet_peerinfo *)opt);
> + opt += sizeof(struct fwnet_peerinfo);
> + space -= sizeof(struct fwnet_peerinfo);
> + }
As noted, please do not add EXPORTs to drivers/firewire/net.c and call
those from net/ipv6/*.c or anywhere else.
Instead, let drivers/firewire/net.c provide a function pointer to
ndisc_build_skb() or, if possible, just let it provide a pointer to struct
fwnet_peerinfo source data to be copied here.
Whether the function pointer or the source data go via struct net_device
or some other struct or via an extended version of ndisc_build_skb() with
added arguments is something I can't decide, not having worked with the
networking code myself yet.
> + if (space > 0)
> + memset(opt, 0, space);
> +
> + return opt + space;
> +}
> +#endif
> +
> static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
> struct net_device *dev)
> {
> @@ -160,9 +178,20 @@ static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
> memcpy(opt+2, data, data_len);
> data_len += 2;
> opt += data_len;
> - if ((space -= data_len) > 0)
> - memset(opt, 0, space);
> - return opt + space;
> +
> + if ((space -= data_len) > 0) {
> + switch (dev->type) {
> +#if defined(CONFIG_FIREWIRE_NET)
> + case ARPHRD_IEEE1394:
> + opt = __ndisc_fill_addr_option_firewire_postpad(opt, space,
> + data, dev);
> +#endif
> + default:
> + memset(opt, 0, space);
> + opt += space;
> + }
> + }
> + return opt;
> }
>
> static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
> @@ -366,6 +395,19 @@ static void pndisc_destructor(struct pneigh_entry *n)
> ipv6_dev_mc_dec(dev, &maddr);
> }
>
> +void ndisc_update_peerinfo(struct net_device *dev, void *lladdr)
> +{
> +#if defined(CONFIG_FIREWIRE_NET)
> + switch (dev->type) {
> + case ARPHRD_IEEE1394:
> + fwnet_update_peerinfo(dev, lladdr, (struct fwnet_peerinfo *)((__u64 *)lladdr + 1));
> + break;
> + default:
> + break;
> + }
> +#endif
[...]
Dito, please do not solve this with an EXPORT from drivers/firewire/net.c.
Either a new driver callback is required, and the function pointer to this
callback needs to be reachable indirectly via the skb pointer.
Or drivers/firewire/net.c needs to be aware that it just received an NDP
packet, and then call a parser function in net/ipv6/ndisc.c which returns
the data that drivers/firewire/net.c wants to know.
--
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
^ permalink raw reply
* Re: [net-next] gianfar: use more portable i/o accessors
From: Richard Cochran @ 2013-01-12 15:57 UTC (permalink / raw)
To: Tabi Timur-B04825
Cc: Phillips Kim-R1AAHA, netdev@vger.kernel.org, David S. Miller
In-Reply-To: <6AE080B68D46FC4BA2D2769E68D765B70820D753@039-SN2MPN1-023.039d.mgd.msft.net>
On Sat, Jan 12, 2013 at 01:44:43PM +0000, Tabi Timur-B04825 wrote:
>
> Can't we just get rid of these functions altogether?
Since they are already in place, I would leave them there. Watching
the kernel development over time, every few years these IO access
idioms tend to change form, and having helper functions avoids huge
change sets when updating.
> Or at least, get
> rid of the local variable?
Okay, sure.
Thanks,
Richard
^ permalink raw reply
* RE: [PATCH net-next] be2net: fix unconditionally returning IRQ_HANDLED in INTx
From: Perla, Sathya @ 2013-01-12 16:29 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20130112.012146.1746775070657245621.davem@davemloft.net>
>-----Original Message-----
>From: David Miller [mailto:davem@davemloft.net]
>
>From: Sathya Perla <sathya.perla@emulex.com>
>Date: Sat, 12 Jan 2013 14:17:02 +0530
>
>> commit e49cc34f introduced an unconditional IRQ_HANDLED return in be_intx()
>> to workaround Lancer and BE2 HW issues. This is bad as it prevents the kernel
>> from detecting interrupt storms due to broken HW.
>>
...
>> Issue (1) can cause the notified events to be orphaned, if NAPI was already
>> running.
>> This patch fixes this issue by scheduling NAPI only if it is not scheduled
>> already. Doing this also takes care of possible events_get() race that may be
>> caused due to issue (2) and (3). Also, IRQ_HANDLED is returned only the first
>> time zero events are detected.
>> (Thanks Ben H. for the feedback and suggestions.)
>>
>> Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
>
>Any particular reason why we shouldn't put this fix into 'net' instead
>of 'net-next'?
Dave, this fix can surely go into "net" as the previous commit is already in Linus tree....
I guess I requested "net-next" just out of habit.
thanks,
-Sathya
^ permalink raw reply
* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stephan Gatzka @ 2013-01-12 16:31 UTC (permalink / raw)
To: Stefan Richter; +Cc: YOSHIFUJI Hideaki, netdev, linux1394-devel
In-Reply-To: <20130112162224.10e2aa44@stein>
> This is a bit premature. At least one thing which is still missing (also
> missing in Stephan's patch from previous week) is the RFC 3146 clause 5
> Configuration ROM entry.
Argh, my fault. I already had it when I began to implement this stuff.
It got lost somewhere...
No problem, I'll add it.
^ permalink raw reply
* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: Stephan Gatzka @ 2013-01-12 16:37 UTC (permalink / raw)
To: Stefan Richter; +Cc: YOSHIFUJI Hideaki, netdev, linux1394-devel
In-Reply-To: <20130112164741.1a0ab7bb@stein>
> Dito, please do not solve this with an EXPORT from drivers/firewire/net.c.
Again, I totally agree from the architectural point of view.
>
> Either a new driver callback is required, and the function pointer to this
> callback needs to be reachable indirectly via the skb pointer.
How I understand the whole ndisc code, ndisc just copes with struct
net_devices. So to break the dependency to the firewire net driver an
optional callback routine in struct net_device might be the easiest way.
> Or drivers/firewire/net.c needs to be aware that it just received an NDP
> packet, and then call a parser function in net/ipv6/ndisc.c which returns
> the data that drivers/firewire/net.c wants to know.
I think that is definitely to late. All cryptographic stuff (IPSEC) will
be done and I don't think we want to recalculate that afterwards.
^ permalink raw reply
* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: YOSHIFUJI Hideaki @ 2013-01-12 16:39 UTC (permalink / raw)
To: Stefan Richter; +Cc: Stephan Gatzka, netdev, linux1394-devel, YOSHIFUJI Hideaki
In-Reply-To: <20130112164741.1a0ab7bb@stein>
Stefan Richter wrote:
> On Jan 12 YOSHIFUJI Hideaki wrote:
>> static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
>> @@ -366,6 +395,19 @@ static void pndisc_destructor(struct pneigh_entry *n)
>> ipv6_dev_mc_dec(dev, &maddr);
>> }
>>
>> +void ndisc_update_peerinfo(struct net_device *dev, void *lladdr)
>> +{
>> +#if defined(CONFIG_FIREWIRE_NET)
>> + switch (dev->type) {
>> + case ARPHRD_IEEE1394:
>> + fwnet_update_peerinfo(dev, lladdr, (struct fwnet_peerinfo *)((__u64 *)lladdr + 1));
>> + break;
>> + default:
>> + break;
>> + }
>> +#endif
> [...]
>
> Dito, please do not solve this with an EXPORT from drivers/firewire/net.c.
>
> Either a new driver callback is required, and the function pointer to this
> callback needs to be reachable indirectly via the skb pointer.
>
> Or drivers/firewire/net.c needs to be aware that it just received an NDP
> packet, and then call a parser function in net/ipv6/ndisc.c which returns
> the data that drivers/firewire/net.c wants to know.
How about putting EUI64, maxrec, sspd and fifo in dev->dev_addr?
This enable us to send NDISC/ARP packet easily (based on neighbor
cache entry), and driver can be notified for new neighbors (thus
new peers). Driver can manage peer information based on this
notification.
Note that notification mechanism is used in Chelsio cxgbe4
driver, for example.
It requires some further modification to driver itself, but I
guess we do not need any exports with this, and I guess most
of most of arp related code can be removed from the driver.
--yoshfuji
^ permalink raw reply
* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: Stephan Gatzka @ 2013-01-12 16:44 UTC (permalink / raw)
To: YOSHIFUJI Hideaki; +Cc: Stefan Richter, netdev, linux1394-devel
In-Reply-To: <50F191CF.3060803@linux-ipv6.org>
> How about putting EUI64, maxrec, sspd and fifo in dev->dev_addr?
> This enable us to send NDISC/ARP packet easily (based on neighbor
> cache entry), and driver can be notified for new neighbors (thus
> new peers).
Hm, that looks a bit strange to me, because we need that only for link
layer option packets and not for every IPv6 packet transmitted via firewire.
^ permalink raw reply
* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stefan Richter @ 2013-01-12 17:00 UTC (permalink / raw)
To: Stefan Richter; +Cc: YOSHIFUJI Hideaki, Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <20130112162224.10e2aa44@stein>
On Jan 12 Stefan Richter wrote:
> At least one thing which is still missing (also
> missing in Stephan's patch from previous week) is the RFC 3146 clause 5
> Configuration ROM entry.
Another thing: As far as I understand, the current code assumes that
peers will use the same unicast_FIFO for IPv4 unicast as for IPv6
unicast. This is not necessarily true. Either firewire-net needs to
maintain two lists of peers (one for IPv4, another for IPv6), or it needs
to maintain two unicast_FIFOs per peer.
--
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
^ permalink raw reply
* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stephan Gatzka @ 2013-01-12 17:15 UTC (permalink / raw)
To: Stefan Richter; +Cc: YOSHIFUJI Hideaki, netdev, linux1394-devel
In-Reply-To: <20130112180058.0289baba@stein>
> Another thing: As far as I understand, the current code assumes that
> peers will use the same unicast_FIFO for IPv4 unicast as for IPv6
> unicast. This is not necessarily true. Either firewire-net needs to
> maintain two lists of peers (one for IPv4, another for IPv6), or it needs
> to maintain two unicast_FIFOs per peer.
>
Thanks for pointing that out. I would go for two unicast_Fifos per peer.
^ permalink raw reply
* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stefan Richter @ 2013-01-12 17:42 UTC (permalink / raw)
To: stephan.gatzka; +Cc: YOSHIFUJI Hideaki, netdev, linux1394-devel
In-Reply-To: <50F19A1B.7050200@gmail.com>
On Jan 12 Stephan Gatzka wrote:
>
> > Another thing: As far as I understand, the current code assumes that
> > peers will use the same unicast_FIFO for IPv4 unicast as for IPv6
> > unicast. This is not necessarily true. Either firewire-net needs to
> > maintain two lists of peers (one for IPv4, another for IPv6), or it needs
> > to maintain two unicast_FIFOs per peer.
> >
>
> Thanks for pointing that out. I would go for two unicast_Fifos per peer.
Indeed. Plus, if we look up an IPv6 peer whose IPv6 unicast_FIFO is as
yet unkown but whose IPv4 unicast_FIFO is already known, we could
optimistically use the latter until we learn the former. And vice versa.
--
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
^ permalink raw reply
* Re: [RFC davem] revert: net: Make skb->skb_iif always track skb->dev
From: Jiri Pirko @ 2013-01-12 18:13 UTC (permalink / raw)
To: Oliver Hartkopp; +Cc: David Miller, Linux Netdev List
In-Reply-To: <50F1699E.1000200@hartkopp.net>
Sat, Jan 12, 2013 at 02:48:14PM CET, socketcan@hartkopp.net wrote:
>Hello Dave,
>
>in your below patch from 23 Jul 2012 you removed the check for an already set
>value of skb_iif in net/core/dev.c
>
>I'm currently working on a solution to prevent some routed CAN frames to be
>sent back onto the originating network device.
Hm, I'm not sure where exactly you want to use this information, but
can_rcv() can get it from orig_dev->ifindex
>
>With your patch it is not possible anymore to check on which netdev the
>CAN frame has originally been received, as for every routing the frame
>goes through netif_receive_skb(), which hard sets
>
> skb->skb_iif = skb->dev->ifindex
>
>and therefore kills the original incoming interface index.
>
>To me it is not clear why skb_iff is needed anyway as the value should
>always be available via skb->dev->ifindex, right?
>
>But if skb_iff has any right to exist it should contain the first incoming
>interface on the host IMO.
>
>Please correct my if i'm wrong and/or tell me what your commit message means
>in respect to my request and why skb->dev->ifindex is not used instead of
>skb_iif. I feel somehow lost about the skb_iif intention ...
I believe that skb_iif should be removed.
>
>Best regards,
>Oliver
>
>---
>
>
>http://git.kernel.org/?p=linux/kernel/git/davem/net-next.git;a=commitdiff;h=b68581778cd0051a3fb9a2b614dee7eccb5127ff
>
>net: Make skb->skb_iif always track skb->dev
>
>Make it follow device decapsulation, from things such as VLAN and
>bonding.
>
>The stuff that actually cares about pre-demuxed device pointers, is
>handled by the "orig_dev" variable in __netif_receive_skb(). And
>the only consumer of that is the po->origdev feature of AF_PACKET
>sockets.
>
>Signed-off-by: David S. Miller <davem@davemloft.net>
>---
>
>diff --git a/net/core/dev.c b/net/core/dev.c
>index cca02ae..0ebaea1 100644
>--- a/net/core/dev.c
>+++ b/net/core/dev.c
>@@ -3173,8 +3173,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
> if (netpoll_receive_skb(skb))
> return NET_RX_DROP;
>
>- if (!skb->skb_iif)
>- skb->skb_iif = skb->dev->ifindex;
> orig_dev = skb->dev;
>
> skb_reset_network_header(skb);
>@@ -3186,6 +3184,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
> rcu_read_lock();
>
> another_round:
>+ skb->skb_iif = skb->dev->ifindex;
>
> __this_cpu_inc(softnet_data.processed);
>
>
>
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC davem] revert: net: Make skb->skb_iif always track skb->dev
From: Oliver Hartkopp @ 2013-01-12 18:40 UTC (permalink / raw)
To: Jiri Pirko; +Cc: David Miller, Linux Netdev List
In-Reply-To: <20130112181307.GA1567@minipsycho.orion>
Hello Jiri,
On 12.01.2013 19:13, Jiri Pirko wrote:
> Sat, Jan 12, 2013 at 02:48:14PM CET, socketcan@hartkopp.net wrote:
>> Hello Dave,
>>
>> in your below patch from 23 Jul 2012 you removed the check for an already set
>> value of skb_iif in net/core/dev.c
>>
>> I'm currently working on a solution to prevent some routed CAN frames to be
>> sent back onto the originating network device.
>
> Hm, I'm not sure where exactly you want to use this information, but
> can_rcv() can get it from orig_dev->ifindex
No - it's not in can_rcv() ...
Depending on the filter lists in can_rcv() the received skb is passed to the
function can_can_gw_rcv() in net/can/gw.c.
An there i wanted to add this code to omit sending the CAN frame on the
originating interface:
@@ .. @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data
if (!(gwj->dst.dev->flags & IFF_UP)) {
gwj->dropped_frames++;
return;
}
+ /* is sending the skb back to the incoming interface allowed? */
+ if (!(gwj->flags & CGW_FLAGS_CAN_IIF_TX_OK) &&
+ skb->skb_iif == gwj->dst.dev->ifindex)
+ return;
+
/*
* clone the given skb, which has not been done in can_rcv()
*
This works fine, when the patch from Dave is reverted.
I did not find any good solution to preserve the originating netdev over
several netif_receive_skb() calls - but this skb_iif which has been made
unusable ...
(..)
>>
>> To me it is not clear why skb_iff is needed anyway as the value should
>> always be available via skb->dev->ifindex, right?
>>
>> But if skb_iff has any right to exist it should contain the first incoming
>> interface on the host IMO.
>>
>> Please correct my if i'm wrong and/or tell me what your commit message means
>> in respect to my request and why skb->dev->ifindex is not used instead of
>> skb_iif. I feel somehow lost about the skb_iif intention ...
>
> I believe that skb_iif should be removed.
AFAICS skb->skb_iif is used as some kind of cached variable for the original
skb->dev->ifindex - or is it really possible that skb->skb_iif is set while
skb->dev->ifindex is not accessible?
Btw. i my case skb_iif would make sense though.
Regards,
Oliver
>>
>> ---
>>
>>
>> http://git.kernel.org/?p=linux/kernel/git/davem/net-next.git;a=commitdiff;h=b68581778cd0051a3fb9a2b614dee7eccb5127ff
>>
>> net: Make skb->skb_iif always track skb->dev
>>
>> Make it follow device decapsulation, from things such as VLAN and
>> bonding.
>>
>> The stuff that actually cares about pre-demuxed device pointers, is
>> handled by the "orig_dev" variable in __netif_receive_skb(). And
>> the only consumer of that is the po->origdev feature of AF_PACKET
>> sockets.
>>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>> ---
>>
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index cca02ae..0ebaea1 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -3173,8 +3173,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
>> if (netpoll_receive_skb(skb))
>> return NET_RX_DROP;
>>
>> - if (!skb->skb_iif)
>> - skb->skb_iif = skb->dev->ifindex;
>> orig_dev = skb->dev;
>>
>> skb_reset_network_header(skb);
>> @@ -3186,6 +3184,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
>> rcu_read_lock();
>>
>> another_round:
>> + skb->skb_iif = skb->dev->ifindex;
>>
>> __this_cpu_inc(softnet_data.processed);
>>
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox