ethernet: check destination mac for L3 in ethernet-input node
[vpp.git] / src / vnet / ipsec / ipsec_tun.h
1 /*
2  * ipsec_tun.h : IPSEC tunnel protection
3  *
4  * Copyright (c) 2015 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <vnet/ipsec/ipsec.h>
19
20 #define foreach_ipsec_protect_flags                                           \
21   _ (L2, 1, "l2")                                                             \
22   _ (ENCAPED, 2, "encapped")                                                  \
23   _ (ITF, 4, "itf")                                                           \
24   _ (FEAT, 8, "feat")
25
26 typedef enum ipsec_protect_flags_t_
27 {
28   IPSEC_PROTECT_NONE = 0,
29 #define _(a,b,c) IPSEC_PROTECT_##a = b,
30   foreach_ipsec_protect_flags
31 #undef _
32 } __clib_packed ipsec_protect_flags_t;
33
34 extern u8 *format_ipsec_tun_protect_flags (u8 * s, va_list * args);
35
36 /**
37  * result of a lookup in the protection bihash
38  */
39 typedef struct ipsec_tun_lkup_result_t_
40 {
41   u32 tun_index;
42   u32 sa_index;
43   u32 sw_if_index;
44   ipsec_protect_flags_t flags;
45   u8 __pad[3];
46 } ipsec_tun_lkup_result_t;
47
48 typedef struct ipsec4_tunnel_kv_t
49 {
50   /*
51    * Key fields: remote ip and spi on incoming packet
52    * all fields in NET byte order
53    */
54   u64 key;
55   ipsec_tun_lkup_result_t value;
56 } __clib_packed ipsec4_tunnel_kv_t;
57
58 STATIC_ASSERT_SIZEOF (ipsec4_tunnel_kv_t, sizeof (clib_bihash_kv_8_16_t));
59 STATIC_ASSERT_OFFSET_OF (ipsec4_tunnel_kv_t, value,
60                          STRUCT_OFFSET_OF (clib_bihash_kv_8_16_t, value));
61
62 static inline void
63 ipsec4_tunnel_mk_key (ipsec4_tunnel_kv_t * k,
64                       const ip4_address_t * ip, u32 spi)
65 {
66   k->key = (((u64) ip->as_u32) << 32 | spi);
67 }
68
69 static inline void
70 ipsec4_tunnel_extract_key (const ipsec4_tunnel_kv_t * k,
71                            ip4_address_t * ip, u32 * spi)
72 {
73   *spi = (u32) k->key;
74   (*ip).as_u32 = k->key >> 32;
75 }
76
77 typedef struct ipsec6_tunnel_kv_t_
78 {
79   /*
80    * Key fields: remote ip and spi on incoming packet
81    * all fields in NET byte order
82    */
83   struct
84   {
85     ip6_address_t remote_ip;
86     u32 spi;
87     u32 __pad;
88   } key;
89   ipsec_tun_lkup_result_t value;
90 } __clib_packed ipsec6_tunnel_kv_t;
91
92 STATIC_ASSERT_SIZEOF (ipsec6_tunnel_kv_t, sizeof (clib_bihash_kv_24_16_t));
93 STATIC_ASSERT_OFFSET_OF (ipsec6_tunnel_kv_t, value,
94                          STRUCT_OFFSET_OF (clib_bihash_kv_24_16_t, value));
95
96 extern u8 *format_ipsec4_tunnel_kv (u8 * s, va_list * args);
97 extern u8 *format_ipsec6_tunnel_kv (u8 * s, va_list * args);
98
99 typedef struct ipsec_ep_t_
100 {
101   ip46_address_t src;
102   ip46_address_t dst;
103 } ipsec_ep_t;
104
105 #define ITP_MAX_N_SA_IN 4
106
107 typedef struct ipsec_tun_protect_t_
108 {
109   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
110   index_t itp_out_sa;
111
112   /* not using a vector since we want the memory inline
113    * with this struct */
114   u32 itp_n_sa_in;
115   index_t itp_in_sas[ITP_MAX_N_SA_IN];
116
117   u32 itp_sw_if_index;
118
119   ipsec_ep_t itp_crypto;
120
121   ipsec_protect_flags_t itp_flags;
122   adj_index_t itp_ai;
123
124   ipsec_ep_t itp_tun;
125
126   ip_address_t *itp_key;
127
128 } ipsec_tun_protect_t;
129
130 #define FOR_EACH_IPSEC_PROTECT_INPUT_SAI(_itp, _sai, body) \
131 {                                                          \
132   u32 __ii;                                                \
133   for (__ii = 0; __ii < _itp->itp_n_sa_in; __ii++) {       \
134     _sai = itp->itp_in_sas[__ii];                          \
135     body;                                                  \
136   }                                                        \
137 }
138 #define FOR_EACH_IPSEC_PROTECT_INPUT_SA(_itp, _sa, body)   \
139 {                                                          \
140   u32 __ii;                                                \
141   for (__ii = 0; __ii < _itp->itp_n_sa_in; __ii++) {       \
142     _sa = ipsec_sa_get(itp->itp_in_sas[__ii]);             \
143     body;                                                  \
144   }                                                        \
145 }
146
147 extern int ipsec_tun_protect_update (u32 sw_if_index,
148                                      const ip_address_t * nh,
149                                      u32 sa_out, u32 * sa_ins);
150
151 extern int ipsec_tun_protect_del (u32 sw_if_index, const ip_address_t * nh);
152
153 typedef walk_rc_t (*ipsec_tun_protect_walk_cb_t) (index_t itpi, void *arg);
154 extern void ipsec_tun_protect_walk (ipsec_tun_protect_walk_cb_t fn,
155                                     void *cttx);
156 extern void ipsec_tun_protect_walk_itf (u32 sw_if_index,
157                                         ipsec_tun_protect_walk_cb_t fn,
158                                         void *cttx);
159
160 extern u8 *format_ipsec_tun_protect (u8 * s, va_list * args);
161 extern u8 *format_ipsec_tun_protect_index (u8 * s, va_list * args);
162
163 extern void ipsec_tun_register_nodes (ip_address_family_t af);
164 extern void ipsec_tun_unregister_nodes (ip_address_family_t af);
165
166 extern void ipsec_tun_table_init (ip_address_family_t af, uword table_size,
167                                   u32 n_buckets);
168
169 /*
170  * DP API
171  */
172 extern ipsec_tun_protect_t *ipsec_tun_protect_pool;
173
174 always_inline ipsec_tun_protect_t *
175 ipsec_tun_protect_get (u32 index)
176 {
177   return (pool_elt_at_index (ipsec_tun_protect_pool, index));
178 }
179
180 extern index_t *ipsec_tun_protect_sa_by_adj_index;
181 always_inline index_t
182 ipsec_tun_protect_get_sa_out (adj_index_t ai)
183 {
184   ASSERT (vec_len (ipsec_tun_protect_sa_by_adj_index) > ai);
185
186   return (ipsec_tun_protect_sa_by_adj_index[ai]);
187 }
188
189 /*
190  * fd.io coding-style-patch-verification: ON
191  *
192  * Local Variables:
193  * eval: (c-set-style "gnu")
194  * End:
195  */