src/dpdk/drivers/net/i40e/i40e_ethdev.c
int
i40e_ethertype_filter_set(struct i40e_pf *pf,
			struct rte_eth_ethertype_filter *filter,
			bool add)
{
	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
	struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
	struct i40e_ethertype_filter *ethertype_filter, *node;
	struct i40e_ethertype_filter check_filter;
	struct i40e_control_filter_stats stats;
	uint16_t flags = 0;
	int ret;

	if (filter->queue >= pf->dev_data->nb_rx_queues) {
		PMD_DRV_LOG(ERR, "Invalid queue ID");
		return -EINVAL;
	}
	if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
		filter->ether_type == RTE_ETHER_TYPE_IPV6) {
		PMD_DRV_LOG(INFO,
			"unsupported ether_type(0x%04x) in control packet filter.",
			filter->ether_type);
		return -EINVAL;
	}
	if (filter->ether_type == RTE_ETHER_TYPE_VLAN)
		PMD_DRV_LOG(WARNING,
			"filter vlan ether_type in first tag is not supported.");

	/* Check if there is the filter in SW list */
	memset(&check_filter, 0, sizeof(check_filter));
	i40e_ethertype_filter_convert(filter, &check_filter);
	node = i40e_sw_ethertype_filter_lookup(ethertype_rule,
					       &check_filter.input);
	if (add && node) {
		PMD_DRV_LOG(ERR, "Conflict with existing ethertype rules!");
		return -EINVAL;
	}

	if (!add && !node) {
		//PMD_DRV_LOG(ERR, "There's no corresponding ethertype filter!");
		return -EINVAL;
	}

	if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC))
		flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
	if (filter->flags & RTE_ETHTYPE_FLAGS_DROP)
		flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP;
	flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE;

	memset(&stats, 0, sizeof(stats));
	ret = i40e_aq_add_rem_control_packet_filter(hw,
			filter->mac_addr.addr_bytes,
			filter->ether_type, flags,
			pf->main_vsi->seid,
			filter->queue, add, &stats, NULL);

	PMD_DRV_LOG(INFO,
		"add/rem control packet filter, return %d, mac_etype_used = %u, etype_used = %u, mac_etype_free = %u, etype_free = %u",
		ret, stats.mac_etype_used, stats.etype_used,
		stats.mac_etype_free, stats.etype_free);
	if (ret < 0)
		return -ENOSYS;

	/* Add or delete a filter in SW list */
	if (add) {
		ethertype_filter = rte_zmalloc("ethertype_filter",
				       sizeof(*ethertype_filter), 0);
		if (ethertype_filter == NULL) {
			PMD_DRV_LOG(ERR, "Failed to alloc memory.");
			return -ENOMEM;
		}

		rte_memcpy(ethertype_filter, &check_filter,
			   sizeof(check_filter));
		ret = i40e_sw_ethertype_filter_insert(pf, ethertype_filter);
		if (ret < 0)
			rte_free(ethertype_filter);
	} else {
		ret = i40e_sw_ethertype_filter_del(pf, &node->input);
	}

	return ret;
}
/*
 * Configure ethertype filter, which can director packet by filtering
 * with mac address and ether_type or only ether_type
 */
Configure ethertype filter, which can director packet by filtering
with mac address and ether_type or only ether_type
Configure ethertype filter which can director packet by filtering with mac address and ether_type or only ether_type
int
i40e_ethertype_filter_set(struct i40e_pf *pf,
			struct rte_eth_ethertype_filter *filter,
			bool add)
{
	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
	struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
	struct i40e_ethertype_filter *ethertype_filter, *node;
	struct i40e_ethertype_filter check_filter;
	struct i40e_control_filter_stats stats;
	uint16_t flags = 0;
	int ret;
	if (filter->queue >= pf->dev_data->nb_rx_queues) {
		PMD_DRV_LOG(ERR, "Invalid queue ID");
		return -EINVAL;
	}
	if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
		filter->ether_type == RTE_ETHER_TYPE_IPV6) {
		PMD_DRV_LOG(INFO,
			"unsupported ether_type(0x%04x) in control packet filter.",
			filter->ether_type);
		return -EINVAL;
	}
	if (filter->ether_type == RTE_ETHER_TYPE_VLAN)
		PMD_DRV_LOG(WARNING,
			"filter vlan ether_type in first tag is not supported.");
	memset(&check_filter, 0, sizeof(check_filter));
	i40e_ethertype_filter_convert(filter, &check_filter);
	node = i40e_sw_ethertype_filter_lookup(ethertype_rule,
					       &check_filter.input);
	if (add && node) {
		PMD_DRV_LOG(ERR, "Conflict with existing ethertype rules!");
		return -EINVAL;
	}
	if (!add && !node) {
		return -EINVAL;
	}
	if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC))
		flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
	if (filter->flags & RTE_ETHTYPE_FLAGS_DROP)
		flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP;
	flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE;
	memset(&stats, 0, sizeof(stats));
	ret = i40e_aq_add_rem_control_packet_filter(hw,
			filter->mac_addr.addr_bytes,
			filter->ether_type, flags,
			pf->main_vsi->seid,
			filter->queue, add, &stats, NULL);
	PMD_DRV_LOG(INFO,
		"add/rem control packet filter, return %d, mac_etype_used = %u, etype_used = %u, mac_etype_free = %u, etype_free = %u",
		ret, stats.mac_etype_used, stats.etype_used,
		stats.mac_etype_free, stats.etype_free);
	if (ret < 0)
		return -ENOSYS;
	if (add) {
		ethertype_filter = rte_zmalloc("ethertype_filter",
				       sizeof(*ethertype_filter), 0);
		if (ethertype_filter == NULL) {
			PMD_DRV_LOG(ERR, "Failed to alloc memory.");
			return -ENOMEM;
		}
		rte_memcpy(ethertype_filter, &check_filter,
			   sizeof(check_filter));
		ret = i40e_sw_ethertype_filter_insert(pf, ethertype_filter);
		if (ret < 0)
			rte_free(ethertype_filter);
	} else {
		ret = i40e_sw_ethertype_filter_del(pf, &node->input);
	}
	return ret;
}
int i40e_ethertype_filter_set ( struct i40e_pf * pf , struct rte_eth_ethertype_filter * filter , bool add ) { struct i40e_hw * hw = I40E_PF_TO_HW ( pf ) ; struct i40e_ethertype_rule * ethertype_rule = & pf -> ethertype ; struct i40e_ethertype_filter * ethertype_filter , * node ; struct i40e_ethertype_filter check_filter ; struct i40e_control_filter_stats stats ; uint16_t flags = 0 ; int ret ; if ( filter -> queue >= pf -> dev_data -> nb_rx_queues ) { PMD_DRV_LOG ( ERR , " " ) ; return - EINVAL ; } if ( filter -> ether_type == RTE_ETHER_TYPE_IPV4 || filter -> ether_type == RTE_ETHER_TYPE_IPV6 ) { PMD_DRV_LOG ( INFO , " " , filter -> ether_type ) ; return - EINVAL ; } if ( filter -> ether_type == RTE_ETHER_TYPE_VLAN ) PMD_DRV_LOG ( WARNING , " " ) ; memset ( & check_filter , 0 , sizeof ( check_filter ) ) ; i40e_ethertype_filter_convert ( filter , & check_filter ) ; node = i40e_sw_ethertype_filter_lookup ( ethertype_rule , & check_filter . input ) ; if ( add && node ) { PMD_DRV_LOG ( ERR , " " ) ; return - EINVAL ; } if ( ! add && ! node ) { return - EINVAL ; } if ( ! ( filter -> flags & RTE_ETHTYPE_FLAGS_MAC ) ) flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC ; if ( filter -> flags & RTE_ETHTYPE_FLAGS_DROP ) flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP ; flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE ; memset ( & stats , 0 , sizeof ( stats ) ) ; ret = i40e_aq_add_rem_control_packet_filter ( hw , filter -> mac_addr . addr_bytes , filter -> ether_type , flags , pf -> main_vsi -> seid , filter -> queue , add , & stats , NULL ) ; PMD_DRV_LOG ( INFO , " " , ret , stats . mac_etype_used , stats . etype_used , stats . mac_etype_free , stats . etype_free ) ; if ( ret < 0 ) return - ENOSYS ; if ( add ) { ethertype_filter = rte_zmalloc ( " " , sizeof ( * ethertype_filter ) , 0 ) ; if ( ethertype_filter == NULL ) { PMD_DRV_LOG ( ERR , " " ) ; return - ENOMEM ; } rte_memcpy ( ethertype_filter , & check_filter , sizeof ( check_filter ) ) ; ret = i40e_sw_ethertype_filter_insert ( pf , ethertype_filter ) ; if ( ret < 0 ) rte_free ( ethertype_filter ) ; } else { ret = i40e_sw_ethertype_filter_del ( pf , & node -> input ) ; } return ret ; }
Configure ethertype filter, which can director packet by filtering
 with mac address and ether_type or only ether_type
Configure ethertype filter which can director packet by filtering with mac address and ether_type or only ether_type
/* Check if there is the filter in SW list */ //PMD_DRV_LOG(ERR, "There's no corresponding ethertype filter!"); /* Add or delete a filter in SW list */