From patchwork Mon Feb 6 22:38:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Keller, Jacob E" X-Patchwork-Id: 724791 X-Patchwork-Delegate: jeffrey.t.kirsher@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vHMpl5jqWz9s1y for ; Tue, 7 Feb 2017 09:39:27 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 4B304309F8; Mon, 6 Feb 2017 22:39:26 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cTrFIW78ePeP; Mon, 6 Feb 2017 22:39:21 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by silver.osuosl.org (Postfix) with ESMTP id 7FC9F30A98; Mon, 6 Feb 2017 22:39:03 +0000 (UTC) X-Original-To: intel-wired-lan@lists.osuosl.org Delivered-To: intel-wired-lan@lists.osuosl.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by ash.osuosl.org (Postfix) with ESMTP id 44FBF1BFF07 for ; Mon, 6 Feb 2017 22:38:59 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 4349A815B4 for ; Mon, 6 Feb 2017 22:38:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DooYQxGqUe-O for ; Mon, 6 Feb 2017 22:38:57 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by whitealder.osuosl.org (Postfix) with ESMTPS id C14FE8885E for ; Mon, 6 Feb 2017 22:38:55 +0000 (UTC) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga102.fm.intel.com with ESMTP; 06 Feb 2017 14:38:54 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,342,1477983600"; d="scan'208";a="61907704" Received: from jekeller-desk.amr.corp.intel.com (HELO jekeller-desk.jekeller.internal) ([10.166.35.174]) by fmsmga005.fm.intel.com with ESMTP; 06 Feb 2017 14:38:54 -0800 From: Jacob Keller To: Intel Wired LAN Date: Mon, 6 Feb 2017 14:38:51 -0800 Message-Id: <20170206223852.31177-9-jacob.e.keller@intel.com> X-Mailer: git-send-email 2.12.0.rc0.151.g8a5726c42288 In-Reply-To: <20170206223852.31177-1-jacob.e.keller@intel.com> References: <20170206223852.31177-1-jacob.e.keller@intel.com> Subject: [Intel-wired-lan] [PART2 PATCH 8/9] i40e: add support for SCTPv4 FDir filters X-BeenThere: intel-wired-lan@lists.osuosl.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Intel Wired Ethernet Linux Kernel Driver Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-wired-lan-bounces@lists.osuosl.org Sender: "Intel-wired-lan" Enable FDir filters for SCTPv4 packets using the ethtool ntuple interface to enable filters. The ethtool API does not allow masking on the verification tag. Testing-hints: Ethtool commands to enable sctp4 filters should not produce errors, and should properly direct traffic to the desired queue. ethtool -N flow-type sctp4 action 1 Signed-off-by: Jacob Keller Change-Id: I093e88a8143994c7e6f4b7b17a0bd5cf861d18e4 Tested-by: Andrew Bowers --- drivers/net/ethernet/intel/i40e/i40e.h | 1 + drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 10 ++++ drivers/net/ethernet/intel/i40e/i40e_main.c | 2 + drivers/net/ethernet/intel/i40e/i40e_txrx.c | 80 ++++++++++++++++++++++++++ 4 files changed, 93 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index f218a5bb7a16..33d1730878b7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -381,6 +381,7 @@ struct i40e_pf { */ u16 fd_tcp4_filter_cnt; u16 fd_udp4_filter_cnt; + u16 fd_sctp4_filter_cnt; u16 fd_ip4_filter_cnt; /* Flexible filter table values that need to be programmed into diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 2dce5f5a486e..d9b379ef203b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -2469,6 +2469,9 @@ static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf, fsp->h_u.tcp_ip4_spec.ip4dst = rule->src_ip; switch (rule->flow_type) { + case SCTP_V4_FLOW: + index = I40E_FILTER_PCTYPE_NONF_IPV4_SCTP; + break; case TCP_V4_FLOW: index = I40E_FILTER_PCTYPE_NONF_IPV4_TCP; break; @@ -3291,6 +3294,10 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi, int err; switch (fsp->flow_type & ~FLOW_EXT) { + case SCTP_V4_FLOW: + index = I40E_FILTER_PCTYPE_NONF_IPV4_SCTP; + fdir_filter_count = &pf->fd_sctp4_filter_cnt; + break; case TCP_V4_FLOW: index = I40E_FILTER_PCTYPE_NONF_IPV4_TCP; fdir_filter_count = &pf->fd_tcp4_filter_cnt; @@ -3322,6 +3329,9 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi, * ip4dst fields. */ switch (fsp->flow_type & ~FLOW_EXT) { + case SCTP_V4_FLOW: + new_mask &= ~I40E_VERIFY_TAG_MASK; + /* Fall through */ case TCP_V4_FLOW: case UDP_V4_FLOW: tcp_ip4_spec = &fsp->m_u.tcp_ip4_spec; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index a2cd3979b81a..6223db6ac728 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3323,6 +3323,7 @@ static void i40e_fdir_filter_restore(struct i40e_vsi *vsi) /* Reset FDir counters as we're replaying all existing filters */ pf->fd_tcp4_filter_cnt = 0; pf->fd_udp4_filter_cnt = 0; + pf->fd_sctp4_filter_cnt = 0; pf->fd_ip4_filter_cnt = 0; hlist_for_each_entry_safe(filter, node, @@ -5912,6 +5913,7 @@ static void i40e_fdir_filter_exit(struct i40e_pf *pf) pf->fdir_pf_active_filters = 0; pf->fd_tcp4_filter_cnt = 0; pf->fd_udp4_filter_cnt = 0; + pf->fd_sctp4_filter_cnt = 0; pf->fd_ip4_filter_cnt = 0; /* Reprogram the default input set for TCP/IPv4 */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index cb38a248c38f..1dabe5c57a88 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -347,6 +347,80 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi, return 0; } +#define I40E_SCTPIP_DUMMY_PACKET_LEN 46 +/** + * i40e_add_del_fdir_sctpv4 - Add/Remove SCTPv4 Flow Director filters for + * a specific flow spec + * @vsi: pointer to the targeted VSI + * @fd_data: the flow director data required for the FDir descriptor + * @add: true adds a filter, false removes it + * + * Returns 0 if the filters were successfully added or removed + **/ +static int i40e_add_del_fdir_sctpv4(struct i40e_vsi *vsi, + struct i40e_fdir_filter *fd_data, + bool add) +{ + struct i40e_pf *pf = vsi->back; + struct sctphdr *sctp; + struct iphdr *ip; + u8 *raw_packet; + int ret; + /* Dummy packet */ + static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0, + 0x45, 0, 0, 0x20, 0, 0, 0x40, 0, 0x40, 0x84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_SIZE, GFP_KERNEL); + if (!raw_packet) + return -ENOMEM; + memcpy(raw_packet, packet, I40E_SCTPIP_DUMMY_PACKET_LEN); + + ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET); + sctp = (struct sctphdr *)(raw_packet + IP_HEADER_OFFSET + + sizeof(struct iphdr)); + + ip->daddr = fd_data->dst_ip; + sctp->dest = fd_data->dst_port; + ip->saddr = fd_data->src_ip; + sctp->source = fd_data->src_port; + + if (fd_data->flex_filter) { + u8 *payload = raw_packet + I40E_SCTPIP_DUMMY_PACKET_LEN; + __be16 pattern = fd_data->flex_word; + u16 off = fd_data->flex_offset; + + *((__force __be16 *)(payload + off)) = pattern; + } + + fd_data->pctype = I40E_FILTER_PCTYPE_NONF_IPV4_SCTP; + ret = i40e_program_fdir_filter(fd_data, raw_packet, pf, add); + if (ret) { + dev_info(&pf->pdev->dev, + "PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n", + fd_data->pctype, fd_data->fd_id, ret); + /* Free the packet buffer since it wasn't added to the ring */ + kfree(raw_packet); + return -EOPNOTSUPP; + } else if (I40E_DEBUG_FD & pf->hw.debug_mask) { + if (add) + dev_info(&pf->pdev->dev, + "Filter OK for PCTYPE %d loc = %d\n", + fd_data->pctype, fd_data->fd_id); + else + dev_info(&pf->pdev->dev, + "Filter deleted for PCTYPE %d loc = %d\n", + fd_data->pctype, fd_data->fd_id); + } + + if (add) + pf->fd_sctp4_filter_cnt++; + else + pf->fd_sctp4_filter_cnt--; + + return 0; +} + #define I40E_IP_DUMMY_PACKET_LEN 34 /** * i40e_add_del_fdir_ipv4 - Add/Remove IPv4 Flow Director filters for @@ -441,6 +515,9 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi, case UDP_V4_FLOW: ret = i40e_add_del_fdir_udpv4(vsi, input, add); break; + case SCTP_V4_FLOW: + ret = i40e_add_del_fdir_sctpv4(vsi, input, add); + break; case IP_USER_FLOW: switch (input->ip4_proto) { case IPPROTO_TCP: @@ -449,6 +526,9 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi, case IPPROTO_UDP: ret = i40e_add_del_fdir_udpv4(vsi, input, add); break; + case IPPROTO_SCTP: + ret = i40e_add_del_fdir_sctpv4(vsi, input, add); + break; case IPPROTO_IP: ret = i40e_add_del_fdir_ipv4(vsi, input, add); break;