/* * Copyright (c) 2015 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include /* Dispatch functions meant to be instantiated elsewhere */ typedef struct { u32 next_index; u32 sw_if_index; u32 policer_index; } vnet_policer_trace_t; /* packet trace format function */ static u8 * format_policer_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); vnet_policer_trace_t *t = va_arg (*args, vnet_policer_trace_t *); s = format (s, "VNET_POLICER: sw_if_index %d policer_index %d next %d", t->sw_if_index, t->policer_index, t->next_index); return s; } #define foreach_vnet_policer_error \ _(TRANSMIT, "Packets Transmitted") \ _(DROP, "Packets Dropped") typedef enum { #define _(sym,str) VNET_POLICER_ERROR_##sym, foreach_vnet_policer_error #undef _ VNET_POLICER_N_ERROR, } vnet_policer_error_t; static char *vnet_policer_error_strings[] = { #define _(sym,string) string, foreach_vnet_policer_error #undef _ }; static inline uword vnet_policer_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame, vnet_policer_index_t which) { u32 n_left_from, *from, *to_next; vnet_policer_next_t next_index; vnet_policer_main_t *pm = &vnet_policer_main; u64 time_in_policer_periods; u32 transmitted = 0; time_in_policer_periods = clib_cpu_time_now () >> POLICER_TICKS_PER_PERIOD_SHIFT; from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; next_index = node->cached_next_index; while (n_left_from > 0) { u32 n_left_to_next; vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from >= 4 && n_left_to_next >= 2) { u32 bi0, bi1; vlib_buffer_t *b0, *b1; u32 next0, next1; u32 sw_if_index0, sw_if_index1; u32 pi0 = 0, pi1 = 0; u8 act0, act1; /* Prefetch next iteration. */ { vlib_buffer_t *b2, *b3; b2 = vlib_get_buffer (vm, from[2]); b3 = vlib_get_buffer (vm, from[3]); vlib_prefetch_buffer_header (b2, LOAD); vlib_prefetch_buffer_header (b3, LOAD); } /* speculatively enqueue b0 and b1 to the current next frame */ to_next[0] = bi0 = from[0]; to_next[1] = bi1 = from[1]; from += 2; to_next += 2; n_left_from -= 2; n_left_to_next -= 2; b0 = vlib_get_buffer (vm, bi0); b1 = vlib_get_buffer (vm, bi1); sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; next0 = VNET_POLICER_NEXT_TRANSMIT; sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; next1 = VNET_POLICER_NEXT_TRANSMIT; if (which == VNET_POLICER_INDEX_BY_SW_IF_INDEX) { pi0 = pm->policer_index_by_sw_if_index[sw_if_index0]; pi1 = pm->policer_index_by_sw_if_index[sw_if_index1]; } if (which == VNET_POLICER_INDEX_BY_OPAQUE) { pi0 = vnet_buffer (b0)->policer.index; pi1 = vnet_buffer (b1)->policer.index; } if (which == VNET_POLICER_INDEX_BY_EITHER) { pi0 = vnet_buffer (b0)->policer.index; pi0 = (pi0 != ~0) ? pi0 : pm->policer_index_by_sw_if_index[sw_if_index0]; pi1 = vnet_buffer (b1)->policer.index; pi1 = (pi1 != ~0) ? pi1 : pm->policer_index_by_sw_if_index[sw_if_index1]; } act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods, POLICE_CONFORM /* no chaining */ ); act1 = vnet_policer_police (vm, b1, pi1, time_in_policer_periods, POLICE_CONFORM /* no chaining */ ); if (PREDICT_FALSE (act0 == SSE2_QOS_ACTION_DROP)) /* drop action */ { next0 = VNET_POLICER_NEXT_DROP; b0->error = node->errors[VNET_POLICER_ERROR_DROP]; } else /* transmit or mark-and-transmit action */ { transmitted++; } if (PREDICT_FALSE (act1 == SSE2_QOS_ACTION_DROP)) /* drop action */ { next1 = VNET_POLICER_NEXT_DROP; b1->error = node->errors[VNET_POLICER_ERROR_DROP]; } else /* transmit or mark-and-transmit action */ { transmitted++; } if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE))) { if (b0->flags & VLIB_BUFFER_IS_TRACED) { vnet_policer_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); t->sw_if_index = sw_if_index0; t->next_index = next0; } if (b1->flags & VLIB_BUFFER_IS_TRACED) { vnet_policer_trace_t *t = vlib_add_trace (vm, node, b1, sizeof (*t)); t->sw_if_index = sw_if_index1; t->next_index = next1; } } /* verify speculative enqueues, maybe switch current next frame */ vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1); } while (n_left_from > 0 && n_left_to_next > 0) { u32 bi0; vlib_buffer_t *b0; u32 next0; u32 sw_if_index0; u32 pi0 = 0; u8 act0; bi0 = from[0]; to_next[0] = bi0; from += 1; to_next += 1; n_left_from -= 1; n_left_to_next -= 1; b0 = vlib_get_buffer (vm, bi0); sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; next0 = VNET_POLICER_NEXT_TRANSMIT; if (which == VNET_POLICER_INDEX_BY_SW_IF_INDEX) pi0 = pm->policer_index_by_sw_if_index[sw_if_index0]; if (which == VNET_POLICER_INDEX_BY_OPAQUE) pi0 = vnet_buffer (b0)->policer.index; if (which == VNET_POLICER_INDEX_BY_EITHER) { pi0 = vnet_buffer (b0)->policer.index; pi0 = (pi0 != ~0) ? pi0 : pm->policer_index_by_sw_if_index[sw_if_index0]; } act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods
# Copyright (c) 2018 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

ipsec-mb_version             := 1.5
ipsec-mb_tarball             := v$(ipsec-mb_version).tar.gz
ipsec-mb_tarball_md5sum_1.0  := 906e701937751e761671dc83a41cff65
ipsec-mb_tarball_md5sum_1.1  := 3916471d3713d27e42473cb6af9c65e5
ipsec-mb_tarball_md5sum_1.2  := f551d9c208893a436c1f5c146a615bd6
ipsec-mb_tarball_md5sum_1.3  := d8692db9efe32a263b61f12ac0dca950
ipsec-mb_tarball_md5sum_1.4  := fddba2611f822296ddd82d1c31d22b24
ipsec-mb_tarball_md5sum_1.5  := f18680f8dd43208a15a19a494423bdb9

ipsec-mb_tarball_md5sum      := $(ipsec-mb_tarball_md5sum_$(ipsec-mb_version))
ipsec-mb_tarball_strip_dirs  := 1
ipsec-mb_url                 := http://github.com/intel/intel-ipsec-mb/archive/$(ipsec-mb_tarball)

define  ipsec-mb_config_cmds
	@true
endef

define  ipsec-mb_build_cmds
	@make -C $(ipsec-mb_src_dir)/lib -j \
	  SHARED=n \
	  SAFE_PARAM=n \
	  SAFE_LOOKUP=n \
	  SAFE_DATA=n \
	  PREFIX=$(ipsec-mb_install_dir) \
	  EXTRA_CFLAGS="-g -msse4.2" > $(ipsec-mb_build_log)
endef

define  ipsec-mb_install_cmds
	@mkdir -p $(ipsec-mb_install_dir)/include
	@mkdir -p $(ipsec-mb_install_dir)/lib
	@cp $(ipsec-mb_src_dir)/lib/intel-ipsec-mb.h $(ipsec-mb_install_dir)/include
	@cp $(ipsec-mb_src_dir)/lib/libIPSec_MB.a $(ipsec-mb_install_dir)/lib
endef

$(eval $(call package,ipsec-mb))
ybe switch current next frame */ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi0, next0); } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, node->node_index, POLICER_CLASSIFY_ERROR_MISS, misses); vlib_node_increment_counter (vm, node->node_index, POLICER_CLASSIFY_ERROR_HIT, hits); vlib_node_increment_counter (vm, node->node_index, POLICER_CLASSIFY_ERROR_CHAIN_HIT, chain_hits); vlib_node_increment_counter (vm, node->node_index, POLICER_CLASSIFY_ERROR_DROP, drop); return frame->n_vectors; } static uword ip4_policer_classify (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { return policer_classify_inline (vm, node, frame, POLICER_CLASSIFY_TABLE_IP4); } /* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip4_policer_classify_node) = { .function = ip4_policer_classify, .name = "ip4-policer-classify", .vector_size = sizeof (u32), .format_trace = format_policer_classify_trace, .n_errors = ARRAY_LEN(policer_classify_error_strings), .error_strings = policer_classify_error_strings, .n_next_nodes = POLICER_CLASSIFY_NEXT_INDEX_N_NEXT, .next_nodes = { [POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop", }, }; VLIB_NODE_FUNCTION_MULTIARCH (ip4_policer_classify_node, ip4_policer_classify); /* *INDENT-ON* */ static uword ip6_policer_classify (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { return policer_classify_inline (vm, node, frame, POLICER_CLASSIFY_TABLE_IP6); } /* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip6_policer_classify_node) = { .function = ip6_policer_classify, .name = "ip6-policer-classify", .vector_size = sizeof (u32), .format_trace = format_policer_classify_trace, .n_errors = ARRAY_LEN(policer_classify_error_strings), .error_strings = policer_classify_error_strings, .n_next_nodes = POLICER_CLASSIFY_NEXT_INDEX_N_NEXT, .next_nodes = { [POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop", }, }; VLIB_NODE_FUNCTION_MULTIARCH (ip6_policer_classify_node, ip6_policer_classify); /* *INDENT-ON* */ static uword l2_policer_classify (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { return policer_classify_inline (vm, node, frame, POLICER_CLASSIFY_TABLE_L2); } /* *INDENT-OFF* */ VLIB_REGISTER_NODE (l2_policer_classify_node) = { .function = l2_policer_classify, .name = "l2-policer-classify", .vector_size = sizeof (u32), .format_trace = format_policer_classify_trace, .n_errors = ARRAY_LEN (policer_classify_error_strings), .error_strings = policer_classify_error_strings, .n_next_nodes = POLICER_CLASSIFY_NEXT_INDEX_N_NEXT, .next_nodes = { [POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop", }, }; VLIB_NODE_FUNCTION_MULTIARCH (l2_policer_classify_node, l2_policer_classify); /* *INDENT-ON* */ static clib_error_t * policer_classify_init (vlib_main_t * vm) { policer_classify_main_t *pcm = &policer_classify_main; pcm->vlib_main = vm; pcm->vnet_main = vnet_get_main (); pcm->vnet_classify_main = &vnet_classify_main; /* Initialize L2 feature next-node indexes */ feat_bitmap_init_next_nodes (vm, l2_policer_classify_node.index, L2INPUT_N_FEAT, l2input_get_feat_names (), pcm->feat_next_node_index); return 0; } VLIB_INIT_FUNCTION (policer_classify_init); /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */