lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Sat, 18 Jun 2011 07:54:33 +0200
From:	Eric Dumazet <eric.dumazet@...il.com>
To:	greearb@...delatech.com
Cc:	netdev@...r.kernel.org
Subject: Re: [RFC 4/5] net:  Support sending frame with specified FCS.

Le vendredi 17 juin 2011 à 17:09 -0700, greearb@...delatech.com a
écrit :
> From: Ben Greear <greearb@...delatech.com>
> 
> This allows user-space to send a packet with the
> ethernet FCS appended to the end.  Supporting NICs
> will know to disable their own FCS calculations and
> send frame as is.
> 
> This is useful for injecting bad frames on a network
> for testing.
> 
> Signed-off-by: Ben Greear <greearb@...delatech.com>
> ---
> :100644 100644 9a6115e... 22193a2... M	include/asm-generic/socket.h
> :100644 100644 c0a4f3a... 05b15be... M	include/linux/skbuff.h
> :100644 100644 f2046e4... d7e0d88... M	include/net/sock.h
> :100644 100644 46cbd28... a552560... M	net/core/skbuff.c
> :100644 100644 6e81978... 0c5f827... M	net/core/sock.c
> :100644 100644 c0c3cda... 0d29d68... M	net/packet/af_packet.c
>  include/asm-generic/socket.h |    7 +++++++
>  include/linux/skbuff.h       |    5 ++++-
>  include/net/sock.h           |    6 ++++++
>  net/core/skbuff.c            |    1 +
>  net/core/sock.c              |    7 +++++++
>  net/packet/af_packet.c       |   22 ++++++++++++++++++++--
>  6 files changed, 45 insertions(+), 3 deletions(-)
> 
> diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
> index 9a6115e..22193a2 100644
> --- a/include/asm-generic/socket.h
> +++ b/include/asm-generic/socket.h
> @@ -64,4 +64,11 @@
>  #define SO_DOMAIN		39
>  
>  #define SO_RXQ_OVFL             40
> +
> +/* Instruct lower device to not calculate the frame
> + * checksum.  Useful for generating Ethernet frames
> + * with custom checksums.
> + */
> +#define SO_NOFCS		41
> +

Please take a look at :

arch/*/include/asm/socket.h for many arches.

>  #endif /* __ASM_GENERIC_SOCKET_H */
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index c0a4f3a..05b15be 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -307,6 +307,8 @@ typedef unsigned char *sk_buff_data_t;
>   *	@peeked: this packet has been seen already, so stats have been
>   *		done for it, don't do them again
>   *	@nf_trace: netfilter packet trace flag
> + *	@use_specified_ether_crc: skb is Ethernet frame with FCS already
> + *		appended.  Use that FCS.  Requires special support in NIC.
>   *	@nfctinfo: Relationship of this skb to the connection
>   *	@nfct_reasm: netfilter conntrack re-assembly pointer
>   *	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c
> @@ -396,7 +398,8 @@ struct sk_buff {
>  #ifdef CONFIG_IPV6_NDISC_NODETYPE
>  	__u8			ndisc_nodetype:2;
>  #endif
> -	__u8			ooo_okay:1;
> +	__u8			ooo_okay:1,
> +				use_specified_ether_crc:1;
>  	kmemcheck_bitfield_end(flags2);
>  
>  	/* 0/13 bit hole */
> diff --git a/include/net/sock.h b/include/net/sock.h
> index f2046e4..d7e0d88 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -563,6 +563,12 @@ enum sock_flags {
>  	SOCK_TIMESTAMPING_SYS_HARDWARE, /* %SOF_TIMESTAMPING_SYS_HARDWARE */
>  	SOCK_FASYNC, /* fasync() active */
>  	SOCK_RXQ_OVFL,
> +	SOCK_DONT_DO_LL_FCS, /* Tell NIC not to do the Ethernet FCS.
> +			      * Will use last 4 bytes of packet sent from
> +			      * user-space instead.  Requires special
> +			      * support in NIC.
> +			      */
> +
>  };
>  
>  static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 46cbd28..a552560 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -541,6 +541,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
>  	new->tc_verd		= old->tc_verd;
>  #endif
>  #endif
> +	new->use_specified_ether_crc = old->use_specified_ether_crc;
>  	new->vlan_tci		= old->vlan_tci;
>  
>  	skb_copy_secmark(new, old);
> diff --git a/net/core/sock.c b/net/core/sock.c
> index 6e81978..0c5f827 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -641,6 +641,13 @@ set_rcvbuf:
>  		sock_warn_obsolete_bsdism("setsockopt");
>  		break;
>  
> +	case SO_NOFCS:
> +		if (valbool)
> +			sk->sk_flags |= SOCK_DONT_DO_LL_FCS;
> +		else
> +			sk->sk_flags &= ~(SOCK_DONT_DO_LL_FCS);
> +		break;
> +
>  	case SO_PASSCRED:
>  		if (valbool)
>  			set_bit(SOCK_PASSCRED, &sock->flags);
> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> index c0c3cda..0d29d68 100644
> --- a/net/packet/af_packet.c
> +++ b/net/packet/af_packet.c
> @@ -430,6 +430,10 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
>  	struct net_device *dev;
>  	__be16 proto = 0;
>  	int err;
> +	int kludge = 0;
> +
> +	if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
> +		kludge = 4; /* We're doing our own FCS */
>  
>  	/*
>  	 *	Get and verify the address.
> @@ -465,7 +469,7 @@ retry:
>  	 */
>  
>  	err = -EMSGSIZE;
> -	if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN)
> +	if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN + kludge)
>  		goto out_unlock;
>  
>  	if (!skb) {
> @@ -518,6 +522,11 @@ retry:
>  	if (err < 0)
>  		goto out_unlock;
>  
> +	if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
> +		skb->use_specified_ether_crc = 1;
> +	else
> +		skb->use_specified_ether_crc = 0;
> +

Manipulating a bit field is very expensive, and having an else branch is
expensive as well, so please avoid setting crc to zero if its already
guaranteed to be so.



Also I cant see where you actually _set_ the fcs value : that might
trigger a kmemcheck warning later when we read it.


>  	dev_queue_xmit(skb);
>  	rcu_read_unlock();
>  	return len;
> @@ -1134,6 +1143,10 @@ static int packet_snd(struct socket *sock,
>  	int vnet_hdr_len;
>  	struct packet_sock *po = pkt_sk(sk);
>  	unsigned short gso_type = 0;
> +	int kludge = 0;
> +
> +	if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
> +		kludge = 4; /* We're doing our own Ethernet FCS */

kludge ? You mean fcs_len or something ? ;)
>  
>  	/*
>  	 *	Get and verify the address.
> @@ -1215,7 +1228,7 @@ static int packet_snd(struct socket *sock,
>  	}
>  
>  	err = -EMSGSIZE;
> -	if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN))
> +	if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN + kludge))
>  		goto out_unlock;
>  
>  	err = -ENOBUFS;
> @@ -1278,6 +1291,11 @@ static int packet_snd(struct socket *sock,
>  		len += vnet_hdr_len;
>  	}
>  
> +	if (unlikely(sk->sk_flags & SOCK_DONT_DO_LL_FCS))
> +		skb->use_specified_ether_crc = 1;
> +	else
> +		skb->use_specified_ether_crc = 0;

same remark here : ether_crc is already 0 here.

> +
>  	/*
>  	 *	Now send it
>  	 */


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ