|
@@ -305,11 +305,14 @@ static void macvlan_process_broadcast(struct work_struct *w)
|
|
|
|
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
|
|
|
|
|
|
+ if (src)
|
|
|
|
+ dev_put(src->dev);
|
|
kfree_skb(skb);
|
|
kfree_skb(skb);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void macvlan_broadcast_enqueue(struct macvlan_port *port,
|
|
static void macvlan_broadcast_enqueue(struct macvlan_port *port,
|
|
|
|
+ const struct macvlan_dev *src,
|
|
struct sk_buff *skb)
|
|
struct sk_buff *skb)
|
|
{
|
|
{
|
|
struct sk_buff *nskb;
|
|
struct sk_buff *nskb;
|
|
@@ -319,8 +322,12 @@ static void macvlan_broadcast_enqueue(struct macvlan_port *port,
|
|
if (!nskb)
|
|
if (!nskb)
|
|
goto err;
|
|
goto err;
|
|
|
|
|
|
|
|
+ MACVLAN_SKB_CB(nskb)->src = src;
|
|
|
|
+
|
|
spin_lock(&port->bc_queue.lock);
|
|
spin_lock(&port->bc_queue.lock);
|
|
if (skb_queue_len(&port->bc_queue) < MACVLAN_BC_QUEUE_LEN) {
|
|
if (skb_queue_len(&port->bc_queue) < MACVLAN_BC_QUEUE_LEN) {
|
|
|
|
+ if (src)
|
|
|
|
+ dev_hold(src->dev);
|
|
__skb_queue_tail(&port->bc_queue, nskb);
|
|
__skb_queue_tail(&port->bc_queue, nskb);
|
|
err = 0;
|
|
err = 0;
|
|
}
|
|
}
|
|
@@ -429,8 +436,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- MACVLAN_SKB_CB(skb)->src = src;
|
|
|
|
- macvlan_broadcast_enqueue(port, skb);
|
|
|
|
|
|
+ macvlan_broadcast_enqueue(port, src, skb);
|
|
|
|
|
|
return RX_HANDLER_PASS;
|
|
return RX_HANDLER_PASS;
|
|
}
|
|
}
|