<commit_before>/*
 * Copyright 2008-2014 Cisco Systems, Inc.  All rights reserved.
 * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
 *
 * Copyright (c) 2014, Cisco Systems, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <libgen.h>

#include <rte_ethdev.h>
#include <rte_malloc.h>
#include <rte_hash.h>
#include <rte_byteorder.h>
#include <rte_ip.h>
#include <rte_tcp.h>
#include <rte_udp.h>
#include <rte_sctp.h>
#include <rte_eth_ctrl.h>

#include "enic_compat.h"
#include "enic.h"
#include "wq_enet_desc.h"
#include "rq_enet_desc.h"
#include "cq_enet_desc.h"
#include "vnic_enet.h"
#include "vnic_dev.h"
#include "vnic_wq.h"
#include "vnic_rq.h"
#include "vnic_cq.h"
#include "vnic_intr.h"
#include "vnic_nic.h"

#ifdef RTE_MACHINE_CPUFLAG_SSE4_2
#include <rte_hash_crc.h>
#define DEFAULT_HASH_FUNC       rte_hash_crc
#else
#include <rte_jhash.h>
#define DEFAULT_HASH_FUNC       rte_jhash
#endif

#define ENICPMD_CLSF_HASH_ENTRIES       ENICPMD_FDIR_MAX

void enic_fdir_stats_get(struct enic *enic, struct rte_eth_fdir_stats *stats)
{
	*stats = enic->fdir.stats;
}

void enic_fdir_info_get(struct enic *enic, struct rte_eth_fdir_info *info)
{
	info->mode = (enum rte_fdir_mode)enic->fdir.modes;
	info->flow_types_mask[0] = enic->fdir.types_mask;
}

void enic_fdir_info(struct enic *enic)
{
	enic->fdir.modes = (u32)RTE_FDIR_MODE_PERFECT;
	enic->fdir.types_mask  = 1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP |
				 1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP;
	if (enic->adv_filters) {
		enic->fdir.types_mask |= 1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER;
		enic->fdir.copy_fltr_fn = copy_fltr_v2;
	} else {
		enic->fdir.copy_fltr_fn = copy_fltr_v1;
	}
}

static void
enic_set_layer(struct filter_generic_1 *gp, unsigned int flag,
	       enum filter_generic_1_layer layer, void *mask, void *val,
	       unsigned int len)
{
	gp->mask_flags |= flag;
	gp->val_flags |= gp->mask_flags;
	memcpy(gp->layer[layer].mask, mask, len);
	memcpy(gp->layer[layer].val, val, len);
}

/* Copy Flow Director filter to a VIC ipv4 filter (for Cisco VICs
 * without advanced filter support.
 */
void
copy_fltr_v1(struct filter_v2 *fltr, struct rte_eth_fdir_input *input,
	     __rte_unused struct rte_eth_fdir_masks *masks)
{
	fltr->type = FILTER_IPV4_5TUPLE;
	fltr->u.ipv4.src_addr = rte_be_to_cpu_32(
		input->flow.ip4_flow.src_ip);
	fltr->u.ipv4.dst_addr = rte_be_to_cpu_32(
		input->flow.ip4_flow.dst_ip);
	fltr->u.ipv4.src_port = rte_be_to_cpu_16(
		input->flow.udp4_flow.src_port);
	fltr->u.ipv4.dst_port = rte_be_to_cpu_16(
		input->flow.udp4_flow.dst_port);

	if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_TCP)
		fltr->u.ipv4.protocol = PROTO_TCP;
	else
		fltr->u.ipv4.protocol = PROTO_UDP;

	fltr->u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE;
}

/* Copy Flow Director filter to a VIC generic filter (requires advanced
 * filter support.
 */
void
copy_fltr_v2(struct filter_v2 *fltr, struct rte_eth_fdir_input *input,
	     struct rte_eth_fdir_masks *masks)
{
	struct filter_generic_1 *gp = &fltr->u.generic_1;
	int i;

	fltr->type = FILTER_DPDK_1;
	memset(gp, 0, sizeof(*gp));

	if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_UDP) {
		struct udp_hdr udp_mask, udp_val;
		memset(&udp_mask, 0, sizeof(udp_mask));
		memset(&udp_val, 0, sizeof(udp_val));

		if (input->flow.udp4_flow.src_port) {
			udp_mask.src_port = masks->src_port_mask;
			udp_val.src_port = input->flow.udp4_flow.src_port;
		}
		if (input->flow.udp4_flow.dst_port) {
			udp_mask.src_port = masks->dst_port_mask;
			udp_val.dst_port = input->flow.udp4_flow.dst_port;
		}

		enic_set_layer(gp, FILTER_GENERIC_1_UDP, FILTER_GENERIC_1_L4,
			       &udp_mask, &udp_val, sizeof(struct udp_hdr));
	} else if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_TCP) {
		struct tcp_hdr tcp_mask, tcp_val;
		memset(&tcp_mask, 0, sizeof(tcp_mask));
		memset(&tcp_val, 0, sizeof(tcp_val));

		if (input->flow.tcp4_flow.src_port) {
			tcp_mask.src_port = masks->src_port_mask;
			tcp_val.src_port = input->flow.tcp4_flow.src_port;
		}
		if (input->flow.tcp4_flow.dst_port) {
			tcp_mask.dst_port = masks->dst_port_mask;<commit_msg>net/enic: fix UDP port in flow director<commit_after>/*
 * Copyright 2008-2014 Cisco Systems, Inc.  All rights reserved.
 * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
 *
 * Copyright (c) 2014, Cisco Systems, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <libgen.h>

#include <rte_ethdev.h>
#include <rte_malloc.h>
#include <rte_hash.h>
#include <rte_byteorder.h>
#include <rte_ip.h>
#include <rte_tcp.h>
#include <rte_udp.h>
#include <rte_sctp.h>
#include <rte_eth_ctrl.h>

#include "enic_compat.h"
#include "enic.h"
#include "wq_enet_desc.h"
#include "rq_enet_desc.h"
#include "cq_enet_desc.h"
#include "vnic_enet.h"
#include "vnic_dev.h"
#include "vnic_wq.h"
#include "vnic_rq.h"
#include "vnic_cq.h"
#include "vnic_intr.h"
#include "vnic_nic.h"

#ifdef RTE_MACHINE_CPUFLAG_SSE4_2
#include <rte_hash_crc.h>
#define DEFAULT_HASH_FUNC       rte_hash_crc
#else
#include <rte_jhash.h>
#define DEFAULT_HASH_FUNC       rte_jhash
#endif

#define ENICPMD_CLSF_HASH_ENTRIES       ENICPMD_FDIR_MAX

void enic_fdir_stats_get(struct enic *enic, struct rte_eth_fdir_stats *stats)
{
	*stats = enic->fdir.stats;
}

void enic_fdir_info_get(struct enic *enic, struct rte_eth_fdir_info *info)
{
	info->mode = (enum rte_fdir_mode)enic->fdir.modes;
	info->flow_types_mask[0] = enic->fdir.types_mask;
}

void enic_fdir_info(struct enic *enic)
{
	enic->fdir.modes = (u32)RTE_FDIR_MODE_PERFECT;
	enic->fdir.types_mask  = 1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP |
				 1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP;
	if (enic->adv_filters) {
		enic->fdir.types_mask |= 1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP |
					 1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER;
		enic->fdir.copy_fltr_fn = copy_fltr_v2;
	} else {
		enic->fdir.copy_fltr_fn = copy_fltr_v1;
	}
}

static void
enic_set_layer(struct filter_generic_1 *gp, unsigned int flag,
	       enum filter_generic_1_layer layer, void *mask, void *val,
	       unsigned int len)
{
	gp->mask_flags |= flag;
	gp->val_flags |= gp->mask_flags;
	memcpy(gp->layer[layer].mask, mask, len);
	memcpy(gp->layer[layer].val, val, len);
}

/* Copy Flow Director filter to a VIC ipv4 filter (for Cisco VICs
 * without advanced filter support.
 */
void
copy_fltr_v1(struct filter_v2 *fltr, struct rte_eth_fdir_input *input,
	     __rte_unused struct rte_eth_fdir_masks *masks)
{
	fltr->type = FILTER_IPV4_5TUPLE;
	fltr->u.ipv4.src_addr = rte_be_to_cpu_32(
		input->flow.ip4_flow.src_ip);
	fltr->u.ipv4.dst_addr = rte_be_to_cpu_32(
		input->flow.ip4_flow.dst_ip);
	fltr->u.ipv4.src_port = rte_be_to_cpu_16(
		input->flow.udp4_flow.src_port);
	fltr->u.ipv4.dst_port = rte_be_to_cpu_16(
		input->flow.udp4_flow.dst_port);

	if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_TCP)
		fltr->u.ipv4.protocol = PROTO_TCP;
	else
		fltr->u.ipv4.protocol = PROTO_UDP;

	fltr->u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE;
}

/* Copy Flow Director filter to a VIC generic filter (requires advanced
 * filter support.
 */
void
copy_fltr_v2(struct filter_v2 *fltr, struct rte_eth_fdir_input *input,
	     struct rte_eth_fdir_masks *masks)
{
	struct filter_generic_1 *gp = &fltr->u.generic_1;
	int i;

	fltr->type = FILTER_DPDK_1;
	memset(gp, 0, sizeof(*gp));

	if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_UDP) {
		struct udp_hdr udp_mask, udp_val;
		memset(&udp_mask, 0, sizeof(udp_mask));
		memset(&udp_val, 0, sizeof(udp_val));

		if (input->flow.udp4_flow.src_port) {
			udp_mask.src_port = masks->src_port_mask;
			udp_val.src_port = input->flow.udp4_flow.src_port;
		}
		if (input->flow.udp4_flow.dst_port) {
			udp_mask.dst_port = masks->dst_port_mask;
			udp_val.dst_port = input->flow.udp4_flow.dst_port;
		}

		enic_set_layer(gp, FILTER_GENERIC_1_UDP, FILTER_GENERIC_1_L4,
			       &udp_mask, &udp_val, sizeof(struct udp_hdr));
	} else if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_TCP) {
		struct tcp_hdr tcp_mask, tcp_val;
		memset(&tcp_mask, 0, sizeof(tcp_mask));
		memset(&tcp_val, 0, sizeof(tcp_val));

		if (input->flow.tcp4_flow.src_port) {
			tcp_mask.src_port = masks->src_port_mask;
			tcp_val.src_port = input->flow.tcp4_flow.src_port;
		}
		if (input->flow.tcp4_flow.dst_port) {
			tcp_mask.dst_port = masks->dst_port_mask;
{'fraction_non_alphanumeric': 0.10649304316803425, 'fraction_numerical': 0.01641098822689975, 'mean_word_length': 4.674595141700405, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 115, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1754647', 'n_tokens_mistral': 4790, 'n_tokens_neox': 4410, 'n_words': 991}