net: capture: Add capture function that returns a status
The net_capture_pkt() does not return information what happened to the net_pkt because the packet was always cloned. With cooked capture we can avoid the cloning in which case we need to know the capture status in order to unref the packet if needed. Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
parent
46cb5c0bd1
commit
0516ce9311
|
@ -211,6 +211,31 @@ static inline void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt)
|
||||||
}
|
}
|
||||||
#endif
|
#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. */
|
/** The type and direction of the captured data. */
|
||||||
enum net_capture_packet_type {
|
enum net_capture_packet_type {
|
||||||
NET_CAPTURE_HOST, /**< Packet was sent to us by somebody else */
|
NET_CAPTURE_HOST, /**< Packet was sent to us by somebody else */
|
||||||
|
|
|
@ -503,18 +503,19 @@ static int capture_disable(const struct device *dev)
|
||||||
return 0;
|
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 k_mem_slab *orig_slab;
|
||||||
struct net_pkt *captured;
|
struct net_pkt *captured;
|
||||||
sys_snode_t *sn, *sns;
|
sys_snode_t *sn, *sns;
|
||||||
bool skip_clone = false;
|
bool skip_clone = false;
|
||||||
|
int ret = -ENOENT;
|
||||||
|
|
||||||
/* We must prevent to capture network packet that is already captured
|
/* We must prevent to capture network packet that is already captured
|
||||||
* in order to avoid recursion.
|
* in order to avoid recursion.
|
||||||
*/
|
*/
|
||||||
if (net_pkt_is_captured(pkt)) {
|
if (net_pkt_is_captured(pkt)) {
|
||||||
return;
|
return -EALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
k_mutex_lock(&lock, K_FOREVER);
|
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) {
|
SYS_SLIST_FOR_EACH_NODE_SAFE(&net_capture_devlist, sn, sns) {
|
||||||
struct net_capture *ctx = CONTAINER_OF(sn, struct net_capture,
|
struct net_capture *ctx = CONTAINER_OF(sn, struct net_capture,
|
||||||
node);
|
node);
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!ctx->in_use || !ctx->is_enabled ||
|
if (!ctx->in_use || !ctx->is_enabled ||
|
||||||
ctx->capture_iface != iface) {
|
ctx->capture_iface != iface) {
|
||||||
|
@ -550,6 +550,7 @@ void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt)
|
||||||
if (captured == NULL) {
|
if (captured == NULL) {
|
||||||
NET_DBG("Captured pkt %s", "dropped");
|
NET_DBG("Captured pkt %s", "dropped");
|
||||||
/* TODO: update capture data statistics */
|
/* TODO: update capture data statistics */
|
||||||
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,8 +561,10 @@ void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt)
|
||||||
|
|
||||||
ret = net_capture_send(ctx->dev, ctx->tunnel_iface, captured);
|
ret = net_capture_send(ctx->dev, ctx->tunnel_iface, captured);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
if (!skip_clone) {
|
||||||
net_pkt_unref(captured);
|
net_pkt_unref(captured);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
net_pkt_set_cooked_mode(pkt, false);
|
net_pkt_set_cooked_mode(pkt, false);
|
||||||
|
|
||||||
|
@ -570,6 +573,13 @@ void net_capture_pkt(struct net_if *iface, struct net_pkt *pkt)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
k_mutex_unlock(&lock);
|
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)
|
static int capture_dev_init(const struct device *dev)
|
||||||
|
|
Loading…
Reference in a new issue