aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/include/asm/socket.h3
-rw-r--r--arch/arm/include/asm/socket.h3
-rw-r--r--arch/avr32/include/asm/socket.h3
-rw-r--r--arch/cris/include/asm/socket.h3
-rw-r--r--arch/frv/include/asm/socket.h3
-rw-r--r--arch/h8300/include/asm/socket.h3
-rw-r--r--arch/ia64/include/asm/socket.h3
-rw-r--r--arch/m32r/include/asm/socket.h3
-rw-r--r--arch/m68k/include/asm/socket.h3
-rw-r--r--arch/mips/include/asm/socket.h3
-rw-r--r--arch/mn10300/include/asm/socket.h3
-rw-r--r--arch/parisc/include/asm/socket.h4
-rw-r--r--arch/powerpc/include/asm/socket.h3
-rw-r--r--arch/s390/include/asm/socket.h3
-rw-r--r--arch/sparc/include/asm/socket.h4
-rw-r--r--arch/xtensa/include/asm/socket.h3
-rw-r--r--include/asm-generic/socket.h4
-rw-r--r--include/linux/if.h2
-rw-r--r--include/linux/netdevice.h8
-rw-r--r--include/linux/skbuff.h4
-rw-r--r--include/net/sock.h4
-rw-r--r--net/core/skbuff.c1
-rw-r--r--net/core/sock.c5
-rw-r--r--net/packet/af_packet.c32
24 files changed, 104 insertions, 6 deletions
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h
index 16449d330dae..dcb221a4b5be 100644
--- a/arch/alpha/include/asm/socket.h
+++ b/arch/alpha/include/asm/socket.h
@@ -73,6 +73,9 @@
73#define SCM_WIFI_STATUS SO_WIFI_STATUS 73#define SCM_WIFI_STATUS SO_WIFI_STATUS
74#define SO_PEEK_OFF 42 74#define SO_PEEK_OFF 42
75 75
76/* Instruct lower device to use last 4-bytes of skb data as FCS */
77#define SO_NOFCS 43
78
76/* O_NONBLOCK clashes with the bits used for socket types. Therefore we 79/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
77 * have to define SOCK_NONBLOCK to a different value here. 80 * have to define SOCK_NONBLOCK to a different value here.
78 */ 81 */
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h
index d958c74e5260..6433cadb6ed4 100644
--- a/arch/arm/include/asm/socket.h
+++ b/arch/arm/include/asm/socket.h
@@ -66,4 +66,7 @@
66#define SCM_WIFI_STATUS SO_WIFI_STATUS 66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67#define SO_PEEK_OFF 42 67#define SO_PEEK_OFF 42
68 68
69/* Instruct lower device to use last 4-bytes of skb data as FCS */
70#define SO_NOFCS 43
71
69#endif /* _ASM_SOCKET_H */ 72#endif /* _ASM_SOCKET_H */
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/asm/socket.h
index 30078f98b3ab..a473f8c6a9aa 100644
--- a/arch/avr32/include/asm/socket.h
+++ b/arch/avr32/include/asm/socket.h
@@ -66,4 +66,7 @@
66#define SCM_WIFI_STATUS SO_WIFI_STATUS 66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67#define SO_PEEK_OFF 42 67#define SO_PEEK_OFF 42
68 68
69/* Instruct lower device to use last 4-bytes of skb data as FCS */
70#define SO_NOFCS 43
71
69#endif /* __ASM_AVR32_SOCKET_H */ 72#endif /* __ASM_AVR32_SOCKET_H */
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h
index 048aba64600c..ae52825021af 100644
--- a/arch/cris/include/asm/socket.h
+++ b/arch/cris/include/asm/socket.h
@@ -68,6 +68,9 @@
68#define SCM_WIFI_STATUS SO_WIFI_STATUS 68#define SCM_WIFI_STATUS SO_WIFI_STATUS
69#define SO_PEEK_OFF 42 69#define SO_PEEK_OFF 42
70 70
71/* Instruct lower device to use last 4-bytes of skb data as FCS */
72#define SO_NOFCS 43
73
71#endif /* _ASM_SOCKET_H */ 74#endif /* _ASM_SOCKET_H */
72 75
73 76
diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/asm/socket.h
index 7a361810f3cc..a5b1d7dbb205 100644
--- a/arch/frv/include/asm/socket.h
+++ b/arch/frv/include/asm/socket.h
@@ -66,5 +66,8 @@
66#define SCM_WIFI_STATUS SO_WIFI_STATUS 66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67#define SO_PEEK_OFF 42 67#define SO_PEEK_OFF 42
68 68
69/* Instruct lower device to use last 4-bytes of skb data as FCS */
70#define SO_NOFCS 43
71
69#endif /* _ASM_SOCKET_H */ 72#endif /* _ASM_SOCKET_H */
70 73
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h
index e7bbfcee5b99..ec4554e7b04b 100644
--- a/arch/h8300/include/asm/socket.h
+++ b/arch/h8300/include/asm/socket.h
@@ -66,4 +66,7 @@
66#define SCM_WIFI_STATUS SO_WIFI_STATUS 66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67#define SO_PEEK_OFF 42 67#define SO_PEEK_OFF 42
68 68
69/* Instruct lower device to use last 4-bytes of skb data as FCS */
70#define SO_NOFCS 43
71
69#endif /* _ASM_SOCKET_H */ 72#endif /* _ASM_SOCKET_H */
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h
index ced62de9d5a9..41fc28a4a18a 100644
--- a/arch/ia64/include/asm/socket.h
+++ b/arch/ia64/include/asm/socket.h
@@ -75,4 +75,7 @@
75#define SCM_WIFI_STATUS SO_WIFI_STATUS 75#define SCM_WIFI_STATUS SO_WIFI_STATUS
76#define SO_PEEK_OFF 42 76#define SO_PEEK_OFF 42
77 77
78/* Instruct lower device to use last 4-bytes of skb data as FCS */
79#define SO_NOFCS 43
80
78#endif /* _ASM_IA64_SOCKET_H */ 81#endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/m32r/include/asm/socket.h b/arch/m32r/include/asm/socket.h
index 696cb4c7ca4e..a15f40b52783 100644
--- a/arch/m32r/include/asm/socket.h
+++ b/arch/m32r/include/asm/socket.h
@@ -66,4 +66,7 @@
66#define SCM_WIFI_STATUS SO_WIFI_STATUS 66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67#define SO_PEEK_OFF 42 67#define SO_PEEK_OFF 42
68 68
69/* Instruct lower device to use last 4-bytes of skb data as FCS */
70#define SO_NOFCS 43
71
69#endif /* _ASM_M32R_SOCKET_H */ 72#endif /* _ASM_M32R_SOCKET_H */
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h
index e8b41a6775f9..d1be684edf97 100644
--- a/arch/m68k/include/asm/socket.h
+++ b/arch/m68k/include/asm/socket.h
@@ -66,4 +66,7 @@
66#define SCM_WIFI_STATUS SO_WIFI_STATUS 66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67#define SO_PEEK_OFF 42 67#define SO_PEEK_OFF 42
68 68
69/* Instruct lower device to use last 4-bytes of skb data as FCS */
70#define SO_NOFCS 43
71
69#endif /* _ASM_SOCKET_H */ 72#endif /* _ASM_SOCKET_H */
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h
index 52104872e9e3..a2ed6fdad4e0 100644
--- a/arch/mips/include/asm/socket.h
+++ b/arch/mips/include/asm/socket.h
@@ -86,6 +86,9 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
86#define SCM_WIFI_STATUS SO_WIFI_STATUS 86#define SCM_WIFI_STATUS SO_WIFI_STATUS
87#define SO_PEEK_OFF 42 87#define SO_PEEK_OFF 42
88 88
89/* Instruct lower device to use last 4-bytes of skb data as FCS */
90#define SO_NOFCS 43
91
89#ifdef __KERNEL__ 92#ifdef __KERNEL__
90 93
91/** sock_type - Socket types 94/** sock_type - Socket types
diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/asm/socket.h
index 013fcc51698f..820463a484b8 100644
--- a/arch/mn10300/include/asm/socket.h
+++ b/arch/mn10300/include/asm/socket.h
@@ -66,4 +66,7 @@
66#define SCM_WIFI_STATUS SO_WIFI_STATUS 66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67#define SO_PEEK_OFF 42 67#define SO_PEEK_OFF 42
68 68
69/* Instruct lower device to use last 4-bytes of skb data as FCS */
70#define SO_NOFCS 43
71
69#endif /* _ASM_SOCKET_H */ 72#endif /* _ASM_SOCKET_H */
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h
index f717c9bec16f..1b52c2c31a7a 100644
--- a/arch/parisc/include/asm/socket.h
+++ b/arch/parisc/include/asm/socket.h
@@ -65,6 +65,10 @@
65#define SCM_WIFI_STATUS SO_WIFI_STATUS 65#define SCM_WIFI_STATUS SO_WIFI_STATUS
66#define SO_PEEK_OFF 0x4023 66#define SO_PEEK_OFF 0x4023
67 67
68/* Instruct lower device to use last 4-bytes of skb data as FCS */
69#define SO_NOFCS 0x4024
70
71
68/* O_NONBLOCK clashes with the bits used for socket types. Therefore we 72/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
69 * have to define SOCK_NONBLOCK to a different value here. 73 * have to define SOCK_NONBLOCK to a different value here.
70 */ 74 */
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h
index fe1c0b478fd7..3d5179bb122f 100644
--- a/arch/powerpc/include/asm/socket.h
+++ b/arch/powerpc/include/asm/socket.h
@@ -73,4 +73,7 @@
73#define SCM_WIFI_STATUS SO_WIFI_STATUS 73#define SCM_WIFI_STATUS SO_WIFI_STATUS
74#define SO_PEEK_OFF 42 74#define SO_PEEK_OFF 42
75 75
76/* Instruct lower device to use last 4-bytes of skb data as FCS */
77#define SO_NOFCS 43
78
76#endif /* _ASM_POWERPC_SOCKET_H */ 79#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h
index 581702fa1b0c..c91b720965c0 100644
--- a/arch/s390/include/asm/socket.h
+++ b/arch/s390/include/asm/socket.h
@@ -74,4 +74,7 @@
74#define SCM_WIFI_STATUS SO_WIFI_STATUS 74#define SCM_WIFI_STATUS SO_WIFI_STATUS
75#define SO_PEEK_OFF 42 75#define SO_PEEK_OFF 42
76 76
77/* Instruct lower device to use last 4-bytes of skb data as FCS */
78#define SO_NOFCS 43
79
77#endif /* _ASM_SOCKET_H */ 80#endif /* _ASM_SOCKET_H */
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h
index 68e2e2746f6f..bea1568ae4af 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/asm/socket.h
@@ -62,6 +62,10 @@
62#define SCM_WIFI_STATUS SO_WIFI_STATUS 62#define SCM_WIFI_STATUS SO_WIFI_STATUS
63#define SO_PEEK_OFF 0x0026 63#define SO_PEEK_OFF 0x0026
64 64
65/* Instruct lower device to use last 4-bytes of skb data as FCS */
66#define SO_NOFCS 0x0027
67
68
65/* Security levels - as per NRL IPv6 - don't actually do anything */ 69/* Security levels - as per NRL IPv6 - don't actually do anything */
66#define SO_SECURITY_AUTHENTICATION 0x5001 70#define SO_SECURITY_AUTHENTICATION 0x5001
67#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 71#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/arch/xtensa/include/asm/socket.h b/arch/xtensa/include/asm/socket.h
index 74818b161362..e36c68184920 100644
--- a/arch/xtensa/include/asm/socket.h
+++ b/arch/xtensa/include/asm/socket.h
@@ -77,4 +77,7 @@
77#define SCM_WIFI_STATUS SO_WIFI_STATUS 77#define SCM_WIFI_STATUS SO_WIFI_STATUS
78#define SO_PEEK_OFF 42 78#define SO_PEEK_OFF 42
79 79
80/* Instruct lower device to use last 4-bytes of skb data as FCS */
81#define SO_NOFCS 43
82
80#endif /* _XTENSA_SOCKET_H */ 83#endif /* _XTENSA_SOCKET_H */
diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
index d9aaac0c36d4..b1bea03274d5 100644
--- a/include/asm-generic/socket.h
+++ b/include/asm-generic/socket.h
@@ -68,4 +68,8 @@
68#define SO_WIFI_STATUS 41 68#define SO_WIFI_STATUS 41
69#define SCM_WIFI_STATUS SO_WIFI_STATUS 69#define SCM_WIFI_STATUS SO_WIFI_STATUS
70#define SO_PEEK_OFF 42 70#define SO_PEEK_OFF 42
71
72/* Instruct lower device to use last 4-bytes of skb data as FCS */
73#define SO_NOFCS 43
74
71#endif /* __ASM_GENERIC_SOCKET_H */ 75#endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/include/linux/if.h b/include/linux/if.h
index 06b6ef60c821..f995c663c493 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -80,6 +80,8 @@
80 * skbs on transmit */ 80 * skbs on transmit */
81#define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */ 81#define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */
82#define IFF_TEAM_PORT 0x40000 /* device used as team port */ 82#define IFF_TEAM_PORT 0x40000 /* device used as team port */
83#define IFF_SUPP_NOFCS 0x80000 /* device supports sending custom FCS */
84
83 85
84#define IF_GET_IFACE 0x0001 /* for querying only */ 86#define IF_GET_IFACE 0x0001 /* for querying only */
85#define IF_GET_PROTO 0x0002 87#define IF_GET_PROTO 0x0002
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 0eac07c95255..f1b7d037c2c5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1082,7 +1082,8 @@ struct net_device {
1082 const struct header_ops *header_ops; 1082 const struct header_ops *header_ops;
1083 1083
1084 unsigned int flags; /* interface flags (a la BSD) */ 1084 unsigned int flags; /* interface flags (a la BSD) */
1085 unsigned int priv_flags; /* Like 'flags' but invisible to userspace. */ 1085 unsigned int priv_flags; /* Like 'flags' but invisible to userspace.
1086 * See if.h for definitions. */
1086 unsigned short gflags; 1087 unsigned short gflags;
1087 unsigned short padded; /* How much padding added by alloc_netdev() */ 1088 unsigned short padded; /* How much padding added by alloc_netdev() */
1088 1089
@@ -2650,6 +2651,11 @@ static inline int netif_is_bond_slave(struct net_device *dev)
2650 return dev->flags & IFF_SLAVE && dev->priv_flags & IFF_BONDING; 2651 return dev->flags & IFF_SLAVE && dev->priv_flags & IFF_BONDING;
2651} 2652}
2652 2653
2654static inline bool netif_supports_nofcs(struct net_device *dev)
2655{
2656 return dev->priv_flags & IFF_SUPP_NOFCS;
2657}
2658
2653extern struct pernet_operations __net_initdata loopback_net_ops; 2659extern struct pernet_operations __net_initdata loopback_net_ops;
2654 2660
2655/* Logging, debugging and troubleshooting/diagnostic helpers. */ 2661/* Logging, debugging and troubleshooting/diagnostic helpers. */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c11a44ea1bf4..06a4c0fd7bef 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -361,6 +361,7 @@ typedef unsigned char *sk_buff_data_t;
361 * ports. 361 * ports.
362 * @wifi_acked_valid: wifi_acked was set 362 * @wifi_acked_valid: wifi_acked was set
363 * @wifi_acked: whether frame was acked on wifi or not 363 * @wifi_acked: whether frame was acked on wifi or not
364 * @no_fcs: Request NIC to treat last 4 bytes as Ethernet FCS
364 * @dma_cookie: a cookie to one of several possible DMA operations 365 * @dma_cookie: a cookie to one of several possible DMA operations
365 * done by skb DMA functions 366 * done by skb DMA functions
366 * @secmark: security marking 367 * @secmark: security marking
@@ -459,7 +460,8 @@ struct sk_buff {
459 __u8 l4_rxhash:1; 460 __u8 l4_rxhash:1;
460 __u8 wifi_acked_valid:1; 461 __u8 wifi_acked_valid:1;
461 __u8 wifi_acked:1; 462 __u8 wifi_acked:1;
462 /* 10/12 bit hole (depending on ndisc_nodetype presence) */ 463 __u8 no_fcs:1;
464 /* 9/11 bit hole (depending on ndisc_nodetype presence) */
463 kmemcheck_bitfield_end(flags2); 465 kmemcheck_bitfield_end(flags2);
464 466
465#ifdef CONFIG_NET_DMA 467#ifdef CONFIG_NET_DMA
diff --git a/include/net/sock.h b/include/net/sock.h
index 9c0553b9e451..ba761e7de252 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -615,6 +615,10 @@ enum sock_flags {
615 SOCK_RXQ_OVFL, 615 SOCK_RXQ_OVFL,
616 SOCK_ZEROCOPY, /* buffers from userspace */ 616 SOCK_ZEROCOPY, /* buffers from userspace */
617 SOCK_WIFI_STATUS, /* push wifi status to userspace */ 617 SOCK_WIFI_STATUS, /* push wifi status to userspace */
618 SOCK_NOFCS, /* Tell NIC not to do the Ethernet FCS.
619 * Will use last 4 bytes of packet sent from
620 * user-space instead.
621 */
618}; 622};
619 623
620static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) 624static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f3a530780753..6eb656acdfe5 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -592,6 +592,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
592 new->rxhash = old->rxhash; 592 new->rxhash = old->rxhash;
593 new->ooo_okay = old->ooo_okay; 593 new->ooo_okay = old->ooo_okay;
594 new->l4_rxhash = old->l4_rxhash; 594 new->l4_rxhash = old->l4_rxhash;
595 new->no_fcs = old->no_fcs;
595#ifdef CONFIG_XFRM 596#ifdef CONFIG_XFRM
596 new->sp = secpath_get(old->sp); 597 new->sp = secpath_get(old->sp);
597#endif 598#endif
diff --git a/net/core/sock.c b/net/core/sock.c
index 19942d4bb6e6..55011cb691ad 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -799,6 +799,11 @@ set_rcvbuf:
799 else 799 else
800 ret = -EOPNOTSUPP; 800 ret = -EOPNOTSUPP;
801 break; 801 break;
802
803 case SO_NOFCS:
804 sock_valbool_flag(sk, SOCK_NOFCS, valbool);
805 break;
806
802 default: 807 default:
803 ret = -ENOPROTOOPT; 808 ret = -ENOPROTOOPT;
804 break; 809 break;
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 */