int gve_fill_ethtool_flow_spec()

in build/gve_flow_rule.c [11:114]


int gve_fill_ethtool_flow_spec(struct ethtool_rx_flow_spec *fsp,
			       struct gve_adminq_queried_flow_rule *rule)
{
	struct gve_adminq_flow_rule *flow_rule = &rule->flow_rule;
	static const u16 flow_type_lut[] = {
		[GVE_FLOW_TYPE_TCPV4]	= TCP_V4_FLOW,
		[GVE_FLOW_TYPE_UDPV4]	= UDP_V4_FLOW,
		[GVE_FLOW_TYPE_SCTPV4]	= SCTP_V4_FLOW,
		[GVE_FLOW_TYPE_AHV4]	= AH_V4_FLOW,
		[GVE_FLOW_TYPE_ESPV4]	= ESP_V4_FLOW,
		[GVE_FLOW_TYPE_TCPV6]	= TCP_V6_FLOW,
		[GVE_FLOW_TYPE_UDPV6]	= UDP_V6_FLOW,
		[GVE_FLOW_TYPE_SCTPV6]	= SCTP_V6_FLOW,
		[GVE_FLOW_TYPE_AHV6]	= AH_V6_FLOW,
		[GVE_FLOW_TYPE_ESPV6]	= ESP_V6_FLOW,
	};

	if (be16_to_cpu(flow_rule->flow_type) >= ARRAY_SIZE(flow_type_lut))
		return -EINVAL;

	fsp->flow_type = flow_type_lut[be16_to_cpu(flow_rule->flow_type)];

	memset(&fsp->h_u, 0, sizeof(fsp->h_u));
	memset(&fsp->h_ext, 0, sizeof(fsp->h_ext));
	memset(&fsp->m_u, 0, sizeof(fsp->m_u));
	memset(&fsp->m_ext, 0, sizeof(fsp->m_ext));

	switch (fsp->flow_type) {
	case TCP_V4_FLOW:
	case UDP_V4_FLOW:
	case SCTP_V4_FLOW:
		fsp->h_u.tcp_ip4_spec.ip4src = flow_rule->key.src_ip[0];
		fsp->h_u.tcp_ip4_spec.ip4dst = flow_rule->key.dst_ip[0];
		fsp->h_u.tcp_ip4_spec.psrc = flow_rule->key.src_port;
		fsp->h_u.tcp_ip4_spec.pdst = flow_rule->key.dst_port;
		fsp->h_u.tcp_ip4_spec.tos = flow_rule->key.tos;
		fsp->m_u.tcp_ip4_spec.ip4src = flow_rule->mask.src_ip[0];
		fsp->m_u.tcp_ip4_spec.ip4dst = flow_rule->mask.dst_ip[0];
		fsp->m_u.tcp_ip4_spec.psrc = flow_rule->mask.src_port;
		fsp->m_u.tcp_ip4_spec.pdst = flow_rule->mask.dst_port;
		fsp->m_u.tcp_ip4_spec.tos = flow_rule->mask.tos;
		break;
	case AH_V4_FLOW:
	case ESP_V4_FLOW:
		fsp->h_u.ah_ip4_spec.ip4src = flow_rule->key.src_ip[0];
		fsp->h_u.ah_ip4_spec.ip4dst = flow_rule->key.dst_ip[0];
		fsp->h_u.ah_ip4_spec.spi = flow_rule->key.spi;
		fsp->h_u.ah_ip4_spec.tos = flow_rule->key.tos;
		fsp->m_u.ah_ip4_spec.ip4src = flow_rule->mask.src_ip[0];
		fsp->m_u.ah_ip4_spec.ip4dst = flow_rule->mask.dst_ip[0];
		fsp->m_u.ah_ip4_spec.spi = flow_rule->mask.spi;
		fsp->m_u.ah_ip4_spec.tos = flow_rule->mask.tos;
		break;
	case TCP_V6_FLOW:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0))
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) */
	case UDP_V6_FLOW:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0))
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) */
	case SCTP_V6_FLOW:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0))
		memcpy(fsp->h_u.tcp_ip6_spec.ip6src, &flow_rule->key.src_ip,
		       sizeof(struct in6_addr));
		memcpy(fsp->h_u.tcp_ip6_spec.ip6dst, &flow_rule->key.dst_ip,
		       sizeof(struct in6_addr));
		fsp->h_u.tcp_ip6_spec.psrc = flow_rule->key.src_port;
		fsp->h_u.tcp_ip6_spec.pdst = flow_rule->key.dst_port;
		fsp->h_u.tcp_ip6_spec.tclass = flow_rule->key.tclass;
		memcpy(fsp->m_u.tcp_ip6_spec.ip6src, &flow_rule->mask.src_ip,
		       sizeof(struct in6_addr));
		memcpy(fsp->m_u.tcp_ip6_spec.ip6dst, &flow_rule->mask.dst_ip,
		       sizeof(struct in6_addr));
		fsp->m_u.tcp_ip6_spec.psrc = flow_rule->mask.src_port;
		fsp->m_u.tcp_ip6_spec.pdst = flow_rule->mask.dst_port;
		fsp->m_u.tcp_ip6_spec.tclass = flow_rule->mask.tclass;
		break;
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) */
	case AH_V6_FLOW:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0))
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) */
	case ESP_V6_FLOW:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0))
		memcpy(fsp->h_u.ah_ip6_spec.ip6src, &flow_rule->key.src_ip,
		       sizeof(struct in6_addr));
		memcpy(fsp->h_u.ah_ip6_spec.ip6dst, &flow_rule->key.dst_ip,
		       sizeof(struct in6_addr));
		fsp->h_u.ah_ip6_spec.spi = flow_rule->key.spi;
		fsp->h_u.ah_ip6_spec.tclass = flow_rule->key.tclass;
		memcpy(fsp->m_u.ah_ip6_spec.ip6src, &flow_rule->mask.src_ip,
		       sizeof(struct in6_addr));
		memcpy(fsp->m_u.ah_ip6_spec.ip6dst, &flow_rule->mask.dst_ip,
		       sizeof(struct in6_addr));
		fsp->m_u.ah_ip6_spec.spi = flow_rule->mask.spi;
		fsp->m_u.ah_ip6_spec.tclass = flow_rule->mask.tclass;
		break;
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) */
	default:
		return -EINVAL;
	}

	fsp->ring_cookie = be16_to_cpu(flow_rule->action);

	return 0;
}