ipsec_info.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _INET_IPSEC_INFO_H
#define _INET_IPSEC_INFO_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/crypto/common.h>
/*
* IPsec informational messages. These are M_CTL STREAMS messages, which
* convey IPsec information between various IP and related modules. The
* messages come in a few flavors:
*
* * IPSEC_{IN,OUT} - These show what IPsec action have been taken (for
* inbound datagrams), or need to be taken (for outbound datagrams).
* They flow between AH/ESP and IP.
*
* * Keysock consumer interface - These messages are wrappers for
* PF_KEY messages. They flow between AH/ESP and keysock.
*/
/* EXPORT DELETE START */ /* CRYPT DELETE START */
#if 0
/*
* I obscure the ipsec_info "prefix" for purposes of export control, and
* domestic source distribution.
*/
/* EXPORT DELETE END */ /* CRYPT DELETE END */
/*
* The IPsec M_CTL value MUST be something that will not be even close
* to an IPv4 or IPv6 header. This means the first byte must not be
* 0x40 - 0x4f or 0x60-0x6f. For big-endian machines, this is fixable with
* the IPSEC_M_CTL prefix. For little-endian machines, the actual M_CTL
* _type_ must not be in the aforementioned ranges.
*
* The reason for this avoidance is because M_CTL's with a real IPv4/IPv6
* datagram get sent from to TCP or UDP when an ICMP datagram affects a
* TCP/UDP session.
*/
#define IPSEC_M_CTL (('!' << 24) + ('@' << 16) + ('@' << 8))
/* EXPORT DELETE START */ /* CRYPT DELETE START */
#else
#define IPSEC_M_CTL 0x7dfaae00
#endif /* False */
/* EXPORT DELETE END */ /* CRYPT DELETE END */
/*
* M_CTL types for IPsec messages. Remember, the values 0x40 - 0x4f and 0x60
* - 0x6f are not to be used because of potential little-endian confusion.
*
* Offsets 1-25 (decimal) are in use, spread through this file.
* Check for duplicates through the whole file before adding.
*/
/*
* IPSEC_{IN,OUT} policy expressors.
*/
#define IPSEC_IN (IPSEC_M_CTL + 1)
#define IPSEC_OUT (IPSEC_M_CTL + 2)
/*
* This is used for communication between IP and IPSEC (AH/ESP)
* for Inbound datagrams. IPSEC_IN is allocated by IP before IPSEC
* processing begins. On return spi fields are initialized so that
* IP can locate the security associations later on for doing policy
* checks. For loopback case, IPSEC processing is not done. But the
* attributes of the security are reflected in <foo>_done fields below.
* The code in policy check infers that it is a loopback case and
* would not try to get the associations.
*/
typedef struct ipsec_in_s {
uint32_t ipsec_in_type;
uint32_t ipsec_in_len;
frtn_t ipsec_in_frtn; /* for esballoc() callback */
struct ipsa_s *ipsec_in_ah_sa; /* SA for AH */
struct ipsa_s *ipsec_in_esp_sa; /* SA for ESP */
struct ipsec_policy_head_s *ipsec_in_policy;
struct ipsec_action_s *ipsec_in_action; /* how we made it in.. */
unsigned int
ipsec_in_secure : 1, /* Is the message attached secure ? */
ipsec_in_v4 : 1, /* Is this an ipv4 packet ? */
ipsec_in_loopback : 1, /* Is this a loopback request ? */
ipsec_in_dont_check : 1, /* Used by TCP to avoid policy check */
ipsec_in_decaps : 1, /* Was this packet decapsulated from */
/* a matching inner packet? */
ipsec_in_attach_if : 1, /* Don't load spread this packet */
ipsec_in_accelerated : 1, /* hardware accelerated packet */
ipsec_in_icmp_loopback : 1, /* Looped-back ICMP packet, */
/* all should trust this. */
ipsec_in_pad_bits : 24;
int ipsec_in_ill_index; /* interface on which ipha_dst was */
/* configured when pkt was recv'd */
int ipsec_in_rill_index; /* interface on which pkt was recv'd */
mblk_t *ipsec_in_da; /* data attr. for accelerated pkts */
/*
* For call to the kernel crypto framework. State needed during
* the execution of a crypto request. Storing these here
* allow us to avoid a separate allocation before calling the
* crypto framework.
*/
size_t ipsec_in_skip_len; /* len to skip for AH auth */
crypto_data_t ipsec_in_crypto_data; /* single op crypto data */
crypto_dual_data_t ipsec_in_crypto_dual_data; /* for dual ops */
crypto_data_t ipsec_in_crypto_mac; /* to store the MAC */
zoneid_t ipsec_in_zoneid; /* target zone for the datagram */
#ifdef DEBUG
/*
* To aid in IPSEC_IN leak detection, save a copy of the inbound IPsec
* header in DEBUG kernels. It takes no more space overall because
* ipsec_info_t is more than sizeof (IPv4 or IPv6) bytes larger than
* ipsec_in_t. (60 bytes was chosen as a nice safe number. Using
* an IP or IPv6 constant increases the header file count for
* consumers of this header file.)
*/
uint8_t ipsec_in_saved_hdr[60];
#endif
} ipsec_in_t;
/*
* This is used for communication between IP and IPSEC (AH/ESP)
* for Outbound datagrams. IPSEC_OUT is allocated by IP before IPSEC
* processing begins. On return SA fields are initialized so that
* IP can locate the security associations later on for doing policy
* checks. The policy and the actions associated with this packet are
* stored in the ipsec_out_policy and ipsec_out_act fields respectively.
* IPSEC_OUT is also used to carry non-ipsec information when conn is
* absent or the conn information is lost across the calls to ARP.
* example: message from ARP or from ICMP error routines.
*/
typedef struct ipsec_out_s {
uint32_t ipsec_out_type;
uint32_t ipsec_out_len;
frtn_t ipsec_out_frtn; /* for esballoc() callback */
struct ipsec_policy_head_s *ipsec_out_polhead;
ipsec_latch_t *ipsec_out_latch;
struct ipsec_policy_s *ipsec_out_policy; /* why are we here? */
struct ipsec_action_s *ipsec_out_act; /* what do we want? */
struct ipsa_s *ipsec_out_ah_sa; /* AH SA used for the packet */
struct ipsa_s *ipsec_out_esp_sa; /* ESP SA used for the packet */
/*
* NOTE: "Source" and "Dest" are w.r.t. outbound datagrams. Ports can
* be zero, and the protocol number is needed to make the ports
* significant.
*/
uint16_t ipsec_out_src_port; /* Source port number of d-gram. */
uint16_t ipsec_out_dst_port; /* Destination port number of d-gram. */
uint8_t ipsec_out_icmp_type; /* ICMP type of d-gram */
uint8_t ipsec_out_icmp_code; /* ICMP code of d-gram */
uint_t ipsec_out_ill_index; /* ill index used for multicast etc. */
uint8_t ipsec_out_proto; /* IP protocol number for d-gram. */
unsigned int
ipsec_out_encaps : 1, /* Encapsualtion done ? */
ipsec_out_use_global_policy : 1, /* Inherit global policy ? */
ipsec_out_secure : 1, /* Is this secure ? */
ipsec_out_proc_begin : 1, /* IPSEC processing begun */
/*
* Following five values reflects the values stored
* in conn.
*/
ipsec_out_multicast_loop : 1,
ipsec_out_dontroute : 1,
ipsec_out_reserved : 1,
ipsec_out_v4 : 1,
ipsec_out_attach_if : 1,
ipsec_out_unspec_src : 1, /* IPv6 ip6i_t info */
ipsec_out_reachable : 1, /* NDP reachability info */
/*
* Following bit is used by ip_mrtun_forward to convey
* xmit_ill information along with ICMP error msg
*/
ipsec_out_xmit_if: 1,
ipsec_out_failed: 1,
ipsec_out_se_done: 1,
ipsec_out_esp_done: 1,
ipsec_out_ah_done: 1,
ipsec_out_need_policy: 1,
/*
* To indicate that packet must be accelerated, i.e.
* ICV or encryption performed, by Provider.
*/
ipsec_out_accelerated : 1,
/*
* Used by IP to tell IPsec that the outbound ill for this
* packet supports acceleration of the AH or ESP prototocol.
* If set, ipsec_out_capab_ill_index contains the
* index of the ill.
*/
ipsec_out_is_capab_ill : 1,
/*
* Indicates ICMP message destined for self. These
* messages are to be trusted by all receivers.
*/
ipsec_out_icmp_loopback: 1,
ipsec_out_pad_bits : 12;
cred_t *ipsec_out_cred;
uint32_t ipsec_out_capab_ill_index;
/*
* For call to the kernel crypto framework. State needed during
* the execution of a crypto request. Storing these here
* allow us to avoid a separate allocation before calling the
* crypto framework.
*/
size_t ipsec_out_skip_len; /* len to skip for AH auth */
crypto_data_t ipsec_out_crypto_data; /* single op crypto data */
crypto_dual_data_t ipsec_out_crypto_dual_data; /* for dual ops */
crypto_data_t ipsec_out_crypto_mac; /* to store the MAC */
zoneid_t ipsec_out_zoneid; /* source zone for the datagram */
} ipsec_out_t;
/*
* This is used to mark the ipsec_out_t *req* fields
* when the operation is done without affecting the
* requests.
*/
#define IPSEC_REQ_DONE 0x80000000
/*
* Operation could not be performed by the AH/ESP
* module.
*/
#define IPSEC_REQ_FAILED 0x40000000
/*
* Keysock consumer interface.
*
* The driver/module keysock (which is a driver to PF_KEY sockets, but is
* a module to 'consumers' like AH and ESP) uses keysock consumer interface
* messages to pass on PF_KEY messages to consumers who process and act upon
* them.
*/
#define KEYSOCK_IN (IPSEC_M_CTL + 3)
#define KEYSOCK_OUT (IPSEC_M_CTL + 4)
#define KEYSOCK_OUT_ERR (IPSEC_M_CTL + 5)
#define KEYSOCK_HELLO (IPSEC_M_CTL + 6)
#define KEYSOCK_HELLO_ACK (IPSEC_M_CTL + 7)
/*
* KEYSOCK_HELLO is sent by keysock to a consumer when it is pushed on top
* of one (i.e. opened as a module).
*
* NOTE: Keysock_hello is simply an ipsec_info_t
*/
/*
* KEYSOCK_HELLO_ACK is sent by a consumer to acknowledge a KEYSOCK_HELLO.
* It contains the PF_KEYv2 sa_type, so keysock can redirect PF_KEY messages
* to the right consumer.
*/
typedef struct keysock_hello_ack_s {
uint32_t ks_hello_type;
uint32_t ks_hello_len;
uint8_t ks_hello_satype; /* PF_KEYv2 sa_type of ks client */
} keysock_hello_ack_t;
#define KS_IN_ADDR_UNKNOWN 0
#define KS_IN_ADDR_NOTTHERE 1
#define KS_IN_ADDR_UNSPEC 2
#define KS_IN_ADDR_ME 3
#define KS_IN_ADDR_NOTME 4
#define KS_IN_ADDR_MBCAST 5
/*
* KEYSOCK_IN is a PF_KEY message from a PF_KEY socket destined for a consumer.
*/
typedef struct keysock_in_s {
uint32_t ks_in_type;
uint32_t ks_in_len;
/*
* NOTE: These pointers MUST be into the M_DATA that follows
* this M_CTL message. If they aren't, weirdness
* results.
*/
struct sadb_ext *ks_in_extv[SADB_EXT_MAX + 1];
int ks_in_srctype; /* Source address type. */
int ks_in_dsttype; /* Dest address type. */
int ks_in_proxytype; /* Proxy address type. */
minor_t ks_in_serial; /* Serial # of sending socket. */
} keysock_in_t;
/*
* KEYSOCK_OUT is a PF_KEY message from a consumer destined for a PF_KEY
* socket.
*/
typedef struct keysock_out_s {
uint32_t ks_out_type;
uint32_t ks_out_len;
minor_t ks_out_serial; /* Serial # of sending socket. */
} keysock_out_t;
/*
* KEYSOCK_OUT_ERR is sent to a consumer from keysock if for some reason
* keysock could not find a PF_KEY socket to deliver a consumer-originated
* message (e.g. SADB_ACQUIRE).
*/
typedef struct keysock_out_err_s {
uint32_t ks_err_type;
uint32_t ks_err_len;
minor_t ks_err_serial;
int ks_err_errno;
/*
* Other, richer error information may end up going here eventually.
*/
} keysock_out_err_t;
/*
* M_CTL message type for sending inbound pkt information between IP & ULP.
* These are _not_ related to IPsec in any way, but are here so that there is
* one place where all these values are defined which makes it easier to track.
* The choice of this value has the same rationale as explained above.
*/
#define IN_PKTINFO (IPSEC_M_CTL + 24)
/*
* IPSEC_CTL messages are used by IPsec to send control type requests
* to IP. Such a control message is currently used by IPsec to request
* that IP send the contents of an IPsec SA or the entire SADB to
* every IPsec hardware acceleration capable provider.
*/
#define IPSEC_CTL (IPSEC_M_CTL + 25)
typedef struct ipsec_ctl_s {
uint32_t ipsec_ctl_type;
uint32_t ipsec_ctl_len;
uint_t ipsec_ctl_sa_type;
void *ipsec_ctl_sa;
} ipsec_ctl_t;
/*
* All IPsec informational messages are placed into the ipsec_info_t
* union, so that allocation can be done once, and IPsec informational
* messages can be recycled.
*/
typedef union ipsec_info_u {
struct {
uint32_t ipsec_allu_type;
uint32_t ipsec_allu_len; /* In bytes */
} ipsec_allu;
ipsec_in_t ipsec_in;
ipsec_out_t ipsec_out;
keysock_hello_ack_t keysock_hello_ack;
keysock_in_t keysock_in;
keysock_out_t keysock_out;
keysock_out_err_t keysock_out_err;
ipsec_ctl_t ipsec_ctl;
} ipsec_info_t;
#define ipsec_info_type ipsec_allu.ipsec_allu_type
#define ipsec_info_len ipsec_allu.ipsec_allu_len
#ifdef __cplusplus
}
#endif
#endif /* _INET_IPSEC_INFO_H */