IPv6 over Firewire
Subsystems (2)
Hi!
I'm currently implementing IPv6 over firewire.
To make the address mapping to the firewire link layer RFC3146 mandates to use neighbor discovery with a certain format of the source/target link-layer address option.
While it is not too complicated to build that up, I'm wondering how I can reserve enough memory in the corresponding skb.
One possibility is to introduce some option padding in ndisc_addr_option_pad() but I think that's somehow weird.
The second option I see is to set needed_tailroom in struct netdevice for firewire net devices. That's the way I would go for.
Because I'm not really familiar with the whole network infrastructure in Linux, a confirmation for the way to go would be nice.
Regards,
Stephan
Quoted 9 lines · Stephan Gatzka
To make the address mapping to the firewire link layer RFC3146 mandates to use neighbor discovery with a certain format of the source/target link-layer address option.
While it is not too complicated to build that up, I'm wondering how I can reserve enough memory in the corresponding skb.
One possibility is to introduce some option padding in
ndisc_addr_option_pad()but I think that's somehow weird.The second option I see is to set
needed_tailroomin struct netdevice for firewire net devices. That's the way I would go for.Because I'm not really familiar with the whole network infrastructure in Linux, a confirmation for the way to go would be nice.
If you are talking about how to build NS/NA/RS/Redirect messages, you can just use ndisc_opt_addr_space() and ndisc_fill_addr_option() here.
--yoshfuji
Quoted 3 lines
If you are talking about how to build NS/NA/RS/Redirect messages, you can just use
ndisc_opt_addr_space()andndisc_fill_addr_option()here.
Thanks, these functions are certainly helpful. But ndisc_opt_addr_space() calculates the required space from dev->addr_len and ndisc_addr_option_pad(dev->type). The latter is 0 for IEEE1394 (firewire). So the required option space just comes from dev->addr_len, which is 8 for firewire, resulting in an option address space of 16 (2 octets).
But rfc3146 requires an option address space of 3 octets. So my main question is if in such a situation the best is to reserve additional skb tail room using needed_tailroom in struct netdevice. This directly affects the memory allocated in ndisc_build_skb().
Regards,
Stephan
Quoted 7 lines · Stephan Gatzka
Quoted 3 lines
If you are talking about how to build NS/NA/RS/Redirect messages, you can just use
ndisc_opt_addr_space()andndisc_fill_addr_option()here.Thanks, these functions are certainly helpful. But
ndisc_opt_addr_space()calculates the required space fromdev->addr_lenandndisc_addr_option_pad(dev->type). The latter is 0 for IEEE1394 (firewire). So the required option space just comes fromdev->addr_len, which is 8 for firewire, resulting in an option address space of 16 (2 octets).But rfc3146 requires an option address space of 3 octets. So my main question is if in such a situation the best is to reserve additional skb tail room using
needed_tailroomin struct netdevice. This directly affects the memory allocated inndisc_build_skb().
Something like this:
static inline int ndisc_opt_addr_space(struct net_device *dev) {
- return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
+ switch (dev->type) {
+ case ARPHRD_IEEE1394:+ return sizeof(struct ndisc_opt_ieee1394_llinfo);
+ default:
+ return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
+ }
}
--yoshfuji
Quoted 13 lines · On Dec 22 YOSHIFUJI Hideaki wrote:
Quoted 7 lines · Stephan Gatzka
Quoted 3 lines
If you are talking about how to build NS/NA/RS/Redirect messages, you can just use
ndisc_opt_addr_space()andndisc_fill_addr_option()here.Thanks, these functions are certainly helpful. But
ndisc_opt_addr_space()calculates the required space fromdev->addr_lenandndisc_addr_option_pad(dev->type). The latter is 0 for IEEE1394 (firewire). So the required option space just comes fromdev->addr_len, which is 8 for firewire, resulting in an option address space of 16 (2 octets).But rfc3146 requires an option address space of 3 octets. So my main question is if in such a situation the best is to reserve additional skb tail room using
needed_tailroomin struct netdevice. This directly affects the memory allocated inndisc_build_skb().Something like this:
static inline int
ndisc_opt_addr_space(struct net_device *dev){
Review
Quoted 8 lines
(quoted diff) +6
-1- return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type)); + switch (dev->type) { + case ARPHRD_IEEE1394: + return sizeof(struct ndisc_opt_ieee1394_llinfo); + default: + return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type)); + } }
Can't we increase dev->addr_len for RFC 3146 interfaces? Can't we add another dev->type besides ARPHRD_IEEE1394 (RFC 2734)?
Is a single dev instance transporting both IPv4 and IPv6 or will there be separate instances for those?
Signature · 3 lines
Stefan Richter -=====-===-- ==-- =-==- http://arcgraph.de/sr/
Quoted 8 lines
Can't we increase
dev->addr_lenfor RFC 3146 interfaces? Can't we add anotherdev->typebesidesARPHRD_IEEE1394(RFC 2734)?Is a single dev instance transporting both IPv4 and IPv6 or will there be separate instances for those?
Right now there is a single dev instance for both IPv4 and IPv6. Two instances means there will be two separate device, doesn't it?
Stephan
------------------------------------------------------------------------------
LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers
http://p.sf.net/sfu/logmein_12329d2d
Quoted 6 lines
Something like this:
static inline int ndisc_opt_addr_space(struct net_device *dev) {
Review
Quoted 10 lines
(quoted diff) +6
-2- return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type)); + switch (dev->type) { + case ARPHRD_IEEE1394: + return sizeof(struct ndisc_opt_ieee1394_llinfo); + default: + return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type)); + } } --yoshfuji
O.k., this has the advantage that only ndisc packets get some more memory, but the question is if we are under such a hard memory pressure that we don't allow that.
Your solution has the disadvantage that now I have to publish struct ndisc_opt_ieee1394_llinfo to the ndisc stuff. Nobody in ndisc.c really wants to deal with that structure, only the size is of interest. So keeping this struct private is less invasive to the rest of linux. Just my two cents.
Regards,
Stephan
Quoted 21 lines · On Dec 22 Stephan Gatzka wrote:
Quoted 6 lines
Something like this:
static inline int ndisc_opt_addr_space(struct net_device *dev) {Review
Quoted 10 lines
(quoted diff) +6
-2- return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type)); + switch (dev->type) { + case ARPHRD_IEEE1394: + return sizeof(struct ndisc_opt_ieee1394_llinfo); + default: + return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type)); + } } --yoshfujiO.k., this has the advantage that only ndisc packets get some more memory, but the question is if we are under such a hard memory pressure that we don't allow that.
Quoted 5 lines
Your solution has the disadvantage that now I have to publish struct
ndisc_opt_ieee1394_llinfoto the ndisc stuff. Nobody inndisc.creally wants to deal with that structure, only the size is of interest. So keeping this struct private is less invasive to the rest of linux. Just my two cents.
You could add another case to include/net/ndisc.h::ndisc_addr_option_pad() with a hardcoded size, couldn't you?
Signature · 3 lines
Stefan Richter -=====-===-- ==-- =-==- http://arcgraph.de/sr/
Quoted 4 lines
You could add another case to include/net/ndisc.h::ndisc_addr_option_pad() with a hardcoded size, couldn't you?
No, I think that is almost certainly not a good idea. The address space option is handed over to the firewire_net driver like this:
type, length, soure/target link address (GUID)
If I add another case in ndisc_addr_option_pad() I think the option will look like this:
pad, type, length, soure/target link address (GUID)
Because pad, type and GUID are already at the correct position for the 3146 link layer option. So with padding I have to copy them to the correct position.
All I need is some (8 bytes) of additional tail room in the ndisc skb. This could be achieved either by specifying needed_tailroom in the firewire netdevice struct at the expense that now every skb allocated might get 8 bytes more allocated.
The second option is yoshfuji suggestion to pimp ndisc_opt_addr_space a bit. His solution only allocates additional memory for ndisc packets at the expense to introduce a dependency to the struct ndisc_opt_ieee1394_llinfo.
These are the two option we can go for. Personally I think reserving a bit more tail room looks cleaner if nobody votes against it...
Regards,
Stephan
Quoted 14 lines · Stephan Gatzka
Quoted 14 lines
Something like this:
static inline int ndisc_opt_addr_space(struct net_device *dev) {(quoted diff) +6
-1- return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type)); + switch (dev->type) { + case ARPHRD_IEEE1394: + return sizeof(struct ndisc_opt_ieee1394_llinfo); + default: + return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type)); + } }
Quoted 6 lines
Quoted 2 lines
--yoshfuji
O.k., this has the advantage that only ndisc packets get some more memory, but the question is if we are under such a hard memory pressure that we don't allow that.
Your solution has the disadvantage that now I have to publish struct
ndisc_opt_ieee1394_llinfoto the ndisc stuff. Nobody inndisc.creally wants to deal with that structure, only the size is of interest. So keeping this struct private is less invasive to the rest of linux. Just my two cents.
net/ipv6/ndisc.c SHOULD build full NDP messages for IPv6 over IEEE1394 as we do it for Infiniband.
Please, please do not try to mangle them in the driver.
--yoshfuji
Quoted 6 lines
net/ipv6/ndisc.cSHOULD build full NDP messages for IPv6 over IEEE1394 as we do it for Infiniband.Please, please do not try to mangle them in the driver.
As far as I understand the code for Infiniband (and the corresponding RFC4391) I just see the introduction of two pad bytes. Moreover, I see that ndisc_build_skb calls ndisc_fill_addr_option which copies dev->dev_addr. Maybe the so called Queue Pair Number (QPN) is already included in dev->dev_addr. If not, I guess the Infiniband driver will also mangle the QPN into the link layer option. If not, this seems only possible because the format for IPv6 link layer option (IB) and IPv4/ARP (IB) has the same format.
This is not true IPv4/ARP and IPv6 link layer option for firewire. Moreover, firewire link layer address mapping (IPv4 and IPv6) requires some very firewire specific information like speed, max_rec and especially the so called unicast fifo address.
From my point of view the generic ndisc code shall not cope with these nasty details of the specific link layers. I also haven't found a driver specific hook that might fill these information in. That's why I think I _have_ to mangle the NDP stuff in the driver.
Stephan
Quoted 6 lines · Stephan Gatzka
Quoted 5 lines
net/ipv6/ndisc.cSHOULD build full NDP messages for IPv6 over IEEE1394 as we do it for Infiniband.Please, please do not try to mangle them in the driver.
As far as I understand the code for Infiniband (and the corresponding RFC4391) I just see the introduction of two pad bytes. Moreover, I see that
ndisc_build_skbcallsndisc_fill_addr_optionwhich copiesdev->dev_addr. Maybe the so called Queue Pair Number (QPN) is already included indev->dev_addr. If not, I guess the Infiniband driver will also mangle the QPN into the link layer option. If not, this seems only possible because the format for IPv6 link layer option (IB) and IPv4/ARP (IB) has the same format.
Please, please try best not to mangle packets
and keep/make IPsec, SEND right.
Well, Infiniband's hardware length (INFINIBAND_ALEN) is 20, which means that it includes reserved and QPN field. Moreover Infiniband driver uses neighbor notification mechanism.
I think Firewire can use that as well.
What do you think?
--yoshfuji
Quoted 4 lines
Please, please try best not to mangle packets
and keep/make IPsec, SEND right.
O.k., a small excerpt from RFC 3146:
The Source/Target Link-layer Address option has the following form when the link layer is IEEE1394.
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Length = 3 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---+ | node_unique_ID (EUI-64 identifier) | +--- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | max_rec | spd | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | unicast_FIFO | +--- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This is what I _have_ to send to comply with RFC 3146. In the skb I get in the firewire net driver I have: Type, Length and node_unique_ID (the hardware address), all tail padded to a 8 byte boundary:
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Length = 3 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---+ | node_unique_ID (EUI-64 identifier) | +--- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | 0x00 | 0x00 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x00000000 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
So may aim is to rewrite the LL address option both while transmitting and receiving IPv6 data on firewire. While transmitting, I append the required information, while receiving I cut away the the firewire specific stuff. So the upper layers will not see the firewire related information. Yes, that mangling also involves recalculation of the ICMPv6 checksum.
Again, if I shall not mangle the ndisc packets in the driver I have to build RFC 3146 conformant packets in ndisc_build_skb(). But I see no (general) way to get the firewire specific information into the linux ndisc stuff. Of course I can add some if/else into ndisc_fill_addr_option() and ndisc_recv_na(). But then I have to pull a lot of firewire related stuff into the ndisc code.
I think this makes no sense, especially because I need that firewire specific information in the firewire net driver to send correct firewire packets. Besides that, the IPv4 portion of the firewire net drivers does exactly the same with ARP packets what I want to do with IPv6 LL address options.
Regards,
Stephan
Quoted 1 line · Stephan Gatzka
So may aim is to rewrite the LL address option both while transmitting and receiving IPv6 data on firewire. While transmitting, I append the required information, while receiving I cut away the the firewire specific stuff. So the upper layers will not see the firewire related information. Yes, that mangling also involves recalculation of the ICMPv6 checksum.
No, it is not enough. For example, Signature Option of SEND (RFC3971) takes link-layer address options into account. If anything is happened to be altered, verification will fail.
Quoted 3 lines
Again, if I shall not mangle the ndisc packets in the driver I have to build RFC 3146 conformant packets in
ndisc_build_skb(). But I see no (general) way to get the firewire specific information into the linux ndisc stuff. Of course I can add some if/else intondisc_fill_addr_option()andndisc_recv_na(). But then I have to pull a lot of firewire related stuff into the ndisc code.I think this makes no sense, especially because I need that firewire specific information in the firewire net driver to send correct firewire packets. Besides that, the IPv4 portion of the firewire net drivers does exactly the same with ARP packets what I want to do with IPv6 LL address options.
Please, please do not alter bits in your driver, to maintain extensibility of protocols.
I am definitely okay to have firewire supporting stuff in net/ipv6/ndisc.c. Since we already have notification mechanism, I don't think it will be large.
--yoshfuji
Quoted 8 lines
Please, please do not alter bits in your driver, to maintain extensibility of protocols.
I am definitely okay to have firewire supporting stuff in
net/ipv6/ndisc.c. Since we already have notification mechanism, I don't think it will be large.
O.k., let's try it your way.
I believe the the changes in the transmit portions for ndisc are rather simple. All firewire specific information is stored in the private data of struct net_device. For the receive section I think I have to change something in ndisc_recv_ns(), I'll figure that out. Maybe I need some (small) support from you, but I think we can do that off list.
I'll try it out but after Christmas. :)
But I have to emphasize that I really need (read) access to the firewire specific portions of the link layer option in the firewire net driver. That _is_ necessary to build the relation between the firewire hardware address (GUID) and the corresponding firewire node.
Because you mentioned IPSEC: Are the ndisc packets also encrypted? If so, I just can't imagine how I can do the mapping of firewire hardware addresses and firewire nodes.
@Stefan: Are you o.k. if I go that way?
Regards,
Stephan
Quoted 5 lines · Stephan Gatzka
I believe the the changes in the transmit portions for ndisc are rather simple. All firewire specific information is stored in the private data of struct
net_device. For the receive section I think I have to change something inndisc_recv_ns(), I'll figure that out. Maybe I need some (small) support from you, but I think we can do that off list.I'll try it out but after Christmas. :)
But I have to emphasize that I really need (read) access to the firewire specific portions of the link layer option in the firewire net driver. That _is_ necessary to build the relation between the firewire hardware address (GUID) and the corresponding firewire node.
If you change the "hardware address length", you can get notification when you have new neighbor.
Even if you did not change that, you could introduce new netevent notification.
Quoted 1 line
Because you mentioned IPSEC: Are the ndisc packets also encrypted? If so, I just can't imagine how I can do the mapping of firewire hardware addresses and firewire nodes.
I don't think we will see encrypted ND messages, but IP layer should handle encrypted NDISC messages.
--yoshfuji
Quoted 1 line · On Dec 23 Stephan Gatzka wrote:
@Stefan: Are you o.k. if I go that way?
Sure, go ahead. If it comes to networking issues, I am certainly not someone to seek advise at, let alone permission. :-)
Signature · 3 lines
Stefan Richter -=====-===-- ==-- ==--- http://arcgraph.de/sr/