Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: Add framework to allow sending packets with customized CRC.

This is useful for testing RX handling of frames with bad
CRCs.

Requires driver support to actually put the packet on the
wire properly.

Signed-off-by: Ben Greear <greearb@candelatech.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Ben Greear and committed by
Jeff Kirsher
3bdc0eba 0184039a

+104 -6
+3
arch/alpha/include/asm/socket.h
··· 73 73 #define SCM_WIFI_STATUS SO_WIFI_STATUS 74 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 79 /* O_NONBLOCK clashes with the bits used for socket types. Therefore we 77 80 * have to define SOCK_NONBLOCK to a different value here. 78 81 */
+3
arch/arm/include/asm/socket.h
··· 66 66 #define SCM_WIFI_STATUS SO_WIFI_STATUS 67 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 72 #endif /* _ASM_SOCKET_H */
+3
arch/avr32/include/asm/socket.h
··· 66 66 #define SCM_WIFI_STATUS SO_WIFI_STATUS 67 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 72 #endif /* __ASM_AVR32_SOCKET_H */
+3
arch/cris/include/asm/socket.h
··· 68 68 #define SCM_WIFI_STATUS SO_WIFI_STATUS 69 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 74 #endif /* _ASM_SOCKET_H */ 72 75 73 76
+3
arch/frv/include/asm/socket.h
··· 66 66 #define SCM_WIFI_STATUS SO_WIFI_STATUS 67 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 72 #endif /* _ASM_SOCKET_H */ 70 73
+3
arch/h8300/include/asm/socket.h
··· 66 66 #define SCM_WIFI_STATUS SO_WIFI_STATUS 67 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 72 #endif /* _ASM_SOCKET_H */
+3
arch/ia64/include/asm/socket.h
··· 75 75 #define SCM_WIFI_STATUS SO_WIFI_STATUS 76 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 81 #endif /* _ASM_IA64_SOCKET_H */
+3
arch/m32r/include/asm/socket.h
··· 66 66 #define SCM_WIFI_STATUS SO_WIFI_STATUS 67 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 72 #endif /* _ASM_M32R_SOCKET_H */
+3
arch/m68k/include/asm/socket.h
··· 66 66 #define SCM_WIFI_STATUS SO_WIFI_STATUS 67 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 72 #endif /* _ASM_SOCKET_H */
+3
arch/mips/include/asm/socket.h
··· 86 86 #define SCM_WIFI_STATUS SO_WIFI_STATUS 87 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 92 #ifdef __KERNEL__ 90 93 91 94 /** sock_type - Socket types
+3
arch/mn10300/include/asm/socket.h
··· 66 66 #define SCM_WIFI_STATUS SO_WIFI_STATUS 67 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 72 #endif /* _ASM_SOCKET_H */
+4
arch/parisc/include/asm/socket.h
··· 65 65 #define SCM_WIFI_STATUS SO_WIFI_STATUS 66 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 72 /* O_NONBLOCK clashes with the bits used for socket types. Therefore we 69 73 * have to define SOCK_NONBLOCK to a different value here. 70 74 */
+3
arch/powerpc/include/asm/socket.h
··· 73 73 #define SCM_WIFI_STATUS SO_WIFI_STATUS 74 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 79 #endif /* _ASM_POWERPC_SOCKET_H */
+3
arch/s390/include/asm/socket.h
··· 74 74 #define SCM_WIFI_STATUS SO_WIFI_STATUS 75 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 80 #endif /* _ASM_SOCKET_H */
+4
arch/sparc/include/asm/socket.h
··· 62 62 #define SCM_WIFI_STATUS SO_WIFI_STATUS 63 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 69 /* Security levels - as per NRL IPv6 - don't actually do anything */ 66 70 #define SO_SECURITY_AUTHENTICATION 0x5001 67 71 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
+3
arch/xtensa/include/asm/socket.h
··· 77 77 #define SCM_WIFI_STATUS SO_WIFI_STATUS 78 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 83 #endif /* _XTENSA_SOCKET_H */
+4
include/asm-generic/socket.h
··· 68 68 #define SO_WIFI_STATUS 41 69 69 #define SCM_WIFI_STATUS SO_WIFI_STATUS 70 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 75 #endif /* __ASM_GENERIC_SOCKET_H */
+2
include/linux/if.h
··· 80 80 * skbs on transmit */ 81 81 #define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */ 82 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 86 #define IF_GET_IFACE 0x0001 /* for querying only */ 85 87 #define IF_GET_PROTO 0x0002
+7 -1
include/linux/netdevice.h
··· 1082 1082 const struct header_ops *header_ops; 1083 1083 1084 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 1087 unsigned short gflags; 1087 1088 unsigned short padded; /* How much padding added by alloc_netdev() */ 1088 1089 ··· 2649 2648 static inline int netif_is_bond_slave(struct net_device *dev) 2650 2649 { 2651 2650 return dev->flags & IFF_SLAVE && dev->priv_flags & IFF_BONDING; 2651 + } 2652 + 2653 + static inline bool netif_supports_nofcs(struct net_device *dev) 2654 + { 2655 + return dev->priv_flags & IFF_SUPP_NOFCS; 2652 2656 } 2653 2657 2654 2658 extern struct pernet_operations __net_initdata loopback_net_ops;
+3 -1
include/linux/skbuff.h
··· 361 361 * ports. 362 362 * @wifi_acked_valid: wifi_acked was set 363 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 365 * @dma_cookie: a cookie to one of several possible DMA operations 365 366 * done by skb DMA functions 366 367 * @secmark: security marking ··· 460 459 __u8 l4_rxhash:1; 461 460 __u8 wifi_acked_valid:1; 462 461 __u8 wifi_acked:1; 463 - /* 10/12 bit hole (depending on ndisc_nodetype presence) */ 462 + __u8 no_fcs:1; 463 + /* 9/11 bit hole (depending on ndisc_nodetype presence) */ 464 464 kmemcheck_bitfield_end(flags2); 465 465 466 466 #ifdef CONFIG_NET_DMA
+4
include/net/sock.h
··· 615 615 SOCK_RXQ_OVFL, 616 616 SOCK_ZEROCOPY, /* buffers from userspace */ 617 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 620 624 static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
+1
net/core/skbuff.c
··· 592 592 new->rxhash = old->rxhash; 593 593 new->ooo_okay = old->ooo_okay; 594 594 new->l4_rxhash = old->l4_rxhash; 595 + new->no_fcs = old->no_fcs; 595 596 #ifdef CONFIG_XFRM 596 597 new->sp = secpath_get(old->sp); 597 598 #endif
+5
net/core/sock.c
··· 799 799 else 800 800 ret = -EOPNOTSUPP; 801 801 break; 802 + 803 + case SO_NOFCS: 804 + sock_valbool_flag(sk, SOCK_NOFCS, valbool); 805 + break; 806 + 802 807 default: 803 808 ret = -ENOPROTOOPT; 804 809 break;
+28 -4
net/packet/af_packet.c
··· 1459 1459 struct net_device *dev; 1460 1460 __be16 proto = 0; 1461 1461 int err; 1462 + int extra_len = 0; 1462 1463 1463 1464 /* 1464 1465 * Get and verify the address. ··· 1494 1493 * raw protocol and you must do your own fragmentation at this level. 1495 1494 */ 1496 1495 1496 + if (unlikely(sock_flag(sk, SOCK_NOFCS))) { 1497 + if (!netif_supports_nofcs(dev)) { 1498 + err = -EPROTONOSUPPORT; 1499 + goto out_unlock; 1500 + } 1501 + extra_len = 4; /* We're doing our own CRC */ 1502 + } 1503 + 1497 1504 err = -EMSGSIZE; 1498 - if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN) 1505 + if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN + extra_len) 1499 1506 goto out_unlock; 1500 1507 1501 1508 if (!skb) { ··· 1535 1526 goto retry; 1536 1527 } 1537 1528 1538 - if (len > (dev->mtu + dev->hard_header_len)) { 1529 + if (len > (dev->mtu + dev->hard_header_len + extra_len)) { 1539 1530 /* Earlier code assumed this would be a VLAN pkt, 1540 1531 * double-check this now that we have the actual 1541 1532 * packet in hand. ··· 1556 1547 err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); 1557 1548 if (err < 0) 1558 1549 goto out_unlock; 1550 + 1551 + if (unlikely(extra_len == 4)) 1552 + skb->no_fcs = 1; 1559 1553 1560 1554 dev_queue_xmit(skb); 1561 1555 rcu_read_unlock(); ··· 2221 2209 struct packet_sock *po = pkt_sk(sk); 2222 2210 unsigned short gso_type = 0; 2223 2211 int hlen, tlen; 2212 + int extra_len = 0; 2224 2213 2225 2214 /* 2226 2215 * Get and verify the address. ··· 2301 2288 } 2302 2289 } 2303 2290 2291 + if (unlikely(sock_flag(sk, SOCK_NOFCS))) { 2292 + if (!netif_supports_nofcs(dev)) { 2293 + err = -EPROTONOSUPPORT; 2294 + goto out_unlock; 2295 + } 2296 + extra_len = 4; /* We're doing our own CRC */ 2297 + } 2298 + 2304 2299 err = -EMSGSIZE; 2305 - if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN)) 2300 + if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN + extra_len)) 2306 2301 goto out_unlock; 2307 2302 2308 2303 err = -ENOBUFS; ··· 2336 2315 if (err < 0) 2337 2316 goto out_free; 2338 2317 2339 - if (!gso_type && (len > dev->mtu + reserve)) { 2318 + if (!gso_type && (len > dev->mtu + reserve + extra_len)) { 2340 2319 /* Earlier code assumed this would be a VLAN pkt, 2341 2320 * double-check this now that we have the actual 2342 2321 * packet in hand. ··· 2373 2352 2374 2353 len += vnet_hdr_len; 2375 2354 } 2355 + 2356 + if (unlikely(extra_len == 4)) 2357 + skb->no_fcs = 1; 2376 2358 2377 2359 /* 2378 2360 * Now send it