net: virtual: Hook into packet filter processing
Make sure that we check possible network packet filtering status before accepting the packet. Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
parent
cde70232b9
commit
bd3ce84d91
1 changed files with 52 additions and 10 deletions
|
@ -25,6 +25,7 @@ static enum net_verdict virtual_recv(struct net_if *iface,
|
|||
{
|
||||
struct virtual_interface_context *ctx, *tmp;
|
||||
const struct virtual_interface_api *api;
|
||||
struct net_if *filtered_iface = NULL;
|
||||
enum net_verdict verdict;
|
||||
sys_slist_t *interfaces;
|
||||
|
||||
|
@ -46,6 +47,28 @@ static enum net_verdict virtual_recv(struct net_if *iface,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_PKT_FILTER)) {
|
||||
struct net_if *tmp_iface;
|
||||
|
||||
tmp_iface = net_pkt_iface(pkt);
|
||||
net_pkt_set_iface(pkt, ctx->virtual_iface);
|
||||
|
||||
if (!net_pkt_filter_recv_ok(pkt)) {
|
||||
/* We cannot update the statistics here because
|
||||
* the interface might not be the correct one for
|
||||
* the packet. We would know that only after the
|
||||
* call to api->recv() which is too late. So mark
|
||||
* the interface as filtered and continue and
|
||||
* update the filter statistics out of the loop.
|
||||
*/
|
||||
net_pkt_set_iface(pkt, tmp_iface);
|
||||
filtered_iface = tmp_iface;
|
||||
continue;
|
||||
}
|
||||
|
||||
net_pkt_set_iface(pkt, tmp_iface);
|
||||
}
|
||||
|
||||
verdict = api->recv(ctx->virtual_iface, pkt);
|
||||
if (verdict == NET_CONTINUE) {
|
||||
continue;
|
||||
|
@ -69,14 +92,11 @@ static enum net_verdict virtual_recv(struct net_if *iface,
|
|||
return verdict;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_STATISTICS)) {
|
||||
size_t pkt_len;
|
||||
|
||||
pkt_len = net_pkt_get_len(pkt);
|
||||
|
||||
NET_DBG("Received pkt %p len %zu", pkt, pkt_len);
|
||||
|
||||
net_stats_update_bytes_recv(iface, pkt_len);
|
||||
if (IS_ENABLED(CONFIG_NET_PKT_FILTER) && filtered_iface != NULL) {
|
||||
/* We need to update the statistics for the filtered iface here.
|
||||
*/
|
||||
net_stats_update_filter_rx_drop(filtered_iface);
|
||||
goto silent_drop;
|
||||
}
|
||||
|
||||
/* If there are no virtual interfaces attached, then pass the packet
|
||||
|
@ -89,14 +109,36 @@ static enum net_verdict virtual_recv(struct net_if *iface,
|
|||
|
||||
if (!net_if_is_up(iface)) {
|
||||
NET_DBG("Interface %d is down.", net_if_get_by_iface(iface));
|
||||
goto drop;
|
||||
goto silent_drop;
|
||||
}
|
||||
|
||||
return api->recv(iface, pkt);
|
||||
if (!net_pkt_filter_recv_ok(pkt)) {
|
||||
net_stats_update_filter_rx_drop(iface);
|
||||
goto silent_drop;
|
||||
}
|
||||
|
||||
verdict = api->recv(iface, pkt);
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_STATISTICS)) {
|
||||
size_t pkt_len;
|
||||
|
||||
pkt_len = net_pkt_get_len(pkt);
|
||||
|
||||
NET_DBG("Received pkt %p len %zu", pkt, pkt_len);
|
||||
|
||||
net_stats_update_bytes_recv(iface, pkt_len);
|
||||
}
|
||||
|
||||
if (verdict == NET_DROP) {
|
||||
net_stats_update_processing_error(iface);
|
||||
}
|
||||
|
||||
return verdict;
|
||||
|
||||
drop:
|
||||
NET_DBG("No handler, dropping pkt %p len %zu", pkt, net_pkt_get_len(pkt));
|
||||
|
||||
silent_drop:
|
||||
return NET_DROP;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue