diff options
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r-- | net/packet/af_packet.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index d9d4970b9b07..2dbb32b988c4 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1499,10 +1499,11 @@ retry: | |||
1499 | 1499 | ||
1500 | if (!skb) { | 1500 | if (!skb) { |
1501 | size_t reserved = LL_RESERVED_SPACE(dev); | 1501 | size_t reserved = LL_RESERVED_SPACE(dev); |
1502 | int tlen = dev->needed_tailroom; | ||
1502 | unsigned int hhlen = dev->header_ops ? dev->hard_header_len : 0; | 1503 | unsigned int hhlen = dev->header_ops ? dev->hard_header_len : 0; |
1503 | 1504 | ||
1504 | rcu_read_unlock(); | 1505 | rcu_read_unlock(); |
1505 | skb = sock_wmalloc(sk, len + reserved, 0, GFP_KERNEL); | 1506 | skb = sock_wmalloc(sk, len + reserved + tlen, 0, GFP_KERNEL); |
1506 | if (skb == NULL) | 1507 | if (skb == NULL) |
1507 | return -ENOBUFS; | 1508 | return -ENOBUFS; |
1508 | /* FIXME: Save some space for broken drivers that write a hard | 1509 | /* FIXME: Save some space for broken drivers that write a hard |
@@ -1942,7 +1943,7 @@ static void tpacket_destruct_skb(struct sk_buff *skb) | |||
1942 | 1943 | ||
1943 | static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | 1944 | static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
1944 | void *frame, struct net_device *dev, int size_max, | 1945 | void *frame, struct net_device *dev, int size_max, |
1945 | __be16 proto, unsigned char *addr) | 1946 | __be16 proto, unsigned char *addr, int hlen) |
1946 | { | 1947 | { |
1947 | union { | 1948 | union { |
1948 | struct tpacket_hdr *h1; | 1949 | struct tpacket_hdr *h1; |
@@ -1976,7 +1977,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
1976 | return -EMSGSIZE; | 1977 | return -EMSGSIZE; |
1977 | } | 1978 | } |
1978 | 1979 | ||
1979 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1980 | skb_reserve(skb, hlen); |
1980 | skb_reset_network_header(skb); | 1981 | skb_reset_network_header(skb); |
1981 | 1982 | ||
1982 | data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll); | 1983 | data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll); |
@@ -2051,6 +2052,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2051 | unsigned char *addr; | 2052 | unsigned char *addr; |
2052 | int len_sum = 0; | 2053 | int len_sum = 0; |
2053 | int status = 0; | 2054 | int status = 0; |
2055 | int hlen, tlen; | ||
2054 | 2056 | ||
2055 | mutex_lock(&po->pg_vec_lock); | 2057 | mutex_lock(&po->pg_vec_lock); |
2056 | 2058 | ||
@@ -2099,16 +2101,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2099 | } | 2101 | } |
2100 | 2102 | ||
2101 | status = TP_STATUS_SEND_REQUEST; | 2103 | status = TP_STATUS_SEND_REQUEST; |
2104 | hlen = LL_RESERVED_SPACE(dev); | ||
2105 | tlen = dev->needed_tailroom; | ||
2102 | skb = sock_alloc_send_skb(&po->sk, | 2106 | skb = sock_alloc_send_skb(&po->sk, |
2103 | LL_ALLOCATED_SPACE(dev) | 2107 | hlen + tlen + sizeof(struct sockaddr_ll), |
2104 | + sizeof(struct sockaddr_ll), | ||
2105 | 0, &err); | 2108 | 0, &err); |
2106 | 2109 | ||
2107 | if (unlikely(skb == NULL)) | 2110 | if (unlikely(skb == NULL)) |
2108 | goto out_status; | 2111 | goto out_status; |
2109 | 2112 | ||
2110 | tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, | 2113 | tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, |
2111 | addr); | 2114 | addr, hlen); |
2112 | 2115 | ||
2113 | if (unlikely(tp_len < 0)) { | 2116 | if (unlikely(tp_len < 0)) { |
2114 | if (po->tp_loss) { | 2117 | if (po->tp_loss) { |
@@ -2205,6 +2208,7 @@ static int packet_snd(struct socket *sock, | |||
2205 | int vnet_hdr_len; | 2208 | int vnet_hdr_len; |
2206 | struct packet_sock *po = pkt_sk(sk); | 2209 | struct packet_sock *po = pkt_sk(sk); |
2207 | unsigned short gso_type = 0; | 2210 | unsigned short gso_type = 0; |
2211 | int hlen, tlen; | ||
2208 | 2212 | ||
2209 | /* | 2213 | /* |
2210 | * Get and verify the address. | 2214 | * Get and verify the address. |
@@ -2289,8 +2293,9 @@ static int packet_snd(struct socket *sock, | |||
2289 | goto out_unlock; | 2293 | goto out_unlock; |
2290 | 2294 | ||
2291 | err = -ENOBUFS; | 2295 | err = -ENOBUFS; |
2292 | skb = packet_alloc_skb(sk, LL_ALLOCATED_SPACE(dev), | 2296 | hlen = LL_RESERVED_SPACE(dev); |
2293 | LL_RESERVED_SPACE(dev), len, vnet_hdr.hdr_len, | 2297 | tlen = dev->needed_tailroom; |
2298 | skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len, | ||
2294 | msg->msg_flags & MSG_DONTWAIT, &err); | 2299 | msg->msg_flags & MSG_DONTWAIT, &err); |
2295 | if (skb == NULL) | 2300 | if (skb == NULL) |
2296 | goto out_unlock; | 2301 | goto out_unlock; |