sfc: Enable accelerated RFS on vlans
authorAndy Lutomirski <luto@amacapital.net>
Fri, 10 May 2013 23:51:33 +0000 (16:51 -0700)
committerBen Hutchings <bhutchings@solarflare.com>
Mon, 24 Jun 2013 18:58:30 +0000 (19:58 +0100)
As far as I know, the hardware doesn't support matching on both IP
fields and vlan tag, but it can at least match on the IP fields.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
drivers/net/ethernet/sfc/filter.c

index 2397f0e8d3ebf7e50c75e13cfeccc9b3c24237fa..b74a60ab9ac79913111a4f79d4a5a8ca1c723862 100644 (file)
@@ -1185,8 +1185,21 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
 
        nhoff = skb_network_offset(skb);
 
-       if (skb->protocol != htons(ETH_P_IP))
+       if (skb->protocol == htons(ETH_P_8021Q)) {
+               EFX_BUG_ON_PARANOID(skb_headlen(skb) <
+                                   nhoff + sizeof(struct vlan_hdr));
+               if (((const struct vlan_hdr *)skb->data + nhoff)->
+                   h_vlan_encapsulated_proto != htons(ETH_P_IP))
+                       return -EPROTONOSUPPORT;
+
+               /* This is IP over 802.1q VLAN.  We can't filter on the
+                * IP 5-tuple and the vlan together, so just strip the
+                * vlan header and filter on the IP part.
+                */
+               nhoff += sizeof(struct vlan_hdr);
+       } else if (skb->protocol != htons(ETH_P_IP)) {
                return -EPROTONOSUPPORT;
+       }
 
        /* RFS must validate the IP header length before calling us */
        EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + sizeof(*ip));