X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Finterface.c;h=982abbd0199dfe402bfe54b81d201a27f5ef7851;hb=9c412e9ee58ae4a2671d63f70add6fd2c6c15a2b;hp=278cd6e50c3ca98efe58c1a7cedd6dc8fe0a6b72;hpb=79e087fb0a4f075c478d3d56ee3d39396f5f827d;p=vpp.git diff --git a/src/vnet/interface.c b/src/vnet/interface.c index 278cd6e50c3..982abbd0199 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -462,9 +462,6 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, goto done; } - /* 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; @@ -807,6 +804,36 @@ setup_output_node (vlib_main_t * vm, n->unformat_buffer = hw_class->unformat_header; } +void +vnet_reset_interface_l3_output_node (vlib_main_t *vm, u32 sw_if_index) +{ + vnet_set_interface_l3_output_node (vm, sw_if_index, + (u8 *) "interface-output"); +} + +void +vnet_set_interface_l3_output_node (vlib_main_t *vm, u32 sw_if_index, + u8 *output_node) +{ + vlib_node_t *l3_node; + + l3_node = vlib_get_node_by_name (vm, output_node); + + static char *arcs[] = { + "ip4-output", + "ip6-output", + "mpls-output", + "ethernet-output", + }; + u8 a; + + for (a = 0; a < ARRAY_LEN (arcs); a++) + { + u8 arc = vnet_get_feature_arc_index (arcs[a]); + vnet_feature_modify_end_node (arc, sw_if_index, l3_node->index); + } +} + /* Register an interface instance. */ u32 vnet_register_interface (vnet_main_t * vnm, @@ -836,6 +863,10 @@ vnet_register_interface (vnet_main_t * vnm, hw->hw_if_index = hw_index; hw->default_rx_mode = VNET_HW_IF_RX_MODE_POLLING; + if (hw_class->tx_hash_fn_type == VNET_HASH_FN_TYPE_ETHERNET || + hw_class->tx_hash_fn_type == VNET_HASH_FN_TYPE_IP) + hw->hf = vnet_hash_default_function (hw_class->tx_hash_fn_type); + 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) @@ -993,6 +1024,7 @@ vnet_register_interface (vnet_main_t * vnm, static char *e[] = { "interface is down", "interface is deleted", + "no tx queue available", }; r.n_errors = ARRAY_LEN (e); @@ -1109,12 +1141,10 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index) 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); vec_free (hw->hw_address); - vec_free (hw->input_node_thread_index_by_queue); - vec_free (hw->rx_queue_indices); + vec_free (hw->output_node_thread_runtimes); pool_put (im->hw_interfaces, hw); } @@ -1334,6 +1364,29 @@ vnet_sw_interface_is_nbma (vnet_main_t * vnm, u32 sw_if_index) return (hc->flags & VNET_HW_INTERFACE_CLASS_FLAG_NBMA); } +clib_error_t * +vnet_sw_interface_supports_addressing (vnet_main_t *vnm, u32 sw_if_index) +{ + if (sw_if_index == 0) + { + return clib_error_create ( + "local0 interface doesn't support IP addressing"); + } + + if (vnet_sw_interface_is_sub (vnm, sw_if_index)) + { + vnet_sw_interface_t *si; + si = vnet_get_sw_interface_or_null (vnm, sw_if_index); + if (si && si->type == VNET_SW_INTERFACE_TYPE_SUB && + si->sub.eth.flags.exact_match == 0) + { + return clib_error_create ( + "sub-interface without exact-match doesn't support IP addressing"); + } + } + return NULL; +} + clib_error_t * vnet_interface_init (vlib_main_t * vm) { @@ -1610,20 +1663,48 @@ vnet_hw_interface_change_mac_address (vnet_main_t * vnm, u32 hw_if_index, (vnm, hw_if_index, mac_address); } +static int +vnet_sw_interface_check_table_same (u32 unnumbered_sw_if_index, + u32 ip_sw_if_index) +{ + if (ip4_main.fib_index_by_sw_if_index[unnumbered_sw_if_index] != + ip4_main.fib_index_by_sw_if_index[ip_sw_if_index]) + return VNET_API_ERROR_UNEXPECTED_INTF_STATE; + + if (ip4_main.mfib_index_by_sw_if_index[unnumbered_sw_if_index] != + ip4_main.mfib_index_by_sw_if_index[ip_sw_if_index]) + return VNET_API_ERROR_UNEXPECTED_INTF_STATE; + + if (ip6_main.fib_index_by_sw_if_index[unnumbered_sw_if_index] != + ip6_main.fib_index_by_sw_if_index[ip_sw_if_index]) + return VNET_API_ERROR_UNEXPECTED_INTF_STATE; + + if (ip6_main.mfib_index_by_sw_if_index[unnumbered_sw_if_index] != + ip6_main.mfib_index_by_sw_if_index[ip_sw_if_index]) + return VNET_API_ERROR_UNEXPECTED_INTF_STATE; + + return 0; +} + /* update the unnumbered state of an interface*/ -void +int vnet_sw_interface_update_unnumbered (u32 unnumbered_sw_if_index, u32 ip_sw_if_index, u8 enable) { vnet_main_t *vnm = vnet_get_main (); vnet_sw_interface_t *si; u32 was_unnum; + int rv = 0; si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index); was_unnum = (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED); if (enable) { + rv = vnet_sw_interface_check_table_same (unnumbered_sw_if_index, + ip_sw_if_index); + if (rv != 0) + return rv; si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED; si->unnumbered_sw_if_index = ip_sw_if_index; @@ -1639,13 +1720,20 @@ vnet_sw_interface_update_unnumbered (u32 unnumbered_sw_if_index, } else { - si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED); - si->unnumbered_sw_if_index = (u32) ~ 0; + /* + * Unless the interface is actually unnumbered, don't + * smash e.g. if_address_pool_index_by_sw_if_index + */ + if (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED) + { + si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED); + si->unnumbered_sw_if_index = (u32) ~0; - ip4_main.lookup_main.if_address_pool_index_by_sw_if_index - [unnumbered_sw_if_index] = ~0; - ip6_main.lookup_main.if_address_pool_index_by_sw_if_index - [unnumbered_sw_if_index] = ~0; + ip4_main.lookup_main + .if_address_pool_index_by_sw_if_index[unnumbered_sw_if_index] = ~0; + ip6_main.lookup_main + .if_address_pool_index_by_sw_if_index[unnumbered_sw_if_index] = ~0; + } } if (was_unnum != (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)) @@ -1653,6 +1741,8 @@ vnet_sw_interface_update_unnumbered (u32 unnumbered_sw_if_index, ip4_sw_interface_enable_disable (unnumbered_sw_if_index, enable); ip6_sw_interface_enable_disable (unnumbered_sw_if_index, enable); } + + return 0; } vnet_l3_packet_type_t