On 2018/06/03 23:33, David Miller wrote:
> From: Elad Nachman <ela...@gmail.com>
> Date: Wed, 30 May 2018 08:48:25 +0300
> 
>>  static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb)
>>  {
>> -    struct ethhdr *ehdr;
>> +    struct vlan_ethhdr *veth;
>>      u16 vlanid;
>> +    __be16 vlan_proto;
> 
> Please order local variables from longest to shortest line.
> 
>>  
>> -    if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) ==
>> -        NETIF_F_HW_VLAN_CTAG_RX &&
>> -        !__vlan_get_tag(skb, &vlanid)) {
>> +    if (!__vlan_get_tag(skb, &vlanid)) {
>>              /* pop the vlan tag */
>> -            ehdr = (struct ethhdr *)skb->data;
>> -            memmove(skb->data + VLAN_HLEN, ehdr, ETH_ALEN * 2);
>> +            veth = (struct vlan_ethhdr *)skb->data;
>> +            vlan_proto = veth->h_vlan_proto;
>> +            memmove(skb->data + VLAN_HLEN, veth, ETH_ALEN * 2);
>>              skb_pull(skb, VLAN_HLEN);
>> -            __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlanid);
>> +            __vlan_hwaccel_put_tag(skb, vlan_proto, vlanid);
>>      }
>>  }
> 
> I can't see how it is valid to do an unconditional software VLAN
> untagging even when VLAN is disabled in the kernel config or the
> NETIF_F_* feature bits are not set.

Right. It is not valid.

> 
> At a minimum that feature test has to stay there, and when it's clear
> we let the generic VLAN code untag the packet.

Since NETIF_F_HW_VLAN_*_RX are not protocol agnostic, we need two kind
of similar checking here.

veth = (struct vlan_ethhdr *)skb->data;
vlan_proto = veth->h_vlan_proto;
if ((vlan_proto == htons(ETH_P_8021Q) &&
     dev->features & NETIF_F_HW_VLAN_CTAG_RX) ||
    (vlan_proto == htons(ETH_P_8021AD) &&
     dev->features & NETIF_F_HW_VLAN_STAG_RX) {
        vlanid = ntohs(veth->h_vlan_TCI);
        memmove(...);
        skb_pull(...);
        __vlan_hwaccel_put_tag(skb, vlan_proto, vlanid);
}

An alternative way is not to check vlan_proto or features here but
compile this code only when VLAN is enabled in the kernel config. This
can be valid only because this driver does not have NETIF_F_HW_VLAN_*_RX
in hw_features and they can not be toggled for now.

static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb)
{
#ifdef STMMAC_VLAN_TAG_USED
        ...
        if (!__vlan_get_tag(skb, &vlanid)) {
                ...
                __vlan_hwaccel_put_tag(skb, vlan_proto, vlanid);
        }
#endif
}

-- 
Toshiaki Makita

Reply via email to