I'm sponsoring the following case for Thejaswini Singarajipura. Timer expires on 8/21/2008. This case has a Patch/Micro release binding to permit inclusion in a Solaris 10 Update release.
See interface table for stability levels; there is a (draft) contract for a Contracted Consolidation Private interface in the case directory. (and I'll be rounding up signatures on the contract shortly). Description: ------------ Solaris Cluster (SC), a HA offering from Sun, provides a load balancing, highly available and scalable data service. A scalable data service has several instances of the application running on a subset of the nodes of the cluster. Together these nodes provide a single service image to the remote client. When a node fails, the client connections which are serviced by the other nodes will face no interruptions. If there were service instances on the failed node, the service instance will be broken on the client side if TCP. The client then has to restart the request. This helps in reducing the service down time. The HA feature of Solaris Cluster cannot be supported for IPsec enabled service. IPsec works well on a single node. If a node fails, all IPsec Security Associations (SAs) as defined in RFC 2401, are lost and have to be regenerated on the new node and increases the service down time. If the SAs are synchronized on all the nodes of the SC which service the scalable service, the client can start a new connection after a node failure and the new node servicing the client can use the synchronized SA for the communication. Proposal: --------- The PF_KEY(7P) socket will be extended to facilitate the synchronization of the SA to the other nodes of the cluster The Solaris provided Key management mechanisms ipseckey(1M) and in.iked(1M) will be modified to make use of these new changes. Solaris sadb will be changed to contact Solaris Cluster for the SPI allocation. The in.iked will be modified to provide a method of detecting dead IKE peer as defined in RFC 3706. The project private ipsa_t structure, defined in usr/src/uts/common/inet/sadb.h will be extended to include the changes. These changes are tracked by CRs 6545486,6398024,6558870. Details: -------- The following changes are proposed to pfkeyv2.h: New sadb_x_replay_ctr structure: typedef struct sadb_x_replay_ctr { uint16_t sadb_x_rc_len; uint16_t sadb_x_rc_exttype; uint32_t sadb_x_rc_replay32; /* For 240x SAs. */ uint64_t sadb_x_rc_replay64; /* For 430x SAs. */ } sadb_x_replay_ctr_t; The new extension header contains the sequence number of the SA. The extension header is used to get or update the sequence number of the SA. Once we update a replay counter, we check off the sequence number of the SA as seen, and the SA will not accept any packet with a sequence number lower than the one we set. Also, when we snapshot the SA's replay counter, that value is the highest-seen replay value. New DUMP extension typedef struct sadb_x_edump { uint16_t sadb_x_edump_len; uint16_t sadb_x_edump_exttype; /* X_EDUMP */ uint32_t sadb_x_edump_reserved; /* Reserved */ uint64_t sadb_x_edump_timeout; /* Timeout interval in seconds */ } sadb_x_edump_t; The extended dump message will dump out all the SAs that are active in the interval specified by sadb_x_edump_timeout. The new extension can be used only with SADB_DUMP message. New PF_KEY message types: #define SADB_X_DELPAIR_STATE 15 The new message type is used to delete all SA pairs that are in the state specified and have a source address specified in the request. New PF_KEY message extensions: #define SADB_X_EXT_REPLAY_VALUE 24 #define SADB_X_EXT_EDUMP 25 #define SADB_X_EXT_LIFETIME_IDLE 26 New SA states #define SADB_X_SASTATE_ACTIVE_ELSEWHERE 2 #define SADB_X_SASTATE_IDLE 3 #define SADB_X_SASTATE_ACTIVE 4 The pf_key man page diffs are as below *** pf_key.orig Tue May 13 03:10:28 2008 --- pf_key.change Tue May 13 03:39:47 2008 *************** *** 120,125 **** --- 120,127 ---- #define SADB_X_EXT_ADDRESS_NATT_REM /* NAT-T remote (peer's private) */ #define SADB_X_EXT_ADDRESS_INNER_SRC /* Tunnel-mode inner source */ #define SADB_X_EXT_ADDRESS_INNER_DST /* Tunnel-mode inner dest */ + #define SADB_X_EXT_REPLAY_VALUE /* Replay Value */ + #define SADB_X_EXT_LIFETIME_IDLE /* Idle lifetime */ *************** *** 162,168 **** Lifetime Extension struct sadb_lifetime { uint16_t sadb_lifetime_len; ! uint16_t sadb_lifetime_exttype; /* SOFT, HARD, CURRENT */ uint32_t sadb_lifetime_allocations; uint64_t sadb_lifetime_bytes; uint64_t sadb_lifetime_addtime; --- 164,170 ---- Lifetime Extension struct sadb_lifetime { uint16_t sadb_lifetime_len; ! uint16_t sadb_lifetime_exttype; /* SOFT, HARD, CURRENT, IDLE */ uint32_t sadb_lifetime_allocations; uint64_t sadb_lifetime_bytes; uint64_t sadb_lifetime_addtime; *************** *** 381,386 **** --- 383,397 ---- }; + Replay Value + struct sadb_x_replay_ctr { + uint16_t sadb_x_rc_len; + uint16_t sadb_x_rc_exttype; + uint32_t sadb_x_rc_replay32; /* For 240x SAs. */ + uint64_t sadb_x_rc_replay64; /* For 430x SAs. */ + }; + + Message Use and Behavior Each message has a behavior. A behavior is defined as where the initial message travels, for example, user to kernel, *************** *** 408,416 **** If all other fields must be ignored, this is represented by SA(*). ! The lifetime extensions are represented with one to three letters after the word lifetime, representing (H)ARD, ! (S)OFT, and (C)URRENT. The address extensions are represented with one to three letters after the word "address," representing (S)RC, (D)ST, --- 419,427 ---- If all other fields must be ignored, this is represented by SA(*). ! The lifetime extensions are represented with one to four letters after the word lifetime, representing (H)ARD, ! (S)OFT, (C)URRENT, and (I)DLE. The address extensions are represented with one to three letters after the word "address," representing (S)RC, (D)ST, *************** *** 474,483 **** Send a SADB_UPDATE message from a user process to the ker- nel. ! <base, SA, (lifetime(HS),) address(SD), (address(Is,Id), ! address(Nl,Nr), key (AE), (identity(SD),) (sensitivity)>c - The kernel returns the SADB_UPDATE message to all listening processes. --- 485,494 ---- Send a SADB_UPDATE message from a user process to the ker- nel. ! <base, SA, (lifetime(HSI),) address(SD), (address(Is,Id), ! address(Nl,Nr), key (AE), (identity(SD),) ! (sensitivity), (replay_value)> The kernel returns the SADB_UPDATE message to all listening processes. *************** *** 487,500 **** SADB_ADD Send a SADB_ADD message from a user process to the kernel. ! <base, SA, (lifetime(HS),) address(SD), (address(Is,Id),) ! | (address(Nl,Nr),) key (AE), (identity(SD),) (sensitivity)> - The kernel returns the SADB_ADD message to all listening processes. ! <base, SA, (lifetime(HS),) address (SD), (address(Is,Id),) | (address(Nl,Nr),) (identity (SD),) (sensitivity)> --- 498,510 ---- SADB_ADD Send a SADB_ADD message from a user process to the kernel. ! <base, SA, (lifetime(HSI),) address(SD), (address(Is,Id),) ! | (address(Nl,Nr),) key (AE), (identity(SD),) (sensitivity)> The kernel returns the SADB_ADD message to all listening processes. ! <base, SA, (lifetime(HSI),) address (SD), (address(Is,Id),) | (address(Nl,Nr),) (identity (SD),) (sensitivity)> *************** *** 533,540 **** ! <base, SA , (lifetime (HSC),) address SD), (address (P),) key (AE), ! (identity (SD),) (sensitivity)> SADB_ACQUIRE --- 543,550 ---- ! <base, SA , (lifetime (HSCI),) address SD), (address (P),) key (AE), ! (identity (SD),) (sensitivity), (replay value)> SADB_ACQUIRE *************** *** 619,627 **** SADB_EXPIRE The kernel sends a SADB_EXPIRE message to all listeners when ! the soft lmit of a security association has been expired. ! <base, SA, lifetime (C and one of HS), address (SD)> SADB_FLUSH --- 629,638 ---- SADB_EXPIRE The kernel sends a SADB_EXPIRE message to all listeners when ! the soft limit or the idle limit of a security association has ! been expired. ! <base, SA, lifetime (C and one of HSI), address (SD)> SADB_FLUSH *************** *** 646,652 **** the sending socket. <base, SA, (lifetime (HSC),) address (SD), (address (Is,Id),) ! | (address (Nl,Nr),) key (AE), (identity (SD),) sensitivity)> To mark the end of a dump a single base header arrives with --- 657,664 ---- the sending socket. <base, SA, (lifetime (HSC),) address (SD), (address (Is,Id),) ! | (address (Nl,Nr),) key (AE), (identity (SD),) sensitivity), ! (replay value)> To mark the end of a dump a single base header arrives with Changes to ipseckey(1M) - The following new keywords have been introduced, their functionality is described in the man page diffs below: *** ipseckey.orig Tue May 13 01:44:15 2008 --- ipseckey.change Tue May 13 01:52:23 2008 *************** *** 298,304 **** --- 298,308 ---- not specified, the value defaults to mature. This exten- sion is used by the add and update commands. + replay_value <number> + Specifies the replay value of the SA. This extension is used + by the add and the update commands. + auth_alg <string>|<number> authalg <string>|<number> *************** *** 403,409 **** --- 407,421 ---- This extension is used by the add and update commands. + idle_addtime <number> + idle_usetime <number> + Specifies the number of seconds that this SA can exist if + the SA is not used before the SA is revalidated. If this + extension is not present, the default value is half of the + hard_addtime. This extension is used by the add and update + commands. + After the expiry of the idle time, the kernel sends an SADB_EXPIRE message with idle time as the trigger. ipseckey(1M) does not handle PF_KEY messages. If we do not have IKE daemon, the SADB_EXPIRE message would be discarded. Changes to the sadb allocation - The hook function in sadb will help us manage the cluster-wide unique SPI. The hook functions are enabled only when Solaris is in cluster mode. There will be very minimal impact when Solaris is running in non cluster mode. void (*cl_inet_getspi)(uint8_t, uint8_t *, size_t) = NULL; This will return the SPI value to be used for the SA association. int (*cl_inet_checkspi)(uint8_t, uint32_t) = NULL; This will check if the SPI exists in the cluster wide repository. void (*cl_inet_deletespi)(uint8_t, uint32_t) = NULL; This will delete the SPI from the cluster wide respository. Changes to IP to move the SA from IDLE state to MATURE state - With the SA synchronization, we have copies of the SA on all the nodes of SC hosting the scalable service. But, the node which has the SA in MATURE state will only service the client. When the node which has the SA in MATURE state fails, the new node which is chosen by the global node to handle the client, will have to have the SA state moved to MATURE state. The hook function will facilitate the move of the SA state from IDLE to MATURE. void (*cl_inet_idlesa)(uint8_t, uint32_t, sa_family_t, in6_addr_t, in6_addr_t) = NULL; The IP module when it receives a packet for the IDLE SA, first verifies the packet with the AH and/or ESP and if successful triggers the hook function to inform the SC module about the valid packet. The SC on the worker node then checks with the global node for the client. The global node maintains a list of clients that have sent packets and the node that the same has been forwarded to. The global node will then compare the client against this list to check if the client packet has indeed been forwarded by it. If it matches, the global node sends a messages to the SC daemon to move the SA from IDLE state to MATURE state. Changes to ike.config(4) - A new IKE rule parameter has been added and its functionality is described in the manpage diffs below. p2_idletime_secs <value> *** ike.config_orig Tue May 13 02:26:28 2008 --- ike.config_change Tue May 13 02:32:49 2008 *************** *** 345,350 **** --- 345,356 ---- p2_softlife_secs is ignored if p2_lifetime_secs is not specified. + p2_idletime_secs num + + The idle lifetime of a phase 2 SA, in seconds. If the value + is specified, the value specifies the lifetime of the SA if + the security association is not used before the SA is + revalidated. ikeadm(1M) get command will also be updated to display the new parameter. Changes to in.iked(1M) - in.iked has been enhanced to provide Dead Peer Detection (DPD) as defined in RFC 3706. The Dead Peer Detection method uses IPsec traffic to minimize the number of IKE message to detect liveliness of the peer. The method uses ongoing valid IPsec traffic between the two as proof of liveliness. If a period of time lapses (as specified by the p2_idletime_secs) during which no packet exchange occurs, the liveliness of the peer is questionable and the node will initiate the DPD exchange. Interfaces: ----------- +----------------------------------+------------------+----------------------+ | Interface Name | Commitment | Comments | | | | | +----------------------------------+------------------+----------------------+ | ipseckey(1m) add/dump/ | Committed | Documented in | | update/get commands | | man pages | | | | | | replay_value | | specify replay value | | idle_addtime | | specify idle timeout | | | | after add. | | idle_usetime | | specify idle timeout | | | | after first use | +----------------------------------+------------------+----------------------+ | pfkeyv2.h | Committed | Documented in | | | | man pages | | sadb_x_replay_ctr | | Replay value ext.hdr | | SADB_X_EXT_REPLAY_VALUE | | Ext type replay | | SADB_X_EXT_LIFETIME_IDLE | | Ext type idle time | +----------------------------------+------------------+----------------------+ | pfkeyv2.h | Project Private | | | | | | | SADB_X_SASTATE_ACTIVE_ELSEWHERE| | | | SADB_X_SASTATE_IDLE | | | | SADB_X_SASTATE_ACTIVE | | | | SADB_X_DELPAIR_STATE | | | | SADB_X_EXT_EDUMP | | | +----------------------------------+------------------+----------------------+ | pfkeyv2.h | Uncommitted | | | | | | | sadb_x_edump | | | +----------------------------------+------------------+----------------------+ | ike.config(4) | Committed | Documented in | | | | man pages | | p2_idletime_secs | | idle timeout in | | | | rule | +----------------------------------+------------------+----------------------+ | ikeadm(1M) get defaults | Committed | | | command | | | | | | | | p2_idletime_secs | | | +----------------------------------+------------------+----------------------+ | IKE Dead Peer Detection | Standard | RFC 3706 | +----------------------------------+------------------+----------------------+ | cl_inet_getspi | Contracted | | | cl_inet_checkspi | Project | | | cl_inet_deletspi | Private | | | cl_inet_idlesa | | | +----------------------------------+------------------+----------------------+