diff options
| author | Tom Herbert <therbert@google.com> | 2014-10-14 18:19:06 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-10-15 12:11:00 -0400 |
| commit | 04ffcb255f22a2a988ce7393e6e72f6eb3fcb7aa (patch) | |
| tree | fd5367f3d55fad3b3b9b33a378b9cf4d1eb2298b /include/linux | |
| parent | 71ae8f5271b31da1172751059deb8bfc32b2b759 (diff) | |
net: Add ndo_gso_check
Add ndo_gso_check which a device can define to indicate whether is
is capable of doing GSO on a packet. This funciton would be called from
the stack to determine whether software GSO is needed to be done. A
driver should populate this function if it advertises GSO types for
which there are combinations that it wouldn't be able to handle. For
instance a device that performs UDP tunneling might only implement
support for transparent Ethernet bridging type of inner packets
or might have limitations on lengths of inner headers.
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/netdevice.h | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 838407aea705..74fd5d37f15a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -998,6 +998,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, | |||
| 998 | * Callback to use for xmit over the accelerated station. This | 998 | * Callback to use for xmit over the accelerated station. This |
| 999 | * is used in place of ndo_start_xmit on accelerated net | 999 | * is used in place of ndo_start_xmit on accelerated net |
| 1000 | * devices. | 1000 | * devices. |
| 1001 | * bool (*ndo_gso_check) (struct sk_buff *skb, | ||
| 1002 | * struct net_device *dev); | ||
| 1003 | * Called by core transmit path to determine if device is capable of | ||
| 1004 | * performing GSO on a packet. The device returns true if it is | ||
| 1005 | * able to GSO the packet, false otherwise. If the return value is | ||
| 1006 | * false the stack will do software GSO. | ||
| 1001 | */ | 1007 | */ |
| 1002 | struct net_device_ops { | 1008 | struct net_device_ops { |
| 1003 | int (*ndo_init)(struct net_device *dev); | 1009 | int (*ndo_init)(struct net_device *dev); |
| @@ -1147,6 +1153,8 @@ struct net_device_ops { | |||
| 1147 | struct net_device *dev, | 1153 | struct net_device *dev, |
| 1148 | void *priv); | 1154 | void *priv); |
| 1149 | int (*ndo_get_lock_subclass)(struct net_device *dev); | 1155 | int (*ndo_get_lock_subclass)(struct net_device *dev); |
| 1156 | bool (*ndo_gso_check) (struct sk_buff *skb, | ||
| 1157 | struct net_device *dev); | ||
| 1150 | }; | 1158 | }; |
| 1151 | 1159 | ||
| 1152 | /** | 1160 | /** |
| @@ -3572,10 +3580,12 @@ static inline bool skb_gso_ok(struct sk_buff *skb, netdev_features_t features) | |||
| 3572 | (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST)); | 3580 | (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST)); |
| 3573 | } | 3581 | } |
| 3574 | 3582 | ||
| 3575 | static inline bool netif_needs_gso(struct sk_buff *skb, | 3583 | static inline bool netif_needs_gso(struct net_device *dev, struct sk_buff *skb, |
| 3576 | netdev_features_t features) | 3584 | netdev_features_t features) |
| 3577 | { | 3585 | { |
| 3578 | return skb_is_gso(skb) && (!skb_gso_ok(skb, features) || | 3586 | return skb_is_gso(skb) && (!skb_gso_ok(skb, features) || |
| 3587 | (dev->netdev_ops->ndo_gso_check && | ||
| 3588 | !dev->netdev_ops->ndo_gso_check(skb, dev)) || | ||
| 3579 | unlikely((skb->ip_summed != CHECKSUM_PARTIAL) && | 3589 | unlikely((skb->ip_summed != CHECKSUM_PARTIAL) && |
| 3580 | (skb->ip_summed != CHECKSUM_UNNECESSARY))); | 3590 | (skb->ip_summed != CHECKSUM_UNNECESSARY))); |
| 3581 | } | 3591 | } |
