diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 14f34b12b5b..4f67ea4bdbf 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -147,7 +147,10 @@ static inline void net_context_send_cb(struct net_context *context, static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt) { - struct net_linkaddr *dst; + struct net_linkaddr ll_dst = { + .addr = NULL + }; + struct net_linkaddr_storage ll_dst_storage; struct net_context *context; int status; @@ -164,7 +167,20 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt) debug_check_packet(pkt); - dst = net_pkt_lladdr_dst(pkt); + /* If there're any link callbacks, with such a callback receiving + * a destination address, copy that address out of packet, just in + * case packet is freed before callback is called. + */ + if (!sys_slist_is_empty(&link_callbacks)) { + if (net_linkaddr_set(&ll_dst_storage, + net_pkt_lladdr_dst(pkt)->addr, + net_pkt_lladdr_dst(pkt)->len) == 0) { + ll_dst.addr = ll_dst_storage.addr; + ll_dst.len = ll_dst_storage.len; + ll_dst.type = net_pkt_lladdr_dst(pkt)->type; + } + } + context = net_pkt_context(pkt); if (net_if_flag_is_set(iface, NET_IF_UP)) { @@ -235,8 +251,8 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt) } } - if (dst->addr) { - net_if_call_link_cb(iface, dst, status); + if (ll_dst.addr) { + net_if_call_link_cb(iface, &ll_dst, status); } return true;