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]
Message-ID: <CALx6S368wxfg63jDA85C9g319Jwd9ExPDTidPSZu89jhyYNgTA@mail.gmail.com>
Date:	Tue, 1 Sep 2015 20:31:13 -0700
From:	Tom Herbert <tom@...bertland.com>
To:	Jeff Kirsher <jeffrey.t.kirsher@...el.com>
Cc:	"David S. Miller" <davem@...emloft.net>,
	Mark Rustad <mark.d.rustad@...el.com>,
	Linux Kernel Network Developers <netdev@...r.kernel.org>,
	nhorman@...hat.com, sassmann@...hat.com, jogreene@...hat.com
Subject: Re: [net-next 06/19] ixgbe: Add support for VXLAN RX offloads

On Tue, Sep 1, 2015 at 6:13 PM, Jeff Kirsher
<jeffrey.t.kirsher@...el.com> wrote:
> From: Mark Rustad <mark.d.rustad@...el.com>
>
> Add support for VXLAN RX offloads for the X55x devices that support
> them.
>
> Signed-off-by: Mark Rustad <mark.d.rustad@...el.com>
> Tested-by: Phil Schmitt <phillip.j.schmitt@...el.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@...el.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h       |   6 ++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c |  18 +++-
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  | 119 ++++++++++++++++++++-----
>  drivers/net/ethernet/intel/ixgbe/ixgbe_type.h  |  15 ++--
>  4 files changed, 127 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> index ac3ac2a..8830c0f 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> @@ -630,6 +630,7 @@ struct ixgbe_adapter {
>  #define IXGBE_FLAG_FCOE_ENABLED                 (u32)(1 << 21)
>  #define IXGBE_FLAG_SRIOV_CAPABLE                (u32)(1 << 22)
>  #define IXGBE_FLAG_SRIOV_ENABLED                (u32)(1 << 23)
> +#define IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE       BIT(24)
>
>         u32 flags2;
>  #define IXGBE_FLAG2_RSC_CAPABLE                 (u32)(1 << 0)
> @@ -644,6 +645,9 @@ struct ixgbe_adapter {
>  #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP         (u32)(1 << 9)
>  #define IXGBE_FLAG2_PTP_PPS_ENABLED            (u32)(1 << 10)
>  #define IXGBE_FLAG2_PHY_INTERRUPT              (u32)(1 << 11)
> +#ifdef CONFIG_IXGBE_VXLAN
> +#define IXGBE_FLAG2_VXLAN_REREG_NEEDED         BIT(12)
> +#endif
>
>         /* Tx fast path data */
>         int num_tx_queues;
> @@ -757,7 +761,9 @@ struct ixgbe_adapter {
>         u32 timer_event_accumulator;
>         u32 vferr_refcount;
>         struct ixgbe_mac_addr *mac_table;
> +#ifdef CONFIG_IXGBE_VXLAN
>         u16 vxlan_port;
> +#endif
>         struct kobject *info_kobj;
>  #ifdef CONFIG_IXGBE_HWMON
>         struct hwmon_buff *ixgbe_hwmon_buff;
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
> index d910442..dd7062f 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
> @@ -1519,20 +1519,28 @@ static u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
>   *  @input: unique input dword
>   *  @common: compressed common input dword
>   *  @queue: queue index to direct traffic to
> + *
> + * Note that the tunnel bit in input must not be set when the hardware
> + * tunneling support does not exist.
>   **/
>  s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
>                                           union ixgbe_atr_hash_dword input,
>                                           union ixgbe_atr_hash_dword common,
>                                           u8 queue)
>  {
> -       u64  fdirhashcmd;
> -       u32  fdircmd;
> +       u64 fdirhashcmd;
> +       u8 flow_type;
> +       bool tunnel;
> +       u32 fdircmd;
>
>         /*
>          * Get the flow_type in order to program FDIRCMD properly
>          * lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6
>          */
> -       switch (input.formatted.flow_type) {
> +       tunnel = !!(input.formatted.flow_type & IXGBE_ATR_L4TYPE_TUNNEL_MASK);
> +       flow_type = input.formatted.flow_type &
> +                   (IXGBE_ATR_L4TYPE_TUNNEL_MASK - 1);
> +       switch (flow_type) {
>         case IXGBE_ATR_FLOW_TYPE_TCPV4:
>         case IXGBE_ATR_FLOW_TYPE_UDPV4:
>         case IXGBE_ATR_FLOW_TYPE_SCTPV4:
> @@ -1548,8 +1556,10 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
>         /* configure FDIRCMD register */
>         fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
>                   IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
> -       fdircmd |= input.formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
> +       fdircmd |= (u32)flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
>         fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
> +       if (tunnel)
> +               fdircmd |= IXGBE_FDIRCMD_TUNNEL_FILTER;
>
>         /*
>          * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index 900562e..dcf849d 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -1,7 +1,7 @@
>  /*******************************************************************************
>
>    Intel 10 Gigabit PCI Express Linux driver
> -  Copyright(c) 1999 - 2014 Intel Corporation.
> +  Copyright(c) 1999 - 2015 Intel Corporation.
>
>    This program is free software; you can redistribute it and/or modify it
>    under the terms and conditions of the GNU General Public License,
> @@ -65,6 +65,9 @@
>  #include "ixgbe_common.h"
>  #include "ixgbe_dcb_82599.h"
>  #include "ixgbe_sriov.h"
> +#ifdef CONFIG_IXGBE_VXLAN
> +#include <net/vxlan.h>
> +#endif
>
>  char ixgbe_driver_name[] = "ixgbe";
>  static const char ixgbe_driver_string[] =
> @@ -79,7 +82,7 @@ static char ixgbe_default_device_descr[] =
>  #define DRV_VERSION "4.0.1-k"
>  const char ixgbe_driver_version[] = DRV_VERSION;
>  static const char ixgbe_copyright[] =
> -                               "Copyright (c) 1999-2014 Intel Corporation.";
> +                               "Copyright (c) 1999-2015 Intel Corporation.";
>
>  static const char ixgbe_overheat_msg[] = "Network adapter has been stopped because it has over heated. Restart the computer. If the problem persists, power off the system and replace the adapter";
>
> @@ -1430,7 +1433,6 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
>             (hdr_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_TUNNEL >> 16))) {
>                 encap_pkt = true;
>                 skb->encapsulation = 1;
> -               skb->ip_summed = CHECKSUM_NONE;
>         }
>
>         /* if IP and error */
> @@ -4261,6 +4263,21 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
>         }
>  }
>
> +static void ixgbe_clear_vxlan_port(struct ixgbe_adapter *adapter)
> +{
> +       switch (adapter->hw.mac.type) {
> +       case ixgbe_mac_X550:
> +       case ixgbe_mac_X550EM_x:
> +               IXGBE_WRITE_REG(&adapter->hw, IXGBE_VXLANCTRL, 0);
> +#ifdef CONFIG_IXGBE_VXLAN
> +               adapter->vxlan_port = 0;
> +#endif
> +               break;
> +       default:
> +               break;
> +       }
> +}
> +
>  #ifdef CONFIG_IXGBE_DCB
>  /**
>   * ixgbe_configure_dcb - Configure DCB hardware
> @@ -5302,6 +5319,9 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
>  #ifdef CONFIG_IXGBE_DCA
>                 adapter->flags &= ~IXGBE_FLAG_DCA_CAPABLE;
>  #endif
> +#ifdef CONFIG_IXGBE_VXLAN
> +               adapter->flags |= IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE;
> +#endif
>                 break;
>         default:
>                 break;
> @@ -5753,10 +5773,11 @@ static int ixgbe_open(struct net_device *netdev)
>
>         ixgbe_up_complete(adapter);
>
> -#if IS_ENABLED(CONFIG_IXGBE_VXLAN)
> +       ixgbe_clear_vxlan_port(adapter);
> +#ifdef CONFIG_IXGBE_VXLAN
>         vxlan_get_rx_port(netdev);
> -
>  #endif
> +
>         return 0;
>
>  err_set_queues:
> @@ -6816,6 +6837,12 @@ static void ixgbe_service_task(struct work_struct *work)
>                 ixgbe_service_event_complete(adapter);
>                 return;
>         }
> +#ifdef CONFIG_IXGBE_VXLAN
> +       if (adapter->flags2 & IXGBE_FLAG2_VXLAN_REREG_NEEDED) {
> +               adapter->flags2 &= ~IXGBE_FLAG2_VXLAN_REREG_NEEDED;
> +               vxlan_get_rx_port(adapter->netdev);
> +       }
> +#endif /* CONFIG_IXGBE_VXLAN */
>         ixgbe_reset_subtask(adapter);
>         ixgbe_phy_interrupt_subtask(adapter);
>         ixgbe_sfp_detection_subtask(adapter);
> @@ -7240,6 +7267,10 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
>                 struct ipv6hdr *ipv6;
>         } hdr;
>         struct tcphdr *th;
> +       struct sk_buff *skb;
> +#ifdef CONFIG_IXGBE_VXLAN
> +       u8 encap = false;
> +#endif /* CONFIG_IXGBE_VXLAN */
>         __be16 vlan_id;
>
>         /* if ring doesn't have a interrupt vector, cannot perform ATR */
> @@ -7253,16 +7284,36 @@ static void ixgbe_atr(struct ixgbe_ring *ring,

Isn't this a function in the transmit path? What do these changes have
to do with RX offloads?

>         ring->atr_count++;
>
>         /* snag network header to get L4 type and address */
> -       hdr.network = skb_network_header(first->skb);
> +       skb = first->skb;
> +       hdr.network = skb_network_header(skb);
> +       if (skb->encapsulation) {
> +#ifdef CONFIG_IXGBE_VXLAN
> +               struct ixgbe_adapter *adapter = q_vector->adapter;
>
> -       /* Currently only IPv4/IPv6 with TCP is supported */
> -       if ((first->protocol != htons(ETH_P_IPV6) ||
> -            hdr.ipv6->nexthdr != IPPROTO_TCP) &&
> -           (first->protocol != htons(ETH_P_IP) ||
> -            hdr.ipv4->protocol != IPPROTO_TCP))
> +               if (!adapter->vxlan_port)
> +                       return;
> +               if (first->protocol != htons(ETH_P_IP) ||
> +                   hdr.ipv4->version != IPVERSION ||
> +                   hdr.ipv4->protocol != IPPROTO_UDP) {
> +                       return;
> +               }
> +               if (ntohs(udp_hdr(skb)->dest) != adapter->vxlan_port)
> +                       return;
> +               encap = true;
> +               hdr.network = skb_inner_network_header(skb);
> +               th = inner_tcp_hdr(skb);
> +#else
>                 return;
> -
> -       th = tcp_hdr(first->skb);
> +#endif /* CONFIG_IXGBE_VXLAN */
> +       } else {
> +               /* Currently only IPv4/IPv6 with TCP is supported */
> +               if ((first->protocol != htons(ETH_P_IPV6) ||
> +                    hdr.ipv6->nexthdr != IPPROTO_TCP) &&
> +                   (first->protocol != htons(ETH_P_IP) ||
> +                    hdr.ipv4->protocol != IPPROTO_TCP))
> +                       return;
> +               th = tcp_hdr(skb);
> +       }
>
>         /* skip this packet since it is invalid or the socket is closing */
>         if (!th || th->fin)
> @@ -7311,6 +7362,11 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
>                              hdr.ipv6->daddr.s6_addr32[3];
>         }
>
> +#ifdef CONFIG_IXGBE_VXLAN
> +       if (encap)
> +               input.formatted.flow_type |= IXGBE_ATR_L4TYPE_TUNNEL_MASK;
> +#endif /* CONFIG_IXGBE_VXLAN */
> +
>         /* This assumes the Rx queue and Tx queue are bound to the same CPU */
>         ixgbe_fdir_add_signature_filter_82599(&q_vector->adapter->hw,
>                                               input, common, ring->queue_index);
> @@ -7937,12 +7993,23 @@ static int ixgbe_set_features(struct net_device *netdev,
>                 need_reset = true;
>
>         netdev->features = features;
> +
> +#ifdef CONFIG_IXGBE_VXLAN
> +       if ((adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE)) {
> +               if (features & NETIF_F_RXCSUM)
> +                       adapter->flags2 |= IXGBE_FLAG2_VXLAN_REREG_NEEDED;
> +               else
> +                       ixgbe_clear_vxlan_port(adapter);
> +       }
> +#endif /* CONFIG_IXGBE_VXLAN */
> +
>         if (need_reset)
>                 ixgbe_do_reset(netdev);
>
>         return 0;
>  }
>
> +#ifdef CONFIG_IXGBE_VXLAN
>  /**
>   * ixgbe_add_vxlan_port - Get notifications about VXLAN ports that come up
>   * @dev: The port's netdev
> @@ -7956,17 +8023,18 @@ static void ixgbe_add_vxlan_port(struct net_device *dev, sa_family_t sa_family,
>         struct ixgbe_hw *hw = &adapter->hw;
>         u16 new_port = ntohs(port);
>
> +       if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
> +               return;
> +
>         if (sa_family == AF_INET6)
>                 return;
>
> -       if (adapter->vxlan_port == new_port) {
> -               netdev_info(dev, "Port %d already offloaded\n", new_port);
> +       if (adapter->vxlan_port == new_port)
>                 return;
> -       }
>
>         if (adapter->vxlan_port) {
>                 netdev_info(dev,
> -                           "Hit Max num of UDP ports, not adding port %d\n",
> +                           "Hit Max num of VXLAN ports, not adding port %d\n",
>                             new_port);
>                 return;
>         }
> @@ -7985,9 +8053,11 @@ static void ixgbe_del_vxlan_port(struct net_device *dev, sa_family_t sa_family,
>                                  __be16 port)
>  {
>         struct ixgbe_adapter *adapter = netdev_priv(dev);
> -       struct ixgbe_hw *hw = &adapter->hw;
>         u16 new_port = ntohs(port);
>
> +       if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
> +               return;
> +
>         if (sa_family == AF_INET6)
>                 return;
>
> @@ -7997,9 +8067,10 @@ static void ixgbe_del_vxlan_port(struct net_device *dev, sa_family_t sa_family,
>                 return;
>         }
>
> -       adapter->vxlan_port = 0;
> -       IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, 0);
> +       ixgbe_clear_vxlan_port(adapter);
> +       adapter->flags2 |= IXGBE_FLAG2_VXLAN_REREG_NEEDED;
>  }
> +#endif /* CONFIG_IXGBE_VXLAN */
>
>  static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
>                              struct net_device *dev,
> @@ -8290,8 +8361,10 @@ static const struct net_device_ops ixgbe_netdev_ops = {
>         .ndo_bridge_getlink     = ixgbe_ndo_bridge_getlink,
>         .ndo_dfwd_add_station   = ixgbe_fwd_add,
>         .ndo_dfwd_del_station   = ixgbe_fwd_del,
> +#ifdef CONFIG_IXGBE_VXLAN
>         .ndo_add_vxlan_port     = ixgbe_add_vxlan_port,
>         .ndo_del_vxlan_port     = ixgbe_del_vxlan_port,
> +#endif /* CONFIG_IXGBE_VXLAN */
>         .ndo_features_check     = ixgbe_features_check,
>  };
>
> @@ -8658,14 +8731,18 @@ skip_sriov:
>         netdev->priv_flags |= IFF_UNICAST_FLT;
>         netdev->priv_flags |= IFF_SUPP_NOFCS;
>
> +#ifdef CONFIG_IXGBE_VXLAN
>         switch (adapter->hw.mac.type) {
>         case ixgbe_mac_X550:
>         case ixgbe_mac_X550EM_x:
> -               netdev->hw_enc_features |= NETIF_F_RXCSUM;
> +               netdev->hw_enc_features |= NETIF_F_RXCSUM |
> +                                          NETIF_F_IP_CSUM |
> +                                          NETIF_F_IPV6_CSUM;
>                 break;
>         default:
>                 break;
>         }
> +#endif /* CONFIG_IXGBE_VXLAN */
>
>  #ifdef CONFIG_IXGBE_DCB
>         netdev->dcbnl_ops = &dcbnl_ops;
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
> index 938a410..0e67824 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
> @@ -2540,9 +2540,11 @@ enum ixgbe_fdir_pballoc_type {
>  #define IXGBE_FDIRCMD_QUEUE_EN                  0x00008000
>  #define IXGBE_FDIRCMD_FLOW_TYPE_SHIFT           5
>  #define IXGBE_FDIRCMD_RX_QUEUE_SHIFT            16
> +#define IXGBE_FDIRCMD_RX_TUNNEL_FILTER_SHIFT   23
>  #define IXGBE_FDIRCMD_VT_POOL_SHIFT             24
>  #define IXGBE_FDIR_INIT_DONE_POLL               10
>  #define IXGBE_FDIRCMD_CMD_POLL                  10
> +#define IXGBE_FDIRCMD_TUNNEL_FILTER            0x00800000
>
>  #define IXGBE_FDIR_DROP_QUEUE                   127
>
> @@ -2833,12 +2835,13 @@ typedef u32 ixgbe_link_speed;
>  #define IXGBE_ATR_SIGNATURE_HASH_KEY 0x174D3614
>
>  /* Software ATR input stream values and masks */
> -#define IXGBE_ATR_HASH_MASK     0x7fff
> -#define IXGBE_ATR_L4TYPE_MASK      0x3
> -#define IXGBE_ATR_L4TYPE_UDP       0x1
> -#define IXGBE_ATR_L4TYPE_TCP       0x2
> -#define IXGBE_ATR_L4TYPE_SCTP      0x3
> -#define IXGBE_ATR_L4TYPE_IPV6_MASK 0x4
> +#define IXGBE_ATR_HASH_MASK            0x7fff
> +#define IXGBE_ATR_L4TYPE_MASK          0x3
> +#define IXGBE_ATR_L4TYPE_UDP           0x1
> +#define IXGBE_ATR_L4TYPE_TCP           0x2
> +#define IXGBE_ATR_L4TYPE_SCTP          0x3
> +#define IXGBE_ATR_L4TYPE_IPV6_MASK     0x4
> +#define IXGBE_ATR_L4TYPE_TUNNEL_MASK   0x10
>  enum ixgbe_atr_flow_type {
>         IXGBE_ATR_FLOW_TYPE_IPV4   = 0x0,
>         IXGBE_ATR_FLOW_TYPE_UDPV4  = 0x1,
> --
> 2.4.3
>
> --
> 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
--
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