+static void vl_api_sw_interface_set_mac_address_t_handler
+ (vl_api_sw_interface_set_mac_address_t * mp)
+{
+ vl_api_sw_interface_set_mac_address_reply_t *rmp;
+ vnet_main_t *vnm = vnet_get_main ();
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ vnet_sw_interface_t *si;
+ clib_error_t *error;
+ int rv = 0;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ si = vnet_get_sw_interface (vnm, sw_if_index);
+ error = vnet_hw_interface_change_mac_address (vnm, si->hw_if_index,
+ mp->mac_address);
+ if (error)
+ {
+ rv = VNET_API_ERROR_UNIMPLEMENTED;
+ clib_error_report (error);
+ goto out;
+ }
+
+ BAD_SW_IF_INDEX_LABEL;
+out:
+ REPLY_MACRO (VL_API_SW_INTERFACE_SET_MAC_ADDRESS_REPLY);
+}
+
+static void vl_api_sw_interface_get_mac_address_t_handler
+ (vl_api_sw_interface_get_mac_address_t * mp)
+{
+ vl_api_sw_interface_get_mac_address_reply_t *rmp;
+ vl_api_registration_t *reg;
+ vnet_main_t *vnm = vnet_get_main ();
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ vnet_sw_interface_t *si;
+ ethernet_interface_t *eth_if = 0;
+ int rv = 0;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ si = vnet_get_sup_sw_interface (vnm, sw_if_index);
+ if (si->type == VNET_SW_INTERFACE_TYPE_HARDWARE)
+ eth_if = ethernet_get_interface (ðernet_main, si->hw_if_index);
+
+ BAD_SW_IF_INDEX_LABEL;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ rmp->_vl_msg_id = htons (VL_API_SW_INTERFACE_GET_MAC_ADDRESS_REPLY);
+ rmp->context = mp->context;
+ rmp->retval = htonl (rv);
+ if (!rv && eth_if)
+ memcpy (rmp->mac_address, eth_if->address, 6);
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void vl_api_sw_interface_set_rx_mode_t_handler
+ (vl_api_sw_interface_set_rx_mode_t * mp)
+{
+ vl_api_sw_interface_set_rx_mode_reply_t *rmp;
+ vnet_main_t *vnm = vnet_get_main ();
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ vnet_sw_interface_t *si;
+ clib_error_t *error;
+ int rv = 0;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ si = vnet_get_sw_interface (vnm, sw_if_index);
+ error = set_hw_interface_change_rx_mode (vnm, si->hw_if_index,
+ mp->queue_id_valid,
+ ntohl (mp->queue_id), mp->mode);
+ if (error)
+ {
+ rv = VNET_API_ERROR_UNIMPLEMENTED;
+ clib_error_report (error);
+ goto out;
+ }
+
+ BAD_SW_IF_INDEX_LABEL;
+out:
+ REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_MODE_REPLY);
+}
+
+static void
+vl_api_create_vlan_subif_t_handler (vl_api_create_vlan_subif_t * mp)
+{
+ vl_api_create_vlan_subif_reply_t *rmp;
+ vnet_main_t *vnm = vnet_get_main ();
+ u32 sw_if_index = (u32) ~ 0;
+ vnet_hw_interface_t *hi;
+ int rv = 0;
+ u32 id;
+ vnet_sw_interface_t template;
+ uword *p;
+ vnet_interface_main_t *im = &vnm->interface_main;
+ u64 sup_and_sub_key;
+ vl_api_registration_t *reg;
+ clib_error_t *error;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ 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;
+ }
+
+ id = ntohl (mp->vlan_id);
+ if (id == 0 || id > 4095)
+ {
+ rv = VNET_API_ERROR_INVALID_VLAN;
+ goto out;
+ }
+
+ sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
+
+ p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
+ if (p)
+ {
+ rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
+ goto out;
+ }
+
+ memset (&template, 0, sizeof (template));
+ template.type = VNET_SW_INTERFACE_TYPE_SUB;
+ template.sup_sw_if_index = hi->sw_if_index;
+ template.sub.id = id;
+ template.sub.eth.raw_flags = 0;
+ template.sub.eth.flags.one_tag = 1;
+ template.sub.eth.outer_vlan_id = id;
+ template.sub.eth.flags.exact_match = 1;
+
+ error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
+ if (error)
+ {
+ clib_error_report (error);
+ rv = VNET_API_ERROR_INVALID_REGISTRATION;
+ goto out;
+ }
+
+ u64 *kp = clib_mem_alloc (sizeof (*kp));
+ *kp = sup_and_sub_key;
+
+ hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
+ hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
+
+ BAD_SW_IF_INDEX_LABEL;
+
+out:
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ rmp->_vl_msg_id = htons (VL_API_CREATE_VLAN_SUBIF_REPLY);
+ rmp->context = mp->context;
+ rmp->retval = htonl (rv);
+ rmp->sw_if_index = htonl (sw_if_index);
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+