Commit e16b8598 authored by Martin Willi's avatar Martin Willi Committed by David S. Miller

macvlan: Fix leaking skb in source mode with nodst option

The MACVLAN receive handler clones skbs to all matching source MACVLAN
interfaces, before it passes the packet along to match on destination
based MACVLANs.

When using the MACVLAN nodst mode, passing the packet to destination based
MACVLANs is omitted and the handler returns with RX_HANDLER_CONSUMED.
However, the passed skb is not freed, leaking for any packet processed
with the nodst option.

Properly free the skb when consuming packets to fix that leak.

Fixes: 427f0c8c ("macvlan: Add nodst option to macvlan type source")
Signed-off-by: default avatarMartin Willi <martin@strongswan.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 625e8cb8
...@@ -460,8 +460,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) ...@@ -460,8 +460,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
return RX_HANDLER_CONSUMED; return RX_HANDLER_CONSUMED;
*pskb = skb; *pskb = skb;
eth = eth_hdr(skb); eth = eth_hdr(skb);
if (macvlan_forward_source(skb, port, eth->h_source)) if (macvlan_forward_source(skb, port, eth->h_source)) {
kfree_skb(skb);
return RX_HANDLER_CONSUMED; return RX_HANDLER_CONSUMED;
}
src = macvlan_hash_lookup(port, eth->h_source); src = macvlan_hash_lookup(port, eth->h_source);
if (src && src->mode != MACVLAN_MODE_VEPA && if (src && src->mode != MACVLAN_MODE_VEPA &&
src->mode != MACVLAN_MODE_BRIDGE) { src->mode != MACVLAN_MODE_BRIDGE) {
...@@ -480,8 +482,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) ...@@ -480,8 +482,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
return RX_HANDLER_PASS; return RX_HANDLER_PASS;
} }
if (macvlan_forward_source(skb, port, eth->h_source)) if (macvlan_forward_source(skb, port, eth->h_source)) {
kfree_skb(skb);
return RX_HANDLER_CONSUMED; return RX_HANDLER_CONSUMED;
}
if (macvlan_passthru(port)) if (macvlan_passthru(port))
vlan = list_first_or_null_rcu(&port->vlans, vlan = list_first_or_null_rcu(&port->vlans,
struct macvlan_dev, list); struct macvlan_dev, list);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment