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 82a6f34d39d0..0da505c9ac23 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 |
@@ -1944,7 +1945,7 @@ static void tpacket_destruct_skb(struct sk_buff *skb) | |||
1944 | 1945 | ||
1945 | static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | 1946 | static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
1946 | void *frame, struct net_device *dev, int size_max, | 1947 | void *frame, struct net_device *dev, int size_max, |
1947 | __be16 proto, unsigned char *addr) | 1948 | __be16 proto, unsigned char *addr, int hlen) |
1948 | { | 1949 | { |
1949 | union { | 1950 | union { |
1950 | struct tpacket_hdr *h1; | 1951 | struct tpacket_hdr *h1; |
@@ -1978,7 +1979,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
1978 | return -EMSGSIZE; | 1979 | return -EMSGSIZE; |
1979 | } | 1980 | } |
1980 | 1981 | ||
1981 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1982 | skb_reserve(skb, hlen); |
1982 | skb_reset_network_header(skb); | 1983 | skb_reset_network_header(skb); |
1983 | 1984 | ||
1984 | data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll); | 1985 | data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll); |
@@ -2053,6 +2054,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2053 | unsigned char *addr; | 2054 | unsigned char *addr; |
2054 | int len_sum = 0; | 2055 | int len_sum = 0; |
2055 | int status = 0; | 2056 | int status = 0; |
2057 | int hlen, tlen; | ||
2056 | 2058 | ||
2057 | mutex_lock(&po->pg_vec_lock); | 2059 | mutex_lock(&po->pg_vec_lock); |
2058 | 2060 | ||
@@ -2101,16 +2103,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2101 | } | 2103 | } |
2102 | 2104 | ||
2103 | status = TP_STATUS_SEND_REQUEST; | 2105 | status = TP_STATUS_SEND_REQUEST; |
2106 | hlen = LL_RESERVED_SPACE(dev); | ||
2107 | tlen = dev->needed_tailroom; | ||
2104 | skb = sock_alloc_send_skb(&po->sk, | 2108 | skb = sock_alloc_send_skb(&po->sk, |
2105 | LL_ALLOCATED_SPACE(dev) | 2109 | hlen + tlen + sizeof(struct sockaddr_ll), |
2106 | + sizeof(struct sockaddr_ll), | ||
2107 | 0, &err); | 2110 | 0, &err); |
2108 | 2111 | ||
2109 | if (unlikely(skb == NULL)) | 2112 | if (unlikely(skb == NULL)) |
2110 | goto out_status; | 2113 | goto out_status; |
2111 | 2114 | ||
2112 | tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, | 2115 | tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, |
2113 | addr); | 2116 | addr, hlen); |
2114 | 2117 | ||
2115 | if (unlikely(tp_len < 0)) { | 2118 | if (unlikely(tp_len < 0)) { |
2116 | if (po->tp_loss) { | 2119 | if (po->tp_loss) { |
@@ -2207,6 +2210,7 @@ static int packet_snd(struct socket *sock, | |||
2207 | int vnet_hdr_len; | 2210 | int vnet_hdr_len; |
2208 | struct packet_sock *po = pkt_sk(sk); | 2211 | struct packet_sock *po = pkt_sk(sk); |
2209 | unsigned short gso_type = 0; | 2212 | unsigned short gso_type = 0; |
2213 | int hlen, tlen; | ||
2210 | 2214 | ||
2211 | /* | 2215 | /* |
2212 | * Get and verify the address. | 2216 | * Get and verify the address. |
@@ -2291,8 +2295,9 @@ static int packet_snd(struct socket *sock, | |||
2291 | goto out_unlock; | 2295 | goto out_unlock; |
2292 | 2296 | ||
2293 | err = -ENOBUFS; | 2297 | err = -ENOBUFS; |
2294 | skb = packet_alloc_skb(sk, LL_ALLOCATED_SPACE(dev), | 2298 | hlen = LL_RESERVED_SPACE(dev); |
2295 | LL_RESERVED_SPACE(dev), len, vnet_hdr.hdr_len, | 2299 | tlen = dev->needed_tailroom; |
2300 | skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len, | ||
2296 | msg->msg_flags & MSG_DONTWAIT, &err); | 2301 | msg->msg_flags & MSG_DONTWAIT, &err); |
2297 | if (skb == NULL) | 2302 | if (skb == NULL) |
2298 | goto out_unlock; | 2303 | goto out_unlock; |