-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ng_sixlowpan: Fixes #3494
ng_sixlowpan: Fixes #3494
Conversation
@@ -20,6 +20,7 @@ | |||
#define NG_SIXLOWPAN_FRAG_RBUF_H_ | |||
|
|||
#include <inttypes.h> | |||
#include <stdbool.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you did not add any stdbool.h stuff?
Adressed comments |
The only issue still open is that there is a hard fault at the receiving an uncompressed, but fragmented packet. A don't really know why that is. @gebart do you have an idea maybe? |
75ea011
to
d533aa4
Compare
Rebased to current master |
On Jul 24, 2015 11:34 AM, "Martine Lenders" notifications@github.com
Do you have any more information on the hard fault? Backtrace etc. I can look at it in 10 days, I will be away on holidays next week and will |
Yes, sorry for not giving this earlier: it's happening at [1] due to [2] somehow overwriting the pointers in
Okay, until then I hopefully have found the bug myself :-D [1] https://github.com/RIOT-OS/RIOT/pull/3494/files#diff-a8f58d41a6d77cb7e5f310c61eae2c44R138 |
@authmillenon some hints to find it:
|
Oh I did that already, but to no avail… I suspect that there is either a illegal release somewhere or that the packet buffer has a really nifty bug. |
Did you not get any triggered watch points at all? |
Yes I did, but that was how I found out that [2] was overwriting ;-) |
OK, try expanding the macro for easier debugging: do { \
__typeof(entry->pkt) _tmp; \
(netif)->next=((void *)0); \
if (entry->pkt) { \
_tmp = entry->pkt; \
while (_tmp->next) { _tmp = _tmp->next; } \
_tmp->next=(netif); \
} else { \
(entry->pkt)=(netif); \
} \
} while (0) |
The macro is not the problem… for some reason the
|
sorry, I switched the lines in my head. I agree, it is likely a packet being used after released. |
I can confirm that this PR improves IPHC and fragmentation and does not destroy anything. |
|
||
if (ng_netapi_get(ifs[i], NETCONF_OPT_MAX_PACKET_SIZE, | ||
0, &max_frag_size, sizeof(max_frag_size)) < 0) { | ||
/* if error we assume it works */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it make sense to set the max. packet size to more sensible size than 2^16-1 in case that this fails? E.g. 1280 bytes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is 1280 as the minimum MTU more sensible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because RFC2460 requires a minimum MTU of 1280 bytes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but why take the minimum, when the maximum is just as good. My point is: I don't see the point where 1280 bytes is a more sensible number than UINT16_MAX or 4242 or 2015 or 5555 [edit] as long as it stays in the interval [1280, 2^16-1]. The number is quite arbitrary so I decided for the maximum a (standard) IPv6 frame can carry (since its length field is 16-bit long).
Also just to be clear: this value is not the MTU, this is just the number of bytes 6LoWPAN decides to fragment a packet. So even smaller values than 1280 are possible (and are usually chosen with IEEE 802.15.4 devices ;-)) 6LoWPAN's maximum MTU is max(max_L2_packet_size, 2^11 - 1)
, because the datagram_length field of the fragmentation header is 11 bit long (but nothing stops it to send bigger packets unfragmented if the link-layer supports that).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Furthermore, this is not a new change, I just moved this from [1] since the ifconfig 7 [-]iphc
command then only would work after the first 6LoWPAN frame would have been send).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just think that it is more likely for a link layer to being able to carry 1--2kBytes instead of being able to carry 65kBytes payload.
And yes, I lost track of what this PR is essentially doing. I cannot do a proper review (without reading and understanding the whole fragmentation code again). So, I would say, if no one else is willing to review, let's trust the outcome, which seems to be good according to @PeterKietzmann.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if we are talking over each others heads, but this line does not set anything to the device, but reads the maximum frame length of the link layer into max_frag_size. UINT16_MAX is only used iff the link layer does not support this option.
Yes, that's what I understood. And I think a sensible default value is more in the range of an typical Ethernet frame than in the range of 65kBytes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just think that it is more likely for a link layer to being able to carry 1--2kBytes instead of being able to carry 65kBytes payload.
and
Yes, that's what I understood. And I think a sensible default value is more in the range of an typical Ethernet frame than in the range of 65kBytes.
Well the IPv6 layer usually knows very well about the (in case of 6LoWPAN perceived) MTU of the device, so packets that are bigger than the device can handle would never reach 6LoWPAN anyways (further argument why to take the maximum rather than the minimum, because it makes all checks to fragment a packet false). Ethernet and IEEE 802.15.4 aren't the only link-layers out there, afaik BLE provides fragmentation itself, making its maximum "frame" size pretty big in theory.
And yes, I lost track of what this PR is essentially doing. I cannot do a proper review (without reading and understanding the whole fragmentation code again). So, I would say, if no one else is willing to review, let's trust the outcome, which seems to be good according to @PeterKietzmann.
😁👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well the IPv6 layer usually knows very well about the (in case of 6LoWPAN perceived) MTU of the device
How does it do so?
If this value is only used for 6LoWPAN fragmentation, I would vote for either exiting here or setting this value to a fixed size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does it do so?
Either by being set by the user (though there is arguably no command for this yet) or by getting it from the device. If both are not the case the default value is 1280.
If this value is only used for 6LoWPAN fragmentation, I would vote for either exiting here or setting this value to a fixed size.
I do the later here ;-). But seriously, after this discussion and reviewing what happens to a packet as it traverses the stack I do think UINT16_MAX
is the most sensible solution. Say the link layer has no maximum packet length because it supports streaming. Then UINT16_MAX as the size of a single maxed out IPv6 packet (even that is not true because the header is missing from that the) Is the maximum fragment size 6LoWPAN can send. If not it either can tell both IPv6 and 6LoWPAN this through this option or it is always 1280 (as you proposed earlier) which all will fail the "should I fragment" test because they are all lesser than UINT16_MAX.
Let's assume in IoT (M2M) there is no user/administrator.
Isn't the netapi call exactly doing this?
Are you sure that any link layer supports fragmentation of arbitrary payload? Anyway, is this value only used for 6LoWPAN or also for other parts of IPv6? |
As I've stated before: then IPv6 defaults to its minimum MTU (1280) unless the device is willing to tell it itself ;)
No.
Currently, this is only used by 6LoWPAN, but nothing stops us from using this also for 6LoWPANZ or other 6lo specifications. |
Ok, let's rewind to the original purpose of this variable: it is meant for (at least theoretical) any convergence layer (e.g. 6LoWPAN) below IPv6 to tell this layer the maximum size of a packet on the link layer, right? If the device cannot tell the convergence layer this size, I would expect the implementation to throw an error here. |
I don't dare to ACK this PR but still I'd like to see this merged soon, as it really fixes some issues with fragmentation and IPHC. Who is willing to give an ACK :-) ? Are we ready to squash and run Travis? |
Please squash. Will review. |
@@ -117,7 +105,7 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag, | |||
} | |||
|
|||
while (ptr != NULL) { | |||
if (_rbuf_int_in(ptr, offset, offset + dg_frag_size - 1)) { | |||
if (_rbuf_int_in(ptr, offset, offset + frag_size - 1)) { | |||
DEBUG("6lo rfrag: overlapping or same intervals, discarding datagram\n"); | |||
ng_pktbuf_release(entry->pkt); | |||
_rbuf_rem(entry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_rbuf_rem
sets entry->pkt
to NULL
. Is this a desired behaviour? What if this pkt
has several users?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if this pkt has several users?
- This is not of relevance for this module, since the other user then should have its own reference.
- Normally this module should be the packet's only user, since it creates it and in this case disregards it because of an error. Only if the packet was reassembled successfully it will be handed over to another thread.
54337e2
to
f880280
Compare
Rebased and squashed |
|
||
if (ng_netapi_get(ifs[i], NETCONF_OPT_MAX_PACKET_SIZE, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this needs to be changed to NETOPT_MAX_PACKET_SIZE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NG_
prefixed of course
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jupp fixed already
f880280
to
524a4e8
Compare
Found a little merge-error. |
524a4e8
to
26c98b8
Compare
26c98b8
to
cc298d8
Compare
Everything's broken: ACK |
👍 ACk |
😱 ?!?! |
Fixes some issues with fragmentation, IPHC and the interface state of a 6LoWPAN interface.