VPP-363: add ability to change mac address of the interface
[vpp.git] / vnet / vnet / interface.c
index d84c8b0..ca0df9d 100644 (file)
 
 #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)
 
-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_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_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);
+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 {
+typedef struct
+{
   /* Either sw or hw interface index. */
   u32 sw_hw_if_index;
 
@@ -62,35 +68,47 @@ typedef struct {
   u32 flags;
 } vnet_sw_hw_interface_state_t;
 
-static void serialize_vec_vnet_sw_hw_interface_state (serialize_main_t * m, va_list * va)
+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));
+  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)
+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));
+  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)
+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 *);
+  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)
+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;
@@ -98,11 +116,12 @@ static void unserialize_vnet_sw_interface_set_flags (serialize_main_t * m, va_li
   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,
+    (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)
+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;
@@ -110,38 +129,42 @@ static void unserialize_vnet_hw_interface_set_flags (serialize_main_t * m, va_li
   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,
+    (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_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,
-};
+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)
+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;
+  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)
       {
@@ -150,12 +173,14 @@ void serialize_vnet_interface_state (serialize_main_t * m, va_list * va)
        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)
       {
@@ -164,25 +189,28 @@ void serialize_vnet_interface_state (serialize_main_t * m, va_list * va)
        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)
+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;
+  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;
+    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);
@@ -192,6 +220,7 @@ void unserialize_vnet_interface_state (serialize_main_t * m, va_list * va)
        clib_error_report (error);
       vec_free (class_name);
     }));
+    /* *INDENT-ON* */
   }
 
   vec_unserialize (m, &sts, unserialize_vec_vnet_sw_hw_interface_state);
@@ -208,48 +237,56 @@ void unserialize_vnet_interface_state (serialize_main_t * m, va_list * va)
 }
 
 static clib_error_t *
-call_elf_section_interface_callbacks (vnet_main_t * vnm, u32 if_index, 
-                                      u32 flags, 
-                                      _vnet_interface_function_list_elt_t *elt)
+call_elf_section_interface_callbacks (vnet_main_t * vnm, u32 if_index,
+                                     u32 flags,
+                                     _vnet_interface_function_list_elt_t *
+                                     elt)
 {
-  clib_error_t * error = 0;
+  clib_error_t *error = 0;
 
   while (elt)
     {
-      error = elt->fp(vnm, if_index, flags);
+      error = elt->fp (vnm, if_index, flags);
       if (error)
-        return 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)
+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;
+  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)))
+      && (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)))
+      && (error =
+         dev_class->interface_add_del_function (vnm, hw_if_index,
+                                                is_create)))
     return error;
 
-  error = call_elf_section_interface_callbacks 
+  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)
+call_sw_interface_add_del_callbacks (vnet_main_t * vnm, u32 sw_if_index,
+                                    u32 is_create)
 {
-  return call_elf_section_interface_callbacks 
+  return call_elf_section_interface_callbacks
     (vnm, sw_if_index, is_create, vnm->sw_interface_add_del_functions);
 }
 
@@ -257,19 +294,23 @@ call_sw_interface_add_del_callbacks (vnet_main_t * vnm, u32 sw_if_index, u32 is_
 #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_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;
+  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;
+  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);
+  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. */
@@ -277,12 +318,12 @@ vnet_hw_interface_set_flags_helper (vnet_main_t * vnm, u32 hw_if_index, u32 flag
     call_hw_interface_add_del_callbacks (vnm, hw_if_index, is_create);
 
   /* Already in the desired state? */
-  if (! is_create && (hi->flags & mask) == flags)
+  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 (!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))
@@ -302,9 +343,9 @@ vnet_hw_interface_set_flags_helper (vnet_main_t * vnm, u32 hw_if_index, u32 flag
                                                       flags)))
        goto done;
 
-      error = call_elf_section_interface_callbacks 
-       (vnm, hw_if_index, is_create, vnm->hw_interface_link_up_down_functions);
-      
+      error = call_elf_section_interface_callbacks
+       (vnm, hw_if_index, flags, vnm->hw_interface_link_up_down_functions);
+
       if (error)
        goto done;
     }
@@ -312,19 +353,20 @@ vnet_hw_interface_set_flags_helper (vnet_main_t * vnm, u32 hw_if_index, u32 flag
   hi->flags &= ~mask;
   hi->flags |= flags;
 
- done:
+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_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;
+  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;
+  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;
@@ -332,62 +374,75 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, u32 flag
 
   if (is_create)
     {
-      error = call_sw_interface_add_del_callbacks (vnm, sw_if_index, 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;
-        }
+       {
+         /* 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;
+      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);
 
-         if (flags != (si_sup->flags & mask))
+         /* 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);
+                                        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);
+       {
+         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. */
+         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;
+         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))
+         && (helper_flags &
+             VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE))
        {
          vnet_sw_hw_interface_state_t s;
          s.sw_hw_if_index = sw_if_index;
@@ -395,50 +450,62 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, u32 flag
          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;
+       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;
-            }
+         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)
+         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,
+                                               hi->flags &
+                                               ~VNET_HW_INTERFACE_FLAG_LINK_UP,
                                                helper_flags);
        }
     }
@@ -446,7 +513,7 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, u32 flag
   si->flags &= ~mask;
   si->flags |= flags;
 
- done:
+done:
   return error;
 }
 
@@ -467,10 +534,11 @@ vnet_sw_interface_set_flags (vnet_main_t * vnm, u32 sw_if_index, u32 flags)
 }
 
 static u32
-vnet_create_sw_interface_no_callbacks (vnet_main_t * vnm, vnet_sw_interface_t * template)
+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;
+  vnet_interface_main_t *im = &vnm->interface_main;
+  vnet_sw_interface_t *sw;
   u32 sw_if_index;
 
   pool_get (im->sw_interfaces, sw);
@@ -487,7 +555,7 @@ vnet_create_sw_interface_no_callbacks (vnet_main_t * vnm, vnet_sw_interface_t *
   {
     u32 i;
 
-    vnet_interface_counter_lock(im);
+    vnet_interface_counter_lock (im);
 
     for (i = 0; i < vec_len (im->sw_if_counters); i++)
       {
@@ -497,55 +565,62 @@ vnet_create_sw_interface_no_callbacks (vnet_main_t * vnm, vnet_sw_interface_t *
 
     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);
+       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);
+    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)
+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;
+  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;
-  }
+      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);
-  }
+  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)
+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);
+  vnet_interface_main_t *im = &vnm->interface_main;
+  vnet_sw_interface_t *sw =
+    pool_elt_at_index (im->sw_interfaces, sw_if_index);
 
   /* Bring down interface in case it is up. */
   if (sw->flags != 0)
@@ -556,24 +631,24 @@ void vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
   pool_put (im->sw_interfaces, sw);
 }
 
-static void setup_tx_node (vlib_main_t * vm,
-                          u32 node_index,
-                          vnet_device_class_t * dev_class)
+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);
+  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);
+  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)
+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);
+  vlib_node_t *n = vlib_get_node (vm, node_index);
   n->format_buffer = hw_class->format_header;
   n->unformat_buffer = hw_class->unformat_header;
 }
@@ -583,16 +658,17 @@ u32
 vnet_register_interface (vnet_main_t * vnm,
                         u32 dev_class_index,
                         u32 dev_instance,
-                        u32 hw_class_index,
-                        u32 hw_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_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;
   u32 hw_index;
-  char * tx_node_name, * output_node_name;
+  char *tx_node_name, *output_node_name;
 
   pool_get (im->hw_interfaces, hw);
 
@@ -600,16 +676,15 @@ vnet_register_interface (vnet_main_t * vnm,
   hw->hw_if_index = hw_index;
 
   if (dev_class->format_device_name)
-    hw->name = format (0, "%U",
-                      dev_class->format_device_name, dev_instance);
+    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,
+  if (!im->hw_interface_by_name)
+    im->hw_interface_by_name = hash_create_vec ( /* size */ 0,
                                                sizeof (hw->name[0]),
                                                sizeof (uword));
 
@@ -642,8 +717,8 @@ vnet_register_interface (vnet_main_t * vnm,
   /* 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;
+      vnet_hw_interface_nodes_t *hn;
+      vnet_interface_output_runtime_t *rt;
 
       hn = vec_end (im->deleted_hw_interface_nodes) - 1;
 
@@ -656,7 +731,7 @@ vnet_register_interface (vnet_main_t * vnm,
       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->hw_if_index = hw_index;
       rt->sw_if_index = hw->sw_if_index;
       rt->dev_instance = hw->dev_instance;
 
@@ -665,7 +740,7 @@ vnet_register_interface (vnet_main_t * vnm,
       rt->sw_if_index = hw->sw_if_index;
       rt->dev_instance = hw->dev_instance;
 
-      vlib_worker_thread_node_runtime_update();
+      vlib_worker_thread_node_runtime_update ();
       _vec_len (im->deleted_hw_interface_nodes) -= 1;
     }
   else
@@ -697,13 +772,13 @@ vnet_register_interface (vnet_main_t * vnm,
 
       r.flags = 0;
       r.name = output_node_name;
-      r.function =  dev_class->no_flatten_output_chains ?
-          vnet_interface_output_node_no_flatten_multiarch_select() :
-          vnet_interface_output_node_multiarch_select() ;
+      r.function = dev_class->no_flatten_output_chains ?
+       vnet_interface_output_node_no_flatten_multiarch_select () :
+       vnet_interface_output_node_multiarch_select ();
       r.format_trace = format_vnet_interface_output_trace;
 
       {
-       static char * e[] = {
+       static char *e[] = {
          "interface is down",
          "interface is deleted",
        };
@@ -711,7 +786,6 @@ vnet_register_interface (vnet_main_t * vnm,
        r.n_errors = ARRAY_LEN (e);
        r.error_strings = e;
       }
-
       hw->output_node_index = vlib_register_node (vm, &r);
 
 #define _(sym,str) vlib_node_add_named_next_with_slot (vm, \
@@ -719,10 +793,9 @@ vnet_register_interface (vnet_main_t * vnm,
                      VNET_INTERFACE_OUTPUT_NEXT_##sym);
       foreach_intf_output_feat
 #undef _
-
-      vlib_node_add_named_next_with_slot (vm, hw->output_node_index,
-                                         "error-drop",
-                                         VNET_INTERFACE_OUTPUT_NEXT_DROP);
+       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);
@@ -732,21 +805,20 @@ vnet_register_interface (vnet_main_t * vnm,
   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);
+  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)
+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;
+  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)
@@ -761,20 +833,25 @@ void vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_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);
+    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);
+    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;
@@ -786,42 +863,49 @@ void vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index)
   pool_put (im->hw_interfaces, hw);
 }
 
-static void serialize_vnet_hw_interface_set_class (serialize_main_t * m, va_list * va)
+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 *);
+  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)
+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();
+  vnet_main_t *vnm = vnet_get_main ();
   u32 hw_if_index;
-  char * hw_class_name;
-  uword * p;
-  clib_error_t * error;
+  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);
+  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);
+  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,
-};
+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)
+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);
+  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;
@@ -829,14 +913,18 @@ void vnet_hw_interface_init_for_class (vnet_main_t * vnm, u32 hw_if_index, u32 h
 }
 
 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_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;
+  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)
@@ -847,31 +935,40 @@ vnet_hw_interface_set_class_helper (vnet_main_t * vnm, u32 hw_if_index, u32 hw_c
   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",
+       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",
+          && !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);
+         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);
+    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);
+  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);
+    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);
@@ -880,23 +977,27 @@ vnet_hw_interface_set_class_helper (vnet_main_t * vnm, u32 hw_if_index, u32 hw_c
 }
 
 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); }
+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_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 
+  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);
+      ASSERT (vnm->vlib_main->mc_main == 0);
     }
   if (dev_class->rx_redirect_to_node)
     {
@@ -907,20 +1008,23 @@ vnet_hw_interface_rx_redirect_to_node_helper (vnet_main_t * vnm,
   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 */); }
+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);
+  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);
@@ -931,8 +1035,8 @@ 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);
+  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);
@@ -942,38 +1046,37 @@ vnet_hw_interface_compare (vnet_main_t * vnm,
 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;
+  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))
+  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;
+      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));
+      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 */
+  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);
+  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_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";
@@ -986,43 +1089,43 @@ vnet_interface_init (vlib_main_t * vm)
 
   im->sw_if_counter_lock[0] = 0;
 
-  im->device_class_by_name = hash_create_string (/* size */ 0,
+  im->device_class_by_name = hash_create_string ( /* size */ 0,
                                                 sizeof (uword));
   {
-    vnet_device_class_t * c;
+    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;
+       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,
+  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));
+  im->sw_if_index_by_sup_and_sub = hash_create_mem (0, sizeof (u64),
+                                                   sizeof (uword));
   {
-    vnet_hw_interface_class_t * c;
+    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);
-        vec_add1 (im->hw_interface_classes, c[0]);
-        c = c->next_class_registration;
+       c->index = vec_len (im->hw_interface_classes);
+       hash_set_mem (im->hw_interface_class_by_name, c->name, c->index);
+       vec_add1 (im->hw_interface_classes, c[0]);
+       c = c->next_class_registration;
       }
   }
 
   {
-    clib_error_t * error;
+    clib_error_t *error;
 
     if ((error = vlib_call_init_function (vm, vnet_interface_cli_init)))
       return error;
@@ -1034,18 +1137,19 @@ vnet_interface_init (vlib_main_t * vm)
 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
+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_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 
+  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;
+    return VNET_API_ERROR_UNIMPLEMENTED;
 
   rv = dev_class->name_renumber (hi, new_show_dev_instance);
 
@@ -1055,72 +1159,137 @@ int vnet_interface_name_renumber (u32 sw_if_index, u32 new_show_dev_instance)
   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);
-  
+  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;
 }
 
-int vnet_interface_add_del_feature(vnet_main_t * vnm,
-                                   vlib_main_t *vm,
-                                   u32 sw_if_index,
-                                   intf_output_feat_t feature,
-                                   int is_add)
+int
+vnet_interface_add_del_feature (vnet_main_t * vnm,
+                               vlib_main_t * vm,
+                               u32 sw_if_index,
+                               intf_output_feat_t feature, int is_add)
 {
-  vnet_sw_interface_t * sw;
+  vnet_sw_interface_t *sw;
 
-  sw = vnet_get_sw_interface(vnm, sw_if_index);
+  sw = vnet_get_sw_interface (vnm, sw_if_index);
 
-  if (is_add) {
+  if (is_add)
+    {
 
-    sw->output_feature_bitmap |= (1 << feature);
-    sw->output_feature_bitmap |= (1<< INTF_OUTPUT_FEAT_DONE);
+      sw->output_feature_bitmap |= (1 << feature);
+      sw->output_feature_bitmap |= (1 << INTF_OUTPUT_FEAT_DONE);
 
-  } else { /* delete */
+    }
+  else
+    {                          /* delete */
 
-    sw->output_feature_bitmap &= ~(1<<feature);
-    if (sw->output_feature_bitmap == (1 << INTF_OUTPUT_FEAT_DONE))
-      sw->output_feature_bitmap = 0;
+      sw->output_feature_bitmap &= ~(1 << feature);
+      if (sw->output_feature_bitmap == (1 << INTF_OUTPUT_FEAT_DONE))
+       sw->output_feature_bitmap = 0;
 
-  }
+    }
   return 0;
 }
 
 clib_error_t *
-vnet_rename_interface (vnet_main_t * vnm,
-                       u32           hw_if_index,
-                       char *        new_name)
+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_thw;
-  u8old_name;
-  clib_error_t * error = 0;
+  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);
+  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);
+                               "unable to find hw interface for index %u",
+                               hw_if_index);
     }
 
   old_name = hw->name;
 
-  // set new 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
+  /* 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
+  /* 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
+  /* 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 (vnet_get_hw_interface
+                                                (vnm, hw_if_index),
+                                                (char *) &mac_address);
+       }
+      if (!error)
+       {
+         ethernet_main_t *em = &ethernet_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
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */