diff options
author | Damjan Marion <damarion@cisco.com> | 2016-12-19 23:05:39 +0100 |
---|---|---|
committer | Damjan Marion <damarion@cisco.com> | 2016-12-28 12:25:14 +0100 |
commit | 7cd468a3d7dee7d6c92f69a0bb7061ae208ec727 (patch) | |
tree | 5de62f8dbd3a752f5a676ca600e43d2652d1ff1a /vnet/vnet/interface.c | |
parent | 696f1adec0df3b8f161862566dd9c86174302658 (diff) |
Reorganize source tree to use single autotools instance
Change-Id: I7b51f88292e057c6443b12224486f2d0c9f8ae23
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'vnet/vnet/interface.c')
-rw-r--r-- | vnet/vnet/interface.c | 1398 |
1 files changed, 0 insertions, 1398 deletions
diff --git a/vnet/vnet/interface.c b/vnet/vnet/interface.c deleted file mode 100644 index 78610ed460b..00000000000 --- a/vnet/vnet/interface.c +++ /dev/null @@ -1,1398 +0,0 @@ -/* - * 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. - */ -/* - * interface.c: VNET interfaces/sub-interfaces - * - * Copyright (c) 2008 Eliot Dresselhaus - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <vnet/vnet.h> -#include <vnet/plugin/plugin.h> -#include <vnet/fib/ip6_fib.h> -#include <vnet/adj/adj.h> - -#define VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE (1 << 0) -#define VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE (1 << 1) - -static clib_error_t *vnet_hw_interface_set_flags_helper (vnet_main_t * vnm, - u32 hw_if_index, - u32 flags, - u32 helper_flags); - -static clib_error_t *vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, - u32 sw_if_index, - u32 flags, - u32 helper_flags); - -static clib_error_t *vnet_hw_interface_set_class_helper (vnet_main_t * vnm, - u32 hw_if_index, - u32 hw_class_index, - u32 redistribute); - -typedef struct -{ - /* Either sw or hw interface index. */ - u32 sw_hw_if_index; - - /* Flags. */ - u32 flags; -} vnet_sw_hw_interface_state_t; - -static void -serialize_vec_vnet_sw_hw_interface_state (serialize_main_t * m, va_list * va) -{ - vnet_sw_hw_interface_state_t *s = - va_arg (*va, vnet_sw_hw_interface_state_t *); - u32 n = va_arg (*va, u32); - u32 i; - for (i = 0; i < n; i++) - { - serialize_integer (m, s[i].sw_hw_if_index, - sizeof (s[i].sw_hw_if_index)); - serialize_integer (m, s[i].flags, sizeof (s[i].flags)); - } -} - -static void -unserialize_vec_vnet_sw_hw_interface_state (serialize_main_t * m, - va_list * va) -{ - vnet_sw_hw_interface_state_t *s = - va_arg (*va, vnet_sw_hw_interface_state_t *); - u32 n = va_arg (*va, u32); - u32 i; - for (i = 0; i < n; i++) - { - unserialize_integer (m, &s[i].sw_hw_if_index, - sizeof (s[i].sw_hw_if_index)); - unserialize_integer (m, &s[i].flags, sizeof (s[i].flags)); - } -} - -static void -serialize_vnet_sw_hw_interface_set_flags (serialize_main_t * m, va_list * va) -{ - vnet_sw_hw_interface_state_t *s = - va_arg (*va, vnet_sw_hw_interface_state_t *); - serialize (m, serialize_vec_vnet_sw_hw_interface_state, s, 1); -} - -static void -unserialize_vnet_sw_interface_set_flags (serialize_main_t * m, va_list * va) -{ - CLIB_UNUSED (mc_main_t * mc) = va_arg (*va, mc_main_t *); - vnet_sw_hw_interface_state_t s; - - unserialize (m, unserialize_vec_vnet_sw_hw_interface_state, &s, 1); - - vnet_sw_interface_set_flags_helper - (vnet_get_main (), s.sw_hw_if_index, s.flags, - /* helper_flags no redistribution */ 0); -} - -static void -unserialize_vnet_hw_interface_set_flags (serialize_main_t * m, va_list * va) -{ - CLIB_UNUSED (mc_main_t * mc) = va_arg (*va, mc_main_t *); - vnet_sw_hw_interface_state_t s; - - unserialize (m, unserialize_vec_vnet_sw_hw_interface_state, &s, 1); - - vnet_hw_interface_set_flags_helper - (vnet_get_main (), s.sw_hw_if_index, s.flags, - /* helper_flags no redistribution */ 0); -} - -MC_SERIALIZE_MSG (vnet_sw_interface_set_flags_msg, static) = -{ -.name = "vnet_sw_interface_set_flags",.serialize = - serialize_vnet_sw_hw_interface_set_flags,.unserialize = - unserialize_vnet_sw_interface_set_flags,}; - -MC_SERIALIZE_MSG (vnet_hw_interface_set_flags_msg, static) = -{ -.name = "vnet_hw_interface_set_flags",.serialize = - serialize_vnet_sw_hw_interface_set_flags,.unserialize = - unserialize_vnet_hw_interface_set_flags,}; - -void -serialize_vnet_interface_state (serialize_main_t * m, va_list * va) -{ - vnet_main_t *vnm = va_arg (*va, vnet_main_t *); - vnet_sw_hw_interface_state_t *sts = 0, *st; - vnet_sw_interface_t *sif; - vnet_hw_interface_t *hif; - vnet_interface_main_t *im = &vnm->interface_main; - - /* Serialize hardware interface classes since they may have changed. - Must do this before sending up/down flags. */ - /* *INDENT-OFF* */ - pool_foreach (hif, im->hw_interfaces, ({ - vnet_hw_interface_class_t * hw_class = vnet_get_hw_interface_class (vnm, hif->hw_class_index); - serialize_cstring (m, hw_class->name); - })); - /* *INDENT-ON* */ - - /* Send sw/hw interface state when non-zero. */ - /* *INDENT-OFF* */ - pool_foreach (sif, im->sw_interfaces, ({ - if (sif->flags != 0) - { - vec_add2 (sts, st, 1); - st->sw_hw_if_index = sif->sw_if_index; - st->flags = sif->flags; - } - })); - /* *INDENT-ON* */ - - vec_serialize (m, sts, serialize_vec_vnet_sw_hw_interface_state); - - if (sts) - _vec_len (sts) = 0; - - /* *INDENT-OFF* */ - pool_foreach (hif, im->hw_interfaces, ({ - if (hif->flags != 0) - { - vec_add2 (sts, st, 1); - st->sw_hw_if_index = hif->hw_if_index; - st->flags = hif->flags; - } - })); - /* *INDENT-ON* */ - - vec_serialize (m, sts, serialize_vec_vnet_sw_hw_interface_state); - - vec_free (sts); -} - -void -unserialize_vnet_interface_state (serialize_main_t * m, va_list * va) -{ - vnet_main_t *vnm = va_arg (*va, vnet_main_t *); - vnet_sw_hw_interface_state_t *sts = 0, *st; - - /* First set interface hardware class. */ - { - vnet_interface_main_t *im = &vnm->interface_main; - vnet_hw_interface_t *hif; - char *class_name; - uword *p; - clib_error_t *error; - - /* *INDENT-OFF* */ - pool_foreach (hif, im->hw_interfaces, ({ - unserialize_cstring (m, &class_name); - p = hash_get_mem (im->hw_interface_class_by_name, class_name); - ASSERT (p != 0); - error = vnet_hw_interface_set_class_helper (vnm, hif->hw_if_index, p[0], /* redistribute */ 0); - if (error) - clib_error_report (error); - vec_free (class_name); - })); - /* *INDENT-ON* */ - } - - vec_unserialize (m, &sts, unserialize_vec_vnet_sw_hw_interface_state); - vec_foreach (st, sts) - vnet_sw_interface_set_flags_helper (vnm, st->sw_hw_if_index, st->flags, - /* no distribute */ 0); - vec_free (sts); - - vec_unserialize (m, &sts, unserialize_vec_vnet_sw_hw_interface_state); - vec_foreach (st, sts) - vnet_hw_interface_set_flags_helper (vnm, st->sw_hw_if_index, st->flags, - /* no distribute */ 0); - vec_free (sts); -} - -static clib_error_t * -call_elf_section_interface_callbacks (vnet_main_t * vnm, u32 if_index, - u32 flags, - _vnet_interface_function_list_elt_t ** - elts) -{ - _vnet_interface_function_list_elt_t *elt; - vnet_interface_function_priority_t prio; - clib_error_t *error = 0; - - for (prio = VNET_ITF_FUNC_PRIORITY_LOW; - prio <= VNET_ITF_FUNC_PRIORITY_HIGH; prio++) - { - elt = elts[prio]; - - while (elt) - { - error = elt->fp (vnm, if_index, flags); - if (error) - return error; - elt = elt->next_interface_function; - } - } - return error; -} - -static clib_error_t * -call_hw_interface_add_del_callbacks (vnet_main_t * vnm, u32 hw_if_index, - u32 is_create) -{ - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - vnet_hw_interface_class_t *hw_class = - vnet_get_hw_interface_class (vnm, hi->hw_class_index); - vnet_device_class_t *dev_class = - vnet_get_device_class (vnm, hi->dev_class_index); - clib_error_t *error = 0; - - if (hw_class->interface_add_del_function - && (error = - hw_class->interface_add_del_function (vnm, hw_if_index, is_create))) - return error; - - if (dev_class->interface_add_del_function - && (error = - dev_class->interface_add_del_function (vnm, hw_if_index, - is_create))) - return error; - - error = call_elf_section_interface_callbacks - (vnm, hw_if_index, is_create, vnm->hw_interface_add_del_functions); - - return error; -} - -static clib_error_t * -call_sw_interface_add_del_callbacks (vnet_main_t * vnm, u32 sw_if_index, - u32 is_create) -{ - return call_elf_section_interface_callbacks - (vnm, sw_if_index, is_create, vnm->sw_interface_add_del_functions); -} - -#define VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE (1 << 0) -#define VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE (1 << 1) - -static clib_error_t * -vnet_hw_interface_set_flags_helper (vnet_main_t * vnm, u32 hw_if_index, - u32 flags, u32 helper_flags) -{ - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - vnet_hw_interface_class_t *hw_class = - vnet_get_hw_interface_class (vnm, hi->hw_class_index); - vnet_device_class_t *dev_class = - vnet_get_device_class (vnm, hi->dev_class_index); - vlib_main_t *vm = vnm->vlib_main; - u32 mask; - clib_error_t *error = 0; - u32 is_create = - (helper_flags & VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE) != 0; - - mask = - (VNET_HW_INTERFACE_FLAG_LINK_UP | VNET_HW_INTERFACE_FLAG_DUPLEX_MASK | - VNET_HW_INTERFACE_FLAG_SPEED_MASK); - flags &= mask; - - /* Call hardware interface add/del callbacks. */ - if (is_create) - call_hw_interface_add_del_callbacks (vnm, hw_if_index, is_create); - - /* Already in the desired state? */ - if (!is_create && (hi->flags & mask) == flags) - goto done; - - /* Some interface classes do not redistribute (e.g. are local). */ - if (!dev_class->redistribute) - helper_flags &= ~VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE; - - if (vm->mc_main - && (helper_flags & VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE)) - { - vnet_sw_hw_interface_state_t s; - s.sw_hw_if_index = hw_if_index; - s.flags = flags; - mc_serialize (vm->mc_main, &vnet_hw_interface_set_flags_msg, &s); - } - - if ((hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) != - (flags & VNET_HW_INTERFACE_FLAG_LINK_UP)) - { - /* Do hardware class (e.g. ethernet). */ - if (hw_class->link_up_down_function - && (error = hw_class->link_up_down_function (vnm, hw_if_index, - flags))) - goto done; - - error = call_elf_section_interface_callbacks - (vnm, hw_if_index, flags, vnm->hw_interface_link_up_down_functions); - - if (error) - goto done; - } - - hi->flags &= ~mask; - hi->flags |= flags; - -done: - return error; -} - -static clib_error_t * -vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, - u32 flags, u32 helper_flags) -{ - vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); - vlib_main_t *vm = vnm->vlib_main; - u32 mask; - clib_error_t *error = 0; - u32 is_create = - (helper_flags & VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE) != 0; - u32 old_flags; - - mask = VNET_SW_INTERFACE_FLAG_ADMIN_UP | VNET_SW_INTERFACE_FLAG_PUNT; - flags &= mask; - - if (is_create) - { - error = - call_sw_interface_add_del_callbacks (vnm, sw_if_index, is_create); - if (error) - goto done; - - if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) - { - /* Notify everyone when the interface is created as admin up */ - error = call_elf_section_interface_callbacks (vnm, sw_if_index, - flags, - vnm-> - sw_interface_admin_up_down_functions); - if (error) - goto done; - } - } - else - { - vnet_sw_interface_t *si_sup = si; - - /* Check that super interface is in correct state. */ - if (si->type == VNET_SW_INTERFACE_TYPE_SUB) - { - si_sup = vnet_get_sw_interface (vnm, si->sup_sw_if_index); - - /* Check to see if we're bringing down the soft interface and if it's parent is up */ - if ((flags != (si_sup->flags & mask)) && - (!((flags == 0) - && ((si_sup->flags & mask) == - VNET_SW_INTERFACE_FLAG_ADMIN_UP)))) - { - error = clib_error_return (0, "super-interface %U must be %U", - format_vnet_sw_interface_name, vnm, - si_sup, - format_vnet_sw_interface_flags, - flags); - goto done; - } - } - - /* Donot change state for slave link of bonded interfaces */ - if (si->flags & VNET_SW_INTERFACE_FLAG_BOND_SLAVE) - { - error = clib_error_return - (0, "not allowed as %U belong to a BondEthernet interface", - format_vnet_sw_interface_name, vnm, si); - goto done; - } - - /* Already in the desired state? */ - if ((si->flags & mask) == flags) - goto done; - - /* Sub-interfaces of hardware interfaces that do no redistribute, - do not redistribute themselves. */ - if (si_sup->type == VNET_SW_INTERFACE_TYPE_HARDWARE) - { - vnet_hw_interface_t *hi = - vnet_get_hw_interface (vnm, si_sup->hw_if_index); - vnet_device_class_t *dev_class = - vnet_get_device_class (vnm, hi->dev_class_index); - if (!dev_class->redistribute) - helper_flags &= - ~VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE; - } - - if (vm->mc_main - && (helper_flags & - VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE)) - { - vnet_sw_hw_interface_state_t s; - s.sw_hw_if_index = sw_if_index; - s.flags = flags; - mc_serialize (vm->mc_main, &vnet_sw_interface_set_flags_msg, &s); - } - - /* set the flags now before invoking the registered clients - * so that the state they query is consistent with the state here notified */ - old_flags = si->flags; - si->flags &= ~mask; - si->flags |= flags; - if ((flags | old_flags) & VNET_SW_INTERFACE_FLAG_ADMIN_UP) - error = call_elf_section_interface_callbacks - (vnm, sw_if_index, flags, - vnm->sw_interface_admin_up_down_functions); - si->flags = old_flags; - - if (error) - goto done; - - if (si->type == VNET_SW_INTERFACE_TYPE_HARDWARE) - { - vnet_hw_interface_t *hi = - vnet_get_hw_interface (vnm, si->hw_if_index); - vnet_hw_interface_class_t *hw_class = - vnet_get_hw_interface_class (vnm, hi->hw_class_index); - vnet_device_class_t *dev_class = - vnet_get_device_class (vnm, hi->dev_class_index); - - /* save the si admin up flag */ - old_flags = si->flags; - - /* update si admin up flag in advance if we are going admin down */ - if (!(flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)) - si->flags &= ~VNET_SW_INTERFACE_FLAG_ADMIN_UP; - - if (dev_class->admin_up_down_function - && (error = dev_class->admin_up_down_function (vnm, - si->hw_if_index, - flags))) - { - /* restore si admin up flag to it's original state on errors */ - si->flags = old_flags; - goto done; - } - - if (hw_class->admin_up_down_function - && (error = hw_class->admin_up_down_function (vnm, - si->hw_if_index, - flags))) - { - /* restore si admin up flag to it's original state on errors */ - si->flags = old_flags; - goto done; - } - - /* Admin down implies link down. */ - if (!(flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) - && (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)) - vnet_hw_interface_set_flags_helper (vnm, si->hw_if_index, - hi->flags & - ~VNET_HW_INTERFACE_FLAG_LINK_UP, - helper_flags); - } - } - - si->flags &= ~mask; - si->flags |= flags; - -done: - return error; -} - -clib_error_t * -vnet_hw_interface_set_flags (vnet_main_t * vnm, u32 hw_if_index, u32 flags) -{ - return vnet_hw_interface_set_flags_helper - (vnm, hw_if_index, flags, - VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE); -} - -clib_error_t * -vnet_sw_interface_set_flags (vnet_main_t * vnm, u32 sw_if_index, u32 flags) -{ - return vnet_sw_interface_set_flags_helper - (vnm, sw_if_index, flags, - VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE); -} - -static u32 -vnet_create_sw_interface_no_callbacks (vnet_main_t * vnm, - vnet_sw_interface_t * template) -{ - vnet_interface_main_t *im = &vnm->interface_main; - vnet_sw_interface_t *sw; - u32 sw_if_index; - - pool_get (im->sw_interfaces, sw); - sw_if_index = sw - im->sw_interfaces; - - sw[0] = template[0]; - - sw->flags = 0; - sw->sw_if_index = sw_if_index; - if (sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE) - sw->sup_sw_if_index = sw->sw_if_index; - - /* Allocate counters for this interface. */ - { - u32 i; - - vnet_interface_counter_lock (im); - - for (i = 0; i < vec_len (im->sw_if_counters); i++) - { - vlib_validate_simple_counter (&im->sw_if_counters[i], sw_if_index); - vlib_zero_simple_counter (&im->sw_if_counters[i], sw_if_index); - } - - for (i = 0; i < vec_len (im->combined_sw_if_counters); i++) - { - vlib_validate_combined_counter (&im->combined_sw_if_counters[i], - sw_if_index); - vlib_zero_combined_counter (&im->combined_sw_if_counters[i], - sw_if_index); - } - - vnet_interface_counter_unlock (im); - } - - return sw_if_index; -} - -clib_error_t * -vnet_create_sw_interface (vnet_main_t * vnm, vnet_sw_interface_t * template, - u32 * sw_if_index) -{ - clib_error_t *error; - vnet_hw_interface_t *hi; - vnet_device_class_t *dev_class; - - hi = vnet_get_sup_hw_interface (vnm, template->sup_sw_if_index); - dev_class = vnet_get_device_class (vnm, hi->dev_class_index); - - if (template->type == VNET_SW_INTERFACE_TYPE_SUB && - dev_class->subif_add_del_function) - { - error = dev_class->subif_add_del_function (vnm, hi->hw_if_index, - (struct vnet_sw_interface_t - *) template, 1); - if (error) - return error; - } - - *sw_if_index = vnet_create_sw_interface_no_callbacks (vnm, template); - error = vnet_sw_interface_set_flags_helper - (vnm, *sw_if_index, template->flags, - VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE); - - if (error) - { - /* undo the work done by vnet_create_sw_interface_no_callbacks() */ - vnet_interface_main_t *im = &vnm->interface_main; - vnet_sw_interface_t *sw = - pool_elt_at_index (im->sw_interfaces, *sw_if_index); - pool_put (im->sw_interfaces, sw); - } - - return error; -} - -void -vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index) -{ - vnet_interface_main_t *im = &vnm->interface_main; - vnet_sw_interface_t *sw = - pool_elt_at_index (im->sw_interfaces, sw_if_index); - - /* Make sure the interface is in L3 mode (removed from L2 BD or XConnect) */ - vlib_main_t *vm = vlib_get_main (); - l2_input_config_t *config; - config = vec_elt_at_index (l2input_main.configs, sw_if_index); - if (config->xconnect) - set_int_l2_mode (vm, vnm, MODE_L3, config->output_sw_if_index, 0, 0, 0, - 0); - if (config->xconnect || config->bridge) - set_int_l2_mode (vm, vnm, MODE_L3, sw_if_index, 0, 0, 0, 0); - - /* Bring down interface in case it is up. */ - if (sw->flags != 0) - vnet_sw_interface_set_flags (vnm, sw_if_index, /* flags */ 0); - - call_sw_interface_add_del_callbacks (vnm, sw_if_index, /* is_create */ 0); - - pool_put (im->sw_interfaces, sw); -} - -static void -setup_tx_node (vlib_main_t * vm, - u32 node_index, vnet_device_class_t * dev_class) -{ - vlib_node_t *n = vlib_get_node (vm, node_index); - - n->function = dev_class->tx_function; - n->format_trace = dev_class->format_tx_trace; - - vlib_register_errors (vm, node_index, - dev_class->tx_function_n_errors, - dev_class->tx_function_error_strings); -} - -static void -setup_output_node (vlib_main_t * vm, - u32 node_index, vnet_hw_interface_class_t * hw_class) -{ - vlib_node_t *n = vlib_get_node (vm, node_index); - n->format_buffer = hw_class->format_header; - n->unformat_buffer = hw_class->unformat_header; -} - -/* Register an interface instance. */ -u32 -vnet_register_interface (vnet_main_t * vnm, - u32 dev_class_index, - u32 dev_instance, - u32 hw_class_index, u32 hw_instance) -{ - vnet_interface_main_t *im = &vnm->interface_main; - vnet_hw_interface_t *hw; - vnet_device_class_t *dev_class = - vnet_get_device_class (vnm, dev_class_index); - vnet_hw_interface_class_t *hw_class = - vnet_get_hw_interface_class (vnm, hw_class_index); - vlib_main_t *vm = vnm->vlib_main; - vnet_feature_config_main_t *fcm; - vnet_config_main_t *cm; - u32 hw_index, i; - char *tx_node_name, *output_node_name; - - pool_get (im->hw_interfaces, hw); - - hw_index = hw - im->hw_interfaces; - hw->hw_if_index = hw_index; - - if (dev_class->format_device_name) - hw->name = format (0, "%U", dev_class->format_device_name, dev_instance); - else if (hw_class->format_interface_name) - hw->name = format (0, "%U", hw_class->format_interface_name, - dev_instance); - else - hw->name = format (0, "%s%x", hw_class->name, dev_instance); - - if (!im->hw_interface_by_name) - im->hw_interface_by_name = hash_create_vec ( /* size */ 0, - sizeof (hw->name[0]), - sizeof (uword)); - - hash_set_mem (im->hw_interface_by_name, hw->name, hw_index); - - /* Make hardware interface point to software interface. */ - { - vnet_sw_interface_t sw = { - .type = VNET_SW_INTERFACE_TYPE_HARDWARE, - .flood_class = VNET_FLOOD_CLASS_NORMAL, - .hw_if_index = hw_index - }; - hw->sw_if_index = vnet_create_sw_interface_no_callbacks (vnm, &sw); - } - - hw->dev_class_index = dev_class_index; - hw->dev_instance = dev_instance; - hw->hw_class_index = hw_class_index; - hw->hw_instance = hw_instance; - - hw->max_rate_bits_per_sec = 0; - hw->min_packet_bytes = 0; - hw->per_packet_overhead_bytes = 0; - hw->max_l3_packet_bytes[VLIB_RX] = ~0; - hw->max_l3_packet_bytes[VLIB_TX] = ~0; - - tx_node_name = (char *) format (0, "%v-tx", hw->name); - output_node_name = (char *) format (0, "%v-output", hw->name); - - /* If we have previously deleted interface nodes, re-use them. */ - if (vec_len (im->deleted_hw_interface_nodes) > 0) - { - vnet_hw_interface_nodes_t *hn; - vnet_interface_output_runtime_t *rt; - vlib_node_t *node; - vlib_node_runtime_t *nrt; - - hn = vec_end (im->deleted_hw_interface_nodes) - 1; - - hw->tx_node_index = hn->tx_node_index; - hw->output_node_index = hn->output_node_index; - - vlib_node_rename (vm, hw->tx_node_index, "%v", tx_node_name); - vlib_node_rename (vm, hw->output_node_index, "%v", output_node_name); - - rt = vlib_node_get_runtime_data (vm, hw->output_node_index); - ASSERT (rt->is_deleted == 1); - rt->is_deleted = 0; - rt->hw_if_index = hw_index; - rt->sw_if_index = hw->sw_if_index; - rt->dev_instance = hw->dev_instance; - - rt = vlib_node_get_runtime_data (vm, hw->tx_node_index); - rt->hw_if_index = hw_index; - rt->sw_if_index = hw->sw_if_index; - rt->dev_instance = hw->dev_instance; - - /* The new class may differ from the old one. - * Functions have to be updated. */ - node = vlib_get_node (vm, hw->output_node_index); - node->function = dev_class->flatten_output_chains ? - vnet_interface_output_node_flatten_multiarch_select () : - vnet_interface_output_node_multiarch_select (); - node->format_trace = format_vnet_interface_output_trace; - nrt = vlib_node_get_runtime (vm, hw->output_node_index); - nrt->function = node->function; - - node = vlib_get_node (vm, hw->tx_node_index); - node->function = dev_class->tx_function; - node->format_trace = dev_class->format_tx_trace; - nrt = vlib_node_get_runtime (vm, hw->tx_node_index); - nrt->function = node->function; - - vlib_worker_thread_node_runtime_update (); - _vec_len (im->deleted_hw_interface_nodes) -= 1; - } - else - { - vlib_node_registration_t r; - vnet_interface_output_runtime_t rt = { - .hw_if_index = hw_index, - .sw_if_index = hw->sw_if_index, - .dev_instance = hw->dev_instance, - .is_deleted = 0, - }; - - memset (&r, 0, sizeof (r)); - r.type = VLIB_NODE_TYPE_INTERNAL; - r.runtime_data = &rt; - r.runtime_data_bytes = sizeof (rt); - r.scalar_size = 0; - r.vector_size = sizeof (u32); - - r.flags = VLIB_NODE_FLAG_IS_OUTPUT; - r.name = tx_node_name; - r.function = dev_class->tx_function; - - hw->tx_node_index = vlib_register_node (vm, &r); - - vlib_node_add_named_next_with_slot (vm, hw->tx_node_index, - "error-drop", - VNET_INTERFACE_TX_NEXT_DROP); - - r.flags = 0; - r.name = output_node_name; - r.function = dev_class->flatten_output_chains ? - vnet_interface_output_node_flatten_multiarch_select () : - vnet_interface_output_node_multiarch_select (); - r.format_trace = format_vnet_interface_output_trace; - - { - static char *e[] = { - "interface is down", - "interface is deleted", - }; - - r.n_errors = ARRAY_LEN (e); - r.error_strings = e; - } - hw->output_node_index = vlib_register_node (vm, &r); - - vlib_node_add_named_next_with_slot (vm, hw->output_node_index, - "error-drop", - VNET_INTERFACE_OUTPUT_NEXT_DROP); - vlib_node_add_next_with_slot (vm, hw->output_node_index, - hw->tx_node_index, - VNET_INTERFACE_OUTPUT_NEXT_TX); - - /* add interface to the list of "output-interface" feature arc start nodes - and clone nexts from 1st interface if it exists */ - fcm = vnet_feature_get_config_main (im->output_feature_arc_index); - cm = &fcm->config_main; - i = vec_len (cm->start_node_indices); - vec_validate (cm->start_node_indices, i); - cm->start_node_indices[i] = hw->output_node_index; - if (hw_index) - { - /* copy nexts from 1st interface */ - vnet_hw_interface_t *first_hw; - vlib_node_t *first_node; - - first_hw = vnet_get_hw_interface (vnm, /* hw_if_index */ 0); - first_node = vlib_get_node (vm, first_hw->output_node_index); - - /* 1st 2 nexts are already added above */ - for (i = 2; i < vec_len (first_node->next_nodes); i++) - vlib_node_add_next_with_slot (vm, hw->output_node_index, - first_node->next_nodes[i], i); - } - } - - setup_output_node (vm, hw->output_node_index, hw_class); - setup_tx_node (vm, hw->tx_node_index, dev_class); - - /* Call all up/down callbacks with zero flags when interface is created. */ - vnet_sw_interface_set_flags_helper (vnm, hw->sw_if_index, /* flags */ 0, - VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE); - vnet_hw_interface_set_flags_helper (vnm, hw_index, /* flags */ 0, - VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE); - - return hw_index; -} - -void -vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index) -{ - vnet_interface_main_t *im = &vnm->interface_main; - vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index); - vlib_main_t *vm = vnm->vlib_main; - - /* If it is up, mark it down. */ - if (hw->flags != 0) - vnet_hw_interface_set_flags (vnm, hw_if_index, /* flags */ 0); - - /* Call delete callbacks. */ - call_hw_interface_add_del_callbacks (vnm, hw_if_index, /* is_create */ 0); - - /* Delete software interface corresponding to hardware interface. */ - vnet_delete_sw_interface (vnm, hw->sw_if_index); - - /* Delete any sub-interfaces. */ - { - u32 id, sw_if_index; - /* *INDENT-OFF* */ - hash_foreach (id, sw_if_index, hw->sub_interface_sw_if_index_by_id, ({ - vnet_delete_sw_interface (vnm, sw_if_index); - })); - /* *INDENT-ON* */ - } - - { - vnet_hw_interface_nodes_t *dn; - vnet_interface_output_runtime_t *rt = - vlib_node_get_runtime_data (vm, hw->output_node_index); - - /* Mark node runtime as deleted so output node (if called) will drop packets. */ - rt->is_deleted = 1; - - vlib_node_rename (vm, hw->output_node_index, - "interface-%d-output-deleted", hw_if_index); - vlib_node_rename (vm, hw->tx_node_index, "interface-%d-tx-deleted", - hw_if_index); - vec_add2 (im->deleted_hw_interface_nodes, dn, 1); - dn->tx_node_index = hw->tx_node_index; - dn->output_node_index = hw->output_node_index; - } - - hash_unset_mem (im->hw_interface_by_name, hw->name); - vec_free (hw->name); - - pool_put (im->hw_interfaces, hw); -} - -void -vnet_hw_interface_walk_sw (vnet_main_t * vnm, - u32 hw_if_index, - vnet_hw_sw_interface_walk_t fn, void *ctx) -{ - vnet_hw_interface_t *hi; - u32 id, sw_if_index; - - hi = vnet_get_hw_interface (vnm, hw_if_index); - /* the super first, then the and sub interfaces */ - fn (vnm, hi->sw_if_index, ctx); - - /* *INDENT-OFF* */ - hash_foreach (id, sw_if_index, - hi->sub_interface_sw_if_index_by_id, - ({ - fn (vnm, sw_if_index, ctx); - })); - /* *INDENT-ON* */ -} - -static void -serialize_vnet_hw_interface_set_class (serialize_main_t * m, va_list * va) -{ - u32 hw_if_index = va_arg (*va, u32); - char *hw_class_name = va_arg (*va, char *); - serialize_integer (m, hw_if_index, sizeof (hw_if_index)); - serialize_cstring (m, hw_class_name); -} - -static void -unserialize_vnet_hw_interface_set_class (serialize_main_t * m, va_list * va) -{ - CLIB_UNUSED (mc_main_t * mc) = va_arg (*va, mc_main_t *); - vnet_main_t *vnm = vnet_get_main (); - u32 hw_if_index; - char *hw_class_name; - uword *p; - clib_error_t *error; - - unserialize_integer (m, &hw_if_index, sizeof (hw_if_index)); - unserialize_cstring (m, &hw_class_name); - p = - hash_get (vnm->interface_main.hw_interface_class_by_name, hw_class_name); - ASSERT (p != 0); - error = vnet_hw_interface_set_class_helper (vnm, hw_if_index, p[0], - /* redistribute */ 0); - if (error) - clib_error_report (error); -} - -MC_SERIALIZE_MSG (vnet_hw_interface_set_class_msg, static) = -{ -.name = "vnet_hw_interface_set_class",.serialize = - serialize_vnet_hw_interface_set_class,.unserialize = - unserialize_vnet_hw_interface_set_class,}; - -void -vnet_hw_interface_init_for_class (vnet_main_t * vnm, u32 hw_if_index, - u32 hw_class_index, u32 hw_instance) -{ - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - vnet_hw_interface_class_t *hc = - vnet_get_hw_interface_class (vnm, hw_class_index); - - hi->hw_class_index = hw_class_index; - hi->hw_instance = hw_instance; - setup_output_node (vnm->vlib_main, hi->output_node_index, hc); -} - -static clib_error_t * -vnet_hw_interface_set_class_helper (vnet_main_t * vnm, u32 hw_if_index, - u32 hw_class_index, u32 redistribute) -{ - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, hi->sw_if_index); - vnet_hw_interface_class_t *old_class = - vnet_get_hw_interface_class (vnm, hi->hw_class_index); - vnet_hw_interface_class_t *new_class = - vnet_get_hw_interface_class (vnm, hw_class_index); - vnet_device_class_t *dev_class = - vnet_get_device_class (vnm, hi->dev_class_index); - clib_error_t *error = 0; - - /* New class equals old class? Nothing to do. */ - if (hi->hw_class_index == hw_class_index) - return 0; - - /* No need (and incorrect since admin up flag may be set) to do error checking when - receiving unserialize message. */ - if (redistribute) - { - if (si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) - return clib_error_return (0, - "%v must be admin down to change class from %s to %s", - hi->name, old_class->name, new_class->name); - - /* Make sure interface supports given class. */ - if ((new_class->is_valid_class_for_interface - && !new_class->is_valid_class_for_interface (vnm, hw_if_index, - hw_class_index)) - || (dev_class->is_valid_class_for_interface - && !dev_class->is_valid_class_for_interface (vnm, hw_if_index, - hw_class_index))) - return clib_error_return (0, - "%v class cannot be changed from %s to %s", - hi->name, old_class->name, new_class->name); - - if (vnm->vlib_main->mc_main) - { - mc_serialize (vnm->vlib_main->mc_main, - &vnet_hw_interface_set_class_msg, hw_if_index, - new_class->name); - return 0; - } - } - - if (old_class->hw_class_change) - old_class->hw_class_change (vnm, hw_if_index, old_class->index, - new_class->index); - - vnet_hw_interface_init_for_class (vnm, hw_if_index, new_class->index, - /* instance */ ~0); - - if (new_class->hw_class_change) - new_class->hw_class_change (vnm, hw_if_index, old_class->index, - new_class->index); - - if (dev_class->hw_class_change) - dev_class->hw_class_change (vnm, hw_if_index, new_class->index); - - return error; -} - -clib_error_t * -vnet_hw_interface_set_class (vnet_main_t * vnm, u32 hw_if_index, - u32 hw_class_index) -{ - return vnet_hw_interface_set_class_helper (vnm, hw_if_index, hw_class_index, - /* redistribute */ 1); -} - -static int -vnet_hw_interface_rx_redirect_to_node_helper (vnet_main_t * vnm, - u32 hw_if_index, - u32 node_index, - u32 redistribute) -{ - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - vnet_device_class_t *dev_class = vnet_get_device_class - (vnm, hi->dev_class_index); - - if (redistribute) - { - /* $$$$ fixme someday maybe */ - ASSERT (vnm->vlib_main->mc_main == 0); - } - if (dev_class->rx_redirect_to_node) - { - dev_class->rx_redirect_to_node (vnm, hw_if_index, node_index); - return 0; - } - - return VNET_API_ERROR_UNIMPLEMENTED; -} - -int -vnet_hw_interface_rx_redirect_to_node (vnet_main_t * vnm, u32 hw_if_index, - u32 node_index) -{ - return vnet_hw_interface_rx_redirect_to_node_helper (vnm, hw_if_index, - node_index, - 1 /* redistribute */ ); -} - -word -vnet_sw_interface_compare (vnet_main_t * vnm, - uword sw_if_index0, uword sw_if_index1) -{ - vnet_sw_interface_t *sup0 = vnet_get_sup_sw_interface (vnm, sw_if_index0); - vnet_sw_interface_t *sup1 = vnet_get_sup_sw_interface (vnm, sw_if_index1); - vnet_hw_interface_t *h0 = vnet_get_hw_interface (vnm, sup0->hw_if_index); - vnet_hw_interface_t *h1 = vnet_get_hw_interface (vnm, sup1->hw_if_index); - - if (h0 != h1) - return vec_cmp (h0->name, h1->name); - return (word) h0->hw_instance - (word) h1->hw_instance; -} - -word -vnet_hw_interface_compare (vnet_main_t * vnm, - uword hw_if_index0, uword hw_if_index1) -{ - vnet_hw_interface_t *h0 = vnet_get_hw_interface (vnm, hw_if_index0); - vnet_hw_interface_t *h1 = vnet_get_hw_interface (vnm, hw_if_index1); - - if (h0 != h1) - return vec_cmp (h0->name, h1->name); - return (word) h0->hw_instance - (word) h1->hw_instance; -} - -int -vnet_sw_interface_is_p2p (vnet_main_t * vnm, u32 sw_if_index) -{ - vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index); - vnet_hw_interface_class_t *hc = - vnet_get_hw_interface_class (vnm, hw->hw_class_index); - - return (hc->flags & VNET_HW_INTERFACE_CLASS_FLAG_P2P); -} - -clib_error_t * -vnet_interface_init (vlib_main_t * vm) -{ - vnet_main_t *vnm = vnet_get_main (); - vnet_interface_main_t *im = &vnm->interface_main; - vlib_buffer_t *b = 0; - vnet_buffer_opaque_t *o = 0; - - /* - * Keep people from shooting themselves in the foot. - */ - if (sizeof (b->opaque) != sizeof (vnet_buffer_opaque_t)) - { -#define _(a) if (sizeof(o->a) > sizeof (o->unused)) \ - clib_warning \ - ("FATAL: size of opaque union subtype %s is %d (max %d)", \ - #a, sizeof(o->a), sizeof (o->unused)); - foreach_buffer_opaque_union_subtype; -#undef _ - - return clib_error_return - (0, "FATAL: size of vlib buffer opaque %d, size of vnet opaque %d", - sizeof (b->opaque), sizeof (vnet_buffer_opaque_t)); - } - - im->sw_if_counter_lock = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, - CLIB_CACHE_LINE_BYTES); - im->sw_if_counter_lock[0] = 1; /* should be no need */ - - vec_validate (im->sw_if_counters, VNET_N_SIMPLE_INTERFACE_COUNTER - 1); - im->sw_if_counters[VNET_INTERFACE_COUNTER_DROP].name = "drops"; - im->sw_if_counters[VNET_INTERFACE_COUNTER_PUNT].name = "punts"; - im->sw_if_counters[VNET_INTERFACE_COUNTER_IP4].name = "ip4"; - im->sw_if_counters[VNET_INTERFACE_COUNTER_IP6].name = "ip6"; - im->sw_if_counters[VNET_INTERFACE_COUNTER_RX_NO_BUF].name = "rx-no-buf"; - im->sw_if_counters[VNET_INTERFACE_COUNTER_RX_MISS].name = "rx-miss"; - im->sw_if_counters[VNET_INTERFACE_COUNTER_RX_ERROR].name = "rx-error"; - im->sw_if_counters[VNET_INTERFACE_COUNTER_TX_ERROR].name = "tx-error"; - - vec_validate (im->combined_sw_if_counters, - VNET_N_COMBINED_INTERFACE_COUNTER - 1); - im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX].name = "rx"; - im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX].name = "tx"; - - im->sw_if_counter_lock[0] = 0; - - im->device_class_by_name = hash_create_string ( /* size */ 0, - sizeof (uword)); - { - vnet_device_class_t *c; - - c = vnm->device_class_registrations; - - while (c) - { - c->index = vec_len (im->device_classes); - hash_set_mem (im->device_class_by_name, c->name, c->index); - vec_add1 (im->device_classes, c[0]); - c = c->next_class_registration; - } - } - - im->hw_interface_class_by_name = hash_create_string ( /* size */ 0, - sizeof (uword)); - - im->sw_if_index_by_sup_and_sub = hash_create_mem (0, sizeof (u64), - sizeof (uword)); - { - vnet_hw_interface_class_t *c; - - c = vnm->hw_interface_class_registrations; - - while (c) - { - c->index = vec_len (im->hw_interface_classes); - hash_set_mem (im->hw_interface_class_by_name, c->name, c->index); - - if (NULL == c->build_rewrite) - c->build_rewrite = default_build_rewrite; - if (NULL == c->update_adjacency) - c->update_adjacency = default_update_adjacency; - - vec_add1 (im->hw_interface_classes, c[0]); - c = c->next_class_registration; - } - } - - { - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, vnet_interface_cli_init))) - return error; - - return error; - } - vnm->interface_tag_by_sw_if_index = hash_create (0, sizeof (uword)); -} - -VLIB_INIT_FUNCTION (vnet_interface_init); - -/* Kludge to renumber interface names [only!] */ -int -vnet_interface_name_renumber (u32 sw_if_index, u32 new_show_dev_instance) -{ - int rv; - vnet_main_t *vnm = vnet_get_main (); - vnet_interface_main_t *im = &vnm->interface_main; - vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index); - - vnet_device_class_t *dev_class = vnet_get_device_class - (vnm, hi->dev_class_index); - - if (dev_class->name_renumber == 0 || dev_class->format_device_name == 0) - return VNET_API_ERROR_UNIMPLEMENTED; - - rv = dev_class->name_renumber (hi, new_show_dev_instance); - - if (rv) - return rv; - - hash_unset_mem (im->hw_interface_by_name, hi->name); - vec_free (hi->name); - /* Use the mapping we set up to call it Ishmael */ - hi->name = format (0, "%U", dev_class->format_device_name, - hi->dev_instance); - - hash_set_mem (im->hw_interface_by_name, hi->name, hi->hw_if_index); - return rv; -} - -clib_error_t * -vnet_rename_interface (vnet_main_t * vnm, u32 hw_if_index, char *new_name) -{ - vnet_interface_main_t *im = &vnm->interface_main; - vlib_main_t *vm = vnm->vlib_main; - vnet_hw_interface_t *hw; - u8 *old_name; - clib_error_t *error = 0; - - hw = vnet_get_hw_interface (vnm, hw_if_index); - if (!hw) - { - return clib_error_return (0, - "unable to find hw interface for index %u", - hw_if_index); - } - - old_name = hw->name; - - /* set new hw->name */ - hw->name = format (0, "%s", new_name); - - /* remove the old name to hw_if_index mapping and install the new one */ - hash_unset_mem (im->hw_interface_by_name, old_name); - hash_set_mem (im->hw_interface_by_name, hw->name, hw_if_index); - - /* rename tx/output nodes */ - vlib_node_rename (vm, hw->tx_node_index, "%v-tx", hw->name); - vlib_node_rename (vm, hw->output_node_index, "%v-output", hw->name); - - /* free the old name vector */ - vec_free (old_name); - - return error; -} - -static clib_error_t * -vnet_hw_interface_change_mac_address_helper (vnet_main_t * vnm, - u32 hw_if_index, u64 mac_address) -{ - clib_error_t *error = 0; - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - - if (hi->hw_address) - { - vnet_device_class_t *dev_class = - vnet_get_device_class (vnm, hi->dev_class_index); - if (dev_class->mac_addr_change_function) - { - error = - dev_class->mac_addr_change_function (hi, (char *) &mac_address); - } - if (!error) - { - vnet_hw_interface_class_t *hw_class; - - hw_class = vnet_get_hw_interface_class (vnm, hi->hw_class_index); - - if (NULL != hw_class->mac_addr_change_function) - hw_class->mac_addr_change_function (hi, (char *) &mac_address); - } - else - { - error = - clib_error_return (0, - "MAC Address Change is not supported on this interface"); - } - } - else - { - error = - clib_error_return (0, - "mac address change is not supported for interface index %u", - hw_if_index); - } - return error; -} - -clib_error_t * -vnet_hw_interface_change_mac_address (vnet_main_t * vnm, u32 hw_if_index, - u64 mac_address) -{ - return vnet_hw_interface_change_mac_address_helper - (vnm, hw_if_index, mac_address); -} - -vnet_l3_packet_type_t -vnet_link_to_l3_proto (vnet_link_t link) -{ - switch (link) - { - case VNET_LINK_IP4: - return (VNET_L3_PACKET_TYPE_IP4); - case VNET_LINK_IP6: - return (VNET_L3_PACKET_TYPE_IP6); - case VNET_LINK_MPLS: - return (VNET_L3_PACKET_TYPE_MPLS_UNICAST); - case VNET_LINK_ARP: - return (VNET_L3_PACKET_TYPE_ARP); - case VNET_LINK_ETHERNET: - ASSERT (0); - break; - } - ASSERT (0); - return (0); -} - -u8 * -default_build_rewrite (vnet_main_t * vnm, - u32 sw_if_index, - vnet_link_t link_type, const void *dst_address) -{ - return (NULL); -} - -void -default_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) -{ - u8 *rewrite; - - rewrite = vnet_build_rewrite_for_sw_interface (vnm, sw_if_index, - adj_get_link_type (ai), - NULL); - - adj_nbr_update_rewrite (ai, ADJ_NBR_REWRITE_FLAG_COMPLETE, rewrite); -} - - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ |