net: l2: ieee802154: fix double address swap
As we have to provide LL addresses in big endian to userspace to be
POSIX compliant and we also do not want to reserve extra space for
such addresses, bff6a5cce5
introduced
a change that swaps address bytes in place in the packet before
returning the packet with LL address pointers to userspace.
Unfortunately a regression sneaked into the code base while doing
so: The byte swapping was duplicated when using 6LoWPAN compression
and the byte swapping caused decryption to fail in some cases,
see #53630. This commit fixes the problem.
Fixes: #53630
Signed-off-by: Florian Grandel <jerico.dev@gmail.com>
This commit is contained in:
parent
ce31799c73
commit
e854314928
2 changed files with 18 additions and 26 deletions
|
@ -94,9 +94,9 @@ static inline void ieee802154_acknowledge(struct net_if *iface, struct ieee80215
|
|||
#define ieee802154_acknowledge(...)
|
||||
#endif /* CONFIG_NET_L2_IEEE802154_ACK_REPLY */
|
||||
|
||||
static inline void set_pkt_ll_addr(struct net_linkaddr *addr, bool comp,
|
||||
enum ieee802154_addressing_mode mode,
|
||||
struct ieee802154_address_field *ll)
|
||||
static inline void swap_and_set_pkt_ll_addr(struct net_linkaddr *addr, bool comp,
|
||||
enum ieee802154_addressing_mode mode,
|
||||
struct ieee802154_address_field *ll)
|
||||
{
|
||||
addr->type = NET_LINK_IEEE802154;
|
||||
|
||||
|
@ -127,8 +127,9 @@ static inline void set_pkt_ll_addr(struct net_linkaddr *addr, bool comp,
|
|||
addr->addr = NULL;
|
||||
}
|
||||
|
||||
/* Swap address byte order in place from little to big endian.
|
||||
* This is ok as the ll address field comes from the header
|
||||
/* The net stack expects link layer addresses to be in
|
||||
* big endian format for posix compliance so we must swap it.
|
||||
* This is ok as the L2 address field comes from the header
|
||||
* part of the packet buffer which will not be directly accessible
|
||||
* once the packet reaches the upper layers.
|
||||
*/
|
||||
|
@ -238,18 +239,22 @@ static enum net_verdict ieee802154_recv(struct net_if *iface, struct net_pkt *pk
|
|||
|
||||
ieee802154_acknowledge(iface, &mpdu);
|
||||
|
||||
net_pkt_set_ll_proto_type(pkt, ETH_P_IEEE802154);
|
||||
|
||||
set_pkt_ll_addr(net_pkt_lladdr_src(pkt), mpdu.mhr.fs->fc.pan_id_comp,
|
||||
mpdu.mhr.fs->fc.src_addr_mode, mpdu.mhr.src_addr);
|
||||
|
||||
set_pkt_ll_addr(net_pkt_lladdr_dst(pkt), false, mpdu.mhr.fs->fc.dst_addr_mode,
|
||||
mpdu.mhr.dst_addr);
|
||||
|
||||
if (!ieee802154_decipher_data_frame(iface, pkt, &mpdu)) {
|
||||
return NET_DROP;
|
||||
}
|
||||
|
||||
/* Setting L2 addresses must be done after packet authentication and internal
|
||||
* packet handling as it will mangle the package header to comply with upper
|
||||
* network layers' (POSIX) requirement to represent network addresses in big endian.
|
||||
*/
|
||||
swap_and_set_pkt_ll_addr(net_pkt_lladdr_src(pkt), mpdu.mhr.fs->fc.pan_id_comp,
|
||||
mpdu.mhr.fs->fc.src_addr_mode, mpdu.mhr.src_addr);
|
||||
|
||||
swap_and_set_pkt_ll_addr(net_pkt_lladdr_dst(pkt), false, mpdu.mhr.fs->fc.dst_addr_mode,
|
||||
mpdu.mhr.dst_addr);
|
||||
|
||||
net_pkt_set_ll_proto_type(pkt, ETH_P_IEEE802154);
|
||||
|
||||
pkt_hexdump(RX_PKT_TITLE " (with ll)", pkt, true);
|
||||
|
||||
hdr_len = (uint8_t *)mpdu.payload - net_pkt_data(pkt);
|
||||
|
|
|
@ -24,19 +24,6 @@ LOG_MODULE_REGISTER(net_ieee802154_6lo, CONFIG_NET_L2_IEEE802154_LOG_LEVEL);
|
|||
|
||||
enum net_verdict ieee802154_6lo_decode_pkt(struct net_if *iface, struct net_pkt *pkt)
|
||||
{
|
||||
/* Upper IP stack expects the link layer address to be in
|
||||
* big endian format so we must swap it here.
|
||||
*/
|
||||
if (net_pkt_lladdr_src(pkt)->addr &&
|
||||
net_pkt_lladdr_src(pkt)->len == IEEE802154_EXT_ADDR_LENGTH) {
|
||||
sys_mem_swap(net_pkt_lladdr_src(pkt)->addr, net_pkt_lladdr_src(pkt)->len);
|
||||
}
|
||||
|
||||
if (net_pkt_lladdr_dst(pkt)->addr &&
|
||||
net_pkt_lladdr_dst(pkt)->len == IEEE802154_EXT_ADDR_LENGTH) {
|
||||
sys_mem_swap(net_pkt_lladdr_dst(pkt)->addr, net_pkt_lladdr_dst(pkt)->len);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_L2_IEEE802154_FRAGMENT
|
||||
return ieee802154_6lo_reassemble(pkt);
|
||||
#else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue