|
@@ -1661,6 +1661,29 @@ bool is_skb_forwardable(struct net_device *dev, struct sk_buff *skb)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(is_skb_forwardable);
|
|
|
|
|
|
+int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
|
|
|
+ if (skb_copy_ubufs(skb, GFP_ATOMIC)) {
|
|
|
+ atomic_long_inc(&dev->rx_dropped);
|
|
|
+ kfree_skb(skb);
|
|
|
+ return NET_RX_DROP;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (unlikely(!is_skb_forwardable(dev, skb))) {
|
|
|
+ atomic_long_inc(&dev->rx_dropped);
|
|
|
+ kfree_skb(skb);
|
|
|
+ return NET_RX_DROP;
|
|
|
+ }
|
|
|
+
|
|
|
+ skb_scrub_packet(skb, true);
|
|
|
+ skb->protocol = eth_type_trans(skb, dev);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(__dev_forward_skb);
|
|
|
+
|
|
|
/**
|
|
|
* dev_forward_skb - loopback an skb to another netif
|
|
|
*
|
|
@@ -1681,24 +1704,7 @@ EXPORT_SYMBOL_GPL(is_skb_forwardable);
|
|
|
*/
|
|
|
int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
|
|
|
{
|
|
|
- if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
|
|
|
- if (skb_copy_ubufs(skb, GFP_ATOMIC)) {
|
|
|
- atomic_long_inc(&dev->rx_dropped);
|
|
|
- kfree_skb(skb);
|
|
|
- return NET_RX_DROP;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (unlikely(!is_skb_forwardable(dev, skb))) {
|
|
|
- atomic_long_inc(&dev->rx_dropped);
|
|
|
- kfree_skb(skb);
|
|
|
- return NET_RX_DROP;
|
|
|
- }
|
|
|
-
|
|
|
- skb_scrub_packet(skb, true);
|
|
|
- skb->protocol = eth_type_trans(skb, dev);
|
|
|
-
|
|
|
- return netif_rx_internal(skb);
|
|
|
+ return __dev_forward_skb(dev, skb) ?: netif_rx_internal(skb);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(dev_forward_skb);
|
|
|
|