quic: fix coverity warning
[vpp.git] / src / vnet / ipsec / ipsec_spd_policy.h
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       ip6_address_t ip6_laddr;
132       ip6_address_t ip6_raddr;
133     };
134
135     u16 lport;
136     u16 rport;
137     u16 protocol;
138     u16 is_ipv6;
139   };
140   /* for ipv6 */
141   clib_bihash_kv_40_8_t kv_40_8;
142   /* for ipv4 */
143   struct
144   {
145     u64 padding_for_kv_16_8[3];
146     clib_bihash_kv_16_8_t kv_16_8;
147   };
148 } ipsec_fp_5tuple_t;
149
150 /*
151  * An element describing a particular policy  mask,
152  * and refcount of policies with same mask.
153  */
154 typedef struct
155 {
156   /** Required for pool_get_aligned */
157   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
158   ipsec_fp_5tuple_t mask;
159   u32 refcount; /* counts how many policies use this mask */
160 } ipsec_fp_mask_type_entry_t;
161
162 /*
163  * Bihash lookup value,
164  * contains an unordered vector of policies indices in policy pool.
165  */
166 typedef union
167 {
168   u64 as_u64;
169   struct
170   {
171     u32 *fp_policies_ids;
172   };
173 } ipsec_fp_lookup_value_t;
174
175 /**
176  *  @brief add or delete a fast path policy
177  */
178 int ipsec_fp_add_del_policy (void *fp_spd, ipsec_policy_t *policy, int is_add,
179                              u32 *stat_index);
180
181 static_always_inline int
182 ipsec_policy_is_equal (ipsec_policy_t *p1, ipsec_policy_t *p2)
183 {
184   if (p1->priority != p2->priority)
185     return 0;
186   if (p1->type != p2->type)
187     return (0);
188   if (p1->policy != p2->policy)
189     return (0);
190   if (p1->sa_id != p2->sa_id)
191     return (0);
192   if (p1->protocol != p2->protocol)
193     return (0);
194   if (p1->lport.start != p2->lport.start)
195     return (0);
196   if (p1->lport.stop != p2->lport.stop)
197     return (0);
198   if (p1->rport.start != p2->rport.start)
199     return (0);
200   if (p1->rport.stop != p2->rport.stop)
201     return (0);
202   if (p1->is_ipv6 != p2->is_ipv6)
203     return (0);
204   if (p2->is_ipv6)
205     {
206       if (p1->laddr.start.ip6.as_u64[0] != p2->laddr.start.ip6.as_u64[0])
207         return (0);
208       if (p1->laddr.start.ip6.as_u64[1] != p2->laddr.start.ip6.as_u64[1])
209         return (0);
210       if (p1->laddr.stop.ip6.as_u64[0] != p2->laddr.stop.ip6.as_u64[0])
211         return (0);
212       if (p1->laddr.stop.ip6.as_u64[1] != p2->laddr.stop.ip6.as_u64[1])
213         return (0);
214       if (p1->raddr.start.ip6.as_u64[0] != p2->raddr.start.ip6.as_u64[0])
215         return (0);
216       if (p1->raddr.start.ip6.as_u64[1] != p2->raddr.start.ip6.as_u64[1])
217         return (0);
218       if (p1->raddr.stop.ip6.as_u64[0] != p2->raddr.stop.ip6.as_u64[0])
219         return (0);
220       if (p1->laddr.stop.ip6.as_u64[1] != p2->laddr.stop.ip6.as_u64[1])
221         return (0);
222     }
223   else
224     {
225       if (p1->laddr.start.ip4.as_u32 != p2->laddr.start.ip4.as_u32)
226         return (0);
227       if (p1->laddr.stop.ip4.as_u32 != p2->laddr.stop.ip4.as_u32)
228         return (0);
229       if (p1->raddr.start.ip4.as_u32 != p2->raddr.start.ip4.as_u32)
230         return (0);
231       if (p1->raddr.stop.ip4.as_u32 != p2->raddr.stop.ip4.as_u32)
232         return (0);
233     }
234   return (1);
235 }
236
237 #endif /* __IPSEC_SPD_POLICY_H__ */
238
239 /*
240  * fd.io coding-style-patch-verification: ON
241  *
242  * Local Variables:
243  * eval: (c-set-style "gnu")
244  * End:
245  */