aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-12-12 13:44:43 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:57:23 -0500
commit8b7817f3a959ed99d7443afc12f78a7e1fcc2063 (patch)
tree7e315dfbf5c77e67f6e7ad56f14eaddca621212b /net/xfrm
parentd5422efe680fc55010c6ddca2370ca9548a96355 (diff)
[IPSEC]: Add ICMP host relookup support
RFC 4301 requires us to relookup ICMP traffic that does not match any policies using the reverse of its payload. This patch implements this for ICMP traffic that originates from or terminates on localhost. This is activated on outbound with the new policy flag XFRM_POLICY_ICMP, and on inbound by the new state flag XFRM_STATE_ICMP. On inbound the policy check is now performed by the ICMP protocol so that it can repeat the policy check where necessary. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 2e10d46c0e8c..a83b5e1349ed 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1469,11 +1469,13 @@ restart:
1469 goto dropdst; 1469 goto dropdst;
1470 } 1470 }
1471 1471
1472 err = -ENOENT;
1473
1472 if (!policy) { 1474 if (!policy) {
1473 /* To accelerate a bit... */ 1475 /* To accelerate a bit... */
1474 if ((dst_orig->flags & DST_NOXFRM) || 1476 if ((dst_orig->flags & DST_NOXFRM) ||
1475 !xfrm_policy_count[XFRM_POLICY_OUT]) 1477 !xfrm_policy_count[XFRM_POLICY_OUT])
1476 return 0; 1478 goto nopol;
1477 1479
1478 policy = flow_cache_lookup(fl, dst_orig->ops->family, 1480 policy = flow_cache_lookup(fl, dst_orig->ops->family,
1479 dir, xfrm_policy_lookup); 1481 dir, xfrm_policy_lookup);
@@ -1483,14 +1485,18 @@ restart:
1483 } 1485 }
1484 1486
1485 if (!policy) 1487 if (!policy)
1486 return 0; 1488 goto nopol;
1487 1489
1488 family = dst_orig->ops->family; 1490 family = dst_orig->ops->family;
1489 policy->curlft.use_time = get_seconds();
1490 pols[0] = policy; 1491 pols[0] = policy;
1491 npols ++; 1492 npols ++;
1492 xfrm_nr += pols[0]->xfrm_nr; 1493 xfrm_nr += pols[0]->xfrm_nr;
1493 1494
1495 if ((flags & XFRM_LOOKUP_ICMP) && !(policy->flags & XFRM_POLICY_ICMP))
1496 goto error;
1497
1498 policy->curlft.use_time = get_seconds();
1499
1494 switch (policy->action) { 1500 switch (policy->action) {
1495 default: 1501 default:
1496 case XFRM_POLICY_BLOCK: 1502 case XFRM_POLICY_BLOCK:
@@ -1649,6 +1655,11 @@ dropdst:
1649 dst_release(dst_orig); 1655 dst_release(dst_orig);
1650 *dst_p = NULL; 1656 *dst_p = NULL;
1651 return err; 1657 return err;
1658
1659nopol:
1660 if (flags & XFRM_LOOKUP_ICMP)
1661 goto dropdst;
1662 return 0;
1652} 1663}
1653EXPORT_SYMBOL(__xfrm_lookup); 1664EXPORT_SYMBOL(__xfrm_lookup);
1654 1665