Re: [PATCH net 2/2] virtio_net: check L3 protocol for VLAN packets

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Apr 18, 2022 at 12:44 AM Hangbin Liu <liuhangbin@xxxxxxxxx> wrote:
>
> For gso packets, virtio_net_hdr_to_skb() will check the protocol via
> virtio_net_hdr_match_proto(). But a packet may come from a raw socket
> with a VLAN tag. Checking the VLAN protocol for virtio net_hdr makes no
> sense. Let's check the L3 protocol if it's a VLAN packet.
>
> Make the virtio_net_hdr_match_proto() checking for all skbs instead of
> only skb without protocol setting.
>
> Also update the data, protocol parameter for
> skb_flow_dissect_flow_keys_basic() as the skb->protocol may not IP or IPv6.
>
> Fixes: 7e5cced9ca84 ("net: accept UFOv6 packages in virtio_net_hdr_to_skb")
> Signed-off-by: Hangbin Liu <liuhangbin@xxxxxxxxx>
> ---
>  include/linux/virtio_net.h | 26 +++++++++++++++++++-------
>  1 file changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
> index a960de68ac69..97b4f9680786 100644
> --- a/include/linux/virtio_net.h
> +++ b/include/linux/virtio_net.h
> @@ -3,6 +3,7 @@
>  #define _LINUX_VIRTIO_NET_H
>
>  #include <linux/if_vlan.h>
> +#include <uapi/linux/if_arp.h>
>  #include <uapi/linux/tcp.h>
>  #include <uapi/linux/udp.h>
>  #include <uapi/linux/virtio_net.h>
> @@ -102,25 +103,36 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
>                  */
>                 if (gso_type && skb->network_header) {

This whole branch should not be taken by well formed packets. It is
inside the else clause of

       if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
          ..
       } else {

GSO packets should always request checksum offload. The fact that we
try to patch up some incomplete packets should not have to be expanded
if we expand support to include VLAN.

>                         struct flow_keys_basic keys;
> +                       __be16 protocol;
>
>                         if (!skb->protocol) {
> -                               __be16 protocol = dev_parse_header_protocol(skb);
> +                               protocol = dev_parse_header_protocol(skb);
>
>                                 if (!protocol)
>                                         virtio_net_hdr_set_proto(skb, hdr);
> -                               else if (!virtio_net_hdr_match_proto(protocol, hdr->gso_type))
> -                                       return -EINVAL;
>                                 else
>                                         skb->protocol = protocol;
> +                       } else {
> +                               protocol = skb->protocol;
>                         }
> +
> +                       /* Get L3 protocol if current protocol is VLAN */
> +                       if (likely(skb->dev->type == ARPHRD_ETHER) &&
> +                           eth_type_vlan(protocol))
> +                               protocol = vlan_get_protocol(skb);
> +
> +                       if (!virtio_net_hdr_match_proto(protocol, hdr->gso_type))
> +                               return -EINVAL;
> +
>  retry:
>                         if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
> -                                                             NULL, 0, 0, 0,
> -                                                             0)) {
> +                                                             skb->data, protocol,
> +                                                             skb_network_offset(skb),
> +                                                             skb_headlen(skb), 0)) {
>                                 /* UFO does not specify ipv4 or 6: try both */
>                                 if (gso_type & SKB_GSO_UDP &&
> -                                   skb->protocol == htons(ETH_P_IP)) {
> -                                       skb->protocol = htons(ETH_P_IPV6);
> +                                   protocol == htons(ETH_P_IP)) {
> +                                       protocol = htons(ETH_P_IPV6);
>                                         goto retry;
>                                 }
>                                 return -EINVAL;
> --
> 2.35.1
>
_______________________________________________
Virtualization mailing list
Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linuxfoundation.org/mailman/listinfo/virtualization



[Index of Archives]     [KVM Development]     [Libvirt Development]     [Libvirt Users]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux