X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Finterface.c;h=ca0df9d10733842bddedee452d1a25ac60f6221a;hb=c631f2de6dd06b4cbb92bf8398839b882344fd25;hp=3a12085da29aee266a4caf4d52cd07b6cac817c7;hpb=ba868bb7898edc46ad5f8cd4925af6c8b92e7c89;p=vpp.git diff --git a/vnet/vnet/interface.c b/vnet/vnet/interface.c index 3a12085da29..ca0df9d1073 100644 --- a/vnet/vnet/interface.c +++ b/vnet/vnet/interface.c @@ -39,6 +39,7 @@ #include #include +#include #define VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE (1 << 0) #define VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE (1 << 1) @@ -343,8 +344,7 @@ vnet_hw_interface_set_flags_helper (vnet_main_t * vnm, u32 hw_if_index, goto done; error = call_elf_section_interface_callbacks - (vnm, hw_if_index, is_create, - vnm->hw_interface_link_up_down_functions); + (vnm, hw_if_index, flags, vnm->hw_interface_link_up_down_functions); if (error) goto done; @@ -450,8 +450,16 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, mc_serialize (vm->mc_main, &vnet_sw_interface_set_flags_msg, &s); } - error = call_elf_section_interface_callbacks - (vnm, sw_if_index, flags, vnm->sw_interface_admin_up_down_functions); + /* 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; @@ -1222,6 +1230,62 @@ vnet_rename_interface (vnet_main_t * vnm, u32 hw_if_index, char *new_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 (vnet_get_hw_interface + (vnm, hw_if_index), + (char *) &mac_address); + } + if (!error) + { + ethernet_main_t *em = ðernet_main; + ethernet_interface_t *ei = + pool_elt_at_index (em->interfaces, hi->hw_instance); + + clib_memcpy (hi->hw_address, (u8 *) & mac_address, + sizeof (hi->hw_address)); + clib_memcpy (ei->address, (u8 *) & mac_address, + sizeof (ei->address)); + ethernet_arp_change_mac (vnm, hw_if_index); + ethernet_ndp_change_mac (vnm->vlib_main, hw_if_index); + } + 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); +} + /* * fd.io coding-style-patch-verification: ON *