aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tx.c15
-rw-r--r--drivers/net/tap.c4
-rw-r--r--drivers/net/tun.c4
-rw-r--r--drivers/net/xen-netback/netback.c15
-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
-rw-r--r--net/ethernet/eth.c13
-rw-r--r--net/packet/af_packet.c26
10 files changed, 56 insertions, 39 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
index c1334a8ac8f3..e7aae45a01f8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
@@ -148,12 +148,8 @@ static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)
148 148
149static inline int mlx5e_skb_l3_header_offset(struct sk_buff *skb) 149static inline int mlx5e_skb_l3_header_offset(struct sk_buff *skb)
150{ 150{
151 struct flow_keys keys;
152
153 if (skb_transport_header_was_set(skb)) 151 if (skb_transport_header_was_set(skb))
154 return skb_transport_offset(skb); 152 return skb_transport_offset(skb);
155 else if (skb_flow_dissect_flow_keys(skb, &keys, 0))
156 return keys.control.thoff;
157 else 153 else
158 return mlx5e_skb_l2_header_offset(skb); 154 return mlx5e_skb_l2_header_offset(skb);
159} 155}
@@ -172,15 +168,8 @@ static inline u16 mlx5e_calc_min_inline(enum mlx5_inline_modes mode,
172 hlen += VLAN_HLEN; 168 hlen += VLAN_HLEN;
173 break; 169 break;
174 case MLX5_INLINE_MODE_IP: 170 case MLX5_INLINE_MODE_IP:
175 /* When transport header is set to zero, it means no transport 171 hlen = mlx5e_skb_l3_header_offset(skb);
176 * header. When transport header is set to 0xff's, it means 172 break;
177 * transport header wasn't set.
178 */
179 if (skb_transport_offset(skb)) {
180 hlen = mlx5e_skb_l3_header_offset(skb);
181 break;
182 }
183 /* fall through */
184 case MLX5_INLINE_MODE_L2: 173 case MLX5_INLINE_MODE_L2:
185 default: 174 default:
186 hlen = mlx5e_skb_l2_header_offset(skb); 175 hlen = mlx5e_skb_l2_header_offset(skb);
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index c0b52e48f0e6..2ea9b4976f4a 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -712,7 +712,7 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,
712 goto err_kfree; 712 goto err_kfree;
713 } 713 }
714 714
715 skb_probe_transport_header(skb, ETH_HLEN); 715 skb_probe_transport_header(skb);
716 716
717 /* Move network header to the right position for VLAN tagged packets */ 717 /* Move network header to the right position for VLAN tagged packets */
718 if ((skb->protocol == htons(ETH_P_8021Q) || 718 if ((skb->protocol == htons(ETH_P_8021Q) ||
@@ -1187,7 +1187,7 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
1187 tap = rcu_dereference(q->tap); 1187 tap = rcu_dereference(q->tap);
1188 if (tap) { 1188 if (tap) {
1189 skb->dev = tap->dev; 1189 skb->dev = tap->dev;
1190 skb_probe_transport_header(skb, ETH_HLEN); 1190 skb_probe_transport_header(skb);
1191 dev_queue_xmit(skb); 1191 dev_queue_xmit(skb);
1192 } else { 1192 } else {
1193 kfree_skb(skb); 1193 kfree_skb(skb);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index fed298c0cb39..80bff1b4ec17 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1929,7 +1929,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
1929 } 1929 }
1930 1930
1931 skb_reset_network_header(skb); 1931 skb_reset_network_header(skb);
1932 skb_probe_transport_header(skb, 0); 1932 skb_probe_transport_header(skb);
1933 1933
1934 if (skb_xdp) { 1934 if (skb_xdp) {
1935 struct bpf_prog *xdp_prog; 1935 struct bpf_prog *xdp_prog;
@@ -2482,7 +2482,7 @@ build:
2482 2482
2483 skb->protocol = eth_type_trans(skb, tun->dev); 2483 skb->protocol = eth_type_trans(skb, tun->dev);
2484 skb_reset_network_header(skb); 2484 skb_reset_network_header(skb);
2485 skb_probe_transport_header(skb, 0); 2485 skb_probe_transport_header(skb);
2486 2486
2487 if (skb_xdp) { 2487 if (skb_xdp) {
2488 err = do_xdp_generic(xdp_prog, skb); 2488 err = do_xdp_generic(xdp_prog, skb);
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 80aae3a32c2a..c801a832851c 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1169,15 +1169,24 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
1169 continue; 1169 continue;
1170 } 1170 }
1171 1171
1172 skb_probe_transport_header(skb, 0); 1172 skb_probe_transport_header(skb);
1173 1173
1174 /* If the packet is GSO then we will have just set up the 1174 /* If the packet is GSO then we will have just set up the
1175 * transport header offset in checksum_setup so it's now 1175 * transport header offset in checksum_setup so it's now
1176 * straightforward to calculate gso_segs. 1176 * straightforward to calculate gso_segs.
1177 */ 1177 */
1178 if (skb_is_gso(skb)) { 1178 if (skb_is_gso(skb)) {
1179 int mss = skb_shinfo(skb)->gso_size; 1179 int mss, hdrlen;
1180 int hdrlen = skb_transport_header(skb) - 1180
1181 /* GSO implies having the L4 header. */
1182 WARN_ON_ONCE(!skb_transport_header_was_set(skb));
1183 if (unlikely(!skb_transport_header_was_set(skb))) {
1184 kfree_skb(skb);
1185 continue;
1186 }
1187
1188 mss = skb_shinfo(skb)->gso_size;
1189 hdrlen = skb_transport_header(skb) -
1181 skb_mac_header(skb) + 1190 skb_mac_header(skb) +
1182 tcp_hdrlen(skb); 1191 tcp_hdrlen(skb);
1183 1192
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 }
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 4c520110b04f..f7a3d7a171c7 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -265,6 +265,18 @@ void eth_header_cache_update(struct hh_cache *hh,
265EXPORT_SYMBOL(eth_header_cache_update); 265EXPORT_SYMBOL(eth_header_cache_update);
266 266
267/** 267/**
268 * eth_header_parser_protocol - extract protocol from L2 header
269 * @skb: packet to extract protocol from
270 */
271__be16 eth_header_parse_protocol(const struct sk_buff *skb)
272{
273 const struct ethhdr *eth = eth_hdr(skb);
274
275 return eth->h_proto;
276}
277EXPORT_SYMBOL(eth_header_parse_protocol);
278
279/**
268 * eth_prepare_mac_addr_change - prepare for mac change 280 * eth_prepare_mac_addr_change - prepare for mac change
269 * @dev: network device 281 * @dev: network device
270 * @p: socket address 282 * @p: socket address
@@ -346,6 +358,7 @@ const struct header_ops eth_header_ops ____cacheline_aligned = {
346 .parse = eth_header_parse, 358 .parse = eth_header_parse,
347 .cache = eth_header_cache, 359 .cache = eth_header_cache,
348 .cache_update = eth_header_cache_update, 360 .cache_update = eth_header_cache_update,
361 .parse_protocol = eth_header_parse_protocol,
349}; 362};
350 363
351/** 364/**
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 1cd1d83a4be0..8376bc1c1508 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1850,6 +1850,15 @@ oom:
1850 return 0; 1850 return 0;
1851} 1851}
1852 1852
1853static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)
1854{
1855 if (!skb->protocol && sock->type == SOCK_RAW) {
1856 skb_reset_mac_header(skb);
1857 skb->protocol = dev_parse_header_protocol(skb);
1858 }
1859
1860 skb_probe_transport_header(skb);
1861}
1853 1862
1854/* 1863/*
1855 * Output a raw packet to a device layer. This bypasses all the other 1864 * Output a raw packet to a device layer. This bypasses all the other
@@ -1970,7 +1979,7 @@ retry:
1970 if (unlikely(extra_len == 4)) 1979 if (unlikely(extra_len == 4))
1971 skb->no_fcs = 1; 1980 skb->no_fcs = 1;
1972 1981
1973 skb_probe_transport_header(skb, 0); 1982 packet_parse_headers(skb, sock);
1974 1983
1975 dev_queue_xmit(skb); 1984 dev_queue_xmit(skb);
1976 rcu_read_unlock(); 1985 rcu_read_unlock();
@@ -2404,15 +2413,6 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
2404 sock_wfree(skb); 2413 sock_wfree(skb);
2405} 2414}
2406 2415
2407static void tpacket_set_protocol(const struct net_device *dev,
2408 struct sk_buff *skb)
2409{
2410 if (dev->type == ARPHRD_ETHER) {
2411 skb_reset_mac_header(skb);
2412 skb->protocol = eth_hdr(skb)->h_proto;
2413 }
2414}
2415
2416static int __packet_snd_vnet_parse(struct virtio_net_hdr *vnet_hdr, size_t len) 2416static int __packet_snd_vnet_parse(struct virtio_net_hdr *vnet_hdr, size_t len)
2417{ 2417{
2418 if ((vnet_hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && 2418 if ((vnet_hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
@@ -2483,8 +2483,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2483 return err; 2483 return err;
2484 if (!dev_validate_header(dev, skb->data, hdrlen)) 2484 if (!dev_validate_header(dev, skb->data, hdrlen))
2485 return -EINVAL; 2485 return -EINVAL;
2486 if (!skb->protocol)
2487 tpacket_set_protocol(dev, skb);
2488 2486
2489 data += hdrlen; 2487 data += hdrlen;
2490 to_write -= hdrlen; 2488 to_write -= hdrlen;
@@ -2519,7 +2517,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2519 len = ((to_write > len_max) ? len_max : to_write); 2517 len = ((to_write > len_max) ? len_max : to_write);
2520 } 2518 }
2521 2519
2522 skb_probe_transport_header(skb, 0); 2520 packet_parse_headers(skb, sock);
2523 2521
2524 return tp_len; 2522 return tp_len;
2525} 2523}
@@ -2925,7 +2923,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
2925 virtio_net_hdr_set_proto(skb, &vnet_hdr); 2923 virtio_net_hdr_set_proto(skb, &vnet_hdr);
2926 } 2924 }
2927 2925
2928 skb_probe_transport_header(skb, reserve); 2926 packet_parse_headers(skb, sock);
2929 2927
2930 if (unlikely(extra_len == 4)) 2928 if (unlikely(extra_len == 4))
2931 skb->no_fcs = 1; 2929 skb->no_fcs = 1;