X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Finterface.c;h=60f11bc3957799ecc590f18aba7cb1cb8d2d060e;hb=bdc0e6b7;hp=d85d864839eeec84937598f291f4e07fef3530fb;hpb=a50a14c5577e82866b05f325e359c86ba7145730;p=vpp.git diff --git a/src/vnet/interface.c b/src/vnet/interface.c index d85d864839e..60f11bc3957 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -42,6 +42,7 @@ #include #include #include +#include #define VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE (1 << 0) #define VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE (1 << 1) @@ -122,22 +123,6 @@ unserialize_vnet_sw_interface_set_flags (serialize_main_t * m, va_list * va) /* helper_flags no redistribution */ 0); } -void -vnet_hw_interface_set_mtu (vnet_main_t * vnm, u32 hw_if_index, u32 mtu) -{ - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - - if (hi->max_packet_bytes != mtu) - { - u16 l3_pad = hi->max_packet_bytes - hi->max_l3_packet_bytes[VLIB_TX]; - hi->max_packet_bytes = mtu; - hi->max_l3_packet_bytes[VLIB_TX] = - hi->max_l3_packet_bytes[VLIB_RX] = mtu - l3_pad; - ethernet_set_flags (vnm, hw_if_index, ETHERNET_INTERFACE_FLAG_MTU); - adj_mtu_update (hw_if_index); - } -} - static void unserialize_vnet_hw_interface_set_flags (serialize_main_t * m, va_list * va) { @@ -440,7 +425,7 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, } } - /* Donot change state for slave link of bonded interfaces */ + /* Do not change state for slave link of bonded interfaces */ if (si->flags & VNET_SW_INTERFACE_FLAG_BOND_SLAVE) { error = clib_error_return @@ -670,6 +655,7 @@ vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index) if (config->xconnect || config->bridge) set_int_l2_mode (vm, vnm, MODE_L3, sw_if_index, 0, 0, 0, 0); } + vnet_clear_sw_interface_tag (vnm, sw_if_index); /* Bring down interface in case it is up. */ if (sw->flags != 0) @@ -680,6 +666,87 @@ vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index) pool_put (im->sw_interfaces, sw); } +static clib_error_t * +call_sw_interface_mtu_change_callbacks (vnet_main_t * vnm, u32 sw_if_index) +{ + return call_elf_section_interface_callbacks + (vnm, sw_if_index, 0, vnm->sw_interface_mtu_change_functions); +} + +void +vnet_sw_interface_set_mtu (vnet_main_t * vnm, u32 sw_if_index, u32 mtu) +{ + vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); + + if (si->mtu[VNET_MTU_L3] != mtu) + { + si->mtu[VNET_MTU_L3] = mtu; + call_sw_interface_mtu_change_callbacks (vnm, sw_if_index); + } +} + +void +vnet_sw_interface_set_protocol_mtu (vnet_main_t * vnm, u32 sw_if_index, + u32 mtu[]) +{ + vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); + bool changed = false; + int i; + + for (i = 0; i < VNET_N_MTU; i++) + { + if (si->mtu[i] != mtu[i]) + { + si->mtu[i] = mtu[i]; + changed = true; + } + } + /* Notify interested parties */ + if (changed) + call_sw_interface_mtu_change_callbacks (vnm, sw_if_index); +} + +void +vnet_sw_interface_ip_directed_broadcast (vnet_main_t * vnm, + u32 sw_if_index, u8 enable) +{ + vnet_sw_interface_t *si; + + si = vnet_get_sw_interface (vnm, sw_if_index); + + if (enable) + si->flags |= VNET_SW_INTERFACE_FLAG_DIRECTED_BCAST; + else + si->flags &= ~VNET_SW_INTERFACE_FLAG_DIRECTED_BCAST; + + ip4_directed_broadcast (sw_if_index, enable); +} + +/* + * Reflect a change in hardware MTU on protocol MTUs + */ +static walk_rc_t +sw_interface_walk_callback (vnet_main_t * vnm, u32 sw_if_index, void *ctx) +{ + u32 *link_mtu = ctx; + vnet_sw_interface_set_mtu (vnm, sw_if_index, *link_mtu); + return WALK_CONTINUE; +} + +void +vnet_hw_interface_set_mtu (vnet_main_t * vnm, u32 hw_if_index, u32 mtu) +{ + vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); + + if (hi->max_packet_bytes != mtu) + { + hi->max_packet_bytes = mtu; + ethernet_set_flags (vnm, hw_if_index, ETHERNET_INTERFACE_FLAG_MTU); + vnet_hw_interface_walk_sw (vnm, hw_if_index, sw_interface_walk_callback, + &mtu); + } +} + static void setup_tx_node (vlib_main_t * vm, u32 node_index, vnet_device_class_t * dev_class) @@ -761,9 +828,7 @@ vnet_register_interface (vnet_main_t * vnm, 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; + vnet_sw_interface_set_mtu (vnm, hw->sw_if_index, 0); if (dev_class->tx_function == 0) goto no_output_nodes; /* No output/tx nodes to create */ @@ -994,8 +1059,9 @@ vnet_hw_interface_walk_sw (vnet_main_t * vnm, 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); + /* the super first, then the sub interfaces */ + if (WALK_STOP == fn (vnm, hi->sw_if_index, ctx)) + return; /* *INDENT-OFF* */ hash_foreach (id, sw_if_index, @@ -1007,6 +1073,24 @@ vnet_hw_interface_walk_sw (vnet_main_t * vnm, /* *INDENT-ON* */ } +void +vnet_hw_interface_walk (vnet_main_t * vnm, + vnet_hw_interface_walk_t fn, void *ctx) +{ + vnet_interface_main_t *im; + vnet_hw_interface_t *hi; + + im = &vnm->interface_main; + + /* *INDENT-OFF* */ + pool_foreach (hi, im->hw_interfaces, + ({ + if (WALK_STOP == fn(vnm, hi->hw_if_index, ctx)) + break; + })); + /* *INDENT-ON* */ +} + void vnet_sw_interface_walk (vnet_main_t * vnm, vnet_sw_interface_walk_t fn, void *ctx) @@ -1209,7 +1293,8 @@ int vnet_sw_interface_is_p2p (vnet_main_t * vnm, u32 sw_if_index) { vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); - if (si->type == VNET_SW_INTERFACE_TYPE_P2P) + if ((si->type == VNET_SW_INTERFACE_TYPE_P2P) || + (si->type == VNET_SW_INTERFACE_TYPE_PIPE)) return 1; vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index); @@ -1250,33 +1335,19 @@ vnet_interface_init (vlib_main_t * vm) 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_RX_UNICAST].name = - "rx-unicast"; - im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX_MULTICAST].name = - "rx-multicast"; - im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX_BROADCAST].name = - "rx-broadcast"; - im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX].name = "tx"; - im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX_UNICAST].name = - "tx-unicast"; - im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX_MULTICAST].name = - "tx-multicast"; - im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX_BROADCAST].name = - "tx-broadcast"; - - im->sw_if_counter_lock[0] = 0; +#define _(E,n,p) \ + im->sw_if_counters[VNET_INTERFACE_COUNTER_##E].name = #n; \ + im->sw_if_counters[VNET_INTERFACE_COUNTER_##E].stat_segment_name = "/" #p "/" #n; + foreach_simple_interface_counter_name +#undef _ + vec_validate (im->combined_sw_if_counters, + VNET_N_COMBINED_INTERFACE_COUNTER - 1); +#define _(E,n,p) \ + im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_##E].name = #n; \ + im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_##E].stat_segment_name = "/" #p "/" #n; + foreach_combined_interface_counter_name +#undef _ + im->sw_if_counter_lock[0] = 0; im->device_class_by_name = hash_create_string ( /* size */ 0, sizeof (uword)); @@ -1289,6 +1360,27 @@ vnet_interface_init (vlib_main_t * vm) { c->index = vec_len (im->device_classes); hash_set_mem (im->device_class_by_name, c->name, c->index); + + if (c->tx_fn_registrations) + { + vlib_node_fn_registration_t *fnr = c->tx_fn_registrations; + int priority = -1; + + /* to avoid confusion, please remove ".tx_function" statement + from VNET_DEVICE_CLASS() if using function candidates */ + ASSERT (c->tx_function == 0); + + while (fnr) + { + if (fnr->priority > priority) + { + priority = fnr->priority; + c->tx_function = fnr->function; + } + fnr = fnr->next_registration; + } + } + vec_add1 (im->device_classes, c[0]); c = c->next_class_registration; } @@ -1410,12 +1502,14 @@ vnet_hw_interface_change_mac_address_helper (vnet_main_t * vnm, if (hi->hw_address) { + u8 *old_address = vec_dup (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); + dev_class->mac_addr_change_function (hi, old_address, + mac_address); } if (!error) { @@ -1424,7 +1518,7 @@ vnet_hw_interface_change_mac_address_helper (vnet_main_t * vnm, 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); + hw_class->mac_addr_change_function (hi, old_address, mac_address); } else { @@ -1432,6 +1526,7 @@ vnet_hw_interface_change_mac_address_helper (vnet_main_t * vnm, clib_error_return (0, "MAC Address Change is not supported on this interface"); } + vec_free (old_address); } else { @@ -1518,6 +1613,22 @@ vnet_link_to_l3_proto (vnet_link_t link) return (0); } +vnet_mtu_t +vnet_link_to_mtu (vnet_link_t link) +{ + switch (link) + { + case VNET_LINK_IP4: + return (VNET_MTU_IP4); + case VNET_LINK_IP6: + return (VNET_MTU_IP6); + case VNET_LINK_MPLS: + return (VNET_MTU_MPLS); + default: + return (VNET_MTU_L3); + } +} + u8 * default_build_rewrite (vnet_main_t * vnm, u32 sw_if_index, @@ -1539,8 +1650,9 @@ default_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) adj_glean_update_rewrite (ai); break; case IP_LOOKUP_NEXT_ARP: + case IP_LOOKUP_NEXT_BCAST: /* - * default rewirte in neighbour adj + * default rewrite in neighbour adj */ adj_nbr_update_rewrite (ai,