aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/ethernet/ethernet.h3
-rw-r--r--src/vnet/ethernet/interface.c42
-rw-r--r--src/vnet/interface_api.c66
3 files changed, 56 insertions, 55 deletions
diff --git a/src/vnet/ethernet/ethernet.h b/src/vnet/ethernet/ethernet.h
index 821a576ddf5..cde6fb90038 100644
--- a/src/vnet/ethernet/ethernet.h
+++ b/src/vnet/ethernet/ethernet.h
@@ -445,6 +445,9 @@ clib_error_t *next_by_ethertype_register (next_by_ethertype_t * l3_next,
int vnet_create_loopback_interface (u32 * sw_if_indexp, u8 * mac_address,
u8 is_specified, u32 user_instance);
int vnet_delete_loopback_interface (u32 sw_if_index);
+int vnet_create_sub_interface (u32 sw_if_index, u32 id,
+ u32 flags, u16 inner_vlan_id,
+ u16 outer_vlan_id, u32 * sub_sw_if_index);
int vnet_delete_sub_interface (u32 sw_if_index);
// Perform ethernet subinterface classification table lookups given
diff --git a/src/vnet/ethernet/interface.c b/src/vnet/ethernet/interface.c
index a0fa61c25f4..7b2b162f1a0 100644
--- a/src/vnet/ethernet/interface.c
+++ b/src/vnet/ethernet/interface.c
@@ -960,6 +960,48 @@ vnet_delete_loopback_interface (u32 sw_if_index)
}
int
+vnet_create_sub_interface (u32 sw_if_index, u32 id,
+ u32 flags, u16 inner_vlan_id, u16 outer_vlan_id,
+ u32 * sub_sw_if_index)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ vnet_interface_main_t *im = &vnm->interface_main;
+ vnet_hw_interface_t *hi;
+ u64 sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) id;
+ vnet_sw_interface_t template;
+ uword *p;
+ u64 *kp;
+
+ hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
+
+ p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
+ if (p)
+ {
+ return (VNET_API_ERROR_VLAN_ALREADY_EXISTS);
+ }
+
+ clib_memset (&template, 0, sizeof (template));
+ template.type = VNET_SW_INTERFACE_TYPE_SUB;
+ template.flood_class = VNET_FLOOD_CLASS_NORMAL;
+ template.sup_sw_if_index = sw_if_index;
+ template.sub.id = id;
+ template.sub.eth.raw_flags = flags;
+ template.sub.eth.outer_vlan_id = outer_vlan_id;
+ template.sub.eth.inner_vlan_id = inner_vlan_id;
+
+ if (vnet_create_sw_interface (vnm, &template, sub_sw_if_index))
+ return (VNET_API_ERROR_UNSPECIFIED);
+
+ kp = clib_mem_alloc (sizeof (*kp));
+ *kp = sup_and_sub_key;
+
+ hash_set (hi->sub_interface_sw_if_index_by_id, id, *sub_sw_if_index);
+ hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, *sub_sw_if_index);
+
+ return (0);
+}
+
+int
vnet_delete_sub_interface (u32 sw_if_index)
{
vnet_main_t *vnm = vnet_get_main ();
diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c
index b24c2a1cb52..5e9561fec5f 100644
--- a/src/vnet/interface_api.c
+++ b/src/vnet/interface_api.c
@@ -1243,74 +1243,30 @@ vl_api_create_subif_t_handler (vl_api_create_subif_t * mp)
{
vl_api_create_subif_reply_t *rmp;
vnet_main_t *vnm = vnet_get_main ();
- u32 sw_if_index = ~0;
- int rv = 0;
- u32 sub_id;
- vnet_sw_interface_t *si;
+ u32 sub_sw_if_index = ~0;
vnet_hw_interface_t *hi;
- vnet_sw_interface_t template;
- uword *p;
- vnet_interface_main_t *im = &vnm->interface_main;
- u64 sup_and_sub_key;
- clib_error_t *error;
+ int rv = 0;
VALIDATE_SW_IF_INDEX (mp);
- si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
if (hi->bond_info == VNET_HW_INTERFACE_BOND_INFO_SLAVE)
- {
- rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
- goto out;
- }
-
- sw_if_index = si->sw_if_index;
- sub_id = ntohl (mp->sub_id);
-
- sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
-
- p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
- if (p)
- {
- if (CLIB_DEBUG > 0)
- clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
- sw_if_index, sub_id);
- rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
- goto out;
- }
-
- clib_memset (&template, 0, sizeof (template));
- template.type = VNET_SW_INTERFACE_TYPE_SUB;
- template.flood_class = VNET_FLOOD_CLASS_NORMAL;
- template.sup_sw_if_index = sw_if_index;
- template.sub.id = sub_id;
- template.sub.eth.raw_flags = ntohl (mp->sub_if_flags);
- template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
- template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
-
- error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
- if (error)
- {
- clib_error_report (error);
- rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
- goto out;
- }
-
- u64 *kp = clib_mem_alloc (sizeof (*kp));
- *kp = sup_and_sub_key;
-
- hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
- hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
+ rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
+ else
+ rv = vnet_create_sub_interface (ntohl (mp->sw_if_index),
+ ntohl (mp->sub_id),
+ ntohl (mp->sub_if_flags),
+ ntohs (mp->inner_vlan_id),
+ ntohs (mp->outer_vlan_id),
+ &sub_sw_if_index);
BAD_SW_IF_INDEX_LABEL;
-out:
-
/* *INDENT-OFF* */
REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
({
- rmp->sw_if_index = ntohl(sw_if_index);
+ rmp->sw_if_index = ntohl(sub_sw_if_index);
}));
/* *INDENT-ON* */
}