Skip to contentSkip to conversation

IPv6 over firewire

DISCUSSION Stefan Richter 2 participants 6 messages Jan 12, 2013 5 messages not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): [email protected]

#3 lore raw
Quoted 13 lines · On Jan 12 Stephan Gatzka wrote:
Quoted 4 lines

And, last but big issue is, well, packet inspection at driver level. For example, you use ndisc_parse_options() and code depends on CONFIG_IPV6=y.

Good point. Of course I can make firewire-net dependent from IPv6.

The other option is to build a separate firewire_ipv6 module. Implementing that looks easy enough. From the original firewire net driver I just need a hook to register a function that investigates incoming packets for IPv6 link layer option. In addition, fwnet_peer_find_by_guid must be exported.

Quoted 3 lines

Stefan, what is your opinion on that?

From your previous patch it looks like that the RFC 3146 related parts in

drivers/firewire/net.c are just a few places that can be enclosed into #if/#endif blocks. That way, firewire-net will be built according to the same Kconfig switches as before, and gets RFC 3146 capability if CONFIG_IPV6=y or =m.

#if/#endif are generally not very nice, but in this case I think they can be kept localized and thus are more beneficial than hurtful.

There is a catch: Since both net/ipv6/Kconfig::IPV6 and drivers/firewire/Kconfig::FIREWIRE_NET are tristate variables, we need to prevent CONFIG_FIREWIRE_NET=y while CONFIG_IPV6=m. One way to do that would be like it was done for the infrared remote control support in the firedtv driver which depends on the CONFIG_INPUT tristate variable. This was solved like this:
- The helper variable drivers/media/firewire/Kconfig::DVB_FIREDTV_INPUT was added.
- This variable is true if CONFIG_INPUT=y,
or if CONFIG_DVB_FIREDTV=m and CONFIG_INPUT=m.
In other words, if CONFIG_INPUT=m and CONFIG_DVB_FIREDTV=y, firedtv silently loses support for remote control input.
- The respective firedtv parts are of course made dependent on CONFIG_DVB_FIREDTV. In this case, only drivers/media/firewire/firedtv.h and drivers/media/firewire/Makefile are minimally affected.

So, if implemented like that, the special case of CONFIG_FIREWIRE_NET=y && CONFIG_IPV6=m would mean that firewire-net would be built but would lack RFC 3146 support.

With a little bit more Kconfig related effort one could solve it such that CONFIG_FIREWIRE_NET=y && CONFIG_IPV6=m would actually put RFC 3146 support into firewire-net but would force it to be built modular instead of statically.

Not sure which way is preferrable. Cc'ing netdev.

In case of CONFIG_IPV6=n however, people should still be able to build firewire-net with its current RFC 2734-only feature set.

Signature · 3 lines
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/

A message that is not in the archive (sent off-list or not yet received): 20130110210912.09c62d38@stein

A message that is not in the archive (sent off-list or not yet received): [email protected]

#6 lore raw

[Cc'ing netdev. This is about
http://marc.info/?l=linux1394-devel&m=135723690427469]

Quoted 28 lines · On Jan 12 Stephan Gatzka wrote:
Quoted 7 lines · On Jan 10 Stefan Richter wrote:

Relative to mentioned preliminary patch, there need to be some cleanups done, in my opinion:
- The move of struct fwnet_device from drivers/firewire/net.c into include/linux/firewire.h, the inclusion of <linux/firewire.h> into net/ipv6/ndisc.c, and the use of <linux/firewire.h> definitions in net/ipv6/ndisc.c need to be undone.
- Instead, the dependencies should be solved such that

Quoted 8 lines

include/net/ndisc.h (or whatever net header would be appropriate for these kinds of definitions) defines RFC 3146 specific structs or/and functions (or extensions of existing functions by additional arguments) or/and driver ops (alias methods alias callbacks, in the style of net_device.header_ops and the likes). Then, both net/ipv6/ndisc.c and drivers/firewire/net.c would use these new RFC 3146 related definitions but net/ipv6/ndisc.c would not become a user of any <linux/firewire.h> definitions.

Just to know if I understood you correctly. You want to have a function pointer in struct net_device like fill_link_layer_option(). This function pointer has to be set when allocating a struct net_device object.

This is certainly possible, but if I do so, I'd assume that then _every_ network device (ethernet, infiniband, ...) in linux has to implement such a function. Otherwise, I think the ndisc code only for a firewire net device will call the callback function. So I would introduce a callback routine in struct net_device just for firewire.

Quoted 4 lines

The problem is, that right now, firewire is the _only_ device that requires this special link layer option format. All other network device do not require this right now. So I ask myself if its worth to introduce this callback routine just for firewire.

I haven't looked in detail into what is really required here. Maybe a new driver op (callback) isn't actually needed.

But if a new callback is needed, it doesn't have to burden the kernel much:

- In the linux-kernel OOP model, there are mandatory methods as well as optional methods. A new method for RFC 3146 Neighbor Discovery should of course be an optional one.

- There is a downside to optional methods: The core code which may have to use the method first needs to do a NULL check of the method's function pointer or needs to check a correlated capabilities flag or something like that. Such additional checks are undesirable in hot paths, but I suppose IPv6 Neighbor Discovery is not a particularly hot path.

- There is another downside: Each new driver method increases the memory footprint of instances of respective function pointer tables by 4 or 8 bytes.

Both downsides can be countered somewhat by enclosing the respective code into #ifdef CONFIG_RFC3146_NDISC...#endif and have something like

    select RFC3146_NDISC if IPV6 = y || (IPV6 = m && FIREWIRE_NET = m)

in the "config FIREWIRE_NET" section.

But the new callback (if one is really needed) doesn't have to be a driver method. It could also look about like this:

include/net/ndisc.h:
-extern struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
- struct ndisc_options *ndopts);
+extern struct ndisc_options *__ndisc_parse_options(u8 *opt,
+ int opt_len, struct ndisc_options *ndopts,
+ whatever_type *callback);
+
+static inline struct ndisc_options *ndisc_parse_options(u8 *opt,
+ int opt_len, struct ndisc_options *ndopts)
+{
+ return __ndisc_parse_options(opt, len, ndopts, NULL);
+}

net/ipv6/ndisc.c:
-struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
- struct ndisc_options *ndopts)
+struct ndisc_options *__ndisc_parse_options(u8 *opt, int opt_len,
+ struct ndisc_options *ndopts, whatever_type *callback)
{

Or the (optional!) callback could be a new member of struct ndisc_options.

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?

Signature · 3 lines
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
#7 lore raw
Quoted 6 lines

But if a new callback is needed, it doesn't have to burden the kernel much:

- In the linux-kernel OOP model, there are mandatory methods as well as optional methods. A new method for RFC 3146 Neighbor Discovery should of course be an optional one.

Quoted 6 lines

- There is a downside to optional methods: The core code which may have to use the method first needs to do a NULL check of the method's function pointer or needs to check a correlated capabilities flag or something like that. Such additional checks are undesirable in hot paths, but I suppose IPv6 Neighbor Discovery is not a particularly hot path.

Yes, that should be true.

Quoted 4 lines

- There is another downside: Each new driver method increases the memory footprint of instances of respective function pointer tables by 4 or 8 bytes.

I can't imagine that this is a show stopper. How many instances of struct netdev do we have o a typical system? I guess not the much.

Quoted 22 lines

Both downsides can be countered somewhat by enclosing the respective code into #ifdef CONFIG_RFC3146_NDISC...#endif and have something like

     select RFC3146_NDISC if IPV6 = y || (IPV6 = m && FIREWIRE_NET = m)

in the "config FIREWIRE_NET" section.

But the new callback (if one is really needed) doesn't have to be a driver method. It could also look about like this:

include/net/ndisc.h:
-extern struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
- struct ndisc_options *ndopts);
+extern struct ndisc_options *__ndisc_parse_options(u8 *opt,
+ int opt_len, struct ndisc_options *ndopts,
+ whatever_type *callback);
+
+static inline struct ndisc_options *ndisc_parse_options(u8 *opt,
+ int opt_len, struct ndisc_options *ndopts)
+{
+ return __ndisc_parse_options(opt, len, ndopts, NULL);
+}

Quoted 8 lines

net/ipv6/ndisc.c:
-struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
- struct ndisc_options *ndopts)
+struct ndisc_options *__ndisc_parse_options(u8 *opt, int opt_len,
+ struct ndisc_options *ndopts, whatever_type *callback)
{

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?

Quoted 3 lines

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.

Regards,

Stephan

Signature · 3 lines
Welchen Unterschied gibt es zwischen einem toten Hund auf der
Straße und einer überfahrenen Bratsche auf der Straße? Vor dem
toten Hund gibt es Bremsspuren.
#8 lore raw
Quoted 6 lines · On Jan 12 Stephan Gatzka wrote:
Quoted 3 lines

- There is another downside: Each new driver method increases the memory footprint of instances of respective function pointer tables by 4 or 8 bytes.

I can't imagine that this is a show stopper. How many instances of struct netdev do we have o a typical system? I guess not the much.

There aren't many instances, but these instances are used in hot paths where cache utilization matters. Of course such structures can be ordered so that often used parts are located close to each other.

Signature · 3 lines
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
#9 lore raw
In reply to Stephan Gatzka
Quoted 5 lines · On Jan 12 Stephan Gatzka wrote:
Quoted 1 line

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.

Quoted 8 lines
Quoted 3 lines

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. :-)

Signature · 3 lines
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/
#10 lore raw
Quoted 5 lines

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. :)