summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vlibapi/api_helper_macros.h14
-rw-r--r--src/vnet/api_errno.h5
-rw-r--r--src/vnet/l2/l2_bd.c17
-rw-r--r--src/vnet/l2/l2_bd.h4
-rw-r--r--src/vnet/l2/l2_input.c6
-rw-r--r--src/vnet/lisp-gpe/interface.c6
-rw-r--r--src/vpp/api/api.c2
7 files changed, 45 insertions, 9 deletions
diff --git a/src/vlibapi/api_helper_macros.h b/src/vlibapi/api_helper_macros.h
index a492c3f40e2..2e29d4d7983 100644
--- a/src/vlibapi/api_helper_macros.h
+++ b/src/vlibapi/api_helper_macros.h
@@ -155,6 +155,20 @@ bad_tx_sw_if_index: \
; \
} 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 e694fbf1ed4..b22bb3a879f 100644
--- a/src/vnet/api_errno.h
+++ b/src/vnet/api_errno.h
@@ -110,8 +110,9 @@ _(SVM_SEGMENT_CREATE_FAIL, -117, "svm segment create fail") \
_(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 351e6987446..f68b6638618 100644
--- a/src/vnet/l2/l2_bd.c
+++ b/src/vnet/l2/l2_bd.c
@@ -984,10 +984,10 @@ bd_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd)
{
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 @@ bd_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd)
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 @@ bd_add_del (l2_bridge_domain_add_del_args_t * a)
{
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 @@ bd_add_del_command_fn (vlib_main_t * vm, unformat_input_t * input,
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 e502d497e0b..93ed1a8532a 100644
--- a/src/vnet/l2/l2_bd.h
+++ b/src/vnet/l2/l2_bd.h
@@ -49,7 +49,6 @@ typedef struct
u16 spare;
} l2_flood_member_t;
-
/* Per-bridge domain configuration */
typedef struct
@@ -91,6 +90,9 @@ typedef struct
} 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 41a93f56332..aca23fe03fc 100644
--- a/src/vnet/l2/l2_input.c
+++ b/src/vnet/l2/l2_input.c
@@ -791,6 +791,12 @@ int_l2_bridge (vlib_main_t * vm,
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 ff750563c53..94703abc4cf 100644
--- a/src/vnet/lisp-gpe/interface.c
+++ b/src/vnet/lisp-gpe/interface.c
@@ -653,6 +653,12 @@ lisp_gpe_add_l2_iface (lisp_gpe_main_t * lgm, u32 vni, u32 bd_id)
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 16d512259ac..7e4c341e12b 100644
--- a/src/vpp/api/api.c
+++ b/src/vpp/api/api.c
@@ -419,6 +419,7 @@ static void
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 @@ static void
}
BAD_RX_SW_IF_INDEX_LABEL;
+ BAD_BD_ID_LABEL;
REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
}