aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-02-22 15:55:32 -0500
committerDavid S. Miller <davem@davemloft.net>2019-02-22 15:55:32 -0500
commitd29d1c4957d4dde1a7578b10f2a2d1fae39bd47a (patch)
treeb41c5aa5786c702502de08f1560751c51170156e /include/linux
parent5328b633c9b3c3af38bec8cb70120658c0866e0a (diff)
parent41f5f63cd17530d9eddaf99a71f5d069afd787d8 (diff)
Merge branch 'AF_PACKET-transport_offset-fix'
Maxim Mikityanskiy says: ==================== AF_PACKET transport_offset fix This patch series contains the implementation of the RFC that was posted on this mailing list previously: https://www.spinics.net/lists/netdev/msg541709.html It fixes having incorrect skb->transport_header values in cases when dissect fails. Having correct values set by the kernel fixes mlx5 operation and allows to remove some unnecessary code flows in mlx5. v2 changes: - Rebase against the fresh net-next. - Don't return bool from skb_probe_transport_header (and don't rename the function). - WARN_ON_ONCE and error path in case of GSO without the L4 header. ==================== Acked-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/etherdevice.h1
-rw-r--r--include/linux/netdevice.h10
-rw-r--r--include/linux/skbuff.h5
-rw-r--r--include/linux/virtio_net.h2
4 files changed, 13 insertions, 5 deletions
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 2c0af7b00715..e2f3b21cd72a 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -44,6 +44,7 @@ int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh,
44 __be16 type); 44 __be16 type);
45void eth_header_cache_update(struct hh_cache *hh, const struct net_device *dev, 45void eth_header_cache_update(struct hh_cache *hh, const struct net_device *dev,
46 const unsigned char *haddr); 46 const unsigned char *haddr);
47__be16 eth_header_parse_protocol(const struct sk_buff *skb);
47int eth_prepare_mac_addr_change(struct net_device *dev, void *p); 48int eth_prepare_mac_addr_change(struct net_device *dev, void *p);
48void eth_commit_mac_addr_change(struct net_device *dev, void *p); 49void eth_commit_mac_addr_change(struct net_device *dev, void *p);
49int eth_mac_addr(struct net_device *dev, void *p); 50int eth_mac_addr(struct net_device *dev, void *p);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index aab4d9f6613d..6997f62cb6a0 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -274,6 +274,7 @@ struct header_ops {
274 const struct net_device *dev, 274 const struct net_device *dev,
275 const unsigned char *haddr); 275 const unsigned char *haddr);
276 bool (*validate)(const char *ll_header, unsigned int len); 276 bool (*validate)(const char *ll_header, unsigned int len);
277 __be16 (*parse_protocol)(const struct sk_buff *skb);
277}; 278};
278 279
279/* These flag bits are private to the generic network queueing 280/* These flag bits are private to the generic network queueing
@@ -2939,6 +2940,15 @@ static inline int dev_parse_header(const struct sk_buff *skb,
2939 return dev->header_ops->parse(skb, haddr); 2940 return dev->header_ops->parse(skb, haddr);
2940} 2941}
2941 2942
2943static inline __be16 dev_parse_header_protocol(const struct sk_buff *skb)
2944{
2945 const struct net_device *dev = skb->dev;
2946
2947 if (!dev->header_ops || !dev->header_ops->parse_protocol)
2948 return 0;
2949 return dev->header_ops->parse_protocol(skb);
2950}
2951
2942/* ll_header must have at least hard_header_len allocated */ 2952/* ll_header must have at least hard_header_len allocated */
2943static inline bool dev_validate_header(const struct net_device *dev, 2953static inline bool dev_validate_header(const struct net_device *dev,
2944 char *ll_header, int len) 2954 char *ll_header, int len)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 2069fb90a559..27beb549ffbe 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2429,8 +2429,7 @@ static inline void skb_pop_mac_header(struct sk_buff *skb)
2429 skb->mac_header = skb->network_header; 2429 skb->mac_header = skb->network_header;
2430} 2430}
2431 2431
2432static inline void skb_probe_transport_header(struct sk_buff *skb, 2432static inline void skb_probe_transport_header(struct sk_buff *skb)
2433 const int offset_hint)
2434{ 2433{
2435 struct flow_keys_basic keys; 2434 struct flow_keys_basic keys;
2436 2435
@@ -2439,8 +2438,6 @@ static inline void skb_probe_transport_header(struct sk_buff *skb,
2439 2438
2440 if (skb_flow_dissect_flow_keys_basic(skb, &keys, NULL, 0, 0, 0, 0)) 2439 if (skb_flow_dissect_flow_keys_basic(skb, &keys, NULL, 0, 0, 0, 0))
2441 skb_set_transport_header(skb, keys.control.thoff); 2440 skb_set_transport_header(skb, keys.control.thoff);
2442 else if (offset_hint >= 0)
2443 skb_set_transport_header(skb, offset_hint);
2444} 2441}
2445 2442
2446static inline void skb_mac_header_rebuild(struct sk_buff *skb) 2443static inline void skb_mac_header_rebuild(struct sk_buff *skb)
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index 71f2394abbf7..6728bf581e98 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -62,7 +62,7 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
62 * probe and drop if does not match one of the above types. 62 * probe and drop if does not match one of the above types.
63 */ 63 */
64 if (gso_type) { 64 if (gso_type) {
65 skb_probe_transport_header(skb, -1); 65 skb_probe_transport_header(skb);
66 if (!skb_transport_header_was_set(skb)) 66 if (!skb_transport_header_was_set(skb))
67 return -EINVAL; 67 return -EINVAL;
68 } 68 }