Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Sep 2003 21:18:31 +0200
From:      "Oldach, Helge" <Helge.Oldach@atosorigin.com>
To:        Gabor <gabor@vmunix.com>
Cc:        freebsd-stable@freebsd.org
Subject:   RE: FAST_IPSEC doesn't seem to honor net.key.prefered_oldsa=0
Message-ID:  <D2CFC58E0F8CB443B54BE72201E8916EF41BA4@dehhx005.hbg.de.int.atosorigin.com>

next in thread | raw e-mail | index | archive | help
Gabor,

thank you, this is exactly what I observe as well.

I wish to add that commercial IPSec equipment appears to prefer
net.key.prefered_oldsa=0 which makes FAST_IPSEC (defaulting to "1")
slightly incompatible. This applies to Cisco IPSec gear in particular.

Regards,
Helge


> -----Original Message-----
> From: Gabor [mailto:gabor@vmunix.com]
> Sent: Thursday, 11. September 2003 20:32
> To: freebsd-stable@freebsd.org
> Cc: Sam Leffler
> Subject: FAST_IPSEC doesn't seem to honor net.key.prefered_oldsa=0
> 
> 
> When using the FAST_IPSEC option in the kernel build, the sysctl
> variable net.key.prefered_oldsa seems to make no difference.  The
> kernel always chooses an old SA.  This problem can be easily
> reproduced. Just wait till the soft limit of the SA is expired and do
> a setkey -F on the remote and then ping through the tunnel.  Because
> the old SA's are preferred and the remote no longer has the old SA's
> the server and the remote cannot talk through the tunnel.  Looking
> at the source code in netipsec/key.c and comparing it with
> netkey/key.c I see the there is some differences that didn't make it
> into netipsec/key.c.
> 
> Here is a context diff applied to 1.3.2.2 of the changes I made to fix
> the problem.
> 
> *** /tmp/ipsec.key.c    Thu Sep 11 14:26:07 2003
> --- /usr/src/sys/netipsec/key.c Thu Sep 11 14:27:42 2003
> ***************
> *** 1,4 ****
> ! /*    $FreeBSD: /repoman/r/ncvs/src/sys/netipsec/key.c,v 
> 1.3.2.2 2003/07/01 01:38:13 sam Exp $        */
>   /*    $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $   */
> 
>   /*
> --- 1,4 ----
> ! /*    $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.2 2003/07/01 
> 01:38:13 sam Exp $*/
>   /*    $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $   */
> 
>   /*
> ***************
> *** 133,138 ****
> --- 133,139 ----
>   #endif
>   static LIST_HEAD(_spacqtree, secspacq) spacqtree;     /* SP 
> acquiring list */
> 
> + #if 0
>   /* search order for SAs */
>   static u_int saorder_state_valid[] = {
>         SADB_SASTATE_DYING, SADB_SASTATE_MATURE,
> ***************
> *** 141,146 ****
> --- 142,155 ----
>          * for outbound processing.  For inbound, This is not 
> important.
>          */
>   };
> + #endif
> + static const u_int saorder_state_valid_prefer_old[] = {
> +         SADB_SASTATE_DYING, SADB_SASTATE_MATURE,
> + };
> + static const u_int saorder_state_valid_prefer_new[] = {
> +         SADB_SASTATE_MATURE, SADB_SASTATE_DYING,
> + };
> +
>   static u_int saorder_state_alive[] = {
>         /* except DEAD */
>         SADB_SASTATE_MATURE, SADB_SASTATE_DYING, SADB_SASTATE_LARVAL
> ***************
> *** 816,821 ****
> --- 825,832 ----
>         struct secashead *sah;
>         struct secasvar *sav;
>         u_int stateidx, state;
> +         const u_int *saorder_state_valid;
> +         int arraysize;
> 
>         LIST_FOREACH(sah, &sahtree, chain) {
>                 if (sah->state == SADB_SASTATE_DEAD)
> ***************
> *** 828,836 ****
> 
>       found:
> 
>         /* search valid state */
>         for (stateidx = 0;
> !            stateidx < _ARRAYLEN(saorder_state_valid);
>              stateidx++) {
> 
>                 state = saorder_state_valid[stateidx];
> --- 839,859 ----
> 
>       found:
> 
> +         /*
> +          * search a valid state list for outbound packet.
> +          * This search order is important.
> +          */
> +         if (key_prefered_oldsa) {
> +                 saorder_state_valid = 
> saorder_state_valid_prefer_old;
> +                 arraysize = 
> _ARRAYLEN(saorder_state_valid_prefer_old);
> +         } else {
> +                 saorder_state_valid = 
> saorder_state_valid_prefer_new;
> +                 arraysize = 
> _ARRAYLEN(saorder_state_valid_prefer_new);
> +         }
> +
>         /* search valid state */
>         for (stateidx = 0;
> !            stateidx < arraysize;
>              stateidx++) {
> 
>                 state = saorder_state_valid[stateidx];
> ***************
> *** 997,1008 ****
> --- 1020,1045 ----
>         struct secasvar *sav;
>         u_int stateidx, state;
>         int s;
> +         const u_int *saorder_state_valid;
> +         int arraysize;
> 
>         KASSERT(dst != NULL, ("key_allocsa: null dst address"));
> 
>         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
>                 printf("DP key_allocsa from %s:%u\n", where, tag));
> 
> +         /*
> +          * when both systems employ similar strategy to use a SA.
> +          * the search order is important even in the inbound case.
> +          */
> +         if (key_prefered_oldsa) {
> +                 saorder_state_valid = 
> saorder_state_valid_prefer_old;
> +                 arraysize = 
> _ARRAYLEN(saorder_state_valid_prefer_old);
> +         } else {
> +                 saorder_state_valid = 
> saorder_state_valid_prefer_new;
> +                 arraysize = 
> _ARRAYLEN(saorder_state_valid_prefer_new);
> +         }
> +
>         /*
>          * searching SAD.
>          * XXX: to be checked internal IP header somewhere.  Also when
> ***************
> *** 1013,1019 ****
>         LIST_FOREACH(sah, &sahtree, chain) {
>                 /* search valid state */
>                 for (stateidx = 0;
> !                    stateidx < _ARRAYLEN(saorder_state_valid);
>                      stateidx++) {
>                         state = saorder_state_valid[stateidx];
>                         LIST_FOREACH(sav, 
> &sah->savtree[state], chain) {
> --- 1050,1056 ----
>         LIST_FOREACH(sah, &sahtree, chain) {
>                 /* search valid state */
>                 for (stateidx = 0;
> !                    stateidx < arraysize;
>                      stateidx++) {
>                         state = saorder_state_valid[stateidx];
>                         LIST_FOREACH(sav, 
> &sah->savtree[state], chain) {
> 
> _______________________________________________
> freebsd-stable@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-stable
> To unsubscribe, send any mail to 
> "freebsd-stable-unsubscribe@freebsd.org"
> 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?D2CFC58E0F8CB443B54BE72201E8916EF41BA4>