aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet/af_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r--net/packet/af_packet.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 2dbb32b988c4..ae2d484416dd 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1459,6 +1459,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
1459 struct net_device *dev; 1459 struct net_device *dev;
1460 __be16 proto = 0; 1460 __be16 proto = 0;
1461 int err; 1461 int err;
1462 int extra_len = 0;
1462 1463
1463 /* 1464 /*
1464 * Get and verify the address. 1465 * Get and verify the address.
@@ -1493,8 +1494,16 @@ retry:
1493 * raw protocol and you must do your own fragmentation at this level. 1494 * raw protocol and you must do your own fragmentation at this level.
1494 */ 1495 */
1495 1496
1497 if (unlikely(sock_flag(sk, SOCK_NOFCS))) {
1498 if (!netif_supports_nofcs(dev)) {
1499 err = -EPROTONOSUPPORT;
1500 goto out_unlock;
1501 }
1502 extra_len = 4; /* We're doing our own CRC */
1503 }
1504
1496 err = -EMSGSIZE; 1505 err = -EMSGSIZE;
1497 if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN) 1506 if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN + extra_len)
1498 goto out_unlock; 1507 goto out_unlock;
1499 1508
1500 if (!skb) { 1509 if (!skb) {
@@ -1526,7 +1535,7 @@ retry:
1526 goto retry; 1535 goto retry;
1527 } 1536 }
1528 1537
1529 if (len > (dev->mtu + dev->hard_header_len)) { 1538 if (len > (dev->mtu + dev->hard_header_len + extra_len)) {
1530 /* Earlier code assumed this would be a VLAN pkt, 1539 /* Earlier code assumed this would be a VLAN pkt,
1531 * double-check this now that we have the actual 1540 * double-check this now that we have the actual
1532 * packet in hand. 1541 * packet in hand.
@@ -1548,6 +1557,9 @@ retry:
1548 if (err < 0) 1557 if (err < 0)
1549 goto out_unlock; 1558 goto out_unlock;
1550 1559
1560 if (unlikely(extra_len == 4))
1561 skb->no_fcs = 1;
1562
1551 dev_queue_xmit(skb); 1563 dev_queue_xmit(skb);
1552 rcu_read_unlock(); 1564 rcu_read_unlock();
1553 return len; 1565 return len;
@@ -2209,6 +2221,7 @@ static int packet_snd(struct socket *sock,
2209 struct packet_sock *po = pkt_sk(sk); 2221 struct packet_sock *po = pkt_sk(sk);
2210 unsigned short gso_type = 0; 2222 unsigned short gso_type = 0;
2211 int hlen, tlen; 2223 int hlen, tlen;
2224 int extra_len = 0;
2212 2225
2213 /* 2226 /*
2214 * Get and verify the address. 2227 * Get and verify the address.
@@ -2288,8 +2301,16 @@ static int packet_snd(struct socket *sock,
2288 } 2301 }
2289 } 2302 }
2290 2303
2304 if (unlikely(sock_flag(sk, SOCK_NOFCS))) {
2305 if (!netif_supports_nofcs(dev)) {
2306 err = -EPROTONOSUPPORT;
2307 goto out_unlock;
2308 }
2309 extra_len = 4; /* We're doing our own CRC */
2310 }
2311
2291 err = -EMSGSIZE; 2312 err = -EMSGSIZE;
2292 if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN)) 2313 if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN + extra_len))
2293 goto out_unlock; 2314 goto out_unlock;
2294 2315
2295 err = -ENOBUFS; 2316 err = -ENOBUFS;
@@ -2315,7 +2336,7 @@ static int packet_snd(struct socket *sock,
2315 if (err < 0) 2336 if (err < 0)
2316 goto out_free; 2337 goto out_free;
2317 2338
2318 if (!gso_type && (len > dev->mtu + reserve)) { 2339 if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
2319 /* Earlier code assumed this would be a VLAN pkt, 2340 /* Earlier code assumed this would be a VLAN pkt,
2320 * double-check this now that we have the actual 2341 * double-check this now that we have the actual
2321 * packet in hand. 2342 * packet in hand.
@@ -2353,6 +2374,9 @@ static int packet_snd(struct socket *sock,
2353 len += vnet_hdr_len; 2374 len += vnet_hdr_len;
2354 } 2375 }
2355 2376
2377 if (unlikely(extra_len == 4))
2378 skb->no_fcs = 1;
2379
2356 /* 2380 /*
2357 * Now send it 2381 * Now send it
2358 */ 2382 */