gnrc_netif_ieee802154: drop duplicate broadcast packets (optionally)#7577
Conversation
|
Why only broadcast packets? The dedup is just as useful for unicast, for example when a packet is correctly received, but the ack is not received by the sender. |
|
It makes it a little bit more complicated, but will do. |
| const uint8_t seq = ieee802154_get_seq(mhr); | ||
|
|
||
| return (dev->last_pkt.seq == seq) && | ||
| (((dev->last_pkt.was_bcast) && (netif->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST)) || |
There was a problem hiding this comment.
Maybe for broadcast packet, you should also check the source address, since in case two different senders (A, then B ) successively broadcast two different packets to C (with the same sequence, this time, the possibility is 1/256), then B's bcast packet will be dropped. ;-)
There was a problem hiding this comment.
I do check the source address.
There was a problem hiding this comment.
Ah, I see, and sorry for the noise.
|
A simple solution maybe: you don't need to count whether the received packet is bcast or not, just record the |
True |
9abf3e1 to
e8b52cf
Compare
|
Rebased and no longer dependent on any PR, but please DO NOT MERGE yet! |
jnohlgard
left a comment
There was a problem hiding this comment.
Some comments on the implementation. I think this is a crucial component for the network stack, but the implementation is more complex than it has to be. For IEEE 802.15.4, it should be enough to just check the sender link layer address and the sequence number to identify duplicates.
| /** @} */ | ||
| #ifdef MODULE_GNRC_NETIF2_DEDUP_BCAST | ||
| struct { | ||
| uint8_t dst[IEEE802154_LONG_ADDRESS_LEN]; /**< destination address */ |
There was a problem hiding this comment.
I don't see any reason why you should need to store the destination information. Each sender should not reuse sequence numbers except for retransmissions (and after 256 packets when the counter rolls over)
| uint8_t src[IEEE802154_LONG_ADDRESS_LEN]; /**< source address */ | ||
| uint8_t dst_len; /**< destination address length */ | ||
| uint8_t src_len; /**< source address length */ | ||
| uint8_t was_bcast; /**< indicates if dst was broadcast */ |
There was a problem hiding this comment.
Why is this relevant for deduplication?
| if (_already_received(dev, hdr, ieee802154_hdr->data)) { | ||
| gnrc_pktbuf_release(pkt); | ||
| gnrc_pktbuf_release(netif_hdr); | ||
| DEBUG("_recv_ieee802154: packet dropped by broadcast deduplication\n"); |
There was a problem hiding this comment.
Scratch " broadcast " if this applies to all packets now.
| return (dev->last_pkt.seq == seq) && | ||
| (((dev->last_pkt.was_bcast) && (netif->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST)) || | ||
| ((dev->last_pkt.dst_len == netif->dst_l2addr_len) && | ||
| (memcmp(dev->last_pkt.dst, gnrc_netif_hdr_get_dst_addr(netif), |
There was a problem hiding this comment.
I see no reason why this check is necessary
|
Addressed comments. |
jnohlgard
left a comment
There was a problem hiding this comment.
Some left overs in the implementation referring to was_bcast and dst
| uint8_t chan; /**< channel */ | ||
| uint16_t flags; /**< flags as defined above */ | ||
| /** @} */ | ||
| #ifdef MODULE_GNRC_NETIF2_DEDUP_BCAST |
There was a problem hiding this comment.
Module name could be just gnrc_netif2_dedup
There was a problem hiding this comment.
Rememeber what I said about coffee ^^
| DEBUG("_recv_ieee802154: packet dropped by deduplication\n"); | ||
| return NULL; | ||
| } | ||
| dev->last_pkt.was_bcast = ((netif->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST) != 0); |
There was a problem hiding this comment.
This probably doesn't compile any more
|
Addressed comments. Just a friendly reminder to please not merged, before the whole netif2 situation on the maintainers list was discussed. |
|
Yep, I will let you do the merging when you feel it is time. |
| return snip; | ||
| } | ||
|
|
||
| #if MODULE_GNRC_NETIF2_DEDUP_BCAST |
There was a problem hiding this comment.
Need to update this module name
There was a problem hiding this comment.
Arghs... Need more coffee, I think ^^
| return NULL; | ||
| } | ||
| #endif | ||
| #ifdef MODULE_GNRC_NETIF2_DEDUP_BCAST |
|
Done. |
|
Checked the codes, also look fine to me. ;-) |
jnohlgard
left a comment
There was a problem hiding this comment.
Looks good except for a small typo.
Please squash
| } | ||
| memcpy(dev->last_pkt.src, gnrc_netif_hdr_get_src_addr(hdr)); | ||
| dev->last_pkt.src_len = hdr->src_l2addr_len; | ||
| dev->seq = seq; |
There was a problem hiding this comment.
It seems like this should be dev->last_pkt.seq = seq
914c4e6 to
267d08d
Compare
|
Fixed and squashed |
|
Please wait with merging until #7925 is merged (alternatively we can merge this PR into that, I need to rebase then). |
267d08d to
db69497
Compare
443c3a9 to
9e69c4a
Compare
|
Just by following the comments it seems as if we're good to go? Did someone run any test? |
|
I did a very long time ago. I think i5 would be wise to test again |
|
Made compilable again |
|
I did some basic testing:
current master with this PR -> seems to work! For some reason I don't see all retransmissions I would expect to be sent by board B. Probably some timing issues... |
I'd say this is unrelated to this PR. |
|
I think this is a useful feature although it might make sense to have sort of documentation for the pseudomodule. @aabadie whats your opinion to get this in for the release? |
|
I'd be happy to have it in ;-). Will rebase. |
|
Done |
be82f4f to
4e870b4
Compare
|
I still miss some kind of documentation. How would a user be aware of that module? Don't know what's the best location, maybe doxygen in net/gnrc/netif/ieee802154.h? |
Now that you mention it, it doesn't really make sense to store the data in |
|
Good! |
miri64
left a comment
There was a problem hiding this comment.
Ported to a pure gnrc_netif approach and also added some documentation.
| */ | ||
| typedef struct { | ||
| uint8_t src[GNRC_NETIF_L2ADDR_MAXLEN]; /**< link-layer source address */ | ||
| uint16_t seq; /**< link-layer sequence number */ |
There was a problem hiding this comment.
FYI I chose uint16_t instead of uint8_t since this implementation supposed to be independent of IEEE 802.15.4. I'm not aware of any packet switching Link-Layer with packets >UINT16_MAX so I figured uint16_t might be enough.
| #if MODULE_GNRC_NETIF_DEDUP | ||
| static inline bool _already_received(gnrc_netif_t *netif, | ||
| gnrc_netif_hdr_t *netif_hdr, | ||
| uint8_t *mhr) |
There was a problem hiding this comment.
Seeing this makes me wonder a bit about the netif data structures, although not related to this PR...
There was a problem hiding this comment.
What exactly are you wondering about?
There was a problem hiding this comment.
About that fact that we need three "data structures" in order to get header information such as sequence number or link layer addresses.
There was a problem hiding this comment.
About that fact that we need three "data structures" in order to get header information such as sequence number or link layer addresses.
For that we "only" need two. The third (netif) is the current state against we check that information. We wouldn't actually need two either, but the addresses in the IEEE 802.15.4 are rather complicated to parse out due to its and their variable lengths, so why not actually use the results from a previous parsing step i.e. netif_hdr (we don't need the sequence number in that for most use-cases)
3103bdb to
985d980
Compare
squashed |
PeterKietzmann
left a comment
There was a problem hiding this comment.
ACK from my side. But I'm giving @gebart some time to double-check or at least remove his change request.
Can be activated with
USEMODULE += gnrc_netif_dedup(consideringgnrc_netifis activated, see #7424). Testing procedures see #7577 (comment)Depends on
#7409(merged).