<div dir="ltr">Hi all,<br><br><div class="gmail_extra">any comment about the v2 of the patch?<br><br></div><div class="gmail_extra">Best Regards,<br></div>Christophe<br><br><div class="gmail_extra"><br><br><div class="gmail_quote">
2014-05-27 16:30 GMT+02:00 Christophe Gouault <span dir="ltr"><<a href="mailto:christophe.gouault@6wind.com" target="_blank">christophe.gouault@6wind.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
From: Zheng Zhong <<a href="mailto:zhong.zheng@6wind.com">zhong.zheng@6wind.com</a>><br>
<div class=""><br>
Make replay window configurable per connection.<br>
<br>
</div><div class="">A new ipsec.conf option is available in the conn section:<br>
    replay_window 32<br>
<br>
If unset, then the default value from strongswan.conf is used<br>
(charon.replay_window).<br>
<br>
The replay window size is now available to all kernel interface<br>
implementations.<br>
<br>
Signed-off-by: Zheng Zhong <<a href="mailto:zhong.zheng@6wind.com">zhong.zheng@6wind.com</a>><br>
Signed-off-by: Christophe Gouault <<a href="mailto:christophe.gouault@6wind.com">christophe.gouault@6wind.com</a>><br>
---<br>
</div>v1 -> v2:<br>
<div><div class="h5"><br>
- child_cfg.replay_window is now the actual window size, the magic<br>
  value -1 is only used by stroke.<br>
- update add_sa method of formerly missed kernel interface<br>
  implementations (tkm, libandroidbridge, libipsec, load_tester)<br>
- make replay_window size available to all kernel interface<br>
  implementations.<br>
- cleanup kernel_netlink_ipsec code<br>
---<br>
 src/charon-tkm/src/tkm/tkm_kernel_ipsec.c          |  1 +<br>
 .../jni/libandroidbridge/kernel/android_ipsec.c    |  5 +-<br>
 src/libcharon/config/child_cfg.c                   | 24 ++++++++++<br>
 src/libcharon/config/child_cfg.h                   | 14 ++++++<br>
 .../plugins/load_tester/load_tester_ipsec.c        |  1 +<br>
 src/libcharon/plugins/stroke/stroke_config.c       |  2 +<br>
 src/libcharon/sa/child_sa.c                        |  6 ++-<br>
 src/libhydra/kernel/kernel_interface.c             | 10 ++--<br>
 src/libhydra/kernel/kernel_interface.h             |  4 +-<br>
 src/libhydra/kernel/kernel_ipsec.h                 |  4 +-<br>
 .../plugins/kernel_klips/kernel_klips_ipsec.c      |  6 ++-<br>
 .../plugins/kernel_netlink/kernel_netlink_ipsec.c  | 56 +++++++++-------------<br>
 .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c      |  7 +--<br>
 src/libipsec/ipsec_sa_mgr.c                        |  1 +<br>
 src/libipsec/ipsec_sa_mgr.h                        |  1 +<br>
 src/starter/args.c                                 |  1 +<br>
 src/starter/confread.c                             |  2 +<br>
 src/starter/confread.h                             |  1 +<br>
 src/starter/keywords.h                             |  1 +<br>
 src/starter/keywords.txt                           |  1 +<br>
 src/starter/starterstroke.c                        |  1 +<br>
 src/stroke/stroke_msg.h                            |  1 +<br>
 22 files changed, 101 insertions(+), 49 deletions(-)<br>
<br>
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c<br>
index 72c247d..3e3d139 100644<br>
--- a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c<br>
+++ b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c<br>
@@ -92,6 +92,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
        u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,<br>
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,<br>
</div></div>        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,<br>
+       u_int32_t replay_window,<br>
<div class="">        u_int16_t cpi, bool _initiator, bool encap, bool esn, bool inbound,<br>
        traffic_selector_t* src_ts, traffic_selector_t* dst_ts)<br>
 {<br>
diff --git a/src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c b/src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c<br>
index 48f1487..9885da4 100644<br>
--- a/src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c<br>
+++ b/src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c<br>
@@ -65,13 +65,14 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
        u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,<br>
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,<br>
</div>        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,<br>
+       u_int32_t replay_window,<br>
<div><div class="h5">        u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,<br>
        traffic_selector_t *src_ts, traffic_selector_t *dst_ts)<br>
 {<br>
        return ipsec->sas->add_sa(ipsec->sas, src, dst, spi, protocol, reqid, mark,<br>
                                                          tfc, lifetime, enc_alg, enc_key, int_alg, int_key,<br>
-                                                         mode, ipcomp, cpi, initiator, encap, esn, inbound,<br>
-                                                         src_ts, dst_ts);<br>
+                                                         mode, ipcomp, replay_window, cpi, initiator,<br>
+                                                         encap, esn, inbound, src_ts, dst_ts);<br>
 }<br>
<br>
 METHOD(kernel_ipsec_t, update_sa, status_t,<br>
diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c<br>
index 3f07b58..7e4a143 100644<br>
--- a/src/libcharon/config/child_cfg.c<br>
+++ b/src/libcharon/config/child_cfg.c<br>
@@ -27,6 +27,9 @@ ENUM(action_names, ACTION_NONE, ACTION_RESTART,<br>
        "restart",<br>
 );<br>
<br>
+/** Default replay window size, if not set using charon.replay_window */<br>
+#define DEFAULT_REPLAY_WINDOW 32<br>
+<br>
 typedef struct private_child_cfg_t private_child_cfg_t;<br>
<br>
 /**<br>
@@ -138,6 +141,11 @@ struct private_child_cfg_t {<br>
         * enable installation and removal of kernel IPsec policies<br>
         */<br>
        bool install_policy;<br>
+<br>
+       /**<br>
+        * anti-replay window size<br>
+        */<br>
+       u_int32_t replay_window;<br>
 };<br>
<br>
 METHOD(child_cfg_t, get_name, char*,<br>
@@ -481,6 +489,18 @@ METHOD(child_cfg_t, get_tfc, u_int32_t,<br>
        return this->tfc;<br>
 }<br>
<br>
+METHOD(child_cfg_t, get_replay_window, u_int32_t,<br>
+       private_child_cfg_t *this)<br>
+{<br>
+       return this->replay_window;<br>
+}<br>
+<br>
+METHOD(child_cfg_t, set_replay_window, void,<br>
+       private_child_cfg_t *this, u_int32_t replay_window)<br>
+{<br>
+       this->replay_window = replay_window;<br>
+}<br>
+<br>
 METHOD(child_cfg_t, set_mipv6_options, void,<br>
        private_child_cfg_t *this, bool proxy_mode, bool install_policy)<br>
 {<br>
@@ -558,6 +578,8 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,<br>
                        .get_reqid = _get_reqid,<br>
                        .get_mark = _get_mark,<br>
                        .get_tfc = _get_tfc,<br>
+                       .get_replay_window = _get_replay_window,<br>
+                       .set_replay_window = _set_replay_window,<br>
                        .use_proxy_mode = _use_proxy_mode,<br>
                        .install_policy = _install_policy,<br>
                        .get_ref = _get_ref,<br>
@@ -580,6 +602,8 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,<br>
                .my_ts = linked_list_create(),<br>
                .other_ts = linked_list_create(),<br>
                .tfc = tfc,<br>
+               .replay_window = lib->settings->get_int(lib->settings,<br>
+                               "%s.replay_window", DEFAULT_REPLAY_WINDOW, lib->ns),<br>
        );<br>
<br>
        if (mark_in)<br>
diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h<br>
index 43ad1c5..9f7a92b 100644<br>
--- a/src/libcharon/config/child_cfg.h<br>
+++ b/src/libcharon/config/child_cfg.h<br>
@@ -235,6 +235,20 @@ struct child_cfg_t {<br>
        u_int32_t (*get_tfc)(child_cfg_t *this);<br>
<br>
        /**<br>
+        * Get anti-replay window size<br>
+        *<br>
+        * @return                              anti-replay window size<br>
+        */<br>
+       u_int32_t (*get_replay_window)(child_cfg_t *this);<br>
+<br>
+       /**<br>
+        * Set anti-replay window size<br>
+        *<br>
+        * @param window                anti-replay window size<br>
+        */<br>
+       void (*set_replay_window)(child_cfg_t *this, u_int32_t window);<br>
+<br>
+       /**<br>
         * Sets two options needed for Mobile IPv6 interoperability.<br>
         *<br>
         * @param proxy_mode    use IPsec transport proxy mode (default FALSE)<br>
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c<br>
index 5edd3b8..980c854 100644<br>
--- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c<br>
+++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c<br>
@@ -54,6 +54,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
        u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,<br>
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,<br>
</div></div>        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,<br>
+       u_int32_t replay_window,<br>
<div class="">        u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,<br>
        traffic_selector_t *src_ts, traffic_selector_t *dst_ts)<br>
 {<br>
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c<br>
index df15a16..d22c37f 100644<br>
--- a/src/libcharon/plugins/stroke/stroke_config.c<br>
+++ b/src/libcharon/plugins/stroke/stroke_config.c<br>
@@ -1151,6 +1151,8 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,<br>
                                map_action(msg->add_conn.close_action), msg->add_conn.ipcomp,<br>
                                msg->add_conn.inactivity, msg->add_conn.reqid,<br>
                                &mark_in, &mark_out, msg->add_conn.tfc);<br>
+       if (msg->add_conn.replay_window != -1)<br>
</div><div class="">+               child_cfg->set_replay_window(child_cfg, msg->add_conn.replay_window);<br>
</div><div><div class="h5">        child_cfg->set_mipv6_options(child_cfg, msg->add_conn.proxy_mode,<br>
                                                                                        msg->add_conn.install_policy);<br>
        add_ts(this, &msg-><a href="http://add_conn.me" target="_blank">add_conn.me</a>, child_cfg, TRUE);<br>
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c<br>
index 847cfc7..5a010fc 100644<br>
--- a/src/libcharon/sa/child_sa.c<br>
+++ b/src/libcharon/sa/child_sa.c<br>
@@ -639,6 +639,7 @@ METHOD(child_sa_t, install, status_t,<br>
        host_t *src, *dst;<br>
        status_t status;<br>
        bool update = FALSE;<br>
+       u_int32_t replay_window = 0;<br>
<br>
        /* now we have to decide which spi to use. Use self allocated, if "in",<br>
         * or the one in the proposal, if not "in" (others). Additionally,<br>
@@ -653,6 +654,7 @@ METHOD(child_sa_t, install, status_t,<br>
                }<br>
                this->my_spi = spi;<br>
                this->my_cpi = cpi;<br>
+               replay_window = this->config->get_replay_window(this->config);<br>
        }<br>
        else<br>
        {<br>
@@ -722,8 +724,8 @@ METHOD(child_sa_t, install, status_t,<br>
                                src, dst, spi, proto_ike2ip(this->protocol), this->reqid,<br>
                                inbound ? this->mark_in : this->mark_out, tfc,<br>
                                lifetime, enc_alg, encr, int_alg, integ, this->mode,<br>
-                               this->ipcomp, cpi, initiator, this->encap, esn, update,<br>
-                               src_ts, dst_ts);<br>
+                               this->ipcomp, replay_window, cpi, initiator, this->encap,<br>
+                               esn, update, src_ts, dst_ts);<br>
<br>
        free(lifetime);<br>
<br>
diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c<br>
index 3e34d20..6e10394 100644<br>
--- a/src/libhydra/kernel/kernel_interface.c<br>
+++ b/src/libhydra/kernel/kernel_interface.c<br>
@@ -179,9 +179,10 @@ METHOD(kernel_interface_t, add_sa, status_t,<br>
        private_kernel_interface_t *this, host_t *src, host_t *dst,<br>
        u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,<br>
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,<br>
-       u_int16_t int_alg, chunk_t int_key,     ipsec_mode_t mode, u_int16_t ipcomp,<br>
-       u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,<br>
-       traffic_selector_t *src_ts, traffic_selector_t *dst_ts)<br>
</div></div>+       u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,<br>
+       u_int32_t replay_window,<br>
<div><div class="h5">+       u_int16_t cpi, bool initiator, bool encap, bool esn,<br>
+       bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)<br>
 {<br>
        if (!this->ipsec)<br>
        {<br>
@@ -189,7 +190,8 @@ METHOD(kernel_interface_t, add_sa, status_t,<br>
        }<br>
        return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,<br>
                        mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode,<br>
-                       ipcomp, cpi, initiator, encap, esn, inbound, src_ts, dst_ts);<br>
+                       ipcomp, replay_window, cpi, initiator, encap, esn, inbound,<br>
+                       src_ts, dst_ts);<br>
 }<br>
<br>
 METHOD(kernel_interface_t, update_sa, status_t,<br>
diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h<br>
index cc47d3c..ad13f6e 100644<br>
--- a/src/libhydra/kernel/kernel_interface.h<br>
+++ b/src/libhydra/kernel/kernel_interface.h<br>
@@ -144,6 +144,7 @@ struct kernel_interface_t {<br>
         * @param int_key               key to use for integrity protection<br>
         * @param mode                  mode of the SA (tunnel, transport)<br>
         * @param ipcomp                IPComp transform to use<br>
+        * @param replay_window anti-replay window size<br>
         * @param cpi                   CPI for IPComp<br>
         * @param initiator             TRUE if initiator of the exchange creating this SA<br>
         * @param encap                 enable UDP encapsulation for NAT traversal<br>
@@ -159,7 +160,8 @@ struct kernel_interface_t {<br>
                                                u_int32_t tfc, lifetime_cfg_t *lifetime,<br>
                                                u_int16_t enc_alg, chunk_t enc_key,<br>
                                                u_int16_t int_alg, chunk_t int_key,<br>
</div></div><div class="">-                                               ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,<br>
+                                               ipsec_mode_t mode, u_int16_t ipcomp,<br>
+                                               u_int32_t replay_window, u_int16_t cpi,<br>
</div><div class="">                                                bool initiator, bool encap, bool esn, bool inbound,<br>
                                                traffic_selector_t *src_ts, traffic_selector_t *dst_ts);<br>
<br>
diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h<br>
index 25f5b38..43f5f3d 100644<br>
--- a/src/libhydra/kernel/kernel_ipsec.h<br>
+++ b/src/libhydra/kernel/kernel_ipsec.h<br>
@@ -100,6 +100,7 @@ struct kernel_ipsec_t {<br>
         * @param int_key               key to use for integrity protection<br>
         * @param mode                  mode of the SA (tunnel, transport)<br>
         * @param ipcomp                IPComp transform to use<br>
+        * @param replay_window anti-replay window size<br>
         * @param cpi                   CPI for IPComp<br>
         * @param initiator             TRUE if initiator of the exchange creating this SA<br>
         * @param encap                 enable UDP encapsulation for NAT traversal<br>
</div><div class="">@@ -115,7 +116,8 @@ struct kernel_ipsec_t {<br>
</div><div class="">                                                mark_t mark, u_int32_t tfc, lifetime_cfg_t *lifetime,<br>
                                                u_int16_t enc_alg, chunk_t enc_key,<br>
                                                u_int16_t int_alg, chunk_t int_key,<br>
</div><div class="">-                                               ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,<br>
+                                               ipsec_mode_t mode, u_int16_t ipcomp,<br>
+                                               u_int32_t replay_window, u_int16_t cpi,<br>
</div><div><div class="h5">                                                bool initiator, bool encap, bool esn, bool inbound,<br>
                                                traffic_selector_t *src_ts, traffic_selector_t *dst_ts);<br>
<br>
diff --git a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c<br>
index 0b66b4d..5600410 100644<br>
--- a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c<br>
+++ b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c<br>
@@ -1682,7 +1682,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
        u_int8_t protocol, u_int32_t reqid, mark_t mark, u_int32_t tfc,<br>
        lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,<br>
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,<br>
-       u_int16_t ipcomp, u_int16_t cpi, bool initiator, bool encap, bool esn,<br>
+       u_int16_t ipcomp, u_int32_t replay_window, u_int16_t cpi,<br>
+       bool initiator, bool encap, bool esn,<br>
        bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)<br>
 {<br>
        unsigned char request[PFKEY_BUFFER_SIZE];<br>
@@ -1728,7 +1729,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
        sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));<br>
        sa->sadb_sa_spi = spi;<br>
        sa->sadb_sa_state = SADB_SASTATE_MATURE;<br>
-       sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32;<br>
+       sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0<br>
+                                                 : min(replay_window, 64);<br>
        sa->sadb_sa_auth = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg);<br>
        sa->sadb_sa_encrypt = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg);<br>
        PFKEY_EXT_ADD(msg, sa);<br>
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c<br>
index c864a92..cc425a9 100644<br>
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c<br>
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c<br>
@@ -73,9 +73,6 @@<br>
 /** Default priority of installed policies */<br>
 #define PRIO_BASE 512<br>
<br>
-/** Default replay window size, if not set using charon.replay_window */<br>
-#define DEFAULT_REPLAY_WINDOW 32<br>
-<br>
 /** Default lifetime of an acquire XFRM state (in seconds) */<br>
 #define DEFAULT_ACQUIRE_LIFETIME 165<br>
<br>
@@ -316,16 +313,6 @@ struct private_kernel_netlink_ipsec_t {<br>
         * Whether to track the history of a policy<br>
         */<br>
        bool policy_history;<br>
-<br>
-       /**<br>
-        * Size of the replay window, in packets (= bits)<br>
-        */<br>
-       u_int32_t replay_window;<br>
-<br>
-       /**<br>
-        * Size of the replay window bitmap, in number of __u32 blocks<br>
-        */<br>
-       u_int32_t replay_bmp;<br>
 };<br>
<br>
 typedef struct route_entry_t route_entry_t;<br>
@@ -631,11 +618,12 @@ static inline u_int32_t get_priority(policy_entry_t *policy,<br>
 }<br>
<br>
 /**<br>
- * Return the length of the ESN bitmap<br>
+ * Return the length of the replay bitmap in number of __u32 blocks<br>
  */<br>
-static inline size_t esn_bmp_len(private_kernel_netlink_ipsec_t *this)<br>
+static inline u_int32_t replay_bmp_len(u_int32_t replay_window)<br>
 {<br>
-       return this->replay_bmp * sizeof(u_int32_t);<br>
+       return (replay_window + sizeof(u_int32_t) * 8 - 1) /<br>
+                  (sizeof(u_int32_t) * 8);<br>
 }<br>
<br>
 /**<br>
@@ -1195,6 +1183,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
        u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,<br>
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,<br>
</div></div>        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,<br>
+       u_int32_t replay_window,<br>
<div><div class="h5">        u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,<br>
        traffic_selector_t* src_ts, traffic_selector_t* dst_ts)<br>
 {<br>
@@ -1213,8 +1202,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
                lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}};<br>
                add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,<br>
                           tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,<br>
-                          chunk_empty, mode, ipcomp, 0, initiator, FALSE, FALSE, inbound,<br>
-                          src_ts, dst_ts);<br>
+                          chunk_empty, mode, ipcomp, 0, 0, initiator, FALSE, FALSE,<br>
+                          inbound, src_ts, dst_ts);<br>
                ipcomp = IPCOMP_NONE;<br>
                /* use transport mode ESP SA, IPComp uses tunnel mode */<br>
                mode = MODE_TRANSPORT;<br>
@@ -1480,23 +1469,24 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
<br>
        if (protocol != IPPROTO_COMP)<br>
        {<br>
-               if (esn || this->replay_window > DEFAULT_REPLAY_WINDOW)<br>
+               if (esn || replay_window > 32)<br>
                {<br>
                        /* for ESN or larger replay windows we need the new<br>
                         * XFRMA_REPLAY_ESN_VAL attribute to configure a bitmap */<br>
                        struct xfrm_replay_state_esn *replay;<br>
+                       u_int32_t replay_bmp = replay_bmp_len(replay_window);<br>
<br>
                        replay = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_ESN_VAL,<br>
-                                                                        sizeof(*replay) + esn_bmp_len(this));<br>
+                                                                        sizeof(*replay) + replay_bmp * sizeof(u_int32_t));<br>
                        if (!replay)<br>
                        {<br>
                                goto failed;<br>
                        }<br>
                        /* bmp_len contains number uf __u32's */<br>
-                       replay->bmp_len = this->replay_bmp;<br>
-                       replay->replay_window = this->replay_window;<br>
+                       replay->bmp_len = replay_bmp;<br>
+                       replay->replay_window = replay_window;<br>
                        DBG2(DBG_KNL, "  using replay window of %u packets",<br>
-                                this->replay_window);<br>
+                                replay_window);<br>
<br>
                        if (esn)<br>
                        {<br>
@@ -1507,8 +1497,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
                else<br>
                {<br>
                        DBG2(DBG_KNL, "  using replay window of %u packets",<br>
-                                this->replay_window);<br>
-                       sa->replay_window = this->replay_window;<br>
+                                replay_window);<br>
+                       sa->replay_window = replay_window;<br>
                }<br>
        }<br>
<br>
@@ -1542,6 +1532,7 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,<br>
                                                         u_int32_t spi, u_int8_t protocol,<br>
                                                         host_t *dst, mark_t mark,<br>
                                                         struct xfrm_replay_state_esn **replay_esn,<br>
+                                                        u_int32_t *replay_esn_len,<br>
                                                         struct xfrm_replay_state **replay)<br>
 {<br>
        netlink_buf_t request;<br>
@@ -1618,9 +1609,10 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,<br>
                                break;<br>
                        }<br>
                        if (rta->rta_type == XFRMA_REPLAY_ESN_VAL &&<br>
-                               RTA_PAYLOAD(rta) >= sizeof(**replay_esn) + esn_bmp_len(this))<br>
+                               RTA_PAYLOAD(rta) >= sizeof(**replay_esn))<br>
                        {<br>
                                *replay_esn = malloc(RTA_PAYLOAD(rta));<br>
+                               *replay_esn_len = RTA_PAYLOAD(rta);<br>
                                memcpy(*replay_esn, RTA_DATA(rta), RTA_PAYLOAD(rta));<br>
                                break;<br>
                        }<br>
@@ -1804,6 +1796,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,<br>
        struct xfrm_encap_tmpl* tmpl = NULL;<br>
        struct xfrm_replay_state *replay = NULL;<br>
        struct xfrm_replay_state_esn *replay_esn = NULL;<br>
+       u_int32_t replay_esn_len;<br>
        status_t status = FAILED;<br>
<br>
        /* if IPComp is used, we first update the IPComp SA */<br>
@@ -1868,7 +1861,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,<br>
                goto failed;<br>
        }<br>
<br>
-       get_replay_state(this, spi, protocol, dst, mark, &replay_esn, &replay);<br>
+       get_replay_state(this, spi, protocol, dst, mark, &replay_esn, &replay_esn_len, &replay);<br>
<br>
        /* delete the old SA (without affecting the IPComp SA) */<br>
        if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS)<br>
@@ -1936,12 +1929,12 @@ METHOD(kernel_ipsec_t, update_sa, status_t,<br>
                struct xfrm_replay_state_esn *state;<br>
<br>
                state = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_ESN_VAL,<br>
-                                                               sizeof(*state) + esn_bmp_len(this));<br>
+                                                               replay_esn_len);<br>
                if (!state)<br>
                {<br>
                        goto failed;<br>
                }<br>
-               memcpy(state, replay_esn, sizeof(*state) + esn_bmp_len(this));<br>
+               memcpy(state, replay_esn, replay_esn_len);<br>
        }<br>
        else if (replay)<br>
        {<br>
@@ -2686,13 +2679,8 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()<br>
                .policy_history = TRUE,<br>
                .install_routes = lib->settings->get_bool(lib->settings,<br>
                                                        "%s.install_routes", TRUE, lib->ns),<br>
-               .replay_window = lib->settings->get_int(lib->settings,<br>
-                                                       "%s.replay_window", DEFAULT_REPLAY_WINDOW, lib->ns),<br>
        );<br>
<br>
-       this->replay_bmp = (this->replay_window + sizeof(u_int32_t) * 8 - 1) /<br>
-                                                                                                       (sizeof(u_int32_t) * 8);<br>
-<br>
        if (streq(lib->ns, "starter"))<br>
        {       /* starter has no threads, so we do not register for kernel events */<br>
                register_for_events = FALSE;<br>
diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c<br>
index c865917..95054c2 100644<br>
--- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c<br>
+++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c<br>
@@ -1615,7 +1615,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
        u_int8_t protocol, u_int32_t reqid, mark_t mark, u_int32_t tfc,<br>
        lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,<br>
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,<br>
-       u_int16_t ipcomp, u_int16_t cpi, bool initiator, bool encap, bool esn,<br>
+       u_int16_t ipcomp, u_int32_t replay_window, u_int16_t cpi,<br>
+       bool initiator, bool encap, bool esn,<br>
        bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)<br>
 {<br>
        unsigned char request[PFKEY_BUFFER_SIZE];<br>
@@ -1633,7 +1634,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
                lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}};<br>
                add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,<br>
                           tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,<br>
-                          chunk_empty, mode, ipcomp, 0, FALSE, FALSE, FALSE, inbound,<br>
+                          chunk_empty, mode, ipcomp, 0, 0, FALSE, FALSE, FALSE, inbound,<br>
                           NULL, NULL);<br>
                ipcomp = IPCOMP_NONE;<br>
                /* use transport mode ESP SA, IPComp uses tunnel mode */<br>
@@ -1676,7 +1677,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,<br>
        }<br>
        else<br>
        {<br>
-               sa->sadb_sa_replay = 32;<br>
+               sa->sadb_sa_replay = min(replay_window, 32);<br>
                sa->sadb_sa_auth = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg);<br>
                sa->sadb_sa_encrypt = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg);<br>
        }<br>
diff --git a/src/libipsec/ipsec_sa_mgr.c b/src/libipsec/ipsec_sa_mgr.c<br>
index 1db1776..ba342bd 100644<br>
--- a/src/libipsec/ipsec_sa_mgr.c<br>
+++ b/src/libipsec/ipsec_sa_mgr.c<br>
@@ -441,6 +441,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,<br>
        u_int8_t protocol, u_int32_t reqid,     mark_t mark, u_int32_t tfc,<br>
        lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,<br>
</div></div>        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,<br>
+       u_int32_t replay_window,<br>
<div class="HOEnZb"><div class="h5">        u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,<br>
        traffic_selector_t *src_ts, traffic_selector_t *dst_ts)<br>
 {<br>
diff --git a/src/libipsec/ipsec_sa_mgr.h b/src/libipsec/ipsec_sa_mgr.h<br>
index 8c234ce..9ae0701 100644<br>
--- a/src/libipsec/ipsec_sa_mgr.h<br>
+++ b/src/libipsec/ipsec_sa_mgr.h<br>
@@ -83,6 +83,7 @@ struct ipsec_sa_mgr_t {<br>
                                           mark_t mark, u_int32_t tfc,  lifetime_cfg_t *lifetime,<br>
                                           u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg,<br>
                                           chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,<br>
+                                          uint32_t replay_window,<br>
                                           u_int16_t cpi, bool initiator, bool encap, bool esn,<br>
                                           bool inbound, traffic_selector_t *src_ts,<br>
                                           traffic_selector_t *dst_ts);<br>
diff --git a/src/starter/args.c b/src/starter/args.c<br>
index f5a617e..0d662f4 100644<br>
--- a/src/starter/args.c<br>
+++ b/src/starter/args.c<br>
@@ -173,6 +173,7 @@ static const token_info_t token_info[] =<br>
        { ARG_STR,  offsetof(starter_conn_t, me_mediated_by), NULL                     },<br>
        { ARG_STR,  offsetof(starter_conn_t, me_peerid), NULL                          },<br>
        { ARG_UINT, offsetof(starter_conn_t, reqid), NULL                              },<br>
+       { ARG_UINT, offsetof(starter_conn_t, replay_window), NULL                      },<br>
        { ARG_MISC, 0, NULL  /* KW_MARK */                                             },<br>
        { ARG_MISC, 0, NULL  /* KW_MARK_IN */                                          },<br>
        { ARG_MISC, 0, NULL  /* KW_MARK_OUT */                                         },<br>
diff --git a/src/starter/confread.c b/src/starter/confread.c<br>
index 19178a2..0fac895 100644<br>
--- a/src/starter/confread.c<br>
+++ b/src/starter/confread.c<br>
@@ -34,6 +34,7 @@<br>
 #define SA_REPLACEMENT_MARGIN_DEFAULT  540 /* 9 minutes */<br>
 #define SA_REPLACEMENT_FUZZ_DEFAULT    100 /* 100% of margin */<br>
 #define SA_REPLACEMENT_RETRIES_DEFAULT   3<br>
+#define SA_REPLAY_WINDOW_DEFAULT        -1 /* use charon.replay_window */<br>
<br>
 static const char ike_defaults[] = "aes128-sha1-modp2048,3des-sha1-modp1536";<br>
 static const char esp_defaults[] = "aes128-sha1,3des-sha1";<br>
@@ -132,6 +133,7 @@ static void default_values(starter_config_t *cfg)<br>
        cfg->conn_default.install_policy        = TRUE;<br>
        cfg->conn_default.dpd_delay             =  30; /* seconds */<br>
        cfg->conn_default.dpd_timeout           = 150; /* seconds */<br>
+       cfg->conn_default.replay_window         = SA_REPLAY_WINDOW_DEFAULT;<br>
<br>
        cfg->conn_default.left.seen  = SEEN_NONE;<br>
        cfg->conn_default.right.seen = SEEN_NONE;<br>
diff --git a/src/starter/confread.h b/src/starter/confread.h<br>
index d55a17e..a32f8cb 100644<br>
--- a/src/starter/confread.h<br>
+++ b/src/starter/confread.h<br>
@@ -162,6 +162,7 @@ struct starter_conn {<br>
                u_int32_t       reqid;<br>
                mark_t          mark_in;<br>
                mark_t          mark_out;<br>
+               u_int32_t       replay_window;<br>
                u_int32_t       tfc;<br>
                bool            install_policy;<br>
                bool            aggressive;<br>
diff --git a/src/starter/keywords.h b/src/starter/keywords.h<br>
index 705a7c1..5b6b28b 100644<br>
--- a/src/starter/keywords.h<br>
+++ b/src/starter/keywords.h<br>
@@ -69,6 +69,7 @@ typedef enum {<br>
        KW_MEDIATED_BY,<br>
        KW_ME_PEERID,<br>
        KW_REQID,<br>
+       KW_REPLAY_WINDOW,<br>
        KW_MARK,<br>
        KW_MARK_IN,<br>
        KW_MARK_OUT,<br>
diff --git a/src/starter/keywords.txt b/src/starter/keywords.txt<br>
index ad915bf..ee0bd31 100644<br>
--- a/src/starter/keywords.txt<br>
+++ b/src/starter/keywords.txt<br>
@@ -69,6 +69,7 @@ mediation,         KW_MEDIATION<br>
 mediated_by,       KW_MEDIATED_BY<br>
 me_peerid,         KW_ME_PEERID<br>
 reqid,             KW_REQID<br>
+replay_window,     KW_REPLAY_WINDOW<br>
 mark,              KW_MARK<br>
 mark_in,           KW_MARK_IN<br>
 mark_out,          KW_MARK_OUT<br>
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c<br>
index fca4b1e..839e66e 100644<br>
--- a/src/starter/starterstroke.c<br>
+++ b/src/starter/starterstroke.c<br>
@@ -202,6 +202,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)<br>
        msg.add_conn.ikeme.mediated_by = push_string(&msg, conn->me_mediated_by);<br>
        msg.add_conn.ikeme.peerid = push_string(&msg, conn->me_peerid);<br>
        msg.add_conn.reqid = conn->reqid;<br>
+       msg.add_conn.replay_window = conn->replay_window;<br>
        msg.add_conn.mark_in.value = conn->mark_in.value;<br>
        msg.add_conn.mark_in.mask = conn->mark_in.mask;<br>
        msg.add_conn.mark_out.value = conn->mark_out.value;<br>
diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h<br>
index 5ece724..60886cf 100644<br>
--- a/src/stroke/stroke_msg.h<br>
+++ b/src/stroke/stroke_msg.h<br>
@@ -304,6 +304,7 @@ struct stroke_msg_t {<br>
                                u_int32_t mask;<br>
                        } mark_in, mark_out;<br>
                        stroke_end_t me, other;<br>
+                       u_int32_t replay_window;<br>
                } add_conn;<br>
<br>
                /* data for STR_ADD_CA */<br>
--<br>
1.8.3.2<br>
<br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>Christophe GOUAULT<br>6WIND<br>Project Leader<br><br>Tel: +33 1 39 30 92 19<br>Fax: +33 1 39 30 92 11<br><a href="http://www.6wind.com">www.6wind.com</a><br><a href="http://www.multicorepacketprocessing.com">www.multicorepacketprocessing.com</a><br>
<br>Ce courriel ainsi que toutes les pièces jointes, est uniquement destiné à son ou ses destinataires. Il contient des informations confidentielles qui sont la propriété de 6WIND. Toute révélation, distribution ou copie des informations qu'il contient est strictement interdite. Si vous avez reçu ce message par erreur, veuillez immédiatement le signaler à l'émetteur et détruire toutes les données reçues<br>
<br>This e-mail message, including any attachments, is for the sole use of the intended recipient(s) and contains information that is confidential and proprietary to 6WIND. All unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message.
</div></div>