text:
#ifndef __DESC_IPSEC_H__
#define __DESC_IPSEC_H__

#include "hw/rta.h"
#include "common.h"

/**
 * DOC: IPsec Shared Descriptor Constructors
 *
 * Shared descriptors for IPsec protocol.
 */

/* General IPSec ESP encap / decap PDB options */

/**
 * PDBOPTS_ESP_ESN - Extended sequence included
 */
#define PDBOPTS_ESP_ESN		0x10

/**
 * PDBOPTS_ESP_IPVSN - Process IPv6 header
 *
 * Valid only for IPsec legacy mode.
 */
#define PDBOPTS_ESP_IPVSN	0x02

/**
 * PDBOPTS_ESP_TUNNEL - Tunnel mode next-header byte
 *
 * Valid only for IPsec legacy mode.
 */
#define PDBOPTS_ESP_TUNNEL	0x01

/* IPSec ESP Encap PDB options */

/**
 * PDBOPTS_ESP_UPDATE_CSUM - Update ip header checksum
 *
 * Valid only for IPsec legacy mode.
 */
#define PDBOPTS_ESP_UPDATE_CSUM 0x80

/**
 * PDBOPTS_ESP_DIFFSERV - Copy TOS/TC from inner iphdr
 *
 * Valid only for IPsec legacy mode.
 */
#define PDBOPTS_ESP_DIFFSERV	0x40

/**
 * PDBOPTS_ESP_IVSRC - IV comes from internal random gen
 */
#define PDBOPTS_ESP_IVSRC	0x20

/**
 * PDBOPTS_ESP_IPHDRSRC - IP header comes from PDB
 *
 * Valid only for IPsec legacy mode.
 */
#define PDBOPTS_ESP_IPHDRSRC	0x08

/**
 * PDBOPTS_ESP_INCIPHDR - Prepend IP header to output frame
 *
 * Valid only for IPsec legacy mode.
 */
#define PDBOPTS_ESP_INCIPHDR	0x04

/**
 * PDBOPTS_ESP_OIHI_MASK - Mask for Outer IP Header Included
 *
 * Valid only for IPsec new mode.
 */
#define PDBOPTS_ESP_OIHI_MASK	0x0c

/**
 * PDBOPTS_ESP_OIHI_PDB_INL - Prepend IP header to output frame from PDB (where
 *                            it is inlined).
 *
 * Valid only for IPsec new mode.
 */
#define PDBOPTS_ESP_OIHI_PDB_INL 0x0c

/**
 * PDBOPTS_ESP_OIHI_PDB_REF - Prepend IP header to output frame from PDB
 *                            (referenced by pointer).
 *
 * Vlid only for IPsec new mode.
 */
#define PDBOPTS_ESP_OIHI_PDB_REF 0x08

/**
 * PDBOPTS_ESP_OIHI_IF - Prepend IP header to output frame from input frame
 *
 * Valid only for IPsec new mode.
 */
#define PDBOPTS_ESP_OIHI_IF	0x04

/**
 * PDBOPTS_ESP_NAT - Enable RFC 3948 UDP-encapsulated-ESP
 *
 * Valid only for IPsec new mode.
 */
#define PDBOPTS_ESP_NAT		0x02

/**
 * PDBOPTS_ESP_NUC - Enable NAT UDP Checksum
 *
 * Valid only for IPsec new mode.
 */
#define PDBOPTS_ESP_NUC		0x01

/* IPSec ESP Decap PDB options */

/**
 * PDBOPTS_ESP_ARS_MASK - antireplay window mask
 */
#define PDBOPTS_ESP_ARS_MASK	0xc0

/**
 * PDBOPTS_ESP_ARSNONE - No antireplay window
 */
#define PDBOPTS_ESP_ARSNONE	0x00

/**
 * PDBOPTS_ESP_ARS64 - 64-entry antireplay window
 */
#define PDBOPTS_ESP_ARS64	0xc0

/**
 * PDBOPTS_ESP_ARS128 - 128-entry antireplay window
 *
 * Valid only for IPsec new mode.
 */
#define PDBOPTS_ESP_ARS128	0x80

/**
 * PDBOPTS_ESP_ARS32 - 32-entry antireplay window
 */
#define PDBOPTS_ESP_ARS32	0x40

/**
 * PDBOPTS_ESP_VERIFY_CSUM - Validate ip header checksum
 *
 * Valid only for IPsec legacy mode.
 */
#define PDBOPTS_ESP_VERIFY_CSUM 0x20

/**
 * PDBOPTS_ESP_TECN - Implement RRFC6040 ECN tunneling from outer header to
 *                    inner header.
 *
 * Valid only for IPsec new mode.
 */
#define PDBOPTS_ESP_TECN	0x20

/**
 * PDBOPTS_ESP_OUTFMT - Output only decapsulation
 *
 * Valid only for IPsec legacy mode.
 */
#define PDBOPTS_ESP_OUTFMT	0x08

/**
 * PDBOPTS_ESP_AOFL - Adjust out frame len
 *
 * Valid only for IPsec legacy mode and for SEC >= 5.3.
 */
#define PDBOPTS_ESP_AOFL	0x04

/**
 * PDBOPTS_ESP_ETU - EtherType Update
 *
 * Add corresponding ethertype (0x0800 for IPv4, 0x86dd for IPv6) in the output
 * frame.
 * Valid only for IPsec new mode.
 */
#define PDBOPTS_ESP_ETU		0x01

#define PDBHMO_ESP_DECAP_SHIFT		28
#define PDBHMO_ESP_ENCAP_SHIFT		28
#define PDBNH_ESP_ENCAP_SHIFT		16
#define PDBNH_ESP_ENCAP_MASK		(0xff << PDBNH_ESP_ENCAP_SHIFT)
#define PDBHDRLEN_ESP_DECAP_SHIFT	16
#define PDBHDRLEN_MASK			(0x0fff << PDBHDRLEN_ESP_DECAP_SHIFT)
#define PDB_NH_OFFSET_SHIFT		8
#define PDB_NH_OFFSET_MASK		(0xff << PDB_NH_OFFSET_SHIFT)

/**
 * PDBHMO_ESP_DECAP_DTTL - IPsec ESP decrement TTL (IPv4) / Hop limit (IPv6)
 *                         HMO option.
 */
#define PDBHMO_ESP_DECAP_DTTL	(0x02 << PDBHMO_ESP_DECAP_SHIFT)

/**
 * PDBHMO_ESP_ENCAP_DTTL - IPsec ESP increment TTL (IPv4) / Hop limit (IPv6)
 *                         HMO option.
 */
#define PDBHMO_ESP_ENCAP_DTTL	(0x02 << PDBHMO_ESP_ENCAP_SHIFT)

/**
 * PDBHMO_ESP_DIFFSERV - (Decap) DiffServ Copy - Copy the IPv4 TOS or IPv6
 *                       Traffic Class byte from the outer IP header to the
 *                       inner IP header.
 */
#define PDBHMO_ESP_DIFFSERV	(0x01 << PDBHMO_ESP_DECAP_SHIFT)

/**
 * PDBHMO_ESP_SNR - (Encap) - Sequence Number Rollover control
 *
 * Configures behaviour in case of SN / ESN rollover:
 * error if SNR = 1, rollover allowed if SNR = 0.
 * Valid only for IPsec new mode.
 */
#define PDBHMO_ESP_SNR		(0x01 << PDBHMO_ESP_ENCAP_SHIFT)

/**
 * PDBHMO_ESP_DFBIT - (Encap) Copy DF bit - if an IPv4 tunnel mode outer IP
 *                    header is coming from the PDB, copy the DF bit from the
 *                    inner IP header to the outer IP header.
 */
#define PDBHMO_ESP_DFBIT	(0x04 << PDBHMO_ESP_ENCAP_SHIFT)

/**
 * PDBHMO_ESP_DFV - (Decap) - DF bit value
 *
 * If ODF = 1, DF bit in output frame is replaced by DFV.
 * Valid only from SEC Era 5 onwards.
 */
#define PDBHMO_ESP_DFV		(0x04 << PDBHMO_ESP_DECAP_SHIFT)

/**
 * PDBHMO_ESP_ODF - (Decap) Override DF bit in IPv4 header of decapsulated
 *                  output frame.
 *
 * If ODF = 1, DF is replaced with the value of DFV bit.
 * Valid only from SEC Era 5 onwards.
 */
#define PDBHMO_ESP_ODF		(0x08 << PDBHMO_ESP_DECAP_SHIFT)

/**
 * struct ipsec_encap_cbc - PDB part for IPsec CBC encapsulation
 * @iv: 16-byte array initialization vector
 */
struct ipsec_encap_cbc {
	uint8_t iv[16];
};

/**
 * struct ipsec_encap_ctr - PDB part for IPsec CTR encapsulation
 * @ctr_nonce: 4-byte array nonce
 * @ctr_initial: initial count constant
 * @iv: initialization vector
 */
struct ipsec_encap_ctr {
	uint8_t ctr_nonce[4];
	uint32_t ctr_initial;
	uint64_t iv;
};

/**
 * struct ipsec_encap_ccm - PDB part for IPsec CCM encapsulation
 * @salt: 3-byte array salt (lower 24 bits)
 * @ccm_opt: CCM algorithm options - MSB-LSB description:
 *  b0_flags (8b) - CCM B0; use 0x5B for 8-byte ICV, 0x6B for 12-byte ICV,
 *    0x7B for 16-byte ICV (cf. RFC4309, RFC3610)
 *  ctr_flags (8b) - counter flags; constant equal to 0x3
 *  ctr_initial (16b) - initial count constant
 * @iv: initialization vector
 */
struct ipsec_encap_ccm {
	uint8_t salt[4];
	uint32_t ccm_opt;
	uint64_t iv;
};

/**
 * struct ipsec_encap_gcm - PDB part for IPsec GCM encapsulation
 * @salt: 3-byte array salt (lower 24 bits)
 * @rsvd: reserved, do not use
 * @iv: initialization vector
 */
struct ipsec_encap_gcm {
	uint8_t salt[4];
	uint32_t rsvd;
	uint64_t iv;
};

/**
 * struct ipsec_encap_pdb - PDB for IPsec encapsulation
 * @options: MSB-LSB description (both for legacy and new modes)
 *  hmo (header manipulation options) - 4b
 *  reserved - 4b
 *  next header (legacy) / reserved (new) - 8b
 *  next header offset (legacy) / AOIPHO (actual outer IP header offset) - 8b
 *  option flags (depend on selected algorithm) - 8b
 * @seq_num_ext_hi: (optional) IPsec Extended Sequence Number (ESN)
 * @seq_num: IPsec sequence number
 * @spi: IPsec SPI (Security Parameters Index)
 * @ip_hdr_len: optional IP Header length (in bytes)
 *  reserved - 16b
 *  Opt. IP Hdr Len - 16b
 * @ip_hdr: optional IP Header content (only for IPsec legacy mode)
 */
struct ipsec_encap_pdb {
	uint32_t options;
	uint32_t seq_num_ext_hi;
	uint32_t seq_num;
	union {
		struct ipsec_encap_cbc cbc;
		struct ipsec_encap_ctr ctr;
		struct ipsec_encap_ccm ccm;
		struct ipsec_encap_gcm gcm;
	};
	uint32_t spi;
	uint32_t ip_hdr_len;
	uint8_t ip_hdr[0];
};

static inline unsigned int
__rta_copy_ipsec_encap_pdb(struct program *program,
			   struct ipsec_encap_pdb *pdb,
			   uint32_t algtype)
{
	unsigned int start_pc = program->current_pc;

	__rta_out32(program, pdb->options);
	__rta_out32(program, pdb->seq_num_ext_hi);
	__rta_out32(program, pdb->seq_num);

	switch (algtype & OP_PCL_IPSEC_CIPHER_MASK) {
	case OP_PCL_IPSEC_DES_IV64:
	case OP_PCL_IPSEC_DES:
	case OP_PCL_IPSEC_3DES:
	case OP_PCL_IPSEC_AES_CBC:
	case OP_PCL_IPSEC_NULL:
		rta_copy_data(program, pdb->cbc.iv, sizeof(pdb->cbc.iv));
		break;

	case OP_PCL_IPSEC_AES_CTR:
		rta_copy_data(program, pdb->ctr.ctr_nonce,
			      sizeof(pdb->ctr.ctr_nonce));
		__rta_out32(program, pdb->ctr.ctr_initial);
		__rta_out64(program, true, pdb->ctr.iv);
		break;

	case OP_PCL_IPSEC_AES_CCM8:
	case OP_PCL_IPSEC_AES_CCM12:
	case OP_PCL_IPSEC_AES_CCM16:
		rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
		__rta_out32(program, pdb->ccm.ccm_opt);
		__rta_out64(program, true, pdb->ccm.iv);
		break;

	case OP_PCL_IPSEC_AES_GCM8:
	case OP_PCL_IPSEC_AES_GCM12:
	case OP_PCL_IPSEC_AES_GCM16:
	case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
		rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
		__rta_out32(program, pdb->gcm.rsvd);
		__rta_out64(program, true, pdb->gcm.iv);
		break;
	}

	__rta_out32(program, pdb->spi);
	__rta_out32(program, pdb->ip_hdr_len);

	return start_pc;
}

/**
 * struct ipsec_decap_cbc - PDB part for IPsec CBC decapsulation
 * @rsvd: reserved, do not use
 */
struct ipsec_decap_cbc {
	uint32_t rsvd[2];
};

/**
 * struct ipsec_decap_ctr - PDB part for IPsec CTR decapsulation
 * @ctr_nonce: 4-byte array nonce
 * @ctr_initial: initial count constant
 */
struct ipsec_decap_ctr {
	uint8_t ctr_nonce[4];
	uint32_t ctr_initial;
};

/**
 * struct ipsec_decap_ccm - PDB part for IPsec CCM decapsulation
 * @salt: 3-byte salt (lower 24 bits)
 * @ccm_opt: CCM algorithm options - MSB-LSB description:
 *  b0_flags (8b) - CCM B0; use 0x5B for 8-byte ICV, 0x6B for 12-byte ICV,
 *    0x7B for 16-byte ICV (cf. RFC4309, RFC3610)
 *  ctr_flags (8b) - counter flags; constant equal to 0x3
 *  ctr_initial (16b) - initial count constant
 */
struct ipsec_decap_ccm {
	uint8_t salt[4];
	uint32_t ccm_opt;
};

/**
 * struct ipsec_decap_gcm - PDB part for IPsec GCN decapsulation
 * @salt: 4-byte salt
 * @rsvd: reserved, do not use
 */
struct ipsec_decap_gcm {
	uint8_t salt[4];
	uint32_t rsvd;
};

/**
 * struct ipsec_decap_pdb - PDB for IPsec decapsulation
 * @options: MSB-LSB description (both for legacy and new modes)
 *  hmo (header manipulation options) - 4b
 *  IP header length - 12b
 *  next header offset (legacy) / AOIPHO (actual outer IP header offset) - 8b
 *  option flags (depend on selected algorithm) - 8b
 * @seq_num_ext_hi: (optional) IPsec Extended Sequence Number (ESN)
 * @seq_num: IPsec sequence number
 * @anti_replay: Anti-replay window; size depends on ARS (option flags);
 *  format must be Big Endian, irrespective of platform
 */
struct ipsec_decap_pdb {
	uint32_t options;
	union {
		struct ipsec_decap_cbc cbc;
		struct ipsec_decap_ctr ctr;
		struct ipsec_decap_ccm ccm;
		struct ipsec_decap_gcm gcm;
	};
	uint32_t seq_num_ext_hi;
	uint32_t seq_num;
	uint32_t anti_replay[4];
};

static inline unsigned int
__rta_copy_ipsec_decap_pdb(struct program *program,
			   struct ipsec_decap_pdb *pdb,
			   uint32_t algtype)
{
	unsigned int start_pc = program->current_pc;
	unsigned int i, ars;

	__rta_out32(program, pdb->options);

	switch (algtype & OP_PCL_IPSEC_CIPHER_MASK) {
	case OP_PCL_IPSEC_DES_IV64:
	case OP_PCL_IPSEC_DES:
	case OP_PCL_IPSEC_3DES:
	case OP_PCL_IPSEC_AES_CBC:
	case OP_PCL_IPSEC_NULL:
		__rta_out32(program, pdb->cbc.rsvd[0]);
		__rta_out32(program, pdb->cbc.rsvd[1]);
		break;

	case OP_PCL_IPSEC_AES_CTR:
		rta_copy_data(program, pdb->ctr.ctr_nonce,
			      sizeof(pdb->ctr.ctr_nonce));
		__rta_out32(program, pdb->ctr.ctr_initial);
		break;

	case OP_PCL_IPSEC_AES_CCM8:
	case OP_PCL_IPSEC_AES_CCM12:
	case OP_PCL_IPSEC_AES_CCM16:
		rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
		__rta_out32(program, pdb->ccm.ccm_opt);
		break;

	case OP_PCL_IPSEC_AES_GCM8:
	case OP_PCL_IPSEC_AES_GCM12:
	case OP_PCL_IPSEC_AES_GCM16:
	case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
		rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
		__rta_out32(program, pdb->gcm.rsvd);
		break;
	}

	__rta_out32(program, pdb->seq_num_ext_hi);
	__rta_out32(program, pdb->seq_num);

	switch (pdb->options & PDBOPTS_ESP_ARS_MASK) {
	case PDBOPTS_ESP_ARS128:
		ars = 4;
		break;
	case PDBOPTS_ESP_ARS64:
		ars = 2;
		break;
	case PDBOPTS_ESP_ARS32:
		ars = 1;
		break;
	case PDBOPTS_ESP_ARSNONE:
	default:
		ars = 0;
		break;
	}

	for (i = 0; i < ars; i++)
		__rta_out_be32(program, pdb->anti_replay[i]);

	return start_pc;
}

/**
 * enum ipsec_icv_size - Type selectors for icv size in IPsec protocol
 * @IPSEC_ICV_MD5_SIZE: full-length MD5 ICV
 * @IPSEC_ICV_MD5_TRUNC_SIZE: truncated MD5 ICV
 */
enum ipsec_icv_size {
	IPSEC_ICV_MD5_SIZE = 16,
	IPSEC_ICV_MD5_TRUNC_SIZE = 12
};

/*
 * IPSec ESP Datapath Protocol Override Register (DPOVRD)
 */

#define IPSEC_DECO_DPOVRD_USE		0x80

struct ipsec_deco_dpovrd {
	uint8_t ovrd_ecn;
	uint8_t ip_hdr_len;
	uint8_t nh_offset;
	union {
		uint8_t next_header;	/* next header if encap */
		uint8_t rsvd;		/* reserved if decap */
	};
};

struct ipsec_new_encap_deco_dpovrd {
#define IPSEC_NEW_ENCAP_DECO_DPOVRD_USE	0x8000
	uint16_t ovrd_ip_hdr_len;	/* OVRD + outer IP header material
					 * length
					 */
#define IPSEC_NEW_ENCAP_OIMIF		0x80
	uint8_t oimif_aoipho;		/* OIMIF + actual outer IP header
					 * offset
					 */
	uint8_t rsvd;
};

struct ipsec_new_decap_deco_dpovrd {
	uint8_t ovrd;
	uint8_t aoipho_hi;		/* upper nibble of actual outer IP
					 * header
					 */
	uint16_t aoipho_lo_ip_hdr_len;	/* lower nibble of actual outer IP
					 * header + outer IP header material
					 */
};

static inline void
__gen_auth_key(struct program *program, struct alginfo *authdata)
{
	uint32_t dkp_protid;

	switch (authdata->algtype & OP_PCL_IPSEC_AUTH_MASK) {
	case OP_PCL_IPSEC_HMAC_MD5_96:
	case OP_PCL_IPSEC_HMAC_MD5_128:
		dkp_protid = OP_PCLID_DKP_MD5;
		break;
	case OP_PCL_IPSEC_HMAC_SHA1_96:
	case OP_PCL_IPSEC_HMAC_SHA1_160:
		dkp_protid = OP_PCLID_DKP_SHA1;
		break;
	case OP_PCL_IPSEC_HMAC_SHA2_256_128:
		dkp_protid = OP_PCLID_DKP_SHA256;
		break;
	case OP_PCL_IPSEC_HMAC_SHA2_384_192:
		dkp_protid = OP_PCLID_DKP_SHA384;
		break;
	case OP_PCL_IPSEC_HMAC_SHA2_512_256:
		dkp_protid = OP_PCLID_DKP_SHA512;
		break;
	default:
		KEY(program, KEY2, authdata->key_enc_flags, authdata->key,
		    authdata->keylen, INLINE_KEY(authdata));
		return;
	}

	if (authdata->key_type == RTA_DATA_PTR)
		DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_PTR,
			     OP_PCL_DKP_DST_PTR, (uint16_t)authdata->keylen,
			     authdata->key, authdata->key_type);
	else
		DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_IMM,
			     OP_PCL_DKP_DST_IMM, (uint16_t)authdata->keylen,
			     authdata->key, authdata->key_type);
}

/**
 * cnstr_shdsc_ipsec_encap - IPSec ESP encapsulation protocol-level shared
 *                           descriptor.
 * @descbuf: pointer to buffer used for descriptor construction
 * @ps: if 36/40bit addressing is desired, this parameter must be true
 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
 * @pdb: pointer to the PDB to be used with this descriptor
 *       This structure will be copied inline to the descriptor under
 *       construction. No error checking will be made. Refer to the
 *       block guide for a details of the encapsulation PDB.
 * @cipherdata: pointer to block cipher transform definitions
 *              Valid algorithm values - one of OP_PCL_IPSEC_*
 * @authdata: pointer to authentication transform definitions
 *            If an authentication key is required by the protocol:
 *            -For SEC Eras 1-5, an MDHA split key must be provided;
 *            Note that the size of the split key itself must be specified.
 *            -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
 *            Key Protocol) will be used to compute MDHA on the fly in HW.
 *            Valid algorithm values - one of OP_PCL_IPSEC_*
 *
 * Return: size of descriptor written in words or negative number on error
 */
static inline int
cnstr_shdsc_ipsec_encap(uint32_t *descbuf, bool ps, bool swap,
			struct ipsec_encap_pdb *pdb,
			struct alginfo *cipherdata,
			struct alginfo *authdata)
{
	struct program prg;
	struct program *p = &prg;

	LABEL(keyjmp);
	REFERENCE(pkeyjmp);
	LABEL(hdr);
	REFERENCE(phdr);

	PROGRAM_CNTXT_INIT(p, descbuf, 0);
	if (swap)
		PROGRAM_SET_BSWAP(p);
	if (ps)
		PROGRAM_SET_36BIT_ADDR(p);
	phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
	COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
	SET_LABEL(p, hdr);
	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
	if (authdata->keylen) {
		if (rta_sec_era < RTA_SEC_ERA_6)
			KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
			    authdata->key, authdata->keylen,
			    INLINE_KEY(authdata));
		else
			__gen_auth_key(p, authdata);
	}
	if (cipherdata->keylen)
		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
		    cipherdata->keylen, INLINE_KEY(cipherdata));
	SET_LABEL(p, keyjmp);
	PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
		 OP_PCLID_IPSEC,
		 (uint16_t)(cipherdata->algtype | authdata->algtype));
	PATCH_JUMP(p, pkeyjmp, keyjmp);
	PATCH_HDR(p, phdr, hdr);
	return PROGRAM_FINALIZE(p);
}

/**
 * cnstr_shdsc_ipsec_decap - IPSec ESP decapsulation protocol-level shared
 *                           descriptor.
 * @descbuf: pointer to buffer used for descriptor construction
 * @ps: if 36/40bit addressing is desired, this parameter must be true
 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
 * @pdb: pointer to the PDB to be used with this descriptor
 *       This structure will be copied inline to the descriptor under
 *       construction. No error checking will be made. Refer to the
 *       block guide for details about the decapsulation PDB.
 * @cipherdata: pointer to block cipher transform definitions.
 *              Valid algorithm values - one of OP_PCL_IPSEC_*
 * @authdata: pointer to authentication transform definitions
 *            If an authentication key is required by the protocol:
 *            -For SEC Eras 1-5, an MDHA split key must be provided;
 *            Note that the size of the split key itself must be specified.
 *            -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
 *            Key Protocol) will be used to compute MDHA on the fly in HW.
 *            Valid algorithm values - one of OP_PCL_IPSEC_*
 *
 * Return: size of descriptor written in words or negative number on error
 */
static inline int
cnstr_shdsc_ipsec_decap(uint32_t *descbuf, bool ps, bool swap,
			struct ipsec_decap_pdb *pdb,
			struct alginfo *cipherdata,
			struct alginfo *authdata)
{
	struct program prg;
	struct program *p = &prg;

	LABEL(keyjmp);
	REFERENCE(pkeyjmp);
	LABEL(hdr);
	REFERENCE(phdr);

	PROGRAM_CNTXT_INIT(p, descbuf, 0);
	if (swap)
		PROGRAM_SET_BSWAP(p);
	if (ps)
		PROGRAM_SET_36BIT_ADDR(p);
	phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
	SET_LABEL(p, hdr);
	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
	if (authdata->keylen) {
		if (rta_sec_era < RTA_SEC_ERA_6)
			KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
			    authdata->key, authdata->keylen,
			    INLINE_KEY(authdata));
		else
			__gen_auth_key(p, authdata);
	}
	if (cipherdata->keylen)
		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
		    cipherdata->keylen, INLINE_KEY(cipherdata));
	SET_LABEL(p, keyjmp);
	PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
		 OP_PCLID_IPSEC,
		 (uint16_t)(cipherdata->algtype | authdata->algtype));
	PATCH_JUMP(p, pkeyjmp, keyjmp);
	PATCH_HDR(p, phdr, hdr);
	return PROGRAM_FINALIZE(p);
}

/**
 * cnstr_shdsc_ipsec_encap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
 *     AES-XCBC-MAC-96 ESP encapsulation shared descriptor.
 * @descbuf: pointer to buffer used for descriptor construction
 * @pdb: pointer to the PDB to be used with this descriptor
 *       This structure will be copied inline to the descriptor under
 *       construction. No error checking will be made. Refer to the
 *       block guide for a details of the encapsulation PDB.
 * @cipherdata: pointer to block cipher transform definitions
 *              Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
 * @authdata: pointer to authentication transform definitions
 *            Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
 *
 * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
 * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
 * Outer/Transport IP Header is present in the encapsulation output packet.
 * The descriptor performs DES-CBC/3DES-CBC & HMAC-MD5-96 and then rereads
 * the input packet to do the AES-XCBC-MAC-96 calculation and to overwrite
 * the MD5 ICV.
 * The descriptor uses all the benefits of the built-in protocol by computing
 * the IPsec ESP with a hardware supported algorithms combination
 * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
 * was chosen in order to speed up the computational time for this intermediate
 * step.
 * Warning: The user must allocate at least 32 bytes for the authentication key
 * (in order to use it also with HMAC-MD5-96),even when using a shorter key
 * for the AES-XCBC-MAC-96.
 *
 * Return: size of descriptor written in words or negative number on error
 */
static inline int
cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
				     struct ipsec_encap_pdb *pdb,
				     struct alginfo *cipherdata,
				     struct alginfo *authdata)
{
	struct program prg;
	struct program *p = &prg;

	LABEL(hdr);
	LABEL(shd_ptr);
	LABEL(keyjump);
	LABEL(outptr);
	LABEL(swapped_seqin_fields);
	LABEL(swapped_seqin_ptr);
	REFERENCE(phdr);
	REFERENCE(pkeyjump);
	REFERENCE(move_outlen);
	REFERENCE(move_seqout_ptr);
	REFERENCE(swapped_seqin_ptr_jump);
	REFERENCE(write_swapped_seqin_ptr);

	PROGRAM_CNTXT_INIT(p, descbuf, 0);
	phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
	COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
	SET_LABEL(p, hdr);
	pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
	/*
	 * Hard-coded KEY arguments. The descriptor uses all the benefits of
	 * the built-in protocol by computing the IPsec ESP with a hardware
	 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
	 * The HMAC-MD5 authentication algorithm was chosen with
	 * the keys options from below in order to speed up the computational
	 * time for this intermediate step.
	 * Warning: The user must allocate at least 32 bytes for
	 * the authentication key (in order to use it also with HMAC-MD5-96),
	 * even when using a shorter key for the AES-XCBC-MAC-96.
	 */
	KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
	SET_LABEL(p, keyjump);
	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
	     IMMED);
	KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
	    cipherdata->keylen, INLINE_KEY(cipherdata));
	PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, OP_PCLID_IPSEC,
		 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
	/* Swap SEQINPTR to SEQOUTPTR. */
	move_seqout_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
	MATHB(p, MATH1, AND, ~(CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR), MATH1,
	      8, IFB | IMMED2);
/*
 * TODO: RTA currently doesn't support creating a LOAD command
 * with another command as IMM.
 * To be changed when proper support is added in RTA.
 */
	LOAD(p, 0xa00000e5, MATH3, 4, 4, IMMED);
	MATHB(p, MATH3, SHLD, MATH3, MATH3,  8, 0);
	write_swapped_seqin_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
				       IMMED);
	swapped_seqin_ptr_jump = JUMP(p, swapped_seqin_ptr, LOCAL_JUMP,
				      ALL_TRUE, 0);
	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
	     0);
	SEQOUTPTR(p, 0, 65535, RTO);
	move_outlen = MOVE(p, DESCBUF, 0, MATH0, 4, 8, WAITCOMP | IMMED);
	MATHB(p, MATH0, SUB,
	      (uint64_t)(pdb->ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE),
	      VSEQINSZ, 4, IMMED2);
	MATHB(p, MATH0, SUB, IPSEC_ICV_MD5_TRUNC_SIZE, VSEQOUTSZ, 4, IMMED2);
	KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
	    0);
	ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
		      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
	SEQFIFOLOAD(p, SKIP, pdb->ip_hdr_len, 0);
	SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1 | LAST1);
	SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
	SEQSTORE(p, CONTEXT1, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
/*
 * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
 * To be changed when proper support is added in RTA.
 */
	/* Label the Shared Descriptor Pointer */
	SET_LABEL(p, shd_ptr);
	shd_ptr += 1;
	/* Label the Output Pointer */
	SET_LABEL(p, outptr);
	outptr += 3;
	/* Label the first word after JD */
	SET_LABEL(p, swapped_seqin_fields);
	swapped_seqin_fields += 8;
	/* Label the second word after JD */
	SET_LABEL(p, swapped_seqin_ptr);
	swapped_seqin_ptr += 9;

	PATCH_HDR(p, phdr, hdr);
	PATCH_JUMP(p, pkeyjump, keyjump);
	PATCH_JUMP(p, swapped_seqin_ptr_jump, swapped_seqin_ptr);
	PATCH_MOVE(p, move_outlen, outptr);
	PATCH_MOVE(p, move_seqout_ptr, shd_ptr);
	PATCH_MOVE(p, write_swapped_seqin_ptr, swapped_seqin_fields);
	return PROGRAM_FINALIZE(p);
}

/**
 * cnstr_shdsc_ipsec_decap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
 *     AES-XCBC-MAC-96 ESP decapsulation shared descriptor.
 * @descbuf: pointer to buffer used for descriptor construction
 * @pdb: pointer to the PDB to be used with this descriptor
 *       This structure will be copied inline to the descriptor under
 *       construction. No error checking will be made. Refer to the
 *       block guide for a details of the encapsulation PDB.
 * @cipherdata: pointer to block cipher transform definitions
 *              Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
 * @authdata: pointer to authentication transform definitions
 *            Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
 *
 * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
 * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
 * Outer/Transport IP Header is present in the decapsulation input packet.
 * The descriptor computes the AES-XCBC-MAC-96 to check if the received ICV
 * is correct, rereads the input packet to compute the MD5 ICV, overwrites
 * the XCBC ICV, and then sends the modified input packet to the
 * DES-CBC/3DES-CBC & HMAC-MD5-96 IPsec.
 * The descriptor uses all the benefits of the built-in protocol by computing
 * the IPsec ESP with a hardware supported algorithms combination
 * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
 * was chosen in order to speed up the computational time for this intermediate
 * step.
 * Warning: The user must allocate at least 32 bytes for the authentication key
 * (in order to use it also with HMAC-MD5-96),even when using a shorter key
 * for the AES-XCBC-MAC-96.
 *
 * Return: size of descriptor written in words or negative number on error
 */
static inline int
cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t *descbuf,
				     struct ipsec_decap_pdb *pdb,
				     struct alginfo *cipherdata,
				     struct alginfo *authdata)
{
	struct program prg;
	struct program *p = &prg;
	uint32_t ip_hdr_len = (pdb->options & PDBHDRLEN_MASK) >>
				PDBHDRLEN_ESP_DECAP_SHIFT;

	LABEL(hdr);
	LABEL(jump_cmd);
	LABEL(keyjump);
	LABEL(outlen);
	LABEL(seqin_ptr);
	LABEL(seqout_ptr);
	LABEL(swapped_seqout_fields);
	LABEL(swapped_seqout_ptr);
	REFERENCE(seqout_ptr_jump);
	REFERENCE(phdr);
	REFERENCE(pkeyjump);
	REFERENCE(move_jump);
	REFERENCE(move_jump_back);
	REFERENCE(move_seqin_ptr);
	REFERENCE(swapped_seqout_ptr_jump);
	REFERENCE(write_swapped_seqout_ptr);

	PROGRAM_CNTXT_INIT(p, descbuf, 0);
	phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
	SET_LABEL(p, hdr);
	pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
	/*
	 * Hard-coded KEY arguments. The descriptor uses all the benefits of
	 * the built-in protocol by computing the IPsec ESP with a hardware
	 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
	 * The HMAC-MD5 authentication algorithm was chosen with
	 * the keys options from bellow in order to speed up the computational
	 * time for this intermediate step.
	 * Warning: The user must allocate at least 32 bytes for
	 * the authentication key (in order to use it also with HMAC-MD5-96),
	 * even when using a shorter key for the AES-XCBC-MAC-96.
	 */
	KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
	SET_LABEL(p, keyjump);
	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
	     0);
	KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
	    INLINE_KEY(authdata));
	MATHB(p, SEQINSZ, SUB,
	      (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), MATH0, 4,
	      IMMED2);
	MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
	ALG_OPERATION(p, OP_ALG_ALGSEL_MD5, OP_ALG_AAI_HMAC_PRECOMP,
		      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
	ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
		      OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
	SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
	SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1);
	SEQFIFOLOAD(p, ICV1, IPSEC_ICV_MD5_TRUNC_SIZE, FLUSH1 | LAST1);
	/* Swap SEQOUTPTR to SEQINPTR. */
	move_seqin_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
	MATHB(p, MATH1, OR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 8,
	      IFB | IMMED2);
/*
 * TODO: RTA currently doesn't support creating a LOAD command
 * with another command as IMM.
 * To be changed when proper support is added in RTA.
 */
	LOAD(p, 0xA00000e1, MATH3, 4, 4, IMMED);
	MATHB(p, MATH3, SHLD, MATH3, MATH3,  8, 0);
	write_swapped_seqout_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
					IMMED);
	swapped_seqout_ptr_jump = JUMP(p, swapped_seqout_ptr, LOCAL_JUMP,
				       ALL_TRUE, 0);
/*
 * TODO: To be changed when proper support is added in RTA (can't load
 * a command that is also written by RTA).
 * Change when proper RTA support is added.
 */
	SET_LABEL(p, jump_cmd);
	WORD(p, 0xA00000f3);
	SEQINPTR(p, 0, 65535, RTO);
	MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
	MATHB(p, MATH0, ADD, ip_hdr_len, VSEQOUTSZ, 4, IMMED2);
	move_jump = MOVE(p, DESCBUF, 0, OFIFO, 0, 8, WAITCOMP | IMMED);
	move_jump_back = MOVE(p, OFIFO, 0, DESCBUF, 0, 8, IMMED);
	SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
	SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
	SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
	SEQSTORE(p, CONTEXT2, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
	seqout_ptr_jump = JUMP(p, seqout_ptr, LOCAL_JUMP, ALL_TRUE, CALM);

	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_CLR_C2MODE |
	     CLRW_CLR_C2DATAS | CLRW_CLR_C2CTX | CLRW_RESET_CLS1_CHA, CLRW, 0,
	     4, 0);
	SEQINPTR(p, 0, 65535, RTO);
	MATHB(p, MATH0, ADD,
	      (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), SEQINSZ, 4,
	      IMMED2);
	KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
	    cipherdata->keylen, INLINE_KEY(cipherdata));
	PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, OP_PCLID_IPSEC,
		 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
/*
 * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
 * To be changed when proper support is added in RTA.
 */
	/* Label the SEQ OUT PTR */
	SET_LABEL(p, seqout_ptr);
	seqout_ptr += 2;
	/* Label the Output Length */
	SET_LABEL(p, outlen);
	outlen += 4;
	/* Label the SEQ IN PTR */
	SET_LABEL(p, seqin_ptr);
	seqin_ptr += 5;
	/* Label the first word after JD */
	SET_LABEL(p, swapped_seqout_fields);
	swapped_seqout_fields += 8;
	/* Label the second word after JD */
	SET_LABEL(p, swapped_seqout_ptr);
	swapped_seqout_ptr += 9;

	PATCH_HDR(p, phdr, hdr);
	PATCH_JUMP(p, pkeyjump, keyjump);
	PATCH_JUMP(p, seqout_ptr_jump, seqout_ptr);
	PATCH_JUMP(p, swapped_seqout_ptr_jump, swapped_seqout_ptr);
	PATCH_MOVE(p, move_jump, jump_cmd);
	PATCH_MOVE(p, move_jump_back, seqin_ptr);
	PATCH_MOVE(p, move_seqin_ptr, outlen);
	PATCH_MOVE(p, write_swapped_seqout_ptr, swapped_seqout_fields);
	return PROGRAM_FINALIZE(p);
}

/**
 * IPSEC_NEW_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor length
 *
 * Accounts only for the "base" commands and is intended to be used by upper
 * layers to determine whether Outer IP Header and/or keys can be inlined or
 * not. To be used as first parameter of rta_inline_query().
 */
#define IPSEC_NEW_ENC_BASE_DESC_LEN	(5 * CAAM_CMD_SZ + \
					 sizeof(struct ipsec_encap_pdb))

/**
 * IPSEC_NEW_NULL_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor
 *                                    length for the case of
 *                                    NULL encryption / authentication
 *
 * Accounts only for the "base" commands and is intended to be used by upper
 * layers to determine whether Outer IP Header and/or key can be inlined or
 * not. To be used as first parameter of rta_inline_query().
 */
#define IPSEC_NEW_NULL_ENC_BASE_DESC_LEN	(4 * CAAM_CMD_SZ + \
						 sizeof(struct ipsec_encap_pdb))

/**
 * cnstr_shdsc_ipsec_new_encap -  IPSec new mode ESP encapsulation
 *     protocol-level shared descriptor.
 * @descbuf: pointer to buffer used for descriptor construction
 * @ps: if 36/40bit addressing is desired, this parameter must be true
 * @swap: must be true when core endianness doesn't match SEC endianness
 * @pdb: pointer to the PDB to be used with this descriptor
 *       This structure will be copied inline to the descriptor under
 *       construction. No error checking will be made. Refer to the
 *       block guide for details about the encapsulation PDB.
 * @opt_ip_hdr:  pointer to Optional IP Header
 *     -if OIHI = PDBOPTS_ESP_OIHI_PDB_INL, opt_ip_hdr points to the buffer to
 *     be inlined in the PDB. Number of bytes (buffer size) copied is provided
 *     in pdb->ip_hdr_len.
 *     -if OIHI = PDBOPTS_ESP_OIHI_PDB_REF, opt_ip_hdr points to the address of
 *     the Optional IP Header. The address will be inlined in the PDB verbatim.
 *     -for other values of OIHI options field, opt_ip_hdr is not used.
 * @cipherdata: pointer to block cipher transform definitions
 *              Valid algorithm values - one of OP_PCL_IPSEC_*
 * @authdata: pointer to authentication transform definitions.
 *            If an authentication key is required by the protocol, a "normal"
 *            key must be provided; DKP (Derived Key Protocol) will be used to
 *            compute MDHA on the fly in HW.
 *            Valid algorithm values - one of OP_PCL_IPSEC_*
 *
 * Return: size of descriptor written in words or negative number on error
 */
static inline int
cnstr_shdsc_ipsec_new_encap(uint32_t *descbuf, bool ps,
			    bool swap,
			    struct ipsec_encap_pdb *pdb,
			    uint8_t *opt_ip_hdr,
			    struct alginfo *cipherdata,
			    struct alginfo *authdata)
{
	struct program prg;
	struct program *p = &prg;

	LABEL(keyjmp);
	REFERENCE(pkeyjmp);
	LABEL(hdr);
	REFERENCE(phdr);

	if (rta_sec_era < RTA_SEC_ERA_8) {
		pr_err("IPsec new mode encap: available only for Era %d or above\n",
		       USER_SEC_ERA(RTA_SEC_ERA_8));
		return -ENOTSUP;
	}

	PROGRAM_CNTXT_INIT(p, descbuf, 0);
	if (swap)
		PROGRAM_SET_BSWAP(p);
	if (ps)
		PROGRAM_SET_36BIT_ADDR(p);
	phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);

	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);

	switch (pdb->options & PDBOPTS_ESP_OIHI_MASK) {
	case PDBOPTS_ESP_OIHI_PDB_INL:
		COPY_DATA(p, opt_ip_hdr, pdb->ip_hdr_len);
		break;
	case PDBOPTS_ESP_OIHI_PDB_REF:
		if (ps)
			COPY_DATA(p, opt_ip_hdr, 8);
		else
			COPY_DATA(p, opt_ip_hdr, 4);
		break;
	default:
		break;
	}
	SET_LABEL(p, hdr);

	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
	if (authdata->keylen)
		__gen_auth_key(p, authdata);
	if (cipherdata->keylen)
		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
		    cipherdata->keylen, INLINE_KEY(cipherdata));
	SET_LABEL(p, keyjmp);
	PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
		 OP_PCLID_IPSEC_NEW,
		 (uint16_t)(cipherdata->algtype | authdata->algtype));
	PATCH_JUMP(p, pkeyjmp, keyjmp);
	PATCH_HDR(p, phdr, hdr);
	return PROGRAM_FINALIZE(p);
}

/**
 * IPSEC_NEW_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor length
 *
 * Accounts only for the "base" commands and is intended to be used by upper
 * layers to determine whether keys can be inlined or not. To be used as first
 * parameter of rta_inline_query().
 */
#define IPSEC_NEW_DEC_BASE_DESC_LEN	(5 * CAAM_CMD_SZ + \
					 sizeof(struct ipsec_decap_pdb))

/**
 * IPSEC_NEW_NULL_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor
 *                                    length for the case of
 *                                    NULL decryption / authentication
 *
 * Accounts only for the "base" commands and is intended to be used by upper
 * layers to determine whether key can be inlined or not. To be used as first
 * parameter of rta_inline_query().
 */
#define IPSEC_NEW_NULL_DEC_BASE_DESC_LEN	(4 * CAAM_CMD_SZ + \
						 sizeof(struct ipsec_decap_pdb))

/**
 * cnstr_shdsc_ipsec_new_decap - IPSec new mode ESP decapsulation protocol-level
 *     shared descriptor.
 * @descbuf: pointer to buffer used for descriptor construction
 * @ps: if 36/40bit addressing is desired, this parameter must be true
 * @swap: must be true when core endianness doesn't match SEC endianness
 * @pdb: pointer to the PDB to be used with this descriptor
 *       This structure will be copied inline to the descriptor under
 *       construction. No error checking will be made. Refer to the
 *       block guide for details about the decapsulation PDB.
 * @cipherdata: pointer to block cipher transform definitions
 *              Valid algorithm values 0 one of OP_PCL_IPSEC_*
 * @authdata: pointer to authentication transform definitions.
 *            If an authentication key is required by the protocol, a "normal"
 *            key must be provided; DKP (Derived Key Protocol) will be used to
 *            compute MDHA on the fly in HW.
 *            Valid algorithm values - one of OP_PCL_IPSEC_*
 *
 * Return: size of descriptor written in words or negative number on error
 */
static inline int
cnstr_shdsc_ipsec_new_decap(uint32_t *descbuf, bool ps,
			    bool swap,
			    struct ipsec_decap_pdb *pdb,
			    struct alginfo *cipherdata,
			    struct alginfo *authdata)
{
	struct program prg;
	struct program *p = &prg;

	LABEL(keyjmp);
	REFERENCE(pkeyjmp);
	LABEL(hdr);
	REFERENCE(phdr);

	if (rta_sec_era < RTA_SEC_ERA_8) {
		pr_err("IPsec new mode decap: available only for Era %d or above\n",
		       USER_SEC_ERA(RTA_SEC_ERA_8));
		return -ENOTSUP;
	}

	PROGRAM_CNTXT_INIT(p, descbuf, 0);
	if (swap)
		PROGRAM_SET_BSWAP(p);
	if (ps)
		PROGRAM_SET_36BIT_ADDR(p);
	phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
	SET_LABEL(p, hdr);
	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
	if (authdata->keylen)
		__gen_auth_key(p, authdata);
	if (cipherdata->keylen)
		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
		    cipherdata->keylen, INLINE_KEY(cipherdata));
	SET_LABEL(p, keyjmp);
	PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
		 OP_PCLID_IPSEC_NEW,
		 (uint16_t)(cipherdata->algtype | authdata->algtype));
	PATCH_JUMP(p, pkeyjmp, keyjmp);
	PATCH_HDR(p, phdr, hdr);
	return PROGRAM_FINALIZE(p);
}

/**
 * IPSEC_AUTH_VAR_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
 *				for the case of variable-length authentication
 *				only data.
 *				Note: Only for SoCs with SEC_ERA >= 3.
 *
 * Accounts only for the "base" commands and is intended to be used by upper
 * layers to determine whether keys can be inlined or not. To be used as first
 * parameter of rta_inline_query().
 */
#define IPSEC_AUTH_VAR_BASE_DESC_LEN	(27 * CAAM_CMD_SZ)

/**
 * IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor
 *                              length for variable-length authentication only
 *                              data.
 *                              Note: Only for SoCs with SEC_ERA >= 3.
 *
 * Accounts only for the "base" commands and is intended to be used by upper
 * layers to determine whether key can be inlined or not. To be used as first
 * parameter of rta_inline_query().
 */
#define IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN	\
				(IPSEC_AUTH_VAR_BASE_DESC_LEN + CAAM_CMD_SZ)

/**
 * IPSEC_AUTH_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
 *
 * Accounts only for the "base" commands and is intended to be used by upper
 * layers to determine whether key can be inlined or not. To be used as first
 * parameter of rta_inline_query().
 */
#define IPSEC_AUTH_BASE_DESC_LEN	(19 * CAAM_CMD_SZ)

/**
 * IPSEC_AUTH_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor length
 *
 * Accounts only for the "base" commands and is intended to be used by upper
 * layers to determine whether key can be inlined or not. To be used as first
 * parameter of rta_inline_query().
 */
#define IPSEC_AUTH_AES_DEC_BASE_DESC_LEN	(IPSEC_AUTH_BASE_DESC_LEN + \
						CAAM_CMD_SZ)

/**
 * cnstr_shdsc_authenc - authenc-like descriptor
 * @descbuf: pointer to buffer used for descriptor construction
 * @ps: if 36/40bit addressing is desired, this parameter must be true
 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
 * @cipherdata: pointer to block cipher transform definitions.
 *              Valid algorithm values one of OP_ALG_ALGSEL_* {DES, 3DES, AES}
 *              Valid modes for:
 *                  AES: OP_ALG_AAI_* {CBC, CTR}
 *                  DES, 3DES: OP_ALG_AAI_CBC
 * @authdata: pointer to authentication transform definitions.
 *            Valid algorithm values - one of OP_ALG_ALGSEL_* {MD5, SHA1,
 *            SHA224, SHA256, SHA384, SHA512}
 * Note: The key for authentication is supposed to be given as plain text.
 * Note: There's no support for keys longer than the block size of the
 *       underlying hash function, according to the selected algorithm.
 *
 * @ivlen: length of the IV to be read from the input frame, before any data
 *         to be processed
 * @auth_only_len: length of the data to be authenticated-only (commonly IP
 *                 header, IV, Sequence number and SPI)
 * Note: Extended Sequence Number processing is NOT supported
 *
 * @trunc_len: the length of the ICV to be written to the output frame. If 0,
 *             then the corresponding length of the digest, according to the
 *             selected algorithm shall be used.
 * @dir: Protocol direction, encapsulation or decapsulation (DIR_ENC/DIR_DEC)
 *
 * Note: Here's how the input frame needs to be formatted so that the processing
 *       will be done correctly:
 * For encapsulation:
 *     Input:
 * +----+----------------+---------------------------------------------+
 * | IV | Auth-only data | Padded data to be authenticated & Encrypted |
 * +----+----------------+---------------------------------------------+
 *     Output:
 * +--------------------------------------+
 * | Authenticated & Encrypted data | ICV |
 * +--------------------------------+-----+

 * For decapsulation:
 *     Input:
 * +----+----------------+--------------------------------+-----+
 * | IV | Auth-only data | Authenticated & Encrypted data | ICV |
 * +----+----------------+--------------------------------+-----+
 *     Output:
 * +----+--------------------------+
 * | Decrypted & authenticated data |
 * +----+--------------------------+
 *
 * Note: This descriptor can use per-packet commands, encoded as below in the
 *       DPOVRD register:
 * 32    24    16               0
 * +------+---------------------+
 * | 0x80 | 0x00| auth_only_len |
 * +------+---------------------+
 *
 * This mechanism is available only for SoCs having SEC ERA >= 3. In other
 * words, this will not work for P4080TO2
 *
 * Note: The descriptor does not add any kind of padding to the input data,
 *       so the upper layer needs to ensure that the data is padded properly,
 *       according to the selected cipher. Failure to do so will result in
 *       the descriptor failing with a data-size error.
 *
 * Return: size of descriptor written in words or negative number on error
 */
static inline int
cnstr_shdsc_authenc(uint32_t *descbuf, bool ps, bool swap,
		    struct alginfo *cipherdata,
		    struct alginfo *authdata,
		    uint16_t ivlen, uint16_t auth_only_len,
		    uint8_t trunc_len, uint8_t dir)
{
	struct program prg;
	struct program *p = &prg;
	const bool need_dk = (dir == DIR_DEC) &&
			     (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
			     (cipherdata->algmode == OP_ALG_AAI_CBC);

	LABEL(skip_patch_len);
	LABEL(keyjmp);
	LABEL(skipkeys);
	LABEL(aonly_len_offset);
	REFERENCE(pskip_patch_len);
	REFERENCE(pkeyjmp);
	REFERENCE(pskipkeys);
	REFERENCE(read_len);
	REFERENCE(write_len);

	PROGRAM_CNTXT_INIT(p, descbuf, 0);

	if (swap)
		PROGRAM_SET_BSWAP(p);
	if (ps)
		PROGRAM_SET_36BIT_ADDR(p);

	/*
	 * Since we currently assume that key length is equal to hash digest
	 * size, it's ok to truncate keylen value.
	 */
	trunc_len = trunc_len && (trunc_len < authdata->keylen) ?
			trunc_len : (uint8_t)authdata->keylen;

	SHR_HDR(p, SHR_SERIAL, 1, SC);

	/*
	 * M0 will contain the value provided by the user when creating
	 * the shared descriptor. If the user provided an override in
	 * DPOVRD, then M0 will contain that value
	 */
	MATHB(p, MATH0, ADD, auth_only_len, MATH0, 4, IMMED2);

	if (rta_sec_era >= RTA_SEC_ERA_3) {
		/*
		 * Check if the user wants to override the auth-only len
		 */
		MATHB(p, DPOVRD, ADD, 0x80000000, MATH2, 4, IMMED2);

		/*
		 * No need to patch the length of the auth-only data read if
		 * the user did not override it
		 */
		pskip_patch_len = JUMP(p, skip_patch_len, LOCAL_JUMP, ALL_TRUE,
				  MATH_N);

		/* Get auth-only len in M0 */
		MATHB(p, MATH2, AND, 0xFFFF, MATH0, 4, IMMED2);

		/*
		 * Since M0 is used in calculations, don't mangle it, copy
		 * its content to M1 and use this for patching.
		 */
		MATHB(p, MATH0, ADD, MATH1, MATH1, 4, 0);

		read_len = MOVE(p, DESCBUF, 0, MATH1, 0, 6, WAITCOMP | IMMED);
		write_len = MOVE(p, MATH1, 0, DESCBUF, 0, 8, WAITCOMP | IMMED);

		SET_LABEL(p, skip_patch_len);
	}
	/*
	 * MATH0 contains the value in DPOVRD w/o the MSB, or the initial
	 * value, as provided by the user at descriptor creation time
	 */
	if (dir == DIR_ENC)
		MATHB(p, MATH0, ADD, ivlen, MATH0, 4, IMMED2);
	else
		MATHB(p, MATH0, ADD, ivlen + trunc_len, MATH0, 4, IMMED2);

	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);

	KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
	    INLINE_KEY(authdata));

	/* Insert Key */
	KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
	    cipherdata->keylen, INLINE_KEY(cipherdata));

	/* Do operation */
	ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC,
		      OP_ALG_AS_INITFINAL,
		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
		      dir);

	if (need_dk)
		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode,
			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
	pskipkeys = JUMP(p, skipkeys, LOCAL_JUMP, ALL_TRUE, 0);

	SET_LABEL(p, keyjmp);

	ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
		      OP_ALG_AS_INITFINAL,
		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
		      dir);

	if (need_dk) {
		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode |
			      OP_ALG_AAI_DK, OP_ALG_AS_INITFINAL,
			      ICV_CHECK_DISABLE, dir);
		SET_LABEL(p, skipkeys);
	} else {
		SET_LABEL(p, skipkeys);
		ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
	}

	/*
	 * Prepare the length of the data to be both encrypted/decrypted
	 * and authenticated/checked
	 */
	MATHB(p, SEQINSZ, SUB, MATH0, VSEQINSZ, 4, 0);

	MATHB(p, VSEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);

	/* Prepare for writing the output frame */
	SEQFIFOSTORE(p, MSG, 0, 0, VLF);

	SET_LABEL(p, aonly_len_offset);

	/* Read IV */
	if (cipherdata->algmode == OP_ALG_AAI_CTR)
		SEQLOAD(p, CONTEXT1, 16, ivlen, 0);
	else
		SEQLOAD(p, CONTEXT1, 0, ivlen, 0);

	/*
	 * Read data needed only for authentication. This is overwritten above
	 * if the user requested it.
	 */
	SEQFIFOLOAD(p, MSG2, auth_only_len, 0);

	if (dir == DIR_ENC) {
		/*
		 * Read input plaintext, encrypt and authenticate & write to
		 * output
		 */
		SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);

		/* Finally, write the ICV */
		SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
	} else {
		/*
		 * Read input ciphertext, decrypt and authenticate & write to
		 * output
		 */
		SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);

		/* Read the ICV to check */
		SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
	}

	PATCH_JUMP(p, pkeyjmp, keyjmp);
	PATCH_JUMP(p, pskipkeys, skipkeys);
	PATCH_JUMP(p, pskipkeys, skipkeys);

	if (rta_sec_era >= RTA_SEC_ERA_3) {
		PATCH_JUMP(p, pskip_patch_len, skip_patch_len);
		PATCH_MOVE(p, read_len, aonly_len_offset);
		PATCH_MOVE(p, write_len, aonly_len_offset);
	}

	return PROGRAM_FINALIZE(p);
}

#endif /* __DESC_IPSEC_H__ */


text:
layout: post
title: Simplifying Your Life with this Hybrid Method
author: Manal Ghosain
categories:
tags:
---

![Tree](/images/tree.jpg)

Do you feel anxious or overwhelmed?

Are you chasing time? Too much to do and so little time?

The customary approach to overcome overwhelm and manage anxiety is to become more efficient, to master productivity and time management.

While there is nothing wrong with efficiency, the rewards are usually short-lived. Sooner than later, overwhelm will be replaced by burnout.

You won't reduce overwhelm by taking on many things and trying to do them in less time. It's the exact opposite. You'll feel more at ease by doing less and taking your time doing it the best way you can, savoring the experience and not wanting (or needing) to do more.

In other words, if you want a calmer life, you need to simplify.

> "Simplicity is making the journey of this life with just baggage enough." ~Charles Dudley Warner

To simplify is to make things less complicated, and easier … to reduce action to the basics and eliminate the unnecessary.

If you are interested in simplifying your life and having more peace, start with the following and you'll be on your way.

## Gain clarity

This is the first and most important step you can do for yourself: Be clear about what's important to you.

Clarity about your desires and priorities will guide you through simplifying your life and adding more meaning to your experiences.

When you know what's important to you, you'll let go of the noise and distractions.

Picking a handful of important desires and values will make it easier to say no to everything else. You will focus on the things that matter and reduce the superfluous demands on your time and energy to the minimum.

If you agree that clarity will help you simplify, read on to put this concept into practice.

## How do you gain clarity?

The subject of clarity has been extensively covered in the self growth (development) field. Yet, it's one of hardest aspects of growth to actually do. It's been a constant struggle for me.

I've been experimenting with a combination of two tactics that are helping me tremendously in continuing to stay focused on what's important—and keeping it simple.

The two ideas are not new. I've heard them recommended a few times, among other things. It's the synergy of both that is effective in maintaining simple focus.

## 1- Make a list of what's important to you

List the 3 to 5 most important values or [aspects of life](/who-are-you-12-questions-to-uncover-your-turth/) that matter to you most.

What are you craving in your life right now?

Do you want a meaningful [connection](/regrets-of-the-dying-and-what-we-can-learn/)? Do you want more love?

Do you want financial freedom?

Do you desire a healthy body?

Do you value creativity, peace of mind, autonomy … etc.?

Sit with it and think about it. What would bring you more peace and fulfillment? What would your ideal life look like?

Write down what you [really want](/allow-yourself-to-dream/) and value. List all the things that come to your mind and heart.

## 2- Set your 666 priorities

No. This is not an invitation to call out the devil :). It's an exercise in helping you prioritize your needs and desires.

Answer the following three questions the best way you can.

Start with the first question and give it your full time and attention. Once you're completely done, move on to the next one.

Don't overanalyze; just go with your gut feeling and answer based on how you feel.

**If you had 6 months to live, what would you do in those 6 months?**

Nope. It was a mistake. You don't have 6 months; you only have 6 weeks.

**If you only had 6 weeks to live, what would you do in those weeks?**

Oops, you have less time than that!

**What if you only had 6 days to live, what would you do?**

Answering this question will add a self-imposed sense of urgency—based on your personal values and priorities, not those of others.

By going through the process you will:

  * Clarify what's important
  * Prioritize the important without stress or worry
  * Eliminate the unnecessary.

Now that you have the answers, start with the shortest-term answer. What would you do if you only had 6 days to live?

**A personal example**

I have a lot of things I desire to do. I've always started with the biggest things and ignored the smaller ones that nag at the back of my head.

One of the desires I have is to live the simplest life possible. But instead of focusing on that one, I started with creative expression, which was fine—until I answered the 6-day question.

Turns out that the most important thing to me in the shortest term is to simplify my financial life and make it as easy as possible for my family to deal with our affairs after I'm gone.

If I only had 6 days, the most important thing for me would be to clean up my financial act.

I've complicated things over the years. I have numerous documents, accounts, and transactions known only to me. If I depart this planet today, I'll leave my family with a financial mess that will take them months, if not a year to untangle.

So I've been spending the last week getting rid of the unnecessary and streamlining the process. After I strip down everything to the basics, I aim to leave a document with my will that will serve as a step-by-step guide.

My 6-day action is going to take a bit longer. I had to stop a few times for family obligations and unexpected interruptions. But that's okay. I know where to focus and what to do. More importantly, I didn't commit to anything new and I eliminated a lot of smaller things that didn't matter.

Once I'm done with cleaning up my financial records, I'll have a look at my answers and determine what I'd want to do in the next 6 days. The next thing will be from the 6 weeks list. I'll pick one item at a time and work with it—no excuses or distractions.

When you're focused on a single important action with an added sense of urgency, you'll be able to eliminate the excess without hesitation. And this is the core of simplicity.

Simplifying is one of the best things you can do to have more peace in your life.

redpajama_set_name: RedPajamaGithub


text:
using System.Data.Entity.ModelConfiguration;
using System.ComponentModel.DataAnnotations.Schema;

namespace WcfSample.Client.Entities.Models.Mapping
{
    public class EmployeeMap : EntityTypeConfiguration<Employee>
    {
        public EmployeeMap()
        {
            // Primary Key
            this.HasKey(t => t.EmployeeId);

            // Properties
            this.Property(t => t.LastName)
                .IsRequired()
                .HasMaxLength(20);

            this.Property(t => t.FirstName)
                .IsRequired()
                .HasMaxLength(20);

            this.Property(t => t.City)
                .HasMaxLength(15);

            this.Property(t => t.Country)
                .HasMaxLength(15);

            // Table & Column Mappings
            this.ToTable("Employee");
            this.Property(t => t.EmployeeId).HasColumnName("EmployeeId");
            this.Property(t => t.LastName).HasColumnName("LastName");
            this.Property(t => t.FirstName).HasColumnName("FirstName");
            this.Property(t => t.BirthDate).HasColumnName("BirthDate");
            this.Property(t => t.HireDate).HasColumnName("HireDate");
            this.Property(t => t.City).HasColumnName("City");
            this.Property(t => t.Country).HasColumnName("Country");

            // Tracking Properties
			this.Ignore(t => t.TrackingState);
			this.Ignore(t => t.ModifiedProperties);
			this.Ignore(t => t.EntityIdentifier);

            // Relationships
            this.HasMany(t => t.Territories)
                .WithMany(t => t.Employees)
                .Map(m =>
                    {
                        m.ToTable("EmployeeTerritories");
                        m.MapLeftKey("EmployeeId");
                        m.MapRightKey("TerritoryId");
                    });

        }
    }
}


text:
* [ Introduction ](#intro)
* [ General installation on a Linux distro](#general_installation)
  * [ Fixes for using Fedora CoreOS ](#fedora_coreos)
    * [ Generating the igntion file ](#ignition_file)
    * [ Run fedora CoreOS using the ignition file ](#run_ignition)
  * [ Alternative ways of running Scout ](#alternative_boot)

## Requirements

* podman version >= 2.0.4

## Introduction

Scout can be run by installing a few systemd unit files (the text files scout-*.service)
into a Linux user's home directory. The Scout software and Mongodb software will then be run in containers from Dockerhub.

| Systemd service | Description |
| --              | --          |
| [scout-pod.service](https://github.com/Clinical-Genomics/scout/blob/master/containers/systemd/scout-pod.service) | Runs a pod in which the other containers will be running |
| [scout-create-datadir.service](https://github.com/Clinical-Genomics/scout/blob/master/containers/systemd/scout-create-datadir.service) | Creates an empty directory that will be used by Mongodb to store data |
| [scout-mongo.service](https://github.com/Clinical-Genomics/scout/blob/master/containers/systemd/scout-mongo.service) | Runs Mongodb in the container docker.io/library/mongo |
| [scout-setup-demo.service](https://github.com/Clinical-Genomics/scout/blob/master/containers/systemd/scout-setup-demo.service) | Loads the demo data by running the container docker.io/clinicalgenomics/scout:latest  |
| [scout-scout.service](https://github.com/Clinical-Genomics/scout/blob/master/containers/systemd/scout-scout.service) | Serves the Scout webserver by running the container docker.io/clinicalgenomics/scout:latest |

It is also possible to run the Scout systemd services in the same way but on a new Fedora CoreOS computer.

## Installation into the home directory of a Linux user

In the Git repo root directory, run

1. Copy the systemd unit files located under `scout/containers/systemd` to `~/.config/systemd/user`

```
mkdir -p ~/.config/systemd/user
cp scout/containers/systemd/scout-pod.service ~/.config/systemd/user
cp scout/containers/systemd/scout-create-datadir.service ~/.config/systemd/user
cp scout/containers/systemd/scout-mongo.service ~/.config/systemd/user
cp scout/containers/systemd/scout-setup-demo.service ~/.config/systemd/user
cp scout/containers/systemd/scout-scout.service ~/.config/systemd/user
```

2. __Optional step__ If you would like to use a locally built scout container instead of the one from dockerhub, run

```
sed -i 's/docker.io\/clinicalgenomics\/scout:latest/localhost\/scout/g' ~/.config/systemd/user/scout-setup-demo.service
sed -i 's/docker.io\/clinicalgenomics\/scout:latest/localhost\/scout/g' ~/.config/systemd/user/scout-scout.service
sed -i '/TimeoutStartSec=/d' ~/.config/systemd/user/scout-setup-demo.service
sed -i '/TimeoutStartSec=/d' ~/.config/systemd/user/scout-scout.service
```

3.

```
systemctl --user daemon-reload
systemctl --user enable scout-pod.service
```

## Usage

```
systemctl --user start scout-pod.service
firefox http://localhost:5000
```

To see the status of the services

```
systemctl --user status scout-pod.service scout-create-datadir.service scout-mongo.service scout-setup-demo.service scout-scout.service
```

If you would like the services to start automatically after a reboot of your computer,
run

```
loginctl enable-linger $USER
```
If the above command should fail due to permission issues, run it as superuser (sudo).

# Using Fedora CoreOS

## Generating the Ignition file _scout.ign_

To start Fedora CoreOS, the [Ignition file](https://docs.fedoraproject.org/en-US/fedora-coreos/producing-ign/) _scout.ign_ is needed.
It is generated from from the input file [scout.fcc](./scout.fcc) with the command

```
podman run --rm -v ./systemd:/input:Z quay.io/coreos/fcct:release --pretty --strict -d /input /input/scout.fcc > ./scout.ign
```

(run from the root directory of the Scout repository)

Before generating _scout.ign_, please edit _scout.fcc_ and replace the ssh public key with your ssh public key.

It is possible to automate the generation of _scout.ign_ with a GitHub Actions workflow so that
it is downloadable from GitHub pages (e.g. https://< username >.github.io/scout/scout.ign)

This GitHub Actions workflow generates such an Ignition file:

```
name: Run Fedora CoreOS Configuration Transpiler
on:
  push:
    branch:
      - master

jobs:
  run_fcct:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: |
          mkdir output
      - uses: docker://quay.io/coreos/fcct:release
        with:
          args: --pretty --strict -d ./systemd -o output/scout.ign systemd/scout.fcc
      - uses: actions/upload-artifact@master
        with:
          name: scout.ign
          path: output/scout.ign
      - name: deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./output
```

References:
* https://github.com/coreos/fcct
* https://github.com/coreos/fcct/blob/master/docs/specs.md

# Using the generated Ignition file to run Fedora CoreOS

The Ignition file _scout.ign_ can be used to run Scout in different ways:

* AWS
* Azure
* DigitalOcean
* Exoscale
* GCP
* libvirt
* QEMU
* VMware
* Vultr
* Run in Live mode from USB stick
* Install from USB stick

Fedora CoreOS documentation:
https://docs.fedoraproject.org/en-US/fedora-coreos/

See for instance __User guides__ -> __Provisioning Machines__

## Run Scout in live mode in RAM memory from a USB stick

Download the Bare metal __ISO__ from

https://getfedora.org/en/coreos/download?tab=metal_virtualized&stream=next

Either stop grub in the early boot phase and append the kernel argument
`ignition.config.url=https://example.com/scout.ign` (adjust URL)

or alternatively embed the ignition file _scout.ign_ into the ISO before writing it to the USB stick

```
cat scout.ign | coreos-installer iso embed file.iso
```

## Run Scout on AWS

Doc:
https://docs.fedoraproject.org/en-US/fedora-coreos/provisioning-aws/

A sketch (untested)

```
aws ec2 run-instances <other options> --image-id <ami> --user-data file://scout.ign
```

## Run Scout in a VM on an Ubuntu 20.04 host with virt-install

Assume you are logged in as the user __mytest__

```
mytest@laptop:~$  cat /etc/issue
Ubuntu 20.04.1 LTS \n \l

mytest@laptop:~$
```

Download and decompress
```
mytest@laptop:~$ wget https://builds.coreos.fedoraproject.org/prod/streams/next/builds/32.20200901.1.0/x86_64/fedora-coreos-32.20200901.1.0-qemu.x86_64.qcow2.xz
mytest@laptop:~$ unxz fedora-coreos-32.20200901.1.0-qemu.x86_64.qcow2.xz
```

Add the line
```
 /home/mytest/scout.ign rk
```

for Apparmor
```
mytest@laptop:~$ sudo cat /etc/apparmor.d/libvirt/TEMPLATE.qemu
#
# This profile is for the domain whose UUID matches this file.
#

#include <tunables/global>

profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
  #include <abstractions/libvirt-qemu>
}
mytest@laptop:~$ sudo nano /etc/apparmor.d/libvirt/TEMPLATE.qemu
mytest@laptop:~$ sudo cat /etc/apparmor.d/libvirt/TEMPLATE.qemu
#
# This profile is for the domain whose UUID matches this file.
#

#include <tunables/global>

profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
  #include <abstractions/libvirt-qemu>
 /home/mytest/scout.ign rk,
}
mytest@laptop:~$
```

```
mytest@laptop:~$ virt-install --connect qemu:///system -n firsttest -r "2048" --os-variant=fedora31 --import --graphics=none --disk "size=15,backing_store=/home/mytest/fedora-coreos-32.20200824.1.0-qemu.x86_64.qcow2"         --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=/home/mytest/scout.ign"
```
The IP address is printed on the screen the installation.
Another way to list the IP address, is to run the command `virsh net-dhcp-leases default`

```
mytest@laptop:~$ virsh net-dhcp-leases default
 Expiry Time           MAC address         Protocol   IP address           Hostname   Client ID or DUID
------------------------------------------------------------------------------------------------------------
 2020-09-02 21:57:10   52:54:00:88:3c:a3   ipv4       192.168.122.237/24   -          01:52:54:00:88:3c:a3
```

Download the Scout web page

```
mytest@laptop:~$ curl -s http://192.168.122.90:5000 | head -1
<!DOCTYPE html>
mytest@laptop:~$
```

## Erase computer and install Scout instead

:warning: This will erase the harddrive of the computer.

In case you want to install to the drive _/dev/sda_
append the kernel arguments

* `coreos.inst.install_dev=/dev/sda`
* `coreos.inst.ignition_url=https://example.com/scout.ign`

# Add users to Scout

A sketch (untested)

1.
```
ssh -i ssh_private_key core@<IPADDRESS OF FEDORA-COREOS-MACHINE>
```

2.

```
podman exec scout-scout scout load user -i $INSTID -u $NAME -id $ADID -m $USERMAIL $ADMIN
```
or maybe

```
podman exec -ti scout-scout scout load user -i $INSTID -u $NAME -id $ADID -m $USERMAIL $ADMIN
```


text:
package vtk.resourcemanagement;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import vtk.resourcemanagement.property.PropertyDescription;
import vtk.resourcemanagement.property.SimplePropertyDescription;
import vtk.util.text.Json;

public class StructuredResource {

    private StructuredResourceDescription desc;
    private Map<String, Object> properties;

    private StructuredResource(StructuredResourceDescription desc, Map<String, Object> properties) {
        if (desc == null) {
            throw new IllegalArgumentException("Description cannot be null");
        }
        this.desc = desc;
        this.properties = properties;
    }

    @SuppressWarnings("unchecked")
    static StructuredResource create(StructuredResourceDescription desc, InputStream source) {
        try {
            Object json = Json.parse(source);

            ValidationResult validation = validateInternal(desc, json);
            if (!validation.isValid()) {
                throw new RuntimeException("Invalid document: " + validation.getErrors());
            }
            Map<?,?> jsonObject= (Map<?,?>) json;
            Map<String, Object> properties = (Map<String, Object>) jsonObject.get("properties");
            return new StructuredResource(desc, properties);
        }
        catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    @SuppressWarnings("unchecked")
    static StructuredResource createFromMap(StructuredResourceDescription desc, Map<String, Object> json) {
        ValidationResult validation = validateInternal(desc, json);
        if (!validation.isValid()) {
            throw new RuntimeException("Invalid document: " + validation.getErrors());
        }
        Map<?,?> jsonObject = json;
        Map<String, Object> properties = (Map<String, Object>) jsonObject.get("properties");
        return new StructuredResource(desc, properties);
    }

    public ValidationResult validate(Object document) {
        return validateInternal(this.desc, document);
    }

    public boolean isValidDocument(Object document) {
        try {
            ValidationResult validation = validateInternal(this.desc, document);
            return validation.isValid();
        } catch (Exception e) {
            return false;
        }
    }

    // XXX: make recursive:
    public Map<String, Object> toJSON() {
        Map<String, Object> json = new HashMap<>();
        json.put("resourcetype", desc.getName());
        Map<String, Object> props = new HashMap<>();

        for (String name : this.properties.keySet()) {
            Object value = this.properties.get(name);
            if (value != null) {
                if (value instanceof String) {
                    String s = (String) value;
                    if (s.trim().equals("")) {
                        continue;
                    }
                }
                props.put(name, this.properties.get(name));
            }
        }
        json.put("properties", props);
        return json;
    }

    private static ValidationResult validateInternal(StructuredResourceDescription desc, Object json) {
        if (json == null) {
            throw new IllegalStateException("Input is NULL");
        }
        if (!(json instanceof Map<?,?>)) {
            throw new IllegalArgumentException("Not a JSON object");
        }
        Map<?,?> map = (Map<?,?>) json;
        Object typeEntry = map.get("resourcetype");
        if (typeEntry == null) {
            throw new IllegalArgumentException(
            "Unable to validate: missing 'resourcetype' element");
        }

        String type = typeEntry.toString();

        Object propertiesEntry = map.get("properties");
        if (propertiesEntry == null) {
            throw new IllegalArgumentException(
            "Unable to validate: missing 'properties' element");
        }
        if (!(propertiesEntry instanceof Map<?,?>)) {
            throw new IllegalArgumentException(
            "Unable to validate: 'properties' element is not a JSON object");
        }

        Map<?,?> properties = (Map<?,?>) propertiesEntry;

        List<ValidationError> errors = new ArrayList<>();
        for (PropertyDescription propDesc : desc.getPropertyDescriptions()) {
            if (propDesc instanceof SimplePropertyDescription) {
                if (((SimplePropertyDescription) propDesc).isRequired()) {
                    Object value = properties.get(propDesc.getName());
                    if (value == null) {
                        errors.add(new ValidationError(propDesc.getName(),
                        "property is required"));
                    }
                    // TODO: validate types and multiple properties
                }
            }
        }
        ValidationResult result = new ValidationResult(errors);
        return result;
    }

    public StructuredResourceDescription getType() {
        return this.desc;
    }

    public Object getProperty(String name) {
        return this.properties.get(name);
    }

    public void addProperty(String name, Object value) {
        this.properties.put(name, value);
    }

    public void addProperty(String name, Object[] values) {
        this.properties.put(name, values);
    }

    public void removeProperty(String name) {
        this.properties.remove(name);
    }

    public Collection<String> getPropertyNames() {
        return Collections.unmodifiableCollection(this.properties.keySet());
    }

    public String getLocalizedMsg(String key, Locale locale, Locale contentLocale, Object[] param) {
        return this.desc.getLocalizedMsg(key, locale, contentLocale, param);
    }

    public String getLocalizedTooltip(String key, Locale locale) {
        return this.desc.getLocalizedTooltip(key, locale);
    }

}


text:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lachesis.mnis.core.mybatis.mapper.CriticalServiceMapper">
	<resultMap id="criticalValueMap" type="CriticalValue">
		<id property="criticalValueId" column="barcode" />
		<result property="deptNo" column="ward_code" />
		<result property="patientName" column="name" />
		<result property="bedCode" column="bed_code" />
		<result property="inHospNo" column="in_hosp_no" />
		<result property="sendPeople" column="send_people" />
		<result property="sendTime" column="send_time" />
		<result property="criticalValue" column="critical_value" />
		<result property="dispose" column="dispose_doctor_name" />
		<result property="type" column="type" />
		<result property="status" column="dispose_status" />
		<result property="disposeTime" column="dispose_date" />
		<result property="receiveName" column="RECEIVE_NAME" />
		<result property="doctorName" column="DOCTOR_NAME" />
		<result property="isRepeat" column="IS_REPEAT" />
	</resultMap>

	<resultMap id="criticalValueRecordMap" type="com.lachesis.mnis.core.critical.entity.CriticalValueRecord">
		<id property="criticalValueId" column="barcode" />
		<result property="deptNo" column="ward_code" />
		<result property="patientName" column="name" />
		<result property="bedCode" column="bed_code" />
		<result property="inHospNo" column="in_hosp_no" />
		<result property="sendPeople" column="send_people" />
		<result property="sendTime" column="send_time" />
		<result property="criticalValue" column="critical_value" />
		<result property="dispose" column="dispose_doctor_name" />
		<result property="type" column="type" />
		<result property="status" column="dispose_status" />
		<result property="disposeTime" column="dispose_date" />
		<result property="itemSubject" column="item_subject" />
		<association property="criticalOperRecord" resultMap="criticalOperRecordMap" />
		<collection property="labTestItems" resultMap="labTestItemMap"></collection>
	</resultMap>
	<resultMap id="criticalOperRecordMap" type="com.lachesis.mnis.core.critical.entity.CriticalOperRecord">
		<id property="id" column="id"/>
		<result property="operNurseCode" column="oper_nurse_code"/>
		<result property="operNurseName" column="oper_nurse_name"/>
		<result property="operTime" column="oper_time"/>
		<result property="operValue" column="oper_value"/>
		<result property="barcode" column="barcode"/>
		<result property="doctorName" column="DOCTOR_NAME"/>
		<result property="receiveName" column="RECEIVE_NAME"/>
		<result property="isRepeat" column="IS_REPEAT"/>
	</resultMap>
	<resultMap id="labTestItemMap" type="LabTestItem">
		<id property="detailRecordId" column="id" />
		<result property="itemName" column="item_name" />
		<result property="result" column="result_value" />
		<result property="resultUnit" column="result_unit" />
		<result property="normalFlag" column="normal_flag" />
		<result property="ranges" column="ref_ranges" />
		<result property="masterId" column="barcode" />
	</resultMap>
	<resultMap type="java.util.Map" id="CriticalItem"></resultMap>
	<select id="getCriticalValue" parameterType="Map" resultMap="criticalValueMap">
		select
		cv.ward_code,cv.bed_code,cv.critical_value,cv.send_people,cv.send_time,
		cv.dispose_doctor_name,cv.dispose_nurse_code,cv.dispose_nurse_name
		,cv.dispose_date,
		cv.dispose_status,cv.in_hosp_no ,p.name,cv.TEST_NO as
		barcode, pcr.DOCTOR_NAME, pcr.RECEIVE_NAME, pcr.IS_REPEAT
		from dbo.PAT_CRITICAL_RECORD pcr, pat_critical_value cv
		left join pat_cure_info p on p.pat_id = cv.pat_id

		<where>
			<if test="patIds != null and patIds.size() > 0">
				cv.pat_id in (
					<foreach collection="patIds" item="patId" index="index"
							 separator=",">
						#{patId}
					</foreach>
					)
			</if>
			<if test="deptno != null">
				and cv.ward_code = #{deptno}
			</if>
			<if test="startTime != null">
			 <![CDATA[AND cv.send_time > #{startTime} ]]>
			</if>
			<if test="endTime != null">
			 <![CDATA[AND cv.send_time <=#{endTime} ]]>
			</if>
			<if test="status != null">
			 <![CDATA[AND cv.dispose_status =#{status} AND cv.dispose_nurse_code is null]]>
			</if>
			AND pcr.BARCODE = cv.TEST_NO
		</where>
		order by cv.send_time
	</select>

	<select id="getCriticalValueById" parameterType="String"
		resultMap="criticalValueMap">
		select
		cv.ward_code,cv.bed_code,cv.critical_value,cv.send_people,cv.send_time,
		cv.dispose_doctor_name,cv.dispose_nurse_code,cv.dispose_nurse_name
		,cv.dispose_date,
		cv.dispose_status,cv.in_hosp_no ,p.name,p.barcode as barcode
		from pat_critical_value cv
		left join pat_cure_info p on p.pat_id = cv.pat_id
		where
		p.barcode = #{param1}
	</select>

	<insert id="updateCritical">
		update pat_critical_value set dispose_nurse_code = #{param2},
		dispose_nurse_name=#{param3},
		dispose_date = #{param3}
		where critical_id=#{param1}
		<!-- insert into pat_critical_value (critical_id ,nurse_id
		,nurse_name ,process_time ) values
		(#{param1}, #{param2}, #{param3},
		#{param4}) -->
	</insert>

	<select id="getCriticalValueRecord" parameterType="Map" resultMap="criticalValueRecordMap">
		SELECT  cv.ward_code ,
		        cv.bed_code ,
		        cv.in_hosp_no ,
		        p.name ,
		        cv.TEST_NO barcode ,
		        cv.critical_value ,
		        cv.send_people ,
		        cv.send_time ,
		        cv.dispose_doctor_name ,
		        cv.dispose_date ,
		        cv.dispose_status ,
		        pcr.ID ,
		        pcr.OPER_NURSE_CODE ,
		        pcr.OPER_NURSE_NAME ,
		        pcr.OPER_TIME ,
		        pcr.OPER_VALUE,
		        pcr.DOCTOR_NAME,
		        pcr.RECEIVE_NAME,
		        pcr.IS_REPEAT,
		 		m.TEST_SUBJECT item_subject,
		        d.ID,
		        d.ITEM_NAME,
		        d.NORMAL_FLAG,
		        d.REF_RANGES,
		        d.RESULT_UNIT,
		        d.RESULT_VALUE
		FROM    dbo.PAT_CRITICAL_VALUE cv
		        INNER JOIN dbo.PAT_CURE_INFO p ON p.PAT_ID = cv.PAT_ID
		                                          AND p.STATUS = 1
		        INNER JOIN dbo.PAT_LAB_TEST_MAS m ON cv.TEST_NO = m.TEST_NO
		        INNER JOIN dbo.PAT_LAB_TEST_DETAIL d ON cv.TEST_NO = d.TEST_NO
		        LEFT JOIN dbo.PAT_CRITICAL_RECORD pcr ON pcr.BARCODE = cv.TEST_NO

		WHERE d.NORMAL_FLAG IN ('CL','CH')
		<if test="deptCode != null">
			AND cv.WARD_CODE = #{deptCode}
		</if>
		<if test="patId != null">
			AND p.PAT_ID = #{patId}
		</if>
		<if test="isAll == null">
			AND pcr.id is null
		</if>
		<if test="startTime != null">
			AND cv.send_time >= #{startTime}
		</if>
		<if test="endTime != null">
			AND cv.send_time < #{endTime}
		</if>
		ORDER BY cv.send_time,d.item_no
	</select>

	<select id="getCritiveRecordCount" parameterType="String" resultType="Integer">
		SELECT
			count(1)
		FROM PAT_CRITICAL_RECORD
		WHERE barcode=#{param1}
	</select>

	<insert id="insertCriticalOperRecord" parameterType="com.lachesis.mnis.core.critical.entity.CriticalOperRecord">
		INSERT dbo.PAT_CRITICAL_RECORD
		        ( OPER_NURSE_CODE ,OPER_NURSE_NAME ,OPER_TIME ,OPER_VALUE ,BARCODE, DOCTOR_NAME, RECEIVE_NAME, IS_REPEAT
		        )
		VALUES  (#{operNurseCode},#{operNurseName},#{operTime},#{operValue},#{barcode},#{doctorName},#{receiveName},#{isRepeat}
		        )
	</insert>
</mapper>


text:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::ProgressEventBinding;
use dom::bindings::codegen::Bindings::ProgressEventBinding::ProgressEventMethods;
use dom::bindings::error::Fallible;
use dom::bindings::inheritance::Castable;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::root::DomRoot;
use dom::bindings::str::DOMString;
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use servo_atoms::Atom;

#[dom_struct]
pub struct ProgressEvent {
    event: Event,
    length_computable: bool,
    loaded: u64,
    total: u64
}

impl ProgressEvent {
    fn new_inherited(length_computable: bool, loaded: u64, total: u64) -> ProgressEvent {
        ProgressEvent {
            event: Event::new_inherited(),
            length_computable: length_computable,
            loaded: loaded,
            total: total
        }
    }
    pub fn new_uninitialized(global: &GlobalScope) -> DomRoot<ProgressEvent> {
        reflect_dom_object(Box::new(ProgressEvent::new_inherited(false, 0, 0)),
                           global,
                           ProgressEventBinding::Wrap)
    }
    pub fn new(global: &GlobalScope, type_: Atom,
               can_bubble: EventBubbles, cancelable: EventCancelable,
               length_computable: bool, loaded: u64, total: u64) -> DomRoot<ProgressEvent> {
        let ev = reflect_dom_object(Box::new(ProgressEvent::new_inherited(length_computable, loaded, total)),
                                    global,
                                    ProgressEventBinding::Wrap);
        {
            let event = ev.upcast::<Event>();
            event.init_event(type_, bool::from(can_bubble), bool::from(cancelable));
        }
        ev
    }
    pub fn Constructor(global: &GlobalScope,
                       type_: DOMString,
                       init: &ProgressEventBinding::ProgressEventInit)
                       -> Fallible<DomRoot<ProgressEvent>> {
        let bubbles = EventBubbles::from(init.parent.bubbles);
        let cancelable = EventCancelable::from(init.parent.cancelable);
        let ev = ProgressEvent::new(global, Atom::from(type_), bubbles, cancelable,
                                    init.lengthComputable, init.loaded, init.total);
        Ok(ev)
    }
}

impl ProgressEventMethods for ProgressEvent {
    // https://xhr.spec.whatwg.org/#dom-progressevent-lengthcomputable
    fn LengthComputable(&self) -> bool {
        self.length_computable
    }

    // https://xhr.spec.whatwg.org/#dom-progressevent-loaded
    fn Loaded(&self) -> u64 {
        self.loaded
    }

    // https://xhr.spec.whatwg.org/#dom-progressevent-total
    fn Total(&self) -> u64 {
        self.total
    }

    // https://dom.spec.whatwg.org/#dom-event-istrusted
    fn IsTrusted(&self) -> bool {
        self.event.IsTrusted()
    }
}


text:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
 Copyright 2021 Google LLC

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->
<RaiseFault name="RF-500">
    <FaultResponse>
        <Set>
            <StatusCode>500</StatusCode>
            <Payload contentType="application/json">{"code": "500.99.01", "message": "Internal Error. If persists, check access to apigee.googleapis.com from Apigee runtime"}</Payload>
        </Set>
    </FaultResponse>
</RaiseFault>


text:
namespace fe
{

class IBodyBuilder;

typedef std::vector<sf::Sprite> 	  TSpriteVec;
typedef std::shared_ptr<IBodyBuilder> TBodyBuilderPtr;

class IBodyBuilder
{
private:
	IBodyBuilder(const IBodyBuilder& toCopy);
	IBodyBuilder& operator=(const IBodyBuilder& toCopy);

public:
	IBodyBuilder() 			{}
	virtual ~IBodyBuilder() {}

	virtual bool Build(const TBodyPartVec& bodyParts,
		const sf::Texture& texture, TSpriteVec& bodyOut) = 0;
};

}

#endif


text:
import logging

from __writer import Writer

class StdoutWriter(Writer):
    """Conf: none"""
    def setup(self):
        self.log = logging.getLogger('pycollector')

    def write(self, msg):
        try:
            print "\n[WRITER] message: %s" % msg
            return True
        except Exception, e:
            self.log.error("Can't write in stdout")
            self.log.error(e)
            return False


text:
#ifndef itkFEMElement2DStress_h
#define itkFEMElement2DStress_h

#include "itkFEMElementBase.h"
#include "itkFEMMaterialLinearElasticity.h"

namespace itk
{
namespace fem
{
/**
 * \class Element2DStress
 * \brief Class that is used to define linear elasticity problem in 2D space.
 *
 * This class only defines the physics of the problem. Use his class together
 * with element classes that specify the geometry to fully define the element.
 *
 * You can specify one template parameter:
 *
 *   TBaseClass - Class from which Element2DStress is derived. TBaseClass must
 *                be derived from the Element base class. This enables you
 *                to use this class at any level of element definition.
 *                If not specified, it defaults to the Element base class.
 * \ingroup ITKFEM
 */
template <typename TBaseClass = Element>
class ITK_TEMPLATE_EXPORT Element2DStress : public TBaseClass
{
public:
  /** Standard class type aliases. */
  using Self = Element2DStress;
  using Superclass = TBaseClass;
  using Pointer = SmartPointer<Self>;
  using ConstPointer = SmartPointer<const Self>;

  /** Run-time type information (and related methods). */
  itkTypeMacro(Element2DStress, TBaseClass);

  // Repeat the required type alias and enums from parent class
  using typename Superclass::Float;
  using typename Superclass::MatrixType;
  using typename Superclass::VectorType;

  /**
   * Default constructor only clears the internal storage
   */
  Element2DStress();

  // ////////////////////////////////////////////////////////////////////////
  /*
   * Methods related to the physics of the problem.
   */

  /**
   * Compute the B matrix.
   */
  void
  GetStrainDisplacementMatrix(MatrixType & B, const MatrixType & shapeDgl) const override;

  /**
   * Compute the D matrix.
   */
  void
  GetMaterialMatrix(MatrixType & D) const override;

  /**
   * Compute the mass matrix specific for 2D stress problems.
   */
  void
  GetMassMatrix(MatrixType & Me) const override;

  /**
   * 2D stress elements have 2 DOFs per node.
   */
  unsigned int
  GetNumberOfDegreesOfFreedomPerNode() const override
  {
    return 2;
  }

  /**
   * Get/Set the material properties for the element
   */
  Material::ConstPointer
  GetMaterial() const override
  {
    return dynamic_cast<const Material *>(m_mat);
  }

  void
  SetMaterial(Material::ConstPointer mat_) override
  {
    this->SetMaterialInternal(mat_);
  }
  virtual void
  SetMaterial(Material::Pointer mat_)
  {
    this->SetMaterialInternal(mat_);
  }

protected:
  void
  PrintSelf(std::ostream & os, Indent indent) const override;

  /**
   * Pointer to material properties of the element
   */
  const MaterialLinearElasticity * m_mat{ nullptr };
  virtual void
  SetMaterialInternal(const Material * mat_)
  {
    m_mat = dynamic_cast<const MaterialLinearElasticity *>(mat_);
  }
};

} // end namespace fem
} // end namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
#  include "itkFEMElement2DStress.hxx"
#endif

#endif // itkFEMElement2DStress_h


text:
from django_th.models import ServicesActivated
from django_th.tests.test_main import MainTest
from django_th.templatetags.django_th_extras import service_readable_class, \
    service_readable, trigger_disabled

class TemplateTagsTest(MainTest):

    def test_service_readable_class(self):
        self.create_triggerservice(consumer_name="ServiceWallabag",
                                   status=True)
        service = ServicesActivated.objects.get(name="ServiceWallabag")
        self.assertTrue(type(service_readable_class(service)) is str)

    def test_service_readable(self):
        self.create_triggerservice(consumer_name="ServiceWallabag",
                                   status=True)
        service = ServicesActivated.objects.get(name="ServiceWallabag")
        self.assertTrue('Service' not in service_readable(service))

    def test_trigger_disabled(self):
        trigger = self.create_triggerservice(service_status=False)
        self.assertTrue(type(trigger_disabled(trigger)) is str)

    def test_trigger_disabled2(self):
        trigger = self.create_triggerservice(consumer_name="ServiceWallabag",
                                             status=False,
                                             service_status=True)
        self.assertTrue(type(trigger_disabled(trigger)) is str)


text:
<title>
Inside Socialist Worker
</title>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<?php include "../../legacy-includes/Script.htmlf" ?>

<?php include "../../legacy-includes/TopLogo.htmlf" ?>

<?php include "../../legacy-includes/TopAd.htmlf" ?>

<?php include "../../legacy-includes/LeftButtons.htmlf" ?>

April 5, 2002 | Issue 401

FRONT AND BACK PAGES

"No one is safe from this terror"

Stop Israel's war on the Palestinians

Israeli Prime Minister Ariel Sharon has declared an all-out war on Palestinians. And his first target was Palestinian Authority leader Yasser Arafat.

Jobs and benefits slashed while the CEOs cash in

"Where am I going to work?"

The 20,000 workers who got pink slips from United Airlines last fall are scrambling to make ends meet. But one person who lost his job at United doesn't have to worry. He's James Goodwin, the former CEO who was forced to resign in disgrace--but still got a $5.7 million severance package.

ISRAEL'S REIGN OF TERROR

A call to action from besieged Ramallah:

"Raise your voices right now"

Toufic Haddad is a Palestinian living in Ramallah and co-editor of the left-wing journal Between the Lines. He spoke with Socialist Worker as Israeli soldiers besieged Yasser Arafat's compound not far from his home.

Israel's cruel reign of terror

The U.S. mantra that Yasser Arafat "must make a 100 percent effort to fight terrorism" is a way of avoiding the main issue and the true source of violence--Israel's daily humiliation and intimidation of hundreds of thousands of Palestinians living under its military occupation.

Suicide attacks "borne of despair"

The Israeli government claims that Palestinian suicide bombings are proof of the fanaticism they must defend against. But in reality, these Palestinian attacks are a product of hopelessness and despair--in the face of Israel's military offensive to drown the Palestinian resistance in blood.

SPECIAL FEATURES

A look inside Illinois' broken death penalty system

The real face of death row

Illinois Gov. George Ryan--who two years ago bowed to growing pressure and called a halt on all executions--has said that he will review the cases of all 163 Illinois death row prisoners during his final months in office. What will he learn?

The revolutionary legacy that the media covers up

The real Malcolm X

The recent discovery of letters, diaries and notebooks belonging to Malcolm X has stirred new interest in the man and his politics. But establishment voices that treat Malcolm X as a saint today seek to bury his real legacy of revolutionary internationalism and anti-imperialism.

Back to the top

WHAT WE THINK

U.S. bears responsibility for Israel's savage crackdown

The monster that Washington created

When reporters asked George W. Bush about the solution to the Israel-Palestine conflict on Monday, he sputtered: "There needs to be a focused coalition effort in the region against peace--I mean, against terror, for peace." He was more truthful the first time.

Supreme Court rules against rights of illegal immigrants

An attack on all workers

Illegal immigrants don't count as human beings. That's the message that the U.S. Supreme Court sent last week when it ruled in a 5-4 vote that illegal immigrants aren't entitled to legal protection when they are wrongly fired from their jobs.

SW turns 25

Socialist Worker turns 25 years old this month. That's a quarter century of reporting on struggles throughout U.S. society--the stories of working people that don't make it into the mainstream media.

Back to the top

NATIONAL NEWS

S.F. cops' sick attack on four youths

Standing up to police brutality

Residents of the Bay View Hunters Point neighborhood in San Francisco are coming together to say no to police brutality.

Plea from a prisoner held at Guantánamo Bay:

"Can you tell the world about us?"

When journalists toured Camp X-Ray, the U.S. prison camp in Guantánamo Bay, Cuba, in March, one prisoner tried desperately to attract their attention. "We've been on a hunger strike for 14 days, and nobody cares," he called out. "Can you tell the world about us?"

New study exposes racism

The back of the health care bus

"The medical world just reflects the real world." That's how one African American patient summed up the reality of the health care system--a reality reflected in the findings of a report released last month that found that minorities in the U.S. consistently receive lower quality health care than whites.

Justices uphold war on drugs in public housing

The U.S. Supreme Court ruled unanimously last week that public housing officials can evict tenants for drug use by family members--whether or not the tenants know about it, and even if it occurs off public housing property.

Back to the top

COLUMNS

WHICH SIDE ARE YOU ON?

Confronting the crime of slavery in the U.S.

In 1865, the U.S. government promised every freed slave 40 acres of tillable land, known as the "40 Acres and a Mule Proclamation." That was the last time the U.S. government gave any thought to compensating African Americans for 300 years of slavery. The reparations movement is now forcing the political establishment to reconsider.

THE MEANING OF MARXISM

Why do they tell lies about Lenin?

The Russian revolutionary Lenin is perhaps the most misunderstood, maligned and lied-about figure in history. If you learn about him at all, you're likely to hear that Lenin was a violent conspirator and a fanatical dictator.

INSIDE THE SYSTEM

Birdbrained logic

When environmental groups filed a lawsuit claiming that the Navy's bombing and shelling exercises on the tiny Pacific island of Farallon de Medinilla was killing the native bird population, Navy officials insisted that dropping bombs on the island is actually good--for both birds and bird-watchers.

Back to the top

ON THE PICKET LINE

New DC 37 leaders still silent on contract showdown

AFSCME shake-up in NYC

As the contract between 135,000 AFSCME District Council 37 union members and the New York City government nears its June 30 deadline, the uproar in the union grows more intense.

Defend immigrant workers

Immigration and Naturalization Service agents raided San Francisco and San Jose International Airports last week, arresting 25 service workers for immigration violations--as part of a nationwide sweep of airports that began following September 11.

Berkeley teachers

In response to deep cuts by the Berkeley Unified School District because of years of gross budget mismanagement, members of the Berkeley Federation of Teachers are preparing to fight for their jobs, their programs and better teaching conditions.

State of Wisconsin

"Enough is enough!" shouted more than 1,000 state workers who were protesting the proposed state budget cuts at the Wisconsin State Capitol on March 28.

Back to the top

REPORTS FROM THE STRUGGLE

Thousands show their outrage at Israeli repression

We want justice for Palestinians!

Thousands of people across the country took to the streets March 30 to commemorate Palestinian Land Day--the day 26 years ago that Israeli soldiers killed six Palestinians protesting the confiscation of their land. But Israel's stepped-up war in Ramallah and elsewhere gave the events added urgency.

Free Rabih Haddad

The Justice Department has provided no credible evidence that either Rabih Haddad or the Global Relief Foundation are connected to "terrorists." But that isn't stopping them from trying.

Back to the top

SW READERS SPEAK OUT

D.C. families don't have a decent place to live

This housing crisis kills

The Washington metro area is facing a housing crisis that is leaving thousands of families without a decent place to live. This situation doesn't just increase homelessness. It kills.

We won't be intimidated or silenced by police

We're members of the ISO in Albany, Ga., a very conservative area in southwest Georgia. We found out just how conservative after our meeting last week.

They say the recession's over?

I am an unemployed white-collar worker currently living in Northern California. As someone who has been laid off--twice--in the past year, I get really burned when I hear politicians saying that the recession "never really happened."

Back to the top

REVIEWS

Past struggles with lessons for today

THREE STRIKES is a wonderful book that recounts three important labor struggles from the first half of the century.

Ozomatli's catchy call to be active

It seems like every time you go to a meeting to organize a protest here in Southern California, someone says, "We should see if we can get Ozomatli to play!" And for good reason.

<?php include "../../legacy-includes/BottomNavLinks.htmlf" ?>

<?php include "../../legacy-includes/RightAdFolder.htmlf" ?>


text:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by org.testng.reporters.JUnitReportReporter -->
<testsuite hostname="PC-SBARANOVA" name="product.Wishlist" tests="1" failures="0" timestamp="19 Mar 2015 10:15:17 GMT" time="60.417" errors="0">
  <testcase name="Wishlist" time="60.417" classname="product.Wishlist"/>
</testsuite> <!-- product.Wishlist -->


text:
require 'spec_helper'

describe Spongecms::Configuration do
end