Here's what I have so far. With the event replacement changes in the patch, ipsecdoi_replace initiates and sends a new Parent SA when the old one expires. The rekeymargin options also don't seem to work with IKEv2 (since it's not negotiated?) so I needed a hack to delay the delete event otherwise it goes right out after the first IKE message on the rekey.
So we get to ikev2parent_outI1 to rekey. I don't understand the policy part of this in regards to the addition of a pending state, as it seems that we need our new SA's to pend until they are established and the code later on expects that it can find a pending state. It does: if (HAS_IPSEC_POLICY(policy)) { #ifdef HAVE_LABELED_IPSEC st->sec_ctx = NULL; if ( uctx != NULL) libreswan_log( "Labeled ipsec is not supported with ikev2 yet"); #endif add_pending(dup_any(whack_sock), st, c, policy, 1, predecessor == NULL ? SOS_NOBODY : predecessor->st_serialno #ifdef HAVE_LABELED_IPSEC , st->sec_ctx #endif ); Before we rekey the IPSEC part of the policy is removed. So this is confusing and I work around it in the patch. Now we rekey: May 28 15:45:15 west pluto[16030]: | event after this is EVENT_PENDING_DDNS in 3 seconds May 28 15:45:15 west pluto[16030]: | processing connection rekey May 28 15:45:15 west pluto[16030]: "rekey" #1: replacing stale ISAKMP SA May 28 15:45:15 west pluto[16030]: | creating state object #3 at 0x7f64366d6630 May 28 15:45:15 west pluto[16030]: | processing connection rekey May 28 15:45:15 west pluto[16030]: | ICOOKIE: f0 48 39 19 c8 3c 58 e8 May 28 15:45:15 west pluto[16030]: | RCOOKIE: 00 00 00 00 00 00 00 00 May 28 15:45:15 west pluto[16030]: | state hash entry 20 May 28 15:45:15 west pluto[16030]: | inserting state object #3 May 28 15:45:15 west pluto[16030]: | inserting event EVENT_SO_DISCARD, timeout in 0 seconds for #3 May 28 15:45:15 west pluto[16030]: | event added at head of queue May 28 15:45:15 west pluto[16030]: | processing connection rekey May 28 15:45:15 west pluto[16030]: | Queuing pending Quick Mode with 192.168.1.113 "rekey" May 28 15:45:15 west pluto[16030]: "rekey" #3: initiating v2 parent SA to replace #1 v2R1 comes back and: May 28 15:45:16 west pluto[16030]: | PSK auth octets cf 29 10 e6 1d 7b bc c1 61 8c 38 6b 6d e4 47 0d May 28 15:45:16 west pluto[16030]: | emitting 16 raw bytes of PSK auth into IKEv2 Authentication Payload May 28 15:45:16 west pluto[16030]: | PSK auth cf 29 10 e6 1d 7b bc c1 61 8c 38 6b 6d e4 47 0d May 28 15:45:16 west pluto[16030]: | emitting length of IKEv2 Authentication Payload: 24 May 28 15:45:16 west pluto[16030]: | kernel_alg_db_new() initial trans_cnt=0 May 28 15:45:16 west pluto[16030]: | kernel_alg_db_new() will return p_new->protoid=0, p_new->trans_cnt=0 May 28 15:45:16 west pluto[16030]: | returning new proposal from esp_info May 28 15:45:16 west pluto[16030]: | *****emit IKEv2 Security Association Payload: May 28 15:45:16 west pluto[16030]: | next payload type: ISAKMP_NEXT_v2TSi May 28 15:45:16 west pluto[16030]: | critical bit: none May 28 15:45:16 west pluto[16030]: | netlink_get_spi: allocated 0xf99f3a87 for esp.0@192.168.1.112 <crash> :( Program received signal SIGSEGV, Segmentation fault. ikev2_out_sa (outs=outs@entry=0x7fffb9898920, protoid=protoid@entry=3, sadb=0x7f1e871eb330, st=0x7f1e871f1c50, parentSA=parentSA@entry=0, np=np@entry=44 ',') at /root/libreswan-test/programs/pluto/ikev2_spdb_struct.c:149 (gdb) bt #0 ikev2_out_sa (outs=outs@entry=0x7fffb9898920, protoid=protoid@entry=3, sadb=0x7f1e871eb330, st=0x7f1e871f1c50, parentSA=parentSA@entry=0, np=np@entry=44 ',') at /root/libreswan-test/programs/pluto/ikev2_spdb_struct.c:149 #1 0x00007f1e86529485 in ikev2_emit_ipsec_sa (md=md@entry=0x7f1e871c6aa0, outpbs=outpbs@entry=0x7fffb9898920, np=np@entry=44, c=c@entry=0x7f1e871c00c0, policy=<optimized out>) at /root/libreswan-test/programs/pluto/ikev2_spdb_struct.c:175 8 #2 0x00007f1e86521cd4 in ikev2_parent_inR1outI2_tail (pcrc=pcrc@entry=0x7f1e871ecad0, r=r@entry=0x7fffb9898b70) at /root/libreswan-test/programs/pluto/ikev2_parent.c:1625 #3 0x00007f1e86522005 in ikev2_parent_inR1outI2_continue (pcrc=0x7f1e871ecad0, r=0x7fffb9898b70, ugh=<optimized out>) at /root/libreswan-test/programs/pluto/ikev2_parent.c:1168 This happens at: 144| for (pc_cnt = 0; pc_cnt < sadb->prop_disj_cnt; pc_cnt++) { 145| struct db_v2_prop *vp = &sadb->prop_disj[pc_cnt]; 146| unsigned int pr_cnt; 147| 148| /* now send out all the transforms */ 149+> for (pr_cnt = 0; pr_cnt < vp->prop_cnt; pr_cnt++) { 150| unsigned int ts_cnt; 151| struct db_v2_prop_conj *vpc = &vp->props[pr_cnt]; (gdb) p vp $1 = (struct db_v2_prop *) 0x0 (gdb) p *sadb $4 = { dynamic = 1, parentSA = 0, prop_conjs = 0x7f1e871f56c0, prop_conj_cnt = 1, prop_disj = 0x0, prop_disj_cnt = 1 } I can't tell why the prop_disj data is missing here. Any ideas? While IKEv2 rekeying without a CREATE_CHILD_SA seems hacky enough so I don't want to butcher this too much :) Matt
diff --git a/include/pluto_constants.h b/include/pluto_constants.h index 88fa7ab..b0e174b 100644 --- a/include/pluto_constants.h +++ b/include/pluto_constants.h @@ -437,6 +437,10 @@ enum phase1_role { #define IS_PARENT_SA(st) (!IS_CHILD_SA(st)) +#define V1_V2_IKESA(st) (IS_PHASE1(st->st_state) || \ + IS_PHASE15(st->st_state) || \ + IS_PARENT_SA(st)) + /* kind of struct connection * Ordered (mostly) by concreteness. Order is exploited. */ diff --git a/programs/pluto/ikev2_parent.c b/programs/pluto/ikev2_parent.c index 324610c..ed5868f 100644 --- a/programs/pluto/ikev2_parent.c +++ b/programs/pluto/ikev2_parent.c @@ -124,7 +124,7 @@ stf_status ikev2parent_outI1(int whack_sock, st->st_msgid_nextuse = 0; st->st_try = try; - if (HAS_IPSEC_POLICY(policy)) { + if (HAS_IPSEC_POLICY(policy) || predecessor != NULL) { #ifdef HAVE_LABELED_IPSEC st->sec_ctx = NULL; if ( uctx != NULL) diff --git a/programs/pluto/timer.c b/programs/pluto/timer.c index 1e919b0..7d94944 100644 --- a/programs/pluto/timer.c +++ b/programs/pluto/timer.c @@ -627,11 +627,11 @@ void handle_next_timer_event(void) { struct connection *c; so_serial_t newest; + time_t margin; passert(st != NULL); c = st->st_connection; - newest = (IS_PHASE1(st->st_state) || - IS_PHASE15(st->st_state )) ? + newest = V1_V2_IKESA(st) ? c->newest_isakmp_sa : c->newest_ipsec_sa; if (newest > st->st_serialno && @@ -640,9 +640,8 @@ void handle_next_timer_event(void) DBG(DBG_LIFECYCLE, libreswan_log( "not replacing stale %s SA: #%lu will do", - (IS_PHASE1(st->st_state) || - IS_PHASE15(st->st_state )) ? - "ISAKMP" : "IPsec", newest)); + V1_V2_IKESA(st) ? + "ISAKMP" : "IPsec", newest)); } else if (type == EVENT_SA_REPLACE_IF_USED && st->st_outbound_time <= tm - c->sa_rekey_margin) { /* @@ -666,22 +665,26 @@ void handle_next_timer_event(void) DBG(DBG_LIFECYCLE, libreswan_log( "not replacing stale %s SA: inactive for %lus", - (IS_PHASE1(st->st_state) || - IS_PHASE15(st->st_state )) ? - "ISAKMP" : "IPsec", + V1_V2_IKESA(st) ? "ISAKMP" : "IPsec", (unsigned long)(tm - st->st_outbound_time))); } else { DBG(DBG_LIFECYCLE, libreswan_log("replacing stale %s SA", - (IS_PHASE1(st->st_state) || - IS_PHASE15(st->st_state)) ? - "ISAKMP" : "IPsec")); + V1_V2_IKESA(st) ? + "ISAKMP" : "IPsec")); ipsecdoi_replace(st, LEMPTY, LEMPTY, 1); } delete_liveness_event(st); delete_dpd_event(st); - event_schedule(EVENT_SA_EXPIRE, st->st_margin, st); + + /* XXX hack - get around st->st_margin being 0 here on ikev2 rekey for the moment */ + if (st->st_ikev2 && st->st_margin < 1) + margin = 10; + else + margin = st->st_margin; + + event_schedule(EVENT_SA_EXPIRE, margin, st); } break; @@ -694,7 +697,7 @@ void handle_next_timer_event(void) passert(st != NULL); c = st->st_connection; - if (IS_PHASE1(st->st_state) || IS_PHASE15(st->st_state)) { + if (V1_V2_IKESA(st)) { satype = "ISAKMP"; latest = c->newest_isakmp_sa; } else {
_______________________________________________ Swan-dev mailing list Swan-dev@lists.libreswan.org https://lists.libreswan.org/mailman/listinfo/swan-dev