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] [day] [month] [year] [list]
Message-ID: <20210604080131.GF40979@gauss3.secunet.de>
Date:   Fri, 4 Jun 2021 10:01:31 +0200
From:   Steffen Klassert <steffen.klassert@...unet.com>
To:     Huy Nguyen <huyn@...dia.com>
CC:     <netdev@...r.kernel.org>, <saeedm@...dia.com>, <borisp@...dia.com>,
        <raeds@...dia.com>, <danielj@...dia.com>, <yossiku@...dia.com>,
        <kuba@...nel.org>
Subject: Re: [RESEND PATCH net v3 2/3] net/xfrm: Add inner_ipproto into
 sec_path

On Thu, Jun 03, 2021 at 07:00:44PM +0300, Huy Nguyen wrote:
>  
> +/* For partial checksum offload, the outer header checksum is calculated
> + * by software and the inner header checksum is calculated by hardware.
> + * This requires hardware to know the inner packet type to calculate
> + * the inner header checksum. Save inner ip protocol here to avoid
> + * traversing the packet in the vendor's xmit code.
> + * If the encap type is IPIP, just save skb->inner_ipproto. Otherwise,
> + * get the ip protocol from the IP header.
> + */
> +static void xfrm_get_inner_ipproto(struct sk_buff *skb)
> +{
> +	struct xfrm_offload *xo = xfrm_offload(skb);
> +	const struct ethhdr *eth;
> +
> +	if (!skb->inner_protocol)
> +		return;

inner_protocol is only valid if skb->encapsulation is set, maybe
you should test for that before calling this function. In particular,
you should do that before we set it explicitly in xfrm_output.

> +
> +	xo = xfrm_offload(skb);
> +	if (!xo)
> +		return;
> +
> +	if (skb->inner_protocol_type == ENCAP_TYPE_IPPROTO) {
> +		xo->inner_ipproto = skb->inner_ipproto;
> +		return;
> +	}
> +
> +	if (skb->inner_protocol_type != ENCAP_TYPE_ETHER)
> +		return;
> +
> +	eth = (struct ethhdr *)skb_inner_mac_header(skb);
> +
> +	switch (ntohs(eth->h_proto)) {
> +	case ETH_P_IPV6:
> +		xo->inner_ipproto = inner_ipv6_hdr(skb)->nexthdr;
> +		break;
> +	case ETH_P_IP:
> +		xo->inner_ipproto = inner_ip_hdr(skb)->protocol;
> +		break;
> +	}
> +}
> +
>  int xfrm_output(struct sock *sk, struct sk_buff *skb)
>  {
>  	struct net *net = dev_net(skb_dst(skb)->dev);
> @@ -594,12 +634,14 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
>  			kfree_skb(skb);
>  			return -ENOMEM;
>  		}
> -		skb->encapsulation = 1;
>  
> +		skb->encapsulation = 1;
>  		sp->olen++;
>  		sp->xvec[sp->len++] = x;
>  		xfrm_state_hold(x);
>  
> +		xfrm_get_inner_ipproto(skb);
> +
>  		if (skb_is_gso(skb)) {
>  			if (skb->inner_protocol)
>  				return xfrm_output_gso(net, sk, skb);
> -- 
> 2.24.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ