blob: b50f5b1ff674fc4057faf2d311425fe7094bb151 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
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#include <vnet/ip/ip.h>
16#include <vnet/classify/vnet_classify.h>
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010017#include <vnet/classify/in_out_acl.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070018
Dave Barachd7cb1b52016-12-09 09:52:16 -050019typedef struct
20{
Ed Warnickecb9cada2015-12-08 15:45:58 -070021 u32 sw_if_index;
22 u32 next_index;
23 u32 table_index;
24 u32 offset;
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010025} ip_in_out_acl_trace_t;
Ed Warnickecb9cada2015-12-08 15:45:58 -070026
27/* packet trace format function */
Dave Barachd7cb1b52016-12-09 09:52:16 -050028static u8 *
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010029format_ip_in_out_acl_trace (u8 * s, u32 is_output, va_list * args)
Ed Warnickecb9cada2015-12-08 15:45:58 -070030{
31 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
32 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010033 ip_in_out_acl_trace_t *t = va_arg (*args, ip_in_out_acl_trace_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070034
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010035 s = format (s, "%s: sw_if_index %d, next_index %d, table %d, offset %d",
36 is_output ? "OUTACL" : "INACL",
Dave Barachd7cb1b52016-12-09 09:52:16 -050037 t->sw_if_index, t->next_index, t->table_index, t->offset);
Ed Warnickecb9cada2015-12-08 15:45:58 -070038 return s;
39}
40
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010041static u8 *
42format_ip_inacl_trace (u8 * s, va_list * args)
43{
44 return format_ip_in_out_acl_trace (s, 0 /* is_output */ , args);
45}
46
47static u8 *
48format_ip_outacl_trace (u8 * s, va_list * args)
49{
50 return format_ip_in_out_acl_trace (s, 1 /* is_output */ , args);
51}
52
Ed Warnickecb9cada2015-12-08 15:45:58 -070053vlib_node_registration_t ip4_inacl_node;
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010054vlib_node_registration_t ip4_outacl_node;
Ed Warnickecb9cada2015-12-08 15:45:58 -070055vlib_node_registration_t ip6_inacl_node;
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010056vlib_node_registration_t ip6_outacl_node;
Ed Warnickecb9cada2015-12-08 15:45:58 -070057
58#define foreach_ip_inacl_error \
59_(MISS, "input ACL misses") \
60_(HIT, "input ACL hits") \
61_(CHAIN_HIT, "input ACL hits after chain walk")
62
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010063#define foreach_ip_outacl_error \
64_(MISS, "output ACL misses") \
65_(HIT, "output ACL hits") \
66_(CHAIN_HIT, "output ACL hits after chain walk")
67
Dave Barachd7cb1b52016-12-09 09:52:16 -050068typedef enum
69{
Ed Warnickecb9cada2015-12-08 15:45:58 -070070#define _(sym,str) IP_INACL_ERROR_##sym,
71 foreach_ip_inacl_error
72#undef _
Dave Barachd7cb1b52016-12-09 09:52:16 -050073 IP_INACL_N_ERROR,
Ed Warnickecb9cada2015-12-08 15:45:58 -070074} ip_inacl_error_t;
75
Dave Barachd7cb1b52016-12-09 09:52:16 -050076static char *ip_inacl_error_strings[] = {
Ed Warnickecb9cada2015-12-08 15:45:58 -070077#define _(sym,string) string,
78 foreach_ip_inacl_error
79#undef _
80};
81
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010082typedef enum
83{
84#define _(sym,str) IP_OUTACL_ERROR_##sym,
85 foreach_ip_outacl_error
86#undef _
87 IP_OUTACL_N_ERROR,
88} ip_outacl_error_t;
89
90static char *ip_outacl_error_strings[] = {
91#define _(sym,string) string,
92 foreach_ip_outacl_error
93#undef _
94};
95
Ed Warnickecb9cada2015-12-08 15:45:58 -070096static inline uword
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +010097ip_in_out_acl_inline (vlib_main_t * vm,
98 vlib_node_runtime_t * node, vlib_frame_t * frame,
99 int is_ip4, int is_output)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700100{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500101 u32 n_left_from, *from, *to_next;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102 acl_next_index_t next_index;
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100103 in_out_acl_main_t *am = &in_out_acl_main;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500104 vnet_classify_main_t *vcm = am->vnet_classify_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700105 f64 now = vlib_time_now (vm);
106 u32 hits = 0;
107 u32 misses = 0;
108 u32 chain_hits = 0;
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100109 in_out_acl_table_id_t tid;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500110 vlib_node_runtime_t *error_node;
Dave Barachf39ff742016-03-20 10:14:45 -0400111 u32 n_next_nodes;
112
113 n_next_nodes = node->n_next_nodes;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700114
115 if (is_ip4)
116 {
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100117 tid = IN_OUT_ACL_TABLE_IP4;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700118 error_node = vlib_node_get_runtime (vm, ip4_input_node.index);
119 }
120 else
121 {
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100122 tid = IN_OUT_ACL_TABLE_IP6;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700123 error_node = vlib_node_get_runtime (vm, ip6_input_node.index);
124 }
125
126 from = vlib_frame_vector_args (frame);
127 n_left_from = frame->n_vectors;
128
129 /* First pass: compute hashes */
130
131 while (n_left_from > 2)
132 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500133 vlib_buffer_t *b0, *b1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700134 u32 bi0, bi1;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500135 u8 *h0, *h1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700136 u32 sw_if_index0, sw_if_index1;
137 u32 table_index0, table_index1;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500138 vnet_classify_table_t *t0, *t1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700139
140 /* prefetch next iteration */
141 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500142 vlib_buffer_t *p1, *p2;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700143
Dave Barachd7cb1b52016-12-09 09:52:16 -0500144 p1 = vlib_get_buffer (vm, from[1]);
145 p2 = vlib_get_buffer (vm, from[2]);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700146
Dave Barachd7cb1b52016-12-09 09:52:16 -0500147 vlib_prefetch_buffer_header (p1, STORE);
148 CLIB_PREFETCH (p1->data, CLIB_CACHE_LINE_BYTES, STORE);
149 vlib_prefetch_buffer_header (p2, STORE);
150 CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700151 }
152
153 bi0 = from[0];
154 b0 = vlib_get_buffer (vm, bi0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700155
156 bi1 = from[1];
157 b1 = vlib_get_buffer (vm, bi1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700158
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100159 sw_if_index0 =
160 vnet_buffer (b0)->sw_if_index[is_output ? VLIB_TX : VLIB_RX];
Dave Barachd7cb1b52016-12-09 09:52:16 -0500161 table_index0 =
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100162 am->classify_table_index_by_sw_if_index[is_output][tid][sw_if_index0];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700163
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100164 sw_if_index1 =
165 vnet_buffer (b1)->sw_if_index[is_output ? VLIB_TX : VLIB_RX];
Dave Barachd7cb1b52016-12-09 09:52:16 -0500166 table_index1 =
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100167 am->classify_table_index_by_sw_if_index[is_output][tid][sw_if_index1];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700168
169 t0 = pool_elt_at_index (vcm->tables, table_index0);
170
171 t1 = pool_elt_at_index (vcm->tables, table_index1);
172
Steve Shin25e26dc2016-11-08 10:47:10 -0800173 if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
Dave Barachd7cb1b52016-12-09 09:52:16 -0500174 h0 = (void *) vlib_buffer_get_current (b0) + t0->current_data_offset;
Steve Shin25e26dc2016-11-08 10:47:10 -0800175 else
Dave Barachd7cb1b52016-12-09 09:52:16 -0500176 h0 = b0->data;
Steve Shin25e26dc2016-11-08 10:47:10 -0800177
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100178 if (is_output)
179 {
180 /* Save the rewrite length, since we are using the l2_classify struct */
181 vnet_buffer (b0)->l2_classify.pad.l2_len =
182 vnet_buffer (b0)->ip.save_rewrite_length;
183 /* advance the match pointer so the matching happens on IP header */
184 h0 += vnet_buffer (b0)->l2_classify.pad.l2_len;
185 }
186
Dave Barachd7cb1b52016-12-09 09:52:16 -0500187 vnet_buffer (b0)->l2_classify.hash =
188 vnet_classify_hash_packet (t0, (u8 *) h0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700189
Dave Barachd7cb1b52016-12-09 09:52:16 -0500190 vnet_classify_prefetch_bucket (t0, vnet_buffer (b0)->l2_classify.hash);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700191
Steve Shin25e26dc2016-11-08 10:47:10 -0800192 if (t1->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
Dave Barachd7cb1b52016-12-09 09:52:16 -0500193 h1 = (void *) vlib_buffer_get_current (b1) + t1->current_data_offset;
Steve Shin25e26dc2016-11-08 10:47:10 -0800194 else
Dave Barachd7cb1b52016-12-09 09:52:16 -0500195 h1 = b1->data;
Steve Shin25e26dc2016-11-08 10:47:10 -0800196
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100197 if (is_output)
198 {
199 /* Save the rewrite length, since we are using the l2_classify struct */
200 vnet_buffer (b1)->l2_classify.pad.l2_len =
201 vnet_buffer (b1)->ip.save_rewrite_length;
202 /* advance the match pointer so the matching happens on IP header */
203 h1 += vnet_buffer (b1)->l2_classify.pad.l2_len;
204 }
205
Dave Barachd7cb1b52016-12-09 09:52:16 -0500206 vnet_buffer (b1)->l2_classify.hash =
207 vnet_classify_hash_packet (t1, (u8 *) h1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208
Dave Barachd7cb1b52016-12-09 09:52:16 -0500209 vnet_classify_prefetch_bucket (t1, vnet_buffer (b1)->l2_classify.hash);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210
Dave Barachd7cb1b52016-12-09 09:52:16 -0500211 vnet_buffer (b0)->l2_classify.table_index = table_index0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700212
Dave Barachd7cb1b52016-12-09 09:52:16 -0500213 vnet_buffer (b1)->l2_classify.table_index = table_index1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700214
215 from += 2;
216 n_left_from -= 2;
217 }
218
219 while (n_left_from > 0)
220 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500221 vlib_buffer_t *b0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700222 u32 bi0;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500223 u8 *h0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700224 u32 sw_if_index0;
225 u32 table_index0;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500226 vnet_classify_table_t *t0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700227
228 bi0 = from[0];
229 b0 = vlib_get_buffer (vm, bi0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700230
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100231 sw_if_index0 =
232 vnet_buffer (b0)->sw_if_index[is_output ? VLIB_TX : VLIB_RX];
Dave Barachd7cb1b52016-12-09 09:52:16 -0500233 table_index0 =
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100234 am->classify_table_index_by_sw_if_index[is_output][tid][sw_if_index0];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700235
236 t0 = pool_elt_at_index (vcm->tables, table_index0);
Steve Shin25e26dc2016-11-08 10:47:10 -0800237
238 if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
Dave Barachd7cb1b52016-12-09 09:52:16 -0500239 h0 = (void *) vlib_buffer_get_current (b0) + t0->current_data_offset;
Steve Shin25e26dc2016-11-08 10:47:10 -0800240 else
Dave Barachd7cb1b52016-12-09 09:52:16 -0500241 h0 = b0->data;
Steve Shin25e26dc2016-11-08 10:47:10 -0800242
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100243 if (is_output)
244 {
245 /* Save the rewrite length, since we are using the l2_classify struct */
246 vnet_buffer (b0)->l2_classify.pad.l2_len =
247 vnet_buffer (b0)->ip.save_rewrite_length;
248 /* advance the match pointer so the matching happens on IP header */
249 h0 += vnet_buffer (b0)->l2_classify.pad.l2_len;
250 }
251
Dave Barachd7cb1b52016-12-09 09:52:16 -0500252 vnet_buffer (b0)->l2_classify.hash =
253 vnet_classify_hash_packet (t0, (u8 *) h0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700254
Dave Barachd7cb1b52016-12-09 09:52:16 -0500255 vnet_buffer (b0)->l2_classify.table_index = table_index0;
256 vnet_classify_prefetch_bucket (t0, vnet_buffer (b0)->l2_classify.hash);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700257
258 from++;
259 n_left_from--;
260 }
261
262 next_index = node->cached_next_index;
263 from = vlib_frame_vector_args (frame);
264 n_left_from = frame->n_vectors;
265
266 while (n_left_from > 0)
267 {
268 u32 n_left_to_next;
269
Dave Barachd7cb1b52016-12-09 09:52:16 -0500270 vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700271
272 /* Not enough load/store slots to dual loop... */
273 while (n_left_from > 0 && n_left_to_next > 0)
Dave Barachd7cb1b52016-12-09 09:52:16 -0500274 {
275 u32 bi0;
276 vlib_buffer_t *b0;
277 u32 next0 = ACL_NEXT_INDEX_DENY;
278 u32 table_index0;
279 vnet_classify_table_t *t0;
280 vnet_classify_entry_t *e0;
281 u64 hash0;
282 u8 *h0;
283 u8 error0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700284
Dave Barachd7cb1b52016-12-09 09:52:16 -0500285 /* Stride 3 seems to work best */
286 if (PREDICT_TRUE (n_left_from > 3))
287 {
288 vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
289 vnet_classify_table_t *tp1;
290 u32 table_index1;
291 u64 phash1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700292
Dave Barachd7cb1b52016-12-09 09:52:16 -0500293 table_index1 = vnet_buffer (p1)->l2_classify.table_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700294
Dave Barachd7cb1b52016-12-09 09:52:16 -0500295 if (PREDICT_TRUE (table_index1 != ~0))
296 {
297 tp1 = pool_elt_at_index (vcm->tables, table_index1);
298 phash1 = vnet_buffer (p1)->l2_classify.hash;
299 vnet_classify_prefetch_entry (tp1, phash1);
300 }
301 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700302
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100303
Dave Barachd7cb1b52016-12-09 09:52:16 -0500304 /* speculatively enqueue b0 to the current next frame */
305 bi0 = from[0];
306 to_next[0] = bi0;
307 from += 1;
308 to_next += 1;
309 n_left_from -= 1;
310 n_left_to_next -= 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700311
Dave Barachd7cb1b52016-12-09 09:52:16 -0500312 b0 = vlib_get_buffer (vm, bi0);
313 table_index0 = vnet_buffer (b0)->l2_classify.table_index;
314 e0 = 0;
315 t0 = 0;
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100316 vnet_get_config_data (am->vnet_config_main[is_output][tid],
Dave Barachd7cb1b52016-12-09 09:52:16 -0500317 &b0->current_config_index, &next0,
318 /* # bytes of config data */ 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700319
Dave Barachd7cb1b52016-12-09 09:52:16 -0500320 vnet_buffer (b0)->l2_classify.opaque_index = ~0;
rangan09306492016-04-13 17:08:11 +0530321
Dave Barachd7cb1b52016-12-09 09:52:16 -0500322 if (PREDICT_TRUE (table_index0 != ~0))
323 {
324 hash0 = vnet_buffer (b0)->l2_classify.hash;
325 t0 = pool_elt_at_index (vcm->tables, table_index0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700326
Dave Barachd7cb1b52016-12-09 09:52:16 -0500327 if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
328 h0 =
329 (void *) vlib_buffer_get_current (b0) +
330 t0->current_data_offset;
331 else
332 h0 = b0->data;
Steve Shin25e26dc2016-11-08 10:47:10 -0800333
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100334 /* advance the match pointer so the matching happens on IP header */
335 if (is_output)
336 h0 += vnet_buffer (b0)->l2_classify.pad.l2_len;
337
Dave Barachd7cb1b52016-12-09 09:52:16 -0500338 e0 = vnet_classify_find_entry (t0, (u8 *) h0, hash0, now);
339 if (e0)
340 {
341 vnet_buffer (b0)->l2_classify.opaque_index
342 = e0->opaque_index;
343 vlib_buffer_advance (b0, e0->advance);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700344
Dave Barachd7cb1b52016-12-09 09:52:16 -0500345 next0 = (e0->next_index < n_next_nodes) ?
346 e0->next_index : next0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700347
Dave Barachd7cb1b52016-12-09 09:52:16 -0500348 hits++;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700349
Dave Barachd7cb1b52016-12-09 09:52:16 -0500350 if (is_ip4)
351 error0 = (next0 == ACL_NEXT_INDEX_DENY) ?
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100352 (is_output ? IP4_ERROR_OUTACL_SESSION_DENY :
353 IP4_ERROR_INACL_SESSION_DENY) : IP4_ERROR_NONE;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500354 else
355 error0 = (next0 == ACL_NEXT_INDEX_DENY) ?
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100356 (is_output ? IP6_ERROR_OUTACL_SESSION_DENY :
357 IP6_ERROR_INACL_SESSION_DENY) : IP6_ERROR_NONE;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500358 b0->error = error_node->errors[error0];
Steve Shin25e26dc2016-11-08 10:47:10 -0800359
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100360 if (!is_output)
361 {
362 if (e0->action == CLASSIFY_ACTION_SET_IP4_FIB_INDEX ||
363 e0->action == CLASSIFY_ACTION_SET_IP6_FIB_INDEX)
364 vnet_buffer (b0)->sw_if_index[VLIB_TX] = e0->metadata;
365 else if (e0->action == CLASSIFY_ACTION_SET_METADATA)
366 vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
367 e0->metadata;
368 }
Dave Barachd7cb1b52016-12-09 09:52:16 -0500369 }
370 else
371 {
372 while (1)
373 {
374 if (PREDICT_TRUE (t0->next_table_index != ~0))
375 t0 = pool_elt_at_index (vcm->tables,
376 t0->next_table_index);
377 else
378 {
379 next0 = (t0->miss_next_index < n_next_nodes) ?
380 t0->miss_next_index : next0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700381
Dave Barachd7cb1b52016-12-09 09:52:16 -0500382 misses++;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700383
Dave Barachd7cb1b52016-12-09 09:52:16 -0500384 if (is_ip4)
385 error0 = (next0 == ACL_NEXT_INDEX_DENY) ?
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100386 (is_output ? IP4_ERROR_OUTACL_TABLE_MISS :
387 IP4_ERROR_INACL_TABLE_MISS) : IP4_ERROR_NONE;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500388 else
389 error0 = (next0 == ACL_NEXT_INDEX_DENY) ?
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100390 (is_output ? IP6_ERROR_OUTACL_TABLE_MISS :
391 IP6_ERROR_INACL_TABLE_MISS) : IP6_ERROR_NONE;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500392 b0->error = error_node->errors[error0];
393 break;
394 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700395
Dave Barachd7cb1b52016-12-09 09:52:16 -0500396 if (t0->current_data_flag ==
397 CLASSIFY_FLAG_USE_CURR_DATA)
398 h0 =
399 (void *) vlib_buffer_get_current (b0) +
400 t0->current_data_offset;
401 else
402 h0 = b0->data;
Steve Shin25e26dc2016-11-08 10:47:10 -0800403
Dave Barachd7cb1b52016-12-09 09:52:16 -0500404 hash0 = vnet_classify_hash_packet (t0, (u8 *) h0);
405 e0 = vnet_classify_find_entry
406 (t0, (u8 *) h0, hash0, now);
407 if (e0)
408 {
409 vnet_buffer (b0)->l2_classify.opaque_index
410 = e0->opaque_index;
411 vlib_buffer_advance (b0, e0->advance);
412 next0 = (e0->next_index < n_next_nodes) ?
413 e0->next_index : next0;
414 hits++;
415 chain_hits++;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700416
Dave Barachd7cb1b52016-12-09 09:52:16 -0500417 if (is_ip4)
418 error0 = (next0 == ACL_NEXT_INDEX_DENY) ?
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100419 (is_output ? IP4_ERROR_OUTACL_SESSION_DENY :
420 IP4_ERROR_INACL_SESSION_DENY) : IP4_ERROR_NONE;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500421 else
422 error0 = (next0 == ACL_NEXT_INDEX_DENY) ?
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100423 (is_output ? IP6_ERROR_OUTACL_SESSION_DENY :
424 IP6_ERROR_INACL_SESSION_DENY) : IP6_ERROR_NONE;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500425 b0->error = error_node->errors[error0];
Steve Shin25e26dc2016-11-08 10:47:10 -0800426
Dave Barachd7cb1b52016-12-09 09:52:16 -0500427 if (e0->action == CLASSIFY_ACTION_SET_IP4_FIB_INDEX
428 || e0->action ==
429 CLASSIFY_ACTION_SET_IP6_FIB_INDEX)
430 vnet_buffer (b0)->sw_if_index[VLIB_TX] =
431 e0->metadata;
432 break;
433 }
434 }
435 }
436 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700437
Dave Barachd7cb1b52016-12-09 09:52:16 -0500438 if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
439 && (b0->flags & VLIB_BUFFER_IS_TRACED)))
440 {
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100441 ip_in_out_acl_trace_t *t =
Dave Barachd7cb1b52016-12-09 09:52:16 -0500442 vlib_add_trace (vm, node, b0, sizeof (*t));
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100443 t->sw_if_index =
444 vnet_buffer (b0)->sw_if_index[is_output ? VLIB_TX : VLIB_RX];
Dave Barachd7cb1b52016-12-09 09:52:16 -0500445 t->next_index = next0;
446 t->table_index = t0 ? t0 - vcm->tables : ~0;
447 t->offset = (e0 && t0) ? vnet_classify_get_offset (t0, e0) : ~0;
448 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700449
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100450 if ((next0 == ACL_NEXT_INDEX_DENY) && is_output)
451 {
452 /* on output, for the drop node to work properly, go back to ip header */
453 vlib_buffer_advance (b0, vnet_buffer (b0)->l2.l2_len);
454 }
455
Dave Barachd7cb1b52016-12-09 09:52:16 -0500456 /* verify speculative enqueue, maybe switch current next frame */
457 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
458 to_next, n_left_to_next,
459 bi0, next0);
460 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700461
462 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
463 }
464
465 vlib_node_increment_counter (vm, node->node_index,
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100466 is_output ? IP_OUTACL_ERROR_MISS :
Dave Barachd7cb1b52016-12-09 09:52:16 -0500467 IP_INACL_ERROR_MISS, misses);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700468 vlib_node_increment_counter (vm, node->node_index,
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100469 is_output ? IP_OUTACL_ERROR_HIT :
Dave Barachd7cb1b52016-12-09 09:52:16 -0500470 IP_INACL_ERROR_HIT, hits);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700471 vlib_node_increment_counter (vm, node->node_index,
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100472 is_output ? IP_OUTACL_ERROR_CHAIN_HIT :
Dave Barachd7cb1b52016-12-09 09:52:16 -0500473 IP_INACL_ERROR_CHAIN_HIT, chain_hits);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700474 return frame->n_vectors;
475}
476
477static uword
Dave Barachd7cb1b52016-12-09 09:52:16 -0500478ip4_inacl (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700479{
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100480 return ip_in_out_acl_inline (vm, node, frame, 1 /* is_ip4 */ ,
481 0 /* is_output */ );
482}
483
484static uword
485ip4_outacl (vlib_main_t * vm, vlib_node_runtime_t * node,
486 vlib_frame_t * frame)
487{
488 return ip_in_out_acl_inline (vm, node, frame, 1 /* is_ip4 */ ,
489 1 /* is_output */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700490}
491
492
Dave Barachd7cb1b52016-12-09 09:52:16 -0500493/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700494VLIB_REGISTER_NODE (ip4_inacl_node) = {
495 .function = ip4_inacl,
496 .name = "ip4-inacl",
497 .vector_size = sizeof (u32),
498 .format_trace = format_ip_inacl_trace,
499 .n_errors = ARRAY_LEN(ip_inacl_error_strings),
500 .error_strings = ip_inacl_error_strings,
501
502 .n_next_nodes = ACL_NEXT_INDEX_N_NEXT,
503 .next_nodes = {
Vijayabhaskar Katamreddyce074122017-11-15 13:50:26 -0800504 [ACL_NEXT_INDEX_DENY] = "ip4-drop",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700505 },
506};
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100507
508VLIB_REGISTER_NODE (ip4_outacl_node) = {
509 .function = ip4_outacl,
510 .name = "ip4-outacl",
511 .vector_size = sizeof (u32),
512 .format_trace = format_ip_outacl_trace,
513 .n_errors = ARRAY_LEN(ip_outacl_error_strings),
514 .error_strings = ip_outacl_error_strings,
515
516 .n_next_nodes = ACL_NEXT_INDEX_N_NEXT,
517 .next_nodes = {
518 [ACL_NEXT_INDEX_DENY] = "ip4-drop",
519 },
520};
Dave Barachd7cb1b52016-12-09 09:52:16 -0500521/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700522
Dave Barachd7cb1b52016-12-09 09:52:16 -0500523VLIB_NODE_FUNCTION_MULTIARCH (ip4_inacl_node, ip4_inacl);
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100524VLIB_NODE_FUNCTION_MULTIARCH (ip4_outacl_node, ip4_outacl);
Damjan Marion1c80e832016-05-11 23:07:18 +0200525
Ed Warnickecb9cada2015-12-08 15:45:58 -0700526static uword
Dave Barachd7cb1b52016-12-09 09:52:16 -0500527ip6_inacl (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700528{
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100529 return ip_in_out_acl_inline (vm, node, frame, 0 /* is_ip4 */ ,
530 0 /* is_output */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700531}
532
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100533static uword
534ip6_outacl (vlib_main_t * vm, vlib_node_runtime_t * node,
535 vlib_frame_t * frame)
536{
537 return ip_in_out_acl_inline (vm, node, frame, 0 /* is_ip4 */ ,
538 1 /* is_output */ );
539}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700540
Dave Barachd7cb1b52016-12-09 09:52:16 -0500541/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700542VLIB_REGISTER_NODE (ip6_inacl_node) = {
543 .function = ip6_inacl,
544 .name = "ip6-inacl",
545 .vector_size = sizeof (u32),
546 .format_trace = format_ip_inacl_trace,
547 .n_errors = ARRAY_LEN(ip_inacl_error_strings),
548 .error_strings = ip_inacl_error_strings,
549
550 .n_next_nodes = ACL_NEXT_INDEX_N_NEXT,
551 .next_nodes = {
Vijayabhaskar Katamreddyce074122017-11-15 13:50:26 -0800552 [ACL_NEXT_INDEX_DENY] = "ip6-drop",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700553 },
554};
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100555
556VLIB_REGISTER_NODE (ip6_outacl_node) = {
557 .function = ip6_outacl,
558 .name = "ip6-outacl",
559 .vector_size = sizeof (u32),
560 .format_trace = format_ip_outacl_trace,
561 .n_errors = ARRAY_LEN(ip_outacl_error_strings),
562 .error_strings = ip_outacl_error_strings,
563
564 .n_next_nodes = ACL_NEXT_INDEX_N_NEXT,
565 .next_nodes = {
566 [ACL_NEXT_INDEX_DENY] = "ip6-drop",
567 },
568};
Dave Barachd7cb1b52016-12-09 09:52:16 -0500569/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700570
Dave Barachd7cb1b52016-12-09 09:52:16 -0500571VLIB_NODE_FUNCTION_MULTIARCH (ip6_inacl_node, ip6_inacl);
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100572VLIB_NODE_FUNCTION_MULTIARCH (ip6_outacl_node, ip6_outacl);
Damjan Marion1c80e832016-05-11 23:07:18 +0200573
Ed Warnickecb9cada2015-12-08 15:45:58 -0700574static clib_error_t *
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100575ip_in_out_acl_init (vlib_main_t * vm)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700576{
577 return 0;
578}
579
Andrew Yourtchenko815d7d52018-02-07 11:37:02 +0100580VLIB_INIT_FUNCTION (ip_in_out_acl_init);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700581
Dave Barachd7cb1b52016-12-09 09:52:16 -0500582
583/*
584 * fd.io coding-style-patch-verification: ON
585 *
586 * Local Variables:
587 * eval: (c-set-style "gnu")
588 * End:
589 */