[strongSwan-dev] [PATCH v2] charon: per connection replay window configuration

Christophe Gouault christophe.gouault at 6wind.com
Tue Jun 10 17:23:45 CEST 2014


Hi all,

any comment about the v2 of the patch?

Best Regards,
Christophe



2014-05-27 16:30 GMT+02:00 Christophe Gouault <christophe.gouault at 6wind.com>
:

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


-- 
Christophe GOUAULT
6WIND
Project Leader

Tel: +33 1 39 30 92 19
Fax: +33 1 39 30 92 11
www.6wind.com
www.multicorepacketprocessing.com

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

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.strongswan.org/pipermail/dev/attachments/20140610/23d29037/attachment-0001.html>


More information about the Dev mailing list