Prevent Bridge Domain operations on BD 0.
[vpp.git] / src / vnet / l2 / l2_bd.c
index cfaf4c9..4ebbb54 100644 (file)
@@ -92,15 +92,21 @@ bd_add_bd_index (bd_main_t * bdm, u32 bd_id)
 static int
 bd_delete (bd_main_t * bdm, u32 bd_index)
 {
-  u32 bd_id = l2input_main.bd_configs[bd_index].bd_id;
+  l2_bridge_domain_t *bd = &l2input_main.bd_configs[bd_index];
+  u32 bd_id = bd->bd_id;
   hash_unset (bdm->bd_index_by_bd_id, bd_id);
 
   /* mark this index clear */
   bdm->bd_index_bitmap = clib_bitmap_set (bdm->bd_index_bitmap, bd_index, 0);
 
-  l2input_main.bd_configs[bd_index].bd_id = ~0;
-  l2input_main.bd_configs[bd_index].feature_bitmap = 0;
+  /* clear BD config for reuse: bd_id to -1 and clear feature_bitmap */
+  bd->bd_id = ~0;
+  bd->feature_bitmap = 0;
 
+  /* free memory used by BD and flush non-static MACs in BD */
+  vec_free (bd->members);
+  hash_free (bd->mac_by_ip4);
+  hash_free (bd->mac_by_ip6);
   l2fib_flush_bd_mac (vlib_get_main (), bd_index);
 
   return 0;
@@ -298,6 +304,10 @@ bd_learn (vlib_main_t * vm,
       goto done;
     }
 
+  if (bd_id == 0)
+    return clib_error_return (0,
+                             "No operations on the default bridge domain are supported");
+
   p = hash_get (bdm->bd_index_by_bd_id, bd_id);
 
   if (p == 0)
@@ -363,6 +373,10 @@ bd_fwd (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd)
       goto done;
     }
 
+  if (bd_id == 0)
+    return clib_error_return (0,
+                             "No operations on the default bridge domain are supported");
+
   p = hash_get (bdm->bd_index_by_bd_id, bd_id);
 
   if (p == 0)
@@ -430,6 +444,10 @@ bd_flood (vlib_main_t * vm,
       goto done;
     }
 
+  if (bd_id == 0)
+    return clib_error_return (0,
+                             "No operations on the default bridge domain are supported");
+
   p = hash_get (bdm->bd_index_by_bd_id, bd_id);
 
   if (p == 0)
@@ -496,6 +514,10 @@ bd_uu_flood (vlib_main_t * vm,
       goto done;
     }
 
+  if (bd_id == 0)
+    return clib_error_return (0,
+                             "No operations on the default bridge domain are supported");
+
   p = hash_get (bdm->bd_index_by_bd_id, bd_id);
 
   if (p == 0)
@@ -562,6 +584,10 @@ bd_arp_term (vlib_main_t * vm,
       goto done;
     }
 
+  if (bd_id == 0)
+    return clib_error_return (0,
+                             "No operations on the default bridge domain are supported");
+
   p = hash_get (bdm->bd_index_by_bd_id, bd_id);
   if (p)
     bd_index = *p;
@@ -601,6 +627,10 @@ bd_mac_age (vlib_main_t * vm,
       goto done;
     }
 
+  if (bd_id == 0)
+    return clib_error_return (0,
+                             "No operations on the default bridge domain are supported");
+
   p = hash_get (bdm->bd_index_by_bd_id, bd_id);
 
   if (p == 0)
@@ -774,6 +804,10 @@ bd_arp_entry (vlib_main_t * vm,
       goto done;
     }
 
+  if (bd_id == 0)
+    return clib_error_return (0,
+                             "No operations on the default bridge domain are supported");
+
   p = hash_get (bdm->bd_index_by_bd_id, bd_id);
 
   if (p)
@@ -894,7 +928,7 @@ bd_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd)
   u32 bd_id = ~0;
   uword *p;
 
-  start = 0;
+  start = 1;
   end = vec_len (l2input_main.bd_configs);
 
   if (unformat (input, "%d", &bd_id))
@@ -908,6 +942,10 @@ bd_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd)
       if (unformat (input, "arp"))
        arp = 1;
 
+      if (bd_id == 0)
+       return clib_error_return (0,
+                                 "No operations on the default bridge domain are supported");
+
       p = hash_get (bdm->bd_index_by_bd_id, bd_id);
       if (p)
        bd_index = *p;
@@ -1119,6 +1157,8 @@ bd_add_del (l2_bridge_domain_add_del_args_t * a)
     {
       if (bd_index == ~0)
        return VNET_API_ERROR_NO_SUCH_ENTRY;
+      if (bd_index == 0)
+       return VNET_API_ERROR_BD_NOT_MODIFIABLE;
       if (vec_len (l2input_main.bd_configs[bd_index].members))
        return VNET_API_ERROR_BD_IN_USE;
       rv = bd_delete (bdm, bd_index);
@@ -1182,6 +1222,12 @@ bd_add_del_command_fn (vlib_main_t * vm, unformat_input_t * input,
       goto done;
     }
 
+  if (bd_id == 0)
+    {
+      error = clib_error_return (0, "bridge domain 0 can not be modified");
+      goto done;
+    }
+
   if (mac_age > 255)
     {
       error = clib_error_return (0, "mac age must be less than 256");
@@ -1212,6 +1258,9 @@ bd_add_del_command_fn (vlib_main_t * vm, unformat_input_t * input,
     case VNET_API_ERROR_NO_SUCH_ENTRY:
       error = clib_error_return (0, "bridge domain id does not exist");
       goto done;
+    case VNET_API_ERROR_BD_NOT_MODIFIABLE:
+      error = clib_error_return (0, "bridge domain 0 can not be modified");
+      goto done;
     default:
       error = clib_error_return (0, "bd_add_del returned %d", rv);
       goto done;