{
if (p1->priority != p2->priority)
return 0;
- if (p1->is_outbound != p2->is_outbound)
+ if (p1->type != p2->type)
return (0);
if (p1->policy != p2->policy)
return (0);
return 0;
}
+int
+ipsec_policy_mk_type (bool is_outbound,
+ bool is_ipv6,
+ ipsec_policy_action_t action,
+ ipsec_spd_policy_type_t * type)
+{
+ if (is_outbound)
+ {
+ *type = (is_ipv6 ?
+ IPSEC_SPD_POLICY_IP6_OUTBOUND : IPSEC_SPD_POLICY_IP4_OUTBOUND);
+ return (0);
+ }
+ else
+ {
+ switch (action)
+ {
+ case IPSEC_POLICY_ACTION_PROTECT:
+ *type = (is_ipv6 ?
+ IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT :
+ IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT);
+ return (0);
+ case IPSEC_POLICY_ACTION_BYPASS:
+ *type = (is_ipv6 ?
+ IPSEC_SPD_POLICY_IP6_INBOUND_BYPASS :
+ IPSEC_SPD_POLICY_IP4_INBOUND_BYPASS);
+ return (0);
+ case IPSEC_POLICY_ACTION_DISCARD:
+ case IPSEC_POLICY_ACTION_RESOLVE:
+ break;
+ }
+ }
+
+ /* Unsupported type */
+ return (-1);
+}
+
int
ipsec_add_del_policy (vlib_main_t * vm,
ipsec_policy_t * policy, int is_add, u32 * stat_index)
u32 spd_index;
uword *p;
- clib_warning ("policy-id %u priority %d is_outbound %u", policy->id,
- policy->priority, policy->is_outbound);
-
- if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
- {
- p = hash_get (im->sa_index_by_sa_id, policy->sa_id);
- if (!p)
- return VNET_API_ERROR_SYSCALL_ERROR_1;
- policy->sa_index = p[0];
- }
-
p = hash_get (im->spd_index_by_spd_id, policy->id);
if (!p)
{
u32 policy_index;
+ if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
+ {
+ index_t sa_index = ipsec_sa_find_and_lock (policy->sa_id);
+
+ if (INDEX_INVALID == sa_index)
+ return VNET_API_ERROR_SYSCALL_ERROR_1;
+ policy->sa_index = sa_index;
+ }
+ else
+ policy->sa_index = INDEX_INVALID;
+
pool_get (im->policies, vp);
clib_memcpy (vp, policy, sizeof (*vp));
policy_index = vp - im->policies;
policy_index);
vlib_zero_combined_counter (&ipsec_spd_policy_counters, policy_index);
- if (policy->is_outbound)
- {
- if (policy->is_ipv6)
- {
- vec_add1 (spd->policies[IPSEC_SPD_POLICY_IP6_OUTBOUND],
- policy_index);
- vec_sort_with_function (spd->policies
- [IPSEC_SPD_POLICY_IP6_OUTBOUND],
- ipsec_spd_entry_sort);
- }
- else
- {
- vec_add1 (spd->policies[IPSEC_SPD_POLICY_IP4_OUTBOUND],
- policy_index);
- vec_sort_with_function (spd->policies
- [IPSEC_SPD_POLICY_IP4_OUTBOUND],
- ipsec_spd_entry_sort);
- }
- }
- else
- {
- if (policy->is_ipv6)
- {
- if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
- {
- vec_add1 (spd->policies
- [IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT],
- policy_index);
- vec_sort_with_function (spd->policies
- [IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT],
- ipsec_spd_entry_sort);
- }
- else
- {
- vec_add1
- (spd->policies[IPSEC_SPD_POLICY_IP6_INBOUND_BYPASS],
- policy_index);
- vec_sort_with_function
- (spd->policies[IPSEC_SPD_POLICY_IP6_INBOUND_BYPASS],
- ipsec_spd_entry_sort);
- }
- }
- else
- {
- if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
- {
- vec_add1 (spd->policies
- [IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT],
- policy_index);
- vec_sort_with_function (spd->policies
- [IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT],
- ipsec_spd_entry_sort);
- }
- else
- {
- vec_add1
- (spd->policies[IPSEC_SPD_POLICY_IP4_INBOUND_BYPASS],
- policy_index);
- vec_sort_with_function
- (spd->policies[IPSEC_SPD_POLICY_IP4_INBOUND_BYPASS],
- ipsec_spd_entry_sort);
- }
- }
- }
+ vec_add1 (spd->policies[policy->type], policy_index);
+ vec_sort_with_function (spd->policies[policy->type],
+ ipsec_spd_entry_sort);
*stat_index = policy_index;
}
else
{
- ipsec_spd_policy_t ptype;
u32 ii;
- FOR_EACH_IPSEC_SPD_POLICY_TYPE (ptype)
+ vec_foreach_index (ii, (spd->policies[policy->type]))
{
- vec_foreach_index (ii, (spd->policies[ptype]))
- {
- vp = pool_elt_at_index (im->policies, spd->policies[ptype][ii]);
- if (ipsec_policy_is_equal (vp, policy))
- {
- vec_del1 (spd->policies[ptype], ii);
- pool_put (im->policies, vp);
- goto done;
- }
- }
+ vp = pool_elt_at_index (im->policies,
+ spd->policies[policy->type][ii]);
+ if (ipsec_policy_is_equal (vp, policy))
+ {
+ vec_del1 (spd->policies[policy->type], ii);
+ ipsec_sa_unlock (vp->sa_index);
+ pool_put (im->policies, vp);
+ break;
+ }
}
- done:;
}
return 0;