Line data Source code
1 : /* 2 : * Copyright (c) 2015 Cisco and/or its affiliates. 3 : * Licensed under the Apache License, Version 2.0 (the "License"); 4 : * you may not use this file except in compliance with the License. 5 : * You may obtain a copy of the License at: 6 : * 7 : * http://www.apache.org/licenses/LICENSE-2.0 8 : * 9 : * Unless required by applicable law or agreed to in writing, software 10 : * distributed under the License is distributed on an "AS IS" BASIS, 11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : * See the License for the specific language governing permissions and 13 : * limitations under the License. 14 : */ 15 : #ifndef __IPSEC_SPD_POLICY_H__ 16 : #define __IPSEC_SPD_POLICY_H__ 17 : 18 : #include <vppinfra/bihash_40_8.h> 19 : #include <vppinfra/bihash_16_8.h> 20 : #include <vnet/ipsec/ipsec_spd.h> 21 : /** 22 : * calculated as max number of flows (2^10) divided by KVP_PER_PAGE (4) 23 : */ 24 : #define IPSEC_FP_HASH_LOOKUP_HASH_BUCKETS (1 << 8) 25 : 26 : #define IPSEC_POLICY_PROTOCOL_ANY IP_PROTOCOL_RESERVED 27 : 28 : /** 29 : * This number is calculated as ceil power of 2 for the number 30 : * sizeof(clib_bihash_kv_16_8_t)=24 * BIHASH_KVP_PER_PAGE=4 * COLLISIONS_NO=8 31 : * 32 : */ 33 : 34 : #define IPSEC_FP_IP4_HASH_MEM_PER_BUCKET 1024 35 : 36 : /** 37 : * This number is calculated as ceil power of 2 for the number 38 : * sizeof(clib_bihash_kv_40_8_t)=48 * BIHASH_KVP_PER_PAGE=4 * COLLISIONS_NO=8 39 : * 40 : */ 41 : #define IPSEC_FP_IP6_HASH_MEM_PER_BUCKET 2048 42 : 43 : #define foreach_ipsec_policy_action \ 44 : _ (0, BYPASS, "bypass") \ 45 : _ (1, DISCARD, "discard") \ 46 : _ (2, RESOLVE, "resolve") \ 47 : _ (3, PROTECT, "protect") 48 : 49 : typedef enum 50 : { 51 : #define _(v, f, s) IPSEC_POLICY_ACTION_##f = v, 52 : foreach_ipsec_policy_action 53 : #undef _ 54 : } ipsec_policy_action_t; 55 : 56 : #define IPSEC_POLICY_N_ACTION (IPSEC_POLICY_ACTION_PROTECT + 1) 57 : 58 : typedef struct 59 : { 60 : ip46_address_t start, stop; 61 : } ip46_address_range_t; 62 : 63 : typedef struct 64 : { 65 : u16 start, stop; 66 : } port_range_t; 67 : 68 : /** 69 : * @brief 70 : * Policy packet & bytes counters 71 : */ 72 : extern vlib_combined_counter_main_t ipsec_spd_policy_counters; 73 : 74 : /** 75 : * @brief A Secruity Policy. An entry in an SPD 76 : */ 77 : typedef struct ipsec_policy_t_ 78 : { 79 : u32 id; 80 : i32 priority; 81 : 82 : // the type of policy 83 : ipsec_spd_policy_type_t type; 84 : 85 : // Selector 86 : u8 is_ipv6; 87 : ip46_address_range_t laddr; 88 : ip46_address_range_t raddr; 89 : u8 protocol; 90 : port_range_t lport; 91 : port_range_t rport; 92 : 93 : // Policy 94 : ipsec_policy_action_t policy; 95 : u32 sa_id; 96 : u32 sa_index; 97 : u32 fp_mask_type_id; 98 : } ipsec_policy_t; 99 : 100 : /** 101 : * @brief Add/Delete a SPD 102 : */ 103 : extern int ipsec_add_del_policy (vlib_main_t * vm, 104 : ipsec_policy_t * policy, 105 : int is_add, u32 * stat_index); 106 : 107 : extern u8 *format_ipsec_policy (u8 * s, va_list * args); 108 : extern u8 *format_ipsec_policy_action (u8 * s, va_list * args); 109 : extern uword unformat_ipsec_policy_action (unformat_input_t * input, 110 : va_list * args); 111 : 112 : 113 : extern int ipsec_policy_mk_type (bool is_outbound, 114 : bool is_ipv6, 115 : ipsec_policy_action_t action, 116 : ipsec_spd_policy_type_t * type); 117 : 118 : /* A 5-tuple used to calculate the bihash entry */ 119 : typedef union 120 : { 121 : struct 122 : { 123 : union 124 : { 125 : struct 126 : { 127 : u32 l3_zero_pad[6]; 128 : ip4_address_t laddr; 129 : ip4_address_t raddr; 130 : }; 131 : struct 132 : { 133 : ip6_address_t ip6_laddr; 134 : ip6_address_t ip6_raddr; 135 : }; 136 : }; 137 : union 138 : { 139 : struct 140 : { 141 : u16 lport; 142 : u16 rport; 143 : }; 144 : u32 spi; 145 : }; 146 : u8 protocol; 147 : u8 action; 148 : u16 is_ipv6; 149 : }; 150 : /* for ipv6 */ 151 : clib_bihash_kv_40_8_t kv_40_8; 152 : /* for ipv4 */ 153 : struct 154 : { 155 : u64 padding_for_kv_16_8[3]; 156 : clib_bihash_kv_16_8_t kv_16_8; 157 : }; 158 : } ipsec_fp_5tuple_t; 159 : 160 : /* 161 : * An element describing a particular policy mask, 162 : * and refcount of policies with same mask. 163 : */ 164 : typedef struct 165 : { 166 : /** Required for pool_get_aligned */ 167 : CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); 168 : ipsec_fp_5tuple_t mask; 169 : u32 refcount; /* counts how many policies use this mask */ 170 : } ipsec_fp_mask_type_entry_t; 171 : 172 : /* 173 : * Bihash lookup value, 174 : * contains an unordered vector of policies indices in policy pool. 175 : */ 176 : typedef union 177 : { 178 : u64 as_u64; 179 : struct 180 : { 181 : u32 *fp_policies_ids; 182 : }; 183 : } ipsec_fp_lookup_value_t; 184 : 185 : /** 186 : * @brief add or delete a fast path policy 187 : */ 188 : int ipsec_fp_add_del_policy (void *fp_spd, ipsec_policy_t *policy, int is_add, 189 : u32 *stat_index); 190 : 191 : static_always_inline int 192 21625 : ipsec_policy_is_equal (ipsec_policy_t *p1, ipsec_policy_t *p2) 193 : { 194 21625 : if (p1->priority != p2->priority) 195 4977 : return 0; 196 16648 : if (p1->type != p2->type) 197 0 : return (0); 198 16648 : if (p1->policy != p2->policy) 199 7 : return (0); 200 16641 : if (p1->sa_id != p2->sa_id) 201 2 : return (0); 202 16639 : if (p1->protocol != p2->protocol) 203 0 : return (0); 204 16639 : if (p1->lport.start != p2->lport.start) 205 0 : return (0); 206 16639 : if (p1->lport.stop != p2->lport.stop) 207 0 : return (0); 208 16639 : if (p1->rport.start != p2->rport.start) 209 0 : return (0); 210 16639 : if (p1->rport.stop != p2->rport.stop) 211 0 : return (0); 212 16639 : if (p1->is_ipv6 != p2->is_ipv6) 213 0 : return (0); 214 16639 : if (p2->is_ipv6) 215 : { 216 8250 : if (p1->laddr.start.ip6.as_u64[0] != p2->laddr.start.ip6.as_u64[0]) 217 0 : return (0); 218 8250 : if (p1->laddr.start.ip6.as_u64[1] != p2->laddr.start.ip6.as_u64[1]) 219 0 : return (0); 220 8250 : if (p1->laddr.stop.ip6.as_u64[0] != p2->laddr.stop.ip6.as_u64[0]) 221 0 : return (0); 222 8250 : if (p1->laddr.stop.ip6.as_u64[1] != p2->laddr.stop.ip6.as_u64[1]) 223 0 : return (0); 224 8250 : if (p1->raddr.start.ip6.as_u64[0] != p2->raddr.start.ip6.as_u64[0]) 225 0 : return (0); 226 8250 : if (p1->raddr.start.ip6.as_u64[1] != p2->raddr.start.ip6.as_u64[1]) 227 0 : return (0); 228 8250 : if (p1->raddr.stop.ip6.as_u64[0] != p2->raddr.stop.ip6.as_u64[0]) 229 0 : return (0); 230 8250 : if (p1->laddr.stop.ip6.as_u64[1] != p2->laddr.stop.ip6.as_u64[1]) 231 0 : return (0); 232 : } 233 : else 234 : { 235 8389 : if (p1->laddr.start.ip4.as_u32 != p2->laddr.start.ip4.as_u32) 236 10 : return (0); 237 8379 : if (p1->laddr.stop.ip4.as_u32 != p2->laddr.stop.ip4.as_u32) 238 0 : return (0); 239 8379 : if (p1->raddr.start.ip4.as_u32 != p2->raddr.start.ip4.as_u32) 240 0 : return (0); 241 8379 : if (p1->raddr.stop.ip4.as_u32 != p2->raddr.stop.ip4.as_u32) 242 0 : return (0); 243 : } 244 16629 : return (1); 245 : } 246 : 247 : #endif /* __IPSEC_SPD_POLICY_H__ */ 248 : 249 : /* 250 : * fd.io coding-style-patch-verification: ON 251 : * 252 : * Local Variables: 253 : * eval: (c-set-style "gnu") 254 : * End: 255 : */