All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: David Woodhouse <dwmw2@infradead.org>, netdev@vger.kernel.org
Cc: "Eugenio Pérez" <eperezma@redhat.com>
Subject: Re: [PATCH v2 1/4] net: tun: fix tun_xdp_one() for IFF_TUN mode
Date: Thu, 24 Jun 2021 14:18:08 +0800	[thread overview]
Message-ID: <f860d6a2-12a4-c766-ee57-db789c4a8d1f@redhat.com> (raw)
In-Reply-To: <e8843f32aa14baff398584e5b3a00d20994836b6.camel@infradead.org>


在 2021/6/23 下午9:52, David Woodhouse 写道:
> On Wed, 2021-06-23 at 11:45 +0800, Jason Wang wrote:
>> As replied in previous version, it would be better if we can unify
>> similar logic in tun_get_user().
> So that ends up looking something like this (incremental).
>
> Note the '/* XXX: frags && */' part in tun_skb_set_protocol(), because
> the 'frags &&' was there in tun_get_user() and it wasn't obvious to me
> whether I should be lifting that out as a separate argument to
> tun_skb_set_protocol() or if there's a better way.
>
> Either way, in my judgement this is less suitable for a stable fix and
> more appropriate for a follow-on cleanup. But I don't feel that
> strongly; I'm more than happy for you to overrule me on that.
> Especially if you fix the above XXX part while you're at it :)


By simply adding a boolean "pull" in tun_skb_set_protocol()?

Thanks


>
> I tested this with vhost-net and !IFF_NO_PI, and TX works. RX is still
> hosed on the vhost-net side, for the same reason that a bunch of test
> cases were already listed in #if 0, but I'll address that in a separate
> email. It's not part of *this* patch.
>
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -1641,6 +1641,40 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
>   	return NULL;
>   }
>   
> +static int tun_skb_set_protocol(struct tun_struct *tun, struct sk_buff *skb,
> +				__be16 pi_proto)
> +{
> +	switch (tun->flags & TUN_TYPE_MASK) {
> +	case IFF_TUN:
> +		if (tun->flags & IFF_NO_PI) {
> +			u8 ip_version = skb->len ? (skb->data[0] >> 4) : 0;
> +
> +			switch (ip_version) {
> +			case 4:
> +				pi_proto = htons(ETH_P_IP);
> +				break;
> +			case 6:
> +				pi_proto = htons(ETH_P_IPV6);
> +				break;
> +			default:
> +				return -EINVAL;
> +			}
> +		}
> +
> +		skb_reset_mac_header(skb);
> +		skb->protocol = pi_proto;
> +		skb->dev = tun->dev;
> +		break;
> +	case IFF_TAP:
> +		if (/* XXX frags && */!pskb_may_pull(skb, ETH_HLEN))
> +			return -ENOMEM;
> +
> +		skb->protocol = eth_type_trans(skb, tun->dev);
> +		break;
> +	}
> +	return 0;
> +}
> +
>   /* Get packet from user space buffer */
>   static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
>   			    void *msg_control, struct iov_iter *from,
> @@ -1784,37 +1818,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
>   		return -EINVAL;
>   	}
>   
> -	switch (tun->flags & TUN_TYPE_MASK) {
> -	case IFF_TUN:
> -		if (tun->flags & IFF_NO_PI) {
> -			u8 ip_version = skb->len ? (skb->data[0] >> 4) : 0;
> -
> -			switch (ip_version) {
> -			case 4:
> -				pi.proto = htons(ETH_P_IP);
> -				break;
> -			case 6:
> -				pi.proto = htons(ETH_P_IPV6);
> -				break;
> -			default:
> -				atomic_long_inc(&tun->dev->rx_dropped);
> -				kfree_skb(skb);
> -				return -EINVAL;
> -			}
> -		}
> -
> -		skb_reset_mac_header(skb);
> -		skb->protocol = pi.proto;
> -		skb->dev = tun->dev;
> -		break;
> -	case IFF_TAP:
> -		if (frags && !pskb_may_pull(skb, ETH_HLEN)) {
> -			err = -ENOMEM;
> -			goto drop;
> -		}
> -		skb->protocol = eth_type_trans(skb, tun->dev);
> -		break;
> -	}
> +	err = tun_skb_set_protocol(tun, skb, pi.proto);
> +	if (err)
> +		goto drop;
>   
>   	/* copy skb_ubuf_info for callback when skb has no error */
>   	if (zerocopy) {
> @@ -2334,8 +2340,10 @@ static int tun_xdp_one(struct tun_struct *tun,
>   	struct virtio_net_hdr *gso = NULL;
>   	struct bpf_prog *xdp_prog;
>   	struct sk_buff *skb = NULL;
> +	__be16 proto = 0;
>   	u32 rxhash = 0, act;
>   	int buflen = hdr->buflen;
> +	int reservelen = xdp->data - xdp->data_hard_start;
>   	int err = 0;
>   	bool skb_xdp = false;
>   	struct page *page;
> @@ -2343,6 +2351,17 @@ static int tun_xdp_one(struct tun_struct *tun,
>   	if (tun->flags & IFF_VNET_HDR)
>   		gso = &hdr->gso;
>   
> +	if (!(tun->flags & IFF_NO_PI)) {
> +		struct tun_pi *pi = xdp->data;
> +		if (datasize < sizeof(*pi)) {
> +			atomic_long_inc(&tun->rx_frame_errors);
> +			return  -EINVAL;
> +		}
> +		proto = pi->proto;
> +		reservelen += sizeof(*pi);
> +		datasize -= sizeof(*pi);
> +	}
> +
>   	xdp_prog = rcu_dereference(tun->xdp_prog);
>   	if (xdp_prog) {
>   		if (gso && gso->gso_type) {
> @@ -2388,8 +2407,8 @@ static int tun_xdp_one(struct tun_struct *tun,
>   		goto out;
>   	}
>   
> -	skb_reserve(skb, xdp->data - xdp->data_hard_start);
> -	skb_put(skb, xdp->data_end - xdp->data);
> +	skb_reserve(skb, reservelen);
> +	skb_put(skb, datasize);
>   
>   	if (gso && virtio_net_hdr_to_skb(skb, gso, tun_is_little_endian(tun))) {
>   		atomic_long_inc(&tun->rx_frame_errors);
> @@ -2397,48 +2416,12 @@ static int tun_xdp_one(struct tun_struct *tun,
>   		err = -EINVAL;
>   		goto out;
>   	}
> -	switch (tun->flags & TUN_TYPE_MASK) {
> -	case IFF_TUN:
> -		if (tun->flags & IFF_NO_PI) {
> -			u8 ip_version = skb->len ? (skb->data[0] >> 4) : 0;
>   
> -			switch (ip_version) {
> -			case 4:
> -				skb->protocol = htons(ETH_P_IP);
> -				break;
> -			case 6:
> -				skb->protocol = htons(ETH_P_IPV6);
> -				break;
> -			default:
> -				atomic_long_inc(&tun->dev->rx_dropped);
> -				kfree_skb(skb);
> -				err = -EINVAL;
> -				goto out;
> -			}
> -		} else {
> -			struct tun_pi *pi = (struct tun_pi *)skb->data;
> -			if (!pskb_may_pull(skb, sizeof(*pi))) {
> -				atomic_long_inc(&tun->dev->rx_dropped);
> -				kfree_skb(skb);
> -				err = -ENOMEM;
> -				goto out;
> -			}
> -			skb_pull_inline(skb, sizeof(*pi));
> -			skb->protocol = pi->proto;
> -		}
> -
> -		skb_reset_mac_header(skb);
> -		skb->dev = tun->dev;
> -		break;
> -	case IFF_TAP:
> -		if (!pskb_may_pull(skb, ETH_HLEN)) {
> -			atomic_long_inc(&tun->dev->rx_dropped);
> -			kfree_skb(skb);
> -			err = -ENOMEM;
> -			goto out;
> -		}
> -		skb->protocol = eth_type_trans(skb, tun->dev);
> -		break;
> +	err = tun_skb_set_protocol(tun, skb, proto);
> +	if (err) {
> +		atomic_long_inc(&tun->dev->rx_dropped);
> +		kfree_skb(skb);
> +		goto out;
>   	}
>   
>   	skb_reset_network_header(skb);
>


  parent reply	other threads:[~2021-06-24  6:18 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-19 13:33 [PATCH] net: tun: fix tun_xdp_one() for IFF_TUN mode David Woodhouse
2021-06-21  7:00 ` Jason Wang
2021-06-21 10:52   ` David Woodhouse
2021-06-21 14:50     ` David Woodhouse
2021-06-21 20:43       ` David Woodhouse
2021-06-22  4:52         ` Jason Wang
2021-06-22  7:24           ` David Woodhouse
2021-06-22  7:51             ` Jason Wang
2021-06-22  8:10               ` David Woodhouse
2021-06-22 11:36               ` David Woodhouse
2021-06-22  4:34       ` Jason Wang
2021-06-22  4:34     ` Jason Wang
2021-06-22  7:28       ` David Woodhouse
2021-06-22  8:00         ` Jason Wang
2021-06-22  8:29           ` David Woodhouse
2021-06-23  3:39             ` Jason Wang
2021-06-24 12:39               ` David Woodhouse
2021-06-22 16:15 ` [PATCH v2 1/4] " David Woodhouse
2021-06-22 16:15   ` [PATCH v2 2/4] net: tun: don't assume IFF_VNET_HDR in tun_xdp_one() tx path David Woodhouse
2021-06-23  3:46     ` Jason Wang
2021-06-22 16:15   ` [PATCH v2 3/4] vhost_net: validate virtio_net_hdr only if it exists David Woodhouse
2021-06-23  3:48     ` Jason Wang
2021-06-22 16:15   ` [PATCH v2 4/4] vhost_net: Add self test with tun device David Woodhouse
2021-06-23  4:02     ` Jason Wang
2021-06-23 16:12       ` David Woodhouse
2021-06-24  6:12         ` Jason Wang
2021-06-24 10:42           ` David Woodhouse
2021-06-25  2:55             ` Jason Wang
2021-06-25  7:54               ` David Woodhouse
2021-06-23  3:45   ` [PATCH v2 1/4] net: tun: fix tun_xdp_one() for IFF_TUN mode Jason Wang
2021-06-23  8:30     ` David Woodhouse
2021-06-23 13:52     ` David Woodhouse
2021-06-23 17:31       ` David Woodhouse
2021-06-23 22:52         ` David Woodhouse
2021-06-24  6:37           ` Jason Wang
2021-06-24  7:23             ` David Woodhouse
2021-06-24  6:18       ` Jason Wang [this message]
2021-06-24  7:05         ` David Woodhouse
2021-06-24 12:30 ` [PATCH v3 1/5] net: add header len parameter to tun_get_socket(), tap_get_socket() David Woodhouse
2021-06-24 12:30   ` [PATCH v3 2/5] net: tun: don't assume IFF_VNET_HDR in tun_xdp_one() tx path David Woodhouse
2021-06-25  6:58     ` Jason Wang
2021-06-24 12:30   ` [PATCH v3 3/5] vhost_net: remove virtio_net_hdr validation, let tun/tap do it themselves David Woodhouse
2021-06-25  7:33     ` Jason Wang
2021-06-25  8:37       ` David Woodhouse
2021-06-28  4:23         ` Jason Wang
2021-06-28 11:23           ` David Woodhouse
2021-06-28 23:29             ` David Woodhouse
2021-06-29  3:43               ` Jason Wang
2021-06-29  6:59                 ` David Woodhouse
2021-06-29 10:49                 ` David Woodhouse
2021-06-29 13:15                   ` David Woodhouse
2021-06-30  4:39                   ` Jason Wang
2021-06-30 10:02                     ` David Woodhouse
2021-07-01  4:13                       ` Jason Wang
2021-07-01 17:39                         ` David Woodhouse
2021-07-02  3:13                           ` Jason Wang
2021-07-02  8:08                             ` David Woodhouse
2021-07-02  8:50                               ` Jason Wang
2021-07-09 15:04                               ` Eugenio Perez Martin
2021-06-29  3:21             ` Jason Wang
2021-06-24 12:30   ` [PATCH v3 4/5] net: tun: fix tun_xdp_one() for IFF_TUN mode David Woodhouse
2021-06-25  7:41     ` Jason Wang
2021-06-25  8:51       ` David Woodhouse
2021-06-28  4:27         ` Jason Wang
2021-06-28 10:43           ` David Woodhouse
2021-06-25 18:43     ` Willem de Bruijn
2021-06-25 19:00       ` David Woodhouse
2021-06-24 12:30   ` [PATCH v3 5/5] vhost_net: Add self test with tun device David Woodhouse
2021-06-25  5:00   ` [PATCH v3 1/5] net: add header len parameter to tun_get_socket(), tap_get_socket() Jason Wang
2021-06-25  8:23     ` David Woodhouse
2021-06-28  4:22       ` Jason Wang
2021-06-25 18:13   ` Willem de Bruijn
2021-06-25 18:55     ` David Woodhouse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f860d6a2-12a4-c766-ee57-db789c4a8d1f@redhat.com \
    --to=jasowang@redhat.com \
    --cc=dwmw2@infradead.org \
    --cc=eperezma@redhat.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.