aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2016-04-11 11:19:26 +0200
committerTobias Brunner <tobias@strongswan.org>2016-04-15 10:39:00 +0200
commit4e59618382d3e96f5a0039f18f3620c6435b8247 (patch)
tree8e7811c98ad0bbfa040e93b198800a99121daf58 /src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
parent869f4e90b1b86e7d25b5624d2906d803327f2a7f (diff)
downloadstrongswan-4e59618382d3e96f5a0039f18f3620c6435b8247.tar.bz2
strongswan-4e59618382d3e96f5a0039f18f3620c6435b8247.tar.xz
kernel-pfkey: Update priority calculation formula to the new one in kernel-netlink
Since the selectors are not exactly the same (no port masks, no interface) some small tweaks have been applied.
Diffstat (limited to 'src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c')
-rw-r--r--src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 7eb6c5808..8de33d33e 100644
--- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -141,8 +141,8 @@
#define SOL_UDP IPPROTO_UDP
#endif
-/** base priority for installed policies */
-#define PRIO_BASE 384
+/** Base priority for installed policies */
+#define PRIO_BASE 100000
#ifdef __APPLE__
/** from xnu/bsd/net/pfkeyv2.h */
@@ -590,33 +590,44 @@ static inline bool policy_entry_match_byindex(policy_entry_t *current,
/**
* Calculate the priority of a policy
+ *
+ * This is the same formula we use in the kernel-netlink interface, but some
+ * features are currently not or only partially supported by PF_KEY.
+ *
+ * bits 0-0: reserved for interface restriction (0..1) 1 bit
+ * bits 1-6: src + dst port mask bits (2 * 0..16) 6 bits
+ * bits 7-7: restriction to protocol (0..1) 1 bit
+ * bits 8-16: src + dst network mask bits (2 * 0..128) 9 bits
+ * 17 bits
+ *
+ * smallest value: 000000000 0 000000 0: 0, lowest priority = 100'000
+ * largest value : 100000000 1 100000 0: 65'728, highst priority = 34'272
*/
static inline uint32_t get_priority(policy_entry_t *policy,
policy_priority_t prio)
{
uint32_t priority = PRIO_BASE;
+
switch (prio)
{
case POLICY_PRIORITY_FALLBACK:
- priority <<= 1;
+ priority += PRIO_BASE;
/* fall-through */
case POLICY_PRIORITY_ROUTED:
- priority <<= 1;
+ priority += PRIO_BASE;
/* fall-through */
case POLICY_PRIORITY_DEFAULT:
- priority <<= 1;
- /* fall-trough */
+ priority += PRIO_BASE;
+ /* fall-through */
case POLICY_PRIORITY_PASS:
break;
}
- /* calculate priority based on selector size, small size = high prio */
- priority -= policy->src.mask;
- priority -= policy->dst.mask;
- priority <<= 2; /* make some room for the two flags */
- priority += policy->src.net->get_port(policy->src.net) ||
- policy->dst.net->get_port(policy->dst.net) ?
- 0 : 2;
- priority += policy->src.proto != IPSEC_PROTO_ANY ? 0 : 1;
+
+ /* calculate priority */
+ priority -= (policy->src.mask + policy->dst.mask) * 256;
+ priority -= policy->src.proto != IPSEC_PROTO_ANY ? 128 : 0;
+ priority -= policy->src.net->get_port(policy->src.net) ? 32 : 0;
+ priority -= policy->dst.net->get_port(policy->dst.net) ? 32 : 0;
return priority;
}