#include <vnet/vnet.h>
#include <vnet/plugin/plugin.h>
+#include <vnet/fib/ip6_fib.h>
#define VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE (1 << 0)
#define VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE (1 << 1)
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;
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;
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
*