Enforce Bridge Domain ID range to match 24-bit VNI range
Enforce bridge domain ID range to allow a maximum value of 16M
which matches the range of 24-bit VNI used for virtual overlay
network ID.
Fix "show bridge-domain" output to allow full 16M BD ID range
to be displayed using 8-digit spaces.
Change-Id: I80d9c76ea7c001bcccd3c19df1f3e55d2970f01c
Signed-off-by: John Lo <loj@cisco.com>
diff --git a/src/vlibapi/api_helper_macros.h b/src/vlibapi/api_helper_macros.h
index a492c3f..2e29d4d 100644
--- a/src/vlibapi/api_helper_macros.h
+++ b/src/vlibapi/api_helper_macros.h
@@ -155,6 +155,20 @@
; \
} while (0);
+#define VALIDATE_BD_ID(mp) \
+ do { u32 __rx_bd_id = ntohl(mp->bd_id); \
+ if (__rx_bd_id > L2_BD_ID_MAX) { \
+ rv = VNET_API_ERROR_BD_ID_EXCEED_MAX; \
+ goto bad_bd_id; \
+ } \
+} while(0);
+
+#define BAD_BD_ID_LABEL \
+do { \
+bad_bd_id: \
+ ; \
+} while (0);
+
#define pub_sub_handler(lca,UCA) \
static void vl_api_want_##lca##_t_handler ( \
vl_api_want_##lca##_t *mp) \
diff --git a/src/vnet/api_errno.h b/src/vnet/api_errno.h
index e694fbf..b22bb3a 100644
--- a/src/vnet/api_errno.h
+++ b/src/vnet/api_errno.h
@@ -110,8 +110,9 @@
_(APPLICATION_NOT_ATTACHED, -118, "application not attached") \
_(BD_ALREADY_EXISTS, -119, "Bridge domain already exists") \
_(BD_IN_USE, -120, "Bridge domain has member interfaces") \
-_(BD_NOT_MODIFIABLE, -121, "Default bridge domain 0 can be neither deleted nor modified") \
-_(UNSUPPORTED, -122, "Unsupported")
+_(BD_NOT_MODIFIABLE, -121, "Bridge domain 0 can't be deleted/modified") \
+_(BD_ID_EXCEED_MAX, -122, "Bridge domain ID exceed 16M limit") \
+_(UNSUPPORTED, -123, "Unsupported")
typedef enum
{
diff --git a/src/vnet/l2/l2_bd.c b/src/vnet/l2/l2_bd.c
index 351e698..f68b663 100644
--- a/src/vnet/l2/l2_bd.c
+++ b/src/vnet/l2/l2_bd.c
@@ -984,10 +984,10 @@
{
printed = 1;
vlib_cli_output (vm,
- "%=5s %=7s %=4s %=9s %=9s %=9s %=9s %=9s %=9s %=9s",
- "ID", "Index", "BSN", "Age(min)", "Learning",
- "U-Forwrd", "UU-Flood", "Flooding", "ARP-Term",
- "BVI-Intf");
+ "%=8s %=7s %=4s %=9s %=9s %=9s %=9s %=9s %=9s %=9s",
+ "BD-ID", "Index", "BSN", "Age(min)",
+ "Learning", "U-Forwrd", "UU-Flood", "Flooding",
+ "ARP-Term", "BVI-Intf");
}
if (bd_config->mac_age)
@@ -995,7 +995,7 @@
else
as = format (as, "off");
vlib_cli_output (vm,
- "%=5d %=7d %=4d %=9v %=9s %=9s %=9s %=9s %=9s %=9U",
+ "%=8d %=7d %=4d %=9v %=9s %=9s %=9s %=9s %=9s %=9U",
bd_config->bd_id, bd_index, bd_config->seq_num, as,
bd_config->feature_bitmap & L2INPUT_FEAT_LEARN ?
"on" : "off",
@@ -1123,6 +1123,8 @@
{
if (bd_index != ~0)
return VNET_API_ERROR_BD_ALREADY_EXISTS;
+ if (a->bd_id > L2_BD_ID_MAX)
+ return VNET_API_ERROR_BD_ID_EXCEED_MAX;
bd_index = bd_add_bd_index (bdm, a->bd_id);
u32 enable_flags = 0, disable_flags = 0;
@@ -1262,11 +1264,14 @@
error = clib_error_return (0, "bridge domain in use - remove members");
goto done;
case VNET_API_ERROR_NO_SUCH_ENTRY:
- error = clib_error_return (0, "bridge domain id does not exist");
+ 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;
+ case VNET_API_ERROR_BD_ID_EXCEED_MAX:
+ error = clib_error_return (0, "bridge domain ID exceed 16M limit");
+ goto done;
default:
error = clib_error_return (0, "bd_add_del returned %d", rv);
goto done;
diff --git a/src/vnet/l2/l2_bd.h b/src/vnet/l2/l2_bd.h
index e502d49..93ed1a8 100644
--- a/src/vnet/l2/l2_bd.h
+++ b/src/vnet/l2/l2_bd.h
@@ -49,7 +49,6 @@
u16 spare;
} l2_flood_member_t;
-
/* Per-bridge domain configuration */
typedef struct
@@ -91,6 +90,9 @@
} l2_bridge_domain_t;
+/* Limit Bridge Domain ID to 24 bits to match 24-bit VNI range */
+#define L2_BD_ID_MAX ((1<<24)-1)
+
typedef struct
{
u32 bd_id;
diff --git a/src/vnet/l2/l2_input.c b/src/vnet/l2/l2_input.c
index 41a93f5..aca23fe 100644
--- a/src/vnet/l2/l2_input.c
+++ b/src/vnet/l2/l2_input.c
@@ -791,6 +791,12 @@
goto done;
}
+ if (bd_id > L2_BD_ID_MAX)
+ {
+ error = clib_error_return (0, "bridge domain ID exceed 16M limit",
+ format_unformat_error, input);
+ goto done;
+ }
bd_index = bd_find_or_add_bd_index (&bd_main, bd_id);
/* optional bvi */
diff --git a/src/vnet/lisp-gpe/interface.c b/src/vnet/lisp-gpe/interface.c
index ff75056..94703ab 100644
--- a/src/vnet/lisp-gpe/interface.c
+++ b/src/vnet/lisp-gpe/interface.c
@@ -653,6 +653,12 @@
uword *hip, *si;
u16 bd_index;
+ if (bd_id > L2_BD_ID_MAX)
+ {
+ clib_warning ("bridge domain ID %d exceed 16M limit", bd_id);
+ return ~0;
+ }
+
bd_index = bd_find_or_add_bd_index (&bd_main, bd_id);
hip = hash_get (l2_ifaces->hw_if_index_by_dp_table, bd_index);
diff --git a/src/vpp/api/api.c b/src/vpp/api/api.c
index 16d5122..7e4c341 100644
--- a/src/vpp/api/api.c
+++ b/src/vpp/api/api.c
@@ -419,6 +419,7 @@
if (mp->enable)
{
+ VALIDATE_BD_ID (mp);
u32 bd_id = ntohl (mp->bd_id);
u32 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
u32 bvi = mp->bvi;
@@ -432,6 +433,7 @@
}
BAD_RX_SW_IF_INDEX_LABEL;
+ BAD_BD_ID_LABEL;
REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
}