]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
kernel-netlink: Add support to enable per-CPU acquires on policies
authorTobias Brunner <tobias@strongswan.org>
Tue, 11 May 2021 14:24:38 +0000 (16:24 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 28 May 2025 14:35:26 +0000 (16:35 +0200)
src/libcharon/kernel/kernel_ipsec.h
src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c

index 8b79acac9d46ad0c75197e700a817c39913f506f..6663d730b19e141b76b4a9b0340fcf329b203b14 100644 (file)
@@ -186,6 +186,8 @@ struct kernel_ipsec_manage_policy_t {
        uint32_t manual_prio;
        /** HW offload mode */
        hw_offload_t hw_offload;
+       /** Enable per-CPU acquires */
+       bool pcpu_acquires;
        /** Source address of the SA(s) tied to this policy */
        host_t *src;
        /** Destination address of the SA(s) tied to this policy */
index 74b33d8839dc973e10c63cc30ace88241f7344a0..fd47e4068045fc04ad9e0946caacd56c1ebcb738 100644 (file)
@@ -545,6 +545,9 @@ struct policy_sa_t {
        /** Type of the policy */
        policy_type_t type;
 
+       /** Whether to trigger per-CPU acquires for this policy */
+       bool pcpu_acquires;
+
        /** Assigned SA */
        ipsec_sa_t *sa;
 };
@@ -565,12 +568,13 @@ struct policy_sa_out_t {
 };
 
 /**
- * Create a policy_sa(_in)_t object
+ * Create a policy_sa(_out)_t object
  */
 static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this,
        policy_dir_t dir, policy_type_t type, host_t *src, host_t *dst,
        traffic_selector_t *src_ts, traffic_selector_t *dst_ts, mark_t mark,
-       uint32_t if_id, hw_offload_t hw_offload, ipsec_sa_cfg_t *cfg)
+       uint32_t if_id, hw_offload_t hw_offload, bool pcpu_acquires,
+       ipsec_sa_cfg_t *cfg)
 {
        policy_sa_t *policy;
 
@@ -588,6 +592,7 @@ static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this,
                INIT(policy, .priority = 0);
        }
        policy->type = type;
+       policy->pcpu_acquires = pcpu_acquires;
        policy->sa = ipsec_sa_create(this, src, dst, mark, if_id, hw_offload, cfg);
        return policy;
 }
@@ -2951,6 +2956,11 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
        policy_info->sel = policy->sel;
        policy_info->dir = policy->direction;
 
+       if (mapping->pcpu_acquires)
+       {
+               policy_info->flags |= XFRM_POLICY_CPU_ACQUIRE;
+       }
+
        /* calculate priority based on selector size, small size = high prio */
        policy_info->priority = mapping->priority;
        policy_info->action = mapping->type != POLICY_DROP ? XFRM_POLICY_ALLOW
@@ -3007,8 +3017,9 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
                        tmpl->reqid = ipsec->cfg.reqid;
                        tmpl->id.proto = protos[i].proto;
                        /* in order to match SAs with all matching labels, we can't have the
-                        * SPI in the template */
-                       if (policy->direction == POLICY_OUT && !policy->label)
+                        * SPI in the template, similarly for per-CPU policies and sub-SAs */
+                       if (policy->direction == POLICY_OUT && !policy->label &&
+                               !mapping->pcpu_acquires)
                        {
                                tmpl->id.spi = protos[i].spi;
                        }
@@ -3154,7 +3165,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
        /* cache the assigned IPsec SA */
        assigned_sa = policy_sa_create(this, id->dir, data->type, data->src,
                                                                   data->dst, id->src_ts, id->dst_ts, id->mark,
-                                                                  id->if_id, data->hw_offload, data->sa);
+                                                                  id->if_id, data->hw_offload,
+                                                                  data->pcpu_acquires, data->sa);
        assigned_sa->auto_priority = get_priority(policy, data->prio, id->interface);
        assigned_sa->priority = this->get_priority ? this->get_priority(id, data)
                                                                                           : data->manual_prio;
@@ -3387,6 +3399,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
                if (priority == mapping->priority &&
                        auto_priority == mapping->auto_priority &&
                        data->type == mapping->type &&
+                       data->pcpu_acquires == mapping->pcpu_acquires &&
                        ipsec_sa_equals(mapping->sa, &assigned_sa))
                {
                        current->used_by->remove_at(current->used_by, enumerator);