/*
 * ********************************************************************************
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************************
 */
#ifndef __NSS_IPSECMGR_FLOW_H
#define __NSS_IPSECMGR_FLOW_H

#define NSS_IPSECMGR_FLOW_MAX 1024 /* Maximum number of flow(s) */
#if (~(NSS_IPSECMGR_FLOW_MAX - 1) & (NSS_IPSECMGR_FLOW_MAX >> 1))
#error "NSS_IPSECMGR_FLOW_MAX is not a power of 2"
#endif

#define NSS_IPSECMGR_FLOW_PRINT_EXTRA 64
#define NSS_IPSECMGR_FLOW_FREE_TIMEOUT msecs_to_jiffies(20) /* msecs */

struct nss_ipsecmgr_sa;

/*
 * Per flow state
 */
struct nss_ipsecmgr_flow_state {
	struct nss_ipsec_cmn_flow_tuple tuple;	/* Flow tuple */
	struct nss_ipsec_cmn_sa_tuple sa;	/* SA tuple; used during deletion */
};

/*
 * IPsec manager flow entry
 */
struct nss_ipsecmgr_flow {
	struct list_head list;			/* List object. */
	struct nss_ipsecmgr_ref ref;		/* Reference object. */
	struct nss_ipsecmgr_sa *sa;		/* Parent SA object */

	uint32_t ifnum;				/* NSS interface attached to flow */
	struct nss_ctx_instance *nss_ctx;	/* NSS context */
	struct nss_ipsecmgr_flow_state state;

	int tunnel_id;				/* Linux device index */
};

/*
 * nss_ipsecmgr_flow_ntoh_v6addr()
 *	Network to host order and swap
 */
static inline void nss_ipsecmgr_flow_ntoh_v6addr(uint32_t *dest, uint32_t *src)
{
	dest[0] = ntohl(src[0]);
	dest[1] = ntohl(src[1]);
	dest[2] = ntohl(src[2]);
	dest[3] = ntohl(src[3]);
}

/*
 * nss_ipsecmgr_flow_tuple_match()
 * 	Match flow tuple
 */
static inline bool nss_ipsecmgr_flow_tuple_match(struct nss_ipsec_cmn_flow_tuple *d, struct nss_ipsec_cmn_flow_tuple *s)
{
	uint32_t status = 0;

	switch (d->ip_ver) {
	case IPVERSION:
		status += d->dest_ip[0] ^ s->dest_ip[0];
		status += d->src_ip[0] ^ s->src_ip[0];
		status += d->spi_index ^ s->spi_index;
		status += d->protocol ^ s->protocol;
		status += d->ip_ver ^ s->ip_ver;
		status += d->user_pattern ^ s->user_pattern;
		return !status;

	default:
		status += d->dest_ip[0] ^ s->dest_ip[0];
		status += d->dest_ip[1] ^ s->dest_ip[1];
		status += d->dest_ip[2] ^ s->dest_ip[2];
		status += d->dest_ip[3] ^ s->dest_ip[3];
		status += d->src_ip[0] ^ s->src_ip[0];
		status += d->src_ip[1] ^ s->src_ip[1];
		status += d->src_ip[2] ^ s->src_ip[2];
		status += d->src_ip[3] ^ s->src_ip[3];
		status += d->spi_index ^ s->spi_index;
		status += d->protocol ^ s->protocol;
		status += d->ip_ver ^ s->ip_ver;
		status += d->user_pattern ^ s->user_pattern;
		return !status;
	}
}

/*
 * nss_ipsecmgr_flow_tuple2index()
 * 	Change tuple to hash index
 */
static inline uint32_t nss_ipsecmgr_flow_tuple2hash(struct nss_ipsec_cmn_flow_tuple *tuple, uint32_t max)
{
	uint32_t val = 0;

	val ^= tuple->dest_ip[0];
	val ^= tuple->src_ip[0];
	val ^= tuple->dest_ip[1];
	val ^= tuple->src_ip[1];
	val ^= tuple->dest_ip[2];
	val ^= tuple->src_ip[2];
	val ^= tuple->dest_ip[3];
	val ^= tuple->src_ip[3];
	val ^= tuple->spi_index;
	val ^= tuple->protocol;
	val ^= tuple->ip_ver;
	val ^= tuple->user_pattern;

	return val & (max - 1);
}

/*
 * nss_ipsecmgr_flow2tuple()
 * 	Change flow to tuple
 */
static inline void nss_ipsecmgr_flow2tuple(struct nss_ipsecmgr_flow_tuple *f, struct nss_ipsec_cmn_flow_tuple *t)
{
	memcpy(t->dest_ip, f->dest_ip, sizeof(t->dest_ip));
	memcpy(t->src_ip, f->src_ip, sizeof(t->src_ip));
	t->spi_index = f->spi_index;
	t->protocol = f->proto_next_hdr;
	t->ip_ver = f->ip_version;
	t->src_port = f->sport;
	t->dst_port = f->dport;
	t->user_pattern = f->use_pattern;
}

/*
 * nss_ipsecmgr_flow_ipv4_inner2tuple()
 * 	Change inner IPv4 flow to tuple
 */
static inline void nss_ipsecmgr_flow_ipv4_inner2tuple(struct iphdr *iph, struct nss_ipsec_cmn_flow_tuple *t)
{
	t->src_ip[0] = ntohl(iph->saddr);
	t->dest_ip[0] = ntohl(iph->daddr);
	t->ip_ver = IPVERSION;
	t->protocol = iph->protocol;
}

/*
 * nss_ipsecmgr_flow_ipv4_outer2tuple()
 * 	Change outer IPv4 flow to tuple
 */
static inline void nss_ipsecmgr_flow_ipv4_outer2tuple(struct iphdr *iph, struct nss_ipsec_cmn_flow_tuple *t)
{
	uint8_t *data = (uint8_t *)iph;
	struct ip_esp_hdr *esph;

	WARN_ON((iph->protocol != IPPROTO_ESP) && (iph->protocol != IPPROTO_UDP));

	t->src_ip[0] = ntohl(iph->saddr);
	t->dest_ip[0] = ntohl(iph->daddr);
	t->ip_ver = IPVERSION;
	t->protocol = iph->protocol;

	data += sizeof(*iph);

	if (t->protocol == IPPROTO_UDP)
		data += sizeof(struct udphdr);

	esph = (struct ip_esp_hdr *)data;
	t->spi_index = ntohl(esph->spi);
}

/*
 * nss_ipsecmgr_flow_ipv6_inner2tuple()
 * 	Change inner IPv6 flow to tuple
 */
static inline void nss_ipsecmgr_flow_ipv6_inner2tuple(struct ipv6hdr *ip6h, struct nss_ipsec_cmn_flow_tuple *t)
{
	uint8_t *data = (uint8_t *)ip6h;
	struct frag_hdr *fragh;

	nss_ipsecmgr_flow_ntoh_v6addr(t->src_ip, ip6h->saddr.s6_addr32);
	nss_ipsecmgr_flow_ntoh_v6addr(t->dest_ip, ip6h->daddr.s6_addr32);

	t->protocol = ip6h->nexthdr;
	t->ip_ver = 6;

	data += sizeof(*ip6h);

	if (t->protocol == NEXTHDR_FRAGMENT) {
		fragh = (struct frag_hdr *)data;
		t->protocol = fragh->nexthdr;
	}
}

/*
 * nss_ipsecmgr_flow_ipv6_outer2tuple()
 * 	Change inner IPv6 flow to tuple
 */
static inline void nss_ipsecmgr_flow_ipv6_outer2tuple(struct ipv6hdr *ip6h, struct nss_ipsec_cmn_flow_tuple *t)
{
	uint8_t *data = (uint8_t *)ip6h;
	struct ip_esp_hdr *esph;

	nss_ipsecmgr_flow_ntoh_v6addr(t->src_ip, ip6h->saddr.s6_addr32);
	nss_ipsecmgr_flow_ntoh_v6addr(t->dest_ip, ip6h->daddr.s6_addr32);

	t->protocol = ip6h->nexthdr;
	t->ip_ver = 6;

	WARN_ON(ip6h->nexthdr != IPPROTO_ESP);

	data += sizeof(*ip6h);

	esph = (struct ip_esp_hdr *)data;
	t->spi_index = ntohl(esph->spi);
}

struct nss_ipsecmgr_flow *nss_ipsecmgr_flow_find(struct list_head *db, struct nss_ipsec_cmn_flow_tuple *t);
#endif
