/*
 * Copyright (C) 2006-2016 Tobias Brunner
 * Copyright (C) 2006 Daniel Roethlisberger
 * Copyright (C) 2005-2006 Martin Willi
 * Copyright (C) 2005 Jan Hutter
 * HSR Hochschule fuer Technik Rapperswil
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

/*
 * Copyright (c) 2012 Nanoteq Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * @defgroup kernel_interface kernel_interface
 * @{ @ingroup kernel
 */

#ifndef KERNEL_INTERFACE_H_
#define KERNEL_INTERFACE_H_

typedef struct kernel_interface_t kernel_interface_t;
typedef enum kernel_feature_t kernel_feature_t;

#include <networking/host.h>
#include <crypto/prf_plus.h>

#include <kernel/kernel_listener.h>
#include <kernel/kernel_ipsec.h>
#include <kernel/kernel_net.h>

/**
 * Default range for SPIs requested from kernels
 */
#define KERNEL_SPI_MIN 0xc0000000
#define KERNEL_SPI_MAX 0xcfffffff

/**
 * Bitfield of optional features a kernel backend supports.
 *
 * This feature-set is for both, kernel_ipsec_t and kernel_net_t. Each
 * backend returns a subset of these features.
 */
enum kernel_feature_t {
	/** IPsec can process ESPv3 (RFC 4303) TFC padded packets */
	KERNEL_ESP_V3_TFC = (1<<0),
	/** Networking requires an "exclude" route for IKE/ESP packets */
	KERNEL_REQUIRE_EXCLUDE_ROUTE = (1<<1),
	/** IPsec implementation requires UDP encapsulation of ESP packets */
	KERNEL_REQUIRE_UDP_ENCAPSULATION = (1<<2),
	/** IPsec backend does not require a policy reinstall on SA updates */
	KERNEL_NO_POLICY_UPDATES = (1<<3),
	/** IPsec backend supports installing SPIs on policies */
	KERNEL_POLICY_SPI = (1<<4),
};

/**
 * Constructor function for ipsec kernel interface
 */
typedef kernel_ipsec_t* (*kernel_ipsec_constructor_t)(void);

/**
 * Constructor function for network kernel interface
 */
typedef kernel_net_t* (*kernel_net_constructor_t)(void);

/**
 * Manager and wrapper for different kernel interfaces.
 *
 * The kernel interface handles the communication with the kernel
 * for SA and policy management and interface and IP address management.
 */
struct kernel_interface_t {

	/**
	 * Get the feature set supported by the net and ipsec kernel backends.
	 *
	 * @return				ORed feature-set of backends
	 */
	kernel_feature_t (*get_features)(kernel_interface_t *this);

	/**
	 * Get a SPI from the kernel.
	 *
	 * @param src		source address of SA
	 * @param dst		destination address of SA
	 * @param protocol	protocol for SA (ESP/AH)
	 * @param spi		allocated spi
	 * @return			SUCCESS if operation completed
	 */
	status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst,
						uint8_t protocol, uint32_t *spi);

	/**
	 * Get a Compression Parameter Index (CPI) from the kernel.
	 *
	 * @param src		source address of SA
	 * @param dst		destination address of SA
	 * @param cpi		allocated cpi
	 * @return			SUCCESS if operation completed
	 */
	status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst,
						uint16_t *cpi);

	/**
	 * Allocate or confirm a reqid to use for a given SA pair.
	 *
	 * Each returned reqid by a successful call to alloc_reqid() must be
	 * released using release_reqid().
	 *
	 * The reqid parameter is an in/out parameter. If it points to non-zero,
	 * the reqid is confirmed and registered for use. If it points to zero,
	 * a reqid is allocated for the given selectors, and returned to reqid.
	 *
	 * @param local_ts	traffic selectors of local side for SA
	 * @param remote_ts	traffic selectors of remote side for SA
	 * @param mark_in	inbound mark on SA
	 * @param mark_out	outbound mark on SA
	 * @param if_id_in	inbound interface ID on SA
	 * @param if_id_out	outbound interface ID on SA
	 * @param reqid		allocated reqid
	 * @return			SUCCESS if reqid allocated
	 */
	status_t (*alloc_reqid)(kernel_interface_t *this,
							linked_list_t *local_ts, linked_list_t *remote_ts,
							mark_t mark_in, mark_t mark_out, uint32_t if_id_in,
							uint32_t if_id_out, uint32_t *reqid);

	/**
	 * Release a previously allocated reqid.
	 *
	 * @param reqid		reqid to release
	 * @param mark_in	inbound mark on SA
	 * @param mark_out	outbound mark on SA
	 * @param if_id_in	inbound interface ID on SA
	 * @param if_id_out	outbound interface ID on SA
	 * @return			SUCCESS if reqid released
	 */
	status_t (*release_reqid)(kernel_interface_t *this, uint32_t reqid,
							  mark_t mark_in, mark_t mark_out,
							  uint32_t if_id_in, uint32_t if_id_out);

	/**
	 * Add an SA to the SAD.
	 *
	 * This function does install a single SA for a single protocol in one
	 * direction.
	 *
	 * @param id			data identifying this SA
	 * @param data			data for this SA
	 * @return				SUCCESS if operation completed
	 */
	status_t (*add_sa)(kernel_interface_t *this, kernel_ipsec_sa_id_t *id,
					   kernel_ipsec_add_sa_t *data);

	/**
	 * Update the hosts on an installed SA.
	 *
	 * We cannot directly update the destination address as the kernel
	 * requires the spi, the protocol AND the destination address (and family)
	 * to identify SAs. Therefore if the destination address changed we
	 * create a new SA and delete the old one.
	 *
	 * @param id			data identifying this SA
	 * @param data			updated data for this SA
	 * @return				SUCCESS if operation completed, NOT_SUPPORTED if
	 *						the kernel interface can't update the SA
	 */
	status_t (*update_sa)(kernel_interface_t *this, kernel_ipsec_sa_id_t *id,
						  kernel_ipsec_update_sa_t *data);

	/**
	 * Query the number of bytes processed by an SA from the SAD.
	 *
	 * @param id			data identifying this SA
	 * @param data			data to query the SA
	 * @param[out] bytes	the number of bytes processed by SA
	 * @param[out] packets	number of packets processed by SA
	 * @param[out] time		last (monotonic) time of SA use
	 * @return				SUCCESS if operation completed
	 */
	status_t (*query_sa)(kernel_interface_t *this, kernel_ipsec_sa_id_t *id,
						 kernel_ipsec_query_sa_t *data, uint64_t *bytes,
						 uint64_t *packets, time_t *time);

	/**
	 * Delete a previously installed SA from the SAD.
	 *
	 * @param id			data identifying this SA
	 * @param data			data to delete the SA
	 * @return				SUCCESS if operation completed
	 */
	status_t (*del_sa)(kernel_interface_t *this, kernel_ipsec_sa_id_t *id,
					   kernel_ipsec_del_sa_t *data);

	/**
	 * Flush all SAs from the SAD.
	 *
	 * @return				SUCCESS if operation completed
	 */
	status_t (*flush_sas)(kernel_interface_t *this);

	/**
	 * Add a policy to the SPD.
	 *
	 * @param id			data identifying this policy
	 * @param data			data for this policy
	 * @return				SUCCESS if operation completed
	 */
	status_t (*add_policy)(kernel_interface_t *this,
						   kernel_ipsec_policy_id_t *id,
						   kernel_ipsec_manage_policy_t *data);

	/**
	 * Query the use time of a policy.
	 *
	 * The use time of a policy is the time the policy was used
	 * for the last time.
	 *
	 * @param id			data identifying this policy
	 * @param data			data to query the policy
	 * @param[out] use_time	the monotonic timestamp of this SA's last use
	 * @return				SUCCESS if operation completed
	 */
	status_t (*query_policy)(kernel_interface_t *this,
							 kernel_ipsec_policy_id_t *id,
							 kernel_ipsec_query_policy_t *data,
							 time_t *use_time);

	/**
	 * Remove a policy from the SPD.
	 *
	 * @param id			data identifying this policy
	 * @param data			data for this policy
	 * @return				SUCCESS if operation completed
	 */
	status_t (*del_policy)(kernel_interface_t *this,
						   kernel_ipsec_policy_id_t *id,
						   kernel_ipsec_manage_policy_t *data);

	/**
	 * Flush all policies from the SPD.
	 *
	 * @return				SUCCESS if operation completed
	 */
	status_t (*flush_policies)(kernel_interface_t *this);

	/**
	 * Get our outgoing source address for a destination.
	 *
	 * Does a route lookup to get the source address used to reach dest.
	 * The returned host is allocated and must be destroyed.
	 * An optional src address can be used to check if a route is available
	 * for the given source to dest.
	 *
	 * @param dest			target destination address
	 * @param src			source address to check, or NULL
	 * @return				outgoing source address, NULL if unreachable
	 */
	host_t* (*get_source_addr)(kernel_interface_t *this,
							   host_t *dest, host_t *src);

	/**
	 * Get the next hop for a destination.
	 *
	 * Does a route lookup to get the next hop used to reach dest.
	 * The returned host is allocated and must be destroyed.
	 * An optional src address can be used to check if a route is available
	 * for the given source to dest.
	 *
	 * @param dest			target destination address
	 * @param prefix		prefix length if dest is a subnet, -1 for auto
	 * @param src			source address to check, or NULL
	 * @param[out] iface	allocated name of the interface to reach dest, if
	 *						available (optional)
	 * @return				next hop address, NULL if unreachable
	 */
	host_t* (*get_nexthop)(kernel_interface_t *this, host_t *dest,
						   int prefix, host_t *src, char **iface);

	/**
	 * Get the interface name of a local address. Interfaces that are down or
	 * ignored by config are not considered.
	 *
	 * @param host			address to get interface name from
	 * @param name			allocated interface name (optional)
	 * @return				TRUE if interface found and usable
	 */
	bool (*get_interface)(kernel_interface_t *this, host_t *host, char **name);

	/**
	 * Creates an enumerator over all local addresses.
	 *
	 * This function blocks an internal cached address list until the
	 * enumerator gets destroyed.
	 * The hosts are read-only, do not modify of free.
	 *
	 * @param which			a combination of address types to enumerate
	 * @return				enumerator over host_t's
	 */
	enumerator_t *(*create_address_enumerator) (kernel_interface_t *this,
												kernel_address_type_t which);

	/**
	 * Creates an enumerator over all local subnets.
	 *
	 * Local subnets are subnets the host is directly connected to.
	 *
	 * The enumerator returns the network, subnet mask and interface.
	 *
	 * @return				enumerator over host_t*, uint8_t, char*
	 */
	enumerator_t *(*create_local_subnet_enumerator)(kernel_interface_t *this);

	/**
	 * Add a virtual IP to an interface.
	 *
	 * Virtual IPs are attached to an interface. If an IP is added multiple
	 * times, the IP is refcounted and not removed until del_ip() was called
	 * as many times as add_ip().
	 *
	 * @param virtual_ip	virtual ip address to assign
	 * @param prefix		prefix length to install IP with, -1 for auto
	 * @param iface			interface to install virtual IP on
	 * @return				SUCCESS if operation completed
	 */
	status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip, int prefix,
						char *iface);

	/**
	 * Remove a virtual IP from an interface.
	 *
	 * The kernel interface uses refcounting, see add_ip().
	 *
	 * @param virtual_ip	virtual ip address to remove
	 * @param prefix		prefix length of the IP to uninstall, -1 for auto
	 * @param wait			TRUE to wait until IP is gone
	 * @return				SUCCESS if operation completed
	 */
	status_t (*del_ip) (kernel_interface_t *this, host_t *virtual_ip,
						int prefix, bool wait);

	/**
	 * Add a route.
	 *
	 * @param dst_net		destination net
	 * @param prefixlen		destination net prefix length
	 * @param gateway		gateway for this route
	 * @param src_ip		source ip of the route
	 * @param if_name		name of the interface the route is bound to
	 * @param pass			TRUE if route is installed for passthrough policy
	 * @return				SUCCESS if operation completed
	 *						ALREADY_DONE if the route already exists
	 */
	status_t (*add_route) (kernel_interface_t *this, chunk_t dst_net,
						   uint8_t prefixlen, host_t *gateway, host_t *src_ip,
						   char *if_name, bool pass);

	/**
	 * Delete a route.
	 *
	 * @param dst_net		destination net
	 * @param prefixlen		destination net prefix length
	 * @param gateway		gateway for this route
	 * @param src_ip		source ip of the route
	 * @param if_name		name of the interface the route is bound to
	 * @param pass			TRUE if route was installed for passthrough policy
	 * @return				SUCCESS if operation completed
	 */
	status_t (*del_route) (kernel_interface_t *this, chunk_t dst_net,
						   uint8_t prefixlen, host_t *gateway, host_t *src_ip,
						   char *if_name, bool pass);

	/**
	 * Set up a bypass policy for a given socket.
	 *
	 * @param fd			socket file descriptor to setup policy for
	 * @param family		protocol family of the socket
	 * @return				TRUE if policy set up successfully
	 */
	bool (*bypass_socket)(kernel_interface_t *this, int fd, int family);

	/**
	 * Enable decapsulation of ESP-in-UDP packets for the given port/socket.
	 *
	 * @param fd			socket file descriptor
	 * @param family		protocol family of the socket
	 * @param port			the UDP port
	 * @return				TRUE if UDP decapsulation was enabled successfully
	 */
	bool (*enable_udp_decap)(kernel_interface_t *this, int fd, int family,
							 uint16_t port);


	/**
	 * manager methods
	 */

	/**
	 * Verifies that the given interface is usable and not excluded by
	 * configuration.
	 *
	 * @param iface			interface name
	 * @return				TRUE if usable
	 */
	bool (*is_interface_usable)(kernel_interface_t *this, const char *iface);

	/**
	 * Check if interfaces are excluded by config.
	 *
	 * @return				TRUE if no interfaces are excluded by config
	 */
	bool (*all_interfaces_usable)(kernel_interface_t *this);

	/**
	 * Tries to find an IP address of a local interface that is included in the
	 * supplied traffic selector.
	 *
	 * @param ts			traffic selector
	 * @param ip			returned IP address (has to be destroyed)
	 * @param vip			set to TRUE if returned address is a virtual IP
	 * @return				SUCCESS if address found
	 */
	status_t (*get_address_by_ts)(kernel_interface_t *this,
								  traffic_selector_t *ts, host_t **ip, bool *vip);

	/**
	 * Register an ipsec kernel interface constructor on the manager.
	 *
	 * @param create		constructor to register
	 * @return				TRUE if the ipsec kernel interface was registered
	 *						successfully, FALSE if an interface was already
	 *						registered or the registration failed
	 */
	bool (*add_ipsec_interface)(kernel_interface_t *this,
								kernel_ipsec_constructor_t create);

	/**
	 * Unregister an ipsec kernel interface constructor.
	 *
	 * @param create		constructor to unregister
	 * @return				TRUE if the ipsec kernel interface was unregistered
	 *						successfully, FALSE otherwise
	 */
	bool (*remove_ipsec_interface)(kernel_interface_t *this,
								   kernel_ipsec_constructor_t create);

	/**
	 * Register a network kernel interface constructor on the manager.
	 *
	 * @param create		constructor to register
	 * @return				TRUE if the kernel net interface was registered
	 *						successfully, FALSE if an interface was already
	 *						registered or the registration failed
	 */
	bool (*add_net_interface)(kernel_interface_t *this,
							  kernel_net_constructor_t create);

	/**
	 * Unregister a network kernel interface constructor.
	 *
	 * @param create		constructor to unregister
	 * @return				TRUE if the kernel net interface was unregistered
	 *						successfully, FALSE otherwise
	 */
	bool (*remove_net_interface)(kernel_interface_t *this,
								 kernel_net_constructor_t create);

	/**
	 * Add a listener to the kernel interface.
	 *
	 * @param listener		listener to add
	 */
	void (*add_listener)(kernel_interface_t *this,
						 kernel_listener_t *listener);

	/**
	 * Remove a listener from the kernel interface.
	 *
	 * @param listener		listener to remove
	 */
	void (*remove_listener)(kernel_interface_t *this,
							kernel_listener_t *listener);

	/**
	 * Raise an acquire event.
	 *
	 * @param reqid			reqid of the policy to acquire
	 * @param src_ts		source traffic selector
	 * @param dst_ts		destination traffic selector
	 */
	void (*acquire)(kernel_interface_t *this, uint32_t reqid,
					traffic_selector_t *src_ts, traffic_selector_t *dst_ts);

	/**
	 * Raise an expire event.
	 *
	 * @param protocol		protocol of the expired SA
	 * @param spi			spi of the expired SA
	 * @param dst			destination address of expired SA
	 * @param hard			TRUE if it is a hard expire, FALSE otherwise
	 */
	void (*expire)(kernel_interface_t *this, uint8_t protocol, uint32_t spi,
				   host_t *dst, bool hard);

	/**
	 * Raise a mapping event.
	 *
	 * @param protocol		protocol of affected SA
	 * @param spi			spi of the SA
	 * @param dst			original destination address of SA
	 * @param remote		new remote host
	 */
	void (*mapping)(kernel_interface_t *this, uint8_t protocol, uint32_t spi,
					host_t *dst, host_t *remote);

	/**
	 * Raise a migrate event.
	 *
	 * @param reqid			reqid of the policy
	 * @param src_ts		source traffic selector
	 * @param dst_ts		destination traffic selector
	 * @param direction		direction of the policy (in|out)
	 * @param local			local host address to be used in the IKE_SA
	 * @param remote		remote host address to be used in the IKE_SA
	 */
	void (*migrate)(kernel_interface_t *this, uint32_t reqid,
					traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
					policy_dir_t direction, host_t *local, host_t *remote);

	/**
	 * Raise a roam event.
	 *
	 * @param address		TRUE if address list, FALSE if routing changed
	 */
	void (*roam)(kernel_interface_t *this, bool address);

	/**
	 * Raise a tun event.
	 *
	 * @param tun			TUN device
	 * @param created		TRUE if created, FALSE if going to be destroyed
	 */
	void (*tun)(kernel_interface_t *this, tun_device_t *tun, bool created);

	/**
	 * Register a new algorithm with the kernel interface.
	 *
	 * @param alg_id			the IKE id of the algorithm
	 * @param type				the transform type of the algorithm
	 * @param kernel_id			the kernel id of the algorithm
	 * @param kernel_name		the kernel name of the algorithm
	 */
	void (*register_algorithm)(kernel_interface_t *this, uint16_t alg_id,
							   transform_type_t type, uint16_t kernel_id,
							   char *kernel_name);

	/**
	 * Return the kernel-specific id and/or name for an algorithms depending on
	 * the arguments specified.
	 *
	 * @param alg_id			the IKE id of the algorithm
	 * @param type				the transform type of the algorithm
	 * @param kernel_id			the kernel id of the algorithm (optional)
	 * @param kernel_name		the kernel name of the algorithm (optional)
	 * @return					TRUE if algorithm was found
	 */
	bool (*lookup_algorithm)(kernel_interface_t *this, uint16_t alg_id,
							 transform_type_t type, uint16_t *kernel_id,
							 char **kernel_name);

	/**
	 * Destroys a kernel_interface_t object.
	 */
	void (*destroy) (kernel_interface_t *this);
};

/**
 * Creates an object of type kernel_interface_t.
 */
kernel_interface_t *kernel_interface_create(void);

#endif /** KERNEL_INTERFACE_H_ @}*/
