diff --git a/include/zephyr/net/capture.h b/include/zephyr/net/capture.h index 476f7b6729..eb3cd32973 100644 --- a/include/zephyr/net/capture.h +++ b/include/zephyr/net/capture.h @@ -211,6 +211,31 @@ static inline void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt) } #endif +/** @cond INTERNAL_HIDDEN */ + +/** + * @brief Special variant for net_capture_pkt() which returns the status + * of the send message. + * + * @param iface Network interface the packet is being sent + * @param pkt The network packet that is sent + * + * @return 0 if captured packet was handled ok, <0 if the capture failed + */ +#if defined(CONFIG_NET_CAPTURE) +int net_capture_pkt_with_status(struct net_if *iface, struct net_pkt *pkt); +#else +static inline int net_capture_pkt_with_status(struct net_if *iface, struct net_pkt *pkt) +{ + ARG_UNUSED(iface); + ARG_UNUSED(pkt); + + return -ENOTSUP; +} +#endif + +/** @endcond */ + /** The type and direction of the captured data. */ enum net_capture_packet_type { NET_CAPTURE_HOST, /**< Packet was sent to us by somebody else */ diff --git a/subsys/net/lib/capture/capture.c b/subsys/net/lib/capture/capture.c index c0f5ddd056..d786dca336 100644 --- a/subsys/net/lib/capture/capture.c +++ b/subsys/net/lib/capture/capture.c @@ -503,18 +503,19 @@ static int capture_disable(const struct device *dev) return 0; } -void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt) +int net_capture_pkt_with_status(struct net_if *iface, struct net_pkt *pkt) { struct k_mem_slab *orig_slab; struct net_pkt *captured; sys_snode_t *sn, *sns; bool skip_clone = false; + int ret = -ENOENT; /* We must prevent to capture network packet that is already captured * in order to avoid recursion. */ if (net_pkt_is_captured(pkt)) { - return; + return -EALREADY; } k_mutex_lock(&lock, K_FOREVER); @@ -522,7 +523,6 @@ void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt) SYS_SLIST_FOR_EACH_NODE_SAFE(&net_capture_devlist, sn, sns) { struct net_capture *ctx = CONTAINER_OF(sn, struct net_capture, node); - int ret; if (!ctx->in_use || !ctx->is_enabled || ctx->capture_iface != iface) { @@ -550,6 +550,7 @@ void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt) if (captured == NULL) { NET_DBG("Captured pkt %s", "dropped"); /* TODO: update capture data statistics */ + ret = -ENOMEM; goto out; } } @@ -560,7 +561,9 @@ void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt) ret = net_capture_send(ctx->dev, ctx->tunnel_iface, captured); if (ret < 0) { - net_pkt_unref(captured); + if (!skip_clone) { + net_pkt_unref(captured); + } } net_pkt_set_cooked_mode(pkt, false); @@ -570,6 +573,13 @@ void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt) out: k_mutex_unlock(&lock); + + return ret; +} + +void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt) +{ + (void)net_capture_pkt_with_status(iface, pkt); } static int capture_dev_init(const struct device *dev)