On Tue, 21 Jul 2020 12:44:03 +0530
Sriram Krishnan <[email protected]> wrote:

> +     /* When using AF_PACKET we need to drop VLAN header from
> +      * the frame and update the SKB to allow the HOST OS
> +      * to transmit the 802.1Q packet
> +      */
> +     if (skb->protocol == htons(ETH_P_8021Q)) {
> +             u16 vlan_tci = 0;
Unnecessary initialization.

> +             skb_reset_mac_header(skb);
> +             if (eth_type_vlan(eth_hdr(skb)->h_proto)) {
> +                     int pop_err;
> +                     pop_err = __skb_vlan_pop(skb, &vlan_tci);
> +                     if (likely(pop_err == 0)) {
> +                             __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), 
> vlan_tci);
> +                             /* Update the NDIS header pkt lengths */
> +                             packet->total_data_buflen -= VLAN_HLEN;
> +                             rndis_msg->msg_len = packet->total_data_buflen;
> +                             rndis_msg->msg.pkt.data_len = 
> packet->total_data_buflen;
> +                     } else {
> +                             netdev_err(net, "Pop vlan err %x\n", pop_err);
> +                             goto drop;
> +                     }
> +             }
> +     }

Printing error messages is good for debugging but bad IRL.
Users ignore it, or it overflows the log buffer.

A better alternative would be to add a counter to netvsc_ethtool_stats.
Something like:

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index abda736e7c7d..2181d4538ab7 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -897,6 +897,7 @@ struct netvsc_ethtool_stats {
        unsigned long rx_no_memory;
        unsigned long stop_queue;
        unsigned long wake_queue;
+       unsigned long vlan_error;
 };
 
 struct netvsc_ethtool_pcpu_stats {
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 6267f706e8ee..89568276e653 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -605,6 +605,28 @@ static int netvsc_xmit(struct sk_buff *skb, struct 
net_device *net, bool xdp_tx)
                *hash_info = hash;
        }
 
+       /* When using AF_PACKET we need to drop VLAN header from
+        * the frame and update the SKB to allow the HOST OS
+        * to transmit the 802.1Q packet
+        */
+       if (skb->protocol == htons(ETH_P_8021Q)) {
+               skb_reset_mac_header(skb);
+               if (eth_type_vlan(eth_hdr(skb)->h_proto)) {
+                       u16 vlan_tci;
+
+                       if (unlikely(__skb_vlan_pop(skb, &vlan_tci) != 0)) {
+                               ++net_device_ctx->eth_stats.vlan_error;
+                               goto drop;
+                       }
+
+                       __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), 
vlan_tci);
+                       /* Update the NDIS header pkt lengths */
+                       packet->total_data_buflen -= VLAN_HLEN;
+                       rndis_msg->msg_len = packet->total_data_buflen;
+                       rndis_msg->msg.pkt.data_len = packet->total_data_buflen;
+               }
+       }
+
        if (skb_vlan_tag_present(skb)) {
                struct ndis_pkt_8021q_info *vlan;
 
@@ -1427,6 +1449,7 @@ static const struct {
        { "rx_no_memory", offsetof(struct netvsc_ethtool_stats, rx_no_memory) },
        { "stop_queue", offsetof(struct netvsc_ethtool_stats, stop_queue) },
        { "wake_queue", offsetof(struct netvsc_ethtool_stats, wake_queue) },
+       { "vlan_error", offsetof(struct netvsc_ethtool_stats, vlan_error) },
 }, pcpu_stats[] = {
        { "cpu%u_rx_packets",
                offsetof(struct netvsc_ethtool_pcpu_stats, rx_packets) },

        

Reply via email to