diff options
-rw-r--r-- | net/packet/af_packet.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index bd0d14c97d41..83fdd0a87eb6 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -88,6 +88,7 @@ | |||
88 | #include <linux/virtio_net.h> | 88 | #include <linux/virtio_net.h> |
89 | #include <linux/errqueue.h> | 89 | #include <linux/errqueue.h> |
90 | #include <linux/net_tstamp.h> | 90 | #include <linux/net_tstamp.h> |
91 | #include <net/flow_keys.h> | ||
91 | 92 | ||
92 | #ifdef CONFIG_INET | 93 | #ifdef CONFIG_INET |
93 | #include <net/inet_common.h> | 94 | #include <net/inet_common.h> |
@@ -1412,6 +1413,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock, | |||
1412 | __be16 proto = 0; | 1413 | __be16 proto = 0; |
1413 | int err; | 1414 | int err; |
1414 | int extra_len = 0; | 1415 | int extra_len = 0; |
1416 | struct flow_keys keys; | ||
1415 | 1417 | ||
1416 | /* | 1418 | /* |
1417 | * Get and verify the address. | 1419 | * Get and verify the address. |
@@ -1512,6 +1514,11 @@ retry: | |||
1512 | if (unlikely(extra_len == 4)) | 1514 | if (unlikely(extra_len == 4)) |
1513 | skb->no_fcs = 1; | 1515 | skb->no_fcs = 1; |
1514 | 1516 | ||
1517 | if (skb_flow_dissect(skb, &keys)) | ||
1518 | skb_set_transport_header(skb, keys.thoff); | ||
1519 | else | ||
1520 | skb_reset_transport_header(skb); | ||
1521 | |||
1515 | dev_queue_xmit(skb); | 1522 | dev_queue_xmit(skb); |
1516 | rcu_read_unlock(); | 1523 | rcu_read_unlock(); |
1517 | return len; | 1524 | return len; |
@@ -1918,6 +1925,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
1918 | struct page *page; | 1925 | struct page *page; |
1919 | void *data; | 1926 | void *data; |
1920 | int err; | 1927 | int err; |
1928 | struct flow_keys keys; | ||
1921 | 1929 | ||
1922 | ph.raw = frame; | 1930 | ph.raw = frame; |
1923 | 1931 | ||
@@ -1943,6 +1951,11 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
1943 | skb_reserve(skb, hlen); | 1951 | skb_reserve(skb, hlen); |
1944 | skb_reset_network_header(skb); | 1952 | skb_reset_network_header(skb); |
1945 | 1953 | ||
1954 | if (skb_flow_dissect(skb, &keys)) | ||
1955 | skb_set_transport_header(skb, keys.thoff); | ||
1956 | else | ||
1957 | skb_reset_transport_header(skb); | ||
1958 | |||
1946 | if (po->tp_tx_has_off) { | 1959 | if (po->tp_tx_has_off) { |
1947 | int off_min, off_max, off; | 1960 | int off_min, off_max, off; |
1948 | off_min = po->tp_hdrlen - sizeof(struct sockaddr_ll); | 1961 | off_min = po->tp_hdrlen - sizeof(struct sockaddr_ll); |
@@ -2199,6 +2212,7 @@ static int packet_snd(struct socket *sock, | |||
2199 | unsigned short gso_type = 0; | 2212 | unsigned short gso_type = 0; |
2200 | int hlen, tlen; | 2213 | int hlen, tlen; |
2201 | int extra_len = 0; | 2214 | int extra_len = 0; |
2215 | struct flow_keys keys; | ||
2202 | 2216 | ||
2203 | /* | 2217 | /* |
2204 | * Get and verify the address. | 2218 | * Get and verify the address. |
@@ -2351,6 +2365,13 @@ static int packet_snd(struct socket *sock, | |||
2351 | len += vnet_hdr_len; | 2365 | len += vnet_hdr_len; |
2352 | } | 2366 | } |
2353 | 2367 | ||
2368 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
2369 | skb_set_transport_header(skb, skb_checksum_start_offset(skb)); | ||
2370 | else if (skb_flow_dissect(skb, &keys)) | ||
2371 | skb_set_transport_header(skb, keys.thoff); | ||
2372 | else | ||
2373 | skb_set_transport_header(skb, reserve); | ||
2374 | |||
2354 | if (unlikely(extra_len == 4)) | 2375 | if (unlikely(extra_len == 4)) |
2355 | skb->no_fcs = 1; | 2376 | skb->no_fcs = 1; |
2356 | 2377 | ||