[strongSwan] Issue about the IPsec (tunnel mode) over IP-in-IP tunnel, please help, thanks!

David Deng david.live.koo at gmail.com
Tue Nov 23 10:59:17 CET 2010


Hi Andreas, Hi Martin, Hi All,

I have encountered one tough issue and need your all help. Please give me a
help.  Thanks!

Because the need of one special project, I need to establish two tunnel
(IPsec tunnel over IP-in-IP tunnel) and the three IP header is the same.
detail information will be listed as followed.

The scenario is:
__________________________________________________________________________________________
{IP-in-IP Client }<-- Ip package --> {IP-in-IP server} <-- IP-in-IP package
--> {IPsec Gateway} <--IPsec over IP-in-IP package--> {Client with IPsec
(using tunnel mode) over IP-in-IP}
-------------------------------------------------------------------------------------------------------------------------------------------------
Note:
1) two tunnel used in Client: IPsec tunnel over IP-in-IP tunnel;
2) the three Sourece IP in the header used in the client of IPsec over
IP-in-IP is the same.

The issue is:

When I initiate a ping from client of IPsec over IP-in-IP, from TCPDUMP log,
we can see that the package of ICMP request can reach IP-in-IP Client and
ICMP reply can also reach client of IPsec over IP-in-IP successfully but
ICMP reply can not be delievered to the upper layer (ICMP reply package can
not be seen on the console).

More Information:
1) The implementation of IPsec uses the method: "integrate IPsec to native
IP stack"  --- ie: NETKEY
2) The IP-In-IP configuration listed as followed: (a virtual interface
IP-in-IP adopted)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ifconfig eth1 172.19.2.168 netmask 255.255.255.0
ip tunnel add ip-in-ip mode ipip remote 139.200.9.1 local 172.19.2.168 dev
eth1
ip addr add 172.19.2.168/24 dev ip-in-ip
ip link set ip-in-ip up
route add -host 139.200.9.9 gateway 172.19.2.177 dev ip-in-ip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3) The Linux Kernel Version is: 2.6.28

Question:
1) Whether two tunnel mode (IPsec tunnel over IP-in-IP tunnel) can be
supported?
2) The Root causes of the above issue?
3) Whether there are some patches of kernel can fix this issue?
4) Any suggestion can be given?

Look forward to your answer, Thanks a lot!


Hi All,

I have encountered one tough issue and need your all help. Please give me a
help.  Thanks!

The scenario is:
__________________________________________________________________________________________
{IP-in-IP Client }<-- Ip package --> {IP-in-IP server} <-- IP-in-IP package
--> {IPsec Gateway} <--IPsec over IP-in-IP package--> {Client with IPsec
(using tunnel mode) over IP-in-IP}
-------------------------------------------------------------------------------------------------------------------------------------------------
Note:
1) two tunnel used in Client: IPsec tunnel over IP-in-IP tunnel;
2) the three Sourece IP in the header used in the client of IPsec over
IP-in-IP is the same.

The issue is:

When I initiate a ping from client of IPsec over IP-in-IP, from TCPDUMP log,
we can see that the package of ICMP request can reach IP-in-IP Client and
ICMP reply can also reach client of IPsec over IP-in-IP successfully but
ICMP reply can not be delievered to the upper layer (ICMP reply package can
not be seen on the console).

More Information:
1) The implementation of IPsec uses the method: "integrate IPsec to native
IP stack"  --- ie: NETKEY
2) The IP-In-IP configuration listed as followed: (a virtual interface
IP-in-IP adopted)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ifconfig eth1 172.19.2.168 netmask 255.255.255.0
ip tunnel add ip-in-ip mode ipip remote 139.200.9.1 local 172.19.2.168 dev
eth1
ip addr add 172.19.2.168/24 dev ip-in-ip
ip link set ip-in-ip up
route add -host 139.200.9.9 gateway 172.19.2.177 dev ip-in-ip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3) The Linux Kernel Version is: 2.6.28

Question:
1) Whether two tunnel mode (IPsec tunnel over IP-in-IP tunnel) can be
supported?
2) The Root causes of the above issue?
3) Whether there are some patches of kernel can fix this issue?
4) Any suggestion can be given?



I debug with "kgdb" and found the package has been reject in one handling
branch of ICMP package. I listed the related code as followed, please help
to check what caused this problem and whether there are some patches can
solve this problem. PS: the linux kernel I used is LINUX2.6.28.



-------------------------------------------------------------------------------------------------------------------------------------------------------------

nt __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,

   unsigned short family)

{

 struct xfrm_policy *pol;

 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];

 int npols = 0;

 int xfrm_nr;

 int pi;

 int reverse;

 struct flowi fl;

 u8 fl_dir;

 int xerr_idx = -1;

 reverse = dir & ~XFRM_POLICY_MASK;

 dir &= XFRM_POLICY_MASK;

 fl_dir = policy_to_flow_dir(dir);

 if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) {

  XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);

  return 0;

 }

 nf_nat_decode_session(skb, &fl, family);

 /* First, check used SA against their selectors. */

 if (skb->sp) {

  int i;

  for (i=skb->sp->len-1; i>=0; i--) {

   struct xfrm_state *x = skb->sp->xvec[i];

   if (!xfrm_selector_match(&x->sel, &fl, family)) {

    XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH);

    return 0;

   }

  }

 }

 pol = NULL;

 if (sk && sk->sk_policy[dir]) {

  pol = xfrm_sk_policy_lookup(sk, dir, &fl);

  if (IS_ERR(pol)) {

   XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);

   return 0;

  }

 }

 if (!pol)

  pol = flow_cache_lookup(&fl, family, fl_dir,

     xfrm_policy_lookup);

 if (IS_ERR(pol)) {

  XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);

  return 0;

 }

 if (!pol) {

  if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) {

   xfrm_secpath_reject(xerr_idx, skb, &fl);

   XFRM_INC_STATS(LINUX_MIB_XFRMINNOPOLS);

   return 0;

  }

  return 1;

 }

 pol->curlft.use_time = get_seconds();

 pols[0] = pol;

 npols ++;

#ifdef CONFIG_XFRM_SUB_POLICY

 if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) {

  pols[1] = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN,

          &fl, family,

          XFRM_POLICY_IN);

  if (pols[1]) {

   if (IS_ERR(pols[1])) {

    XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);

    return 0;

   }

   pols[1]->curlft.use_time = get_seconds();

   npols ++;

  }

 }

#endif

 if (pol->action == XFRM_POLICY_ALLOW) {

  struct sec_path *sp;

  static struct sec_path dummy;

  struct xfrm_tmpl *tp[XFRM_MAX_DEPTH];

  struct xfrm_tmpl *stp[XFRM_MAX_DEPTH];

  struct xfrm_tmpl **tpp = tp;

  int ti = 0;

  int i, k;

  if ((sp = skb->sp) == NULL)

   sp = &dummy;

  for (pi = 0; pi < npols; pi++) {

   if (pols[pi] != pol &&

       pols[pi]->action != XFRM_POLICY_ALLOW) {

    XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);

    goto reject;

   }

   if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) {

    XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);

    goto reject_error;

   }

   for (i = 0; i < pols[pi]->xfrm_nr; i++)

    tpp[ti++] = &pols[pi]->xfrm_vec[i];

  }

  xfrm_nr = ti;

  if (npols > 1) {

   xfrm_tmpl_sort(stp, tpp, xfrm_nr, family);

   tpp = stp;

  }

  /* For each tunnel xfrm, find the first matching tmpl.

   * For each tmpl before that, find corresponding xfrm.

   * Order is _important_. Later we will implement

   * some barriers, but at the moment barriers

   * are implied between each two transformations.

   */

  for (i = xfrm_nr-1, k = 0; i >= 0; i--) {

   k = xfrm_policy_ok(tpp[i], sp, k, family);

   if (k < 0) {

    if (k < -1)

     /* "-2 - errored_index" returned */

     xerr_idx = -(2+k);

    XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);

    goto reject;

   }

  }

  if (secpath_has_nontransport(sp, k, &xerr_idx)) {

   XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);

   goto reject;

  }

  xfrm_pols_put(pols, npols);

  return 1;

 }

 XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);

reject:

 xfrm_secpath_reject(xerr_idx, skb, &fl);

reject_error:

 xfrm_pols_put(pols, npols);

 return 0;

}


Look forward to your answer, Thanks a lot!


Best Wishes
David Morris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.strongswan.org/pipermail/users/attachments/20101123/2bb4ffac/attachment.html>


More information about the Users mailing list