IPsec policies can be looked up based on an IP packet
authorTobias Brunner <tobias@strongswan.org>
Fri, 13 Jul 2012 13:18:07 +0000 (15:18 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 Aug 2012 13:41:03 +0000 (15:41 +0200)
src/libipsec/ipsec_policy.c
src/libipsec/ipsec_policy.h
src/libipsec/ipsec_policy_mgr.c
src/libipsec/ipsec_policy_mgr.h

index 54bae6a..af8ea9f 100644 (file)
@@ -101,6 +101,18 @@ METHOD(ipsec_policy_t, match, bool,
                        this->dst_ts->equals(this->dst_ts, dst_ts));
 }
 
+METHOD(ipsec_policy_t, match_packet, bool,
+       private_ipsec_policy_t *this, ip_packet_t *packet)
+{
+       u_int8_t proto = packet->get_next_header(packet);
+       host_t *src = packet->get_source(packet),
+                  *dst = packet->get_destination(packet);
+
+       return (!this->protocol || this->protocol == proto) &&
+                  this->src_ts->includes(this->src_ts, src) &&
+                  this->dst_ts->includes(this->dst_ts, dst);
+}
+
 METHOD(ipsec_policy_t, get_source_ts, traffic_selector_t*,
        private_ipsec_policy_t *this)
 {
@@ -172,6 +184,7 @@ ipsec_policy_t *ipsec_policy_create(host_t *src, host_t *dst,
        INIT(this,
                .public = {
                        .match = _match,
+                       .match_packet = _match_packet,
                        .get_source_ts = _get_source_ts,
                        .get_destination_ts = _get_destination_ts,
                        .get_direction = _get_direction,
index 0806930..67ad0b0 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef IPSEC_POLICY_H
 #define IPSEC_POLICY_H
 
+#include "ip_packet.h"
+
 #include <library.h>
 #include <utils/host.h>
 #include <ipsec/ipsec_types.h>
@@ -100,6 +102,14 @@ struct ipsec_policy_t {
                                  u_int32_t reqid, mark_t mark, policy_priority_t priority);
 
        /**
+        * Check if this policy matches the given IP packet
+        *
+        * @param packet                IP packet
+        * @return                              TRUE if policy matches the packet
+        */
+       bool (*match_packet)(ipsec_policy_t *this, ip_packet_t *packet);
+
+       /**
         * Destroy an ipsec_policy_t
         */
        void (*destroy)(ipsec_policy_t *this);
index 70447b2..41ba792 100644 (file)
@@ -16,7 +16,6 @@
  */
 
 #include "ipsec_policy_mgr.h"
-#include "ipsec_policy.h"
 
 #include <debug.h>
 #include <threading/rwlock.h>
@@ -230,6 +229,31 @@ METHOD(ipsec_policy_mgr_t, flush_policies, status_t,
        return SUCCESS;
 }
 
+METHOD(ipsec_policy_mgr_t, find_by_packet, ipsec_policy_t*,
+       private_ipsec_policy_mgr_t *this, ip_packet_t *packet, bool inbound)
+{
+       enumerator_t *enumerator;
+       ipsec_policy_entry_t *current;
+       ipsec_policy_t *found = NULL;
+
+       this->lock->read_lock(this->lock);
+       enumerator = this->policies->create_enumerator(this->policies);
+       while (enumerator->enumerate(enumerator, (void**)&current))
+       {
+               ipsec_policy_t *policy = current->policy;
+
+               if ((inbound == (policy->get_direction(policy) == POLICY_IN)) &&
+                        policy->match_packet(policy, packet))
+               {
+                       found = policy->get_ref(policy);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return found;
+}
+
 METHOD(ipsec_policy_mgr_t, destroy, void,
        private_ipsec_policy_mgr_t *this)
 {
@@ -251,6 +275,7 @@ ipsec_policy_mgr_t *ipsec_policy_mgr_create()
                        .add_policy = _add_policy,
                        .del_policy = _del_policy,
                        .flush_policies = _flush_policies,
+                       .find_by_packet = _find_by_packet,
                        .destroy = _destroy,
                },
                .policies = linked_list_create(),
index 0a2f632..d3ee107 100644 (file)
@@ -23,6 +23,9 @@
 #ifndef IPSEC_POLICY_MGR_H_
 #define IPSEC_POLICY_MGR_H_
 
+#include "ipsec_policy.h"
+#include "ip_packet.h"
+
 #include <library.h>
 #include <utils/host.h>
 #include <utils/linked_list.h>
@@ -90,6 +93,16 @@ struct ipsec_policy_mgr_t {
        status_t (*flush_policies)(ipsec_policy_mgr_t *this);
 
        /**
+        * Find the policy that matches the given IP packet best
+        *
+        * @param packet                IP packet to match
+        * @param inbound               TRUE for an inbound packet
+        * @return                              reference to the policy, or NULL if none found
+        */
+       ipsec_policy_t *(*find_by_packet)(ipsec_policy_mgr_t *this,
+                                                                         ip_packet_t *packet, bool inbound);
+
+       /**
         * Destroy an ipsec_policy_mgr_t
         */
        void (*destroy)(ipsec_policy_mgr_t *this);