Hello linux-wpan devs,
I have been experimenting with the RPL SRH support implemented by
Alexander Aring. I hope related questions fit into this mailing list,
otherwise feel free to redirect me elsewhere.
In the original merge commit (96376cad3508) for this feature, the log
indicates that IPv6-in-IPv6 encapsulation is implemented:
In receive handling I add handling for IPIP encapsulation as RFC6554
describes it as possible.
However, my observations suggest that it is actually not the case when
forwarding packets. Instead, the IPv6 header of the packet is modified
in a way which violates the IPv6 specification (RFC 8200 section 4):
Extension headers (except for the Hop-by-Hop Options header) are not
processed, inserted, or deleted by any node along a packet's delivery
path, until the packet reaches the node (or each of the set of nodes,
in the case of multicast) identified in the Destination Address field
of the IPv6 header.
In the appendix I describe more precisely the steps I took to come to
this conclusion. A couple questions follow from my observations:
- First of all, is my analysis flawed?
- Then, was this behavior implemented knowingly?
- Finally, should it be changed?
########################################################################
Appendix: my experiment
I have 2 TUN devices setup and a couple simple routes to do testing.
$ ip -6 route
[...]
2001:db8::1 dev tun1 proto kernel metric 256 pref medium
2001:db8::2 dev tun2 proto kernel metric 256 pref medium
2001:db8::3 dev tun2 metric 1024 pref medium
2001:db8::4 encap rpl segs 1 [ 2001:db8::3 ] dev tun2 metric 1024
pref medium
[...]
I am then generating a packet at tun1, destined to 2001:db8::4, and
observing what goes through both interfaces using tshark.
$ tshark -i tun1 -i tun2 -V
Capturing on 'tun1' and 'tun2'
Frame 1: 48 bytes on wire (384 bits), 48 bytes captured (384 bits)
on interface tun1, id 0
[...]
Internet Protocol Version 6, Src: 2001:db8::1, Dst: 2001:db8::4
0110 .... = Version: 6
.... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00
(DSCP: CS0, ECN: Not-ECT)
.... 0000 00.. .... .... .... .... .... = Differentiated
Services Codepoint: Default (0)
.... .... ..00 .... .... .... .... .... = Explicit
Congestion Notification: Not ECN-Capable Transport (0)
.... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
Payload Length: 8
Next Header: UDP (17)
Hop Limit: 255
Source Address: 2001:db8::1
Destination Address: 2001:db8::4
User Datagram Protocol, Src Port: 5000, Dst Port: 5000
Source Port: 5000
Destination Port: 5000
Length: 8
Checksum: 0x7d57 [unverified]
[Checksum Status: Unverified]
[Stream index: 0]
Frame 2: 64 bytes on wire (512 bits), 64 bytes captured (512 bits)
on interface tun2, id 1
[...]
Internet Protocol Version 6, Src: 2001:db8::1, Dst: 2001:db8::3
0110 .... = Version: 6
.... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00
(DSCP: CS0, ECN: Not-ECT)
.... 0000 00.. .... .... .... .... .... = Differentiated
Services Codepoint: Default (0)
.... .... ..00 .... .... .... .... .... = Explicit
Congestion Notification: Not ECN-Capable Transport (0)
.... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
Payload Length: 24
Next Header: Routing Header for IPv6 (43)
Hop Limit: 254
Source Address: 2001:db8::1
Destination Address: 2001:db8::3
Routing Header for IPv6 (RPL Source Route)
Next Header: UDP (17)
Length: 1
[Length: 16 bytes]
Type: RPL Source Route (3)
Segments Left: 1
1111 .... .... .... .... .... .... .... = Compressed
Internal Octets (CmprI): 15
.... 1111 .... .... .... .... .... .... = Compressed Final
Octets (CmprE): 15
.... .... 0111 .... .... .... .... .... = Padding Bytes: 7
.... .... .... 0000 0000 0000 0000 0000 = Reserved: 0
[Total Address Count: 1]
Address: 04
[Address[1]: 2001:db8::4]
User Datagram Protocol, Src Port: 5000, Dst Port: 5000
Source Port: 5000
Destination Port: 5000
Length: 8
Checksum: 0x7d57 [unverified]
[Checksum Status: Unverified]
[Stream index: 0]
We can then see that the original packet header was modified, with
destination address changed, and a routing extension header added. If
IPv6-in-IPv6 encapsulation was at play, the original header would have
been copied unchanged (except the hop limit I suppose), and an
additional IPv6 header accompanied with the SRH would have been added as
an outer header.