blob: 64a0088136b1f3f272fe48b7eb07dce3ebaecdfd [file] [log] [blame]
Damjan Marion8389fb92017-10-13 18:29:53 +02001/*
2 *------------------------------------------------------------------
3 * tap_api.c - vnet tap device driver API support
4 *
5 * Copyright (c) 2017 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <vnet/vnet.h>
21#include <vlibmemory/api.h>
22
23#include <vnet/interface.h>
24#include <vnet/api_errno.h>
25#include <vnet/ethernet/ethernet.h>
26#include <vnet/ip/ip.h>
Jakub Grajciar5de4fb72019-09-03 10:40:01 +020027#include <vnet/ethernet/ethernet_types_api.h>
28#include <vnet/ip/ip_types_api.h>
Damjan Marionc99b4cd2017-12-04 15:25:58 +010029#include <vnet/devices/tap/tap.h>
Damjan Marion8389fb92017-10-13 18:29:53 +020030
Filip Tehlar3808ec02021-06-22 12:03:55 +000031#include <vnet/format_fns.h>
32#include <vnet/devices/tap/tapv2.api_enum.h>
33#include <vnet/devices/tap/tapv2.api_types.h>
34
Mohsin Kazmib21fd4b2021-09-22 20:03:28 +000035#define REPLY_MSG_ID_BASE tap_main.msg_id_base
Filip Tehlar3808ec02021-06-22 12:03:55 +000036#include <vlibapi/api_helper_macros.h>
37
Damjan Marion8389fb92017-10-13 18:29:53 +020038static void
39vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp)
40{
Paul Vinciguerra44d06912019-10-30 01:53:25 +000041 vl_api_registration_t *reg;
42 reg = vl_api_client_index_to_registration (mp->client_index);
43 if (!reg)
44 return;
45
Jerome Tollet0b061112018-06-04 16:40:26 +010046 vnet_main_t *vnm = vnet_get_main ();
Damjan Marion8389fb92017-10-13 18:29:53 +020047 vlib_main_t *vm = vlib_get_main ();
Damjan Marion8389fb92017-10-13 18:29:53 +020048 vl_api_tap_create_v2_reply_t *rmp;
Paul Vinciguerra44d06912019-10-30 01:53:25 +000049
Damjan Marion8389fb92017-10-13 18:29:53 +020050 tap_create_if_args_t _a, *ap = &_a;
51
Dave Barachb7b92992018-10-17 10:38:51 -040052 clib_memset (ap, 0, sizeof (*ap));
Damjan Marion8389fb92017-10-13 18:29:53 +020053
Steven9e635692018-03-01 09:36:01 -080054 ap->id = ntohl (mp->id);
Damjan Marion8389fb92017-10-13 18:29:53 +020055 if (!mp->use_random_mac)
56 {
Jakub Grajciar5de4fb72019-09-03 10:40:01 +020057 mac_address_decode (mp->mac_address, &ap->mac_addr);
Damjan Marion2df39092017-12-04 20:03:37 +010058 ap->mac_addr_set = 1;
Damjan Marion8389fb92017-10-13 18:29:53 +020059 }
Milan Lenco2aef64f2017-12-05 12:18:15 +010060 ap->rx_ring_sz = ntohs (mp->rx_ring_sz);
61 ap->tx_ring_sz = ntohs (mp->tx_ring_sz);
Damjan Marion8389fb92017-10-13 18:29:53 +020062 ap->sw_if_index = (u32) ~ 0;
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +000063 ap->num_rx_queues = 1;
Damjan Marion8389fb92017-10-13 18:29:53 +020064
Mohsin Kazmi9f32b6a2020-02-14 12:09:04 +000065 if (mp->num_rx_queues > 1)
66 ap->num_rx_queues = mp->num_rx_queues;
Jakub Grajciar5de4fb72019-09-03 10:40:01 +020067
Damjan Marion2df39092017-12-04 20:03:37 +010068 if (mp->host_if_name_set)
Mohsin Kazmi784bbcc2020-10-21 18:32:59 +020069 ap->host_if_name = format (0, "%s%c", mp->host_if_name, 0);
Damjan Marion2df39092017-12-04 20:03:37 +010070
71 if (mp->host_mac_addr_set)
72 {
Jakub Grajciar5de4fb72019-09-03 10:40:01 +020073 mac_address_decode (mp->host_mac_addr, &ap->host_mac_addr);
Damjan Marion2df39092017-12-04 20:03:37 +010074 }
75
Damjan Marion91c6ef72017-12-01 13:34:24 +010076 if (mp->host_namespace_set)
Mohsin Kazmi784bbcc2020-10-21 18:32:59 +020077 ap->host_namespace = format (0, "%s%c", mp->host_namespace, 0);
Damjan Marion91c6ef72017-12-01 13:34:24 +010078
79 if (mp->host_bridge_set)
Mohsin Kazmi784bbcc2020-10-21 18:32:59 +020080 ap->host_bridge = format (0, "%s%c", mp->host_bridge, 0);
Damjan Marion91c6ef72017-12-01 13:34:24 +010081
Jakub Grajciar5de4fb72019-09-03 10:40:01 +020082 if (mp->host_ip4_prefix_set)
Damjan Marion91c6ef72017-12-01 13:34:24 +010083 {
Jakub Grajciar5de4fb72019-09-03 10:40:01 +020084 ip4_address_decode (mp->host_ip4_prefix.address, &ap->host_ip4_addr);
85 ap->host_ip4_prefix_len = mp->host_ip4_prefix.len;
Damjan Marion91c6ef72017-12-01 13:34:24 +010086 }
87
Jakub Grajciar5de4fb72019-09-03 10:40:01 +020088 if (mp->host_ip6_prefix_set)
Damjan Marion91c6ef72017-12-01 13:34:24 +010089 {
Jakub Grajciar5de4fb72019-09-03 10:40:01 +020090 ip6_address_decode (mp->host_ip6_prefix.address, &ap->host_ip6_addr);
91 ap->host_ip6_prefix_len = mp->host_ip6_prefix.len;
Damjan Marion91c6ef72017-12-01 13:34:24 +010092 }
93
Damjan Marion7866c452018-01-18 13:35:11 +010094 if (mp->host_ip4_gw_set)
95 {
Jakub Grajciar5de4fb72019-09-03 10:40:01 +020096 ip4_address_decode (mp->host_ip4_gw, &ap->host_ip4_gw);
Damjan Marion7866c452018-01-18 13:35:11 +010097 ap->host_ip4_gw_set = 1;
98 }
99
100 if (mp->host_ip6_gw_set)
101 {
Jakub Grajciar5de4fb72019-09-03 10:40:01 +0200102 ip6_address_decode (mp->host_ip6_gw, &ap->host_ip6_gw);
Damjan Marion7866c452018-01-18 13:35:11 +0100103 ap->host_ip6_gw_set = 1;
104 }
105
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +0200106 if (mp->host_mtu_set)
107 {
108 ap->host_mtu_size = ntohl (mp->host_mtu_size);
109 ap->host_mtu_set = 1;
110 }
111
Mohsin Kazmia1a22462020-09-02 11:59:37 +0000112 STATIC_ASSERT (((int) TAP_API_FLAG_GSO == (int) TAP_FLAG_GSO),
113 "tap gso api flag mismatch");
114 STATIC_ASSERT (((int) TAP_API_FLAG_CSUM_OFFLOAD ==
115 (int) TAP_FLAG_CSUM_OFFLOAD),
116 "tap checksum offload api flag mismatch");
117 STATIC_ASSERT (((int) TAP_API_FLAG_PERSIST == (int) TAP_FLAG_PERSIST),
118 "tap persist api flag mismatch");
119 STATIC_ASSERT (((int) TAP_API_FLAG_ATTACH == (int) TAP_FLAG_ATTACH),
120 "tap attach api flag mismatch");
121 STATIC_ASSERT (((int) TAP_API_FLAG_TUN == (int) TAP_FLAG_TUN),
122 "tap tun api flag mismatch");
123 STATIC_ASSERT (((int) TAP_API_FLAG_GRO_COALESCE ==
124 (int) TAP_FLAG_GRO_COALESCE),
125 "tap gro coalesce api flag mismatch");
126 STATIC_ASSERT (((int) TAP_API_FLAG_PACKED == (int) TAP_FLAG_PACKED),
127 "tap packed api flag mismatch");
128 STATIC_ASSERT (((int) TAP_API_FLAG_IN_ORDER ==
129 (int) TAP_FLAG_IN_ORDER), "tap in-order api flag mismatch");
130
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +0100131 ap->tap_flags = ntohl (mp->tap_flags);
132
Damjan Marion91c6ef72017-12-01 13:34:24 +0100133 tap_create_if (vm, ap);
Damjan Marion8389fb92017-10-13 18:29:53 +0200134
Damjan Marion8389fb92017-10-13 18:29:53 +0200135
Jerome Tollet0b061112018-06-04 16:40:26 +0100136 /* If a tag was supplied... */
Jakub Grajciar5de4fb72019-09-03 10:40:01 +0200137 if (vl_api_string_len (&mp->tag))
Jerome Tollet0b061112018-06-04 16:40:26 +0100138 {
Dave Barach77841402020-04-29 17:04:10 -0400139 u8 *tag = vl_api_from_api_to_new_vec (mp, &mp->tag);
Jerome Tollet0b061112018-06-04 16:40:26 +0100140 vnet_set_sw_interface_tag (vnm, tag, ap->sw_if_index);
141 }
142
Damjan Marion8389fb92017-10-13 18:29:53 +0200143 rmp = vl_msg_api_alloc (sizeof (*rmp));
Filip Tehlar3808ec02021-06-22 12:03:55 +0000144 rmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_TAP_CREATE_V2_REPLY);
Damjan Marion8389fb92017-10-13 18:29:53 +0200145 rmp->context = mp->context;
Damjan Marion91c6ef72017-12-01 13:34:24 +0100146 rmp->retval = ntohl (ap->rv);
Damjan Marion8389fb92017-10-13 18:29:53 +0200147 rmp->sw_if_index = ntohl (ap->sw_if_index);
148
Florin Coras6c4dae22018-01-09 06:39:23 -0800149 vl_api_send_msg (reg, (u8 *) rmp);
Mohsin Kazmi784bbcc2020-10-21 18:32:59 +0200150
151 vec_free (ap->host_if_name);
152 vec_free (ap->host_namespace);
153 vec_free (ap->host_bridge);
154
Damjan Marion8389fb92017-10-13 18:29:53 +0200155}
156
157static void
Damjan Marion8389fb92017-10-13 18:29:53 +0200158vl_api_tap_delete_v2_t_handler (vl_api_tap_delete_v2_t * mp)
159{
Paul Vinciguerra44d06912019-10-30 01:53:25 +0000160 vl_api_registration_t *reg;
161 reg = vl_api_client_index_to_registration (mp->client_index);
162 if (!reg)
163 return;
164
Jerome Tollet0b061112018-06-04 16:40:26 +0100165 vnet_main_t *vnm = vnet_get_main ();
Damjan Marion8389fb92017-10-13 18:29:53 +0200166 vlib_main_t *vm = vlib_get_main ();
167 int rv;
Damjan Marion8389fb92017-10-13 18:29:53 +0200168 vl_api_tap_delete_v2_reply_t *rmp;
Paul Vinciguerra44d06912019-10-30 01:53:25 +0000169
Damjan Marion8389fb92017-10-13 18:29:53 +0200170 u32 sw_if_index = ntohl (mp->sw_if_index);
171
172 rv = tap_delete_if (vm, sw_if_index);
173
Damjan Marion8389fb92017-10-13 18:29:53 +0200174 rmp = vl_msg_api_alloc (sizeof (*rmp));
Filip Tehlar3808ec02021-06-22 12:03:55 +0000175 rmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_TAP_DELETE_V2_REPLY);
Damjan Marion8389fb92017-10-13 18:29:53 +0200176 rmp->context = mp->context;
177 rmp->retval = ntohl (rv);
178
Florin Coras6c4dae22018-01-09 06:39:23 -0800179 vl_api_send_msg (reg, (u8 *) rmp);
Damjan Marion8389fb92017-10-13 18:29:53 +0200180
181 if (!rv)
Ole Troan2e1c8962019-04-10 09:44:23 +0200182 vnet_clear_sw_interface_tag (vnm, sw_if_index);
Damjan Marion8389fb92017-10-13 18:29:53 +0200183}
184
185static void
186tap_send_sw_interface_details (vpe_api_main_t * am,
Florin Coras6c4dae22018-01-09 06:39:23 -0800187 vl_api_registration_t * reg,
Damjan Marion8389fb92017-10-13 18:29:53 +0200188 tap_interface_details_t * tap_if, u32 context)
189{
190 vl_api_sw_interface_tap_v2_details_t *mp;
191 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400192 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlar3808ec02021-06-22 12:03:55 +0000193 mp->_vl_msg_id =
194 htons (REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_TAP_V2_DETAILS);
Milan Lenco73e7f422017-12-14 10:04:25 +0100195 mp->id = htonl (tap_if->id);
196 mp->sw_if_index = htonl (tap_if->sw_if_index);
Andrew Yourtchenko754f24b2019-01-07 20:56:46 +0100197 mp->tap_flags = htonl (tap_if->tap_flags);
Damjan Marion8389fb92017-10-13 18:29:53 +0200198 clib_memcpy (mp->dev_name, tap_if->dev_name,
199 MIN (ARRAY_LEN (mp->dev_name) - 1,
200 strlen ((const char *) tap_if->dev_name)));
Milan Lenco73e7f422017-12-14 10:04:25 +0100201 mp->rx_ring_sz = htons (tap_if->rx_ring_sz);
202 mp->tx_ring_sz = htons (tap_if->tx_ring_sz);
Jakub Grajciar5de4fb72019-09-03 10:40:01 +0200203 mac_address_encode (&tap_if->host_mac_addr, mp->host_mac_addr);
Milan Lenco73e7f422017-12-14 10:04:25 +0100204 clib_memcpy (mp->host_if_name, tap_if->host_if_name,
205 MIN (ARRAY_LEN (mp->host_if_name) - 1,
206 strlen ((const char *) tap_if->host_if_name)));
207 clib_memcpy (mp->host_namespace, tap_if->host_namespace,
208 MIN (ARRAY_LEN (mp->host_namespace) - 1,
209 strlen ((const char *) tap_if->host_namespace)));
210 clib_memcpy (mp->host_bridge, tap_if->host_bridge,
211 MIN (ARRAY_LEN (mp->host_bridge) - 1,
212 strlen ((const char *) tap_if->host_bridge)));
Mohsin Kazmi97d54ed2019-06-10 11:20:15 +0200213 mp->host_mtu_size = htonl (tap_if->host_mtu_size);
Jakub Grajciar5de4fb72019-09-03 10:40:01 +0200214 mac_address_encode (&tap_if->host_mac_addr, mp->host_mac_addr);
215
Milan Lenco73e7f422017-12-14 10:04:25 +0100216 if (tap_if->host_ip4_prefix_len)
Jakub Grajciar5de4fb72019-09-03 10:40:01 +0200217 ip4_address_encode (&tap_if->host_ip4_addr, mp->host_ip4_prefix.address);
218 mp->host_ip4_prefix.len = tap_if->host_ip4_prefix_len;
Milan Lenco73e7f422017-12-14 10:04:25 +0100219 if (tap_if->host_ip6_prefix_len)
Jakub Grajciar5de4fb72019-09-03 10:40:01 +0200220 ip6_address_encode (&tap_if->host_ip6_addr, mp->host_ip6_prefix.address);
221 mp->host_ip6_prefix.len = tap_if->host_ip6_prefix_len;
Damjan Marion8389fb92017-10-13 18:29:53 +0200222
Milan Lenco73e7f422017-12-14 10:04:25 +0100223 mp->context = context;
Florin Coras6c4dae22018-01-09 06:39:23 -0800224 vl_api_send_msg (reg, (u8 *) mp);
Damjan Marion8389fb92017-10-13 18:29:53 +0200225}
226
227static void
228vl_api_sw_interface_tap_v2_dump_t_handler (vl_api_sw_interface_tap_v2_dump_t *
229 mp)
230{
231 int rv;
232 vpe_api_main_t *am = &vpe_api_main;
Florin Coras6c4dae22018-01-09 06:39:23 -0800233 vl_api_registration_t *reg;
Damjan Marion8389fb92017-10-13 18:29:53 +0200234 tap_interface_details_t *tapifs = NULL;
235 tap_interface_details_t *tap_if = NULL;
Jakub Grajciar5de4fb72019-09-03 10:40:01 +0200236 u32 filter_sw_if_index;
Damjan Marion8389fb92017-10-13 18:29:53 +0200237
Florin Coras6c4dae22018-01-09 06:39:23 -0800238 reg = vl_api_client_index_to_registration (mp->client_index);
239 if (!reg)
Damjan Marion8389fb92017-10-13 18:29:53 +0200240 return;
241
Jakub Grajciar5de4fb72019-09-03 10:40:01 +0200242 filter_sw_if_index = htonl (mp->sw_if_index);
Paul Vinciguerra073d74d2020-04-27 01:12:48 -0400243 if (mp->sw_if_index != ~0)
244 VALIDATE_SW_IF_INDEX (mp);
Jakub Grajciar5de4fb72019-09-03 10:40:01 +0200245
Damjan Marion8389fb92017-10-13 18:29:53 +0200246 rv = tap_dump_ifs (&tapifs);
247 if (rv)
248 return;
249
250 vec_foreach (tap_if, tapifs)
251 {
Paul Vinciguerra073d74d2020-04-27 01:12:48 -0400252 if ((filter_sw_if_index == ~0)
253 || (tap_if->sw_if_index == filter_sw_if_index))
254 tap_send_sw_interface_details (am, reg, tap_if, mp->context);
Damjan Marion8389fb92017-10-13 18:29:53 +0200255 }
Paul Vinciguerra073d74d2020-04-27 01:12:48 -0400256 BAD_SW_IF_INDEX_LABEL;
Damjan Marion8389fb92017-10-13 18:29:53 +0200257 vec_free (tapifs);
258}
259
Filip Tehlar3808ec02021-06-22 12:03:55 +0000260#include <vnet/devices/tap/tapv2.api.c>
Damjan Marion8389fb92017-10-13 18:29:53 +0200261static clib_error_t *
262tapv2_api_hookup (vlib_main_t * vm)
263{
Damjan Marion8389fb92017-10-13 18:29:53 +0200264 /*
265 * Set up the (msg_name, crc, message-id) table
266 */
Filip Tehlar3808ec02021-06-22 12:03:55 +0000267 REPLY_MSG_ID_BASE = setup_message_id_table ();
Damjan Marion8389fb92017-10-13 18:29:53 +0200268
269 return 0;
270}
271
272VLIB_API_INIT_FUNCTION (tapv2_api_hookup);
273
274/*
275 * fd.io coding-style-patch-verification: ON
276 *
277 * Local Variables:
278 * eval: (c-set-style "gnu")
279 * End:
280 */