aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohsin Kazmi <sykazmi@cisco.com>2019-06-10 11:20:15 +0200
committerDamjan Marion <dmarion@me.com>2019-06-20 03:39:31 +0000
commit97d54ed43eb69f6ea731c02305ebe0ca0b1a5cc4 (patch)
tree1247bbd99b64313aa7dc9aa9fd51d822a42e31d8
parent3a9f11e6d93c9839c7bb0aaa62662299165123d8 (diff)
tap: add support to configure tap interface host MTU size
This patch adds support to configure host mtu size using api, cli or startup.conf. Type: feature Change-Id: I8ab087d82dbe7dedc498825c1a3ea3fcb2cce030 Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
-rw-r--r--MAINTAINERS9
-rw-r--r--src/vat/api_format.c20
-rw-r--r--src/vnet/devices/netlink.h1
-rw-r--r--src/vnet/devices/tap/cli.c7
-rw-r--r--src/vnet/devices/tap/tap.c47
-rw-r--r--src/vnet/devices/tap/tap.h6
-rw-r--r--src/vnet/devices/tap/tapv2.api8
-rw-r--r--src/vnet/devices/tap/tapv2_api.c7
-rw-r--r--src/vnet/devices/virtio/virtio.c3
-rw-r--r--src/vnet/devices/virtio/virtio.h1
-rw-r--r--src/vpp/api/custom_dump.c4
11 files changed, 110 insertions, 3 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index cd8bf49afbc..eeaca9b03f0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -78,6 +78,15 @@ I: devices
M: Damjan Marion <damarion@cisco.com>
F: src/vnet/devices/
+VNET TAP Drivers
+I: tap
+M: Damjan Marion <damarion@cisco.com>
+M: Steven Luong <sluong@cisco.com>
+M: Mohsin Kazmi <sykazmi@cisco.com>
+F: src/vnet/devices/tap/
+F: src/vnet/devices/virtio/node.c
+F: src/vnet/devices/virtio/device.c
+
VNET Feature Arcs
I: feature
M: Dave Barach <dave@barachs.net>
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index d9a9d223804..f107246774c 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -7429,6 +7429,7 @@ api_tap_create_v2 (vat_main_t * vam)
{
unformat_input_t *i = vam->input;
vl_api_tap_create_v2_t *mp;
+#define TAP_FLAG_GSO (1 << 0)
u8 mac_address[6];
u8 random_mac = 1;
u32 id = ~0;
@@ -7445,6 +7446,9 @@ api_tap_create_v2 (vat_main_t * vam)
ip6_address_t host_ip6_gw;
u8 host_ip6_gw_set = 0;
u32 host_ip6_prefix_len = 0;
+ u8 host_mtu_set = 0;
+ u32 host_mtu_size = 0;
+ u32 tap_flags = 0;
int ret;
u32 rx_ring_sz = 0, tx_ring_sz = 0;
@@ -7484,6 +7488,12 @@ api_tap_create_v2 (vat_main_t * vam)
;
else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
;
+ else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
+ host_mtu_set = 1;
+ else if (unformat (i, "no-gso"))
+ tap_flags &= ~TAP_FLAG_GSO;
+ else if (unformat (i, "gso"))
+ tap_flags |= TAP_FLAG_GSO;
else
break;
}
@@ -7533,6 +7543,11 @@ api_tap_create_v2 (vat_main_t * vam)
errmsg ("tx ring size must be 32768 or lower. ");
return -99;
}
+ if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
+ {
+ errmsg ("host MTU size must be in between 64 and 65355. ");
+ return -99;
+ }
/* Construct the API message */
M (TAP_CREATE_V2, mp);
@@ -7546,6 +7561,9 @@ api_tap_create_v2 (vat_main_t * vam)
mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
mp->rx_ring_sz = ntohs (rx_ring_sz);
mp->tx_ring_sz = ntohs (tx_ring_sz);
+ mp->host_mtu_set = host_mtu_set;
+ mp->host_mtu_size = ntohl (host_mtu_size);
+ mp->tap_flags = ntohl (tap_flags);
if (random_mac == 0)
clib_memcpy (mp->mac_address, mac_address, 6);
@@ -21843,7 +21861,7 @@ _(l2_flags, \
_(bridge_flags, \
"bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
_(tap_create_v2, \
- "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
+ "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
_(tap_delete_v2, \
"<vpp-if-name> | sw_if_index <id>") \
_(sw_interface_tap_v2_dump, "") \
diff --git a/src/vnet/devices/netlink.h b/src/vnet/devices/netlink.h
index 0d3e0d23ac6..4c765685091 100644
--- a/src/vnet/devices/netlink.h
+++ b/src/vnet/devices/netlink.h
@@ -22,6 +22,7 @@ clib_error_t *vnet_netlink_set_link_netns (int ifindex, int netns_fd,
clib_error_t *vnet_netlink_set_link_master (int ifindex, char *master_ifname);
clib_error_t *vnet_netlink_set_link_addr (int ifindex, u8 * addr);
clib_error_t *vnet_netlink_set_link_state (int ifindex, int up);
+clib_error_t *vnet_netlink_set_link_mtu (int ifindex, int mtu);
clib_error_t *vnet_netlink_add_ip4_addr (int ifindex, void *addr,
int pfx_len);
clib_error_t *vnet_netlink_add_ip6_addr (int ifindex, void *addr,
diff --git a/src/vnet/devices/tap/cli.c b/src/vnet/devices/tap/cli.c
index 084fb908dc9..c74d24a12a9 100644
--- a/src/vnet/devices/tap/cli.c
+++ b/src/vnet/devices/tap/cli.c
@@ -76,6 +76,10 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
;
else if (unformat (line_input, "tx-ring-size %d", &args.tx_ring_sz))
;
+ else
+ if (unformat
+ (line_input, "host-mtu-size %d", &args.host_mtu_size))
+ args.host_mtu_set = 1;
else if (unformat (line_input, "no-gso"))
args.tap_flags &= ~TAP_FLAG_GSO;
else if (unformat (line_input, "gso"))
@@ -114,7 +118,8 @@ VLIB_CLI_COMMAND (tap_create_command, static) = {
"[rx-ring-size <size>] [tx-ring-size <size>] [host-ns <netns>] "
"[host-bridge <bridge-name>] [host-ip4-addr <ip4addr/mask>] "
"[host-ip6-addr <ip6-addr>] [host-ip4-gw <ip4-addr>] "
- "[host-ip6-gw <ip6-addr>] [host-if-name <name>] [no-gso|gso]",
+ "[host-ip6-gw <ip6-addr>] [host-mac-addr <host-mac-address>] "
+ "[host-if-name <name>] [host-mtu-size <size>] [no-gso|gso]",
.function = tap_create_command_fn,
};
/* *INDENT-ON* */
diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c
index 35f1f2a3451..8dc798a3cb3 100644
--- a/src/vnet/devices/tap/tap.c
+++ b/src/vnet/devices/tap/tap.c
@@ -361,6 +361,29 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
}
}
+ if (args->host_mtu_set)
+ {
+ args->error =
+ vnet_netlink_set_link_mtu (vif->ifindex, args->host_mtu_size);
+ if (args->error)
+ {
+ args->rv = VNET_API_ERROR_NETLINK_ERROR;
+ goto error;
+ }
+ }
+ else if (tm->host_mtu_size != 0)
+ {
+ args->error =
+ vnet_netlink_set_link_mtu (vif->ifindex, tm->host_mtu_size);
+ if (args->error)
+ {
+ args->rv = VNET_API_ERROR_NETLINK_ERROR;
+ goto error;
+ }
+ args->host_mtu_set = 1;
+ args->host_mtu_size = tm->host_mtu_size;
+ }
+
/* Set vhost memory table */
i = sizeof (struct vhost_memory) + sizeof (struct vhost_memory_region);
vhost_mem = clib_mem_alloc (i);
@@ -396,6 +419,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
args->host_namespace = 0;
vif->host_bridge = args->host_bridge;
args->host_bridge = 0;
+ vif->host_mtu_size = args->host_mtu_size;
clib_memcpy (vif->host_mac_addr, args->host_mac_addr, 6);
vif->host_ip4_prefix_len = args->host_ip4_prefix_len;
vif->host_ip6_prefix_len = args->host_ip6_prefix_len;
@@ -627,6 +651,7 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
if (vif->host_ip6_prefix_len)
clib_memcpy(tapid->host_ip6_addr, &vif->host_ip6_addr, 16);
tapid->host_ip6_prefix_len = vif->host_ip6_prefix_len;
+ tapid->host_mtu_size = vif->host_mtu_size;
);
/* *INDENT-ON* */
@@ -636,6 +661,26 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
}
static clib_error_t *
+tap_mtu_config (vlib_main_t * vm, unformat_input_t * input)
+{
+ tap_main_t *tm = &tap_main;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "host-mtu %d", &tm->host_mtu_size))
+ ;
+ else
+ return clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, input);
+ }
+
+ return 0;
+}
+
+/* tap { host-mtu <size> } configuration. */
+VLIB_CONFIG_FUNCTION (tap_mtu_config, "tap");
+
+static clib_error_t *
tap_init (vlib_main_t * vm)
{
tap_main_t *tm = &tap_main;
@@ -644,6 +689,8 @@ tap_init (vlib_main_t * vm)
tm->log_default = vlib_log_register_class ("tap", 0);
vlib_log_debug (tm->log_default, "initialized");
+ tm->host_mtu_size = 0;
+
return error;
}
diff --git a/src/vnet/devices/tap/tap.h b/src/vnet/devices/tap/tap.h
index 745f9fca304..45ff1d9910e 100644
--- a/src/vnet/devices/tap/tap.h
+++ b/src/vnet/devices/tap/tap.h
@@ -43,6 +43,8 @@ typedef struct
u8 host_ip6_prefix_len;
ip6_address_t host_ip6_gw;
u8 host_ip6_gw_set;
+ u8 host_mtu_set;
+ u32 host_mtu_size;
/* return */
u32 sw_if_index;
int rv;
@@ -66,6 +68,7 @@ typedef struct
u8 host_ip4_prefix_len;
u8 host_ip6_addr[16];
u8 host_ip6_prefix_len;
+ u32 host_mtu_size;
} tap_interface_details_t;
typedef struct
@@ -75,6 +78,9 @@ typedef struct
/* bit-map of in-use IDs */
uword *tap_ids;
+
+ /* host mtu size, configurable through startup.conf */
+ int host_mtu_size;
} tap_main_t;
void tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args);
diff --git a/src/vnet/devices/tap/tapv2.api b/src/vnet/devices/tap/tapv2.api
index fb90483efbe..2d4d5c3497d 100644
--- a/src/vnet/devices/tap/tapv2.api
+++ b/src/vnet/devices/tap/tapv2.api
@@ -19,7 +19,7 @@
the Linux kernel TAP device driver
*/
-option version = "2.0.0";
+option version = "2.1.0";
/** \brief Initialize a new tap interface with the given paramters
@param client_index - opaque cookie to identify the sender
@@ -47,6 +47,8 @@ option version = "2.0.0";
@param host_ip4_gw - host IPv4 default gateway
@param host_ip6_gw_set - host IPv6 default gateway should be set
@param host_ip6_gw - host IPv6 default gateway
+ @param host_mtu_set - host MTU should be set
+ @param host_mtu_size - host MTU size
@param tap_flags - flags for the TAP interface creation
*/
define tap_create_v2
@@ -76,6 +78,8 @@ define tap_create_v2
u8 host_ip4_gw[4];
u8 host_ip6_gw_set;
u8 host_ip6_gw[16];
+ u8 host_mtu_set;
+ u32 host_mtu_size;
u8 tag[64];
u32 tap_flags;
};
@@ -125,6 +129,7 @@ define sw_interface_tap_v2_dump
@param host_ip4_prefix_len - host IPv4 ip address prefix length; 0 if unset
@param host_ip6_addr - host IPv6 ip address
@param host_ip6_prefix_len - host IPv6 ip address prefix length; 0 if unset
+ @param host_mtu_size - host mtu size
*/
define sw_interface_tap_v2_details
{
@@ -142,6 +147,7 @@ define sw_interface_tap_v2_details
u8 host_ip4_prefix_len;
u8 host_ip6_addr[16];
u8 host_ip6_prefix_len;
+ u32 host_mtu_size;
u32 tap_flags;
};
diff --git a/src/vnet/devices/tap/tapv2_api.c b/src/vnet/devices/tap/tapv2_api.c
index 40ff22eaeaa..2471d0084e1 100644
--- a/src/vnet/devices/tap/tapv2_api.c
+++ b/src/vnet/devices/tap/tapv2_api.c
@@ -109,6 +109,12 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp)
ap->host_ip6_gw_set = 1;
}
+ if (mp->host_mtu_set)
+ {
+ ap->host_mtu_size = ntohl (mp->host_mtu_size);
+ ap->host_mtu_set = 1;
+ }
+
ap->tap_flags = ntohl (mp->tap_flags);
tap_create_if (vm, ap);
@@ -190,6 +196,7 @@ tap_send_sw_interface_details (vpe_api_main_t * am,
clib_memcpy (mp->host_bridge, tap_if->host_bridge,
MIN (ARRAY_LEN (mp->host_bridge) - 1,
strlen ((const char *) tap_if->host_bridge)));
+ mp->host_mtu_size = htonl (tap_if->host_mtu_size);
if (tap_if->host_ip4_prefix_len)
clib_memcpy (&mp->host_ip4_addr, &tap_if->host_ip4_addr, 4);
mp->host_ip4_prefix_len = tap_if->host_ip4_prefix_len;
diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c
index a3fd05dbb55..9e2067bd521 100644
--- a/src/vnet/devices/virtio/virtio.c
+++ b/src/vnet/devices/virtio/virtio.c
@@ -317,6 +317,9 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type)
vlib_cli_output (vm, " name \"%s\"", vif->host_if_name);
if (vif->net_ns)
vlib_cli_output (vm, " host-ns \"%s\"", vif->net_ns);
+ if (vif->host_mtu_size)
+ vlib_cli_output (vm, " host-mtu-size \"%d\"",
+ vif->host_mtu_size);
vlib_cli_output (vm, " fd %d", vif->fd);
vlib_cli_output (vm, " tap-fd %d", vif->tap_fd);
vlib_cli_output (vm, " gso-enabled %d", vif->gso_enabled);
diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h
index 55b6271b337..52b57e9d95f 100644
--- a/src/vnet/devices/virtio/virtio.h
+++ b/src/vnet/devices/virtio/virtio.h
@@ -178,6 +178,7 @@ typedef struct
u8 host_ip4_prefix_len;
ip6_address_t host_ip6_addr;
u8 host_ip6_prefix_len;
+ u32 host_mtu_size;
u32 tap_file_index;
int gso_enabled;
int ifindex;
diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c
index 94a868e0353..524ad368c89 100644
--- a/src/vpp/api/custom_dump.c
+++ b/src/vpp/api/custom_dump.c
@@ -579,6 +579,10 @@ static void *vl_api_tap_create_v2_t_print
s = format (s, "tx-ring-size %u ", ntohs (mp->tx_ring_sz));
if (mp->rx_ring_sz)
s = format (s, "rx-ring-size %u ", ntohs (mp->rx_ring_sz));
+ if (mp->host_mtu_set)
+ s = format (s, "host-mtu-size %u ", ntohl (mp->host_mtu_size));
+ if (ntohl (mp->tap_flags) & 0x1)
+ s = format (s, "gso-enabled");
FINISH;
}