|
@@ -530,6 +530,23 @@ static const struct header_ops vlan_header_ops = {
|
|
|
.parse = eth_header_parse,
|
|
|
};
|
|
|
|
|
|
+static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev,
|
|
|
+ unsigned short type,
|
|
|
+ const void *daddr, const void *saddr,
|
|
|
+ unsigned int len)
|
|
|
+{
|
|
|
+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
|
|
|
+ struct net_device *real_dev = vlan->real_dev;
|
|
|
+
|
|
|
+ return dev_hard_header(skb, real_dev, type, daddr, saddr, len);
|
|
|
+}
|
|
|
+
|
|
|
+static const struct header_ops vlan_passthru_header_ops = {
|
|
|
+ .create = vlan_passthru_hard_header,
|
|
|
+ .rebuild = dev_rebuild_header,
|
|
|
+ .parse = eth_header_parse,
|
|
|
+};
|
|
|
+
|
|
|
static struct device_type vlan_type = {
|
|
|
.name = "vlan",
|
|
|
};
|
|
@@ -573,7 +590,7 @@ static int vlan_dev_init(struct net_device *dev)
|
|
|
|
|
|
dev->needed_headroom = real_dev->needed_headroom;
|
|
|
if (real_dev->features & NETIF_F_HW_VLAN_CTAG_TX) {
|
|
|
- dev->header_ops = real_dev->header_ops;
|
|
|
+ dev->header_ops = &vlan_passthru_header_ops;
|
|
|
dev->hard_header_len = real_dev->hard_header_len;
|
|
|
} else {
|
|
|
dev->header_ops = &vlan_header_ops;
|